blob: 4deb8bcb1be7c069c64b9844eb10c945c881dc5d [file] [log] [blame]
Matthias Andreas Benkard261532a2021-12-12 20:09:27 +01001package eu.mulk.jgvariant.core;
2
3import static java.nio.ByteOrder.LITTLE_ENDIAN;
4import static java.nio.charset.StandardCharsets.UTF_8;
5import static org.junit.jupiter.api.Assertions.assertEquals;
6
7import eu.mulk.jgvariant.core.Value.Array;
8import eu.mulk.jgvariant.core.Value.Bool;
9import eu.mulk.jgvariant.core.Value.Int32;
10import eu.mulk.jgvariant.core.Value.Int8;
11import eu.mulk.jgvariant.core.Value.Maybe;
12import eu.mulk.jgvariant.core.Value.Str;
13import eu.mulk.jgvariant.core.Value.Structure;
14import java.nio.ByteBuffer;
15import java.util.List;
16import java.util.Optional;
17import org.junit.jupiter.api.Test;
18
19/**
20 * Tests based on the examples given in <a
21 * href="https://people.gnome.org/~desrt/gvariant-serialisation.pdf">~desrt/gvariant-serialisation.pdf</a>.
22 */
23class DecoderTest {
24
25 @Test
26 void testString() {
27 var data = new byte[] {0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x00};
28 var decoder = Decoder.ofStr(UTF_8);
29 assertEquals(new Str("hello world"), decoder.decode(ByteBuffer.wrap(data)));
30 }
31
32 @Test
33 void testMaybe() {
34 var data =
35 new byte[] {0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x00, 0x00};
36 var decoder = Decoder.ofMaybe(Decoder.ofStr(UTF_8));
37 assertEquals(
38 new Maybe<>(Optional.of(new Str("hello world"))), decoder.decode(ByteBuffer.wrap(data)));
39 }
40
41 @Test
42 void testBooleanArray() {
43 var data = new byte[] {0x01, 0x00, 0x00, 0x01, 0x01};
44 var decoder = Decoder.ofArray(Decoder.ofBoolean());
45 assertEquals(
46 new Array<>(List.of(Bool.TRUE, Bool.FALSE, Bool.FALSE, Bool.TRUE, Bool.TRUE)),
47 decoder.decode(ByteBuffer.wrap(data)));
48 }
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
57 record TestRecord(Str s, Int32 i) {}
58
59 var decoder = Decoder.ofStructure(TestRecord.class, Decoder.ofStr(UTF_8), Decoder.ofInt32());
60 assertEquals(
61 new Structure<>(new TestRecord(new Str("foo"), new Int32(-1))),
62 decoder.decode(ByteBuffer.wrap(data)));
63 }
64
65 @Test
66 void testComplexStructureArray() {
67 var data =
68 new byte[] {
69 0x68,
70 0x69,
71 0x00,
72 0x00,
73 (byte) 0xfe,
74 (byte) 0xff,
75 (byte) 0xff,
76 (byte) 0xff,
77 0x03,
78 0x00,
79 0x00,
80 0x00,
81 0x62,
82 0x79,
83 0x65,
84 0x00,
85 (byte) 0xff,
86 (byte) 0xff,
87 (byte) 0xff,
88 (byte) 0xff,
89 0x04,
90 0x09,
91 0x15
92 };
93
94 record TestRecord(Str s, Int32 i) {}
95
96 var decoder =
97 Decoder.ofArray(
98 Decoder.ofStructure(
99 TestRecord.class,
100 Decoder.ofStr(UTF_8),
101 Decoder.ofInt32().withByteOrder(LITTLE_ENDIAN)));
102 assertEquals(
103 new Array<>(
104 List.of(
105 new Structure<>(new TestRecord(new Str("hi"), new Int32(-2))),
106 new Structure<>(new TestRecord(new Str("bye"), new Int32(-1))))),
107 decoder.decode(ByteBuffer.wrap(data)));
108 }
109
110 @Test
111 void testStringArray() {
112 var data =
113 new byte[] {
114 0x69, 0x00, 0x63, 0x61, 0x6E, 0x00, 0x68, 0x61, 0x73, 0x00, 0x73, 0x74, 0x72, 0x69, 0x6E,
115 0x67, 0x73, 0x3F, 0x00, 0x02, 0x06, 0x0a, 0x13
116 };
117 var decoder = Decoder.ofArray(Decoder.ofStr(UTF_8));
118 assertEquals(
119 new Array<>(List.of(new Str("i"), new Str("can"), new Str("has"), new Str("strings?"))),
120 decoder.decode(ByteBuffer.wrap(data)));
121 }
122
123 @Test
124 void testNestedStructure() {
125 var data =
126 new byte[] {
127 0x69, 0x63, 0x61, 0x6E, 0x00, 0x68, 0x61, 0x73, 0x00, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67,
128 0x73, 0x3F, 0x00, 0x04, 0x0d, 0x05
129 };
130
131 record TestChild(Int8 b, Str s) {}
132 record TestParent(Structure<TestChild> tc, Array<Str> as) {}
133
134 var decoder =
135 Decoder.ofStructure(
136 TestParent.class,
137 Decoder.ofStructure(TestChild.class, Decoder.ofInt8(), Decoder.ofStr(UTF_8)),
138 Decoder.ofArray(Decoder.ofStr(UTF_8)));
139
140 assertEquals(
141 new Structure<>(
142 new TestParent(
143 new Structure<>(new TestChild(new Int8((byte) 0x69), new Str("can"))),
144 new Array<>(List.of(new Str("has"), new Str("strings?"))))),
145 decoder.decode(ByteBuffer.wrap(data)));
146 }
147
148 @Test
149 void testSimpleStructure() {
150 var data = new byte[] {0x60, 0x70};
151
152 record TestRecord(Int8 b1, Int8 b2) {}
153
154 var decoder =
155 Decoder.ofStructure(
156 TestRecord.class,
157 Decoder.ofInt8().withByteOrder(LITTLE_ENDIAN),
158 Decoder.ofInt8().withByteOrder(LITTLE_ENDIAN));
159
160 assertEquals(
161 new Structure<>(new TestRecord(new Int8((byte) 0x60), new Int8((byte) 0x70))),
162 decoder.decode(ByteBuffer.wrap(data)));
163 }
164
165 @Test
166 void testPaddedStructureRight() {
167 var data = new byte[] {0x60, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00};
168
169 record TestRecord(Int32 b1, Int8 b2) {}
170
171 var decoder =
172 Decoder.ofStructure(
173 TestRecord.class,
174 Decoder.ofInt32().withByteOrder(LITTLE_ENDIAN),
175 Decoder.ofInt8().withByteOrder(LITTLE_ENDIAN));
176
177 assertEquals(
178 new Structure<>(new TestRecord(new Int32(0x60), new Int8((byte) 0x70))),
179 decoder.decode(ByteBuffer.wrap(data)));
180 }
181
182 @Test
183 void testPaddedStructureLeft() {
184 var data = new byte[] {0x60, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00};
185
186 record TestRecord(Int8 b1, Int32 b2) {}
187
188 var decoder =
189 Decoder.ofStructure(
190 TestRecord.class,
191 Decoder.ofInt8().withByteOrder(LITTLE_ENDIAN),
192 Decoder.ofInt32().withByteOrder(LITTLE_ENDIAN));
193
194 assertEquals(
195 new Structure<>(new TestRecord(new Int8((byte) 0x60), new Int32(0x70))),
196 decoder.decode(ByteBuffer.wrap(data)));
197 }
198
199 @Test
200 void testSimpleStructureArray() {
201 var data =
202 new byte[] {
203 0x60,
204 0x00,
205 0x00,
206 0x00,
207 0x70,
208 0x00,
209 0x00,
210 0x00,
211 (byte) 0x88,
212 0x02,
213 0x00,
214 0x00,
215 (byte) 0xF7,
216 0x00,
217 0x00,
218 0x00
219 };
220
221 record TestRecord(Int32 b1, Int8 b2) {}
222
223 var decoder =
224 Decoder.ofArray(
225 Decoder.ofStructure(
226 TestRecord.class,
227 Decoder.ofInt32().withByteOrder(LITTLE_ENDIAN),
228 Decoder.ofInt8().withByteOrder(LITTLE_ENDIAN)));
229
230 assertEquals(
231 new Array<>(
232 List.of(
233 new Structure<>(new TestRecord(new Int32(96), new Int8((byte) 0x70))),
234 new Structure<>(new TestRecord(new Int32(648), new Int8((byte) 0xf7))))),
235 decoder.decode(ByteBuffer.wrap(data)));
236 }
237
238 @Test
239 void testByteArray() {
240 var data = new byte[] {0x04, 0x05, 0x06, 0x07};
241
242 var decoder = Decoder.ofArray(Decoder.ofInt8());
243
244 assertEquals(
245 new Array<>(
246 List.of(
247 new Int8((byte) 0x04),
248 new Int8((byte) 0x05),
249 new Int8((byte) 0x06),
250 new Int8((byte) 0x07))),
251 decoder.decode(ByteBuffer.wrap(data)));
252 }
253
254 @Test
255 void testIntegerArray() {
256 var data = new byte[] {0x04, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00};
257
258 var decoder = Decoder.ofArray(Decoder.ofInt32().withByteOrder(LITTLE_ENDIAN));
259
260 assertEquals(
261 new Array<>(List.of(new Int32(4), new Int32(258))), decoder.decode(ByteBuffer.wrap(data)));
262 }
263
264 @Test
265 void testDictionaryEntry() {
266 var data =
267 new byte[] {0x61, 0x20, 0x6B, 0x65, 0x79, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x06};
268
269 record TestEntry(Str key, Int32 value) {}
270
271 var decoder =
272 Decoder.ofStructure(
273 TestEntry.class, Decoder.ofStr(UTF_8), Decoder.ofInt32().withByteOrder(LITTLE_ENDIAN));
274 assertEquals(
275 new Structure<>(new TestEntry(new Str("a key"), new Int32(514))),
276 decoder.decode(ByteBuffer.wrap(data)));
277 }
278}