blob: 496b4b36730e4dfccd87c7077d11f92ec70bc95b [file] [log] [blame]
zongqiang.zhang0c6a0882019-08-07 14:48:21 +08001/* CWPack - cwpack.c */
2/*
3 The MIT License (MIT)
4
5 Copyright (c) 2017 Claes Wihlborg
6
7 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:
12
13 The above copyright notice and this permission notice shall be included in all copies or
14 substantial portions of the Software.
15
16 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
34static void *memcpy(void *dst, const void *src, size_t n)
35{
36 unsigned int i;
37 uint8_t *d=(uint8_t*)dst, *s=(uint8_t*)src;
38 for (i=0; i<n; i++)
39 {
40 *d++ = *s++;
41 }
42 return dst;
43}
44
45#endif
46
47
48
49/************************* B Y T E O R D E R ****************************/
50
51
52static int test_byte_order(void)
53{
54#ifdef COMPILE_FOR_BIG_ENDIAN
55 const char *endianness = "1234";
56 if (*(uint32_t*)endianness != 0x31323334UL)
57 return CWP_RC_WRONG_BYTE_ORDER;
58#else
59
60#ifdef COMPILE_FOR_LITTLE_ENDIAN
61 const char *endianness = "1234";
62 if (*(uint32_t*)endianness != 0x34333231UL)
63 return CWP_RC_WRONG_BYTE_ORDER;
64#endif
65#endif
66 return CWP_RC_OK;
67}
68
69
70/******************************* P A C K **********************************/
71
72
73
74int cw_pack_context_init (cw_pack_context* pack_context, void* data, unsigned long length, pack_overflow_handler hpo)
75{
76 pack_context->start = pack_context->current = (uint8_t*)data;
77 pack_context->end = pack_context->start + length;
78 pack_context->be_compatible = false;
79 pack_context->err_no = 0;
80 pack_context->handle_pack_overflow = hpo;
81 pack_context->return_code = test_byte_order();
82 return pack_context->return_code;
83}
84
85void cw_pack_set_compatibility (cw_pack_context* pack_context, bool be_compatible)
86{
87 pack_context->be_compatible = be_compatible;
88}
89
90
91
92/* Packing routines -------------------------------------------------------------------------------- */
93
94
95void cw_pack_unsigned(cw_pack_context* pack_context, uint64_t i)
96{
97 if (pack_context->return_code)
98 return;
99
100 if (i < 128)
101 tryMove0(i);
102
103 if (i < 256)
104 tryMove1(0xcc, i);
105
106 if (i < 0x10000L)
107 {
108 tryMove2(0xcd, i);
109 }
110 if (i < 0x100000000LL)
111 tryMove4(0xce, i);
112
113 tryMove8(0xcf,i);
114}
115
116
117void cw_pack_signed(cw_pack_context* pack_context, int64_t i)
118{
119 if (pack_context->return_code)
120 return;
121
122 if (i >127)
123 {
124 if (i < 256)
125 tryMove1(0xcc, i);
126
127 if (i < 0x10000L)
128 tryMove2(0xcd, i);
129
130 if (i < 0x100000000LL)
131 tryMove4(0xce, i);
132
133 tryMove8(0xcf,i);
134 }
135
136 if (i >= -32)
137 tryMove0(i);
138
139 if (i >= -128)
140 tryMove1(0xd0, i);
141
142 if (i >= -32768)
143 tryMove2(0xd1,i);
144
145 if (i >= (int64_t)0xffffffff80000000LL)
146 tryMove4(0xd2,i);
147
148 tryMove8(0xd3,i);
149}
150
151
152void cw_pack_float(cw_pack_context* pack_context, float f)
153{
154 if (pack_context->return_code)
155 return;
156
157 uint32_t tmp = *((uint32_t*)&f);
158 tryMove4(0xca,tmp);
159}
160
161
162void cw_pack_double(cw_pack_context* pack_context, double d)
163{
164 if (pack_context->return_code)
165 return;
166
167 uint64_t tmp = *((uint64_t*)&d);
168 tryMove8(0xcb,tmp);
169}
170
171
172void cw_pack_real (cw_pack_context* pack_context, double d)
173{
174 float f = (float)d;
175 double df = f;
176 if (df == d)
177 cw_pack_float (pack_context, f);
178 else
179 cw_pack_double (pack_context, d);
180}
181
182
183void cw_pack_nil(cw_pack_context* pack_context)
184{
185 if (pack_context->return_code)
186 return;
187
188 tryMove0(0xc0);
189}
190
191
192void cw_pack_true (cw_pack_context* pack_context)
193{
194 if (pack_context->return_code)
195 return;
196
197 tryMove0(0xc3);
198}
199
200
201void cw_pack_false (cw_pack_context* pack_context)
202{
203 if (pack_context->return_code)
204 return;
205
206 tryMove0(0xc2);
207}
208
209
210void cw_pack_boolean(cw_pack_context* pack_context, bool b)
211{
212 if (pack_context->return_code)
213 return;
214
215 tryMove0(b? 0xc3: 0xc2);
216}
217
218
219void cw_pack_array_size(cw_pack_context* pack_context, uint32_t n)
220{
221 if (pack_context->return_code)
222 return;
223
224 if (n < 16)
225 tryMove0(0x90 | n);
226
227 if (n < 65536)
228 tryMove2(0xdc, n);
229
230 tryMove4(0xdd, n);
231}
232
233
234void cw_pack_map_size(cw_pack_context* pack_context, uint32_t n)
235{
236 if (pack_context->return_code)
237 return;
238
239 if (n < 16)
240 tryMove0(0x80 | n);
241
242 if (n < 65536)
243 tryMove2(0xde, n);
244
245 tryMove4(0xdf, n);
246}
247
248
249void cw_pack_str(cw_pack_context* pack_context, const char* v, uint32_t l)
250{
251 if (pack_context->return_code)
252 return;
253
254 uint8_t *p;
255
256 if (l < 32) // Fixstr
257 {
258 cw_pack_reserve_space(l+1);
259 *p = (uint8_t)(0xa0 + l);
260 memcpy(p+1,v,l);
261 return;
262 }
263 if (l < 256 && !pack_context->be_compatible) // Str 8
264 {
265 cw_pack_reserve_space(l+2);
266 *p++ = (uint8_t)(0xd9);
267 *p = (uint8_t)(l);
268 memcpy(p+1,v,l);
269 return;
270 }
271 if (l < 65536) // Str 16
272 {
273 cw_pack_reserve_space(l+3)
274 *p++ = (uint8_t)0xda;
275 cw_store16(l);
276 memcpy(p+2,v,l);
277 return;
278 }
279 // Str 32
280 cw_pack_reserve_space(l+5)
281 *p++ = (uint8_t)0xdb;
282 cw_store32(l);
283 memcpy(p+4,v,l);
284 return;
285}
286
287
288void cw_pack_bin(cw_pack_context* pack_context, const void* v, uint32_t l)
289{
290 if (pack_context->return_code)
291 return;
292
293 if (pack_context->be_compatible)
294 {
295 cw_pack_str( pack_context, v, l);
296 return;
297 }
298
299 uint8_t *p;
300
301 if (l < 256) // Bin 8
302 {
303 cw_pack_reserve_space(l+2);
304 *p++ = (uint8_t)(0xc4);
305 *p = (uint8_t)(l);
306 memcpy(p+1,v,l);
307 return;
308 }
309 if (l < 65536) // Bin 16
310 {
311 cw_pack_reserve_space(l+3)
312 *p++ = (uint8_t)0xc5;
313 cw_store16(l);
314 memcpy(p+2,v,l);
315 return;
316 }
317 // Bin 32
318 cw_pack_reserve_space(l+5)
319 *p++ = (uint8_t)0xc6;
320 cw_store32(l);
321 memcpy(p+4,v,l);
322 return;
323}
324
325
326void cw_pack_ext (cw_pack_context* pack_context, int8_t type, const void* v, uint32_t l)
327{
328 if (pack_context->return_code)
329 return;
330
331 if (pack_context->be_compatible)
332 PACK_ERROR(CWP_RC_ILLEGAL_CALL);
333
334 uint8_t *p;
335
336 switch (l)
337 {
338 case 1: // Fixext 1
339 cw_pack_reserve_space(3);
340 *p++ = (uint8_t)0xd4;
341 *p++ = (uint8_t)type;
342 *p++ = *(uint8_t*)v;
343 return;
344 case 2: // Fixext 2
345 cw_pack_reserve_space(4);
346 *p++ = (uint8_t)0xd5;
347 break;
348 case 4: // Fixext 4
349 cw_pack_reserve_space(6);
350 *p++ = (uint8_t)0xd6;
351 break;
352 case 8: // Fixext 8
353 cw_pack_reserve_space(10);
354 *p++ = (uint8_t)0xd7;
355 break;
356 case 16: // Fixext16
357 cw_pack_reserve_space(18);
358 *p++ = (uint8_t)0xd8;
359 break;
360 default:
361 if (l < 256) // Ext 8
362 {
363 cw_pack_reserve_space(l+3);
364 *p++ = (uint8_t)0xc7;
365 *p++ = (uint8_t)(l);
366 }
367 else if (l < 65536) // Ext 16
368 {
369 cw_pack_reserve_space(l+4)
370 *p++ = (uint8_t)0xc8;
371 cw_store16(l);
372 p += 2;
373 }
374 else // Ext 32
375 {
376 cw_pack_reserve_space(l+6)
377 *p++ = (uint8_t)0xc9;
378 cw_store32(l);
379 p += 4;
380 }
381 }
382 *p++ = (uint8_t)type;
383 memcpy(p,v,l);
384}
385
386
387void cw_pack_insert (cw_pack_context* pack_context, const void* v, uint32_t l)
388{
389 uint8_t *p;
390 cw_pack_reserve_space(l);
391 memcpy(p,v,l);
392}
393
394/******************************* U N P A C K **********************************/
395
396
397int cw_unpack_context_init (cw_unpack_context* unpack_context, void* data, unsigned long length, unpack_underflow_handler huu)
398{
399 unpack_context->start = unpack_context->current = (uint8_t*)data;
400 unpack_context->end = unpack_context->start + length;
401 unpack_context->return_code = test_byte_order();
402 unpack_context->err_no = 0;
403 unpack_context->handle_unpack_underflow = huu;
404 return unpack_context->return_code;
405}
406
407
408/* Unpacking routines ---------------------------------------------------------- */
409
410
411
412void cw_unpack_next (cw_unpack_context* unpack_context)
413{
414 if (unpack_context->return_code)
415 return;
416
417 uint64_t tmpu64;
418 uint32_t tmpu32;
419 uint16_t tmpu16;
420 uint8_t* p;
421
422#define buffer_end_return_code CWP_RC_END_OF_INPUT;
423 cw_unpack_assert_space(1);
424 uint8_t c = *p;
425#undef buffer_end_return_code
426#define buffer_end_return_code CWP_RC_BUFFER_UNDERFLOW;
427 switch (c)
428 {
429 case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
430 case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
431 case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
432 case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
433 case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
434 case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
435 case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
436 case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f:
437 case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:
438 case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f:
439 case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57:
440 case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f:
441 case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67:
442 case 0x68: case 0x69: case 0x6a: case 0x6b: case 0x6c: case 0x6d: case 0x6e: case 0x6f:
443 case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77:
444 case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f:
445 getDDItem(CWP_ITEM_POSITIVE_INTEGER, i64, c); return; // positive fixnum
446 case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87:
447 case 0x88: case 0x89: case 0x8a: case 0x8b: case 0x8c: case 0x8d: case 0x8e: case 0x8f:
448 getDDItem(CWP_ITEM_MAP, map.size, c & 0x0f); return; // fixmap
449 case 0x90: case 0x91: case 0x92: case 0x93: case 0x94: case 0x95: case 0x96: case 0x97:
450 case 0x98: case 0x99: case 0x9a: case 0x9b: case 0x9c: case 0x9d: case 0x9e: case 0x9f:
451 getDDItem(CWP_ITEM_ARRAY, array.size, c & 0x0f); return; // fixarray
452 case 0xa0: case 0xa1: case 0xa2: case 0xa3: case 0xa4: case 0xa5: case 0xa6: case 0xa7:
453 case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf:
454 case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7:
455 case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf:
456 getDDItem(CWP_ITEM_STR, str.length, c & 0x1f); // fixraw
457 cw_unpack_assert_blob(str);
458 case 0xc0: unpack_context->item.type = CWP_ITEM_NIL; return; // nil
459 case 0xc2: getDDItem(CWP_ITEM_BOOLEAN, boolean, false); return; // false
460 case 0xc3: getDDItem(CWP_ITEM_BOOLEAN, boolean, true); return; // true
461 case 0xc4: getDDItem1(CWP_ITEM_BIN, bin.length, uint8_t); // bin 8
462 cw_unpack_assert_blob(bin);
463 case 0xc5: getDDItem2(CWP_ITEM_BIN, bin.length, uint16_t); // bin 16
464 cw_unpack_assert_blob(bin);
465 case 0xc6: getDDItem4(CWP_ITEM_BIN, bin.length, uint32_t); // bin 32
466 cw_unpack_assert_blob(bin);
467 case 0xc7: getDDItem1(CWP_ITEM_EXT, ext.length, uint8_t); // ext 8
468 cw_unpack_assert_space(1);
469 unpack_context->item.type = *(int8_t*)p;
470 cw_unpack_assert_blob(ext);
471 case 0xc8: getDDItem2(CWP_ITEM_EXT, ext.length, uint16_t); // ext 16
472 cw_unpack_assert_space(1);
473 unpack_context->item.type = *(int8_t*)p;
474 cw_unpack_assert_blob(ext);
475 case 0xc9: getDDItem4(CWP_ITEM_EXT, ext.length, uint32_t); // ext 32
476 cw_unpack_assert_space(1);
477 unpack_context->item.type = *(int8_t*)p;
478 cw_unpack_assert_blob(ext);
479 case 0xca: unpack_context->item.type = CWP_ITEM_FLOAT; // float
480 cw_unpack_assert_space(4);
481 cw_load32(p);
482 unpack_context->item.as.real = *(float*)&tmpu32; return;
483 case 0xcb: getDDItem8(CWP_ITEM_DOUBLE); return; // double
484 case 0xcc: getDDItem1(CWP_ITEM_POSITIVE_INTEGER, u64, uint8_t); return; // unsigned int 8
485 case 0xcd: getDDItem2(CWP_ITEM_POSITIVE_INTEGER, u64, uint16_t); return; // unsigned int 16
486 case 0xce: getDDItem4(CWP_ITEM_POSITIVE_INTEGER, u64, uint32_t); return; // unsigned int 32
487 case 0xcf: getDDItem8(CWP_ITEM_POSITIVE_INTEGER); return; // unsigned int 64
488 case 0xd0: getDDItem1(CWP_ITEM_NEGATIVE_INTEGER, i64, int8_t); // signed int 8
489 if (unpack_context->item.as.i64 >= 0)
490 unpack_context->item.type = CWP_ITEM_POSITIVE_INTEGER;
491 return;
492 case 0xd1: getDDItem2(CWP_ITEM_NEGATIVE_INTEGER, i64, int16_t); // signed int 16
493 if (unpack_context->item.as.i64 >= 0)
494 unpack_context->item.type = CWP_ITEM_POSITIVE_INTEGER;
495 return;
496 case 0xd2: getDDItem4(CWP_ITEM_NEGATIVE_INTEGER, i64, int32_t); // signed int 32
497 if (unpack_context->item.as.i64 >= 0)
498 unpack_context->item.type = CWP_ITEM_POSITIVE_INTEGER;
499 return;
500 case 0xd3: getDDItem8(CWP_ITEM_NEGATIVE_INTEGER); // signed int 64
501 if (unpack_context->item.as.i64 >= 0)
502 unpack_context->item.type = CWP_ITEM_POSITIVE_INTEGER;
503 return;
504 case 0xd4: getDDItemFix(1); // fixext 1
505 case 0xd5: getDDItemFix(2); // fixext 2
506 case 0xd6: getDDItemFix(4); // fixext 4
507 case 0xd7: getDDItemFix(8); // fixext 8
508 case 0xd8: getDDItemFix(16); // fixext 16
509 case 0xd9: getDDItem1(CWP_ITEM_STR, str.length, uint8_t); // str 8
510 cw_unpack_assert_blob(str);
511 case 0xda: getDDItem2(CWP_ITEM_STR, str.length, uint16_t); // str 16
512 cw_unpack_assert_blob(str);
513 case 0xdb: getDDItem4(CWP_ITEM_STR, str.length, uint32_t); // str 32
514 cw_unpack_assert_blob(str);
515 case 0xdc: getDDItem2(CWP_ITEM_ARRAY, array.size, uint16_t); return; // array 16
516 case 0xdd: getDDItem4(CWP_ITEM_ARRAY, array.size, uint32_t); return; // array 32
517 case 0xde: getDDItem2(CWP_ITEM_MAP, map.size, uint16_t); return; // map 16
518 case 0xdf: getDDItem4(CWP_ITEM_MAP, map.size, uint32_t); return; // map 32
519 case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7:
520 case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef:
521 case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7:
522 case 0xf8: case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: case 0xff:
523 getDDItem(CWP_ITEM_NEGATIVE_INTEGER, i64, (int8_t)c); return; // negative fixnum
524 default:
525 UNPACK_ERROR(CWP_RC_MALFORMED_INPUT)
526 }
527}
528
529#define cw_skip_bytes(n) \
530 cw_unpack_assert_space((n)); \
531 break;
532
533void cw_skip_items (cw_unpack_context* unpack_context, long item_count)
534{
535 if (unpack_context->return_code)
536 return;
537
538 uint32_t tmpu32;
539 uint16_t tmpu16;
540 uint8_t* p;
541
542 while (item_count-- > 0)
543 {
544#undef buffer_end_return_code
545#define buffer_end_return_code CWP_RC_END_OF_INPUT;
546 cw_unpack_assert_space(1);
547 uint8_t c = *p;
548
549#undef buffer_end_return_code
550#define buffer_end_return_code CWP_RC_BUFFER_UNDERFLOW;
551 switch (c)
552 {
553 case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
554 case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
555 case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
556 case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
557 case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
558 case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
559 case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
560 case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f:
561 case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:
562 case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f:
563 case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57:
564 case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f:
565 case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67:
566 case 0x68: case 0x69: case 0x6a: case 0x6b: case 0x6c: case 0x6d: case 0x6e: case 0x6f:
567 case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77:
568 case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f:
569 // unsigned fixint
570 case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7:
571 case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef:
572 case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7:
573 case 0xf8: case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: case 0xff:
574 // signed fixint
575 case 0xc0: // nil
576 case 0xc2: // false
577 case 0xc3: break; // true
578 case 0xcc: // unsigned int 8
579 case 0xd0: cw_skip_bytes(1); // signed int 8
580 case 0xcd: // unsigned int 16
581 case 0xd1: // signed int 16
582 case 0xd4: cw_skip_bytes(2); // fixext 1
583 case 0xd5: cw_skip_bytes(3); // fixext 2
584 case 0xca: // float
585 case 0xce: // unsigned int 32
586 case 0xd2: cw_skip_bytes(4); // signed int 32
587 case 0xd6: cw_skip_bytes(5); // fixext 4
588 case 0xcb: // double
589 case 0xcf: // unsigned int 64
590 case 0xd3: cw_skip_bytes(8); // signed int 64
591 case 0xd7: cw_skip_bytes(9); // fixext 8
592 case 0xd8: cw_skip_bytes(17); // fixext 16
593 case 0xa0: case 0xa1: case 0xa2: case 0xa3: case 0xa4: case 0xa5: case 0xa6: case 0xa7:
594 case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf:
595 case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7:
596 case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf:
597 cw_skip_bytes(c & 0x1f); // fixstr
598 case 0xd9: // str 8
599 case 0xc4: // bin 8
600 cw_unpack_assert_space(1);
601 tmpu32 = *p;
602 cw_skip_bytes(tmpu32);
603
604 case 0xda: // str 16
605 case 0xc5: // bin 16
606 cw_unpack_assert_space(2);
607 cw_load16(p);
608 cw_skip_bytes(tmpu16);
609
610 case 0xdb: // str 32
611 case 0xc6: // bin 32
612 cw_unpack_assert_space(4);
613 cw_load32(p);
614 cw_skip_bytes(tmpu32);
615
616 case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87:
617 case 0x88: case 0x89: case 0x8a: case 0x8b: case 0x8c: case 0x8d: case 0x8e: case 0x8f:
618 item_count += 2*(c & 15); // FixMap
619 break;
620
621 case 0x90: case 0x91: case 0x92: case 0x93: case 0x94: case 0x95: case 0x96: case 0x97:
622 case 0x98: case 0x99: case 0x9a: case 0x9b: case 0x9c: case 0x9d: case 0x9e: case 0x9f:
623 item_count += c & 15; // FixArray
624 break;
625
626 case 0xdc: // array 16
627 cw_unpack_assert_space(2);
628 cw_load16(p);
629 item_count += tmpu16;
630 break;
631
632 case 0xde: // map 16
633 cw_unpack_assert_space(2);
634 cw_load16(p);
635 item_count += 2*tmpu16;
636 break;
637
638 case 0xdd: // array 32
639 cw_unpack_assert_space(4);
640 cw_load32(p);
641 item_count += tmpu32;
642 break;
643
644 case 0xdf: // map 32
645 cw_unpack_assert_space(4);
646 cw_load32(p);
647 item_count += 2*tmpu32;
648 break;
649
650 case 0xc7: // ext 8
651 cw_unpack_assert_space(1);
652 tmpu32 = *p;
653 cw_skip_bytes(tmpu32 +1);
654
655 case 0xc8: // ext 16
656 cw_unpack_assert_space(2);
657 cw_load16(p);
658 cw_skip_bytes(tmpu16 +1);
659
660 case 0xc9: // ext 32
661 cw_unpack_assert_space(4);
662 cw_load32(p);
663 cw_skip_bytes(tmpu32 +1);
664
665 default: // illegal
666 UNPACK_ERROR(CWP_RC_MALFORMED_INPUT)
667 }
668 }
669 return;
670}
671
672/* end cwpack.c */