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 @SuppressWarnings("checkstyle:visibilitymodifier")
411 public Integer intValue;
412
413
414 @SuppressWarnings("checkstyle:visibilitymodifier")
415 public Double doubleValue;
416
417 @Override
418 public int hashCode()
419 {
420 final int prime = 31;
421 int result = 1;
422 result = prime * result + ((this.doubleValue == null) ? 0 : this.doubleValue.hashCode());
423 result = prime * result + ((this.intValue == null) ? 0 : this.intValue.hashCode());
424 return result;
425 }
426
427 @SuppressWarnings("checkstyle:needbraces")
428 @Override
429 public boolean equals(final Object obj)
430 {
431 if (this == obj)
432 return true;
433 if (obj == null)
434 return false;
435 if (getClass() != obj.getClass())
436 return false;
437 Compound other = (Compound) obj;
438 if (this.doubleValue == null)
439 {
440 if (other.doubleValue != null)
441 return false;
442 }
443 else if (!this.doubleValue.equals(other.doubleValue))
444 return false;
445 if (this.intValue == null)
446 {
447 if (other.intValue != null)
448 return false;
449 }
450 else if (!this.intValue.equals(other.intValue))
451 return false;
452 return true;
453 }
454
455 @Override
456 public String toString()
457 {
458 return "Compound [intValue=" + this.intValue + ", doubleValue=" + this.doubleValue + "]";
459 }
460
461
462
463
464
465
466 Compound(final int intValue, final double doubleValue)
467 {
468 this.intValue = intValue;
469 this.doubleValue = doubleValue;
470 }
471
472 @Override
473 public List<Object> exportAsList()
474 {
475 List<Object> result = new ArrayList<>();
476 result.add(this.intValue);
477 result.add(this.doubleValue);
478 return result;
479 }
480
481 }
482
483
484
485
486
487 @Test
488 public void testCompoundArrays() throws SerializationException
489 {
490 Compound[] testArray = new Compound[] {new Compound(1, 0.1), new Compound(2, 0.2), new Compound(3, 0.3)};
491 Object[] objects = new Object[] {testArray};
492 for (EndianUtil endianUtil : new EndianUtil[] {EndianUtil.BIG_ENDIAN, EndianUtil.LITTLE_ENDIAN})
493 {
494 for (boolean encodeUTF8 : new boolean[] {false, true})
495 {
496
497 byte[] serialized = encodeUTF8 ? TypedMessage.encodeUTF8(endianUtil, objects)
498 : TypedMessage.encodeUTF16(endianUtil, objects);
499
500 for (boolean primitive : new boolean[] {false, true})
501 {
502 Object[] decodedObjects = primitive ? TypedMessage.decodeToPrimitiveDataTypes(serialized, endianUtil)
503 : TypedMessage.decodeToObjectDataTypes(serialized, endianUtil);
504 assertEquals("Size of decoded matches", objects.length, decodedObjects.length);
505
506 for (int i = 0; i < objects.length; i++)
507 {
508 Object o = decodedObjects[i];
509 if (o instanceof TypedMessage.MinimalSerializableObject[])
510 {
511 TypedMessage.MinimalSerializableObject[] in = ((TypedMessage.MinimalSerializableObject[]) o);
512 Compound[] out = new Compound[in.length];
513 for (int j = 0; j < in.length; j++)
514 {
515 List<Object> fields = in[j].exportAsList();
516 Integer intValue = (Integer) fields.get(0);
517 Double doubleValue = (Double) fields.get(1);
518 out[j] = new Compound(intValue, doubleValue);
519 }
520 decodedObjects[i] = out;
521 }
522 }
523 for (int i = 0; i < objects.length; i++)
524 {
525 if (objects[i] instanceof Compound[])
526 {
527 Compound[] in = (Compound[]) objects[i];
528 assertTrue("decoded object is now also a Compound[]", decodedObjects[i] instanceof Compound[]);
529 Compound[] out = (Compound[]) objects[i];
530 assertEquals("Compound arrays have same length", in.length, out.length);
531 for (int j = 0; j < in.length; j++)
532 {
533 assertEquals("reconstructed compound object matches input", in[j], out[j]);
534 }
535 }
536 else
537 {
538 assertTrue(
539 "decoded object at index " + i + "(" + objects[i]
540 + ") equals corresponding object in input",
541 deepEquals0(makePrimitive(objects[i]), makePrimitive(decodedObjects[i])));
542 }
543 }
544 }
545 }
546 }
547 }
548
549
550
551
552
553
554 @SuppressWarnings("unchecked")
555 @Test
556 public void testArrayOfDjutilsVectors() throws ValueRuntimeException, SerializationException
557 {
558 AbstractDoubleVector<?, ?, ?>[] array = new AbstractDoubleVector[] {
559 DoubleVector.instantiate(new double[] {0.1, 0.2, 0.3}, LengthUnit.INCH, StorageType.DENSE),
560 DoubleVector.instantiate(new double[] {10.1, 20.2, 30.3}, TimeUnit.BASE_MINUTE, StorageType.DENSE)};
561 Object[] objects = new Object[] {array};
562 for (EndianUtil endianUtil : new EndianUtil[] {EndianUtil.BIG_ENDIAN, EndianUtil.LITTLE_ENDIAN})
563 {
564 for (boolean encodeUTF8 : new boolean[] {false, true})
565 {
566
567 byte[] serialized = encodeUTF8 ? TypedMessage.encodeUTF8(endianUtil, objects)
568 : TypedMessage.encodeUTF16(endianUtil, objects);
569 System.out.print(HexDumper.hexDumper(serialized));
570 System.out.print(SerialDataDumper.serialDataDumper(endianUtil, serialized));
571 for (boolean primitive : new boolean[] {false, true})
572 {
573 Object[] decodedObjects = primitive ? TypedMessage.decodeToPrimitiveDataTypes(serialized, endianUtil)
574 : TypedMessage.decodeToObjectDataTypes(serialized, endianUtil);
575 assertEquals("Size of decoded matches", objects.length, decodedObjects.length);
576 for (int i = 0; i < objects.length; i++)
577 {
578 if (objects[i] instanceof AbstractDoubleVector<?, ?, ?>[])
579 {
580 AbstractDoubleVector<?, ?, ?>[] arrayIn = (AbstractDoubleVector<?, ?, ?>[]) objects[i];
581 AbstractDoubleVector<?, ?, ?>[] arrayOut = (AbstractDoubleVector<?, ?, ?>[]) decodedObjects[i];
582 for (int j = 0; j < arrayOut.length; j++)
583 {
584 assertEquals("Decoded Djutils array vector element matches", arrayIn[j], arrayOut[j]);
585 }
586 }
587 else
588 {
589 assertTrue(
590 "decoded object at index " + i + "(" + objects[i]
591 + ") equals corresponding object in input",
592 deepEquals0(makePrimitive(objects[i]), makePrimitive(decodedObjects[i])));
593 }
594 }
595 }
596 }
597 }
598 }
599
600
601
602
603 @Test
604 public void testJaggedMatrices()
605 {
606 int[][] integer = new int[][] {{1, 2, 3}, {5, 6}};
607 Integer[][] integerValues2 = new Integer[][] {{-1, -2}, {-4, -5, -6}};
608 short[][] shortValues = new short[][] {{10, 20}, {40, 50, 60}};
609 Short[][] shortValues2 = new Short[][] {{-10, -20, -30}, {-40, -50}};
610 long[][] longValues = new long[][] {{1000, 2000, 3000}, {3000, 4000}};
611 Long[][] longValues2 = new Long[][] {{-1000L, -2000L}, {-3000L, -4000L, -5000L}};
612 byte[][] byteValues = new byte[][] {{12, 13}, {15, 16, 17}};
613 Byte[][] byteValues2 = new Byte[][] {{-12, -13, -14}, {-15, -16}};
614 boolean[][] boolValues = new boolean[][] {{false, true, true}, {false, false}};
615 Boolean[][] boolValues2 = new Boolean[][] {{true, true}, {true, true, true}};
616 float[][] floatValues = new float[][] {{12.3f, 23.4f}, {44.4f, 55.5f, 66.6f}};
617 Float[][] floatValues2 = new Float[][] {{-12.3f, -23.4f, -34.5f}, {-11.1f, -22.2f}};
618 double[][] doubleValues = new double[][] {{23.45, 34.56, 45.67}, {55.5, 66.6}};
619 Double[][] doubleValues2 = new Double[][] {{-23.45, -34.56}, {-22.2, -33.3, -44.4}};
620 Object[] objects = new Object[] {integer, integerValues2, shortValues, shortValues2, longValues, longValues2,
621 byteValues, byteValues2, floatValues, floatValues2, doubleValues, doubleValues2, boolValues, boolValues2};
622 for (EndianUtil endianUtil : new EndianUtil[] {EndianUtil.BIG_ENDIAN, EndianUtil.LITTLE_ENDIAN})
623 {
624 for (Object object : objects)
625 {
626 Object[] singleObjectArray = new Object[] {object};
627 try
628 {
629 TypedMessage.encodeUTF16(endianUtil, singleObjectArray);
630 fail("Jagged array should have thrown a SerializationException");
631 }
632 catch (SerializationException se)
633 {
634
635 }
636 try
637 {
638 TypedMessage.encodeUTF8(endianUtil, singleObjectArray);
639 fail("Jagged array should have thrown a SerializationException");
640 }
641 catch (SerializationException se)
642 {
643
644 }
645 }
646 }
647 }
648
649
650
651
652 @Test
653 public void testUnhandledObject()
654 {
655 File file = new File("whatever");
656 Object[] objects = new Object[] {file};
657 for (EndianUtil endianUtil : new EndianUtil[] {EndianUtil.BIG_ENDIAN, EndianUtil.LITTLE_ENDIAN})
658 {
659 try
660 {
661 TypedMessage.encodeUTF16(endianUtil, objects);
662 fail("Non serializable object should have thrown a SerializationException");
663 }
664 catch (SerializationException se)
665 {
666
667 }
668
669 Integer[][] badMatrix = new Integer[0][0];
670 objects = new Object[] {badMatrix};
671 try
672 {
673 TypedMessage.encodeUTF16(endianUtil, objects);
674 fail("Zero sized matrix should have thrown a SerializationException");
675 }
676 catch (SerializationException se)
677 {
678
679 }
680 }
681 }
682
683
684
685
686 @Test
687 public void pointerTest()
688 {
689 Pointer pointer = new Pointer();
690 assertEquals("initial offset is 0", 0, pointer.get());
691 assertEquals("initial offset is 0", 0, pointer.getAndIncrement(10));
692 assertEquals("offset is now 10", 10, pointer.get());
693 pointer.inc(20);
694 assertEquals("offset is now 30", 30, pointer.get());
695 assertTrue("ToString method returns something descriptive", pointer.toString().startsWith("Pointer"));
696 }
697
698
699
700
701
702
703 static Object makePrimitive(final Object in)
704 {
705 if (in instanceof Byte[])
706 {
707 Byte[] byteIn = (Byte[]) in;
708 byte[] result = new byte[byteIn.length];
709 for (int i = 0; i < result.length; i++)
710 {
711 result[i] = byteIn[i];
712 }
713 return result;
714 }
715 if (in instanceof Short[])
716 {
717 Short[] shortIn = (Short[]) in;
718 short[] result = new short[shortIn.length];
719 for (int i = 0; i < result.length; i++)
720 {
721 result[i] = shortIn[i];
722 }
723 return result;
724 }
725 if (in instanceof Integer[])
726 {
727 Integer[] integerIn = (Integer[]) in;
728 int[] result = new int[integerIn.length];
729 for (int i = 0; i < result.length; i++)
730 {
731 result[i] = integerIn[i];
732 }
733 return result;
734 }
735 if (in instanceof Long[])
736 {
737 Long[] longIn = (Long[]) in;
738 long[] result = new long[longIn.length];
739 for (int i = 0; i < result.length; i++)
740 {
741 result[i] = longIn[i];
742 }
743 return result;
744 }
745 if (in instanceof Float[])
746 {
747 Float[] floatIn = (Float[]) in;
748 float[] result = new float[floatIn.length];
749 for (int i = 0; i < result.length; i++)
750 {
751 result[i] = floatIn[i];
752 }
753 return result;
754 }
755 if (in instanceof Double[])
756 {
757 Double[] doubleIn = (Double[]) in;
758 double[] result = new double[doubleIn.length];
759 for (int i = 0; i < result.length; i++)
760 {
761 result[i] = doubleIn[i];
762 }
763 return result;
764 }
765 if (in instanceof Boolean[])
766 {
767 Boolean[] booleanIn = (Boolean[]) in;
768 boolean[] result = new boolean[booleanIn.length];
769 for (int i = 0; i < result.length; i++)
770 {
771 result[i] = booleanIn[i];
772 }
773 return result;
774 }
775 if (in instanceof Byte[][])
776 {
777 Byte[][] byteIn = (Byte[][]) in;
778 byte[][] result = new byte[byteIn.length][byteIn[0].length];
779 for (int i = 0; i < result.length; i++)
780 {
781 for (int j = 0; j < result[0].length; j++)
782 {
783 result[i][j] = byteIn[i][j];
784 }
785 }
786 return result;
787 }
788 if (in instanceof Short[][])
789 {
790 Short[][] shortIn = (Short[][]) in;
791 short[][] result = new short[shortIn.length][shortIn[0].length];
792 for (int i = 0; i < result.length; i++)
793 {
794 for (int j = 0; j < result[0].length; j++)
795 {
796 result[i][j] = shortIn[i][j];
797 }
798 }
799 return result;
800 }
801 if (in instanceof Integer[][])
802 {
803 Integer[][] integerIn = (Integer[][]) in;
804 int[][] result = new int[integerIn.length][integerIn[0].length];
805 for (int i = 0; i < result.length; i++)
806 {
807 for (int j = 0; j < result[0].length; j++)
808 {
809 result[i][j] = integerIn[i][j];
810 }
811 }
812 return result;
813 }
814 if (in instanceof Long[][])
815 {
816 Long[][] longIn = (Long[][]) in;
817 long[][] result = new long[longIn.length][longIn[0].length];
818 for (int i = 0; i < result.length; i++)
819 {
820 for (int j = 0; j < result[0].length; j++)
821 {
822 result[i][j] = longIn[i][j];
823 }
824 }
825 return result;
826 }
827 if (in instanceof Float[][])
828 {
829 Float[][] floatIn = (Float[][]) in;
830 float[][] result = new float[floatIn.length][floatIn[0].length];
831 for (int i = 0; i < result.length; i++)
832 {
833 for (int j = 0; j < result[0].length; j++)
834 {
835 result[i][j] = floatIn[i][j];
836 }
837 }
838 return result;
839 }
840 if (in instanceof Double[][])
841 {
842 Double[][] doubleIn = (Double[][]) in;
843 double[][] result = new double[doubleIn.length][doubleIn[0].length];
844 for (int i = 0; i < result.length; i++)
845 {
846 for (int j = 0; j < result[0].length; j++)
847 {
848 result[i][j] = doubleIn[i][j];
849 }
850 }
851 return result;
852 }
853 if (in instanceof Boolean[][])
854 {
855 Boolean[][] booleanIn = (Boolean[][]) in;
856 boolean[][] result = new boolean[booleanIn.length][booleanIn[0].length];
857 for (int i = 0; i < result.length; i++)
858 {
859 for (int j = 0; j < result[0].length; j++)
860 {
861 result[i][j] = booleanIn[i][j];
862 }
863 }
864 return result;
865 }
866 return in;
867 }
868
869
870
871
872
873
874
875
876 static boolean deepEquals0(final Object e1, final Object e2)
877 {
878 if (e1 instanceof Object[] && e2 instanceof Object[])
879 {
880 return Arrays.deepEquals((Object[]) e1, (Object[]) e2);
881 }
882 if (e1 instanceof byte[] && e2 instanceof byte[])
883 {
884 return Arrays.equals((byte[]) e1, (byte[]) e2);
885 }
886 if (e1 instanceof short[] && e2 instanceof short[])
887 {
888 return Arrays.equals((short[]) e1, (short[]) e2);
889 }
890 if (e1 instanceof int[] && e2 instanceof int[])
891 {
892 return Arrays.equals((int[]) e1, (int[]) e2);
893 }
894 if (e1 instanceof long[] && e2 instanceof long[])
895 {
896 return Arrays.equals((long[]) e1, (long[]) e2);
897 }
898 if (e1 instanceof char[] && e2 instanceof char[])
899 {
900 return Arrays.equals((char[]) e1, (char[]) e2);
901 }
902 if (e1 instanceof float[] && e2 instanceof float[])
903 {
904 return Arrays.equals((float[]) e1, (float[]) e2);
905 }
906 if (e1 instanceof double[] && e2 instanceof double[])
907 {
908 return Arrays.equals((double[]) e1, (double[]) e2);
909 }
910 if (e1 instanceof boolean[] && e2 instanceof boolean[])
911 {
912 return Arrays.equals((boolean[]) e1, (boolean[]) e2);
913 }
914 return e1.equals(e2);
915 }
916
917
918
919
920 @Test
921 public void testUnitType()
922 {
923 byte code = 127;
924 Class<AccelerationUnit> unitClass = AccelerationUnit.class;
925 String name = "AccelerationName";
926 String description = "AccelerationDescription";
927 String siUnit = "[m/s^2]";
928 SerializationUnits testAccelerationUnitType = new SerializationUnits(code, unitClass, name, description, siUnit);
929 assertEquals("code is returned", code, testAccelerationUnitType.getCode());
930 assertEquals("unit class is returned", unitClass, testAccelerationUnitType.getDjunitsType());
931 assertEquals("name is returned", name, testAccelerationUnitType.getName());
932 assertEquals("description is returned", description, testAccelerationUnitType.getDescription());
933 assertEquals("SI unit is returned", siUnit, testAccelerationUnitType.getSiUnit());
934 assertTrue("toString returns something descriptive", testAccelerationUnitType.toString().startsWith("UnitType"));
935
936 byte undefined = 126;
937 assertEquals("new unit is in the byte type map", testAccelerationUnitType, SerializationUnits.getUnitType(code));
938 assertNull("undefined byte returns null", SerializationUnits.getUnitType(undefined));
939 assertEquals("djunits type is returned", unitClass, SerializationUnits.getUnitClass(code));
940 assertNull("undefined byte returns null", SerializationUnits.getUnitClass(undefined));
941 assertEquals("speed type can be found by byte code", SerializationUnits.SPEED,
942 SerializationUnits.getUnitType((byte) 22));
943 assertEquals("speed type can be found by unit type", SerializationUnits.SPEED,
944 SerializationUnits.getUnitType(SpeedUnit.SI));
945 assertEquals("speed type can be found by non SI unit type", SerializationUnits.SPEED,
946 SerializationUnits.getUnitType(SpeedUnit.FOOT_PER_SECOND));
947 assertEquals("speed unit code can be found by unit type", 22, SerializationUnits.getUnitCode(SpeedUnit.SI));
948 }
949
950
951
952
953 @Test
954 public final void serializationExceptionTest()
955 {
956 String message = "MessageString";
957 Exception e = new SerializationException(message);
958 assertEquals("message should be our message", message, e.getMessage());
959 assertEquals("cause should be null", null, e.getCause());
960 e = new SerializationException();
961 assertEquals("cause should be null", null, e.getCause());
962 String causeString = "CauseString";
963 Throwable cause = new Throwable(causeString);
964 e = new SerializationException(cause);
965 assertEquals("cause should not be our cause", cause, e.getCause());
966 assertEquals("cause description should be our cause string", causeString, e.getCause().getMessage());
967 e = new SerializationException(message, cause);
968 assertEquals("message should be our message", message, e.getMessage());
969 assertEquals("cause should not be our cause", cause, e.getCause());
970 assertEquals("cause description should be our cause string", causeString, e.getCause().getMessage());
971 for (boolean enableSuppression : new boolean[] {true, false})
972 {
973 for (boolean writableStackTrace : new boolean[] {true, false})
974 {
975 e = new SerializationException(message, cause, enableSuppression, writableStackTrace);
976 assertTrue("Exception should not be null", null != e);
977 assertEquals("message should be our message", message, e.getMessage());
978 assertEquals("cause should not be our cause", cause, e.getCause());
979 assertEquals("cause description should be our cause string", causeString, e.getCause().getMessage());
980
981 StackTraceElement[] stackTrace = new StackTraceElement[1];
982 stackTrace[0] = new StackTraceElement("a", "b", "c", 1234);
983 try
984 {
985 e.setStackTrace(stackTrace);
986 }
987 catch (Exception e1)
988 {
989 assertTrue("Stack trace should be writable", writableStackTrace);
990 continue;
991 }
992
993 StackTraceElement[] retrievedStackTrace = e.getStackTrace();
994 if (retrievedStackTrace.length > 0)
995 {
996 assertTrue("stack trace should be writable", writableStackTrace);
997 }
998 }
999 }
1000 }
1001
1002
1003
1004
1005 @Test
1006 public final void serializationRuntimeExceptionTest()
1007 {
1008 String message = "MessageString";
1009 Exception e = new SerializationRuntimeException(message);
1010 assertEquals("message should be our message", message, e.getMessage());
1011 assertEquals("cause should be null", null, e.getCause());
1012 e = new SerializationRuntimeException();
1013 assertEquals("cause should be null", null, e.getCause());
1014 String causeString = "CauseString";
1015 Throwable cause = new Throwable(causeString);
1016 e = new SerializationRuntimeException(cause);
1017 assertEquals("cause should not be our cause", cause, e.getCause());
1018 assertEquals("cause description should be our cause string", causeString, e.getCause().getMessage());
1019 e = new SerializationRuntimeException(message, cause);
1020 assertEquals("message should be our message", message, e.getMessage());
1021 assertEquals("cause should not be our cause", cause, e.getCause());
1022 assertEquals("cause description should be our cause string", causeString, e.getCause().getMessage());
1023 for (boolean enableSuppression : new boolean[] {true, false})
1024 {
1025 for (boolean writableStackTrace : new boolean[] {true, false})
1026 {
1027 e = new SerializationRuntimeException(message, cause, enableSuppression, writableStackTrace);
1028 assertTrue("Exception should not be null", null != e);
1029 assertEquals("message should be our message", message, e.getMessage());
1030 assertEquals("cause should not be our cause", cause, e.getCause());
1031 assertEquals("cause description should be our cause string", causeString, e.getCause().getMessage());
1032
1033 StackTraceElement[] stackTrace = new StackTraceElement[1];
1034 stackTrace[0] = new StackTraceElement("a", "b", "c", 1234);
1035 try
1036 {
1037 e.setStackTrace(stackTrace);
1038 }
1039 catch (Exception e1)
1040 {
1041 assertTrue("Stack trace should be writable", writableStackTrace);
1042 continue;
1043 }
1044
1045 StackTraceElement[] retrievedStackTrace = e.getStackTrace();
1046 if (retrievedStackTrace.length > 0)
1047 {
1048 assertTrue("stack trace should be writable", writableStackTrace);
1049 }
1050 }
1051 }
1052 }
1053
1054
1055
1056
1057 @Test
1058 public void testEndianUtil()
1059 {
1060 assertTrue("EndianUtil.BIG_ENDIAN is big endian", EndianUtil.BIG_ENDIAN.isBigEndian());
1061 assertFalse("EndianUtil.LITTLE_ENDIAN is not big endian", EndianUtil.LITTLE_ENDIAN.isBigEndian());
1062 assertEquals("Platform endianness matches what EndianUtil says", ByteOrder.nativeOrder().equals(ByteOrder.BIG_ENDIAN),
1063 EndianUtil.isPlatformBigEndian());
1064 assertTrue("EndianUtil.BIG_ENDIAN is big endian", EndianUtil.bigEndian().isBigEndian());
1065 assertFalse("EndianUtil.LITTLE_ENDIAN is not big endian", EndianUtil.littleEndian().isBigEndian());
1066 assertTrue("EndianUtil has descriptive toString method", EndianUtil.BIG_ENDIAN.toString().startsWith("EndianUtil"));
1067 }
1068
1069
1070
1071
1072 @Test
1073 public void testBasicSerializer()
1074 {
1075 byte code = 123;
1076 String dataClassName = "dataClass";
1077 BasicSerializer<Byte> testSerializer = new BasicSerializer<Byte>(code, dataClassName)
1078 {
1079
1080 @Override
1081 public int size(final Byte object) throws SerializationException
1082 {
1083
1084 return 0;
1085 }
1086
1087 @Override
1088 public int sizeWithPrefix(final Byte object) throws SerializationException
1089 {
1090
1091 return 0;
1092 }
1093
1094 @Override
1095 public void serialize(final Byte object, final byte[] buffer, final Pointer pointer, final EndianUtil endianUtil)
1096 throws SerializationException
1097 {
1098
1099 }
1100
1101 @Override
1102 public void serializeWithPrefix(final Byte object, final byte[] buffer, final Pointer pointer,
1103 final EndianUtil endianUtil) throws SerializationException
1104 {
1105
1106 }
1107
1108 @Override
1109 public Byte deSerialize(final byte[] buffer, final Pointer pointer, final EndianUtil endianUtil)
1110 throws SerializationException
1111 {
1112
1113 return null;
1114 }
1115
1116 @Override
1117 public int getNumberOfDimensions()
1118 {
1119
1120 return 0;
1121 }
1122 };
1123
1124 assertEquals("data class name is returned", dataClassName, testSerializer.dataClassName());
1125 assertTrue("toString returns something descriptive", testSerializer.toString().startsWith("BasicSerializer"));
1126 }
1127
1128 }