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
100void
101ucl_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
184void
185ucl_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
204void
205ucl_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
213void
214ucl_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
250void
251ucl_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
283void
284ucl_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
292void
293ucl_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
301void
302ucl_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
331void
332ucl_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
362enum 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
402typedef 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
406static 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);
409static 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);
412static 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);
415static 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);
418static 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);
421static 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);
424static 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);
427static 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 */
442struct 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
745static inline struct ucl_msgpack_parser *
746ucl_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
762static inline struct ucl_stack *
763ucl_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
823static bool
824ucl_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
841static bool
842ucl_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
886static struct ucl_stack *
887ucl_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
957static bool
958ucl_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
1320bool
1321ucl_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
1359static ssize_t
1360ucl_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
1369static ssize_t
1370ucl_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
1379static ssize_t
1380ucl_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
1416static ssize_t
1417ucl_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
1501static ssize_t
1502ucl_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
1543static ssize_t
1544ucl_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
1573static ssize_t
1574ucl_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
1590static ssize_t
1591ucl_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