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