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.vdouble.scalar.base.DoubleScalar;
15 import org.djunits.value.vdouble.vector.SIVector;
16 import org.djunits.value.vdouble.vector.base.DoubleVector;
17 import org.djunits.value.vdouble.vector.data.DoubleVectorData;
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 DoubleVectorSerializer<U extends Unit<U>, S extends DoubleScalar<U, S>, V extends DoubleVector<U, S, V>>
34 extends ArrayOrMatrixWithUnitSerializer<U, V>
35 {
36
37 private static final Map<Unit<?>, Constructor<? extends DoubleVector<?, ?, ?>>> CACHE = new HashMap<>();
38
39
40 public DoubleVectorSerializer()
41 {
42 super(FieldTypes.DOUBLE_64_UNIT_ARRAY, "Djunits_DoubleVector", 1);
43 }
44
45 @Override
46 public int size(final V adv) throws SerializationException
47 {
48 try
49 {
50 return 4 + 2 + 8 * adv.size();
51 }
52 catch (ValueRuntimeException e)
53 {
54 throw new SerializationException(e);
55 }
56 }
57
58 @Override
59 public void serialize(final V adv, final byte[] buffer, final Pointer pointer, final EndianUtil endianUtil)
60 throws SerializationException
61 {
62 try
63 {
64 endianUtil.encodeInt(adv.size(), buffer, pointer.getAndIncrement(4));
65 encodeUnit(adv.getDisplayUnit(), buffer, pointer, endianUtil);
66 for (int i = 0; i < adv.size(); i++)
67 {
68 endianUtil.encodeDouble(adv.get(i).getSI(), buffer, pointer.getAndIncrement(8));
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<? extends Unit<?>> unit = getUnit(buffer, pointer, endianUtil);
82 double[] array = new double[size];
83 for (int i = 0; i < size; i++)
84 {
85 array[i] = endianUtil.decodeDouble(buffer, pointer.getAndIncrement(8));
86 }
87 try
88 {
89 DoubleVectorData fvd = DoubleVectorData.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 DoubleScalar<U, S>,
111 V extends DoubleVector<U, S, V>> V instantiateAnonymous(final DoubleVectorData data, final Unit<?> unit)
112 {
113 try
114 {
115 Constructor<? extends DoubleVector<?, ?, ?>> 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 DoubleVector<?, ?, ?>> vectorClass;
124 if (unit instanceof SIUnit)
125 {
126 vectorClass = SIVector.class;
127 }
128 else
129 {
130 vectorClass = (Class<DoubleVector<?, ?, ?>>) Class.forName("org.djunits.value.vdouble.vector."
131 + unit.getClass().getSimpleName().replace("Unit", "") + "Vector");
132 }
133 vectorConstructor = vectorClass.getDeclaredConstructor(DoubleVectorData.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 DoubleVector of unit " + unit.toString() + ". Reason: " + exception.getMessage());
143 }
144 }
145 }