View Javadoc
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 }