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