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.junit.jupiter.api.Assertions.*;
20
21 import org.apache.juneau.*;
22 import org.apache.juneau.collections.*;
23 import org.apache.juneau.common.utils.*;
24 import org.junit.jupiter.api.*;
25
26 class MsgPackSerializerTest extends TestBase {
27
28 //====================================================================================================
29 // testBasic
30 //====================================================================================================
31 @Test void a01_basic() throws Exception {
32
33 test(null, "C0");
34
35 test(false, "C2");
36 test(true, "C3");
37
38 // positive fixnum stores 7-bit positive integer
39 // +--------+
40 // |0XXXXXXX|
41 // +--------+
42 //
43 // int 8 stores a 8-bit signed integer
44 // +--------+--------+
45 // | 0xd0 |ZZZZZZZZ|
46 // +--------+--------+
47 //
48 // int 16 stores a 16-bit big-endian signed integer
49 // +--------+--------+--------+
50 // | 0xd1 |ZZZZZZZZ|ZZZZZZZZ|
51 // +--------+--------+--------+
52 //
53 // int 32 stores a 32-bit big-endian signed integer
54 // +--------+--------+--------+--------+--------+
55 // | 0xd2 |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|
56 // +--------+--------+--------+--------+--------+
57 //
58 // int 64 stores a 64-bit big-endian signed integer
59 // +--------+--------+--------+--------+--------+--------+--------+--------+--------+
60 // | 0xd3 |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|
61 // +--------+--------+--------+--------+--------+--------+--------+--------+--------+
62 //
63 // negative fixnum stores 5-bit negative integer
64 // +--------+
65 // |111YYYYY|
66 // +--------+
67 //
68 // * 0XXXXXXX is 8-bit unsigned integer
69 // * 111YYYYY is 8-bit signed integer
70 //
71
72 test(0, "00");
73 test(0x7F, "7F");
74
75 test(0x80, "D1 00 80");
76 test(0x0100, "D1 01 00");
77 test(0x7FFF, "D1 7F FF");
78 test(0x8000, "D2 00 00 80 00");
79 test(0xFFFF, "D2 00 00 FF FF");
80 test(0x00010000, "D2 00 01 00 00");
81 test(Long.decode("0x000000007FFFFFFF"), "D2 7F FF FF FF");
82 test(Long.decode("0x0000000080000000"), "D3 00 00 00 00 80 00 00 00");
83 test(Long.decode("0x0000000100000000"), "D3 00 00 00 01 00 00 00 00");
84 test(Long.decode("0x7FFFFFFFFFFFFFFF"), "D3 7F FF FF FF FF FF FF FF");
85 test(-Long.decode("0x7FFFFFFFFFFFFFFF").longValue(), "D3 80 00 00 00 00 00 00 01");
86 test(-1, "E1");
87 test(-63, "FF");
88 test(-64, "D0 C0");
89
90 test(-0x7F, "D0 81");
91 test(-0x80, "D1 FF 80");
92 test(-0x0100, "D1 FF 00");
93 test(-0x7FFF, "D1 80 01");
94 test(-0x8000, "D2 FF FF 80 00");
95 test(-0xFFFF, "D2 FF FF 00 01");
96 test(-0x00010000, "D2 FF FF 00 00");
97 test(-Long.decode("0x000000007FFFFFFF").longValue(), "D2 80 00 00 01");
98 test(-Long.decode("0x0000000080000000").longValue(), "D3 FF FF FF FF 80 00 00 00");
99 test(-Long.decode("0x0000000100000000").longValue(), "D3 FF FF FF FF 00 00 00 00");
100 test(-Long.decode("0x7FFFFFFFFFFFFFFF").longValue(), "D3 80 00 00 00 00 00 00 01");
101
102 // float 32 stores a floating point number in IEEE 754 single precision floating point number format:
103 // +--------+--------+--------+--------+--------+
104 // | 0xca |XXXXXXXX|XXXXXXXX|XXXXXXXX|XXXXXXXX|
105 // +--------+--------+--------+--------+--------+
106 //
107 // float 64 stores a floating point number in IEEE 754 double precision floating point number format:
108 // +--------+--------+--------+--------+--------+--------+--------+--------+--------+
109 // | 0xcb |YYYYYYYY|YYYYYYYY|YYYYYYYY|YYYYYYYY|YYYYYYYY|YYYYYYYY|YYYYYYYY|YYYYYYYY|
110 // +--------+--------+--------+--------+--------+--------+--------+--------+--------+
111 //
112 // where
113 // * XXXXXXXX_XXXXXXXX_XXXXXXXX_XXXXXXXX is a big-endian IEEE 754 single precision floating point number.
114 // Extension of precision from single-precision to double-precision does not lose precision.
115 // * YYYYYYYY_YYYYYYYY_YYYYYYYY_YYYYYYYY_YYYYYYYY_YYYYYYYY_YYYYYYYY_YYYYYYYY is a big-endian
116 // IEEE 754 double precision floating point number
117
118 test(0f, "CA 00 00 00 00");
119 test(1f, "CA 3F 80 00 00");
120 test(-1f, "CA BF 80 00 00");
121 test(1d, "CB 3F F0 00 00 00 00 00 00");
122 test(-1d, "CB BF F0 00 00 00 00 00 00");
123
124 // fixstr stores a byte array whose length is upto 31 bytes:
125 // +--------+========+
126 // |101XXXXX| data |
127 // +--------+========+
128 //
129 // str 8 stores a byte array whose length is upto (2^8)-1 bytes:
130 // +--------+--------+========+
131 // | 0xd9 |YYYYYYYY| data |
132 // +--------+--------+========+
133 //
134 // str 16 stores a byte array whose length is upto (2^16)-1 bytes:
135 // +--------+--------+--------+========+
136 // | 0xda |ZZZZZZZZ|ZZZZZZZZ| data |
137 // +--------+--------+--------+========+
138 //
139 // str 32 stores a byte array whose length is upto (2^32)-1 bytes:
140 // +--------+--------+--------+--------+--------+========+
141 // | 0xdb |AAAAAAAA|AAAAAAAA|AAAAAAAA|AAAAAAAA| data |
142 // +--------+--------+--------+--------+--------+========+
143 //
144 // where
145 // * XXXXX is a 5-bit unsigned integer which represents N
146 // * YYYYYYYY is a 8-bit unsigned integer which represents N
147 // * ZZZZZZZZ_ZZZZZZZZ is a 16-bit big-endian unsigned integer which represents N
148 // * AAAAAAAA_AAAAAAAA_AAAAAAAA_AAAAAAAA is a 32-bit big-endian unsigned integer which represents N
149 // * N is the length of data
150
151 test("", "A0");
152 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");
153 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");
154
155 // fixarray stores an array whose length is upto 15 elements:
156 // +--------+~~~~~~~~~~~~~~~~~+
157 // |1001XXXX| N objects |
158 // +--------+~~~~~~~~~~~~~~~~~+
159 //
160 // array 16 stores an array whose length is upto (2^16)-1 elements:
161 // +--------+--------+--------+~~~~~~~~~~~~~~~~~+
162 // | 0xdc |YYYYYYYY|YYYYYYYY| N objects |
163 // +--------+--------+--------+~~~~~~~~~~~~~~~~~+
164 //
165 // array 32 stores an array whose length is upto (2^32)-1 elements:
166 // +--------+--------+--------+--------+--------+~~~~~~~~~~~~~~~~~+
167 // | 0xdd |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ| N objects |
168 // +--------+--------+--------+--------+--------+~~~~~~~~~~~~~~~~~+
169 //
170 // where
171 // * XXXX is a 4-bit unsigned integer which represents N
172 // * YYYYYYYY_YYYYYYYY is a 16-bit big-endian unsigned integer which represents N
173 // * ZZZZZZZZ_ZZZZZZZZ_ZZZZZZZZ_ZZZZZZZZ is a 32-bit big-endian unsigned integer which represents N
174 // N is the size of a array
175
176 test(new int[0], "90");
177 test(new int[]{1}, "91 01");
178 test(new int[]{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");
179 test(new int[]{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");
180
181 // fixmap stores a map whose length is upto 15 elements
182 // +--------+~~~~~~~~~~~~~~~~~+
183 // |1000XXXX| N*2 objects |
184 // +--------+~~~~~~~~~~~~~~~~~+
185 //
186 // map 16 stores a map whose length is upto (2^16)-1 elements
187 // +--------+--------+--------+~~~~~~~~~~~~~~~~~+
188 // | 0xde |YYYYYYYY|YYYYYYYY| N*2 objects |
189 // +--------+--------+--------+~~~~~~~~~~~~~~~~~+
190 //
191 // map 32 stores a map whose length is upto (2^32)-1 elements
192 // +--------+--------+--------+--------+--------+~~~~~~~~~~~~~~~~~+
193 // | 0xdf |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ| N*2 objects |
194 // +--------+--------+--------+--------+--------+~~~~~~~~~~~~~~~~~+
195 //
196 // where
197 // * XXXX is a 4-bit unsigned integer which represents N
198 // * YYYYYYYY_YYYYYYYY is a 16-bit big-endian unsigned integer which represents N
199 // * ZZZZZZZZ_ZZZZZZZZ_ZZZZZZZZ_ZZZZZZZZ is a 32-bit big-endian unsigned integer which represents N
200 // * N is the size of a map
201 // * odd elements in objects are keys of a map
202 // * the next element of a key is its associated value
203
204 test(JsonMap.ofJson("{}"), "80");
205 test(JsonMap.ofJson("{1:1}"), "81 A1 31 01");
206 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");
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,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");
208 }
209
210 public static class Person {
211 public String name = "John Smith";
212 public int age = 21;
213 }
214
215 private void test(Object input, String expected) throws Exception {
216 byte[] b = MsgPackSerializer.DEFAULT.serialize(input);
217 assertEquals(expected, StringUtils.toSpacedHex(b));
218 }
219 }