blob: 774ceb7b59cc8b473625f20e96ebaeda3312dc16 [file] [log] [blame]
zongqiang.zhang0c6a0882019-08-07 14:48:21 +08001/* CWPack - cwpack.c */
2/*
3 The MIT License (MIT)
guangcheng.qinf87ed972019-08-30 10:50:01 +08004
zongqiang.zhang0c6a0882019-08-07 14:48:21 +08005 Copyright (c) 2017 Claes Wihlborg
guangcheng.qinf87ed972019-08-30 10:50:01 +08006
zongqiang.zhang0c6a0882019-08-07 14:48:21 +08007 Permission is hereby granted, free of charge, to any person obtaining a copy of this
8 software and associated documentation files (the "Software"), to deal in the Software
9 without restriction, including without limitation the rights to use, copy, modify,
10 merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
11 persons to whom the Software is furnished to do so, subject to the following conditions:
guangcheng.qinf87ed972019-08-30 10:50:01 +080012
zongqiang.zhang0c6a0882019-08-07 14:48:21 +080013 The above copyright notice and this permission notice shall be included in all copies or
14 substantial portions of the Software.
guangcheng.qinf87ed972019-08-30 10:50:01 +080015
zongqiang.zhang0c6a0882019-08-07 14:48:21 +080016 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
17 BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
19 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 */
22
23#include <string.h>
24
25#include "cwpack.h"
26#include "cwpack_defines.h"
27
28
29
30/************************* C S Y S T E M L I B R A R Y ****************/
31
32#ifdef FORCE_NO_LIBRARY
33
guangcheng.qinf87ed972019-08-30 10:50:01 +080034static void* memcpy(void* dst, const void* src, size_t n)
zongqiang.zhang0c6a0882019-08-07 14:48:21 +080035{
guangcheng.qinf87ed972019-08-30 10:50:01 +080036 unsigned int i;
37 uint8_t* d;
38 uint8_t* s;
39 d=(uint8_t*)dst;
40 s=(uint8_t*)src;
41 for(i=0; i<n; i++)
42 {
43 *d++ = *s++;
44 }
45 return dst;
zongqiang.zhang0c6a0882019-08-07 14:48:21 +080046}
47
48#endif
49
zongqiang.zhang0c6a0882019-08-07 14:48:21 +080050/************************* B Y T E O R D E R ****************************/
51
52
53static int test_byte_order(void)
54{
55#ifdef COMPILE_FOR_BIG_ENDIAN
guangcheng.qinf87ed972019-08-30 10:50:01 +080056 const char* endianness = "1234";
57 if(*(uint32_t*)endianness != 0x31323334UL)
58 return CWP_RC_WRONG_BYTE_ORDER;
zongqiang.zhang0c6a0882019-08-07 14:48:21 +080059#else
60
61#ifdef COMPILE_FOR_LITTLE_ENDIAN
guangcheng.qinf87ed972019-08-30 10:50:01 +080062 const char* endianness = "1234";
63 if(*(uint32_t*)endianness != 0x34333231UL)
64 return CWP_RC_WRONG_BYTE_ORDER;
zongqiang.zhang0c6a0882019-08-07 14:48:21 +080065#endif
66#endif
guangcheng.qinf87ed972019-08-30 10:50:01 +080067 return CWP_RC_OK;
zongqiang.zhang0c6a0882019-08-07 14:48:21 +080068}
69
70
71/******************************* P A C K **********************************/
72
73
74
guangcheng.qinf87ed972019-08-30 10:50:01 +080075int cw_pack_context_init(cw_pack_context* pack_context, void* data, unsigned long length,
76 pack_overflow_handler hpo)
zongqiang.zhang0c6a0882019-08-07 14:48:21 +080077{
guangcheng.qinf87ed972019-08-30 10:50:01 +080078 pack_context->start = pack_context->current = (uint8_t*)data;
79 pack_context->end = pack_context->start + length;
80 pack_context->be_compatible = false;
81 pack_context->err_no = 0;
82 pack_context->handle_pack_overflow = hpo;
83 pack_context->return_code = test_byte_order();
84 return pack_context->return_code;
zongqiang.zhang0c6a0882019-08-07 14:48:21 +080085}
86
guangcheng.qinf87ed972019-08-30 10:50:01 +080087void cw_pack_set_compatibility(cw_pack_context* pack_context, bool be_compatible)
zongqiang.zhang0c6a0882019-08-07 14:48:21 +080088{
guangcheng.qinf87ed972019-08-30 10:50:01 +080089 pack_context->be_compatible = be_compatible;
zongqiang.zhang0c6a0882019-08-07 14:48:21 +080090}
91
92
93
94/* Packing routines -------------------------------------------------------------------------------- */
95
96
97void cw_pack_unsigned(cw_pack_context* pack_context, uint64_t i)
98{
guangcheng.qinf87ed972019-08-30 10:50:01 +080099 int rc;
100 uint8_t* p;
101 uint8_t* nyp;
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800102
guangcheng.qinf87ed972019-08-30 10:50:01 +0800103 if(pack_context->return_code)
104 return;
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800105
guangcheng.qinf87ed972019-08-30 10:50:01 +0800106 if(i < 128)
107 tryMove0(i);
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800108
guangcheng.qinf87ed972019-08-30 10:50:01 +0800109 if(i < 256)
110 tryMove1(0xcc, i);
111
112 if(i < 0x10000L)
113 {
114 tryMove2(0xcd, i);
115 }
116 if(i < 0x100000000LL)
117 tryMove4(0xce, i);
118
119 tryMove8(0xcf,i);
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800120}
121
122
123void cw_pack_signed(cw_pack_context* pack_context, int64_t i)
124{
guangcheng.qinf87ed972019-08-30 10:50:01 +0800125 int rc;
126 uint8_t* p;
127 uint8_t* nyp;
128 if(pack_context->return_code)
129 return;
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800130
guangcheng.qinf87ed972019-08-30 10:50:01 +0800131 if(i >127)
132 {
133 if(i < 256)
134 tryMove1(0xcc, i);
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800135
guangcheng.qinf87ed972019-08-30 10:50:01 +0800136 if(i < 0x10000L)
137 tryMove2(0xcd, i);
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800138
guangcheng.qinf87ed972019-08-30 10:50:01 +0800139 if(i < 0x100000000LL)
140 tryMove4(0xce, i);
141
142 tryMove8(0xcf,i);
143 }
144
145 if(i >= -32)
146 tryMove0(i);
147
148 if(i >= -128)
149 tryMove1(0xd0, i);
150
151 if(i >= -32768)
152 tryMove2(0xd1,i);
153
154 if(i >= (int64_t)0xffffffff80000000LL)
155 tryMove4(0xd2,i);
156
157 tryMove8(0xd3,i);
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800158}
159
160
161void cw_pack_float(cw_pack_context* pack_context, float f)
162{
guangcheng.qinf87ed972019-08-30 10:50:01 +0800163 uint32_t tmp;
164 int rc;
165 uint8_t* p;
166 uint8_t* nyp;
167 if(pack_context->return_code)
168 return;
169
170 tmp = *((uint32_t*)&f);
171 tryMove4(0xca,tmp);
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800172}
173
174
175void cw_pack_double(cw_pack_context* pack_context, double d)
176{
guangcheng.qinf87ed972019-08-30 10:50:01 +0800177 uint64_t tmp;
178 int rc;
179 uint8_t* p;
180 uint8_t* nyp;
181 if(pack_context->return_code)
182 return;
183
184 tmp = *((uint64_t*)&d);
185 tryMove8(0xcb,tmp);
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800186}
187
188
guangcheng.qinf87ed972019-08-30 10:50:01 +0800189void cw_pack_real(cw_pack_context* pack_context, double d)
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800190{
guangcheng.qinf87ed972019-08-30 10:50:01 +0800191 float f = (float)d;
192 double df = f;
193 if(df == d)
194 cw_pack_float(pack_context, f);
195 else
196 cw_pack_double(pack_context, d);
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800197}
198
199
200void cw_pack_nil(cw_pack_context* pack_context)
201{
guangcheng.qinf87ed972019-08-30 10:50:01 +0800202 int rc;
203 uint8_t* p;
204 uint8_t* nyp;
205 if(pack_context->return_code)
206 return;
207
208 tryMove0(0xc0);
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800209}
210
211
guangcheng.qinf87ed972019-08-30 10:50:01 +0800212void cw_pack_true(cw_pack_context* pack_context)
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800213{
guangcheng.qinf87ed972019-08-30 10:50:01 +0800214 int rc;
215 uint8_t* p;
216 uint8_t* nyp;
217 if(pack_context->return_code)
218 return;
219
220 tryMove0(0xc3);
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800221}
222
223
guangcheng.qinf87ed972019-08-30 10:50:01 +0800224void cw_pack_false(cw_pack_context* pack_context)
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800225{
guangcheng.qinf87ed972019-08-30 10:50:01 +0800226 int rc;
227 uint8_t* p;
228 uint8_t* nyp;
229 if(pack_context->return_code)
230 return;
231
232 tryMove0(0xc2);
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800233}
234
235
236void cw_pack_boolean(cw_pack_context* pack_context, bool b)
237{
guangcheng.qinf87ed972019-08-30 10:50:01 +0800238 int rc;
239 uint8_t* p;
240 uint8_t* nyp;
241 if(pack_context->return_code)
242 return;
243 tryMove0(b? 0xc3: 0xc2);
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800244}
245
246
247void cw_pack_array_size(cw_pack_context* pack_context, uint32_t n)
248{
guangcheng.qinf87ed972019-08-30 10:50:01 +0800249 int rc;
250 uint8_t* p;
251 uint8_t* nyp;
252 if(pack_context->return_code)
253 return;
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800254
guangcheng.qinf87ed972019-08-30 10:50:01 +0800255 if(n < 16)
256 tryMove0(0x90 | n);
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800257
guangcheng.qinf87ed972019-08-30 10:50:01 +0800258 if(n < 65536)
259 tryMove2(0xdc, n);
260
261 tryMove4(0xdd, n);
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800262}
263
264
265void cw_pack_map_size(cw_pack_context* pack_context, uint32_t n)
266{
guangcheng.qinf87ed972019-08-30 10:50:01 +0800267 int rc;
268 uint8_t* p;
269 uint8_t* nyp;
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800270
guangcheng.qinf87ed972019-08-30 10:50:01 +0800271 if(pack_context->return_code)
272 return;
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800273
guangcheng.qinf87ed972019-08-30 10:50:01 +0800274 if(n < 16)
275 tryMove0(0x80 | n);
276
277 if(n < 65536)
278 tryMove2(0xde, n);
279
280 tryMove4(0xdf, n);
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800281}
282
283
284void cw_pack_str(cw_pack_context* pack_context, const char* v, uint32_t l)
285{
guangcheng.qinf87ed972019-08-30 10:50:01 +0800286 int rc;
287 uint8_t* p;
288 uint8_t* nyp;
289 if(pack_context->return_code)
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800290 return;
guangcheng.qinf87ed972019-08-30 10:50:01 +0800291
292 if(l < 32) // Fixstr
293 {
294 cw_pack_reserve_space(l+1);
295 *p = (uint8_t)(0xa0 + l);
296 memcpy(p+1,v,l);
297 return;
298 }
299 if(l < 256 && !pack_context->be_compatible) // Str 8
300 {
301 cw_pack_reserve_space(l+2);
302 *p++ = (uint8_t)(0xd9);
303 *p = (uint8_t)(l);
304 memcpy(p+1,v,l);
305 return;
306 }
307 if(l < 65536) // Str 16
308 {
309 cw_pack_reserve_space(l+3)
310 *p++ = (uint8_t)0xda;
311 cw_store16(l);
312 memcpy(p+2,v,l);
313 return;
314 }
315 // Str 32
316 cw_pack_reserve_space(l+5)
317 *p++ = (uint8_t)0xdb;
318 cw_store32(l);
319 memcpy(p+4,v,l);
320 return;
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800321}
322
323
324void cw_pack_bin(cw_pack_context* pack_context, const void* v, uint32_t l)
325{
guangcheng.qinf87ed972019-08-30 10:50:01 +0800326 int rc;
327 uint8_t* p;
328 uint8_t* nyp;
329 if(pack_context->return_code)
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800330 return;
guangcheng.qinf87ed972019-08-30 10:50:01 +0800331
332 if(pack_context->be_compatible)
333 {
334 cw_pack_str(pack_context, v, l);
335 return;
336 }
337 if(l < 256) // Bin 8
338 {
339 cw_pack_reserve_space(l+2);
340 *p++ = (uint8_t)(0xc4);
341 *p = (uint8_t)(l);
342 memcpy(p+1,v,l);
343 return;
344 }
345 if(l < 65536) // Bin 16
346 {
347 cw_pack_reserve_space(l+3)
348 *p++ = (uint8_t)0xc5;
349 cw_store16(l);
350 memcpy(p+2,v,l);
351 return;
352 }
353 // Bin 32
354 cw_pack_reserve_space(l+5)
355 *p++ = (uint8_t)0xc6;
356 cw_store32(l);
357 memcpy(p+4,v,l);
358 return;
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800359}
360
361
guangcheng.qinf87ed972019-08-30 10:50:01 +0800362void cw_pack_ext(cw_pack_context* pack_context, int8_t type, const void* v, uint32_t l)
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800363{
guangcheng.qinf87ed972019-08-30 10:50:01 +0800364 int rc;
365 uint8_t* p;
366 uint8_t* nyp;
367 if(pack_context->return_code)
368 return;
369
370 if(pack_context->be_compatible)
371 PACK_ERROR(CWP_RC_ILLEGAL_CALL);
372
373 switch(l)
374 {
375 case 1: // Fixext 1
376 cw_pack_reserve_space(3);
377 *p++ = (uint8_t)0xd4;
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800378 *p++ = (uint8_t)type;
guangcheng.qinf87ed972019-08-30 10:50:01 +0800379 *p++ = *(uint8_t*)v;
380 return;
381 case 2: // Fixext 2
382 cw_pack_reserve_space(4);
383 *p++ = (uint8_t)0xd5;
384 break;
385 case 4: // Fixext 4
386 cw_pack_reserve_space(6);
387 *p++ = (uint8_t)0xd6;
388 break;
389 case 8: // Fixext 8
390 cw_pack_reserve_space(10);
391 *p++ = (uint8_t)0xd7;
392 break;
393 case 16: // Fixext16
394 cw_pack_reserve_space(18);
395 *p++ = (uint8_t)0xd8;
396 break;
397 default:
398 if(l < 256) // Ext 8
399 {
400 cw_pack_reserve_space(l+3);
401 *p++ = (uint8_t)0xc7;
402 *p++ = (uint8_t)(l);
403 }
404 else if(l < 65536) // Ext 16
405 {
406 cw_pack_reserve_space(l+4)
407 *p++ = (uint8_t)0xc8;
408 cw_store16(l);
409 p += 2;
410 }
411 else // Ext 32
412 {
413 cw_pack_reserve_space(l+6)
414 *p++ = (uint8_t)0xc9;
415 cw_store32(l);
416 p += 4;
417 }
418 }
419 *p++ = (uint8_t)type;
420 memcpy(p,v,l);
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800421}
422
423
guangcheng.qinf87ed972019-08-30 10:50:01 +0800424void cw_pack_insert(cw_pack_context* pack_context, const void* v, uint32_t l)
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800425{
guangcheng.qinf87ed972019-08-30 10:50:01 +0800426 int rc;
427 uint8_t* p;
428 uint8_t* nyp;
429 cw_pack_reserve_space(l);
430 memcpy(p,v,l);
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800431}
432
433/******************************* U N P A C K **********************************/
434
435
guangcheng.qinf87ed972019-08-30 10:50:01 +0800436int cw_unpack_context_init(cw_unpack_context* unpack_context, void* data,
437 unsigned long length, unpack_underflow_handler huu)
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800438{
guangcheng.qinf87ed972019-08-30 10:50:01 +0800439 unpack_context->start = unpack_context->current = (uint8_t*)data;
440 unpack_context->end = unpack_context->start + length;
441 unpack_context->return_code = test_byte_order();
442 unpack_context->err_no = 0;
443 unpack_context->handle_unpack_underflow = huu;
444 return unpack_context->return_code;
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800445}
446
447
448/* Unpacking routines ---------------------------------------------------------- */
449
450
451
guangcheng.qinf87ed972019-08-30 10:50:01 +0800452void cw_unpack_next(cw_unpack_context* unpack_context)
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800453{
guangcheng.qinf87ed972019-08-30 10:50:01 +0800454 uint64_t tmpu64;
455 uint32_t tmpu32;
456 uint16_t tmpu16;
457 uint8_t* p;
458 uint8_t c;
459 uint8_t* nyp;
460 int rc;
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800461
guangcheng.qinf87ed972019-08-30 10:50:01 +0800462 if(unpack_context->return_code)
463 return;
464
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800465#define buffer_end_return_code CWP_RC_END_OF_INPUT;
guangcheng.qinf87ed972019-08-30 10:50:01 +0800466 cw_unpack_assert_space(1);
467 c = *p;
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800468#undef buffer_end_return_code
469#define buffer_end_return_code CWP_RC_BUFFER_UNDERFLOW;
guangcheng.qinf87ed972019-08-30 10:50:01 +0800470 switch(c)
471 {
472 case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
473 case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
474 case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
475 case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
476 case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
477 case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
478 case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
479 case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f:
480 case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:
481 case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f:
482 case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57:
483 case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f:
484 case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67:
485 case 0x68: case 0x69: case 0x6a: case 0x6b: case 0x6c: case 0x6d: case 0x6e: case 0x6f:
486 case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77:
487 case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f:
488 getDDItem(CWP_ITEM_POSITIVE_INTEGER, i64, c); return; // positive fixnum
489 case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87:
490 case 0x88: case 0x89: case 0x8a: case 0x8b: case 0x8c: case 0x8d: case 0x8e: case 0x8f:
491 getDDItem(CWP_ITEM_MAP, map.size, c & 0x0f); return; // fixmap
492 case 0x90: case 0x91: case 0x92: case 0x93: case 0x94: case 0x95: case 0x96: case 0x97:
493 case 0x98: case 0x99: case 0x9a: case 0x9b: case 0x9c: case 0x9d: case 0x9e: case 0x9f:
494 getDDItem(CWP_ITEM_ARRAY, array.size, c & 0x0f); return; // fixarray
495 case 0xa0: case 0xa1: case 0xa2: case 0xa3: case 0xa4: case 0xa5: case 0xa6: case 0xa7:
496 case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf:
497 case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7:
498 case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf:
499 getDDItem(CWP_ITEM_STR, str.length, c & 0x1f); // fixraw
500 cw_unpack_assert_blob(str);
501 case 0xc0: unpack_context->item.type = CWP_ITEM_NIL; return; // nil
502 case 0xc2: getDDItem(CWP_ITEM_BOOLEAN, boolean, false); return; // false
503 case 0xc3: getDDItem(CWP_ITEM_BOOLEAN, boolean, true); return; // true
504 case 0xc4: getDDItem1(CWP_ITEM_BIN, bin.length, uint8_t); // bin 8
505 cw_unpack_assert_blob(bin);
506 case 0xc5: getDDItem2(CWP_ITEM_BIN, bin.length, uint16_t); // bin 16
507 cw_unpack_assert_blob(bin);
508 case 0xc6: getDDItem4(CWP_ITEM_BIN, bin.length, uint32_t); // bin 32
509 cw_unpack_assert_blob(bin);
510 case 0xc7: getDDItem1(CWP_ITEM_EXT, ext.length, uint8_t); // ext 8
511 cw_unpack_assert_space(1);
512 unpack_context->item.type = *(int8_t*)p;
513 cw_unpack_assert_blob(ext);
514 case 0xc8: getDDItem2(CWP_ITEM_EXT, ext.length, uint16_t); // ext 16
515 cw_unpack_assert_space(1);
516 unpack_context->item.type = *(int8_t*)p;
517 cw_unpack_assert_blob(ext);
518 case 0xc9: getDDItem4(CWP_ITEM_EXT, ext.length, uint32_t); // ext 32
519 cw_unpack_assert_space(1);
520 unpack_context->item.type = *(int8_t*)p;
521 cw_unpack_assert_blob(ext);
522 case 0xca: unpack_context->item.type = CWP_ITEM_FLOAT; // float
523 cw_unpack_assert_space(4);
524 cw_load32(p);
525 unpack_context->item.as.real = *(float*)&tmpu32; return;
526 case 0xcb: getDDItem8(CWP_ITEM_DOUBLE); return; // double
527 case 0xcc: getDDItem1(CWP_ITEM_POSITIVE_INTEGER, u64, uint8_t);
528 return; // unsigned int 8
529 case 0xcd: getDDItem2(CWP_ITEM_POSITIVE_INTEGER, u64, uint16_t);
530 return; // unsigned int 16
531 case 0xce: getDDItem4(CWP_ITEM_POSITIVE_INTEGER, u64, uint32_t);
532 return; // unsigned int 32
533 case 0xcf: getDDItem8(CWP_ITEM_POSITIVE_INTEGER);
534 return; // unsigned int 64
535 case 0xd0: getDDItem1(CWP_ITEM_NEGATIVE_INTEGER, i64, int8_t); // signed int 8
536 if(unpack_context->item.as.i64 >= 0)
537 unpack_context->item.type = CWP_ITEM_POSITIVE_INTEGER;
538 return;
539 case 0xd1: getDDItem2(CWP_ITEM_NEGATIVE_INTEGER, i64, int16_t); // signed int 16
540 if(unpack_context->item.as.i64 >= 0)
541 unpack_context->item.type = CWP_ITEM_POSITIVE_INTEGER;
542 return;
543 case 0xd2: getDDItem4(CWP_ITEM_NEGATIVE_INTEGER, i64, int32_t); // signed int 32
544 if(unpack_context->item.as.i64 >= 0)
545 unpack_context->item.type = CWP_ITEM_POSITIVE_INTEGER;
546 return;
547 case 0xd3: getDDItem8(CWP_ITEM_NEGATIVE_INTEGER); // signed int 64
548 if(unpack_context->item.as.i64 >= 0)
549 unpack_context->item.type = CWP_ITEM_POSITIVE_INTEGER;
550 return;
551 case 0xd4: getDDItemFix(1); // fixext 1
552 case 0xd5: getDDItemFix(2); // fixext 2
553 case 0xd6: getDDItemFix(4); // fixext 4
554 case 0xd7: getDDItemFix(8); // fixext 8
555 case 0xd8: getDDItemFix(16); // fixext 16
556 case 0xd9: getDDItem1(CWP_ITEM_STR, str.length, uint8_t); // str 8
557 cw_unpack_assert_blob(str);
558 case 0xda: getDDItem2(CWP_ITEM_STR, str.length, uint16_t); // str 16
559 cw_unpack_assert_blob(str);
560 case 0xdb: getDDItem4(CWP_ITEM_STR, str.length, uint32_t); // str 32
561 cw_unpack_assert_blob(str);
562 case 0xdc: getDDItem2(CWP_ITEM_ARRAY, array.size, uint16_t); return; // array 16
563 case 0xdd: getDDItem4(CWP_ITEM_ARRAY, array.size, uint32_t); return; // array 32
564 case 0xde: getDDItem2(CWP_ITEM_MAP, map.size, uint16_t); return; // map 16
565 case 0xdf: getDDItem4(CWP_ITEM_MAP, map.size, uint32_t); return; // map 32
566 case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7:
567 case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef:
568 case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7:
569 case 0xf8: case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: case 0xff:
570 getDDItem(CWP_ITEM_NEGATIVE_INTEGER, i64, (int8_t)c); return; // negative fixnum
571 default:
572 UNPACK_ERROR(CWP_RC_MALFORMED_INPUT)
573 }
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800574}
575
576#define cw_skip_bytes(n) \
guangcheng.qinf87ed972019-08-30 10:50:01 +0800577 cw_unpack_assert_space((n)); \
578 break;
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800579
guangcheng.qinf87ed972019-08-30 10:50:01 +0800580void cw_skip_items(cw_unpack_context* unpack_context, long item_count)
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800581{
guangcheng.qinf87ed972019-08-30 10:50:01 +0800582 uint32_t tmpu32;
583 uint16_t tmpu16;
584 uint8_t* p;
585 uint8_t c;
586 uint8_t* nyp;
587 int rc;
588
589 if(unpack_context->return_code)
590 return;
591
592 while(item_count-- > 0)
593 {
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800594#undef buffer_end_return_code
595#define buffer_end_return_code CWP_RC_END_OF_INPUT;
guangcheng.qinf87ed972019-08-30 10:50:01 +0800596 cw_unpack_assert_space(1);
597 c = *p;
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800598
599#undef buffer_end_return_code
600#define buffer_end_return_code CWP_RC_BUFFER_UNDERFLOW;
guangcheng.qinf87ed972019-08-30 10:50:01 +0800601 switch(c)
602 {
603 case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
604 case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
605 case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
606 case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
607 case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
608 case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
609 case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
610 case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f:
611 case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:
612 case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f:
613 case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57:
614 case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f:
615 case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67:
616 case 0x68: case 0x69: case 0x6a: case 0x6b: case 0x6c: case 0x6d: case 0x6e: case 0x6f:
617 case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77:
618 case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f:
619 // unsigned fixint
620 case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7:
621 case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef:
622 case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7:
623 case 0xf8: case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: case 0xff:
624 // signed fixint
625 case 0xc0: // nil
626 case 0xc2: // false
627 case 0xc3: break; // true
628 case 0xcc: // unsigned int 8
629 case 0xd0: cw_skip_bytes(1); // signed int 8
630 case 0xcd: // unsigned int 16
631 case 0xd1: // signed int 16
632 case 0xd4: cw_skip_bytes(2); // fixext 1
633 case 0xd5: cw_skip_bytes(3); // fixext 2
634 case 0xca: // float
635 case 0xce: // unsigned int 32
636 case 0xd2: cw_skip_bytes(4); // signed int 32
637 case 0xd6: cw_skip_bytes(5); // fixext 4
638 case 0xcb: // double
639 case 0xcf: // unsigned int 64
640 case 0xd3: cw_skip_bytes(8); // signed int 64
641 case 0xd7: cw_skip_bytes(9); // fixext 8
642 case 0xd8: cw_skip_bytes(17); // fixext 16
643 case 0xa0: case 0xa1: case 0xa2: case 0xa3: case 0xa4: case 0xa5: case 0xa6: case 0xa7:
644 case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf:
645 case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7:
646 case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf:
647 cw_skip_bytes(c & 0x1f); // fixstr
648 case 0xd9: // str 8
649 case 0xc4: // bin 8
650 cw_unpack_assert_space(1);
651 tmpu32 = *p;
652 cw_skip_bytes(tmpu32);
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800653
guangcheng.qinf87ed972019-08-30 10:50:01 +0800654 case 0xda: // str 16
655 case 0xc5: // bin 16
656 cw_unpack_assert_space(2);
657 cw_load16(p);
658 cw_skip_bytes(tmpu16);
659
660 case 0xdb: // str 32
661 case 0xc6: // bin 32
662 cw_unpack_assert_space(4);
663 cw_load32(p);
664 cw_skip_bytes(tmpu32);
665
666 case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87:
667 case 0x88: case 0x89: case 0x8a: case 0x8b: case 0x8c: case 0x8d: case 0x8e: case 0x8f:
668 item_count += 2*(c & 15); // FixMap
669 break;
670
671 case 0x90: case 0x91: case 0x92: case 0x93: case 0x94: case 0x95: case 0x96: case 0x97:
672 case 0x98: case 0x99: case 0x9a: case 0x9b: case 0x9c: case 0x9d: case 0x9e: case 0x9f:
673 item_count += c & 15; // FixArray
674 break;
675
676 case 0xdc: // array 16
677 cw_unpack_assert_space(2);
678 cw_load16(p);
679 item_count += tmpu16;
680 break;
681
682 case 0xde: // map 16
683 cw_unpack_assert_space(2);
684 cw_load16(p);
685 item_count += 2*tmpu16;
686 break;
687
688 case 0xdd: // array 32
689 cw_unpack_assert_space(4);
690 cw_load32(p);
691 item_count += tmpu32;
692 break;
693
694 case 0xdf: // map 32
695 cw_unpack_assert_space(4);
696 cw_load32(p);
697 item_count += 2*tmpu32;
698 break;
699
700 case 0xc7: // ext 8
701 cw_unpack_assert_space(1);
702 tmpu32 = *p;
703 cw_skip_bytes(tmpu32 +1);
704
705 case 0xc8: // ext 16
706 cw_unpack_assert_space(2);
707 cw_load16(p);
708 cw_skip_bytes(tmpu16 +1);
709
710 case 0xc9: // ext 32
711 cw_unpack_assert_space(4);
712 cw_load32(p);
713 cw_skip_bytes(tmpu32 +1);
714
715 default: // illegal
716 UNPACK_ERROR(CWP_RC_MALFORMED_INPUT)
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800717 }
guangcheng.qinf87ed972019-08-30 10:50:01 +0800718 }
719 return;
zongqiang.zhang0c6a0882019-08-07 14:48:21 +0800720}
721
722/* end cwpack.c */