44 */
55package org .epics .vtype .json ;
66
7- import org .epics .util .array .ListNumber ;
7+ import org .epics .util .array .* ;
88import org .epics .util .number .UByte ;
99import org .epics .util .number .UInteger ;
1010import org .epics .util .number .ULong ;
1515import javax .json .JsonArrayBuilder ;
1616import javax .json .JsonObject ;
1717import java .util .ArrayList ;
18+ import java .util .Arrays ;
1819import java .util .Collections ;
1920import 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 "unsigned primitives" (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