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