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