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.vdouble.scalar.base.DoubleScalar;
14 import org.djunits.value.vdouble.vector.SIVector;
15 import org.djunits.value.vdouble.vector.base.DoubleVector;
16 import org.djunits.value.vdouble.vector.data.DoubleVectorData;
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 DoubleVectorSerializer<U extends Unit<U>, S extends DoubleScalar<U, S>, V extends DoubleVector<U, S, V>>
33 extends ArrayOrMatrixWithUnitSerializer<U, V>
34 {
35
36 private static final Map<Unit<?>, Constructor<? extends DoubleVector<?, ?, ?>>> CACHE = new HashMap<>();
37
38
39 public DoubleVectorSerializer()
40 {
41 super(FieldTypes.DOUBLE_64_UNIT_ARRAY, "Djunits_DoubleVector", 1);
42 }
43
44 @Override
45 public int size(final V adv)
46 {
47 return 4 + 2 + 8 * adv.size();
48 }
49
50 @Override
51 public int getElementSize()
52 {
53 return 8;
54 }
55
56 @Override
57 public void serialize(final V adv, final byte[] buffer, final Pointer pointer, final EndianUtil endianUtil)
58 throws SerializationException
59 {
60 endianUtil.encodeInt(adv.size(), buffer, pointer.getAndIncrement(4));
61 encodeUnit(adv.getDisplayUnit(), buffer, pointer, endianUtil);
62 for (int i = 0; i < adv.size(); i++)
63 {
64 endianUtil.encodeDouble(adv.get(i).getSI(), buffer, pointer.getAndIncrement(8));
65 }
66 }
67
68 @Override
69 public V deSerialize(final byte[] buffer, final Pointer pointer, final EndianUtil endianUtil) throws SerializationException
70 {
71 int size = endianUtil.decodeInt(buffer, pointer.getAndIncrement(4));
72 Unit<? extends Unit<?>> unit = getUnit(buffer, pointer, endianUtil);
73 double[] array = new double[size];
74 for (int i = 0; i < size; i++)
75 {
76 array[i] = endianUtil.decodeDouble(buffer, pointer.getAndIncrement(8));
77 }
78 try
79 {
80 DoubleVectorData fvd = DoubleVectorData.instantiate(array, IdentityScale.SCALE, StorageType.DENSE);
81 return instantiateAnonymous(fvd, unit);
82 }
83 catch (UnitRuntimeException exception)
84 {
85 throw new SerializationException(exception);
86 }
87 }
88
89
90
91
92
93
94
95
96
97
98
99
100 @SuppressWarnings("unchecked")
101 public static <U extends Unit<U>, S extends DoubleScalar<U, S>,
102 V extends DoubleVector<U, S, V>> V instantiateAnonymous(final DoubleVectorData data, final Unit<?> unit)
103 {
104 try
105 {
106 Constructor<? extends DoubleVector<?, ?, ?>> vectorConstructor = CACHE.get(unit);
107 if (vectorConstructor == null)
108 {
109 if (!unit.getClass().getSimpleName().endsWith("Unit"))
110 {
111 throw new ClassNotFoundException("Unit " + unit.getClass().getSimpleName()
112 + " name does noet end with 'Unit'. Cannot find corresponding scalar");
113 }
114 Class<? extends DoubleVector<?, ?, ?>> vectorClass;
115 if (unit instanceof SIUnit)
116 {
117 vectorClass = SIVector.class;
118 }
119 else
120 {
121 vectorClass = (Class<DoubleVector<?, ?, ?>>) Class.forName("org.djunits.value.vdouble.vector."
122 + unit.getClass().getSimpleName().replace("Unit", "") + "Vector");
123 }
124 vectorConstructor = vectorClass.getDeclaredConstructor(DoubleVectorData.class, unit.getClass());
125 CACHE.put(unit, vectorConstructor);
126 }
127 return (V) vectorConstructor.newInstance(data, unit);
128 }
129 catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException
130 | IllegalAccessException | IllegalArgumentException | InvocationTargetException exception)
131 {
132 throw new UnitRuntimeException(
133 "Cannot instantiate DoubleVector of unit " + unit.toString() + ". Reason: " + exception.getMessage());
134 }
135 }
136 }