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