sessiond: Add msgpack-c 3.3.0 to the tree
[lttng-tools.git] / src / vendor / msgpack / unpack_template.h
1 /*
2 * MessagePack unpacking routine template
3 *
4 * Copyright (C) 2008-2010 FURUHASHI Sadayuki
5 *
6 * Distributed under the Boost Software License, Version 1.0.
7 * (See accompanying file LICENSE_1_0.txt or copy at
8 * http://www.boost.org/LICENSE_1_0.txt)
9 */
10
11 #ifndef msgpack_unpack_func
12 #error msgpack_unpack_func template is not defined
13 #endif
14
15 #ifndef msgpack_unpack_callback
16 #error msgpack_unpack_callback template is not defined
17 #endif
18
19 #ifndef msgpack_unpack_struct
20 #error msgpack_unpack_struct template is not defined
21 #endif
22
23 #ifndef msgpack_unpack_struct_decl
24 #define msgpack_unpack_struct_decl(name) msgpack_unpack_struct(name)
25 #endif
26
27 #ifndef msgpack_unpack_object
28 #error msgpack_unpack_object type is not defined
29 #endif
30
31 #ifndef msgpack_unpack_user
32 #error msgpack_unpack_user type is not defined
33 #endif
34
35 #ifndef USE_CASE_RANGE
36 #if !defined(_MSC_VER)
37 #define USE_CASE_RANGE
38 #endif
39 #endif
40
41 #if defined(_KERNEL_MODE)
42 #undef assert
43 #define assert NT_ASSERT
44 #endif
45
46 msgpack_unpack_struct_decl(_stack) {
47 msgpack_unpack_object obj;
48 size_t count;
49 unsigned int ct;
50 msgpack_unpack_object map_key;
51 };
52
53 msgpack_unpack_struct_decl(_context) {
54 msgpack_unpack_user user;
55 unsigned int cs;
56 unsigned int trail;
57 unsigned int top;
58 /*
59 msgpack_unpack_struct(_stack)* stack;
60 unsigned int stack_size;
61 msgpack_unpack_struct(_stack) embed_stack[MSGPACK_EMBED_STACK_SIZE];
62 */
63 msgpack_unpack_struct(_stack) stack[MSGPACK_EMBED_STACK_SIZE];
64 };
65
66
67 msgpack_unpack_func(void, _init)(msgpack_unpack_struct(_context)* ctx)
68 {
69 ctx->cs = MSGPACK_CS_HEADER;
70 ctx->trail = 0;
71 ctx->top = 0;
72 /*
73 ctx->stack = ctx->embed_stack;
74 ctx->stack_size = MSGPACK_EMBED_STACK_SIZE;
75 */
76 ctx->stack[0].obj = msgpack_unpack_callback(_root)(&ctx->user);
77 }
78
79 /*
80 msgpack_unpack_func(void, _destroy)(msgpack_unpack_struct(_context)* ctx)
81 {
82 if(ctx->stack_size != MSGPACK_EMBED_STACK_SIZE) {
83 free(ctx->stack);
84 }
85 }
86 */
87
88 msgpack_unpack_func(msgpack_unpack_object, _data)(msgpack_unpack_struct(_context)* ctx)
89 {
90 return (ctx)->stack[0].obj;
91 }
92
93
94 msgpack_unpack_func(int, _execute)(msgpack_unpack_struct(_context)* ctx, const char* data, size_t len, size_t* off)
95 {
96 assert(len >= *off);
97 {
98 const unsigned char* p = (unsigned char*)data + *off;
99 const unsigned char* const pe = (unsigned char*)data + len;
100 const void* n = NULL;
101
102 unsigned int trail = ctx->trail;
103 unsigned int cs = ctx->cs;
104 unsigned int top = ctx->top;
105 msgpack_unpack_struct(_stack)* stack = ctx->stack;
106 /*
107 unsigned int stack_size = ctx->stack_size;
108 */
109 msgpack_unpack_user* user = &ctx->user;
110
111 msgpack_unpack_object obj;
112 msgpack_unpack_struct(_stack)* c = NULL;
113
114 int ret;
115
116 #define push_simple_value(func) \
117 ret = msgpack_unpack_callback(func)(user, &obj); \
118 if(ret < 0) { goto _failed; } \
119 goto _push
120 #define push_fixed_value(func, arg) \
121 ret = msgpack_unpack_callback(func)(user, arg, &obj); \
122 if(ret < 0) { goto _failed; } \
123 goto _push
124 #define push_variable_value(func, base, pos, len) \
125 ret = msgpack_unpack_callback(func)(user, \
126 (const char*)base, (const char*)pos, len, &obj); \
127 if(ret < 0) { goto _failed; } \
128 goto _push
129
130 #define again_fixed_trail(_cs, trail_len) \
131 trail = trail_len; \
132 cs = _cs; \
133 goto _fixed_trail_again
134 #define again_fixed_trail_if_zero(_cs, trail_len, ifzero) \
135 trail = trail_len; \
136 if(trail == 0) { goto ifzero; } \
137 cs = _cs; \
138 goto _fixed_trail_again
139
140 #define start_container(func, count_, ct_) \
141 if(top >= MSGPACK_EMBED_STACK_SIZE) { \
142 ret = MSGPACK_UNPACK_NOMEM_ERROR; \
143 goto _failed; \
144 } /* FIXME */ \
145 ret = msgpack_unpack_callback(func)(user, count_, &stack[top].obj); \
146 if(ret < 0) { goto _failed; } \
147 if((count_) == 0) { obj = stack[top].obj; goto _push; } \
148 stack[top].ct = ct_; \
149 stack[top].count = count_; \
150 ++top; \
151 goto _header_again
152
153 #define NEXT_CS(p) \
154 ((unsigned int)*p & 0x1f)
155
156 #ifdef USE_CASE_RANGE
157 #define SWITCH_RANGE_BEGIN switch(*p) {
158 #define SWITCH_RANGE(FROM, TO) case FROM ... TO:
159 #define SWITCH_RANGE_DEFAULT default:
160 #define SWITCH_RANGE_END }
161 #else
162 #define SWITCH_RANGE_BEGIN { if(0) {
163 #define SWITCH_RANGE(FROM, TO) } else if(FROM <= *p && *p <= TO) {
164 #define SWITCH_RANGE_DEFAULT } else {
165 #define SWITCH_RANGE_END } }
166 #endif
167
168 if(p == pe) { goto _out; }
169 do {
170 switch(cs) {
171 case MSGPACK_CS_HEADER:
172 SWITCH_RANGE_BEGIN
173 SWITCH_RANGE(0x00, 0x7f) // Positive Fixnum
174 push_fixed_value(_uint8, *(uint8_t*)p);
175 SWITCH_RANGE(0xe0, 0xff) // Negative Fixnum
176 push_fixed_value(_int8, *(int8_t*)p);
177 SWITCH_RANGE(0xc0, 0xdf) // Variable
178 switch(*p) {
179 case 0xc0: // nil
180 push_simple_value(_nil);
181 //case 0xc1: // string
182 // again_terminal_trail(NEXT_CS(p), p+1);
183 case 0xc2: // false
184 push_simple_value(_false);
185 case 0xc3: // true
186 push_simple_value(_true);
187 case 0xc4: // bin 8
188 case 0xc5: // bin 16
189 case 0xc6: // bin 32
190 again_fixed_trail(NEXT_CS(p), 1 << (((unsigned int)*p) & 0x03));
191 case 0xc7: // ext 8
192 case 0xc8: // ext 16
193 case 0xc9: // ext 32
194 again_fixed_trail(NEXT_CS(p), 1 << ((((unsigned int)*p) + 1) & 0x03));
195 case 0xca: // float
196 case 0xcb: // double
197 case 0xcc: // unsigned int 8
198 case 0xcd: // unsigned int 16
199 case 0xce: // unsigned int 32
200 case 0xcf: // unsigned int 64
201 case 0xd0: // signed int 8
202 case 0xd1: // signed int 16
203 case 0xd2: // signed int 32
204 case 0xd3: // signed int 64
205 again_fixed_trail(NEXT_CS(p), 1 << (((unsigned int)*p) & 0x03));
206 case 0xd4: // fixext 1
207 case 0xd5: // fixext 2
208 case 0xd6: // fixext 4
209 case 0xd7: // fixext 8
210 again_fixed_trail_if_zero(MSGPACK_ACS_EXT_VALUE,
211 (1 << (((unsigned int)*p) & 0x03)) + 1, _ext_zero);
212 case 0xd8: // fixext 16
213 again_fixed_trail_if_zero(MSGPACK_ACS_EXT_VALUE, 16+1, _ext_zero);
214
215 case 0xd9: // str 8
216 case 0xda: // str 16
217 case 0xdb: // str 32
218 again_fixed_trail(NEXT_CS(p), 1 << ((((unsigned int)*p) & 0x03) - 1));
219 case 0xdc: // array 16
220 case 0xdd: // array 32
221 case 0xde: // map 16
222 case 0xdf: // map 32
223 again_fixed_trail(NEXT_CS(p), 2u << (((unsigned int)*p) & 0x01));
224 default:
225 ret = MSGPACK_UNPACK_PARSE_ERROR;
226 goto _failed;
227 }
228 SWITCH_RANGE(0xa0, 0xbf) // FixStr
229 again_fixed_trail_if_zero(MSGPACK_ACS_STR_VALUE, ((unsigned int)*p & 0x1f), _str_zero);
230 SWITCH_RANGE(0x90, 0x9f) // FixArray
231 start_container(_array, ((unsigned int)*p) & 0x0f, MSGPACK_CT_ARRAY_ITEM);
232 SWITCH_RANGE(0x80, 0x8f) // FixMap
233 start_container(_map, ((unsigned int)*p) & 0x0f, MSGPACK_CT_MAP_KEY);
234
235 SWITCH_RANGE_DEFAULT
236 ret = MSGPACK_UNPACK_PARSE_ERROR;
237 goto _failed;
238 SWITCH_RANGE_END
239 // end MSGPACK_CS_HEADER
240
241
242 _fixed_trail_again:
243 ++p;
244 // fallthrough
245
246 default:
247 if((size_t)(pe - p) < trail) { goto _out; }
248 n = p; p += trail - 1;
249 switch(cs) {
250 //case MSGPACK_CS_
251 //case MSGPACK_CS_
252 case MSGPACK_CS_FLOAT: {
253 union { uint32_t i; float f; } mem;
254 _msgpack_load32(uint32_t, n, &mem.i);
255 push_fixed_value(_float, mem.f); }
256 case MSGPACK_CS_DOUBLE: {
257 union { uint64_t i; double f; } mem;
258 _msgpack_load64(uint64_t, n, &mem.i);
259 #if defined(TARGET_OS_IPHONE)
260 // ok
261 #elif defined(__arm__) && !(__ARM_EABI__) // arm-oabi
262 // https://github.com/msgpack/msgpack-perl/pull/1
263 mem.i = (mem.i & 0xFFFFFFFFUL) << 32UL | (mem.i >> 32UL);
264 #endif
265 push_fixed_value(_double, mem.f); }
266 case MSGPACK_CS_UINT_8:
267 push_fixed_value(_uint8, *(uint8_t*)n);
268 case MSGPACK_CS_UINT_16:{
269 uint16_t tmp;
270 _msgpack_load16(uint16_t,n,&tmp);
271 push_fixed_value(_uint16, tmp);
272 }
273 case MSGPACK_CS_UINT_32:{
274 uint32_t tmp;
275 _msgpack_load32(uint32_t,n,&tmp);
276 push_fixed_value(_uint32, tmp);
277 }
278 case MSGPACK_CS_UINT_64:{
279 uint64_t tmp;
280 _msgpack_load64(uint64_t,n,&tmp);
281 push_fixed_value(_uint64, tmp);
282 }
283 case MSGPACK_CS_INT_8:
284 push_fixed_value(_int8, *(int8_t*)n);
285 case MSGPACK_CS_INT_16:{
286 int16_t tmp;
287 _msgpack_load16(int16_t,n,&tmp);
288 push_fixed_value(_int16, tmp);
289 }
290 case MSGPACK_CS_INT_32:{
291 int32_t tmp;
292 _msgpack_load32(int32_t,n,&tmp);
293 push_fixed_value(_int32, tmp);
294 }
295 case MSGPACK_CS_INT_64:{
296 int64_t tmp;
297 _msgpack_load64(int64_t,n,&tmp);
298 push_fixed_value(_int64, tmp);
299 }
300 case MSGPACK_CS_FIXEXT_1:
301 again_fixed_trail_if_zero(MSGPACK_ACS_EXT_VALUE, 1+1, _ext_zero);
302 case MSGPACK_CS_FIXEXT_2:
303 again_fixed_trail_if_zero(MSGPACK_ACS_EXT_VALUE, 2+1, _ext_zero);
304 case MSGPACK_CS_FIXEXT_4:
305 again_fixed_trail_if_zero(MSGPACK_ACS_EXT_VALUE, 4+1, _ext_zero);
306 case MSGPACK_CS_FIXEXT_8:
307 again_fixed_trail_if_zero(MSGPACK_ACS_EXT_VALUE, 8+1, _ext_zero);
308 case MSGPACK_CS_FIXEXT_16:
309 again_fixed_trail_if_zero(MSGPACK_ACS_EXT_VALUE, 16+1, _ext_zero);
310 case MSGPACK_CS_STR_8:
311 again_fixed_trail_if_zero(MSGPACK_ACS_STR_VALUE, *(uint8_t*)n, _str_zero);
312 case MSGPACK_CS_BIN_8:
313 again_fixed_trail_if_zero(MSGPACK_ACS_BIN_VALUE, *(uint8_t*)n, _bin_zero);
314 case MSGPACK_CS_EXT_8:
315 again_fixed_trail_if_zero(MSGPACK_ACS_EXT_VALUE, (*(uint8_t*)n) + 1, _ext_zero);
316 case MSGPACK_CS_STR_16:{
317 uint16_t tmp;
318 _msgpack_load16(uint16_t,n,&tmp);
319 again_fixed_trail_if_zero(MSGPACK_ACS_STR_VALUE, tmp, _str_zero);
320 }
321 case MSGPACK_CS_BIN_16:{
322 uint16_t tmp;
323 _msgpack_load16(uint16_t,n,&tmp);
324 again_fixed_trail_if_zero(MSGPACK_ACS_BIN_VALUE, tmp, _bin_zero);
325 }
326 case MSGPACK_CS_EXT_16:{
327 uint16_t tmp;
328 _msgpack_load16(uint16_t,n,&tmp);
329 again_fixed_trail_if_zero(MSGPACK_ACS_EXT_VALUE, tmp + 1, _ext_zero);
330 }
331 case MSGPACK_CS_STR_32:{
332 uint32_t tmp;
333 _msgpack_load32(uint32_t,n,&tmp);
334 again_fixed_trail_if_zero(MSGPACK_ACS_STR_VALUE, tmp, _str_zero);
335 }
336 case MSGPACK_CS_BIN_32:{
337 uint32_t tmp;
338 _msgpack_load32(uint32_t,n,&tmp);
339 again_fixed_trail_if_zero(MSGPACK_ACS_BIN_VALUE, tmp, _bin_zero);
340 }
341 case MSGPACK_CS_EXT_32:{
342 uint32_t tmp;
343 _msgpack_load32(uint32_t,n,&tmp);
344 again_fixed_trail_if_zero(MSGPACK_ACS_EXT_VALUE, tmp + 1, _ext_zero);
345 }
346 case MSGPACK_ACS_STR_VALUE:
347 _str_zero:
348 push_variable_value(_str, data, n, trail);
349 case MSGPACK_ACS_BIN_VALUE:
350 _bin_zero:
351 push_variable_value(_bin, data, n, trail);
352 case MSGPACK_ACS_EXT_VALUE:
353 _ext_zero:
354 push_variable_value(_ext, data, n, trail);
355
356 case MSGPACK_CS_ARRAY_16:{
357 uint16_t tmp;
358 _msgpack_load16(uint16_t,n,&tmp);
359 start_container(_array, tmp, MSGPACK_CT_ARRAY_ITEM);
360 }
361 case MSGPACK_CS_ARRAY_32:{
362 /* FIXME security guard */
363 uint32_t tmp;
364 _msgpack_load32(uint32_t,n,&tmp);
365 start_container(_array, tmp, MSGPACK_CT_ARRAY_ITEM);
366 }
367
368 case MSGPACK_CS_MAP_16:{
369 uint16_t tmp;
370 _msgpack_load16(uint16_t,n,&tmp);
371 start_container(_map, tmp, MSGPACK_CT_MAP_KEY);
372 }
373 case MSGPACK_CS_MAP_32:{
374 /* FIXME security guard */
375 uint32_t tmp;
376 _msgpack_load32(uint32_t,n,&tmp);
377 start_container(_map, tmp, MSGPACK_CT_MAP_KEY);
378 }
379
380 default:
381 ret = MSGPACK_UNPACK_PARSE_ERROR;
382 goto _failed;
383 }
384 }
385
386 _push:
387 if(top == 0) { goto _finish; }
388 c = &stack[top-1];
389 switch(c->ct) {
390 case MSGPACK_CT_ARRAY_ITEM:
391 ret = msgpack_unpack_callback(_array_item)(user, &c->obj, obj); \
392 if(ret < 0) { goto _failed; }
393 if(--c->count == 0) {
394 obj = c->obj;
395 --top;
396 /*printf("stack pop %d\n", top);*/
397 goto _push;
398 }
399 goto _header_again;
400 case MSGPACK_CT_MAP_KEY:
401 c->map_key = obj;
402 c->ct = MSGPACK_CT_MAP_VALUE;
403 goto _header_again;
404 case MSGPACK_CT_MAP_VALUE:
405 ret = msgpack_unpack_callback(_map_item)(user, &c->obj, c->map_key, obj); \
406 if(ret < 0) { goto _failed; }
407 if(--c->count == 0) {
408 obj = c->obj;
409 --top;
410 /*printf("stack pop %d\n", top);*/
411 goto _push;
412 }
413 c->ct = MSGPACK_CT_MAP_KEY;
414 goto _header_again;
415
416 default:
417 ret = MSGPACK_UNPACK_PARSE_ERROR;
418 goto _failed;
419 }
420
421 _header_again:
422 cs = MSGPACK_CS_HEADER;
423 ++p;
424 } while(p != pe);
425 goto _out;
426
427
428 _finish:
429 stack[0].obj = obj;
430 ++p;
431 ret = 1;
432 /*printf("-- finish --\n"); */
433 goto _end;
434
435 _failed:
436 /*printf("** FAILED **\n"); */
437 goto _end;
438
439 _out:
440 ret = 0;
441 goto _end;
442
443 _end:
444 ctx->cs = cs;
445 ctx->trail = trail;
446 ctx->top = top;
447 *off = (size_t)(p - (const unsigned char*)data);
448
449 return ret;
450 }
451 }
452
453 #undef msgpack_unpack_func
454 #undef msgpack_unpack_callback
455 #undef msgpack_unpack_struct
456 #undef msgpack_unpack_object
457 #undef msgpack_unpack_user
458
459 #undef push_simple_value
460 #undef push_fixed_value
461 #undef push_variable_value
462 #undef again_fixed_trail
463 #undef again_fixed_trail_if_zero
464 #undef start_container
465
466 #undef NEXT_CS
467
468 #undef SWITCH_RANGE_BEGIN
469 #undef SWITCH_RANGE
470 #undef SWITCH_RANGE_DEFAULT
471 #undef SWITCH_RANGE_END
This page took 0.056998 seconds and 4 git commands to generate.