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