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
438/*
439 * Search tree packed in array
440 */
441struct 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
744static inline struct ucl_msgpack_parser *
745ucl_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 == (((unsigned int)t) >> shift)) {
754			return &parsers[i];
755		}
756	}
757
758	return NULL;
759}
760
761static inline struct ucl_stack *
762ucl_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		/*
771		 * Insert new container to the stack
772		 */
773		if (parser->stack == NULL) {
774			parser->stack = calloc (1, sizeof (struct ucl_stack));
775
776			if (parser->stack == NULL) {
777				ucl_create_err (&parser->err, "no memory");
778				return NULL;
779			}
780
781			parser->stack->chunk = parser->chunks;
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->chunk = parser->chunks;
792			stack->next = parser->stack;
793			parser->stack = stack;
794		}
795
796		parser->stack->e.len = len;
797
798#ifdef MSGPACK_DEBUG_PARSER
799		stack = parser->stack;
800		while (stack) {
801			fprintf(stderr, "+");
802			stack = stack->next;
803		}
804
805		fprintf(stderr, "%s -> %d\n", obj_parser->flags & MSGPACK_FLAG_ASSOC ? "object" : "array", (int)len);
806#endif
807	}
808	else {
809		/*
810		 * Get the current stack top
811		 */
812		if (parser->stack) {
813			return parser->stack;
814		}
815		else {
816			ucl_create_err (&parser->err, "bad top level object for msgpack");
817			return NULL;
818		}
819	}
820
821	return parser->stack;
822}
823
824static bool
825ucl_msgpack_is_container_finished (struct ucl_stack *container)
826{
827	assert (container != NULL);
828
829
830	if (container->e.len == 0) {
831		return true;
832	}
833
834	return false;
835}
836
837static bool
838ucl_msgpack_insert_object (struct ucl_parser *parser,
839		const unsigned char *key,
840		size_t keylen, ucl_object_t *obj)
841{
842	struct ucl_stack *container;
843
844	container = parser->stack;
845	assert (container != NULL);
846	assert (container->e.len > 0);
847	assert (obj != NULL);
848	assert (container->obj != NULL);
849
850	if (container->obj->type == UCL_ARRAY) {
851		ucl_array_append (container->obj, obj);
852	}
853	else if (container->obj->type == UCL_OBJECT) {
854		if (key == NULL || keylen == 0) {
855			ucl_create_err (&parser->err, "cannot insert object with no key");
856			return false;
857		}
858
859		obj->key = key;
860		obj->keylen = keylen;
861
862		if (!(parser->flags & UCL_PARSER_ZEROCOPY)) {
863			ucl_copy_key_trash (obj);
864		}
865
866		ucl_parser_process_object_element (parser, obj);
867	}
868	else {
869		ucl_create_err (&parser->err, "bad container type");
870		return false;
871	}
872
873	container->e.len--;
874
875	return true;
876}
877
878static struct ucl_stack *
879ucl_msgpack_get_next_container (struct ucl_parser *parser)
880{
881	struct ucl_stack *cur = NULL;
882	uint64_t len;
883
884	cur = parser->stack;
885
886	if (cur == NULL) {
887		return NULL;
888	}
889
890	len = cur->e.len;
891
892	if (len == 0) {
893		/* We need to switch to the previous container */
894		parser->stack = cur->next;
895		parser->cur_obj = cur->obj;
896		free (cur);
897
898#ifdef MSGPACK_DEBUG_PARSER
899		cur = parser->stack;
900			while (cur) {
901				fprintf(stderr, "-");
902				cur = cur->next;
903			}
904			fprintf(stderr, "-%s -> %d\n", parser->cur_obj->type == UCL_OBJECT ? "object" : "array", (int)parser->cur_obj->len);
905#endif
906
907		return ucl_msgpack_get_next_container (parser);
908	}
909
910	/*
911	 * For UCL containers we don't know length, so we just insert the whole
912	 * message pack blob into the top level container
913	 */
914
915	assert (cur->obj != NULL);
916
917	return cur;
918}
919
920#define CONSUME_RET do {									\
921	if (ret != -1) {										\
922		p += ret;											\
923		remain -= ret;										\
924		obj_parser = NULL;									\
925		assert (remain >= 0);								\
926	}														\
927	else {													\
928		ucl_create_err (&parser->err,						\
929			"cannot parse type %d of len %u",				\
930			(int)obj_parser->fmt,							\
931			(unsigned)len);									\
932		return false;										\
933	}														\
934} while(0)
935
936#define GET_NEXT_STATE do {									\
937	container = ucl_msgpack_get_next_container (parser);	\
938	if (container == NULL) {								\
939		ucl_create_err (&parser->err,						\
940					"empty container");						\
941		return false;										\
942	}														\
943	next_state = container->obj->type == UCL_OBJECT ? 		\
944					read_assoc_key : read_array_value;		\
945} while(0)
946
947static bool
948ucl_msgpack_consume (struct ucl_parser *parser)
949{
950	const unsigned char *p, *end, *key = NULL;
951	struct ucl_stack *container;
952	enum e_msgpack_parser_state {
953		read_type,
954		start_assoc,
955		start_array,
956		read_assoc_key,
957		read_assoc_value,
958		finish_assoc_value,
959		read_array_value,
960		finish_array_value,
961		error_state
962	} state = read_type, next_state = error_state;
963	struct ucl_msgpack_parser *obj_parser = NULL;
964	uint64_t len = 0;
965	ssize_t ret, remain, keylen = 0;
966#ifdef MSGPACK_DEBUG_PARSER
967	uint64_t i;
968	enum e_msgpack_parser_state hist[256];
969#endif
970
971	p = parser->chunks->begin;
972	remain = parser->chunks->remain;
973	end = p + remain;
974
975
976	while (p < end) {
977#ifdef MSGPACK_DEBUG_PARSER
978		hist[i++ % 256] = state;
979#endif
980		switch (state) {
981		case read_type:
982			obj_parser = ucl_msgpack_get_parser_from_type (*p);
983
984			if (obj_parser == NULL) {
985				ucl_create_err (&parser->err, "unknown msgpack format: %x",
986						(unsigned int)*p);
987
988				return false;
989			}
990			/* Now check length sanity */
991			if (obj_parser->flags & MSGPACK_FLAG_FIXED) {
992				if (obj_parser->len == 0) {
993					/* We have an embedded size */
994					len = *p & ~obj_parser->prefix;
995				}
996				else {
997					if (remain < obj_parser->len) {
998						ucl_create_err (&parser->err, "not enough data remain to "
999								"read object's length: %u remain, %u needed",
1000								(unsigned)remain, obj_parser->len);
1001
1002						return false;
1003					}
1004
1005					len = obj_parser->len;
1006				}
1007
1008				if (!(obj_parser->flags & MSGPACK_FLAG_TYPEVALUE)) {
1009					/* We must pass value as the second byte */
1010					if (remain > 0) {
1011						p ++;
1012						remain --;
1013					}
1014				}
1015				else {
1016					/* Len is irrelevant now */
1017					len = 0;
1018				}
1019			}
1020			else {
1021				/* Length is not embedded */
1022				remain --;
1023
1024				if (remain < obj_parser->len) {
1025					ucl_create_err (&parser->err, "not enough data remain to "
1026							"read object's length: %u remain, %u needed",
1027							(unsigned)remain, obj_parser->len);
1028
1029					return false;
1030				}
1031
1032				p ++;
1033
1034				switch (obj_parser->len) {
1035				case 1:
1036					len = *p;
1037					break;
1038				case 2:
1039					len = FROM_BE16 (*(uint16_t *)p);
1040					break;
1041				case 4:
1042					len = FROM_BE32 (*(uint32_t *)p);
1043					break;
1044				case 8:
1045					len = FROM_BE64 (*(uint64_t *)p);
1046					break;
1047				default:
1048					ucl_create_err (&parser->err, "invalid length of the length field: %u",
1049							(unsigned)obj_parser->len);
1050
1051					return false;
1052				}
1053
1054				p += obj_parser->len;
1055				remain -= obj_parser->len;
1056			}
1057
1058			if (obj_parser->flags & MSGPACK_FLAG_ASSOC) {
1059				/* We have just read the new associative map */
1060				state = start_assoc;
1061			}
1062			else if (obj_parser->flags & MSGPACK_FLAG_CONTAINER){
1063				state = start_array;
1064			}
1065			else {
1066				state = next_state;
1067			}
1068
1069			break;
1070		case start_assoc:
1071			parser->cur_obj = ucl_object_new_full (UCL_OBJECT,
1072					parser->chunks->priority);
1073			/* Insert to the previous level container */
1074			if (parser->stack && !ucl_msgpack_insert_object (parser,
1075					key, keylen, parser->cur_obj)) {
1076				return false;
1077			}
1078			/* Get new container */
1079			container = ucl_msgpack_get_container (parser, obj_parser, len);
1080
1081			if (container == NULL) {
1082				return false;
1083			}
1084
1085			ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1086					p, remain);
1087			CONSUME_RET;
1088			key = NULL;
1089			keylen = 0;
1090
1091			if (len > 0) {
1092				state = read_type;
1093				next_state = read_assoc_key;
1094			}
1095			else {
1096				/* Empty object */
1097				state = finish_assoc_value;
1098			}
1099			break;
1100
1101		case start_array:
1102			parser->cur_obj = ucl_object_new_full (UCL_ARRAY,
1103					parser->chunks->priority);
1104			/* Insert to the previous level container */
1105			if (parser->stack && !ucl_msgpack_insert_object (parser,
1106					key, keylen, parser->cur_obj)) {
1107				return false;
1108			}
1109			/* Get new container */
1110			container = ucl_msgpack_get_container (parser, obj_parser, len);
1111
1112			if (container == NULL) {
1113				return false;
1114			}
1115
1116			ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1117								p, remain);
1118			CONSUME_RET;
1119
1120			if (len > 0) {
1121				state = read_type;
1122				next_state = read_array_value;
1123			}
1124			else {
1125				/* Empty array */
1126				state = finish_array_value;
1127			}
1128			break;
1129
1130		case read_array_value:
1131			/*
1132			 * p is now at the value start, len now contains length read and
1133			 * obj_parser contains the corresponding specific parser
1134			 */
1135			container = parser->stack;
1136
1137			if (parser->stack == NULL) {
1138				ucl_create_err (&parser->err,
1139						"read assoc value when no container represented");
1140				return false;
1141			}
1142
1143			ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1144					p, remain);
1145			CONSUME_RET;
1146
1147
1148			/* Insert value to the container and check if we have finished array */
1149			if (!ucl_msgpack_insert_object (parser, NULL, 0,
1150					parser->cur_obj)) {
1151				return false;
1152			}
1153
1154			if (ucl_msgpack_is_container_finished (container)) {
1155				state = finish_array_value;
1156			}
1157			else {
1158				/* Read more elements */
1159				state = read_type;
1160				next_state = read_array_value;
1161			}
1162
1163			break;
1164
1165		case read_assoc_key:
1166			/*
1167			 * Keys must have string type for ucl msgpack
1168			 */
1169			if (!(obj_parser->flags & MSGPACK_FLAG_KEY)) {
1170				ucl_create_err (&parser->err, "bad type for key: %u, expected "
1171						"string", (unsigned)obj_parser->fmt);
1172
1173				return false;
1174			}
1175
1176			key = p;
1177			keylen = len;
1178
1179			if (keylen > remain || keylen == 0) {
1180				ucl_create_err (&parser->err, "too long or empty key");
1181				return false;
1182			}
1183
1184			p += len;
1185			remain -= len;
1186
1187			state = read_type;
1188			next_state = read_assoc_value;
1189			break;
1190
1191		case read_assoc_value:
1192			/*
1193			 * p is now at the value start, len now contains length read and
1194			 * obj_parser contains the corresponding specific parser
1195			 */
1196			container = parser->stack;
1197
1198			if (container == NULL) {
1199				ucl_create_err (&parser->err,
1200						"read assoc value when no container represented");
1201				return false;
1202			}
1203
1204			ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1205					p, remain);
1206			CONSUME_RET;
1207
1208			assert (key != NULL && keylen > 0);
1209
1210			if (!ucl_msgpack_insert_object (parser, key, keylen,
1211					parser->cur_obj)) {
1212
1213				return false;
1214			}
1215
1216			key = NULL;
1217			keylen = 0;
1218
1219			if (ucl_msgpack_is_container_finished (container)) {
1220				state = finish_assoc_value;
1221			}
1222			else {
1223				/* Read more elements */
1224				state = read_type;
1225				next_state = read_assoc_key;
1226			}
1227			break;
1228
1229		case finish_array_value:
1230		case finish_assoc_value:
1231			GET_NEXT_STATE;
1232			state = read_type;
1233			break;
1234
1235		case error_state:
1236			ucl_create_err (&parser->err, "invalid state machine state");
1237
1238			return false;
1239		}
1240	}
1241
1242	/* Check the finishing state */
1243	switch (state) {
1244	case start_array:
1245	case start_assoc:
1246		/* Empty container at the end */
1247		if (len != 0) {
1248			ucl_create_err (&parser->err,
1249					"invalid non-empty container at the end; len=%zu",
1250					(size_t)len);
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
1259		if (parser->stack == NULL) {
1260			ucl_create_err (&parser->err,
1261					"read assoc value when no container represented");
1262			return false;
1263		}
1264		/* Insert to the previous level container */
1265		if (!ucl_msgpack_insert_object (parser,
1266				key, keylen, parser->cur_obj)) {
1267			return false;
1268		}
1269		/* Get new container */
1270		container = ucl_msgpack_get_container (parser, obj_parser, len);
1271
1272		if (container == NULL) {
1273			return false;
1274		}
1275
1276		ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1277				p, remain);
1278		break;
1279
1280	case read_array_value:
1281	case read_assoc_value:
1282		if (len != 0) {
1283			ucl_create_err (&parser->err, "unfinished value at the end");
1284
1285			return false;
1286		}
1287
1288		container = parser->stack;
1289
1290		if (parser->stack == NULL) {
1291			ucl_create_err (&parser->err,
1292					"read assoc value when no container represented");
1293			return false;
1294		}
1295
1296		ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1297				p, remain);
1298		CONSUME_RET;
1299
1300
1301		/* Insert value to the container and check if we have finished array */
1302		if (!ucl_msgpack_insert_object (parser, NULL, 0,
1303				parser->cur_obj)) {
1304			return false;
1305		}
1306		break;
1307	case finish_array_value:
1308	case finish_assoc_value:
1309	case read_type:
1310		/* Valid finishing state */
1311		break;
1312	default:
1313		/* Invalid finishing state */
1314		ucl_create_err (&parser->err, "invalid state machine finishing state: %d",
1315				state);
1316
1317		return false;
1318	}
1319
1320	/* Rewind to the top level container */
1321	ucl_msgpack_get_next_container (parser);
1322
1323	if (parser->stack != NULL) {
1324		ucl_create_err (&parser->err, "incomplete container");
1325
1326		return false;
1327	}
1328
1329	return true;
1330}
1331
1332bool
1333ucl_parse_msgpack (struct ucl_parser *parser)
1334{
1335	ucl_object_t *container = NULL;
1336	const unsigned char *p;
1337	bool ret;
1338
1339	assert (parser != NULL);
1340	assert (parser->chunks != NULL);
1341	assert (parser->chunks->begin != NULL);
1342	assert (parser->chunks->remain != 0);
1343
1344	p = parser->chunks->begin;
1345
1346	if (parser->stack) {
1347		container = parser->stack->obj;
1348	}
1349
1350	/*
1351	 * When we start parsing message pack chunk, we must ensure that we
1352	 * have either a valid container or the top object inside message pack is
1353	 * of container type
1354	 */
1355	if (container == NULL) {
1356		if ((*p & 0x80) != 0x80 && !(*p >= 0xdc && *p <= 0xdf)) {
1357			ucl_create_err (&parser->err, "bad top level object for msgpack");
1358			return false;
1359		}
1360	}
1361
1362	ret = ucl_msgpack_consume (parser);
1363
1364	if (ret && parser->top_obj == NULL) {
1365		parser->top_obj = parser->cur_obj;
1366	}
1367
1368	return ret;
1369}
1370
1371static ssize_t
1372ucl_msgpack_parse_map (struct ucl_parser *parser,
1373		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1374		const unsigned char *pos, size_t remain)
1375{
1376	container->obj = parser->cur_obj;
1377
1378	return 0;
1379}
1380
1381static ssize_t
1382ucl_msgpack_parse_array (struct ucl_parser *parser,
1383		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1384		const unsigned char *pos, size_t remain)
1385{
1386	container->obj = parser->cur_obj;
1387
1388	return 0;
1389}
1390
1391static ssize_t
1392ucl_msgpack_parse_string (struct ucl_parser *parser,
1393		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1394		const unsigned char *pos, size_t remain)
1395{
1396	ucl_object_t *obj;
1397
1398	if (len > remain) {
1399		return -1;
1400	}
1401
1402	obj = ucl_object_new_full (UCL_STRING, parser->chunks->priority);
1403	obj->value.sv = pos;
1404	obj->len = len;
1405
1406	if (fmt >= msgpack_bin8 && fmt <= msgpack_bin32) {
1407		obj->flags |= UCL_OBJECT_BINARY;
1408	}
1409
1410	if (!(parser->flags & UCL_PARSER_ZEROCOPY)) {
1411		if (obj->flags & UCL_OBJECT_BINARY) {
1412			obj->trash_stack[UCL_TRASH_VALUE] = malloc (len);
1413
1414			if (obj->trash_stack[UCL_TRASH_VALUE] != NULL) {
1415				memcpy (obj->trash_stack[UCL_TRASH_VALUE], pos, len);
1416			}
1417		}
1418		else {
1419			ucl_copy_value_trash (obj);
1420		}
1421	}
1422
1423	parser->cur_obj = obj;
1424
1425	return len;
1426}
1427
1428static ssize_t
1429ucl_msgpack_parse_int (struct ucl_parser *parser,
1430		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1431		const unsigned char *pos, size_t remain)
1432{
1433	ucl_object_t *obj;
1434	int8_t iv8;
1435	int16_t iv16;
1436	int32_t iv32;
1437	int64_t iv64;
1438	uint16_t uiv16;
1439	uint32_t uiv32;
1440	uint64_t uiv64;
1441
1442
1443	if (len > remain) {
1444		return -1;
1445	}
1446
1447	obj = ucl_object_new_full (UCL_INT, parser->chunks->priority);
1448
1449	switch (fmt) {
1450	case msgpack_positive_fixint:
1451		obj->value.iv = (*pos & 0x7f);
1452		len = 1;
1453		break;
1454	case msgpack_negative_fixint:
1455		obj->value.iv = - (*pos & 0x1f);
1456		len = 1;
1457		break;
1458	case msgpack_uint8:
1459		obj->value.iv = (unsigned char)*pos;
1460		len = 1;
1461		break;
1462	case msgpack_int8:
1463		memcpy (&iv8, pos, sizeof (iv8));
1464		obj->value.iv = iv8;
1465		len = 1;
1466		break;
1467	case msgpack_int16:
1468		memcpy (&iv16, pos, sizeof (iv16));
1469		iv16 = FROM_BE16 (iv16);
1470		obj->value.iv = iv16;
1471		len = 2;
1472		break;
1473	case msgpack_uint16:
1474		memcpy (&uiv16, pos, sizeof (uiv16));
1475		uiv16 = FROM_BE16 (uiv16);
1476		obj->value.iv = uiv16;
1477		len = 2;
1478		break;
1479	case msgpack_int32:
1480		memcpy (&iv32, pos, sizeof (iv32));
1481		iv32 = FROM_BE32 (iv32);
1482		obj->value.iv = iv32;
1483		len = 4;
1484		break;
1485	case msgpack_uint32:
1486		memcpy(&uiv32, pos, sizeof(uiv32));
1487		uiv32 = FROM_BE32(uiv32);
1488		obj->value.iv = uiv32;
1489		len = 4;
1490		break;
1491	case msgpack_int64:
1492		memcpy (&iv64, pos, sizeof (iv64));
1493		iv64 = FROM_BE64 (iv64);
1494		obj->value.iv = iv64;
1495		len = 8;
1496		break;
1497	case msgpack_uint64:
1498		memcpy(&uiv64, pos, sizeof(uiv64));
1499		uiv64 = FROM_BE64(uiv64);
1500		obj->value.iv = uiv64;
1501		len = 8;
1502		break;
1503	default:
1504		assert (0);
1505		break;
1506	}
1507
1508	parser->cur_obj = obj;
1509
1510	return len;
1511}
1512
1513static ssize_t
1514ucl_msgpack_parse_float (struct ucl_parser *parser,
1515		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1516		const unsigned char *pos, size_t remain)
1517{
1518	ucl_object_t *obj;
1519	union {
1520		uint32_t i;
1521		float f;
1522	} d;
1523	uint64_t uiv64;
1524
1525	if (len > remain) {
1526		return -1;
1527	}
1528
1529	obj = ucl_object_new_full (UCL_FLOAT, parser->chunks->priority);
1530
1531	switch (fmt) {
1532	case msgpack_float32:
1533		memcpy(&d.i, pos, sizeof(d.i));
1534		d.i = FROM_BE32(d.i);
1535		/* XXX: can be slow */
1536		obj->value.dv = d.f;
1537		len = 4;
1538		break;
1539	case msgpack_float64:
1540		memcpy(&uiv64, pos, sizeof(uiv64));
1541		uiv64 = FROM_BE64(uiv64);
1542		obj->value.iv = uiv64;
1543		len = 8;
1544		break;
1545	default:
1546		assert (0);
1547		break;
1548	}
1549
1550	parser->cur_obj = obj;
1551
1552	return len;
1553}
1554
1555static ssize_t
1556ucl_msgpack_parse_bool (struct ucl_parser *parser,
1557		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1558		const unsigned char *pos, size_t remain)
1559{
1560	ucl_object_t *obj;
1561
1562	if (len > remain) {
1563		return -1;
1564	}
1565
1566	obj = ucl_object_new_full (UCL_BOOLEAN, parser->chunks->priority);
1567
1568	switch (fmt) {
1569	case msgpack_true:
1570		obj->value.iv = true;
1571		break;
1572	case msgpack_false:
1573		obj->value.iv = false;
1574		break;
1575	default:
1576		assert (0);
1577		break;
1578	}
1579
1580	parser->cur_obj = obj;
1581
1582	return 1;
1583}
1584
1585static ssize_t
1586ucl_msgpack_parse_null (struct ucl_parser *parser,
1587		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1588		const unsigned char *pos, size_t remain)
1589{
1590	ucl_object_t *obj;
1591
1592	if (len > remain) {
1593		return -1;
1594	}
1595
1596	obj = ucl_object_new_full (UCL_NULL, parser->chunks->priority);
1597	parser->cur_obj = obj;
1598
1599	return 1;
1600}
1601
1602static ssize_t
1603ucl_msgpack_parse_ignore (struct ucl_parser *parser,
1604		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1605		const unsigned char *pos, size_t remain)
1606{
1607	if (len > remain) {
1608		return -1;
1609	}
1610
1611	switch (fmt) {
1612	case msgpack_fixext1:
1613		len = 2;
1614		break;
1615	case msgpack_fixext2:
1616		len = 3;
1617		break;
1618	case msgpack_fixext4:
1619		len = 5;
1620		break;
1621	case msgpack_fixext8:
1622		len = 9;
1623		break;
1624	case msgpack_fixext16:
1625		len = 17;
1626		break;
1627	case msgpack_ext8:
1628	case msgpack_ext16:
1629	case msgpack_ext32:
1630		len = len + 1;
1631		break;
1632	default:
1633		ucl_create_err (&parser->err, "bad type: %x", (unsigned)fmt);
1634		return -1;
1635	}
1636
1637	return len;
1638}
1639