xref: /freebsd/contrib/libucl/src/ucl_msgpack.c (revision 2aa00a6001d7105eaf0d0288a441fa69f06fa534)
1 /*
2  * Copyright (c) 2015, Vsevolod Stakhov
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *	 * Redistributions of source code must retain the above copyright
8  *	   notice, this list of conditions and the following disclaimer.
9  *	 * Redistributions in binary form must reproduce the above copyright
10  *	   notice, this list of conditions and the following disclaimer in the
11  *	   documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY AUTHOR ''AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16  * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY
17  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  */
24 
25 
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29 
30 #include "ucl.h"
31 #include "ucl_internal.h"
32 
33 #ifdef HAVE_ENDIAN_H
34 #include <endian.h>
35 #elif defined(HAVE_SYS_ENDIAN_H)
36 #include <sys/endian.h>
37 #elif defined(HAVE_MACHINE_ENDIAN_H)
38 #include <machine/endian.h>
39 #endif
40 
41 #if !defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)
42 	#if __BYTE_ORDER == __LITTLE_ENDIAN
43 		#define __LITTLE_ENDIAN__
44 	#elif __BYTE_ORDER == __BIG_ENDIAN
45 		#define __BIG_ENDIAN__
46 	#elif _WIN32
47 		#define __LITTLE_ENDIAN__
48 	#endif
49 #endif
50 
51 #define SWAP_LE_BE16(val)	((uint16_t) ( 		\
52 		(uint16_t) ((uint16_t) (val) >> 8) |	\
53 		(uint16_t) ((uint16_t) (val) << 8)))
54 
55 #if defined(__clang__) || (defined(__GNUC__) && __GNUC__ >= 4 && defined (__GNUC_MINOR__) && __GNUC_MINOR__ >= 3)
56 #	define SWAP_LE_BE32(val) ((uint32_t)__builtin_bswap32 ((uint32_t)(val)))
57 #	define SWAP_LE_BE64(val) ((uint64_t)__builtin_bswap64 ((uint64_t)(val)))
58 #else
59 	#define SWAP_LE_BE32(val)	((uint32_t)( \
60 		(((uint32_t)(val) & (uint32_t)0x000000ffU) << 24) | \
61 		(((uint32_t)(val) & (uint32_t)0x0000ff00U) <<  8) | \
62 		(((uint32_t)(val) & (uint32_t)0x00ff0000U) >>  8) | \
63 		(((uint32_t)(val) & (uint32_t)0xff000000U) >> 24)))
64 
65 	#define SWAP_LE_BE64(val)	((uint64_t)( 			\
66 		  (((uint64_t)(val) &							\
67 		(uint64_t)(0x00000000000000ffULL)) << 56) |		\
68 		  (((uint64_t)(val) &							\
69 		(uint64_t)(0x000000000000ff00ULL)) << 40) |		\
70 		  (((uint64_t)(val) &							\
71 		(uint64_t)(0x0000000000ff0000ULL)) << 24) |		\
72 		  (((uint64_t)(val) &							\
73 		(uint64_t) (0x00000000ff000000ULL)) <<  8) |	\
74 		  (((uint64_t)(val) &							\
75 		(uint64_t)(0x000000ff00000000ULL)) >>  8) |		\
76 		  (((uint64_t)(val) &							\
77 		(uint64_t)(0x0000ff0000000000ULL)) >> 24) |		\
78 		  (((uint64_t)(val) &							\
79 		(uint64_t)(0x00ff000000000000ULL)) >> 40) |		\
80 		  (((uint64_t)(val) &							\
81 		(uint64_t)(0xff00000000000000ULL)) >> 56)))
82 #endif
83 
84 #ifdef __LITTLE_ENDIAN__
85 #define TO_BE16 SWAP_LE_BE16
86 #define TO_BE32 SWAP_LE_BE32
87 #define TO_BE64 SWAP_LE_BE64
88 #define FROM_BE16 SWAP_LE_BE16
89 #define FROM_BE32 SWAP_LE_BE32
90 #define FROM_BE64 SWAP_LE_BE64
91 #else
92 #define TO_BE16(val) (uint16_t)(val)
93 #define TO_BE32(val) (uint32_t)(val)
94 #define TO_BE64(val) (uint64_t)(val)
95 #define FROM_BE16(val) (uint16_t)(val)
96 #define FROM_BE32(val) (uint32_t)(val)
97 #define FROM_BE64(val) (uint64_t)(val)
98 #endif
99 
100 void
101 ucl_emitter_print_int_msgpack (struct ucl_emitter_context *ctx, int64_t val)
102 {
103 	const struct ucl_emitter_functions *func = ctx->func;
104 	unsigned char buf[sizeof(uint64_t) + 1];
105 	const unsigned char mask_positive = 0x7f, mask_negative = 0xe0,
106 		uint8_ch = 0xcc, uint16_ch = 0xcd, uint32_ch = 0xce, uint64_ch = 0xcf,
107 		int8_ch = 0xd0, int16_ch = 0xd1, int32_ch = 0xd2, int64_ch = 0xd3;
108 	unsigned len;
109 
110 	if (val >= 0) {
111 		if (val <= 0x7f) {
112 			/* Fixed num 7 bits */
113 			len = 1;
114 			buf[0] = mask_positive & val;
115 		}
116 		else if (val <= 0xff) {
117 			len = 2;
118 			buf[0] = uint8_ch;
119 			buf[1] = val & 0xff;
120 		}
121 		else if (val <= 0xffff) {
122 			uint16_t v = TO_BE16 (val);
123 
124 			len = 3;
125 			buf[0] = uint16_ch;
126 			memcpy (&buf[1], &v, sizeof (v));
127 		}
128 		else if (val <= 0xffffffff) {
129 			uint32_t v = TO_BE32 (val);
130 
131 			len = 5;
132 			buf[0] = uint32_ch;
133 			memcpy (&buf[1], &v, sizeof (v));
134 		}
135 		else {
136 			uint64_t v = TO_BE64 (val);
137 
138 			len = 9;
139 			buf[0] = uint64_ch;
140 			memcpy (&buf[1], &v, sizeof (v));
141 		}
142 	}
143 	else {
144 		uint64_t uval;
145 		/* Bithack abs */
146 		uval = ((val ^ (val >> 63)) - (val >> 63));
147 
148 		if (val > -(1 << 5)) {
149 			len = 1;
150 			buf[0] = (mask_negative | uval) & 0xff;
151 		}
152 		else if (uval <= 0xff) {
153 			len = 2;
154 			buf[0] = int8_ch;
155 			buf[1] = (unsigned char)val;
156 		}
157 		else if (uval <= 0xffff) {
158 			uint16_t v = TO_BE16 (val);
159 
160 			len = 3;
161 			buf[0] = int16_ch;
162 			memcpy (&buf[1], &v, sizeof (v));
163 		}
164 		else if (uval <= 0xffffffff) {
165 			uint32_t v = TO_BE32 (val);
166 
167 			len = 5;
168 			buf[0] = int32_ch;
169 			memcpy (&buf[1], &v, sizeof (v));
170 		}
171 		else {
172 			uint64_t v = TO_BE64 (val);
173 
174 			len = 9;
175 			buf[0] = int64_ch;
176 			memcpy (&buf[1], &v, sizeof (v));
177 		}
178 	}
179 
180 	func->ucl_emitter_append_len (buf, len, func->ud);
181 }
182 
183 void
184 ucl_emitter_print_double_msgpack (struct ucl_emitter_context *ctx, double val)
185 {
186 	const struct ucl_emitter_functions *func = ctx->func;
187 	union {
188 		double d;
189 		uint64_t i;
190 	} u;
191 	const unsigned char dbl_ch = 0xcb;
192 	unsigned char buf[sizeof(double) + 1];
193 
194 	/* Convert to big endian */
195 	u.d = val;
196 	u.i = TO_BE64 (u.i);
197 
198 	buf[0] = dbl_ch;
199 	memcpy (&buf[1], &u.d, sizeof (double));
200 	func->ucl_emitter_append_len (buf, sizeof (buf), func->ud);
201 }
202 
203 void
204 ucl_emitter_print_bool_msgpack (struct ucl_emitter_context *ctx, bool val)
205 {
206 	const struct ucl_emitter_functions *func = ctx->func;
207 	const unsigned char true_ch = 0xc3, false_ch = 0xc2;
208 
209 	func->ucl_emitter_append_character (val ? true_ch : false_ch, 1, func->ud);
210 }
211 
212 void
213 ucl_emitter_print_string_msgpack (struct ucl_emitter_context *ctx,
214 		const char *s, size_t len)
215 {
216 	const struct ucl_emitter_functions *func = ctx->func;
217 	const unsigned char fix_mask = 0xA0, l8_ch = 0xd9, l16_ch = 0xda, l32_ch = 0xdb;
218 	unsigned char buf[5];
219 	unsigned blen;
220 
221 	if (len <= 0x1F) {
222 		blen = 1;
223 		buf[0] = (len | fix_mask) & 0xff;
224 	}
225 	else if (len <= 0xff) {
226 		blen = 2;
227 		buf[0] = l8_ch;
228 		buf[1] = len & 0xff;
229 	}
230 	else if (len <= 0xffff) {
231 		uint16_t bl = TO_BE16 (len);
232 
233 		blen = 3;
234 		buf[0] = l16_ch;
235 		memcpy (&buf[1], &bl, sizeof (bl));
236 	}
237 	else {
238 		uint32_t bl = TO_BE32 (len);
239 
240 		blen = 5;
241 		buf[0] = l32_ch;
242 		memcpy (&buf[1], &bl, sizeof (bl));
243 	}
244 
245 	func->ucl_emitter_append_len (buf, blen, func->ud);
246 	func->ucl_emitter_append_len (s, len, func->ud);
247 }
248 
249 void
250 ucl_emitter_print_binary_string_msgpack (struct ucl_emitter_context *ctx,
251 		const char *s, size_t len)
252 {
253 	const struct ucl_emitter_functions *func = ctx->func;
254 	const unsigned char l8_ch = 0xc4, l16_ch = 0xc5, l32_ch = 0xc6;
255 	unsigned char buf[5];
256 	unsigned blen;
257 
258 	if (len <= 0xff) {
259 		blen = 2;
260 		buf[0] = l8_ch;
261 		buf[1] = len & 0xff;
262 	}
263 	else if (len <= 0xffff) {
264 		uint16_t bl = TO_BE16 (len);
265 
266 		blen = 3;
267 		buf[0] = l16_ch;
268 		memcpy (&buf[1], &bl, sizeof (bl));
269 	}
270 	else {
271 		uint32_t bl = TO_BE32 (len);
272 
273 		blen = 5;
274 		buf[0] = l32_ch;
275 		memcpy (&buf[1], &bl, sizeof (bl));
276 	}
277 
278 	func->ucl_emitter_append_len (buf, blen, func->ud);
279 	func->ucl_emitter_append_len (s, len, func->ud);
280 }
281 
282 void
283 ucl_emitter_print_null_msgpack (struct ucl_emitter_context *ctx)
284 {
285 	const struct ucl_emitter_functions *func = ctx->func;
286 	const unsigned char nil = 0xc0;
287 
288 	func->ucl_emitter_append_character (nil, 1, func->ud);
289 }
290 
291 void
292 ucl_emitter_print_key_msgpack (bool print_key, struct ucl_emitter_context *ctx,
293 		const ucl_object_t *obj)
294 {
295 	if (print_key) {
296 		ucl_emitter_print_string_msgpack (ctx, obj->key, obj->keylen);
297 	}
298 }
299 
300 void
301 ucl_emitter_print_array_msgpack (struct ucl_emitter_context *ctx, size_t len)
302 {
303 	const struct ucl_emitter_functions *func = ctx->func;
304 	const unsigned char fix_mask = 0x90, l16_ch = 0xdc, l32_ch = 0xdd;
305 	unsigned char buf[5];
306 	unsigned blen;
307 
308 	if (len <= 0xF) {
309 		blen = 1;
310 		buf[0] = (len | fix_mask) & 0xff;
311 	}
312 	else if (len <= 0xffff) {
313 		uint16_t bl = TO_BE16 (len);
314 
315 		blen = 3;
316 		buf[0] = l16_ch;
317 		memcpy (&buf[1], &bl, sizeof (bl));
318 	}
319 	else {
320 		uint32_t bl = TO_BE32 (len);
321 
322 		blen = 5;
323 		buf[0] = l32_ch;
324 		memcpy (&buf[1], &bl, sizeof (bl));
325 	}
326 
327 	func->ucl_emitter_append_len (buf, blen, func->ud);
328 }
329 
330 void
331 ucl_emitter_print_object_msgpack (struct ucl_emitter_context *ctx, size_t len)
332 {
333 	const struct ucl_emitter_functions *func = ctx->func;
334 	const unsigned char fix_mask = 0x80, l16_ch = 0xde, l32_ch = 0xdf;
335 	unsigned char buf[5];
336 	unsigned blen;
337 
338 	if (len <= 0xF) {
339 		blen = 1;
340 		buf[0] = (len | fix_mask) & 0xff;
341 	}
342 	else if (len <= 0xffff) {
343 		uint16_t bl = TO_BE16 (len);
344 
345 		blen = 3;
346 		buf[0] = l16_ch;
347 		memcpy (&buf[1], &bl, sizeof (bl));
348 	}
349 	else {
350 		uint32_t bl = TO_BE32 (len);
351 
352 		blen = 5;
353 		buf[0] = l32_ch;
354 		memcpy (&buf[1], &bl, sizeof (bl));
355 	}
356 
357 	func->ucl_emitter_append_len (buf, blen, func->ud);
358 }
359 
360 
361 enum ucl_msgpack_format {
362 	msgpack_positive_fixint = 0,
363 	msgpack_fixmap,
364 	msgpack_fixarray,
365 	msgpack_fixstr,
366 	msgpack_nil,
367 	msgpack_false,
368 	msgpack_true,
369 	msgpack_bin8,
370 	msgpack_bin16,
371 	msgpack_bin32,
372 	msgpack_ext8,
373 	msgpack_ext16,
374 	msgpack_ext32,
375 	msgpack_float32,
376 	msgpack_float64,
377 	msgpack_uint8,
378 	msgpack_uint16,
379 	msgpack_uint32,
380 	msgpack_uint64,
381 	msgpack_int8,
382 	msgpack_int16,
383 	msgpack_int32,
384 	msgpack_int64,
385 	msgpack_fixext1,
386 	msgpack_fixext2,
387 	msgpack_fixext4,
388 	msgpack_fixext8,
389 	msgpack_fixext16,
390 	msgpack_str8,
391 	msgpack_str16,
392 	msgpack_str32,
393 	msgpack_array16,
394 	msgpack_array32,
395 	msgpack_map16,
396 	msgpack_map32,
397 	msgpack_negative_fixint,
398 	msgpack_invalid
399 };
400 
401 typedef ssize_t (*ucl_msgpack_parse_function)(struct ucl_parser *parser,
402 		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
403 		const unsigned char *pos, size_t remain);
404 
405 static ssize_t ucl_msgpack_parse_map (struct ucl_parser *parser,
406 		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
407 		const unsigned char *pos, size_t remain);
408 static ssize_t ucl_msgpack_parse_array (struct ucl_parser *parser,
409 		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
410 		const unsigned char *pos, size_t remain);
411 static ssize_t ucl_msgpack_parse_string (struct ucl_parser *parser,
412 		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
413 		const unsigned char *pos, size_t remain);
414 static ssize_t ucl_msgpack_parse_int (struct ucl_parser *parser,
415 		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
416 		const unsigned char *pos, size_t remain);
417 static ssize_t ucl_msgpack_parse_float (struct ucl_parser *parser,
418 		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
419 		const unsigned char *pos, size_t remain);
420 static ssize_t ucl_msgpack_parse_bool (struct ucl_parser *parser,
421 		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
422 		const unsigned char *pos, size_t remain);
423 static ssize_t ucl_msgpack_parse_null (struct ucl_parser *parser,
424 		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
425 		const unsigned char *pos, size_t remain);
426 static ssize_t ucl_msgpack_parse_ignore (struct ucl_parser *parser,
427 		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
428 		const unsigned char *pos, size_t remain);
429 
430 #define MSGPACK_FLAG_FIXED (1 << 0)
431 #define MSGPACK_FLAG_CONTAINER (1 << 1)
432 #define MSGPACK_FLAG_TYPEVALUE (1 << 2)
433 #define MSGPACK_FLAG_EXT (1 << 3)
434 #define MSGPACK_FLAG_ASSOC (1 << 4)
435 #define MSGPACK_FLAG_KEY (1 << 5)
436 #define MSGPACK_CONTAINER_BIT (1ULL << 62)
437 
438 /*
439  * Search tree packed in array
440  */
441 struct ucl_msgpack_parser {
442 	uint8_t prefix;						/* Prefix byte					*/
443 	uint8_t prefixlen;					/* Length of prefix in bits		*/
444 	uint8_t fmt;						/* The desired format 			*/
445 	uint8_t len;						/* Length of the object
446 										  (either length bytes
447 										  or length of value in case
448 										  of fixed objects 				*/
449 	uint8_t flags;						/* Flags of the specified type	*/
450 	ucl_msgpack_parse_function func;	/* Parser function				*/
451 } parsers[] = {
452 	{
453 			0xa0,
454 			3,
455 			msgpack_fixstr,
456 			0,
457 			MSGPACK_FLAG_FIXED|MSGPACK_FLAG_KEY,
458 			ucl_msgpack_parse_string
459 	},
460 	{
461 			0x0,
462 			1,
463 			msgpack_positive_fixint,
464 			0,
465 			MSGPACK_FLAG_FIXED|MSGPACK_FLAG_TYPEVALUE,
466 			ucl_msgpack_parse_int
467 	},
468 	{
469 			0xe0,
470 			3,
471 			msgpack_negative_fixint,
472 			0,
473 			MSGPACK_FLAG_FIXED|MSGPACK_FLAG_TYPEVALUE,
474 			ucl_msgpack_parse_int
475 	},
476 	{
477 			0x80,
478 			4,
479 			msgpack_fixmap,
480 			0,
481 			MSGPACK_FLAG_FIXED|MSGPACK_FLAG_CONTAINER|MSGPACK_FLAG_ASSOC,
482 			ucl_msgpack_parse_map
483 	},
484 	{
485 			0x90,
486 			4,
487 			msgpack_fixarray,
488 			0,
489 			MSGPACK_FLAG_FIXED|MSGPACK_FLAG_CONTAINER,
490 			ucl_msgpack_parse_array
491 	},
492 	{
493 			0xd9,
494 			8,
495 			msgpack_str8,
496 			1,
497 			MSGPACK_FLAG_KEY,
498 			ucl_msgpack_parse_string
499 	},
500 	{
501 			0xc4,
502 			8,
503 			msgpack_bin8,
504 			1,
505 			MSGPACK_FLAG_KEY,
506 			ucl_msgpack_parse_string
507 	},
508 	{
509 			0xcf,
510 			8,
511 			msgpack_uint64,
512 			8,
513 			MSGPACK_FLAG_FIXED,
514 			ucl_msgpack_parse_int
515 	},
516 	{
517 			0xd3,
518 			8,
519 			msgpack_int64,
520 			8,
521 			MSGPACK_FLAG_FIXED,
522 			ucl_msgpack_parse_int
523 	},
524 	{
525 			0xce,
526 			8,
527 			msgpack_uint32,
528 			4,
529 			MSGPACK_FLAG_FIXED,
530 			ucl_msgpack_parse_int
531 	},
532 	{
533 			0xd2,
534 			8,
535 			msgpack_int32,
536 			4,
537 			MSGPACK_FLAG_FIXED,
538 			ucl_msgpack_parse_int
539 	},
540 	{
541 			0xcb,
542 			8,
543 			msgpack_float64,
544 			8,
545 			MSGPACK_FLAG_FIXED,
546 			ucl_msgpack_parse_float
547 	},
548 	{
549 			0xca,
550 			8,
551 			msgpack_float32,
552 			4,
553 			MSGPACK_FLAG_FIXED,
554 			ucl_msgpack_parse_float
555 	},
556 	{
557 			0xc2,
558 			8,
559 			msgpack_false,
560 			1,
561 			MSGPACK_FLAG_FIXED | MSGPACK_FLAG_TYPEVALUE,
562 			ucl_msgpack_parse_bool
563 	},
564 	{
565 			0xc3,
566 			8,
567 			msgpack_true,
568 			1,
569 			MSGPACK_FLAG_FIXED | MSGPACK_FLAG_TYPEVALUE,
570 			ucl_msgpack_parse_bool
571 	},
572 	{
573 			0xcc,
574 			8,
575 			msgpack_uint8,
576 			1,
577 			MSGPACK_FLAG_FIXED,
578 			ucl_msgpack_parse_int
579 	},
580 	{
581 			0xcd,
582 			8,
583 			msgpack_uint16,
584 			2,
585 			MSGPACK_FLAG_FIXED,
586 			ucl_msgpack_parse_int
587 	},
588 	{
589 			0xd0,
590 			8,
591 			msgpack_int8,
592 			1,
593 			MSGPACK_FLAG_FIXED,
594 			ucl_msgpack_parse_int
595 	},
596 	{
597 			0xd1,
598 			8,
599 			msgpack_int16,
600 			2,
601 			MSGPACK_FLAG_FIXED,
602 			ucl_msgpack_parse_int
603 	},
604 	{
605 			0xc0,
606 			8,
607 			msgpack_nil,
608 			0,
609 			MSGPACK_FLAG_FIXED | MSGPACK_FLAG_TYPEVALUE,
610 			ucl_msgpack_parse_null
611 	},
612 	{
613 			0xda,
614 			8,
615 			msgpack_str16,
616 			2,
617 			MSGPACK_FLAG_KEY,
618 			ucl_msgpack_parse_string
619 	},
620 	{
621 			0xdb,
622 			8,
623 			msgpack_str32,
624 			4,
625 			MSGPACK_FLAG_KEY,
626 			ucl_msgpack_parse_string
627 	},
628 	{
629 			0xc5,
630 			8,
631 			msgpack_bin16,
632 			2,
633 			MSGPACK_FLAG_KEY,
634 			ucl_msgpack_parse_string
635 	},
636 	{
637 			0xc6,
638 			8,
639 			msgpack_bin32,
640 			4,
641 			MSGPACK_FLAG_KEY,
642 			ucl_msgpack_parse_string
643 	},
644 	{
645 			0xdc,
646 			8,
647 			msgpack_array16,
648 			2,
649 			MSGPACK_FLAG_CONTAINER,
650 			ucl_msgpack_parse_array
651 	},
652 	{
653 			0xdd,
654 			8,
655 			msgpack_array32,
656 			4,
657 			MSGPACK_FLAG_CONTAINER,
658 			ucl_msgpack_parse_array
659 	},
660 	{
661 			0xde,
662 			8,
663 			msgpack_map16,
664 			2,
665 			MSGPACK_FLAG_CONTAINER|MSGPACK_FLAG_ASSOC,
666 			ucl_msgpack_parse_map
667 	},
668 	{
669 			0xdf,
670 			8,
671 			msgpack_map32,
672 			4,
673 			MSGPACK_FLAG_CONTAINER|MSGPACK_FLAG_ASSOC,
674 			ucl_msgpack_parse_map
675 	},
676 	{
677 			0xc7,
678 			8,
679 			msgpack_ext8,
680 			1,
681 			MSGPACK_FLAG_EXT,
682 			ucl_msgpack_parse_ignore
683 	},
684 	{
685 			0xc8,
686 			8,
687 			msgpack_ext16,
688 			2,
689 			MSGPACK_FLAG_EXT,
690 			ucl_msgpack_parse_ignore
691 	},
692 	{
693 			0xc9,
694 			8,
695 			msgpack_ext32,
696 			4,
697 			MSGPACK_FLAG_EXT,
698 			ucl_msgpack_parse_ignore
699 	},
700 	{
701 			0xd4,
702 			8,
703 			msgpack_fixext1,
704 			1,
705 			MSGPACK_FLAG_FIXED | MSGPACK_FLAG_EXT,
706 			ucl_msgpack_parse_ignore
707 	},
708 	{
709 			0xd5,
710 			8,
711 			msgpack_fixext2,
712 			2,
713 			MSGPACK_FLAG_FIXED | MSGPACK_FLAG_EXT,
714 			ucl_msgpack_parse_ignore
715 	},
716 	{
717 			0xd6,
718 			8,
719 			msgpack_fixext4,
720 			4,
721 			MSGPACK_FLAG_FIXED | MSGPACK_FLAG_EXT,
722 			ucl_msgpack_parse_ignore
723 	},
724 	{
725 			0xd7,
726 			8,
727 			msgpack_fixext8,
728 			8,
729 			MSGPACK_FLAG_FIXED | MSGPACK_FLAG_EXT,
730 			ucl_msgpack_parse_ignore
731 	},
732 	{
733 			0xd8,
734 			8,
735 			msgpack_fixext16,
736 			16,
737 			MSGPACK_FLAG_FIXED | MSGPACK_FLAG_EXT,
738 			ucl_msgpack_parse_ignore
739 	}
740 };
741 
742 #undef MSGPACK_DEBUG_PARSER
743 
744 static inline struct ucl_msgpack_parser *
745 ucl_msgpack_get_parser_from_type (unsigned char t)
746 {
747 	unsigned int i, shift, mask;
748 
749 	for (i = 0; i < sizeof (parsers) / sizeof (parsers[0]); i ++) {
750 		shift = CHAR_BIT - parsers[i].prefixlen;
751 		mask = parsers[i].prefix >> shift;
752 
753 		if (mask == (t >> shift)) {
754 			return &parsers[i];
755 		}
756 	}
757 
758 	return NULL;
759 }
760 
761 static inline struct ucl_stack *
762 ucl_msgpack_get_container (struct ucl_parser *parser,
763 		struct ucl_msgpack_parser *obj_parser, uint64_t len)
764 {
765 	struct ucl_stack *stack;
766 
767 	assert (obj_parser != NULL);
768 
769 	if (obj_parser->flags & MSGPACK_FLAG_CONTAINER) {
770 		assert ((len & MSGPACK_CONTAINER_BIT) == 0);
771 		/*
772 		 * Insert new container to the stack
773 		 */
774 		if (parser->stack == NULL) {
775 			parser->stack = calloc (1, sizeof (struct ucl_stack));
776 
777 			if (parser->stack == NULL) {
778 				ucl_create_err (&parser->err, "no memory");
779 				return NULL;
780 			}
781 		}
782 		else {
783 			stack = calloc (1, sizeof (struct ucl_stack));
784 
785 			if (stack == NULL) {
786 				ucl_create_err (&parser->err, "no memory");
787 				return NULL;
788 			}
789 
790 			stack->next = parser->stack;
791 			parser->stack = stack;
792 		}
793 
794 		parser->stack->level = len | MSGPACK_CONTAINER_BIT;
795 
796 #ifdef MSGPACK_DEBUG_PARSER
797 		stack = parser->stack;
798 		while (stack) {
799 			fprintf(stderr, "+");
800 			stack = stack->next;
801 		}
802 
803 		fprintf(stderr, "%s -> %d\n", obj_parser->flags & MSGPACK_FLAG_ASSOC ? "object" : "array", (int)len);
804 #endif
805 	}
806 	else {
807 		/*
808 		 * Get the current stack top
809 		 */
810 		if (parser->stack) {
811 			return parser->stack;
812 		}
813 		else {
814 			ucl_create_err (&parser->err, "bad top level object for msgpack");
815 			return NULL;
816 		}
817 	}
818 
819 	return parser->stack;
820 }
821 
822 static bool
823 ucl_msgpack_is_container_finished (struct ucl_stack *container)
824 {
825 	uint64_t level;
826 
827 	assert (container != NULL);
828 
829 	if (container->level & MSGPACK_CONTAINER_BIT) {
830 		level = container->level & ~MSGPACK_CONTAINER_BIT;
831 
832 		if (level == 0) {
833 			return true;
834 		}
835 	}
836 
837 	return false;
838 }
839 
840 static bool
841 ucl_msgpack_insert_object (struct ucl_parser *parser,
842 		const unsigned char *key,
843 		size_t keylen, ucl_object_t *obj)
844 {
845 	uint64_t level;
846 	struct ucl_stack *container;
847 
848 	container = parser->stack;
849 	assert (container != NULL);
850 	assert (container->level > 0);
851 	assert (obj != NULL);
852 	assert (container->obj != NULL);
853 
854 	if (container->obj->type == UCL_ARRAY) {
855 		ucl_array_append (container->obj, obj);
856 	}
857 	else if (container->obj->type == UCL_OBJECT) {
858 		if (key == NULL || keylen == 0) {
859 			ucl_create_err (&parser->err, "cannot insert object with no key");
860 			return false;
861 		}
862 
863 		obj->key = key;
864 		obj->keylen = keylen;
865 
866 		if (!(parser->flags & UCL_PARSER_ZEROCOPY)) {
867 			ucl_copy_key_trash (obj);
868 		}
869 
870 		ucl_parser_process_object_element (parser, obj);
871 	}
872 	else {
873 		ucl_create_err (&parser->err, "bad container type");
874 		return false;
875 	}
876 
877 	if (container->level & MSGPACK_CONTAINER_BIT) {
878 		level = container->level & ~MSGPACK_CONTAINER_BIT;
879 		container->level = (level - 1) | MSGPACK_CONTAINER_BIT;
880 	}
881 
882 	return true;
883 }
884 
885 static struct ucl_stack *
886 ucl_msgpack_get_next_container (struct ucl_parser *parser)
887 {
888 	struct ucl_stack *cur = NULL;
889 	uint64_t level;
890 
891 	cur = parser->stack;
892 
893 	if (cur == NULL) {
894 		return NULL;
895 	}
896 
897 	if (cur->level & MSGPACK_CONTAINER_BIT) {
898 		level = cur->level & ~MSGPACK_CONTAINER_BIT;
899 
900 		if (level == 0) {
901 			/* We need to switch to the previous container */
902 			parser->stack = cur->next;
903 			parser->cur_obj = cur->obj;
904 			free (cur);
905 
906 #ifdef MSGPACK_DEBUG_PARSER
907 			cur = parser->stack;
908 			while (cur) {
909 				fprintf(stderr, "-");
910 				cur = cur->next;
911 			}
912 			fprintf(stderr, "-%s -> %d\n", parser->cur_obj->type == UCL_OBJECT ? "object" : "array", (int)parser->cur_obj->len);
913 #endif
914 
915 			return ucl_msgpack_get_next_container (parser);
916 		}
917 	}
918 
919 	/*
920 	 * For UCL containers we don't know length, so we just insert the whole
921 	 * message pack blob into the top level container
922 	 */
923 
924 	assert (cur->obj != NULL);
925 
926 	return cur;
927 }
928 
929 #define CONSUME_RET do {									\
930 	if (ret != -1) {										\
931 		p += ret;											\
932 		remain -= ret;										\
933 		obj_parser = NULL;									\
934 		assert (remain >= 0);								\
935 	}														\
936 	else {													\
937 		ucl_create_err (&parser->err,						\
938 			"cannot parse type %d of len %u",				\
939 			(int)obj_parser->fmt,							\
940 			(unsigned)len);									\
941 		return false;										\
942 	}														\
943 } while(0)
944 
945 #define GET_NEXT_STATE do {									\
946 	container = ucl_msgpack_get_next_container (parser);	\
947 	if (container == NULL) {								\
948 		ucl_create_err (&parser->err,						\
949 					"empty container");						\
950 		return false;										\
951 	}														\
952 	next_state = container->obj->type == UCL_OBJECT ? 		\
953 					read_assoc_key : read_array_value;		\
954 } while(0)
955 
956 static bool
957 ucl_msgpack_consume (struct ucl_parser *parser)
958 {
959 	const unsigned char *p, *end, *key = NULL;
960 	struct ucl_stack *container;
961 	enum e_msgpack_parser_state {
962 		read_type,
963 		start_assoc,
964 		start_array,
965 		read_assoc_key,
966 		read_assoc_value,
967 		finish_assoc_value,
968 		read_array_value,
969 		finish_array_value,
970 		error_state
971 	} state = read_type, next_state = error_state;
972 	struct ucl_msgpack_parser *obj_parser;
973 	uint64_t len;
974 	ssize_t ret, remain, keylen = 0;
975 #ifdef MSGPACK_DEBUG_PARSER
976 	uint64_t i;
977 	enum e_msgpack_parser_state hist[256];
978 #endif
979 
980 	p = parser->chunks->begin;
981 	remain = parser->chunks->remain;
982 	end = p + remain;
983 
984 
985 	while (p < end) {
986 #ifdef MSGPACK_DEBUG_PARSER
987 		hist[i++ % 256] = state;
988 #endif
989 		switch (state) {
990 		case read_type:
991 			obj_parser = ucl_msgpack_get_parser_from_type (*p);
992 
993 			if (obj_parser == NULL) {
994 				ucl_create_err (&parser->err, "unknown msgpack format: %x",
995 						(unsigned int)*p);
996 
997 				return false;
998 			}
999 			/* Now check length sanity */
1000 			if (obj_parser->flags & MSGPACK_FLAG_FIXED) {
1001 				if (obj_parser->len == 0) {
1002 					/* We have an embedded size */
1003 					len = *p & ~obj_parser->prefix;
1004 				}
1005 				else {
1006 					if (remain < obj_parser->len) {
1007 						ucl_create_err (&parser->err, "not enough data remain to "
1008 								"read object's length: %u remain, %u needed",
1009 								(unsigned)remain, obj_parser->len);
1010 
1011 						return false;
1012 					}
1013 
1014 					len = obj_parser->len;
1015 				}
1016 
1017 				if (!(obj_parser->flags & MSGPACK_FLAG_TYPEVALUE)) {
1018 					/* We must pass value as the second byte */
1019 					if (remain > 0) {
1020 						p ++;
1021 						remain --;
1022 					}
1023 				}
1024 				else {
1025 					/* Len is irrelevant now */
1026 					len = 0;
1027 				}
1028 			}
1029 			else {
1030 				/* Length is not embedded */
1031 				if (remain < obj_parser->len) {
1032 					ucl_create_err (&parser->err, "not enough data remain to "
1033 							"read object's length: %u remain, %u needed",
1034 							(unsigned)remain, obj_parser->len);
1035 
1036 					return false;
1037 				}
1038 
1039 				p ++;
1040 				remain --;
1041 
1042 				switch (obj_parser->len) {
1043 				case 1:
1044 					len = *p;
1045 					break;
1046 				case 2:
1047 					len = FROM_BE16 (*(uint16_t *)p);
1048 					break;
1049 				case 4:
1050 					len = FROM_BE32 (*(uint32_t *)p);
1051 					break;
1052 				case 8:
1053 					len = FROM_BE64 (*(uint64_t *)p);
1054 					break;
1055 				default:
1056 					assert (0);
1057 					break;
1058 				}
1059 
1060 				p += obj_parser->len;
1061 				remain -= obj_parser->len;
1062 			}
1063 
1064 			if (obj_parser->flags & MSGPACK_FLAG_ASSOC) {
1065 				/* We have just read the new associative map */
1066 				state = start_assoc;
1067 			}
1068 			else if (obj_parser->flags & MSGPACK_FLAG_CONTAINER){
1069 				state = start_array;
1070 			}
1071 			else {
1072 				state = next_state;
1073 			}
1074 
1075 			break;
1076 		case start_assoc:
1077 			parser->cur_obj = ucl_object_new_full (UCL_OBJECT,
1078 					parser->chunks->priority);
1079 			/* Insert to the previous level container */
1080 			if (parser->stack && !ucl_msgpack_insert_object (parser,
1081 					key, keylen, parser->cur_obj)) {
1082 				return false;
1083 			}
1084 			/* Get new container */
1085 			container = ucl_msgpack_get_container (parser, obj_parser, len);
1086 
1087 			if (container == NULL) {
1088 				return false;
1089 			}
1090 
1091 			ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1092 					p, remain);
1093 			CONSUME_RET;
1094 			key = NULL;
1095 			keylen = 0;
1096 
1097 			if (len > 0) {
1098 				state = read_type;
1099 				next_state = read_assoc_key;
1100 			}
1101 			else {
1102 				/* Empty object */
1103 				state = finish_assoc_value;
1104 			}
1105 			break;
1106 
1107 		case start_array:
1108 			parser->cur_obj = ucl_object_new_full (UCL_ARRAY,
1109 					parser->chunks->priority);
1110 			/* Insert to the previous level container */
1111 			if (parser->stack && !ucl_msgpack_insert_object (parser,
1112 					key, keylen, parser->cur_obj)) {
1113 				return false;
1114 			}
1115 			/* Get new container */
1116 			container = ucl_msgpack_get_container (parser, obj_parser, len);
1117 
1118 			if (container == NULL) {
1119 				return false;
1120 			}
1121 
1122 			ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1123 								p, remain);
1124 			CONSUME_RET;
1125 
1126 			if (len > 0) {
1127 				state = read_type;
1128 				next_state = read_array_value;
1129 			}
1130 			else {
1131 				/* Empty array */
1132 				state = finish_array_value;
1133 			}
1134 			break;
1135 
1136 		case read_array_value:
1137 			/*
1138 			 * p is now at the value start, len now contains length read and
1139 			 * obj_parser contains the corresponding specific parser
1140 			 */
1141 			container = parser->stack;
1142 
1143 			if (container == NULL) {
1144 				return false;
1145 			}
1146 
1147 			ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1148 					p, remain);
1149 			CONSUME_RET;
1150 
1151 
1152 			/* Insert value to the container and check if we have finished array */
1153 			if (!ucl_msgpack_insert_object (parser, NULL, 0,
1154 					parser->cur_obj)) {
1155 				return false;
1156 			}
1157 
1158 			if (ucl_msgpack_is_container_finished (container)) {
1159 				state = finish_array_value;
1160 			}
1161 			else {
1162 				/* Read more elements */
1163 				state = read_type;
1164 				next_state = read_array_value;
1165 			}
1166 
1167 			break;
1168 
1169 		case read_assoc_key:
1170 			/*
1171 			 * Keys must have string type for ucl msgpack
1172 			 */
1173 			if (!(obj_parser->flags & MSGPACK_FLAG_KEY)) {
1174 				ucl_create_err (&parser->err, "bad type for key: %u, expected "
1175 						"string", (unsigned)obj_parser->fmt);
1176 
1177 				return false;
1178 			}
1179 
1180 			key = p;
1181 			keylen = len;
1182 
1183 			if (keylen > remain || keylen == 0) {
1184 				ucl_create_err (&parser->err, "too long or empty key");
1185 				return false;
1186 			}
1187 
1188 			p += len;
1189 			remain -= len;
1190 
1191 			state = read_type;
1192 			next_state = read_assoc_value;
1193 			break;
1194 
1195 		case read_assoc_value:
1196 			/*
1197 			 * p is now at the value start, len now contains length read and
1198 			 * obj_parser contains the corresponding specific parser
1199 			 */
1200 			container = parser->stack;
1201 
1202 			if (container == NULL) {
1203 				return false;
1204 			}
1205 
1206 			ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1207 					p, remain);
1208 			CONSUME_RET;
1209 
1210 			assert (key != NULL && keylen > 0);
1211 
1212 			if (!ucl_msgpack_insert_object (parser, key, keylen,
1213 					parser->cur_obj)) {
1214 				return false;
1215 			}
1216 
1217 			key = NULL;
1218 			keylen = 0;
1219 
1220 			if (ucl_msgpack_is_container_finished (container)) {
1221 				state = finish_assoc_value;
1222 			}
1223 			else {
1224 				/* Read more elements */
1225 				state = read_type;
1226 				next_state = read_assoc_key;
1227 			}
1228 			break;
1229 
1230 		case finish_array_value:
1231 		case finish_assoc_value:
1232 			GET_NEXT_STATE;
1233 			state = read_type;
1234 			break;
1235 
1236 		case error_state:
1237 			ucl_create_err (&parser->err, "invalid state machine state");
1238 
1239 			return false;
1240 		}
1241 	}
1242 
1243 	/* Check the finishing state */
1244 	switch (state) {
1245 	case start_array:
1246 	case start_assoc:
1247 		/* Empty container at the end */
1248 		if (len != 0) {
1249 			ucl_create_err (&parser->err, "invalid non-empty container at the end");
1250 
1251 			return false;
1252 		}
1253 
1254 		parser->cur_obj = ucl_object_new_full (
1255 				state == start_array ? UCL_ARRAY : UCL_OBJECT,
1256 				parser->chunks->priority);
1257 		/* Insert to the previous level container */
1258 		if (!ucl_msgpack_insert_object (parser,
1259 				key, keylen, parser->cur_obj)) {
1260 			return false;
1261 		}
1262 		/* Get new container */
1263 		container = ucl_msgpack_get_container (parser, obj_parser, len);
1264 
1265 		if (container == NULL) {
1266 			return false;
1267 		}
1268 
1269 		ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1270 				p, remain);
1271 		break;
1272 
1273 	case read_array_value:
1274 	case read_assoc_value:
1275 		if (len != 0) {
1276 			ucl_create_err (&parser->err, "unfinished value at the end");
1277 
1278 			return false;
1279 		}
1280 
1281 		container = parser->stack;
1282 
1283 		if (container == NULL) {
1284 			return false;
1285 		}
1286 
1287 		ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1288 				p, remain);
1289 		CONSUME_RET;
1290 
1291 
1292 		/* Insert value to the container and check if we have finished array */
1293 		if (!ucl_msgpack_insert_object (parser, NULL, 0,
1294 				parser->cur_obj)) {
1295 			return false;
1296 		}
1297 		break;
1298 	case finish_array_value:
1299 	case finish_assoc_value:
1300 	case read_type:
1301 		/* Valid finishing state */
1302 		break;
1303 	default:
1304 		/* Invalid finishing state */
1305 		ucl_create_err (&parser->err, "invalid state machine finishing state: %d",
1306 				state);
1307 
1308 		return false;
1309 	}
1310 
1311 	/* Rewind to the top level container */
1312 	ucl_msgpack_get_next_container (parser);
1313 	assert (parser->stack == NULL ||
1314 			(parser->stack->level & MSGPACK_CONTAINER_BIT) == 0);
1315 
1316 	return true;
1317 }
1318 
1319 bool
1320 ucl_parse_msgpack (struct ucl_parser *parser)
1321 {
1322 	ucl_object_t *container = NULL;
1323 	const unsigned char *p;
1324 	bool ret;
1325 
1326 	assert (parser != NULL);
1327 	assert (parser->chunks != NULL);
1328 	assert (parser->chunks->begin != NULL);
1329 	assert (parser->chunks->remain != 0);
1330 
1331 	p = parser->chunks->begin;
1332 
1333 	if (parser->stack) {
1334 		container = parser->stack->obj;
1335 	}
1336 
1337 	/*
1338 	 * When we start parsing message pack chunk, we must ensure that we
1339 	 * have either a valid container or the top object inside message pack is
1340 	 * of container type
1341 	 */
1342 	if (container == NULL) {
1343 		if ((*p & 0x80) != 0x80 && !(*p >= 0xdc && *p <= 0xdf)) {
1344 			ucl_create_err (&parser->err, "bad top level object for msgpack");
1345 			return false;
1346 		}
1347 	}
1348 
1349 	ret = ucl_msgpack_consume (parser);
1350 
1351 	if (ret && parser->top_obj == NULL) {
1352 		parser->top_obj = parser->cur_obj;
1353 	}
1354 
1355 	return ret;
1356 }
1357 
1358 static ssize_t
1359 ucl_msgpack_parse_map (struct ucl_parser *parser,
1360 		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1361 		const unsigned char *pos, size_t remain)
1362 {
1363 	container->obj = parser->cur_obj;
1364 
1365 	return 0;
1366 }
1367 
1368 static ssize_t
1369 ucl_msgpack_parse_array (struct ucl_parser *parser,
1370 		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1371 		const unsigned char *pos, size_t remain)
1372 {
1373 	container->obj = parser->cur_obj;
1374 
1375 	return 0;
1376 }
1377 
1378 static ssize_t
1379 ucl_msgpack_parse_string (struct ucl_parser *parser,
1380 		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1381 		const unsigned char *pos, size_t remain)
1382 {
1383 	ucl_object_t *obj;
1384 
1385 	if (len > remain) {
1386 		return -1;
1387 	}
1388 
1389 	obj = ucl_object_new_full (UCL_STRING, parser->chunks->priority);
1390 	obj->value.sv = pos;
1391 	obj->len = len;
1392 
1393 	if (fmt >= msgpack_bin8 && fmt <= msgpack_bin32) {
1394 		obj->flags |= UCL_OBJECT_BINARY;
1395 	}
1396 
1397 	if (!(parser->flags & UCL_PARSER_ZEROCOPY)) {
1398 		if (obj->flags & UCL_OBJECT_BINARY) {
1399 			obj->trash_stack[UCL_TRASH_VALUE] = malloc (len);
1400 
1401 			if (obj->trash_stack[UCL_TRASH_VALUE] != NULL) {
1402 				memcpy (obj->trash_stack[UCL_TRASH_VALUE], pos, len);
1403 			}
1404 		}
1405 		else {
1406 			ucl_copy_value_trash (obj);
1407 		}
1408 	}
1409 
1410 	parser->cur_obj = obj;
1411 
1412 	return len;
1413 }
1414 
1415 static ssize_t
1416 ucl_msgpack_parse_int (struct ucl_parser *parser,
1417 		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1418 		const unsigned char *pos, size_t remain)
1419 {
1420 	ucl_object_t *obj;
1421 
1422 	if (len > remain) {
1423 		return -1;
1424 	}
1425 
1426 	obj = ucl_object_new_full (UCL_INT, parser->chunks->priority);
1427 
1428 	switch (fmt) {
1429 	case msgpack_positive_fixint:
1430 		obj->value.iv = (*pos & 0x7f);
1431 		len = 1;
1432 		break;
1433 	case msgpack_negative_fixint:
1434 		obj->value.iv = - (*pos & 0x1f);
1435 		len = 1;
1436 		break;
1437 	case msgpack_uint8:
1438 		obj->value.iv = (unsigned char)*pos;
1439 		len = 1;
1440 		break;
1441 	case msgpack_int8:
1442 		obj->value.iv = (signed char)*pos;
1443 		len = 1;
1444 		break;
1445 	case msgpack_int16:
1446 		obj->value.iv = FROM_BE16 (*(int16_t *)pos);
1447 		len = 2;
1448 		break;
1449 	case msgpack_uint16:
1450 		obj->value.iv = FROM_BE16 (*(uint16_t *)pos);
1451 		len = 2;
1452 		break;
1453 	case msgpack_int32:
1454 		obj->value.iv = FROM_BE32 (*(int32_t *)pos);
1455 		len = 4;
1456 		break;
1457 	case msgpack_uint32:
1458 		obj->value.iv = FROM_BE32 (*(uint32_t *)pos);
1459 		len = 4;
1460 		break;
1461 	case msgpack_int64:
1462 		obj->value.iv = FROM_BE64 (*(int64_t *)pos);
1463 		len = 8;
1464 		break;
1465 	case msgpack_uint64:
1466 		obj->value.iv = FROM_BE64 (*(uint64_t *)pos);
1467 		len = 8;
1468 		break;
1469 	default:
1470 		assert (0);
1471 		break;
1472 	}
1473 
1474 	parser->cur_obj = obj;
1475 
1476 	return len;
1477 }
1478 
1479 static ssize_t
1480 ucl_msgpack_parse_float (struct ucl_parser *parser,
1481 		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1482 		const unsigned char *pos, size_t remain)
1483 {
1484 	ucl_object_t *obj;
1485 	union {
1486 		uint32_t i;
1487 		float f;
1488 	} d;
1489 
1490 	if (len > remain) {
1491 		return -1;
1492 	}
1493 
1494 	obj = ucl_object_new_full (UCL_FLOAT, parser->chunks->priority);
1495 
1496 	switch (fmt) {
1497 	case msgpack_float32:
1498 		d.i = FROM_BE32 (*(uint32_t *)pos);
1499 		/* XXX: can be slow */
1500 		obj->value.dv = d.f;
1501 		len = 4;
1502 		break;
1503 	case msgpack_float64:
1504 		obj->value.iv = FROM_BE64 (*(uint64_t *)pos);
1505 		len = 8;
1506 		break;
1507 	default:
1508 		assert (0);
1509 		break;
1510 	}
1511 
1512 	parser->cur_obj = obj;
1513 
1514 	return len;
1515 }
1516 
1517 static ssize_t
1518 ucl_msgpack_parse_bool (struct ucl_parser *parser,
1519 		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1520 		const unsigned char *pos, size_t remain)
1521 {
1522 	ucl_object_t *obj;
1523 
1524 	if (len > remain) {
1525 		return -1;
1526 	}
1527 
1528 	obj = ucl_object_new_full (UCL_BOOLEAN, parser->chunks->priority);
1529 
1530 	switch (fmt) {
1531 	case msgpack_true:
1532 		obj->value.iv = true;
1533 		break;
1534 	case msgpack_false:
1535 		obj->value.iv = false;
1536 		break;
1537 	default:
1538 		assert (0);
1539 		break;
1540 	}
1541 
1542 	parser->cur_obj = obj;
1543 
1544 	return 1;
1545 }
1546 
1547 static ssize_t
1548 ucl_msgpack_parse_null (struct ucl_parser *parser,
1549 		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1550 		const unsigned char *pos, size_t remain)
1551 {
1552 	ucl_object_t *obj;
1553 
1554 	if (len > remain) {
1555 		return -1;
1556 	}
1557 
1558 	obj = ucl_object_new_full (UCL_NULL, parser->chunks->priority);
1559 	parser->cur_obj = obj;
1560 
1561 	return 1;
1562 }
1563 
1564 static ssize_t
1565 ucl_msgpack_parse_ignore (struct ucl_parser *parser,
1566 		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1567 		const unsigned char *pos, size_t remain)
1568 {
1569 	if (len > remain) {
1570 		return -1;
1571 	}
1572 
1573 	switch (fmt) {
1574 	case msgpack_fixext1:
1575 		len = 2;
1576 		break;
1577 	case msgpack_fixext2:
1578 		len = 3;
1579 		break;
1580 	case msgpack_fixext4:
1581 		len = 5;
1582 		break;
1583 	case msgpack_fixext8:
1584 		len = 9;
1585 		break;
1586 	case msgpack_fixext16:
1587 		len = 17;
1588 		break;
1589 	case msgpack_ext8:
1590 	case msgpack_ext16:
1591 	case msgpack_ext32:
1592 		len = len + 1;
1593 		break;
1594 	default:
1595 		ucl_create_err (&parser->err, "bad type: %x", (unsigned)fmt);
1596 		return -1;
1597 	}
1598 
1599 	return len;
1600 }
1601