1 package org.djutils.serialization.serializers;
2
3 import java.lang.reflect.Constructor;
4 import java.lang.reflect.InvocationTargetException;
5 import java.util.HashMap;
6 import java.util.Map;
7
8 import org.djunits.unit.SIUnit;
9 import org.djunits.unit.Unit;
10 import org.djunits.unit.scale.IdentityScale;
11 import org.djunits.unit.util.UnitRuntimeException;
12 import org.djunits.value.storage.StorageType;
13 import org.djunits.value.vfloat.scalar.base.FloatScalar;
14 import org.djunits.value.vfloat.vector.FloatSIVector;
15 import org.djunits.value.vfloat.vector.base.FloatVector;
16 import org.djunits.value.vfloat.vector.data.FloatVectorData;
17 import org.djutils.serialization.EndianUtil;
18 import org.djutils.serialization.FieldTypes;
19 import org.djutils.serialization.SerializationException;
20
21
22
23
24
25
26
27
28
29
30
31
32 public class FloatVectorSerializer<U extends Unit<U>, S extends FloatScalar<U, S>, V extends FloatVector<U, S, V>>
33 extends ArrayOrMatrixWithUnitSerializer<U, V>
34 {
35
36 private static final Map<Unit<?>, Constructor<? extends FloatVector<?, ?, ?>>> CACHE = new HashMap<>();
37
38
39 public FloatVectorSerializer()
40 {
41 super(FieldTypes.FLOAT_32_UNIT_ARRAY, "Djunits_FloatVector", 1);
42 }
43
44 @Override
45 public int size(final V afv)
46 {
47 return 4 + 2 + 4 * afv.size();
48 }
49
50 @Override
51 public int getElementSize()
52 {
53 return 4;
54 }
55
56 @Override
57 public void serialize(final V afv, final byte[] buffer, final Pointer pointer, final EndianUtil endianUtil)
58 {
59 endianUtil.encodeInt(afv.size(), buffer, pointer.getAndIncrement(4));
60 encodeUnit(afv.getDisplayUnit(), buffer, pointer, endianUtil);
61 for (int i = 0; i < afv.size(); i++)
62 {
63 endianUtil.encodeFloat(afv.get(i).getSI(), buffer, pointer.getAndIncrement(4));
64 }
65 }
66
67 @Override
68 public V deSerialize(final byte[] buffer, final Pointer pointer, final EndianUtil endianUtil) throws SerializationException
69 {
70 int size = endianUtil.decodeInt(buffer, pointer.getAndIncrement(4));
71 Unit<?> unit = getUnit(buffer, pointer, endianUtil);
72 float[] array = new float[size];
73 for (int i = 0; i < size; i++)
74 {
75 array[i] = endianUtil.decodeFloat(buffer, pointer.getAndIncrement(4));
76 }
77 try
78 {
79 FloatVectorData fvd = FloatVectorData.instantiate(array, IdentityScale.SCALE, StorageType.DENSE);
80 return instantiateAnonymous(fvd, unit);
81 }
82 catch (UnitRuntimeException exception)
83 {
84 throw new SerializationException(exception);
85 }
86 }
87
88
89
90
91
92
93
94
95
96
97
98
99 @SuppressWarnings("unchecked")
100 public static <U extends Unit<U>, S extends FloatScalar<U, S>,
101 V extends FloatVector<U, S, V>> V instantiateAnonymous(final FloatVectorData data, final Unit<?> unit)
102 {
103 try
104 {
105 Constructor<? extends FloatVector<?, ?, ?>> vectorConstructor = CACHE.get(unit);
106 if (vectorConstructor == null)
107 {
108 if (!unit.getClass().getSimpleName().endsWith("Unit"))
109 {
110 throw new ClassNotFoundException("Unit " + unit.getClass().getSimpleName()
111 + " name does noet end with 'Unit'. Cannot find corresponding scalar");
112 }
113 Class<? extends FloatVector<?, ?, ?>> vectorClass;
114 if (unit instanceof SIUnit)
115 {
116 vectorClass = FloatSIVector.class;
117 }
118 else
119 {
120 vectorClass = (Class<FloatVector<?, ?, ?>>) Class.forName("org.djunits.value.vfloat.vector.Float"
121 + unit.getClass().getSimpleName().replace("Unit", "") + "Vector");
122 }
123 vectorConstructor = vectorClass.getDeclaredConstructor(FloatVectorData.class, unit.getClass());
124 CACHE.put(unit, vectorConstructor);
125 }
126 return (V) vectorConstructor.newInstance(data, unit);
127 }
128 catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException
129 | IllegalAccessException | IllegalArgumentException | InvocationTargetException exception)
130 {
131 throw new UnitRuntimeException(
132 "Cannot instantiate FloatVector of unit " + unit.toString() + ". Reason: " + exception.getMessage());
133 }
134 }
135
136 }