1 package org.djutils.serialization;
2
3 import static org.junit.Assert.assertEquals;
4 import static org.junit.Assert.assertFalse;
5 import static org.junit.Assert.assertNotEquals;
6 import static org.junit.Assert.assertNull;
7 import static org.junit.Assert.assertTrue;
8 import static org.junit.Assert.fail;
9
10 import java.io.File;
11 import java.io.UnsupportedEncodingException;
12 import java.nio.ByteOrder;
13 import java.util.ArrayList;
14 import java.util.Arrays;
15 import java.util.List;
16
17 import org.djunits.unit.AccelerationUnit;
18 import org.djunits.unit.AreaUnit;
19 import org.djunits.unit.DimensionlessUnit;
20 import org.djunits.unit.ElectricalCurrentUnit;
21 import org.djunits.unit.ElectricalResistanceUnit;
22 import org.djunits.unit.EnergyUnit;
23 import org.djunits.unit.LengthUnit;
24 import org.djunits.unit.SpeedUnit;
25 import org.djunits.unit.TimeUnit;
26 import org.djunits.value.ValueRuntimeException;
27 import org.djunits.value.storage.StorageType;
28 import org.djunits.value.vdouble.matrix.ElectricalCurrentMatrix;
29 import org.djunits.value.vdouble.matrix.base.DoubleMatrix;
30 import org.djunits.value.vdouble.scalar.Dimensionless;
31 import org.djunits.value.vdouble.scalar.Length;
32 import org.djunits.value.vdouble.vector.ElectricalCurrentVector;
33 import org.djunits.value.vdouble.vector.base.AbstractDoubleVector;
34 import org.djunits.value.vdouble.vector.base.DoubleVector;
35 import org.djunits.value.vfloat.matrix.FloatElectricalResistanceMatrix;
36 import org.djunits.value.vfloat.matrix.base.FloatMatrix;
37 import org.djunits.value.vfloat.scalar.FloatArea;
38 import org.djunits.value.vfloat.vector.FloatElectricalResistanceVector;
39 import org.djunits.value.vfloat.vector.base.FloatVector;
40 import org.djutils.decoderdumper.HexDumper;
41 import org.djutils.serialization.serializers.BasicSerializer;
42 import org.djutils.serialization.serializers.Pointer;
43 import org.djutils.serialization.util.SerialDataDumper;
44 import org.junit.Test;
45
46
47
48
49
50
51
52
53
54
55 public class Tests
56 {
57
58
59
60
61
62 @Test
63 public void simpleTests() throws SerializationException
64 {
65 int intValue = 123;
66 Integer integerValue = -456;
67 short shortValue = 234;
68 Short shortValue2 = -345;
69 long longValue = 98765L;
70 Long longValue2 = -98765L;
71 Byte byteValue = 12;
72 byte byteValue2 = -23;
73 float floatValue = 1.234f;
74 Float floatValue2 = -3.456f;
75 double doubleValue = 4.56789;
76 Double doubleValue2 = -4.56789;
77 boolean boolValue = true;
78 Boolean boolValue2 = false;
79 Character charValue = 'a';
80 char charValue2 = 'b';
81 String stringValue = "abcDEF123!@#ȦȧȨ\u0776\u0806\u080e";
82 Object[] objects = new Object[] {intValue, integerValue, shortValue, shortValue2, longValue, longValue2, byteValue,
83 byteValue2, floatValue, floatValue2, doubleValue, doubleValue2, boolValue, boolValue2, charValue, charValue2,
84 stringValue};
85 for (EndianUtil endianUtil : new EndianUtil[] {EndianUtil.BIG_ENDIAN, EndianUtil.LITTLE_ENDIAN})
86 {
87 for (boolean encodeUTF8 : new boolean[] {false, true})
88 {
89
90 byte[] serialized = encodeUTF8 ? TypedMessage.encodeUTF8(endianUtil, objects)
91 : TypedMessage.encodeUTF16(endianUtil, objects);
92 System.out.print(HexDumper.hexDumper(serialized));
93 System.out.print(SerialDataDumper.serialDataDumper(endianUtil, serialized));
94 for (boolean primitive : new boolean[] {false, true})
95 {
96 Object[] decodedObjects = primitive ? TypedMessage.decodeToPrimitiveDataTypes(serialized, endianUtil)
97 : TypedMessage.decodeToObjectDataTypes(serialized, endianUtil);
98 assertEquals("Size of decoded matches", objects.length, decodedObjects.length);
99 for (int i = 0; i < objects.length; i++)
100 {
101 assertEquals(
102 "decoded object at index " + i + "(" + objects[i] + ") equals corresponding object in input",
103 objects[i], decodedObjects[i]);
104 }
105 }
106 }
107 }
108 }
109
110
111
112
113
114
115 @Test
116 public void testStrings() throws SerializationException, UnsupportedEncodingException
117 {
118 String abc = "abc";
119 String copyright = "" + '\u00A9';
120 String xi = "" + '\u03BE';
121 String permille = "" + '\u2030';
122 String smiley = "\uD83D\uDE00";
123 String complex = smiley + copyright + xi + permille;
124
125 testString(3, 6, abc);
126 testString(2, 2, copyright);
127 testString(3, 2, permille);
128 testString(2, 2, xi);
129 testString(4, 4, smiley);
130
131 compare(TypedMessage.encodeUTF8(EndianUtil.BIG_ENDIAN, permille),
132 new byte[] {9, 0, 0, 0, 3, (byte) 0xE2, (byte) 0x80, (byte) 0xB0});
133 compare(TypedMessage.encodeUTF16(EndianUtil.BIG_ENDIAN, permille),
134 new byte[] {10, 0, 0, 0, 1, (byte) 0x20, (byte) 0x30});
135
136 compare(TypedMessage.encodeUTF8(EndianUtil.BIG_ENDIAN, smiley),
137 new byte[] {9, 0, 0, 0, 4, (byte) 0xF0, (byte) 0x9F, (byte) 0x98, (byte) 0x80});
138 compare(TypedMessage.encodeUTF16(EndianUtil.BIG_ENDIAN, smiley),
139 new byte[] {10, 0, 0, 0, 2, (byte) 0xD8, (byte) 0x3D, (byte) 0xDE, (byte) 0x00});
140
141 Object[] objects = new Object[] {copyright, xi, permille, smiley, abc, complex};
142 for (EndianUtil endianUtil : new EndianUtil[] {EndianUtil.BIG_ENDIAN, EndianUtil.LITTLE_ENDIAN})
143 {
144 for (boolean encodeUTF8 : new boolean[] {false, true})
145 {
146 byte[] serialized = encodeUTF8 ? TypedMessage.encodeUTF8(endianUtil, objects)
147 : TypedMessage.encodeUTF16(endianUtil, objects);
148 System.out.print(HexDumper.hexDumper(serialized));
149 System.out.print(SerialDataDumper.serialDataDumper(endianUtil, serialized));
150 Object[] decodedObjects = TypedMessage.decodeToObjectDataTypes(serialized, endianUtil);
151 assertEquals("Size of decoded matches", objects.length, decodedObjects.length);
152 for (int i = 0; i < objects.length; i++)
153 {
154 assertEquals("decoded object at index " + i + "(" + objects[i] + ") equals corresponding object in input",
155 objects[i], decodedObjects[i]);
156 }
157 }
158 }
159
160 }
161
162
163
164
165
166
167 private void compare(final byte[] actual, final byte[] expected)
168 {
169 assertEquals(expected.length, actual.length);
170 for (int i = 0; i < expected.length; i++)
171 {
172 assertEquals("byte " + i + " expected: " + expected[i] + ", actual: " + actual[i], expected[i], actual[i]);
173 }
174 }
175
176
177
178
179
180
181
182
183
184 private void testString(final int expected8, final int expected16, final String s)
185 throws SerializationException, UnsupportedEncodingException
186 {
187 assertEquals(expected8, s.getBytes("UTF-8").length);
188 assertEquals(expected16, s.getBytes("UTF-16BE").length);
189 assertEquals(expected16, s.getBytes("UTF-16LE").length);
190
191 byte[] b8 = TypedMessage.encodeUTF8(EndianUtil.BIG_ENDIAN, s);
192 byte[] b16BE = TypedMessage.encodeUTF16(EndianUtil.BIG_ENDIAN, s);
193 byte[] b16LE = TypedMessage.encodeUTF16(EndianUtil.LITTLE_ENDIAN, s);
194
195 assertEquals(expected8, b8.length - 5);
196 assertEquals(expected16, b16BE.length - 5);
197 assertEquals(expected16, b16LE.length - 5);
198
199
200 assertEquals(9, b8[0]);
201 assertEquals(expected8, EndianUtil.BIG_ENDIAN.decodeInt(b8, 1));
202 assertEquals(10, b16BE[0]);
203 assertEquals(expected16 / 2, EndianUtil.BIG_ENDIAN.decodeInt(b16BE, 1));
204
205 assertEquals(expected16 / 2, EndianUtil.LITTLE_ENDIAN.decodeInt(b16LE, 1));
206 }
207
208
209
210
211
212 @Test
213 public void testArrays() throws SerializationException
214 {
215 int[] integer = new int[] {1, 2, 3};
216 Integer[] integerValues2 = new Integer[] {-1, -2, -3};
217 short[] shortValues = new short[] {10, 20, 30};
218 Short[] shortValues2 = new Short[] {-10, -20, -30};
219 long[] longValues = new long[] {1000, 2000, 3000};
220 Long[] longValues2 = new Long[] {-1000L, -2000L, -3000L};
221 byte[] byteValues = new byte[] {12, 13, 14};
222 Byte[] byteValues2 = new Byte[] {-12, -13, -14};
223 boolean[] boolValues = new boolean[] {false, true, true};
224 Boolean[] boolValues2 = new Boolean[] {true, true, false};
225 float[] floatValues = new float[] {12.3f, 23.4f, 34.5f};
226 Float[] floatValues2 = new Float[] {-12.3f, -23.4f, -34.5f};
227 double[] doubleValues = new double[] {23.45, 34.56, 45.67};
228 Double[] doubleValues2 = new Double[] {-23.45, -34.56, -45.67};
229 Object[] objects = new Object[] {integer, integerValues2, shortValues, shortValues2, longValues, longValues2,
230 byteValues, byteValues2, floatValues, floatValues2, doubleValues, doubleValues2, boolValues, boolValues2};
231 for (EndianUtil endianUtil : new EndianUtil[] {EndianUtil.BIG_ENDIAN, EndianUtil.LITTLE_ENDIAN})
232 {
233 for (boolean encodeUTF8 : new boolean[] {false, true})
234 {
235 byte[] serialized = encodeUTF8 ? TypedMessage.encodeUTF8(endianUtil, objects)
236 : TypedMessage.encodeUTF16(endianUtil, objects);
237 System.out.print(HexDumper.hexDumper(serialized));
238 System.out.print(SerialDataDumper.serialDataDumper(endianUtil, serialized));
239 for (boolean primitive : new boolean[] {false, true})
240 {
241 Object[] decodedObjects = primitive ? TypedMessage.decodeToPrimitiveDataTypes(serialized, endianUtil)
242 : TypedMessage.decodeToObjectDataTypes(serialized, endianUtil);
243 assertEquals("Size of decoded matches", objects.length, decodedObjects.length);
244 for (int i = 0; i < objects.length; i++)
245 {
246 assertTrue("decoded object at index " + i + "(" + objects[i] + ") equals corresponding object in input",
247 deepEquals0(makePrimitive(objects[i]), makePrimitive(decodedObjects[i])));
248 }
249 }
250 }
251 }
252 }
253
254
255
256
257
258 @Test
259 public void testMatrices() throws SerializationException
260 {
261 int[][] integer = new int[][] {{1, 2, 3}, {4, 5, 6}};
262 Integer[][] integerValues2 = new Integer[][] {{-1, -2, -3}, {-4, -5, -6}};
263 short[][] shortValues = new short[][] {{10, 20, 30}, {40, 50, 60}};
264 Short[][] shortValues2 = new Short[][] {{-10, -20, -30}, {-40, -50, -60}};
265 long[][] longValues = new long[][] {{1000, 2000, 3000}, {3000, 4000, 5000}};
266 Long[][] longValues2 = new Long[][] {{-1000L, -2000L, -3000L}, {-3000L, -4000L, -5000L}};
267 byte[][] byteValues = new byte[][] {{12, 13, 14}, {15, 16, 17}};
268 Byte[][] byteValues2 = new Byte[][] {{-12, -13, -14}, {-15, -16, -17}};
269 boolean[][] boolValues = new boolean[][] {{false, true, true}, {false, false, false}};
270 Boolean[][] boolValues2 = new Boolean[][] {{true, true, false}, {true, true, true}};
271 float[][] floatValues = new float[][] {{12.3f, 23.4f, 34.5f}, {44.4f, 55.5f, 66.6f}};
272 Float[][] floatValues2 = new Float[][] {{-12.3f, -23.4f, -34.5f}, {-11.1f, -22.2f, -33.3f}};
273 double[][] doubleValues = new double[][] {{23.45, 34.56, 45.67}, {55.5, 66.6, 77.7}};
274 Double[][] doubleValues2 = new Double[][] {{-23.45, -34.56, -45.67}, {-22.2, -33.3, -44.4}};
275 Object[] objects = new Object[] {integer, integerValues2, shortValues, shortValues2, longValues, longValues2,
276 byteValues, byteValues2, floatValues, floatValues2, doubleValues, doubleValues2, boolValues, boolValues2};
277 for (EndianUtil endianUtil : new EndianUtil[] {EndianUtil.BIG_ENDIAN, EndianUtil.LITTLE_ENDIAN})
278 {
279 for (boolean encodeUTF8 : new boolean[] {false, true})
280 {
281 byte[] serialized = encodeUTF8 ? TypedMessage.encodeUTF8(endianUtil, objects)
282 : TypedMessage.encodeUTF16(endianUtil, objects);
283 System.out.print(HexDumper.hexDumper(serialized));
284 System.out.print(SerialDataDumper.serialDataDumper(endianUtil, serialized));
285 for (boolean primitive : new boolean[] {false, true})
286 {
287 Object[] decodedObjects = primitive ? TypedMessage.decodeToPrimitiveDataTypes(serialized, endianUtil)
288 : TypedMessage.decodeToObjectDataTypes(serialized, endianUtil);
289 assertEquals("Size of decoded matches", objects.length, decodedObjects.length);
290 for (int i = 0; i < objects.length; i++)
291 {
292 assertTrue("decoded object at index " + i + "(" + objects[i] + ") equals corresponding object in input",
293 deepEquals0(makePrimitive(objects[i]), makePrimitive(decodedObjects[i])));
294 }
295 }
296 }
297 }
298 }
299
300
301
302
303
304
305 @Test
306 public void testDJunits() throws SerializationException, ValueRuntimeException
307 {
308 Length length = new Length(123.4, LengthUnit.FOOT);
309 Dimensionless value = new Dimensionless(345.6, DimensionlessUnit.SI);
310 FloatArea area = new FloatArea(66.66f, AreaUnit.ACRE);
311 ElectricalCurrentVector currents =
312 DoubleVector.instantiate(new double[] {1.2, 2.3, 3.4}, ElectricalCurrentUnit.MILLIAMPERE, StorageType.DENSE);
313 FloatElectricalResistanceVector resistors =
314 FloatVector.instantiate(new float[] {1.2f, 4.7f, 6.8f}, ElectricalResistanceUnit.KILOOHM, StorageType.DENSE);
315 ElectricalCurrentMatrix currentMatrix = DoubleMatrix.instantiate(new double[][] {{1.2, 2.3, 3.4}, {5.5, 6.6, 7.7}},
316 ElectricalCurrentUnit.MILLIAMPERE, StorageType.DENSE);
317 FloatElectricalResistanceMatrix resistorMatrix = FloatMatrix.instantiate(
318 new float[][] {{1.2f, 4.7f, 6.8f}, {2.2f, 3.3f, 4.4f}}, ElectricalResistanceUnit.KILOOHM, StorageType.DENSE);
319
320 Object[] objects = new Object[] {length, value, area, currents, resistors, currentMatrix, resistorMatrix};
321 for (EndianUtil endianUtil : new EndianUtil[] {EndianUtil.BIG_ENDIAN, EndianUtil.LITTLE_ENDIAN})
322 {
323 byte[] serialized = TypedMessage.encodeUTF16(endianUtil, objects);
324 System.out.print(HexDumper.hexDumper(serialized));
325 System.out.print(SerialDataDumper.serialDataDumper(endianUtil, serialized));
326 for (boolean primitive : new boolean[] {false, true})
327 {
328 Object[] decodedObjects = primitive ? TypedMessage.decodeToPrimitiveDataTypes(serialized, endianUtil)
329 : TypedMessage.decodeToObjectDataTypes(serialized, endianUtil);
330 assertEquals("Size of decoded matches", objects.length, decodedObjects.length);
331 for (int i = 0; i < objects.length; i++)
332 {
333 assertTrue("decoded object at index " + i + "(" + objects[i] + ") equals corresponding object in input",
334 deepEquals0(makePrimitive(objects[i]), makePrimitive(decodedObjects[i])));
335 }
336 }
337 }
338 }
339
340
341
342
343
344
345 @Test
346 public void testSerializationUnits() throws SerializationException, ValueRuntimeException
347 {
348 SerializationUnits areaSerUnit = SerializationUnits.AREA;
349 assertEquals("Area", areaSerUnit.getName());
350 assertEquals("Area (m2)", areaSerUnit.getDescription());
351 assertEquals(5, areaSerUnit.getCode());
352 assertEquals(AreaUnit.class, areaSerUnit.getDjunitsType());
353 assertEquals("[m^2]", areaSerUnit.getSiUnit());
354
355 assertEquals(LengthUnit.class, SerializationUnits.getUnitClass((byte) 16));
356 assertEquals(16, SerializationUnits.getUnitCode(LengthUnit.INCH));
357 assertEquals(areaSerUnit, SerializationUnits.getUnitType((byte) 5));
358 assertEquals(areaSerUnit, SerializationUnits.getUnitType(AreaUnit.ARE));
359
360 assertNotEquals(SerializationUnits.RADIOACTIVITY, areaSerUnit);
361 assertNotEquals(new Object(), areaSerUnit);
362 assertNotEquals(SerializationUnits.RADIOACTIVITY.hashCode(), areaSerUnit.hashCode());
363 assertNotEquals(new Object().hashCode(), areaSerUnit.hashCode());
364 }
365
366
367
368
369
370
371 @Test
372 public void testDJunitDisplayTypes() throws SerializationException, ValueRuntimeException
373 {
374 SerializationUnits areaSerUnit = SerializationUnits.AREA;
375 DisplayType aream2 = DisplayType.AREA_SQUARE_METER;
376 DisplayType areaacre = DisplayType.AREA_ACRE;
377 DisplayType masskg = DisplayType.MASS_KILOGRAM;
378 assertEquals("m2", aream2.getAbbreviation());
379 assertEquals(0, aream2.getByteCode());
380 assertEquals(18, areaacre.getByteCode());
381 assertEquals(AreaUnit.SQUARE_METER, aream2.getDjunitsType());
382 assertEquals(AreaUnit.ACRE, areaacre.getDjunitsType());
383 assertEquals(0, aream2.getIntCode());
384 assertEquals(18, areaacre.getIntCode());
385 assertEquals("SQUARE_METER", aream2.getName());
386 assertEquals("ACRE", areaacre.getName());
387 assertEquals(areaSerUnit, aream2.getUnitType());
388 assertEquals(areaacre.getUnitType(), aream2.getUnitType());
389
390 assertEquals(8, DisplayType.getByteCode(ElectricalResistanceUnit.STATOHM));
391 assertEquals(areaacre, DisplayType.getDisplayType(AreaUnit.ACRE));
392 assertEquals(DisplayType.ENERGY_CALORIE, DisplayType.getDisplayType((byte) 11, 30));
393 assertEquals(areaacre, DisplayType.getDisplayType(areaSerUnit, 18));
394 assertEquals(30, DisplayType.getIntCode(EnergyUnit.CALORIE));
395 assertEquals(EnergyUnit.CALORIE, DisplayType.getUnit((byte) 11, 30));
396 assertEquals(AreaUnit.ACRE, DisplayType.getUnit(areaSerUnit, 18));
397
398 assertNotEquals(aream2, areaacre);
399 assertNotEquals(masskg, areaacre);
400 assertNotEquals(new Object(), areaacre);
401 assertNotEquals(aream2.hashCode(), areaacre.hashCode());
402 assertNotEquals(masskg.hashCode(), areaacre.hashCode());
403 assertNotEquals(new Object().hashCode(), areaacre.hashCode());
404 }
405
406
407 static class Compound implements SerializableObject<Compound>
408 {
409
410 public Integer intValue;
411
412
413 public Double doubleValue;
414
415 @Override
416 public int hashCode()
417 {
418 final int prime = 31;
419 int result = 1;
420 result = prime * result + ((this.doubleValue == null) ? 0 : this.doubleValue.hashCode());
421 result = prime * result + ((this.intValue == null) ? 0 : this.intValue.hashCode());
422 return result;
423 }
424
425 @SuppressWarnings("checkstyle:needbraces")
426 @Override
427 public boolean equals(final Object obj)
428 {
429 if (this == obj)
430 return true;
431 if (obj == null)
432 return false;
433 if (getClass() != obj.getClass())
434 return false;
435 Compound other = (Compound) obj;
436 if (this.doubleValue == null)
437 {
438 if (other.doubleValue != null)
439 return false;
440 }
441 else if (!this.doubleValue.equals(other.doubleValue))
442 return false;
443 if (this.intValue == null)
444 {
445 if (other.intValue != null)
446 return false;
447 }
448 else if (!this.intValue.equals(other.intValue))
449 return false;
450 return true;
451 }
452
453 @Override
454 public String toString()
455 {
456 return "Compound [intValue=" + this.intValue + ", doubleValue=" + this.doubleValue + "]";
457 }
458
459
460
461
462
463
464 Compound(final int intValue, final double doubleValue)
465 {
466 this.intValue = intValue;
467 this.doubleValue = doubleValue;
468 }
469
470 @Override
471 public List<Object> exportAsList()
472 {
473 List<Object> result = new ArrayList<>();
474 result.add(this.intValue);
475 result.add(this.doubleValue);
476 return result;
477 }
478
479 }
480
481
482
483
484
485 @Test
486 public void testCompoundArrays() throws SerializationException
487 {
488 Compound[] testArray = new Compound[] {new Compound(1, 0.1), new Compound(2, 0.2), new Compound(3, 0.3)};
489 Object[] objects = new Object[] {testArray};
490 for (EndianUtil endianUtil : new EndianUtil[] {EndianUtil.BIG_ENDIAN, EndianUtil.LITTLE_ENDIAN})
491 {
492 for (boolean encodeUTF8 : new boolean[] {false, true})
493 {
494
495 byte[] serialized = encodeUTF8 ? TypedMessage.encodeUTF8(endianUtil, objects)
496 : TypedMessage.encodeUTF16(endianUtil, objects);
497
498 for (boolean primitive : new boolean[] {false, true})
499 {
500 Object[] decodedObjects = primitive ? TypedMessage.decodeToPrimitiveDataTypes(serialized, endianUtil)
501 : TypedMessage.decodeToObjectDataTypes(serialized, endianUtil);
502 assertEquals("Size of decoded matches", objects.length, decodedObjects.length);
503
504 for (int i = 0; i < objects.length; i++)
505 {
506 Object o = decodedObjects[i];
507 if (o instanceof TypedMessage.MinimalSerializableObject[])
508 {
509 TypedMessage.MinimalSerializableObject[] in = ((TypedMessage.MinimalSerializableObject[]) o);
510 Compound[] out = new Compound[in.length];
511 for (int j = 0; j < in.length; j++)
512 {
513 List<Object> fields = in[j].exportAsList();
514 Integer intValue = (Integer) fields.get(0);
515 Double doubleValue = (Double) fields.get(1);
516 out[j] = new Compound(intValue, doubleValue);
517 }
518 decodedObjects[i] = out;
519 }
520 }
521 for (int i = 0; i < objects.length; i++)
522 {
523 if (objects[i] instanceof Compound[])
524 {
525 Compound[] in = (Compound[]) objects[i];
526 assertTrue("decoded object is now also a Compound[]", decodedObjects[i] instanceof Compound[]);
527 Compound[] out = (Compound[]) objects[i];
528 assertEquals("Compound arrays have same length", in.length, out.length);
529 for (int j = 0; j < in.length; j++)
530 {
531 assertEquals("reconstructed compound object matches input", in[j], out[j]);
532 }
533 }
534 else
535 {
536 assertTrue(
537 "decoded object at index " + i + "(" + objects[i]
538 + ") equals corresponding object in input",
539 deepEquals0(makePrimitive(objects[i]), makePrimitive(decodedObjects[i])));
540 }
541 }
542 }
543 }
544 }
545 }
546
547
548
549
550
551
552 @SuppressWarnings("unchecked")
553 @Test
554 public void testArrayOfDjutilsVectors() throws ValueRuntimeException, SerializationException
555 {
556 AbstractDoubleVector<?, ?, ?>[] array = new AbstractDoubleVector[] {
557 DoubleVector.instantiate(new double[] {0.1, 0.2, 0.3}, LengthUnit.INCH, StorageType.DENSE),
558 DoubleVector.instantiate(new double[] {10.1, 20.2, 30.3}, TimeUnit.BASE_MINUTE, StorageType.DENSE)};
559 Object[] objects = new Object[] {array};
560 for (EndianUtil endianUtil : new EndianUtil[] {EndianUtil.BIG_ENDIAN, EndianUtil.LITTLE_ENDIAN})
561 {
562 for (boolean encodeUTF8 : new boolean[] {false, true})
563 {
564
565 byte[] serialized = encodeUTF8 ? TypedMessage.encodeUTF8(endianUtil, objects)
566 : TypedMessage.encodeUTF16(endianUtil, objects);
567 System.out.print(HexDumper.hexDumper(serialized));
568 System.out.print(SerialDataDumper.serialDataDumper(endianUtil, serialized));
569 for (boolean primitive : new boolean[] {false, true})
570 {
571 Object[] decodedObjects = primitive ? TypedMessage.decodeToPrimitiveDataTypes(serialized, endianUtil)
572 : TypedMessage.decodeToObjectDataTypes(serialized, endianUtil);
573 assertEquals("Size of decoded matches", objects.length, decodedObjects.length);
574 for (int i = 0; i < objects.length; i++)
575 {
576 if (objects[i] instanceof AbstractDoubleVector<?, ?, ?>[])
577 {
578 AbstractDoubleVector<?, ?, ?>[] arrayIn = (AbstractDoubleVector<?, ?, ?>[]) objects[i];
579 AbstractDoubleVector<?, ?, ?>[] arrayOut = (AbstractDoubleVector<?, ?, ?>[]) decodedObjects[i];
580 for (int j = 0; j < arrayOut.length; j++)
581 {
582 assertEquals("Decoded Djutils array vector element matches", arrayIn[j], arrayOut[j]);
583 }
584 }
585 else
586 {
587 assertTrue(
588 "decoded object at index " + i + "(" + objects[i]
589 + ") equals corresponding object in input",
590 deepEquals0(makePrimitive(objects[i]), makePrimitive(decodedObjects[i])));
591 }
592 }
593 }
594 }
595 }
596 }
597
598
599
600
601 @Test
602 public void testJaggedMatrices()
603 {
604 int[][] integer = new int[][] {{1, 2, 3}, {5, 6}};
605 Integer[][] integerValues2 = new Integer[][] {{-1, -2}, {-4, -5, -6}};
606 short[][] shortValues = new short[][] {{10, 20}, {40, 50, 60}};
607 Short[][] shortValues2 = new Short[][] {{-10, -20, -30}, {-40, -50}};
608 long[][] longValues = new long[][] {{1000, 2000, 3000}, {3000, 4000}};
609 Long[][] longValues2 = new Long[][] {{-1000L, -2000L}, {-3000L, -4000L, -5000L}};
610 byte[][] byteValues = new byte[][] {{12, 13}, {15, 16, 17}};
611 Byte[][] byteValues2 = new Byte[][] {{-12, -13, -14}, {-15, -16}};
612 boolean[][] boolValues = new boolean[][] {{false, true, true}, {false, false}};
613 Boolean[][] boolValues2 = new Boolean[][] {{true, true}, {true, true, true}};
614 float[][] floatValues = new float[][] {{12.3f, 23.4f}, {44.4f, 55.5f, 66.6f}};
615 Float[][] floatValues2 = new Float[][] {{-12.3f, -23.4f, -34.5f}, {-11.1f, -22.2f}};
616 double[][] doubleValues = new double[][] {{23.45, 34.56, 45.67}, {55.5, 66.6}};
617 Double[][] doubleValues2 = new Double[][] {{-23.45, -34.56}, {-22.2, -33.3, -44.4}};
618 Object[] objects = new Object[] {integer, integerValues2, shortValues, shortValues2, longValues, longValues2,
619 byteValues, byteValues2, floatValues, floatValues2, doubleValues, doubleValues2, boolValues, boolValues2};
620 for (EndianUtil endianUtil : new EndianUtil[] {EndianUtil.BIG_ENDIAN, EndianUtil.LITTLE_ENDIAN})
621 {
622 for (Object object : objects)
623 {
624 Object[] singleObjectArray = new Object[] {object};
625 try
626 {
627 TypedMessage.encodeUTF16(endianUtil, singleObjectArray);
628 fail("Jagged array should have thrown a SerializationException");
629 }
630 catch (SerializationException se)
631 {
632
633 }
634 try
635 {
636 TypedMessage.encodeUTF8(endianUtil, singleObjectArray);
637 fail("Jagged array should have thrown a SerializationException");
638 }
639 catch (SerializationException se)
640 {
641
642 }
643 }
644 }
645 }
646
647
648
649
650 @Test
651 public void testUnhandledObject()
652 {
653 File file = new File("whatever");
654 Object[] objects = new Object[] {file};
655 for (EndianUtil endianUtil : new EndianUtil[] {EndianUtil.BIG_ENDIAN, EndianUtil.LITTLE_ENDIAN})
656 {
657 try
658 {
659 TypedMessage.encodeUTF16(endianUtil, objects);
660 fail("Non serializable object should have thrown a SerializationException");
661 }
662 catch (SerializationException se)
663 {
664
665 }
666
667 Integer[][] badMatrix = new Integer[0][0];
668 objects = new Object[] {badMatrix};
669 try
670 {
671 TypedMessage.encodeUTF16(endianUtil, objects);
672 fail("Zero sized matrix should have thrown a SerializationException");
673 }
674 catch (SerializationException se)
675 {
676
677 }
678 }
679 }
680
681
682
683
684 @Test
685 public void pointerTest()
686 {
687 Pointer pointer = new Pointer();
688 assertEquals("initial offset is 0", 0, pointer.get());
689 assertEquals("initial offset is 0", 0, pointer.getAndIncrement(10));
690 assertEquals("offset is now 10", 10, pointer.get());
691 pointer.inc(20);
692 assertEquals("offset is now 30", 30, pointer.get());
693 assertTrue("ToString method returns something descriptive", pointer.toString().startsWith("Pointer"));
694 }
695
696
697
698
699
700
701 static Object makePrimitive(final Object in)
702 {
703 if (in instanceof Byte[])
704 {
705 Byte[] byteIn = (Byte[]) in;
706 byte[] result = new byte[byteIn.length];
707 for (int i = 0; i < result.length; i++)
708 {
709 result[i] = byteIn[i];
710 }
711 return result;
712 }
713 if (in instanceof Short[])
714 {
715 Short[] shortIn = (Short[]) in;
716 short[] result = new short[shortIn.length];
717 for (int i = 0; i < result.length; i++)
718 {
719 result[i] = shortIn[i];
720 }
721 return result;
722 }
723 if (in instanceof Integer[])
724 {
725 Integer[] integerIn = (Integer[]) in;
726 int[] result = new int[integerIn.length];
727 for (int i = 0; i < result.length; i++)
728 {
729 result[i] = integerIn[i];
730 }
731 return result;
732 }
733 if (in instanceof Long[])
734 {
735 Long[] longIn = (Long[]) in;
736 long[] result = new long[longIn.length];
737 for (int i = 0; i < result.length; i++)
738 {
739 result[i] = longIn[i];
740 }
741 return result;
742 }
743 if (in instanceof Float[])
744 {
745 Float[] floatIn = (Float[]) in;
746 float[] result = new float[floatIn.length];
747 for (int i = 0; i < result.length; i++)
748 {
749 result[i] = floatIn[i];
750 }
751 return result;
752 }
753 if (in instanceof Double[])
754 {
755 Double[] doubleIn = (Double[]) in;
756 double[] result = new double[doubleIn.length];
757 for (int i = 0; i < result.length; i++)
758 {
759 result[i] = doubleIn[i];
760 }
761 return result;
762 }
763 if (in instanceof Boolean[])
764 {
765 Boolean[] booleanIn = (Boolean[]) in;
766 boolean[] result = new boolean[booleanIn.length];
767 for (int i = 0; i < result.length; i++)
768 {
769 result[i] = booleanIn[i];
770 }
771 return result;
772 }
773 if (in instanceof Byte[][])
774 {
775 Byte[][] byteIn = (Byte[][]) in;
776 byte[][] result = new byte[byteIn.length][byteIn[0].length];
777 for (int i = 0; i < result.length; i++)
778 {
779 for (int j = 0; j < result[0].length; j++)
780 {
781 result[i][j] = byteIn[i][j];
782 }
783 }
784 return result;
785 }
786 if (in instanceof Short[][])
787 {
788 Short[][] shortIn = (Short[][]) in;
789 short[][] result = new short[shortIn.length][shortIn[0].length];
790 for (int i = 0; i < result.length; i++)
791 {
792 for (int j = 0; j < result[0].length; j++)
793 {
794 result[i][j] = shortIn[i][j];
795 }
796 }
797 return result;
798 }
799 if (in instanceof Integer[][])
800 {
801 Integer[][] integerIn = (Integer[][]) in;
802 int[][] result = new int[integerIn.length][integerIn[0].length];
803 for (int i = 0; i < result.length; i++)
804 {
805 for (int j = 0; j < result[0].length; j++)
806 {
807 result[i][j] = integerIn[i][j];
808 }
809 }
810 return result;
811 }
812 if (in instanceof Long[][])
813 {
814 Long[][] longIn = (Long[][]) in;
815 long[][] result = new long[longIn.length][longIn[0].length];
816 for (int i = 0; i < result.length; i++)
817 {
818 for (int j = 0; j < result[0].length; j++)
819 {
820 result[i][j] = longIn[i][j];
821 }
822 }
823 return result;
824 }
825 if (in instanceof Float[][])
826 {
827 Float[][] floatIn = (Float[][]) in;
828 float[][] result = new float[floatIn.length][floatIn[0].length];
829 for (int i = 0; i < result.length; i++)
830 {
831 for (int j = 0; j < result[0].length; j++)
832 {
833 result[i][j] = floatIn[i][j];
834 }
835 }
836 return result;
837 }
838 if (in instanceof Double[][])
839 {
840 Double[][] doubleIn = (Double[][]) in;
841 double[][] result = new double[doubleIn.length][doubleIn[0].length];
842 for (int i = 0; i < result.length; i++)
843 {
844 for (int j = 0; j < result[0].length; j++)
845 {
846 result[i][j] = doubleIn[i][j];
847 }
848 }
849 return result;
850 }
851 if (in instanceof Boolean[][])
852 {
853 Boolean[][] booleanIn = (Boolean[][]) in;
854 boolean[][] result = new boolean[booleanIn.length][booleanIn[0].length];
855 for (int i = 0; i < result.length; i++)
856 {
857 for (int j = 0; j < result[0].length; j++)
858 {
859 result[i][j] = booleanIn[i][j];
860 }
861 }
862 return result;
863 }
864 return in;
865 }
866
867
868
869
870
871
872
873
874 static boolean deepEquals0(final Object e1, final Object e2)
875 {
876 if (e1 instanceof Object[] && e2 instanceof Object[])
877 {
878 return Arrays.deepEquals((Object[]) e1, (Object[]) e2);
879 }
880 if (e1 instanceof byte[] && e2 instanceof byte[])
881 {
882 return Arrays.equals((byte[]) e1, (byte[]) e2);
883 }
884 if (e1 instanceof short[] && e2 instanceof short[])
885 {
886 return Arrays.equals((short[]) e1, (short[]) e2);
887 }
888 if (e1 instanceof int[] && e2 instanceof int[])
889 {
890 return Arrays.equals((int[]) e1, (int[]) e2);
891 }
892 if (e1 instanceof long[] && e2 instanceof long[])
893 {
894 return Arrays.equals((long[]) e1, (long[]) e2);
895 }
896 if (e1 instanceof char[] && e2 instanceof char[])
897 {
898 return Arrays.equals((char[]) e1, (char[]) e2);
899 }
900 if (e1 instanceof float[] && e2 instanceof float[])
901 {
902 return Arrays.equals((float[]) e1, (float[]) e2);
903 }
904 if (e1 instanceof double[] && e2 instanceof double[])
905 {
906 return Arrays.equals((double[]) e1, (double[]) e2);
907 }
908 if (e1 instanceof boolean[] && e2 instanceof boolean[])
909 {
910 return Arrays.equals((boolean[]) e1, (boolean[]) e2);
911 }
912 return e1.equals(e2);
913 }
914
915
916
917
918 @Test
919 public void testUnitType()
920 {
921 byte code = 127;
922 Class<AccelerationUnit> unitClass = AccelerationUnit.class;
923 String name = "AccelerationName";
924 String description = "AccelerationDescription";
925 String siUnit = "[m/s^2]";
926 SerializationUnits testAccelerationUnitType = new SerializationUnits(code, unitClass, name, description, siUnit);
927 assertEquals("code is returned", code, testAccelerationUnitType.getCode());
928 assertEquals("unit class is returned", unitClass, testAccelerationUnitType.getDjunitsType());
929 assertEquals("name is returned", name, testAccelerationUnitType.getName());
930 assertEquals("description is returned", description, testAccelerationUnitType.getDescription());
931 assertEquals("SI unit is returned", siUnit, testAccelerationUnitType.getSiUnit());
932 assertTrue("toString returns something descriptive", testAccelerationUnitType.toString().startsWith("UnitType"));
933
934 byte undefined = 126;
935 assertEquals("new unit is in the byte type map", testAccelerationUnitType, SerializationUnits.getUnitType(code));
936 assertNull("undefined byte returns null", SerializationUnits.getUnitType(undefined));
937 assertEquals("djunits type is returned", unitClass, SerializationUnits.getUnitClass(code));
938 assertNull("undefined byte returns null", SerializationUnits.getUnitClass(undefined));
939 assertEquals("speed type can be found by byte code", SerializationUnits.SPEED,
940 SerializationUnits.getUnitType((byte) 22));
941 assertEquals("speed type can be found by unit type", SerializationUnits.SPEED,
942 SerializationUnits.getUnitType(SpeedUnit.SI));
943 assertEquals("speed type can be found by non SI unit type", SerializationUnits.SPEED,
944 SerializationUnits.getUnitType(SpeedUnit.FOOT_PER_SECOND));
945 assertEquals("speed unit code can be found by unit type", 22, SerializationUnits.getUnitCode(SpeedUnit.SI));
946 }
947
948
949
950
951 @Test
952 public final void serializationExceptionTest()
953 {
954 String message = "MessageString";
955 Exception e = new SerializationException(message);
956 assertEquals("message should be our message", message, e.getMessage());
957 assertEquals("cause should be null", null, e.getCause());
958 e = new SerializationException();
959 assertEquals("cause should be null", null, e.getCause());
960 String causeString = "CauseString";
961 Throwable cause = new Throwable(causeString);
962 e = new SerializationException(cause);
963 assertEquals("cause should not be our cause", cause, e.getCause());
964 assertEquals("cause description should be our cause string", causeString, e.getCause().getMessage());
965 e = new SerializationException(message, cause);
966 assertEquals("message should be our message", message, e.getMessage());
967 assertEquals("cause should not be our cause", cause, e.getCause());
968 assertEquals("cause description should be our cause string", causeString, e.getCause().getMessage());
969 for (boolean enableSuppression : new boolean[] {true, false})
970 {
971 for (boolean writableStackTrace : new boolean[] {true, false})
972 {
973 e = new SerializationException(message, cause, enableSuppression, writableStackTrace);
974 assertTrue("Exception should not be null", null != e);
975 assertEquals("message should be our message", message, e.getMessage());
976 assertEquals("cause should not be our cause", cause, e.getCause());
977 assertEquals("cause description should be our cause string", causeString, e.getCause().getMessage());
978
979 StackTraceElement[] stackTrace = new StackTraceElement[1];
980 stackTrace[0] = new StackTraceElement("a", "b", "c", 1234);
981 try
982 {
983 e.setStackTrace(stackTrace);
984 }
985 catch (Exception e1)
986 {
987 assertTrue("Stack trace should be writable", writableStackTrace);
988 continue;
989 }
990
991 StackTraceElement[] retrievedStackTrace = e.getStackTrace();
992 if (retrievedStackTrace.length > 0)
993 {
994 assertTrue("stack trace should be writable", writableStackTrace);
995 }
996 }
997 }
998 }
999
1000
1001
1002
1003 @Test
1004 public void testEndianUtil()
1005 {
1006 assertTrue("EndianUtil.BIG_ENDIAN is big endian", EndianUtil.BIG_ENDIAN.isBigEndian());
1007 assertFalse("EndianUtil.LITTLE_ENDIAN is not big endian", EndianUtil.LITTLE_ENDIAN.isBigEndian());
1008 assertEquals("Platform endianness matches what EndianUtil says", ByteOrder.nativeOrder().equals(ByteOrder.BIG_ENDIAN),
1009 EndianUtil.isPlatformBigEndian());
1010 assertTrue("EndianUtil.BIG_ENDIAN is big endian", EndianUtil.bigEndian().isBigEndian());
1011 assertFalse("EndianUtil.LITTLE_ENDIAN is not big endian", EndianUtil.littleEndian().isBigEndian());
1012 assertTrue("EndianUtil has descriptive toString method", EndianUtil.BIG_ENDIAN.toString().startsWith("EndianUtil"));
1013 }
1014
1015
1016
1017
1018 @Test
1019 public void testBasicSerializer()
1020 {
1021 byte code = 123;
1022 String dataClassName = "dataClass";
1023 BasicSerializer<Byte> testSerializer = new BasicSerializer<Byte>(code, dataClassName)
1024 {
1025
1026 @Override
1027 public int size(final Byte object) throws SerializationException
1028 {
1029
1030 return 0;
1031 }
1032
1033 @Override
1034 public int sizeWithPrefix(final Byte object) throws SerializationException
1035 {
1036
1037 return 0;
1038 }
1039
1040 @Override
1041 public void serialize(final Byte object, final byte[] buffer, final Pointer pointer, final EndianUtil endianUtil)
1042 throws SerializationException
1043 {
1044
1045 }
1046
1047 @Override
1048 public void serializeWithPrefix(final Byte object, final byte[] buffer, final Pointer pointer,
1049 final EndianUtil endianUtil) throws SerializationException
1050 {
1051
1052 }
1053
1054 @Override
1055 public Byte deSerialize(final byte[] buffer, final Pointer pointer, final EndianUtil endianUtil)
1056 throws SerializationException
1057 {
1058
1059 return null;
1060 }
1061
1062 @Override
1063 public int getNumberOfDimensions()
1064 {
1065
1066 return 0;
1067 }
1068 };
1069
1070 assertEquals("data class name is returned", dataClassName, testSerializer.dataClassName());
1071 assertTrue("toString returns something descriptive", testSerializer.toString().startsWith("BasicSerializer"));
1072 }
1073
1074 }