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