blob: 3f826be23d0543289c2df3c0033f46571f007640 [file] [log] [blame]
Matthias Andreas Benkardb5d657a2022-02-03 21:14:30 +01001// SPDX-FileCopyrightText: © 2021 Matthias Andreas Benkard <code@mail.matthias.benkard.de>
2//
3// SPDX-License-Identifier: LGPL-3.0-or-later
4
Matthias Andreas Benkard261532a2021-12-12 20:09:27 +01005package eu.mulk.jgvariant.core;
6
Matthias Andreas Benkarde5a5c752021-12-15 19:53:55 +01007import static java.nio.ByteOrder.BIG_ENDIAN;
Matthias Andreas Benkard261532a2021-12-12 20:09:27 +01008import static java.nio.ByteOrder.LITTLE_ENDIAN;
9import static java.nio.charset.StandardCharsets.UTF_8;
Matthias Andreas Benkard55c34812021-12-14 21:51:10 +010010import static org.junit.jupiter.api.Assertions.assertAll;
11import static org.junit.jupiter.api.Assertions.assertArrayEquals;
Matthias Andreas Benkard261532a2021-12-12 20:09:27 +010012import static org.junit.jupiter.api.Assertions.assertEquals;
Matthias Andreas Benkarde5a5c752021-12-15 19:53:55 +010013import static org.junit.jupiter.api.Assertions.assertThrows;
Matthias Andreas Benkard261532a2021-12-12 20:09:27 +010014
Matthias Andreas Benkard261532a2021-12-12 20:09:27 +010015import java.nio.ByteBuffer;
Matthias Andreas Benkard31c61e72021-12-16 20:06:39 +010016import java.text.ParseException;
Matthias Andreas Benkard261532a2021-12-12 20:09:27 +010017import java.util.List;
Matthias Andreas Benkardcd924f62021-12-28 00:46:06 +010018import java.util.Map;
Matthias Andreas Benkard261532a2021-12-12 20:09:27 +010019import java.util.Optional;
20import org.junit.jupiter.api.Test;
21
22/**
23 * Tests based on the examples given in <a
24 * href="https://people.gnome.org/~desrt/gvariant-serialisation.pdf">~desrt/gvariant-serialisation.pdf</a>.
25 */
26class DecoderTest {
27
28 @Test
29 void testString() {
30 var data = new byte[] {0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x00};
Matthias Andreas Benkard35f7a202021-12-14 19:29:26 +010031 var decoder = Decoder.ofString(UTF_8);
32 assertEquals("hello world", decoder.decode(ByteBuffer.wrap(data)));
Matthias Andreas Benkard261532a2021-12-12 20:09:27 +010033 }
34
35 @Test
36 void testMaybe() {
37 var data =
38 new byte[] {0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x00, 0x00};
Matthias Andreas Benkard35f7a202021-12-14 19:29:26 +010039 var decoder = Decoder.ofMaybe(Decoder.ofString(UTF_8));
40 assertEquals(Optional.of("hello world"), decoder.decode(ByteBuffer.wrap(data)));
Matthias Andreas Benkard261532a2021-12-12 20:09:27 +010041 }
42
43 @Test
44 void testBooleanArray() {
45 var data = new byte[] {0x01, 0x00, 0x00, 0x01, 0x01};
Matthias Andreas Benkard35f7a202021-12-14 19:29:26 +010046 var decoder = Decoder.ofArray(Decoder.ofBoolean());
47 assertEquals(List.of(true, false, false, true, true), decoder.decode(ByteBuffer.wrap(data)));
Matthias Andreas Benkard261532a2021-12-12 20:09:27 +010048 }
49
50 @Test
51 void testStructure() {
52 var data =
53 new byte[] {
54 0x66, 0x6F, 0x6F, 0x00, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, 0x04
55 };
56
Matthias Andreas Benkard35f7a202021-12-14 19:29:26 +010057 record TestRecord(String s, int i) {}
Matthias Andreas Benkard261532a2021-12-12 20:09:27 +010058
Matthias Andreas Benkard35f7a202021-12-14 19:29:26 +010059 var decoder = Decoder.ofStructure(TestRecord.class, Decoder.ofString(UTF_8), Decoder.ofInt());
60 assertEquals(new TestRecord("foo", -1), decoder.decode(ByteBuffer.wrap(data)));
Matthias Andreas Benkard261532a2021-12-12 20:09:27 +010061 }
62
63 @Test
64 void testComplexStructureArray() {
65 var data =
66 new byte[] {
67 0x68,
68 0x69,
69 0x00,
70 0x00,
71 (byte) 0xfe,
72 (byte) 0xff,
73 (byte) 0xff,
74 (byte) 0xff,
75 0x03,
76 0x00,
77 0x00,
78 0x00,
79 0x62,
80 0x79,
81 0x65,
82 0x00,
83 (byte) 0xff,
84 (byte) 0xff,
85 (byte) 0xff,
86 (byte) 0xff,
87 0x04,
88 0x09,
89 0x15
90 };
91
Matthias Andreas Benkard35f7a202021-12-14 19:29:26 +010092 record TestRecord(String s, int i) {}
Matthias Andreas Benkard261532a2021-12-12 20:09:27 +010093
94 var decoder =
95 Decoder.ofArray(
96 Decoder.ofStructure(
97 TestRecord.class,
Matthias Andreas Benkard35f7a202021-12-14 19:29:26 +010098 Decoder.ofString(UTF_8),
99 Decoder.ofInt().withByteOrder(LITTLE_ENDIAN)));
Matthias Andreas Benkard261532a2021-12-12 20:09:27 +0100100 assertEquals(
Matthias Andreas Benkard35f7a202021-12-14 19:29:26 +0100101 List.of(new TestRecord("hi", -2), new TestRecord("bye", -1)),
Matthias Andreas Benkard261532a2021-12-12 20:09:27 +0100102 decoder.decode(ByteBuffer.wrap(data)));
103 }
104
105 @Test
Matthias Andreas Benkard9a6c8ed2021-12-28 01:00:22 +0100106 void testDictionary() {
107 var data =
108 new byte[] {
109 0x68,
110 0x69,
111 0x00,
112 0x00,
113 (byte) 0xfe,
114 (byte) 0xff,
115 (byte) 0xff,
116 (byte) 0xff,
117 0x03,
118 0x00,
119 0x00,
120 0x00,
121 0x62,
122 0x79,
123 0x65,
124 0x00,
125 (byte) 0xff,
126 (byte) 0xff,
127 (byte) 0xff,
128 (byte) 0xff,
129 0x04,
130 0x09,
131 0x15
132 };
133
134 var decoder =
135 Decoder.ofDictionary(Decoder.ofString(UTF_8), Decoder.ofInt().withByteOrder(LITTLE_ENDIAN));
136 assertEquals(Map.of("hi", -2, "bye", -1), decoder.decode(ByteBuffer.wrap(data)));
137 }
138
139 @Test
Matthias Andreas Benkard261532a2021-12-12 20:09:27 +0100140 void testStringArray() {
141 var data =
142 new byte[] {
143 0x69, 0x00, 0x63, 0x61, 0x6E, 0x00, 0x68, 0x61, 0x73, 0x00, 0x73, 0x74, 0x72, 0x69, 0x6E,
144 0x67, 0x73, 0x3F, 0x00, 0x02, 0x06, 0x0a, 0x13
145 };
Matthias Andreas Benkard35f7a202021-12-14 19:29:26 +0100146 var decoder = Decoder.ofArray(Decoder.ofString(UTF_8));
147 assertEquals(List.of("i", "can", "has", "strings?"), decoder.decode(ByteBuffer.wrap(data)));
Matthias Andreas Benkard261532a2021-12-12 20:09:27 +0100148 }
149
150 @Test
151 void testNestedStructure() {
152 var data =
153 new byte[] {
154 0x69, 0x63, 0x61, 0x6E, 0x00, 0x68, 0x61, 0x73, 0x00, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67,
155 0x73, 0x3F, 0x00, 0x04, 0x0d, 0x05
156 };
157
Matthias Andreas Benkard35f7a202021-12-14 19:29:26 +0100158 record TestChild(byte b, String s) {}
159 record TestParent(TestChild tc, List<String> as) {}
Matthias Andreas Benkard261532a2021-12-12 20:09:27 +0100160
161 var decoder =
162 Decoder.ofStructure(
163 TestParent.class,
Matthias Andreas Benkard35f7a202021-12-14 19:29:26 +0100164 Decoder.ofStructure(TestChild.class, Decoder.ofByte(), Decoder.ofString(UTF_8)),
165 Decoder.ofArray(Decoder.ofString(UTF_8)));
Matthias Andreas Benkard261532a2021-12-12 20:09:27 +0100166
167 assertEquals(
Matthias Andreas Benkard35f7a202021-12-14 19:29:26 +0100168 new TestParent(new TestChild((byte) 0x69, "can"), List.of("has", "strings?")),
Matthias Andreas Benkard261532a2021-12-12 20:09:27 +0100169 decoder.decode(ByteBuffer.wrap(data)));
170 }
171
172 @Test
Matthias Andreas Benkard55c34812021-12-14 21:51:10 +0100173 void testNestedStructureVariant() {
174 var data =
175 new byte[] {
176 0x69, 0x63, 0x61, 0x6E, 0x00, 0x68, 0x61, 0x73, 0x00, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67,
177 0x73, 0x3F, 0x00, 0x04, 0x0d, 0x05, 0x00, 0x28, 0x28, 0x79, 0x73, 0x29, 0x61, 0x73, 0x29
178 };
179
180 var decoder = Decoder.ofVariant();
Matthias Andreas Benkard31c61e72021-12-16 20:06:39 +0100181 var variant = decoder.decode(ByteBuffer.wrap(data));
182 var result = (Object[]) variant.value();
Matthias Andreas Benkard55c34812021-12-14 21:51:10 +0100183
184 assertAll(
Matthias Andreas Benkard31c61e72021-12-16 20:06:39 +0100185 () -> assertEquals(Signature.parse("((ys)as)"), variant.signature()),
Matthias Andreas Benkard55c34812021-12-14 21:51:10 +0100186 () -> assertEquals(2, result.length),
187 () -> assertArrayEquals(new Object[] {(byte) 0x69, "can"}, (Object[]) result[0]),
188 () -> assertEquals(List.of("has", "strings?"), result[1]));
189 }
190
191 @Test
Matthias Andreas Benkard261532a2021-12-12 20:09:27 +0100192 void testSimpleStructure() {
193 var data = new byte[] {0x60, 0x70};
194
Matthias Andreas Benkard35f7a202021-12-14 19:29:26 +0100195 record TestRecord(byte b1, byte b2) {}
Matthias Andreas Benkard261532a2021-12-12 20:09:27 +0100196
197 var decoder =
198 Decoder.ofStructure(
199 TestRecord.class,
Matthias Andreas Benkard35f7a202021-12-14 19:29:26 +0100200 Decoder.ofByte().withByteOrder(LITTLE_ENDIAN),
201 Decoder.ofByte().withByteOrder(LITTLE_ENDIAN));
Matthias Andreas Benkard261532a2021-12-12 20:09:27 +0100202
Matthias Andreas Benkard35f7a202021-12-14 19:29:26 +0100203 assertEquals(new TestRecord((byte) 0x60, (byte) 0x70), decoder.decode(ByteBuffer.wrap(data)));
Matthias Andreas Benkard261532a2021-12-12 20:09:27 +0100204 }
205
206 @Test
207 void testPaddedStructureRight() {
208 var data = new byte[] {0x60, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00};
209
Matthias Andreas Benkard35f7a202021-12-14 19:29:26 +0100210 record TestRecord(int b1, byte b2) {}
Matthias Andreas Benkard261532a2021-12-12 20:09:27 +0100211
212 var decoder =
213 Decoder.ofStructure(
214 TestRecord.class,
Matthias Andreas Benkard35f7a202021-12-14 19:29:26 +0100215 Decoder.ofInt().withByteOrder(LITTLE_ENDIAN),
216 Decoder.ofByte().withByteOrder(LITTLE_ENDIAN));
Matthias Andreas Benkard261532a2021-12-12 20:09:27 +0100217
Matthias Andreas Benkard35f7a202021-12-14 19:29:26 +0100218 assertEquals(new TestRecord(0x60, (byte) 0x70), decoder.decode(ByteBuffer.wrap(data)));
Matthias Andreas Benkard261532a2021-12-12 20:09:27 +0100219 }
220
221 @Test
222 void testPaddedStructureLeft() {
223 var data = new byte[] {0x60, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00};
224
Matthias Andreas Benkard35f7a202021-12-14 19:29:26 +0100225 record TestRecord(byte b1, int b2) {}
Matthias Andreas Benkard261532a2021-12-12 20:09:27 +0100226
227 var decoder =
228 Decoder.ofStructure(
229 TestRecord.class,
Matthias Andreas Benkard35f7a202021-12-14 19:29:26 +0100230 Decoder.ofByte().withByteOrder(LITTLE_ENDIAN),
231 Decoder.ofInt().withByteOrder(LITTLE_ENDIAN));
Matthias Andreas Benkard261532a2021-12-12 20:09:27 +0100232
Matthias Andreas Benkard35f7a202021-12-14 19:29:26 +0100233 assertEquals(new TestRecord((byte) 0x60, 0x70), decoder.decode(ByteBuffer.wrap(data)));
Matthias Andreas Benkard261532a2021-12-12 20:09:27 +0100234 }
235
236 @Test
237 void testSimpleStructureArray() {
238 var data =
239 new byte[] {
240 0x60,
241 0x00,
242 0x00,
243 0x00,
244 0x70,
245 0x00,
246 0x00,
247 0x00,
248 (byte) 0x88,
249 0x02,
250 0x00,
251 0x00,
252 (byte) 0xF7,
253 0x00,
254 0x00,
255 0x00
256 };
257
Matthias Andreas Benkard35f7a202021-12-14 19:29:26 +0100258 record TestRecord(int b1, byte b2) {}
Matthias Andreas Benkard261532a2021-12-12 20:09:27 +0100259
260 var decoder =
261 Decoder.ofArray(
262 Decoder.ofStructure(
263 TestRecord.class,
Matthias Andreas Benkard35f7a202021-12-14 19:29:26 +0100264 Decoder.ofInt().withByteOrder(LITTLE_ENDIAN),
265 Decoder.ofByte().withByteOrder(LITTLE_ENDIAN)));
Matthias Andreas Benkard261532a2021-12-12 20:09:27 +0100266
267 assertEquals(
Matthias Andreas Benkard35f7a202021-12-14 19:29:26 +0100268 List.of(new TestRecord(96, (byte) 0x70), new TestRecord(648, (byte) 0xf7)),
Matthias Andreas Benkard261532a2021-12-12 20:09:27 +0100269 decoder.decode(ByteBuffer.wrap(data)));
270 }
271
272 @Test
273 void testByteArray() {
274 var data = new byte[] {0x04, 0x05, 0x06, 0x07};
275
Matthias Andreas Benkard35f7a202021-12-14 19:29:26 +0100276 var decoder = Decoder.ofArray(Decoder.ofByte());
Matthias Andreas Benkard261532a2021-12-12 20:09:27 +0100277
278 assertEquals(
Matthias Andreas Benkard35f7a202021-12-14 19:29:26 +0100279 List.of((byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07),
Matthias Andreas Benkard261532a2021-12-12 20:09:27 +0100280 decoder.decode(ByteBuffer.wrap(data)));
281 }
282
283 @Test
Matthias Andreas Benkard4e8423d2021-12-19 22:56:09 +0100284 void testPrimitiveByteArray() {
285 var data = new byte[] {0x04, 0x05, 0x06, 0x07};
286
287 var decoder = Decoder.ofByteArray();
288
289 assertArrayEquals(data, decoder.decode(ByteBuffer.wrap(data)));
290 }
291
292 @Test
293 void testPrimitiveByteArrayRecord() {
294 var data = new byte[] {0x04, 0x05, 0x06, 0x07};
295
296 record TestRecord(byte[] bytes) {}
297
298 var decoder = Decoder.ofStructure(TestRecord.class, Decoder.ofByteArray());
299
300 assertArrayEquals(data, decoder.decode(ByteBuffer.wrap(data)).bytes());
301 }
302
303 @Test
Matthias Andreas Benkard261532a2021-12-12 20:09:27 +0100304 void testIntegerArray() {
305 var data = new byte[] {0x04, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00};
306
Matthias Andreas Benkard35f7a202021-12-14 19:29:26 +0100307 var decoder = Decoder.ofArray(Decoder.ofInt().withByteOrder(LITTLE_ENDIAN));
Matthias Andreas Benkard261532a2021-12-12 20:09:27 +0100308
Matthias Andreas Benkard35f7a202021-12-14 19:29:26 +0100309 assertEquals(List.of(4, 258), decoder.decode(ByteBuffer.wrap(data)));
Matthias Andreas Benkard261532a2021-12-12 20:09:27 +0100310 }
311
312 @Test
Matthias Andreas Benkardcd924f62021-12-28 00:46:06 +0100313 void testDictionaryEntryAsMapEntry() {
314 var data =
315 new byte[] {0x61, 0x20, 0x6B, 0x65, 0x79, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x06};
316
317 var decoder =
318 Decoder.ofDictionaryEntry(
319 Decoder.ofString(UTF_8), Decoder.ofInt().withByteOrder(LITTLE_ENDIAN));
320 assertEquals(Map.entry("a key", 514), decoder.decode(ByteBuffer.wrap(data)));
321 }
322
323 @Test
324 void testDictionaryEntryAsRecord() {
Matthias Andreas Benkard261532a2021-12-12 20:09:27 +0100325 var data =
326 new byte[] {0x61, 0x20, 0x6B, 0x65, 0x79, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x06};
327
Matthias Andreas Benkard35f7a202021-12-14 19:29:26 +0100328 record TestEntry(String key, int value) {}
Matthias Andreas Benkard261532a2021-12-12 20:09:27 +0100329
330 var decoder =
331 Decoder.ofStructure(
Matthias Andreas Benkard35f7a202021-12-14 19:29:26 +0100332 TestEntry.class, Decoder.ofString(UTF_8), Decoder.ofInt().withByteOrder(LITTLE_ENDIAN));
333 assertEquals(new TestEntry("a key", 514), decoder.decode(ByteBuffer.wrap(data)));
Matthias Andreas Benkard261532a2021-12-12 20:09:27 +0100334 }
Matthias Andreas Benkarde5a5c752021-12-15 19:53:55 +0100335
336 @Test
337 void testPaddedPrimitives() {
338 var data =
339 new byte[] {
340 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
341 0x00, 0x40, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
342 };
343
344 record TestRecord(short s, long l, double d) {}
345
346 var decoder =
347 Decoder.ofStructure(
348 TestRecord.class,
349 Decoder.ofShort().withByteOrder(BIG_ENDIAN),
350 Decoder.ofLong().withByteOrder(LITTLE_ENDIAN),
351 Decoder.ofDouble());
352 assertEquals(new TestRecord((short) 1, 2, 3.25), decoder.decode(ByteBuffer.wrap(data)));
353 }
354
355 @Test
356 void testEmbeddedMaybe() {
357 var data = new byte[] {0x01, 0x01};
358
359 record TestRecord(Optional<Byte> set, Optional<Byte> unset) {}
360
361 var decoder =
362 Decoder.ofStructure(
363 TestRecord.class, Decoder.ofMaybe(Decoder.ofByte()), Decoder.ofMaybe(Decoder.ofByte()));
364 assertEquals(
365 new TestRecord(Optional.of((byte) 1), Optional.empty()),
366 decoder.decode(ByteBuffer.wrap(data)));
367 }
368
369 @Test
370 void testRecordComponentMismatch() {
371 record TestRecord(Optional<Byte> set) {}
372
373 var maybeDecoder = Decoder.ofMaybe(Decoder.ofByte());
374 assertThrows(
375 IllegalArgumentException.class,
376 () -> Decoder.ofStructure(TestRecord.class, maybeDecoder, maybeDecoder));
377 }
378
379 @Test
380 void testTrivialRecord() {
381 var data = new byte[] {0x00};
382
383 record TestRecord() {}
384
385 var decoder = Decoder.ofStructure(TestRecord.class);
386 assertEquals(new TestRecord(), decoder.decode(ByteBuffer.wrap(data)));
387 }
388
389 @Test
390 void testTwoElementTrivialRecordArray() {
391 var data = new byte[] {0x00, 0x00};
392
393 record TestRecord() {}
394
395 var decoder = Decoder.ofArray(Decoder.ofStructure(TestRecord.class));
396 assertEquals(
397 List.of(new TestRecord(), new TestRecord()), decoder.decode(ByteBuffer.wrap(data)));
398 }
399
400 @Test
401 void testSingletonTrivialRecordArray() {
402 var data = new byte[] {0x00};
403
404 record TestRecord() {}
405
406 var decoder = Decoder.ofArray(Decoder.ofStructure(TestRecord.class));
407 assertEquals(List.of(new TestRecord()), decoder.decode(ByteBuffer.wrap(data)));
408 }
409
410 @Test
411 void testEmptyTrivialRecordArray() {
412 var data = new byte[] {};
413
414 record TestRecord() {}
415
416 var decoder = Decoder.ofArray(Decoder.ofStructure(TestRecord.class));
417 assertEquals(List.of(), decoder.decode(ByteBuffer.wrap(data)));
418 }
419
420 @Test
421 void testVariantArray() {
422 var data = new byte[] {};
423
424 record TestRecord() {}
425
426 var decoder = Decoder.ofArray(Decoder.ofStructure(TestRecord.class));
427 assertEquals(List.of(), decoder.decode(ByteBuffer.wrap(data)));
428 }
429
430 @Test
431 void testInvalidVariantSignature() {
432 var data = new byte[] {0x00, 0x00, 0x2E};
433
434 var decoder = Decoder.ofVariant();
435 assertThrows(IllegalArgumentException.class, () -> decoder.decode(ByteBuffer.wrap(data)));
436 }
437
438 @Test
439 void testMissingVariantSignature() {
440 var data = new byte[] {0x01};
441
442 var decoder = Decoder.ofVariant();
443 assertThrows(IllegalArgumentException.class, () -> decoder.decode(ByteBuffer.wrap(data)));
444 }
445
446 @Test
Matthias Andreas Benkard31c61e72021-12-16 20:06:39 +0100447 void testSimpleVariantRecord() throws ParseException {
Matthias Andreas Benkarde5a5c752021-12-15 19:53:55 +0100448 // signature: "(bynqiuxtdsogvmiai)"
449 var data =
450 new byte[] {
451 0x01, // b
452 0x02, // y
453 0x00, 0x03, // n
454 0x00, 0x04, // q
455 0x00, 0x00, // (padding)
456 0x00, 0x00, 0x00, 0x05, // i
457 0x00, 0x00, 0x00, 0x06, // u
458 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, // x
459 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, // t
460 0x40, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // d
461 0x68, 0x69, 0x00, // s
462 0x68, 0x69, 0x00, // o
463 0x68, 0x69, 0x00, // g
464 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (padding)
465 0x00, 0x00, 0x00, 0x09, 0x00, 0x69, // v
466 0x00, 0x00, // (padding)
467 0x00, 0x00, 0x00, 0x0a, // mi
468 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, // ai
469 68, 62, 49, 46, 43, // framing offsets
470 0x00, 0x28, 0x62, 0x79, 0x6E, 0x71, 0x69, 0x75, 0x78, 0x74, 0x64, 0x73, 0x6F, 0x67, 0x76,
471 0x6D, 0x69, 0x61, 0x69, 0x29
472 };
473
474 var decoder = Decoder.ofVariant();
475 assertArrayEquals(
476 new Object[] {
477 true,
478 (byte) 2,
479 (short) 3,
480 (short) 4,
481 (int) 5,
482 (int) 6,
483 (long) 7,
484 (long) 8,
485 (double) 3.25,
486 "hi",
487 "hi",
488 "hi",
Matthias Andreas Benkard31c61e72021-12-16 20:06:39 +0100489 new Variant(Signature.parse("i"), 9),
Matthias Andreas Benkarde5a5c752021-12-15 19:53:55 +0100490 Optional.of(10),
491 List.of(11, 12)
492 },
Matthias Andreas Benkard31c61e72021-12-16 20:06:39 +0100493 (Object[]) decoder.decode(ByteBuffer.wrap(data)).value());
494 }
495
496 @Test
497 void testSignatureString() throws ParseException {
498 var data =
499 new byte[] {
500 0x28, 0x62, 0x79, 0x6E, 0x71, 0x69, 0x75, 0x78, 0x74, 0x64, 0x73, 0x6F, 0x67, 0x76, 0x6D,
501 0x69, 0x61, 0x69, 0x29
502 };
503
504 var signature = Signature.parse(ByteBuffer.wrap(data));
505 assertEquals("(bynqiuxtdsogvmiai)", signature.toString());
Matthias Andreas Benkarde5a5c752021-12-15 19:53:55 +0100506 }
Matthias Andreas Benkard4e8423d2021-12-19 22:56:09 +0100507
508 @Test
509 void testMap() {
510 var data = new byte[] {0x0A, 0x0B, 0x0C};
511 var decoder = Decoder.ofByteArray().map(bytes -> bytes.length);
512 assertEquals(3, decoder.decode(ByteBuffer.wrap(data)));
513 }
Matthias Andreas Benkard44df94e2021-12-30 18:43:33 +0100514
515 @Test
516 void testContramap() {
517 var data = new byte[] {0x0A, 0x0B, 0x0C};
518 var decoder = Decoder.ofByteArray().contramap(bytes -> bytes.slice(1, 1));
519 assertArrayEquals(new byte[] {0x0B}, decoder.decode(ByteBuffer.wrap(data)));
520 }
521
522 @Test
523 void testPredicateTrue() {
524 var data = new byte[] {0x00, 0x01, 0x00};
525 var innerDecoder = Decoder.ofShort().contramap(bytes -> bytes.slice(1, 2).order(bytes.order()));
526 var decoder =
527 Decoder.ofPredicate(
528 byteBuffer -> byteBuffer.get(0) == 0,
529 innerDecoder.withByteOrder(LITTLE_ENDIAN),
530 innerDecoder.withByteOrder(BIG_ENDIAN));
531 assertEquals((short) 1, decoder.decode(ByteBuffer.wrap(data)));
532 }
533
534 @Test
535 void testPredicateFalse() {
536 var data = new byte[] {0x01, 0x01, 0x00};
537 var innerDecoder = Decoder.ofShort().contramap(bytes -> bytes.slice(1, 2).order(bytes.order()));
538 var decoder =
539 Decoder.ofPredicate(
540 byteBuffer -> byteBuffer.get(0) == 0,
541 innerDecoder.withByteOrder(LITTLE_ENDIAN),
542 innerDecoder.withByteOrder(BIG_ENDIAN));
543 assertEquals((short) 256, decoder.decode(ByteBuffer.wrap(data)));
544 }
545
546 @Test
547 void testByteOrder() {
548 var data =
549 new byte[] {
550 0x01, 0x00, 0x02, 0x00, 0x00, 0x03, 0x00, 0x04, 0x05, 0x00, 0x00, 0x06, 0x00, 0x07, 0x08,
551 0x00
552 };
553
554 record TestChild(short s1, short s2) {}
555 record TestParent(TestChild tc1, TestChild tc2, TestChild tc3, TestChild tc4) {}
556
557 var decoder =
558 Decoder.ofStructure(
559 TestParent.class,
560 Decoder.ofStructure(TestChild.class, Decoder.ofShort(), Decoder.ofShort())
561 .withByteOrder(LITTLE_ENDIAN),
562 Decoder.ofStructure(TestChild.class, Decoder.ofShort(), Decoder.ofShort())
563 .withByteOrder(BIG_ENDIAN),
564 Decoder.ofStructure(
565 TestChild.class,
566 Decoder.ofShort().withByteOrder(LITTLE_ENDIAN),
567 Decoder.ofShort())
568 .withByteOrder(BIG_ENDIAN),
569 Decoder.ofStructure(
570 TestChild.class, Decoder.ofShort().withByteOrder(BIG_ENDIAN), Decoder.ofShort())
571 .withByteOrder(LITTLE_ENDIAN));
572
573 assertEquals(
574 new TestParent(
575 new TestChild((short) 1, (short) 2),
576 new TestChild((short) 3, (short) 4),
577 new TestChild((short) 5, (short) 6),
578 new TestChild((short) 7, (short) 8)),
579 decoder.decode(ByteBuffer.wrap(data)));
580 }
Matthias Andreas Benkard261532a2021-12-12 20:09:27 +0100581}