Skip to content

Commit 9875561

Browse files
committed
Adding missing pieces in VTable serialization (JSON)
1 parent b8ba2d6 commit 9875561

4 files changed

Lines changed: 226 additions & 87 deletions

File tree

epics-vtype/vtype-json/src/main/java/org/epics/vtype/json/JsonArrays.java

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,20 @@ public static ListByte toListByte(JsonArray array) {
193193
return ArrayByte.of(values);
194194
}
195195

196+
/**
197+
* Converts the given numeric JSON array to a ListBoolean.
198+
*
199+
* @param array an array of booleans
200+
* @return a new ListBoolean
201+
*/
202+
public static ListBoolean toListBoolean(JsonArray array) {
203+
boolean[] values = new boolean[array.size()];
204+
for (int i = 0; i < values.length; i++) {
205+
values[i] = array.getBoolean(i);
206+
}
207+
return ArrayBoolean.of(values);
208+
}
209+
196210
/**
197211
* Converts the given string JSON array to a List of Strings.
198212
*
@@ -321,7 +335,11 @@ public static JsonArrayBuilder fromListNumber(ListNumber list) {
321335
public static JsonArrayBuilder fromList(Object object) {
322336
if (object instanceof ListNumber) {
323337
return fromListNumber((ListNumber) object);
324-
} else if (object instanceof List) {
338+
}
339+
else if(object instanceof ListBoolean){
340+
return fromListBoolean((ListBoolean)object);
341+
}
342+
else if (object instanceof List) {
325343
List list = (List) object;
326344
if (list.isEmpty()) {
327345
return JsonVTypeBuilder.factory.createArrayBuilder();
@@ -330,4 +348,12 @@ public static JsonArrayBuilder fromList(Object object) {
330348
}
331349
return JsonVTypeBuilder.factory.createArrayBuilder();
332350
}
351+
352+
private static JsonArrayBuilder fromListBoolean(ListBoolean listBoolean){
353+
JsonArrayBuilder builder = JsonVTypeBuilder.factory.createArrayBuilder();
354+
for(int i = 0; i < listBoolean.size(); i++){
355+
builder.add(listBoolean.getBoolean(i));
356+
}
357+
return builder;
358+
}
333359
}

epics-vtype/vtype-json/src/main/java/org/epics/vtype/json/VTypeToJsonV1.java

Lines changed: 113 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*/
55
package org.epics.vtype.json;
66

7-
import org.epics.util.array.ListNumber;
7+
import org.epics.util.array.*;
88
import org.epics.util.number.UByte;
99
import org.epics.util.number.UInteger;
1010
import org.epics.util.number.ULong;
@@ -15,6 +15,7 @@
1515
import javax.json.JsonArrayBuilder;
1616
import javax.json.JsonObject;
1717
import java.util.ArrayList;
18+
import java.util.Arrays;
1819
import java.util.Collections;
1920
import java.util.List;
2021

