1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.juneau.msgpack;
18
19 import static org.apache.juneau.commons.utils.CollectionUtils.*;
20 import static org.apache.juneau.commons.utils.StringUtils.*;
21 import static org.junit.jupiter.api.Assertions.*;
22
23 import org.apache.juneau.*;
24 import org.apache.juneau.collections.*;
25 import org.junit.jupiter.api.*;
26
27 class MsgPackSerializerTest extends TestBase {
28
29 //====================================================================================================
30 // testBasic
31 //====================================================================================================
32 @Test void a01_basic() throws Exception {
33
34 test(null, "C0");
35
36 test(false, "C2");
37 test(true, "C3");
38
39 // positive fixnum stores 7-bit positive integer
40 // +--------+
41 // |0XXXXXXX|
42 // +--------+
43 //
44 // int 8 stores a 8-bit signed integer
45 // +--------+--------+
46 // | 0xd0 |ZZZZZZZZ|
47 // +--------+--------+
48 //
49 // int 16 stores a 16-bit big-endian signed integer
50 // +--------+--------+--------+
51 // | 0xd1 |ZZZZZZZZ|ZZZZZZZZ|
52 // +--------+--------+--------+
53 //
54 // int 32 stores a 32-bit big-endian signed integer
55 // +--------+--------+--------+--------+--------+
56 // | 0xd2 |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|
57 // +--------+--------+--------+--------+--------+
58 //
59 // int 64 stores a 64-bit big-endian signed integer
60 // +--------+--------+--------+--------+--------+--------+--------+--------+--------+
61 // | 0xd3 |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|
62 // +--------+--------+--------+--------+--------+--------+--------+--------+--------+
63 //
64 // negative fixnum stores 5-bit negative integer
65 // +--------+
66 // |111YYYYY|
67 // +--------+
68 //
69 // * 0XXXXXXX is 8-bit unsigned integer
70 // * 111YYYYY is 8-bit signed integer
71 //
72
73 test(0, "00");
74 test(0x7F, "7F");
75
76 test(0x80, "D1 00 80");
77 test(0x0100, "D1 01 00");
78 test(0x7FFF, "D1 7F FF");
79 test(0x8000, "D2 00 00 80 00");
80 test(0xFFFF, "D2 00 00 FF FF");
81 test(0x00010000, "D2 00 01 00 00");
82 test(Long.decode("0x000000007FFFFFFF"), "D2 7F FF FF FF");
83 test(Long.decode("0x0000000080000000"), "D3 00 00 00 00 80 00 00 00");
84 test(Long.decode("0x0000000100000000"), "D3 00 00 00 01 00 00 00 00");
85 test(Long.decode("0x7FFFFFFFFFFFFFFF"), "D3 7F FF FF FF FF FF FF FF");
86 test(-Long.decode("0x7FFFFFFFFFFFFFFF").longValue(), "D3 80 00 00 00 00 00 00 01");
87 test(-1, "E1");
88 test(-63, "FF");
89 test(-64, "D0 C0");
90
91 test(-0x7F, "D0 81");
92 test(-0x80, "D1 FF 80");
93 test(-0x0100, "D1 FF 00");
94 test(-0x7FFF, "D1 80 01");
95 test(-0x8000, "D2 FF FF 80 00");
96 test(-0xFFFF, "D2 FF FF 00 01");
97 test(-0x00010000, "D2 FF FF 00 00");
98 test(-Long.decode("0x000000007FFFFFFF").longValue(), "D2 80 00 00 01");
99 test(-Long.decode("0x0000000080000000").longValue(), "D3 FF FF FF FF 80 00 00 00");
100 test(-Long.decode("0x0000000100000000").longValue(), "D3 FF FF FF FF 00 00 00 00");
101 test(-Long.decode("0x7FFFFFFFFFFFFFFF").longValue(), "D3 80 00 00 00 00 00 00 01");
102
103 // float 32 stores a floating point number in IEEE 754 single precision floating point number format:
104 // +--------+--------+--------+--------+--------+
105 // | 0xca |XXXXXXXX|XXXXXXXX|XXXXXXXX|XXXXXXXX|
106 // +--------+--------+--------+--------+--------+
107 //
108 // float 64 stores a floating point number in IEEE 754 double precision floating point number format:
109 // +--------+--------+--------+--------+--------+--------+--------+--------+--------+
110 // | 0xcb |YYYYYYYY|YYYYYYYY|YYYYYYYY|YYYYYYYY|YYYYYYYY|YYYYYYYY|YYYYYYYY|YYYYYYYY|
111 // +--------+--------+--------+--------+--------+--------+--------+--------+--------+
112 //
113 // where
114 // * XXXXXXXX_XXXXXXXX_XXXXXXXX_XXXXXXXX is a big-endian IEEE 754 single precision floating point number.
115 // Extension of precision from single-precision to double-precision does not lose precision.
116 // * YYYYYYYY_YYYYYYYY_YYYYYYYY_YYYYYYYY_YYYYYYYY_YYYYYYYY_YYYYYYYY_YYYYYYYY is a big-endian
117 // IEEE 754 double precision floating point number
118
119 test(0f, "CA 00 00 00 00");
120 test(1f, "CA 3F 80 00 00");
121 test(-1f, "CA BF 80 00 00");
122 test(1d, "CB 3F F0 00 00 00 00 00 00");
123 test(-1d, "CB BF F0 00 00 00 00 00 00");
124
125 // fixstr stores a byte array whose length is upto 31 bytes:
126 // +--------+========+
127 // |101XXXXX| data |
128 // +--------+========+
129 //
130 // str 8 stores a byte array whose length is upto (2^8)-1 bytes:
131 // +--------+--------+========+
132 // | 0xd9 |YYYYYYYY| data |
133 // +--------+--------+========+
134 //
135 // str 16 stores a byte array whose length is upto (2^16)-1 bytes:
136 // +--------+--------+--------+========+
137 // | 0xda |ZZZZZZZZ|ZZZZZZZZ| data |
138 // +--------+--------+--------+========+
139 //
140 // str 32 stores a byte array whose length is upto (2^32)-1 bytes:
141 // +--------+--------+--------+--------+--------+========+
142 // | 0xdb |AAAAAAAA|AAAAAAAA|AAAAAAAA|AAAAAAAA| data |
143 // +--------+--------+--------+--------+--------+========+
144 //
145 // where
146 // * XXXXX is a 5-bit unsigned integer which represents N
147 // * YYYYYYYY is a 8-bit unsigned integer which represents N
148 // * ZZZZZZZZ_ZZZZZZZZ is a 16-bit big-endian unsigned integer which represents N
149 // * AAAAAAAA_AAAAAAAA_AAAAAAAA_AAAAAAAA is a 32-bit big-endian unsigned integer which represents N
150 // * N is the length of data
151
152 test("", "A0");
153 test("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "BF 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61");
154 test("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "D9 20 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61");
155
156 // fixarray stores an array whose length is upto 15 elements:
157 // +--------+~~~~~~~~~~~~~~~~~+
158 // |1001XXXX| N objects |
159 // +--------+~~~~~~~~~~~~~~~~~+
160 //
161 // array 16 stores an array whose length is upto (2^16)-1 elements:
162 // +--------+--------+--------+~~~~~~~~~~~~~~~~~+
163 // | 0xdc |YYYYYYYY|YYYYYYYY| N objects |
164 // +--------+--------+--------+~~~~~~~~~~~~~~~~~+
165 //
166 // array 32 stores an array whose length is upto (2^32)-1 elements:
167 // +--------+--------+--------+--------+--------+~~~~~~~~~~~~~~~~~+
168 // | 0xdd |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ| N objects |
169 // +--------+--------+--------+--------+--------+~~~~~~~~~~~~~~~~~+
170 //
171 // where
172 // * XXXX is a 4-bit unsigned integer which represents N
173 // * YYYYYYYY_YYYYYYYY is a 16-bit big-endian unsigned integer which represents N
174 // * ZZZZZZZZ_ZZZZZZZZ_ZZZZZZZZ_ZZZZZZZZ is a 32-bit big-endian unsigned integer which represents N
175 // N is the size of a array
176
177 test(ints(), "90");
178 test(ints(1), "91 01");
179 test(ints(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1), "9F 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01");
180 test(ints(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1), "DC 00 10 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01");
181
182 // fixmap stores a map whose length is upto 15 elements
183 // +--------+~~~~~~~~~~~~~~~~~+
184 // |1000XXXX| N*2 objects |
185 // +--------+~~~~~~~~~~~~~~~~~+
186 //
187 // map 16 stores a map whose length is upto (2^16)-1 elements
188 // +--------+--------+--------+~~~~~~~~~~~~~~~~~+
189 // | 0xde |YYYYYYYY|YYYYYYYY| N*2 objects |
190 // +--------+--------+--------+~~~~~~~~~~~~~~~~~+
191 //
192 // map 32 stores a map whose length is upto (2^32)-1 elements
193 // +--------+--------+--------+--------+--------+~~~~~~~~~~~~~~~~~+
194 // | 0xdf |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ| N*2 objects |
195 // +--------+--------+--------+--------+--------+~~~~~~~~~~~~~~~~~+
196 //
197 // where
198 // * XXXX is a 4-bit unsigned integer which represents N
199 // * YYYYYYYY_YYYYYYYY is a 16-bit big-endian unsigned integer which represents N
200 // * ZZZZZZZZ_ZZZZZZZZ_ZZZZZZZZ_ZZZZZZZZ is a 32-bit big-endian unsigned integer which represents N
201 // * N is the size of a map
202 // * odd elements in objects are keys of a map
203 // * the next element of a key is its associated value
204
205 test(JsonMap.ofJson("{}"), "80");
206 test(JsonMap.ofJson("{1:1}"), "81 A1 31 01");
207 test(JsonMap.ofJson("{1:1,2:1,3:1,4:1,5:1,6:1,7:1,8:1,9:1,a:1,b:1,c:1,d:1,e:1,f:1}"), "8F A1 31 01 A1 32 01 A1 33 01 A1 34 01 A1 35 01 A1 36 01 A1 37 01 A1 38 01 A1 39 01 A1 61 01 A1 62 01 A1 63 01 A1 64 01 A1 65 01 A1 66 01");
208 test(JsonMap.ofJson("{1:1,2:1,3:1,4:1,5:1,6:1,7:1,8:1,9:1,a:1,b:1,c:1,d:1,e:1,f:1,g:1}"), "DE 00 10 A1 31 01 A1 32 01 A1 33 01 A1 34 01 A1 35 01 A1 36 01 A1 37 01 A1 38 01 A1 39 01 A1 61 01 A1 62 01 A1 63 01 A1 64 01 A1 65 01 A1 66 01 A1 67 01");
209 }
210
211 public static class Person {
212 public String name = "John Smith";
213 public int age = 21;
214 }
215
216 private static void test(Object input, String expected) throws Exception {
217 var b = MsgPackSerializer.DEFAULT.serialize(input);
218 assertEquals(expected, toSpacedHex(b));
219 }
220 }