View Javadoc
1   package org.djutils.serialization.serializers;
2   
3   import org.djunits.unit.Unit;
4   import org.djunits.unit.scale.IdentityScale;
5   import org.djunits.value.ValueRuntimeException;
6   import org.djunits.value.storage.StorageType;
7   import org.djunits.value.vdouble.scalar.base.DoubleScalarInterface;
8   import org.djunits.value.vdouble.vector.base.AbstractDoubleVector;
9   import org.djunits.value.vdouble.vector.base.DoubleVector;
10  import org.djunits.value.vdouble.vector.base.DoubleVectorInterface;
11  import org.djunits.value.vdouble.vector.data.DoubleVectorData;
12  import org.djutils.exceptions.Throw;
13  import org.djutils.serialization.EndianUtil;
14  import org.djutils.serialization.FieldTypes;
15  import org.djutils.serialization.SerializationException;
16  
17  /**
18   * (De)serializes an array of (same length) DJUNITS DoubleVectors.
19   * <p>
20   * Copyright (c) 2019-2023 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
21   * BSD-style license. See <a href="https://djunits.org/docs/license.html">DJUNITS License</a>.
22   * <p>
23   * @author <a href="https://www.tudelft.nl/averbraeck" target="_blank">Alexander Verbraeck</a>
24   * @param <U> the unit type
25   * @param <S> the scalar type
26   * @param <V> the vector type
27   */
28  public class DoubleVectorArraySerializer<U extends Unit<U>, S extends DoubleScalarInterface<U, S>,
29          V extends DoubleVectorInterface<U, S, V>> extends ObjectWithUnitSerializer<U, V[]>
30  {
31      /** */
32      public DoubleVectorArraySerializer()
33      {
34          super(FieldTypes.DOUBLE_64_UNIT_COLUMN_ARRAY, "Djunits_vector_array");
35      }
36  
37      /** {@inheritDoc} */
38      @Override
39      public int size(final V[] adva) throws SerializationException
40      {
41          int result = 4 + 4;
42          int width = adva.length;
43          int height = adva[0].size();
44          for (int i = 0; i < width; i++)
45          {
46              V adv = adva[i];
47              Throw.when(adv.size() != height, SerializationException.class,
48                      "All AbstractDoubleVectors in array must have same size");
49              result += 2;
50          }
51          result += height * width * 8;
52          return result;
53      }
54  
55      /** {@inheritDoc} */
56      @Override
57      public void serialize(final V[] adva, final byte[] buffer, final Pointer pointer, final EndianUtil endianUtil)
58              throws SerializationException
59      {
60          int width = adva.length;
61          int height = adva[0].size();
62          endianUtil.encodeInt(height, buffer, pointer.getAndIncrement(4));
63          endianUtil.encodeInt(adva.length, buffer, pointer.getAndIncrement(4));
64          for (int i = 0; i < width; i++)
65          {
66              V adv = adva[i];
67              Throw.when(adv.size() != height, SerializationException.class,
68                      "All AbstractDoubleVectors in array must have same size");
69              encodeUnit(adv.getDisplayUnit(), buffer, pointer, endianUtil);
70          }
71          for (int row = 0; row < height; row++)
72          {
73              for (int col = 0; col < width; col++)
74              {
75                  try
76                  {
77                      endianUtil.encodeDouble(adva[col].getSI(row), buffer, pointer.getAndIncrement(8));
78                  }
79                  catch (ValueRuntimeException e)
80                  {
81                      throw new SerializationException(e);
82                  }
83              }
84          }
85  
86      }
87  
88      /** {@inheritDoc} */
89      @Override
90      public V[] deSerialize(final byte[] buffer, final Pointer pointer, final EndianUtil endianUtil)
91              throws SerializationException
92      {
93          int height = endianUtil.decodeInt(buffer, pointer.getAndIncrement(4));
94          int width = endianUtil.decodeInt(buffer, pointer.getAndIncrement(4));
95          @SuppressWarnings("unchecked")
96          V[] result = (V[]) new AbstractDoubleVector[width];
97          Unit<? extends Unit<?>>[] units = new Unit<?>[width];
98          for (int col = 0; col < width; col++)
99          {
100             units[col] = getUnit(buffer, pointer, endianUtil);
101         }
102         double[][] values = new double[width][height];
103         for (int row = 0; row < height; row++)
104         {
105             for (int col = 0; col < width; col++)
106             {
107                 values[col][row] = endianUtil.decodeDouble(buffer, pointer.getAndIncrement(8));
108             }
109         }
110         for (int col = 0; col < width; col++)
111         {
112             try
113             {
114                 DoubleVectorData fvd = DoubleVectorData.instantiate(values[col], IdentityScale.SCALE, StorageType.DENSE);
115                 result[col] = DoubleVector.instantiateAnonymous(fvd, units[col]);
116             }
117             catch (ValueRuntimeException e)
118             {
119                 throw new SerializationException(e);
120             }
121         }
122         return result;
123     }
124 
125 }