@@ -103,13 +104,13 @@ static VNumber toVNumber(JsonObject json) {
103104
value = new ULong(mapper.getJsonNumber("value").longValue());
104105
break;
105106
case "VLong":
106-
value = (long) mapper.getJsonNumber("value").longValue();
107+
value = mapper.getJsonNumber("value").longValue();
107108
break;
108109
case "VUInt":
109110
value = new UInteger(mapper.getJsonNumber("value").intValue());
110111
break;
111112
case "VInt":
112-
value = (int) mapper.getJsonNumber("value").intValue();
113+
value = mapper.getJsonNumber("value").intValue();
113114
break;
114115
case "VUShort":
115116
value = new UShort((short) mapper.getJsonNumber("value").intValue());
@@ -248,7 +249,7 @@ static JsonObject toJson(VTable vTable) {
248249
List<String> columnTypes = new ArrayList<>();
249250
for (int i = 0; i < columnCount; i++) {
250251
columnNames.add(i, vTable.getColumnName(i));
251-
columnTypes.add(i, vTable.getColumnType(i).getName());
252+
columnTypes.add(i, getVTableDataType(vTable.getColumnData(i)));
252253
}
253254
jsonVTypeBuilder.addType(vTable)
254255
.add("columnCount", columnCount)
@@ -264,28 +265,84 @@ static JsonObject toJson(VTable vTable) {
264265
}
265266

266267
/**
267-
* @param name A class name, primitives (int, double...) can be used
268-
* @return A {@link Class} derived from the name. Primary purpose is to support
269-
* primitives on top of any Java cononical class name.
270-
* @throws ClassNotFoundException Should not happen under the assumption that underlying
271-
* EPICS data and its Java representation is "well-behaved".
268+
* An NTTable's value columns are always of type struct_t[]. In order to be able to preserve
269+
* the type information when serializing, this method returns a string representation
270+
* of the array type.
271+
* @param data NTTable value field that is always of array type.
272+
* @return A string representation of the array type.
272273
*/
273-
static Class<?> getClass(String name) throws ClassNotFoundException{
274+
static String getVTableDataType(Object data){
275+
if(data instanceof ArrayBoolean){
276+
return "bool";
277+
}
278+
else if(data instanceof ArrayByte){
279+
return "byte";
280+
}
281+
else if(data instanceof ArrayUByte){
282+
return "ubyte";
283+
}
284+
else if(data instanceof ArrayShort){
285+
return "short";
286+
}
287+
else if(data instanceof ArrayUShort){
288+
return "ushort";
289+
}
290+
else if (data instanceof ArrayInteger){
291+
return "int";
292+
}
293+
else if(data instanceof ArrayUInteger){
294+
return "uint";
295+
}
296+
else if(data instanceof ArrayLong){
297+
return "long";
298+
}
299+
else if(data instanceof ArrayULong){
300+
return "ulong";
301+
}
302+
else if(data instanceof ArrayFloat){
303+
return "float";
304+
}
305+
else if(data instanceof ArrayDouble){
306+
return "double";
307+
}
308+
else if(data instanceof List){
309+
return "string";
310+
}
311+
else{
312+
return "invalid";
313+
}
314+
}
315+
316+
/**
317+
* @param name A type name determined at serialization time. The &quot;unsigned primitives&quot; (ushort, uint...)
318+
* are allowed.
319+
* @return A {@link Class} derived from the name, where - for instance - int and uint both map to
320+
* {@link Integer#TYPE}. For unsupported type names <code>null</code> is returned.
321+
*/
322+
static Class<?> getClass(String name) {
274323
switch (name) {
324+
case "bool":
325+
return Boolean.TYPE;
275326
case "int":
327+
case "uint":
276328
return Integer.TYPE;
277329
case "long":
330+
case "ulong":
278331
return Long.TYPE;
279332
case "short":
333+
case "ushort":
280334
return Short.TYPE;
281335
case "byte":
336+
case "ubyte":
282337
return Byte.TYPE;
283338
case "double":
284339
return Double.TYPE;
285340
case "float":
286341
return Float.TYPE;
342+
case "string":
343+
return String.class;
287344
default:
288-
return Class.forName(name);
345+
return null;
289346
}
290347
}
291348

@@ -322,48 +379,60 @@ static VTable toVTable(JsonObject jsonObject) {
322379
List<Class<?>> listClass = new ArrayList<>();
323380
JsonArray columnNames = jsonObject.getJsonArray("columnNames");
324381
JsonArray columnTypes = jsonObject.getJsonArray("columnTypes");
382+
List<Object> listObject = new ArrayList<>();
325383
for (int i = 0; i < columnCount; i++) {
326384
listString.add(i, columnNames.getString(i));
327-
Class<?> clazz;
328-
try {
329-
clazz = getClass(columnTypes.getString(i));
330-
} catch (ClassNotFoundException e) {
331-
clazz = Object.class;
332-
}
385+
Class<?> clazz = getClass(columnTypes.getString(i));
333386
listClass.add(i, clazz);
334-
}
335-
List<Object> listObject = new ArrayList<>();
336-
JsonArray value = jsonObject.getJsonArray("value");
337-
for (int i = 0; i < columnCount; i++) {
387+
JsonArray value = jsonObject.getJsonArray("value");
338388
JsonArray ja = value.getJsonArray(i);
339-
Class clazz = listClass.get(i);
389+
clazz = listClass.get(i);
340390
if (ja == null || ja.isEmpty() || clazz == null) {
341391
listObject.add(i, Collections.emptyList());
342392
} else {
343-
if (clazz.equals(Integer.TYPE)) {
344-
listObject.add(i, JsonArrays.toListInt(ja));
345-
} else if (clazz.equals(Long.TYPE)) {
346-
listObject.add(i, JsonArrays.toListLong(ja));
347-
}
348-
else if (clazz.equals(Short.TYPE)) {
349-
listObject.add(i, JsonArrays.toListShort(ja));
350-
}
351-
else if (clazz.equals(Byte.TYPE)) {
352-
listObject.add(i, JsonArrays.toListByte(ja));
353-
}
354-
else if (clazz.equals(Double.TYPE)) {
355-
listObject.add(i, JsonArrays.toListDouble(ja));
356-
}
357-
else if (clazz.equals(Float.TYPE)) {
358-
listObject.add(i, JsonArrays.toListFloat(ja));
359-
}
360-
else if (clazz.equals(String.class)) {
361-
listObject.add(i, JsonArrays.toListString(ja));
393+
String columnType = columnTypes.getString(i);
394+
switch (columnType){
395+
case "bool":
396+
listObject.add(i, JsonArrays.toListBoolean(ja));
397+
break;
398+
case "byte":
399+
listObject.add(i, JsonArrays.toListByte(ja));
400+
break;
401+
case "ubyte":
402+
listObject.add(i, JsonArrays.toListUByte(ja));
403+
break;
404+
case "short":
405+
listObject.add(i, JsonArrays.toListShort(ja));
406+
break;
407+
case "ushort":
408+
listObject.add(i, JsonArrays.toListUShort(ja));
409+
break;
410+
case "int":
411+
listObject.add(i, JsonArrays.toListInt(ja));
412+
break;
413+
case "uint":
414+
listObject.add(i, JsonArrays.toListUInteger(ja));
415+
break;
416+
case "long":
417+
listObject.add(i, JsonArrays.toListLong(ja));
418+
break;
419+
case "ulong":
420+
listObject.add(i, JsonArrays.toListULong(ja));
421+
break;
422+
case "float":
423+
listObject.add(i, JsonArrays.toListFloat(ja));
424+
break;
425+
case "double":
426+
listObject.add(i, JsonArrays.toListDouble(ja));
427+
break;
428+
case "string":
429+
listObject.add(i, JsonArrays.toListString(ja));
430+
break;
431+
default:
432+
listObject.add(i, Collections.emptyList());
362433
}
363434
}
364435
}
365-
VTable vTable = VTable.of(listClass, listString, listObject);
366-
367-
return vTable;
436+
return VTable.of(listClass, listString, listObject);
368437
}
369438
}

0 commit comments

Comments
 (0)