xref: /freebsd/contrib/libucl/src/ucl_msgpack.c (revision 048488c0)
139ee7a7aSBaptiste Daroussin /*
239ee7a7aSBaptiste Daroussin  * Copyright (c) 2015, Vsevolod Stakhov
339ee7a7aSBaptiste Daroussin  * All rights reserved.
439ee7a7aSBaptiste Daroussin  *
539ee7a7aSBaptiste Daroussin  * Redistribution and use in source and binary forms, with or without
639ee7a7aSBaptiste Daroussin  * modification, are permitted provided that the following conditions are met:
739ee7a7aSBaptiste Daroussin  *	 * Redistributions of source code must retain the above copyright
839ee7a7aSBaptiste Daroussin  *	   notice, this list of conditions and the following disclaimer.
939ee7a7aSBaptiste Daroussin  *	 * Redistributions in binary form must reproduce the above copyright
1039ee7a7aSBaptiste Daroussin  *	   notice, this list of conditions and the following disclaimer in the
1139ee7a7aSBaptiste Daroussin  *	   documentation and/or other materials provided with the distribution.
1239ee7a7aSBaptiste Daroussin  *
1339ee7a7aSBaptiste Daroussin  * THIS SOFTWARE IS PROVIDED BY AUTHOR ''AS IS'' AND ANY
1439ee7a7aSBaptiste Daroussin  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1539ee7a7aSBaptiste Daroussin  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1639ee7a7aSBaptiste Daroussin  * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY
1739ee7a7aSBaptiste Daroussin  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1839ee7a7aSBaptiste Daroussin  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1939ee7a7aSBaptiste Daroussin  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
2039ee7a7aSBaptiste Daroussin  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2139ee7a7aSBaptiste Daroussin  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
2239ee7a7aSBaptiste Daroussin  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2339ee7a7aSBaptiste Daroussin  */
2439ee7a7aSBaptiste Daroussin 
2539ee7a7aSBaptiste Daroussin 
2639ee7a7aSBaptiste Daroussin #ifdef HAVE_CONFIG_H
2739ee7a7aSBaptiste Daroussin #include "config.h"
2839ee7a7aSBaptiste Daroussin #endif
2939ee7a7aSBaptiste Daroussin 
3039ee7a7aSBaptiste Daroussin #include "ucl.h"
3139ee7a7aSBaptiste Daroussin #include "ucl_internal.h"
3239ee7a7aSBaptiste Daroussin 
3339ee7a7aSBaptiste Daroussin #ifdef HAVE_ENDIAN_H
3439ee7a7aSBaptiste Daroussin #include <endian.h>
3539ee7a7aSBaptiste Daroussin #elif defined(HAVE_SYS_ENDIAN_H)
3639ee7a7aSBaptiste Daroussin #include <sys/endian.h>
3739ee7a7aSBaptiste Daroussin #elif defined(HAVE_MACHINE_ENDIAN_H)
3839ee7a7aSBaptiste Daroussin #include <machine/endian.h>
3939ee7a7aSBaptiste Daroussin #endif
4039ee7a7aSBaptiste Daroussin 
4139ee7a7aSBaptiste Daroussin #if !defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)
4239ee7a7aSBaptiste Daroussin 	#if __BYTE_ORDER == __LITTLE_ENDIAN
4339ee7a7aSBaptiste Daroussin 		#define __LITTLE_ENDIAN__
4439ee7a7aSBaptiste Daroussin 	#elif __BYTE_ORDER == __BIG_ENDIAN
4539ee7a7aSBaptiste Daroussin 		#define __BIG_ENDIAN__
4639ee7a7aSBaptiste Daroussin 	#elif _WIN32
4739ee7a7aSBaptiste Daroussin 		#define __LITTLE_ENDIAN__
4839ee7a7aSBaptiste Daroussin 	#endif
4939ee7a7aSBaptiste Daroussin #endif
5039ee7a7aSBaptiste Daroussin 
5139ee7a7aSBaptiste Daroussin #define SWAP_LE_BE16(val)	((uint16_t) ( 		\
5239ee7a7aSBaptiste Daroussin 		(uint16_t) ((uint16_t) (val) >> 8) |	\
5339ee7a7aSBaptiste Daroussin 		(uint16_t) ((uint16_t) (val) << 8)))
5439ee7a7aSBaptiste Daroussin 
5539ee7a7aSBaptiste Daroussin #if defined(__clang__) || (defined(__GNUC__) && __GNUC__ >= 4 && defined (__GNUC_MINOR__) && __GNUC_MINOR__ >= 3)
5639ee7a7aSBaptiste Daroussin #	define SWAP_LE_BE32(val) ((uint32_t)__builtin_bswap32 ((uint32_t)(val)))
5739ee7a7aSBaptiste Daroussin #	define SWAP_LE_BE64(val) ((uint64_t)__builtin_bswap64 ((uint64_t)(val)))
5839ee7a7aSBaptiste Daroussin #else
5939ee7a7aSBaptiste Daroussin 	#define SWAP_LE_BE32(val)	((uint32_t)( \
6039ee7a7aSBaptiste Daroussin 		(((uint32_t)(val) & (uint32_t)0x000000ffU) << 24) | \
6139ee7a7aSBaptiste Daroussin 		(((uint32_t)(val) & (uint32_t)0x0000ff00U) <<  8) | \
6239ee7a7aSBaptiste Daroussin 		(((uint32_t)(val) & (uint32_t)0x00ff0000U) >>  8) | \
6339ee7a7aSBaptiste Daroussin 		(((uint32_t)(val) & (uint32_t)0xff000000U) >> 24)))
6439ee7a7aSBaptiste Daroussin 
6539ee7a7aSBaptiste Daroussin 	#define SWAP_LE_BE64(val)	((uint64_t)( 			\
6639ee7a7aSBaptiste Daroussin 		  (((uint64_t)(val) &							\
6739ee7a7aSBaptiste Daroussin 		(uint64_t)(0x00000000000000ffULL)) << 56) |		\
6839ee7a7aSBaptiste Daroussin 		  (((uint64_t)(val) &							\
6939ee7a7aSBaptiste Daroussin 		(uint64_t)(0x000000000000ff00ULL)) << 40) |		\
7039ee7a7aSBaptiste Daroussin 		  (((uint64_t)(val) &							\
7139ee7a7aSBaptiste Daroussin 		(uint64_t)(0x0000000000ff0000ULL)) << 24) |		\
7239ee7a7aSBaptiste Daroussin 		  (((uint64_t)(val) &							\
7339ee7a7aSBaptiste Daroussin 		(uint64_t) (0x00000000ff000000ULL)) <<  8) |	\
7439ee7a7aSBaptiste Daroussin 		  (((uint64_t)(val) &							\
7539ee7a7aSBaptiste Daroussin 		(uint64_t)(0x000000ff00000000ULL)) >>  8) |		\
7639ee7a7aSBaptiste Daroussin 		  (((uint64_t)(val) &							\
7739ee7a7aSBaptiste Daroussin 		(uint64_t)(0x0000ff0000000000ULL)) >> 24) |		\
7839ee7a7aSBaptiste Daroussin 		  (((uint64_t)(val) &							\
7939ee7a7aSBaptiste Daroussin 		(uint64_t)(0x00ff000000000000ULL)) >> 40) |		\
8039ee7a7aSBaptiste Daroussin 		  (((uint64_t)(val) &							\
8139ee7a7aSBaptiste Daroussin 		(uint64_t)(0xff00000000000000ULL)) >> 56)))
8239ee7a7aSBaptiste Daroussin #endif
8339ee7a7aSBaptiste Daroussin 
8439ee7a7aSBaptiste Daroussin #ifdef __LITTLE_ENDIAN__
8539ee7a7aSBaptiste Daroussin #define TO_BE16 SWAP_LE_BE16
8639ee7a7aSBaptiste Daroussin #define TO_BE32 SWAP_LE_BE32
8739ee7a7aSBaptiste Daroussin #define TO_BE64 SWAP_LE_BE64
8839ee7a7aSBaptiste Daroussin #define FROM_BE16 SWAP_LE_BE16
8939ee7a7aSBaptiste Daroussin #define FROM_BE32 SWAP_LE_BE32
9039ee7a7aSBaptiste Daroussin #define FROM_BE64 SWAP_LE_BE64
9139ee7a7aSBaptiste Daroussin #else
9239ee7a7aSBaptiste Daroussin #define TO_BE16(val) (uint16_t)(val)
9339ee7a7aSBaptiste Daroussin #define TO_BE32(val) (uint32_t)(val)
9439ee7a7aSBaptiste Daroussin #define TO_BE64(val) (uint64_t)(val)
9539ee7a7aSBaptiste Daroussin #define FROM_BE16(val) (uint16_t)(val)
9639ee7a7aSBaptiste Daroussin #define FROM_BE32(val) (uint32_t)(val)
9739ee7a7aSBaptiste Daroussin #define FROM_BE64(val) (uint64_t)(val)
9839ee7a7aSBaptiste Daroussin #endif
9939ee7a7aSBaptiste Daroussin 
10039ee7a7aSBaptiste Daroussin void
ucl_emitter_print_int_msgpack(struct ucl_emitter_context * ctx,int64_t val)10139ee7a7aSBaptiste Daroussin ucl_emitter_print_int_msgpack (struct ucl_emitter_context *ctx, int64_t val)
10239ee7a7aSBaptiste Daroussin {
10339ee7a7aSBaptiste Daroussin 	const struct ucl_emitter_functions *func = ctx->func;
10439ee7a7aSBaptiste Daroussin 	unsigned char buf[sizeof(uint64_t) + 1];
10539ee7a7aSBaptiste Daroussin 	const unsigned char mask_positive = 0x7f, mask_negative = 0xe0,
10639ee7a7aSBaptiste Daroussin 		uint8_ch = 0xcc, uint16_ch = 0xcd, uint32_ch = 0xce, uint64_ch = 0xcf,
10739ee7a7aSBaptiste Daroussin 		int8_ch = 0xd0, int16_ch = 0xd1, int32_ch = 0xd2, int64_ch = 0xd3;
10839ee7a7aSBaptiste Daroussin 	unsigned len;
10939ee7a7aSBaptiste Daroussin 
11039ee7a7aSBaptiste Daroussin 	if (val >= 0) {
11139ee7a7aSBaptiste Daroussin 		if (val <= 0x7f) {
11239ee7a7aSBaptiste Daroussin 			/* Fixed num 7 bits */
11339ee7a7aSBaptiste Daroussin 			len = 1;
11439ee7a7aSBaptiste Daroussin 			buf[0] = mask_positive & val;
11539ee7a7aSBaptiste Daroussin 		}
116d9f0ce31SBaptiste Daroussin 		else if (val <= UINT8_MAX) {
11739ee7a7aSBaptiste Daroussin 			len = 2;
11839ee7a7aSBaptiste Daroussin 			buf[0] = uint8_ch;
11939ee7a7aSBaptiste Daroussin 			buf[1] = val & 0xff;
12039ee7a7aSBaptiste Daroussin 		}
121d9f0ce31SBaptiste Daroussin 		else if (val <= UINT16_MAX) {
12239ee7a7aSBaptiste Daroussin 			uint16_t v = TO_BE16 (val);
12339ee7a7aSBaptiste Daroussin 
12439ee7a7aSBaptiste Daroussin 			len = 3;
12539ee7a7aSBaptiste Daroussin 			buf[0] = uint16_ch;
12639ee7a7aSBaptiste Daroussin 			memcpy (&buf[1], &v, sizeof (v));
12739ee7a7aSBaptiste Daroussin 		}
128d9f0ce31SBaptiste Daroussin 		else if (val <= UINT32_MAX) {
12939ee7a7aSBaptiste Daroussin 			uint32_t v = TO_BE32 (val);
13039ee7a7aSBaptiste Daroussin 
13139ee7a7aSBaptiste Daroussin 			len = 5;
13239ee7a7aSBaptiste Daroussin 			buf[0] = uint32_ch;
13339ee7a7aSBaptiste Daroussin 			memcpy (&buf[1], &v, sizeof (v));
13439ee7a7aSBaptiste Daroussin 		}
13539ee7a7aSBaptiste Daroussin 		else {
13639ee7a7aSBaptiste Daroussin 			uint64_t v = TO_BE64 (val);
13739ee7a7aSBaptiste Daroussin 
13839ee7a7aSBaptiste Daroussin 			len = 9;
13939ee7a7aSBaptiste Daroussin 			buf[0] = uint64_ch;
14039ee7a7aSBaptiste Daroussin 			memcpy (&buf[1], &v, sizeof (v));
14139ee7a7aSBaptiste Daroussin 		}
14239ee7a7aSBaptiste Daroussin 	}
14339ee7a7aSBaptiste Daroussin 	else {
14439ee7a7aSBaptiste Daroussin 		uint64_t uval;
14539ee7a7aSBaptiste Daroussin 		/* Bithack abs */
14639ee7a7aSBaptiste Daroussin 		uval = ((val ^ (val >> 63)) - (val >> 63));
14739ee7a7aSBaptiste Daroussin 
14839ee7a7aSBaptiste Daroussin 		if (val > -(1 << 5)) {
14939ee7a7aSBaptiste Daroussin 			len = 1;
15039ee7a7aSBaptiste Daroussin 			buf[0] = (mask_negative | uval) & 0xff;
15139ee7a7aSBaptiste Daroussin 		}
152d9f0ce31SBaptiste Daroussin 		else if (uval <= INT8_MAX) {
153d9f0ce31SBaptiste Daroussin 			uint8_t v = (uint8_t)val;
15439ee7a7aSBaptiste Daroussin 			len = 2;
15539ee7a7aSBaptiste Daroussin 			buf[0] = int8_ch;
156d9f0ce31SBaptiste Daroussin 			buf[1] = v;
15739ee7a7aSBaptiste Daroussin 		}
158d9f0ce31SBaptiste Daroussin 		else if (uval <= INT16_MAX) {
15939ee7a7aSBaptiste Daroussin 			uint16_t v = TO_BE16 (val);
16039ee7a7aSBaptiste Daroussin 
16139ee7a7aSBaptiste Daroussin 			len = 3;
16239ee7a7aSBaptiste Daroussin 			buf[0] = int16_ch;
16339ee7a7aSBaptiste Daroussin 			memcpy (&buf[1], &v, sizeof (v));
16439ee7a7aSBaptiste Daroussin 		}
165d9f0ce31SBaptiste Daroussin 		else if (uval <= INT32_MAX) {
16639ee7a7aSBaptiste Daroussin 			uint32_t v = TO_BE32 (val);
16739ee7a7aSBaptiste Daroussin 
16839ee7a7aSBaptiste Daroussin 			len = 5;
16939ee7a7aSBaptiste Daroussin 			buf[0] = int32_ch;
17039ee7a7aSBaptiste Daroussin 			memcpy (&buf[1], &v, sizeof (v));
17139ee7a7aSBaptiste Daroussin 		}
17239ee7a7aSBaptiste Daroussin 		else {
17339ee7a7aSBaptiste Daroussin 			uint64_t v = TO_BE64 (val);
17439ee7a7aSBaptiste Daroussin 
17539ee7a7aSBaptiste Daroussin 			len = 9;
17639ee7a7aSBaptiste Daroussin 			buf[0] = int64_ch;
17739ee7a7aSBaptiste Daroussin 			memcpy (&buf[1], &v, sizeof (v));
17839ee7a7aSBaptiste Daroussin 		}
17939ee7a7aSBaptiste Daroussin 	}
18039ee7a7aSBaptiste Daroussin 
18139ee7a7aSBaptiste Daroussin 	func->ucl_emitter_append_len (buf, len, func->ud);
18239ee7a7aSBaptiste Daroussin }
18339ee7a7aSBaptiste Daroussin 
18439ee7a7aSBaptiste Daroussin void
ucl_emitter_print_double_msgpack(struct ucl_emitter_context * ctx,double val)18539ee7a7aSBaptiste Daroussin ucl_emitter_print_double_msgpack (struct ucl_emitter_context *ctx, double val)
18639ee7a7aSBaptiste Daroussin {
18739ee7a7aSBaptiste Daroussin 	const struct ucl_emitter_functions *func = ctx->func;
18839ee7a7aSBaptiste Daroussin 	union {
18939ee7a7aSBaptiste Daroussin 		double d;
19039ee7a7aSBaptiste Daroussin 		uint64_t i;
19139ee7a7aSBaptiste Daroussin 	} u;
19239ee7a7aSBaptiste Daroussin 	const unsigned char dbl_ch = 0xcb;
19339ee7a7aSBaptiste Daroussin 	unsigned char buf[sizeof(double) + 1];
19439ee7a7aSBaptiste Daroussin 
19539ee7a7aSBaptiste Daroussin 	/* Convert to big endian */
19639ee7a7aSBaptiste Daroussin 	u.d = val;
19739ee7a7aSBaptiste Daroussin 	u.i = TO_BE64 (u.i);
19839ee7a7aSBaptiste Daroussin 
19939ee7a7aSBaptiste Daroussin 	buf[0] = dbl_ch;
20039ee7a7aSBaptiste Daroussin 	memcpy (&buf[1], &u.d, sizeof (double));
20139ee7a7aSBaptiste Daroussin 	func->ucl_emitter_append_len (buf, sizeof (buf), func->ud);
20239ee7a7aSBaptiste Daroussin }
20339ee7a7aSBaptiste Daroussin 
20439ee7a7aSBaptiste Daroussin void
ucl_emitter_print_bool_msgpack(struct ucl_emitter_context * ctx,bool val)20539ee7a7aSBaptiste Daroussin ucl_emitter_print_bool_msgpack (struct ucl_emitter_context *ctx, bool val)
20639ee7a7aSBaptiste Daroussin {
20739ee7a7aSBaptiste Daroussin 	const struct ucl_emitter_functions *func = ctx->func;
20839ee7a7aSBaptiste Daroussin 	const unsigned char true_ch = 0xc3, false_ch = 0xc2;
20939ee7a7aSBaptiste Daroussin 
21039ee7a7aSBaptiste Daroussin 	func->ucl_emitter_append_character (val ? true_ch : false_ch, 1, func->ud);
21139ee7a7aSBaptiste Daroussin }
21239ee7a7aSBaptiste Daroussin 
21339ee7a7aSBaptiste Daroussin void
ucl_emitter_print_string_msgpack(struct ucl_emitter_context * ctx,const char * s,size_t len)21439ee7a7aSBaptiste Daroussin ucl_emitter_print_string_msgpack (struct ucl_emitter_context *ctx,
21539ee7a7aSBaptiste Daroussin 		const char *s, size_t len)
21639ee7a7aSBaptiste Daroussin {
21739ee7a7aSBaptiste Daroussin 	const struct ucl_emitter_functions *func = ctx->func;
21839ee7a7aSBaptiste Daroussin 	const unsigned char fix_mask = 0xA0, l8_ch = 0xd9, l16_ch = 0xda, l32_ch = 0xdb;
21939ee7a7aSBaptiste Daroussin 	unsigned char buf[5];
22039ee7a7aSBaptiste Daroussin 	unsigned blen;
22139ee7a7aSBaptiste Daroussin 
22239ee7a7aSBaptiste Daroussin 	if (len <= 0x1F) {
22339ee7a7aSBaptiste Daroussin 		blen = 1;
22439ee7a7aSBaptiste Daroussin 		buf[0] = (len | fix_mask) & 0xff;
22539ee7a7aSBaptiste Daroussin 	}
22639ee7a7aSBaptiste Daroussin 	else if (len <= 0xff) {
22739ee7a7aSBaptiste Daroussin 		blen = 2;
22839ee7a7aSBaptiste Daroussin 		buf[0] = l8_ch;
22939ee7a7aSBaptiste Daroussin 		buf[1] = len & 0xff;
23039ee7a7aSBaptiste Daroussin 	}
23139ee7a7aSBaptiste Daroussin 	else if (len <= 0xffff) {
23239ee7a7aSBaptiste Daroussin 		uint16_t bl = TO_BE16 (len);
23339ee7a7aSBaptiste Daroussin 
23439ee7a7aSBaptiste Daroussin 		blen = 3;
23539ee7a7aSBaptiste Daroussin 		buf[0] = l16_ch;
23639ee7a7aSBaptiste Daroussin 		memcpy (&buf[1], &bl, sizeof (bl));
23739ee7a7aSBaptiste Daroussin 	}
23839ee7a7aSBaptiste Daroussin 	else {
23939ee7a7aSBaptiste Daroussin 		uint32_t bl = TO_BE32 (len);
24039ee7a7aSBaptiste Daroussin 
24139ee7a7aSBaptiste Daroussin 		blen = 5;
24239ee7a7aSBaptiste Daroussin 		buf[0] = l32_ch;
24339ee7a7aSBaptiste Daroussin 		memcpy (&buf[1], &bl, sizeof (bl));
24439ee7a7aSBaptiste Daroussin 	}
24539ee7a7aSBaptiste Daroussin 
24639ee7a7aSBaptiste Daroussin 	func->ucl_emitter_append_len (buf, blen, func->ud);
24739ee7a7aSBaptiste Daroussin 	func->ucl_emitter_append_len (s, len, func->ud);
24839ee7a7aSBaptiste Daroussin }
24939ee7a7aSBaptiste Daroussin 
25039ee7a7aSBaptiste Daroussin void
ucl_emitter_print_binary_string_msgpack(struct ucl_emitter_context * ctx,const char * s,size_t len)25139ee7a7aSBaptiste Daroussin ucl_emitter_print_binary_string_msgpack (struct ucl_emitter_context *ctx,
25239ee7a7aSBaptiste Daroussin 		const char *s, size_t len)
25339ee7a7aSBaptiste Daroussin {
25439ee7a7aSBaptiste Daroussin 	const struct ucl_emitter_functions *func = ctx->func;
25539ee7a7aSBaptiste Daroussin 	const unsigned char l8_ch = 0xc4, l16_ch = 0xc5, l32_ch = 0xc6;
25639ee7a7aSBaptiste Daroussin 	unsigned char buf[5];
25739ee7a7aSBaptiste Daroussin 	unsigned blen;
25839ee7a7aSBaptiste Daroussin 
25939ee7a7aSBaptiste Daroussin 	if (len <= 0xff) {
26039ee7a7aSBaptiste Daroussin 		blen = 2;
26139ee7a7aSBaptiste Daroussin 		buf[0] = l8_ch;
26239ee7a7aSBaptiste Daroussin 		buf[1] = len & 0xff;
26339ee7a7aSBaptiste Daroussin 	}
26439ee7a7aSBaptiste Daroussin 	else if (len <= 0xffff) {
26539ee7a7aSBaptiste Daroussin 		uint16_t bl = TO_BE16 (len);
26639ee7a7aSBaptiste Daroussin 
26739ee7a7aSBaptiste Daroussin 		blen = 3;
26839ee7a7aSBaptiste Daroussin 		buf[0] = l16_ch;
26939ee7a7aSBaptiste Daroussin 		memcpy (&buf[1], &bl, sizeof (bl));
27039ee7a7aSBaptiste Daroussin 	}
27139ee7a7aSBaptiste Daroussin 	else {
27239ee7a7aSBaptiste Daroussin 		uint32_t bl = TO_BE32 (len);
27339ee7a7aSBaptiste Daroussin 
27439ee7a7aSBaptiste Daroussin 		blen = 5;
27539ee7a7aSBaptiste Daroussin 		buf[0] = l32_ch;
27639ee7a7aSBaptiste Daroussin 		memcpy (&buf[1], &bl, sizeof (bl));
27739ee7a7aSBaptiste Daroussin 	}
27839ee7a7aSBaptiste Daroussin 
27939ee7a7aSBaptiste Daroussin 	func->ucl_emitter_append_len (buf, blen, func->ud);
28039ee7a7aSBaptiste Daroussin 	func->ucl_emitter_append_len (s, len, func->ud);
28139ee7a7aSBaptiste Daroussin }
28239ee7a7aSBaptiste Daroussin 
28339ee7a7aSBaptiste Daroussin void
ucl_emitter_print_null_msgpack(struct ucl_emitter_context * ctx)28439ee7a7aSBaptiste Daroussin ucl_emitter_print_null_msgpack (struct ucl_emitter_context *ctx)
28539ee7a7aSBaptiste Daroussin {
28639ee7a7aSBaptiste Daroussin 	const struct ucl_emitter_functions *func = ctx->func;
28739ee7a7aSBaptiste Daroussin 	const unsigned char nil = 0xc0;
28839ee7a7aSBaptiste Daroussin 
28939ee7a7aSBaptiste Daroussin 	func->ucl_emitter_append_character (nil, 1, func->ud);
29039ee7a7aSBaptiste Daroussin }
29139ee7a7aSBaptiste Daroussin 
29239ee7a7aSBaptiste Daroussin void
ucl_emitter_print_key_msgpack(bool print_key,struct ucl_emitter_context * ctx,const ucl_object_t * obj)29339ee7a7aSBaptiste Daroussin ucl_emitter_print_key_msgpack (bool print_key, struct ucl_emitter_context *ctx,
29439ee7a7aSBaptiste Daroussin 		const ucl_object_t *obj)
29539ee7a7aSBaptiste Daroussin {
29639ee7a7aSBaptiste Daroussin 	if (print_key) {
29739ee7a7aSBaptiste Daroussin 		ucl_emitter_print_string_msgpack (ctx, obj->key, obj->keylen);
29839ee7a7aSBaptiste Daroussin 	}
29939ee7a7aSBaptiste Daroussin }
30039ee7a7aSBaptiste Daroussin 
30139ee7a7aSBaptiste Daroussin void
ucl_emitter_print_array_msgpack(struct ucl_emitter_context * ctx,size_t len)30239ee7a7aSBaptiste Daroussin ucl_emitter_print_array_msgpack (struct ucl_emitter_context *ctx, size_t len)
30339ee7a7aSBaptiste Daroussin {
30439ee7a7aSBaptiste Daroussin 	const struct ucl_emitter_functions *func = ctx->func;
30539ee7a7aSBaptiste Daroussin 	const unsigned char fix_mask = 0x90, l16_ch = 0xdc, l32_ch = 0xdd;
30639ee7a7aSBaptiste Daroussin 	unsigned char buf[5];
30739ee7a7aSBaptiste Daroussin 	unsigned blen;
30839ee7a7aSBaptiste Daroussin 
30939ee7a7aSBaptiste Daroussin 	if (len <= 0xF) {
31039ee7a7aSBaptiste Daroussin 		blen = 1;
31139ee7a7aSBaptiste Daroussin 		buf[0] = (len | fix_mask) & 0xff;
31239ee7a7aSBaptiste Daroussin 	}
31339ee7a7aSBaptiste Daroussin 	else if (len <= 0xffff) {
31439ee7a7aSBaptiste Daroussin 		uint16_t bl = TO_BE16 (len);
31539ee7a7aSBaptiste Daroussin 
31639ee7a7aSBaptiste Daroussin 		blen = 3;
31739ee7a7aSBaptiste Daroussin 		buf[0] = l16_ch;
31839ee7a7aSBaptiste Daroussin 		memcpy (&buf[1], &bl, sizeof (bl));
31939ee7a7aSBaptiste Daroussin 	}
32039ee7a7aSBaptiste Daroussin 	else {
32139ee7a7aSBaptiste Daroussin 		uint32_t bl = TO_BE32 (len);
32239ee7a7aSBaptiste Daroussin 
32339ee7a7aSBaptiste Daroussin 		blen = 5;
32439ee7a7aSBaptiste Daroussin 		buf[0] = l32_ch;
32539ee7a7aSBaptiste Daroussin 		memcpy (&buf[1], &bl, sizeof (bl));
32639ee7a7aSBaptiste Daroussin 	}
32739ee7a7aSBaptiste Daroussin 
32839ee7a7aSBaptiste Daroussin 	func->ucl_emitter_append_len (buf, blen, func->ud);
32939ee7a7aSBaptiste Daroussin }
33039ee7a7aSBaptiste Daroussin 
33139ee7a7aSBaptiste Daroussin void
ucl_emitter_print_object_msgpack(struct ucl_emitter_context * ctx,size_t len)33239ee7a7aSBaptiste Daroussin ucl_emitter_print_object_msgpack (struct ucl_emitter_context *ctx, size_t len)
33339ee7a7aSBaptiste Daroussin {
33439ee7a7aSBaptiste Daroussin 	const struct ucl_emitter_functions *func = ctx->func;
33539ee7a7aSBaptiste Daroussin 	const unsigned char fix_mask = 0x80, l16_ch = 0xde, l32_ch = 0xdf;
33639ee7a7aSBaptiste Daroussin 	unsigned char buf[5];
33739ee7a7aSBaptiste Daroussin 	unsigned blen;
33839ee7a7aSBaptiste Daroussin 
33939ee7a7aSBaptiste Daroussin 	if (len <= 0xF) {
34039ee7a7aSBaptiste Daroussin 		blen = 1;
34139ee7a7aSBaptiste Daroussin 		buf[0] = (len | fix_mask) & 0xff;
34239ee7a7aSBaptiste Daroussin 	}
34339ee7a7aSBaptiste Daroussin 	else if (len <= 0xffff) {
34439ee7a7aSBaptiste Daroussin 		uint16_t bl = TO_BE16 (len);
34539ee7a7aSBaptiste Daroussin 
34639ee7a7aSBaptiste Daroussin 		blen = 3;
34739ee7a7aSBaptiste Daroussin 		buf[0] = l16_ch;
34839ee7a7aSBaptiste Daroussin 		memcpy (&buf[1], &bl, sizeof (bl));
34939ee7a7aSBaptiste Daroussin 	}
35039ee7a7aSBaptiste Daroussin 	else {
35139ee7a7aSBaptiste Daroussin 		uint32_t bl = TO_BE32 (len);
35239ee7a7aSBaptiste Daroussin 
35339ee7a7aSBaptiste Daroussin 		blen = 5;
35439ee7a7aSBaptiste Daroussin 		buf[0] = l32_ch;
35539ee7a7aSBaptiste Daroussin 		memcpy (&buf[1], &bl, sizeof (bl));
35639ee7a7aSBaptiste Daroussin 	}
35739ee7a7aSBaptiste Daroussin 
35839ee7a7aSBaptiste Daroussin 	func->ucl_emitter_append_len (buf, blen, func->ud);
35939ee7a7aSBaptiste Daroussin }
36039ee7a7aSBaptiste Daroussin 
36139ee7a7aSBaptiste Daroussin 
36239ee7a7aSBaptiste Daroussin enum ucl_msgpack_format {
36339ee7a7aSBaptiste Daroussin 	msgpack_positive_fixint = 0,
36439ee7a7aSBaptiste Daroussin 	msgpack_fixmap,
36539ee7a7aSBaptiste Daroussin 	msgpack_fixarray,
36639ee7a7aSBaptiste Daroussin 	msgpack_fixstr,
36739ee7a7aSBaptiste Daroussin 	msgpack_nil,
36839ee7a7aSBaptiste Daroussin 	msgpack_false,
36939ee7a7aSBaptiste Daroussin 	msgpack_true,
37039ee7a7aSBaptiste Daroussin 	msgpack_bin8,
37139ee7a7aSBaptiste Daroussin 	msgpack_bin16,
37239ee7a7aSBaptiste Daroussin 	msgpack_bin32,
37339ee7a7aSBaptiste Daroussin 	msgpack_ext8,
37439ee7a7aSBaptiste Daroussin 	msgpack_ext16,
37539ee7a7aSBaptiste Daroussin 	msgpack_ext32,
37639ee7a7aSBaptiste Daroussin 	msgpack_float32,
37739ee7a7aSBaptiste Daroussin 	msgpack_float64,
37839ee7a7aSBaptiste Daroussin 	msgpack_uint8,
37939ee7a7aSBaptiste Daroussin 	msgpack_uint16,
38039ee7a7aSBaptiste Daroussin 	msgpack_uint32,
38139ee7a7aSBaptiste Daroussin 	msgpack_uint64,
38239ee7a7aSBaptiste Daroussin 	msgpack_int8,
38339ee7a7aSBaptiste Daroussin 	msgpack_int16,
38439ee7a7aSBaptiste Daroussin 	msgpack_int32,
38539ee7a7aSBaptiste Daroussin 	msgpack_int64,
38639ee7a7aSBaptiste Daroussin 	msgpack_fixext1,
38739ee7a7aSBaptiste Daroussin 	msgpack_fixext2,
38839ee7a7aSBaptiste Daroussin 	msgpack_fixext4,
38939ee7a7aSBaptiste Daroussin 	msgpack_fixext8,
39039ee7a7aSBaptiste Daroussin 	msgpack_fixext16,
39139ee7a7aSBaptiste Daroussin 	msgpack_str8,
39239ee7a7aSBaptiste Daroussin 	msgpack_str16,
39339ee7a7aSBaptiste Daroussin 	msgpack_str32,
39439ee7a7aSBaptiste Daroussin 	msgpack_array16,
39539ee7a7aSBaptiste Daroussin 	msgpack_array32,
39639ee7a7aSBaptiste Daroussin 	msgpack_map16,
39739ee7a7aSBaptiste Daroussin 	msgpack_map32,
39839ee7a7aSBaptiste Daroussin 	msgpack_negative_fixint,
39939ee7a7aSBaptiste Daroussin 	msgpack_invalid
40039ee7a7aSBaptiste Daroussin };
40139ee7a7aSBaptiste Daroussin 
40239ee7a7aSBaptiste Daroussin typedef ssize_t (*ucl_msgpack_parse_function)(struct ucl_parser *parser,
40339ee7a7aSBaptiste Daroussin 		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
40439ee7a7aSBaptiste Daroussin 		const unsigned char *pos, size_t remain);
40539ee7a7aSBaptiste Daroussin 
40639ee7a7aSBaptiste Daroussin static ssize_t ucl_msgpack_parse_map (struct ucl_parser *parser,
40739ee7a7aSBaptiste Daroussin 		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
40839ee7a7aSBaptiste Daroussin 		const unsigned char *pos, size_t remain);
40939ee7a7aSBaptiste Daroussin static ssize_t ucl_msgpack_parse_array (struct ucl_parser *parser,
41039ee7a7aSBaptiste Daroussin 		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
41139ee7a7aSBaptiste Daroussin 		const unsigned char *pos, size_t remain);
41239ee7a7aSBaptiste Daroussin static ssize_t ucl_msgpack_parse_string (struct ucl_parser *parser,
41339ee7a7aSBaptiste Daroussin 		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
41439ee7a7aSBaptiste Daroussin 		const unsigned char *pos, size_t remain);
41539ee7a7aSBaptiste Daroussin static ssize_t ucl_msgpack_parse_int (struct ucl_parser *parser,
41639ee7a7aSBaptiste Daroussin 		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
41739ee7a7aSBaptiste Daroussin 		const unsigned char *pos, size_t remain);
41839ee7a7aSBaptiste Daroussin static ssize_t ucl_msgpack_parse_float (struct ucl_parser *parser,
41939ee7a7aSBaptiste Daroussin 		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
42039ee7a7aSBaptiste Daroussin 		const unsigned char *pos, size_t remain);
42139ee7a7aSBaptiste Daroussin static ssize_t ucl_msgpack_parse_bool (struct ucl_parser *parser,
42239ee7a7aSBaptiste Daroussin 		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
42339ee7a7aSBaptiste Daroussin 		const unsigned char *pos, size_t remain);
42439ee7a7aSBaptiste Daroussin static ssize_t ucl_msgpack_parse_null (struct ucl_parser *parser,
42539ee7a7aSBaptiste Daroussin 		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
42639ee7a7aSBaptiste Daroussin 		const unsigned char *pos, size_t remain);
42739ee7a7aSBaptiste Daroussin static ssize_t ucl_msgpack_parse_ignore (struct ucl_parser *parser,
42839ee7a7aSBaptiste Daroussin 		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
42939ee7a7aSBaptiste Daroussin 		const unsigned char *pos, size_t remain);
43039ee7a7aSBaptiste Daroussin 
43139ee7a7aSBaptiste Daroussin #define MSGPACK_FLAG_FIXED (1 << 0)
43239ee7a7aSBaptiste Daroussin #define MSGPACK_FLAG_CONTAINER (1 << 1)
43339ee7a7aSBaptiste Daroussin #define MSGPACK_FLAG_TYPEVALUE (1 << 2)
43439ee7a7aSBaptiste Daroussin #define MSGPACK_FLAG_EXT (1 << 3)
43539ee7a7aSBaptiste Daroussin #define MSGPACK_FLAG_ASSOC (1 << 4)
43639ee7a7aSBaptiste Daroussin #define MSGPACK_FLAG_KEY (1 << 5)
43739ee7a7aSBaptiste Daroussin 
43839ee7a7aSBaptiste Daroussin /*
43939ee7a7aSBaptiste Daroussin  * Search tree packed in array
44039ee7a7aSBaptiste Daroussin  */
44139ee7a7aSBaptiste Daroussin struct ucl_msgpack_parser {
44239ee7a7aSBaptiste Daroussin 	uint8_t prefix;						/* Prefix byte					*/
44339ee7a7aSBaptiste Daroussin 	uint8_t prefixlen;					/* Length of prefix in bits		*/
44439ee7a7aSBaptiste Daroussin 	uint8_t fmt;						/* The desired format 			*/
44539ee7a7aSBaptiste Daroussin 	uint8_t len;						/* Length of the object
44639ee7a7aSBaptiste Daroussin 										  (either length bytes
44739ee7a7aSBaptiste Daroussin 										  or length of value in case
44839ee7a7aSBaptiste Daroussin 										  of fixed objects 				*/
44939ee7a7aSBaptiste Daroussin 	uint8_t flags;						/* Flags of the specified type	*/
45039ee7a7aSBaptiste Daroussin 	ucl_msgpack_parse_function func;	/* Parser function				*/
45139ee7a7aSBaptiste Daroussin } parsers[] = {
45239ee7a7aSBaptiste Daroussin 	{
45339ee7a7aSBaptiste Daroussin 			0xa0,
45439ee7a7aSBaptiste Daroussin 			3,
45539ee7a7aSBaptiste Daroussin 			msgpack_fixstr,
45639ee7a7aSBaptiste Daroussin 			0,
45739ee7a7aSBaptiste Daroussin 			MSGPACK_FLAG_FIXED|MSGPACK_FLAG_KEY,
45839ee7a7aSBaptiste Daroussin 			ucl_msgpack_parse_string
45939ee7a7aSBaptiste Daroussin 	},
46039ee7a7aSBaptiste Daroussin 	{
46139ee7a7aSBaptiste Daroussin 			0x0,
46239ee7a7aSBaptiste Daroussin 			1,
46339ee7a7aSBaptiste Daroussin 			msgpack_positive_fixint,
46439ee7a7aSBaptiste Daroussin 			0,
46539ee7a7aSBaptiste Daroussin 			MSGPACK_FLAG_FIXED|MSGPACK_FLAG_TYPEVALUE,
46639ee7a7aSBaptiste Daroussin 			ucl_msgpack_parse_int
46739ee7a7aSBaptiste Daroussin 	},
46839ee7a7aSBaptiste Daroussin 	{
46939ee7a7aSBaptiste Daroussin 			0xe0,
47039ee7a7aSBaptiste Daroussin 			3,
47139ee7a7aSBaptiste Daroussin 			msgpack_negative_fixint,
47239ee7a7aSBaptiste Daroussin 			0,
47339ee7a7aSBaptiste Daroussin 			MSGPACK_FLAG_FIXED|MSGPACK_FLAG_TYPEVALUE,
47439ee7a7aSBaptiste Daroussin 			ucl_msgpack_parse_int
47539ee7a7aSBaptiste Daroussin 	},
47639ee7a7aSBaptiste Daroussin 	{
47739ee7a7aSBaptiste Daroussin 			0x80,
47839ee7a7aSBaptiste Daroussin 			4,
47939ee7a7aSBaptiste Daroussin 			msgpack_fixmap,
48039ee7a7aSBaptiste Daroussin 			0,
48139ee7a7aSBaptiste Daroussin 			MSGPACK_FLAG_FIXED|MSGPACK_FLAG_CONTAINER|MSGPACK_FLAG_ASSOC,
48239ee7a7aSBaptiste Daroussin 			ucl_msgpack_parse_map
48339ee7a7aSBaptiste Daroussin 	},
48439ee7a7aSBaptiste Daroussin 	{
48539ee7a7aSBaptiste Daroussin 			0x90,
48639ee7a7aSBaptiste Daroussin 			4,
48739ee7a7aSBaptiste Daroussin 			msgpack_fixarray,
48839ee7a7aSBaptiste Daroussin 			0,
48939ee7a7aSBaptiste Daroussin 			MSGPACK_FLAG_FIXED|MSGPACK_FLAG_CONTAINER,
49039ee7a7aSBaptiste Daroussin 			ucl_msgpack_parse_array
49139ee7a7aSBaptiste Daroussin 	},
49239ee7a7aSBaptiste Daroussin 	{
49339ee7a7aSBaptiste Daroussin 			0xd9,
49439ee7a7aSBaptiste Daroussin 			8,
49539ee7a7aSBaptiste Daroussin 			msgpack_str8,
49639ee7a7aSBaptiste Daroussin 			1,
49739ee7a7aSBaptiste Daroussin 			MSGPACK_FLAG_KEY,
49839ee7a7aSBaptiste Daroussin 			ucl_msgpack_parse_string
49939ee7a7aSBaptiste Daroussin 	},
50039ee7a7aSBaptiste Daroussin 	{
50139ee7a7aSBaptiste Daroussin 			0xc4,
50239ee7a7aSBaptiste Daroussin 			8,
50339ee7a7aSBaptiste Daroussin 			msgpack_bin8,
50439ee7a7aSBaptiste Daroussin 			1,
50539ee7a7aSBaptiste Daroussin 			MSGPACK_FLAG_KEY,
50639ee7a7aSBaptiste Daroussin 			ucl_msgpack_parse_string
50739ee7a7aSBaptiste Daroussin 	},
50839ee7a7aSBaptiste Daroussin 	{
50939ee7a7aSBaptiste Daroussin 			0xcf,
51039ee7a7aSBaptiste Daroussin 			8,
51139ee7a7aSBaptiste Daroussin 			msgpack_uint64,
51239ee7a7aSBaptiste Daroussin 			8,
51339ee7a7aSBaptiste Daroussin 			MSGPACK_FLAG_FIXED,
51439ee7a7aSBaptiste Daroussin 			ucl_msgpack_parse_int
51539ee7a7aSBaptiste Daroussin 	},
51639ee7a7aSBaptiste Daroussin 	{
51739ee7a7aSBaptiste Daroussin 			0xd3,
51839ee7a7aSBaptiste Daroussin 			8,
51939ee7a7aSBaptiste Daroussin 			msgpack_int64,
52039ee7a7aSBaptiste Daroussin 			8,
52139ee7a7aSBaptiste Daroussin 			MSGPACK_FLAG_FIXED,
52239ee7a7aSBaptiste Daroussin 			ucl_msgpack_parse_int
52339ee7a7aSBaptiste Daroussin 	},
52439ee7a7aSBaptiste Daroussin 	{
52539ee7a7aSBaptiste Daroussin 			0xce,
52639ee7a7aSBaptiste Daroussin 			8,
52739ee7a7aSBaptiste Daroussin 			msgpack_uint32,
52839ee7a7aSBaptiste Daroussin 			4,
52939ee7a7aSBaptiste Daroussin 			MSGPACK_FLAG_FIXED,
53039ee7a7aSBaptiste Daroussin 			ucl_msgpack_parse_int
53139ee7a7aSBaptiste Daroussin 	},
53239ee7a7aSBaptiste Daroussin 	{
53339ee7a7aSBaptiste Daroussin 			0xd2,
53439ee7a7aSBaptiste Daroussin 			8,
53539ee7a7aSBaptiste Daroussin 			msgpack_int32,
53639ee7a7aSBaptiste Daroussin 			4,
53739ee7a7aSBaptiste Daroussin 			MSGPACK_FLAG_FIXED,
53839ee7a7aSBaptiste Daroussin 			ucl_msgpack_parse_int
53939ee7a7aSBaptiste Daroussin 	},
54039ee7a7aSBaptiste Daroussin 	{
54139ee7a7aSBaptiste Daroussin 			0xcb,
54239ee7a7aSBaptiste Daroussin 			8,
54339ee7a7aSBaptiste Daroussin 			msgpack_float64,
54439ee7a7aSBaptiste Daroussin 			8,
54539ee7a7aSBaptiste Daroussin 			MSGPACK_FLAG_FIXED,
54639ee7a7aSBaptiste Daroussin 			ucl_msgpack_parse_float
54739ee7a7aSBaptiste Daroussin 	},
54839ee7a7aSBaptiste Daroussin 	{
54939ee7a7aSBaptiste Daroussin 			0xca,
55039ee7a7aSBaptiste Daroussin 			8,
55139ee7a7aSBaptiste Daroussin 			msgpack_float32,
55239ee7a7aSBaptiste Daroussin 			4,
55339ee7a7aSBaptiste Daroussin 			MSGPACK_FLAG_FIXED,
55439ee7a7aSBaptiste Daroussin 			ucl_msgpack_parse_float
55539ee7a7aSBaptiste Daroussin 	},
55639ee7a7aSBaptiste Daroussin 	{
55739ee7a7aSBaptiste Daroussin 			0xc2,
55839ee7a7aSBaptiste Daroussin 			8,
55939ee7a7aSBaptiste Daroussin 			msgpack_false,
56039ee7a7aSBaptiste Daroussin 			1,
56139ee7a7aSBaptiste Daroussin 			MSGPACK_FLAG_FIXED | MSGPACK_FLAG_TYPEVALUE,
56239ee7a7aSBaptiste Daroussin 			ucl_msgpack_parse_bool
56339ee7a7aSBaptiste Daroussin 	},
56439ee7a7aSBaptiste Daroussin 	{
56539ee7a7aSBaptiste Daroussin 			0xc3,
56639ee7a7aSBaptiste Daroussin 			8,
56739ee7a7aSBaptiste Daroussin 			msgpack_true,
56839ee7a7aSBaptiste Daroussin 			1,
56939ee7a7aSBaptiste Daroussin 			MSGPACK_FLAG_FIXED | MSGPACK_FLAG_TYPEVALUE,
57039ee7a7aSBaptiste Daroussin 			ucl_msgpack_parse_bool
57139ee7a7aSBaptiste Daroussin 	},
57239ee7a7aSBaptiste Daroussin 	{
57339ee7a7aSBaptiste Daroussin 			0xcc,
57439ee7a7aSBaptiste Daroussin 			8,
57539ee7a7aSBaptiste Daroussin 			msgpack_uint8,
57639ee7a7aSBaptiste Daroussin 			1,
57739ee7a7aSBaptiste Daroussin 			MSGPACK_FLAG_FIXED,
57839ee7a7aSBaptiste Daroussin 			ucl_msgpack_parse_int
57939ee7a7aSBaptiste Daroussin 	},
58039ee7a7aSBaptiste Daroussin 	{
58139ee7a7aSBaptiste Daroussin 			0xcd,
58239ee7a7aSBaptiste Daroussin 			8,
58339ee7a7aSBaptiste Daroussin 			msgpack_uint16,
58439ee7a7aSBaptiste Daroussin 			2,
58539ee7a7aSBaptiste Daroussin 			MSGPACK_FLAG_FIXED,
58639ee7a7aSBaptiste Daroussin 			ucl_msgpack_parse_int
58739ee7a7aSBaptiste Daroussin 	},
58839ee7a7aSBaptiste Daroussin 	{
58939ee7a7aSBaptiste Daroussin 			0xd0,
59039ee7a7aSBaptiste Daroussin 			8,
59139ee7a7aSBaptiste Daroussin 			msgpack_int8,
59239ee7a7aSBaptiste Daroussin 			1,
59339ee7a7aSBaptiste Daroussin 			MSGPACK_FLAG_FIXED,
59439ee7a7aSBaptiste Daroussin 			ucl_msgpack_parse_int
59539ee7a7aSBaptiste Daroussin 	},
59639ee7a7aSBaptiste Daroussin 	{
59739ee7a7aSBaptiste Daroussin 			0xd1,
59839ee7a7aSBaptiste Daroussin 			8,
59939ee7a7aSBaptiste Daroussin 			msgpack_int16,
60039ee7a7aSBaptiste Daroussin 			2,
60139ee7a7aSBaptiste Daroussin 			MSGPACK_FLAG_FIXED,
60239ee7a7aSBaptiste Daroussin 			ucl_msgpack_parse_int
60339ee7a7aSBaptiste Daroussin 	},
60439ee7a7aSBaptiste Daroussin 	{
60539ee7a7aSBaptiste Daroussin 			0xc0,
60639ee7a7aSBaptiste Daroussin 			8,
60739ee7a7aSBaptiste Daroussin 			msgpack_nil,
60839ee7a7aSBaptiste Daroussin 			0,
60939ee7a7aSBaptiste Daroussin 			MSGPACK_FLAG_FIXED | MSGPACK_FLAG_TYPEVALUE,
61039ee7a7aSBaptiste Daroussin 			ucl_msgpack_parse_null
61139ee7a7aSBaptiste Daroussin 	},
61239ee7a7aSBaptiste Daroussin 	{
61339ee7a7aSBaptiste Daroussin 			0xda,
61439ee7a7aSBaptiste Daroussin 			8,
61539ee7a7aSBaptiste Daroussin 			msgpack_str16,
61639ee7a7aSBaptiste Daroussin 			2,
61739ee7a7aSBaptiste Daroussin 			MSGPACK_FLAG_KEY,
61839ee7a7aSBaptiste Daroussin 			ucl_msgpack_parse_string
61939ee7a7aSBaptiste Daroussin 	},
62039ee7a7aSBaptiste Daroussin 	{
62139ee7a7aSBaptiste Daroussin 			0xdb,
62239ee7a7aSBaptiste Daroussin 			8,
62339ee7a7aSBaptiste Daroussin 			msgpack_str32,
62439ee7a7aSBaptiste Daroussin 			4,
62539ee7a7aSBaptiste Daroussin 			MSGPACK_FLAG_KEY,
62639ee7a7aSBaptiste Daroussin 			ucl_msgpack_parse_string
62739ee7a7aSBaptiste Daroussin 	},
62839ee7a7aSBaptiste Daroussin 	{
62939ee7a7aSBaptiste Daroussin 			0xc5,
63039ee7a7aSBaptiste Daroussin 			8,
63139ee7a7aSBaptiste Daroussin 			msgpack_bin16,
63239ee7a7aSBaptiste Daroussin 			2,
63339ee7a7aSBaptiste Daroussin 			MSGPACK_FLAG_KEY,
63439ee7a7aSBaptiste Daroussin 			ucl_msgpack_parse_string
63539ee7a7aSBaptiste Daroussin 	},
63639ee7a7aSBaptiste Daroussin 	{
63739ee7a7aSBaptiste Daroussin 			0xc6,
63839ee7a7aSBaptiste Daroussin 			8,
63939ee7a7aSBaptiste Daroussin 			msgpack_bin32,
64039ee7a7aSBaptiste Daroussin 			4,
64139ee7a7aSBaptiste Daroussin 			MSGPACK_FLAG_KEY,
64239ee7a7aSBaptiste Daroussin 			ucl_msgpack_parse_string
64339ee7a7aSBaptiste Daroussin 	},
64439ee7a7aSBaptiste Daroussin 	{
64539ee7a7aSBaptiste Daroussin 			0xdc,
64639ee7a7aSBaptiste Daroussin 			8,
64739ee7a7aSBaptiste Daroussin 			msgpack_array16,
64839ee7a7aSBaptiste Daroussin 			2,
64939ee7a7aSBaptiste Daroussin 			MSGPACK_FLAG_CONTAINER,
65039ee7a7aSBaptiste Daroussin 			ucl_msgpack_parse_array
65139ee7a7aSBaptiste Daroussin 	},
65239ee7a7aSBaptiste Daroussin 	{
65339ee7a7aSBaptiste Daroussin 			0xdd,
65439ee7a7aSBaptiste Daroussin 			8,
65539ee7a7aSBaptiste Daroussin 			msgpack_array32,
65639ee7a7aSBaptiste Daroussin 			4,
65739ee7a7aSBaptiste Daroussin 			MSGPACK_FLAG_CONTAINER,
65839ee7a7aSBaptiste Daroussin 			ucl_msgpack_parse_array
65939ee7a7aSBaptiste Daroussin 	},
66039ee7a7aSBaptiste Daroussin 	{
66139ee7a7aSBaptiste Daroussin 			0xde,
66239ee7a7aSBaptiste Daroussin 			8,
66339ee7a7aSBaptiste Daroussin 			msgpack_map16,
66439ee7a7aSBaptiste Daroussin 			2,
66539ee7a7aSBaptiste Daroussin 			MSGPACK_FLAG_CONTAINER|MSGPACK_FLAG_ASSOC,
66639ee7a7aSBaptiste Daroussin 			ucl_msgpack_parse_map
66739ee7a7aSBaptiste Daroussin 	},
66839ee7a7aSBaptiste Daroussin 	{
66939ee7a7aSBaptiste Daroussin 			0xdf,
67039ee7a7aSBaptiste Daroussin 			8,
67139ee7a7aSBaptiste Daroussin 			msgpack_map32,
67239ee7a7aSBaptiste Daroussin 			4,
67339ee7a7aSBaptiste Daroussin 			MSGPACK_FLAG_CONTAINER|MSGPACK_FLAG_ASSOC,
67439ee7a7aSBaptiste Daroussin 			ucl_msgpack_parse_map
67539ee7a7aSBaptiste Daroussin 	},
67639ee7a7aSBaptiste Daroussin 	{
67739ee7a7aSBaptiste Daroussin 			0xc7,
67839ee7a7aSBaptiste Daroussin 			8,
67939ee7a7aSBaptiste Daroussin 			msgpack_ext8,
68039ee7a7aSBaptiste Daroussin 			1,
68139ee7a7aSBaptiste Daroussin 			MSGPACK_FLAG_EXT,
68239ee7a7aSBaptiste Daroussin 			ucl_msgpack_parse_ignore
68339ee7a7aSBaptiste Daroussin 	},
68439ee7a7aSBaptiste Daroussin 	{
68539ee7a7aSBaptiste Daroussin 			0xc8,
68639ee7a7aSBaptiste Daroussin 			8,
68739ee7a7aSBaptiste Daroussin 			msgpack_ext16,
68839ee7a7aSBaptiste Daroussin 			2,
68939ee7a7aSBaptiste Daroussin 			MSGPACK_FLAG_EXT,
69039ee7a7aSBaptiste Daroussin 			ucl_msgpack_parse_ignore
69139ee7a7aSBaptiste Daroussin 	},
69239ee7a7aSBaptiste Daroussin 	{
69339ee7a7aSBaptiste Daroussin 			0xc9,
69439ee7a7aSBaptiste Daroussin 			8,
69539ee7a7aSBaptiste Daroussin 			msgpack_ext32,
69639ee7a7aSBaptiste Daroussin 			4,
69739ee7a7aSBaptiste Daroussin 			MSGPACK_FLAG_EXT,
69839ee7a7aSBaptiste Daroussin 			ucl_msgpack_parse_ignore
69939ee7a7aSBaptiste Daroussin 	},
70039ee7a7aSBaptiste Daroussin 	{
70139ee7a7aSBaptiste Daroussin 			0xd4,
70239ee7a7aSBaptiste Daroussin 			8,
70339ee7a7aSBaptiste Daroussin 			msgpack_fixext1,
70439ee7a7aSBaptiste Daroussin 			1,
70539ee7a7aSBaptiste Daroussin 			MSGPACK_FLAG_FIXED | MSGPACK_FLAG_EXT,
70639ee7a7aSBaptiste Daroussin 			ucl_msgpack_parse_ignore
70739ee7a7aSBaptiste Daroussin 	},
70839ee7a7aSBaptiste Daroussin 	{
70939ee7a7aSBaptiste Daroussin 			0xd5,
71039ee7a7aSBaptiste Daroussin 			8,
71139ee7a7aSBaptiste Daroussin 			msgpack_fixext2,
71239ee7a7aSBaptiste Daroussin 			2,
71339ee7a7aSBaptiste Daroussin 			MSGPACK_FLAG_FIXED | MSGPACK_FLAG_EXT,
71439ee7a7aSBaptiste Daroussin 			ucl_msgpack_parse_ignore
71539ee7a7aSBaptiste Daroussin 	},
71639ee7a7aSBaptiste Daroussin 	{
71739ee7a7aSBaptiste Daroussin 			0xd6,
71839ee7a7aSBaptiste Daroussin 			8,
71939ee7a7aSBaptiste Daroussin 			msgpack_fixext4,
72039ee7a7aSBaptiste Daroussin 			4,
72139ee7a7aSBaptiste Daroussin 			MSGPACK_FLAG_FIXED | MSGPACK_FLAG_EXT,
72239ee7a7aSBaptiste Daroussin 			ucl_msgpack_parse_ignore
72339ee7a7aSBaptiste Daroussin 	},
72439ee7a7aSBaptiste Daroussin 	{
72539ee7a7aSBaptiste Daroussin 			0xd7,
72639ee7a7aSBaptiste Daroussin 			8,
72739ee7a7aSBaptiste Daroussin 			msgpack_fixext8,
72839ee7a7aSBaptiste Daroussin 			8,
72939ee7a7aSBaptiste Daroussin 			MSGPACK_FLAG_FIXED | MSGPACK_FLAG_EXT,
73039ee7a7aSBaptiste Daroussin 			ucl_msgpack_parse_ignore
73139ee7a7aSBaptiste Daroussin 	},
73239ee7a7aSBaptiste Daroussin 	{
73339ee7a7aSBaptiste Daroussin 			0xd8,
73439ee7a7aSBaptiste Daroussin 			8,
73539ee7a7aSBaptiste Daroussin 			msgpack_fixext16,
73639ee7a7aSBaptiste Daroussin 			16,
73739ee7a7aSBaptiste Daroussin 			MSGPACK_FLAG_FIXED | MSGPACK_FLAG_EXT,
73839ee7a7aSBaptiste Daroussin 			ucl_msgpack_parse_ignore
73939ee7a7aSBaptiste Daroussin 	}
74039ee7a7aSBaptiste Daroussin };
74139ee7a7aSBaptiste Daroussin 
74239ee7a7aSBaptiste Daroussin #undef MSGPACK_DEBUG_PARSER
74339ee7a7aSBaptiste Daroussin 
74439ee7a7aSBaptiste Daroussin static inline struct ucl_msgpack_parser *
ucl_msgpack_get_parser_from_type(unsigned char t)74539ee7a7aSBaptiste Daroussin ucl_msgpack_get_parser_from_type (unsigned char t)
74639ee7a7aSBaptiste Daroussin {
74739ee7a7aSBaptiste Daroussin 	unsigned int i, shift, mask;
74839ee7a7aSBaptiste Daroussin 
74939ee7a7aSBaptiste Daroussin 	for (i = 0; i < sizeof (parsers) / sizeof (parsers[0]); i ++) {
75039ee7a7aSBaptiste Daroussin 		shift = CHAR_BIT - parsers[i].prefixlen;
75139ee7a7aSBaptiste Daroussin 		mask = parsers[i].prefix >> shift;
75239ee7a7aSBaptiste Daroussin 
753d9f0ce31SBaptiste Daroussin 		if (mask == (((unsigned int)t) >> shift)) {
75439ee7a7aSBaptiste Daroussin 			return &parsers[i];
75539ee7a7aSBaptiste Daroussin 		}
75639ee7a7aSBaptiste Daroussin 	}
75739ee7a7aSBaptiste Daroussin 
75839ee7a7aSBaptiste Daroussin 	return NULL;
75939ee7a7aSBaptiste Daroussin }
76039ee7a7aSBaptiste Daroussin 
76139ee7a7aSBaptiste Daroussin static inline struct ucl_stack *
ucl_msgpack_get_container(struct ucl_parser * parser,struct ucl_msgpack_parser * obj_parser,uint64_t len)76239ee7a7aSBaptiste Daroussin ucl_msgpack_get_container (struct ucl_parser *parser,
76339ee7a7aSBaptiste Daroussin 		struct ucl_msgpack_parser *obj_parser, uint64_t len)
76439ee7a7aSBaptiste Daroussin {
76539ee7a7aSBaptiste Daroussin 	struct ucl_stack *stack;
76639ee7a7aSBaptiste Daroussin 
76739ee7a7aSBaptiste Daroussin 	assert (obj_parser != NULL);
76839ee7a7aSBaptiste Daroussin 
76939ee7a7aSBaptiste Daroussin 	if (obj_parser->flags & MSGPACK_FLAG_CONTAINER) {
77039ee7a7aSBaptiste Daroussin 		/*
77139ee7a7aSBaptiste Daroussin 		 * Insert new container to the stack
77239ee7a7aSBaptiste Daroussin 		 */
77339ee7a7aSBaptiste Daroussin 		if (parser->stack == NULL) {
77439ee7a7aSBaptiste Daroussin 			parser->stack = calloc (1, sizeof (struct ucl_stack));
77539ee7a7aSBaptiste Daroussin 
77639ee7a7aSBaptiste Daroussin 			if (parser->stack == NULL) {
77739ee7a7aSBaptiste Daroussin 				ucl_create_err (&parser->err, "no memory");
77839ee7a7aSBaptiste Daroussin 				return NULL;
77939ee7a7aSBaptiste Daroussin 			}
780a0409676SBaptiste Daroussin 
781a0409676SBaptiste Daroussin 			parser->stack->chunk = parser->chunks;
78239ee7a7aSBaptiste Daroussin 		}
78339ee7a7aSBaptiste Daroussin 		else {
78439ee7a7aSBaptiste Daroussin 			stack = calloc (1, sizeof (struct ucl_stack));
78539ee7a7aSBaptiste Daroussin 
78639ee7a7aSBaptiste Daroussin 			if (stack == NULL) {
78739ee7a7aSBaptiste Daroussin 				ucl_create_err (&parser->err, "no memory");
78839ee7a7aSBaptiste Daroussin 				return NULL;
78939ee7a7aSBaptiste Daroussin 			}
79039ee7a7aSBaptiste Daroussin 
791a0409676SBaptiste Daroussin 			stack->chunk = parser->chunks;
79239ee7a7aSBaptiste Daroussin 			stack->next = parser->stack;
79339ee7a7aSBaptiste Daroussin 			parser->stack = stack;
79439ee7a7aSBaptiste Daroussin 		}
79539ee7a7aSBaptiste Daroussin 
796a0409676SBaptiste Daroussin 		parser->stack->e.len = len;
79739ee7a7aSBaptiste Daroussin 
79839ee7a7aSBaptiste Daroussin #ifdef MSGPACK_DEBUG_PARSER
79939ee7a7aSBaptiste Daroussin 		stack = parser->stack;
80039ee7a7aSBaptiste Daroussin 		while (stack) {
80139ee7a7aSBaptiste Daroussin 			fprintf(stderr, "+");
80239ee7a7aSBaptiste Daroussin 			stack = stack->next;
80339ee7a7aSBaptiste Daroussin 		}
80439ee7a7aSBaptiste Daroussin 
80539ee7a7aSBaptiste Daroussin 		fprintf(stderr, "%s -> %d\n", obj_parser->flags & MSGPACK_FLAG_ASSOC ? "object" : "array", (int)len);
80639ee7a7aSBaptiste Daroussin #endif
80739ee7a7aSBaptiste Daroussin 	}
80839ee7a7aSBaptiste Daroussin 	else {
80939ee7a7aSBaptiste Daroussin 		/*
81039ee7a7aSBaptiste Daroussin 		 * Get the current stack top
81139ee7a7aSBaptiste Daroussin 		 */
81239ee7a7aSBaptiste Daroussin 		if (parser->stack) {
81339ee7a7aSBaptiste Daroussin 			return parser->stack;
81439ee7a7aSBaptiste Daroussin 		}
81539ee7a7aSBaptiste Daroussin 		else {
81639ee7a7aSBaptiste Daroussin 			ucl_create_err (&parser->err, "bad top level object for msgpack");
81739ee7a7aSBaptiste Daroussin 			return NULL;
81839ee7a7aSBaptiste Daroussin 		}
81939ee7a7aSBaptiste Daroussin 	}
82039ee7a7aSBaptiste Daroussin 
82139ee7a7aSBaptiste Daroussin 	return parser->stack;
82239ee7a7aSBaptiste Daroussin }
82339ee7a7aSBaptiste Daroussin 
82439ee7a7aSBaptiste Daroussin static bool
ucl_msgpack_is_container_finished(struct ucl_stack * container)82539ee7a7aSBaptiste Daroussin ucl_msgpack_is_container_finished (struct ucl_stack *container)
82639ee7a7aSBaptiste Daroussin {
82739ee7a7aSBaptiste Daroussin 	assert (container != NULL);
82839ee7a7aSBaptiste Daroussin 
82939ee7a7aSBaptiste Daroussin 
830a0409676SBaptiste Daroussin 	if (container->e.len == 0) {
83139ee7a7aSBaptiste Daroussin 		return true;
83239ee7a7aSBaptiste Daroussin 	}
83339ee7a7aSBaptiste Daroussin 
83439ee7a7aSBaptiste Daroussin 	return false;
83539ee7a7aSBaptiste Daroussin }
83639ee7a7aSBaptiste Daroussin 
83739ee7a7aSBaptiste Daroussin static bool
ucl_msgpack_insert_object(struct ucl_parser * parser,const unsigned char * key,size_t keylen,ucl_object_t * obj)83839ee7a7aSBaptiste Daroussin ucl_msgpack_insert_object (struct ucl_parser *parser,
83939ee7a7aSBaptiste Daroussin 		const unsigned char *key,
84039ee7a7aSBaptiste Daroussin 		size_t keylen, ucl_object_t *obj)
84139ee7a7aSBaptiste Daroussin {
84239ee7a7aSBaptiste Daroussin 	struct ucl_stack *container;
84339ee7a7aSBaptiste Daroussin 
84439ee7a7aSBaptiste Daroussin 	container = parser->stack;
84539ee7a7aSBaptiste Daroussin 	assert (container != NULL);
846a0409676SBaptiste Daroussin 	assert (container->e.len > 0);
84739ee7a7aSBaptiste Daroussin 	assert (obj != NULL);
84839ee7a7aSBaptiste Daroussin 	assert (container->obj != NULL);
84939ee7a7aSBaptiste Daroussin 
85039ee7a7aSBaptiste Daroussin 	if (container->obj->type == UCL_ARRAY) {
85139ee7a7aSBaptiste Daroussin 		ucl_array_append (container->obj, obj);
85239ee7a7aSBaptiste Daroussin 	}
85339ee7a7aSBaptiste Daroussin 	else if (container->obj->type == UCL_OBJECT) {
85439ee7a7aSBaptiste Daroussin 		if (key == NULL || keylen == 0) {
85539ee7a7aSBaptiste Daroussin 			ucl_create_err (&parser->err, "cannot insert object with no key");
85639ee7a7aSBaptiste Daroussin 			return false;
85739ee7a7aSBaptiste Daroussin 		}
85839ee7a7aSBaptiste Daroussin 
85939ee7a7aSBaptiste Daroussin 		obj->key = key;
86039ee7a7aSBaptiste Daroussin 		obj->keylen = keylen;
86139ee7a7aSBaptiste Daroussin 
86239ee7a7aSBaptiste Daroussin 		if (!(parser->flags & UCL_PARSER_ZEROCOPY)) {
86339ee7a7aSBaptiste Daroussin 			ucl_copy_key_trash (obj);
86439ee7a7aSBaptiste Daroussin 		}
86539ee7a7aSBaptiste Daroussin 
86639ee7a7aSBaptiste Daroussin 		ucl_parser_process_object_element (parser, obj);
86739ee7a7aSBaptiste Daroussin 	}
86839ee7a7aSBaptiste Daroussin 	else {
86939ee7a7aSBaptiste Daroussin 		ucl_create_err (&parser->err, "bad container type");
87039ee7a7aSBaptiste Daroussin 		return false;
87139ee7a7aSBaptiste Daroussin 	}
87239ee7a7aSBaptiste Daroussin 
873a0409676SBaptiste Daroussin 	container->e.len--;
87439ee7a7aSBaptiste Daroussin 
87539ee7a7aSBaptiste Daroussin 	return true;
87639ee7a7aSBaptiste Daroussin }
87739ee7a7aSBaptiste Daroussin 
87839ee7a7aSBaptiste Daroussin static struct ucl_stack *
ucl_msgpack_get_next_container(struct ucl_parser * parser)87939ee7a7aSBaptiste Daroussin ucl_msgpack_get_next_container (struct ucl_parser *parser)
88039ee7a7aSBaptiste Daroussin {
88139ee7a7aSBaptiste Daroussin 	struct ucl_stack *cur = NULL;
882a0409676SBaptiste Daroussin 	uint64_t len;
88339ee7a7aSBaptiste Daroussin 
88439ee7a7aSBaptiste Daroussin 	cur = parser->stack;
88539ee7a7aSBaptiste Daroussin 
88639ee7a7aSBaptiste Daroussin 	if (cur == NULL) {
88739ee7a7aSBaptiste Daroussin 		return NULL;
88839ee7a7aSBaptiste Daroussin 	}
88939ee7a7aSBaptiste Daroussin 
890a0409676SBaptiste Daroussin 	len = cur->e.len;
89139ee7a7aSBaptiste Daroussin 
892a0409676SBaptiste Daroussin 	if (len == 0) {
89339ee7a7aSBaptiste Daroussin 		/* We need to switch to the previous container */
89439ee7a7aSBaptiste Daroussin 		parser->stack = cur->next;
89539ee7a7aSBaptiste Daroussin 		parser->cur_obj = cur->obj;
89639ee7a7aSBaptiste Daroussin 		free (cur);
89739ee7a7aSBaptiste Daroussin 
89839ee7a7aSBaptiste Daroussin #ifdef MSGPACK_DEBUG_PARSER
89939ee7a7aSBaptiste Daroussin 		cur = parser->stack;
90039ee7a7aSBaptiste Daroussin 			while (cur) {
90139ee7a7aSBaptiste Daroussin 				fprintf(stderr, "-");
90239ee7a7aSBaptiste Daroussin 				cur = cur->next;
90339ee7a7aSBaptiste Daroussin 			}
90439ee7a7aSBaptiste Daroussin 			fprintf(stderr, "-%s -> %d\n", parser->cur_obj->type == UCL_OBJECT ? "object" : "array", (int)parser->cur_obj->len);
90539ee7a7aSBaptiste Daroussin #endif
90639ee7a7aSBaptiste Daroussin 
90739ee7a7aSBaptiste Daroussin 		return ucl_msgpack_get_next_container (parser);
90839ee7a7aSBaptiste Daroussin 	}
90939ee7a7aSBaptiste Daroussin 
91039ee7a7aSBaptiste Daroussin 	/*
91139ee7a7aSBaptiste Daroussin 	 * For UCL containers we don't know length, so we just insert the whole
91239ee7a7aSBaptiste Daroussin 	 * message pack blob into the top level container
91339ee7a7aSBaptiste Daroussin 	 */
91439ee7a7aSBaptiste Daroussin 
91539ee7a7aSBaptiste Daroussin 	assert (cur->obj != NULL);
91639ee7a7aSBaptiste Daroussin 
91739ee7a7aSBaptiste Daroussin 	return cur;
91839ee7a7aSBaptiste Daroussin }
91939ee7a7aSBaptiste Daroussin 
92039ee7a7aSBaptiste Daroussin #define CONSUME_RET do {									\
92139ee7a7aSBaptiste Daroussin 	if (ret != -1) {										\
92239ee7a7aSBaptiste Daroussin 		p += ret;											\
92339ee7a7aSBaptiste Daroussin 		remain -= ret;										\
92439ee7a7aSBaptiste Daroussin 		obj_parser = NULL;									\
92539ee7a7aSBaptiste Daroussin 		assert (remain >= 0);								\
92639ee7a7aSBaptiste Daroussin 	}														\
92739ee7a7aSBaptiste Daroussin 	else {													\
92839ee7a7aSBaptiste Daroussin 		ucl_create_err (&parser->err,						\
92939ee7a7aSBaptiste Daroussin 			"cannot parse type %d of len %u",				\
93039ee7a7aSBaptiste Daroussin 			(int)obj_parser->fmt,							\
93139ee7a7aSBaptiste Daroussin 			(unsigned)len);									\
93239ee7a7aSBaptiste Daroussin 		return false;										\
93339ee7a7aSBaptiste Daroussin 	}														\
93439ee7a7aSBaptiste Daroussin } while(0)
93539ee7a7aSBaptiste Daroussin 
93639ee7a7aSBaptiste Daroussin #define GET_NEXT_STATE do {									\
93739ee7a7aSBaptiste Daroussin 	container = ucl_msgpack_get_next_container (parser);	\
93839ee7a7aSBaptiste Daroussin 	if (container == NULL) {								\
93939ee7a7aSBaptiste Daroussin 		ucl_create_err (&parser->err,						\
94039ee7a7aSBaptiste Daroussin 					"empty container");						\
94139ee7a7aSBaptiste Daroussin 		return false;										\
94239ee7a7aSBaptiste Daroussin 	}														\
94339ee7a7aSBaptiste Daroussin 	next_state = container->obj->type == UCL_OBJECT ? 		\
94439ee7a7aSBaptiste Daroussin 					read_assoc_key : read_array_value;		\
94539ee7a7aSBaptiste Daroussin } while(0)
94639ee7a7aSBaptiste Daroussin 
94739ee7a7aSBaptiste Daroussin static bool
ucl_msgpack_consume(struct ucl_parser * parser)94839ee7a7aSBaptiste Daroussin ucl_msgpack_consume (struct ucl_parser *parser)
94939ee7a7aSBaptiste Daroussin {
95039ee7a7aSBaptiste Daroussin 	const unsigned char *p, *end, *key = NULL;
95139ee7a7aSBaptiste Daroussin 	struct ucl_stack *container;
95239ee7a7aSBaptiste Daroussin 	enum e_msgpack_parser_state {
95339ee7a7aSBaptiste Daroussin 		read_type,
95439ee7a7aSBaptiste Daroussin 		start_assoc,
95539ee7a7aSBaptiste Daroussin 		start_array,
95639ee7a7aSBaptiste Daroussin 		read_assoc_key,
95739ee7a7aSBaptiste Daroussin 		read_assoc_value,
95839ee7a7aSBaptiste Daroussin 		finish_assoc_value,
95939ee7a7aSBaptiste Daroussin 		read_array_value,
96039ee7a7aSBaptiste Daroussin 		finish_array_value,
96139ee7a7aSBaptiste Daroussin 		error_state
96239ee7a7aSBaptiste Daroussin 	} state = read_type, next_state = error_state;
963d9f0ce31SBaptiste Daroussin 	struct ucl_msgpack_parser *obj_parser = NULL;
964d9f0ce31SBaptiste Daroussin 	uint64_t len = 0;
96539ee7a7aSBaptiste Daroussin 	ssize_t ret, remain, keylen = 0;
96639ee7a7aSBaptiste Daroussin #ifdef MSGPACK_DEBUG_PARSER
96739ee7a7aSBaptiste Daroussin 	uint64_t i;
96839ee7a7aSBaptiste Daroussin 	enum e_msgpack_parser_state hist[256];
96939ee7a7aSBaptiste Daroussin #endif
97039ee7a7aSBaptiste Daroussin 
97139ee7a7aSBaptiste Daroussin 	p = parser->chunks->begin;
97239ee7a7aSBaptiste Daroussin 	remain = parser->chunks->remain;
97339ee7a7aSBaptiste Daroussin 	end = p + remain;
97439ee7a7aSBaptiste Daroussin 
97539ee7a7aSBaptiste Daroussin 
97639ee7a7aSBaptiste Daroussin 	while (p < end) {
97739ee7a7aSBaptiste Daroussin #ifdef MSGPACK_DEBUG_PARSER
97839ee7a7aSBaptiste Daroussin 		hist[i++ % 256] = state;
97939ee7a7aSBaptiste Daroussin #endif
98039ee7a7aSBaptiste Daroussin 		switch (state) {
98139ee7a7aSBaptiste Daroussin 		case read_type:
98239ee7a7aSBaptiste Daroussin 			obj_parser = ucl_msgpack_get_parser_from_type (*p);
98339ee7a7aSBaptiste Daroussin 
98439ee7a7aSBaptiste Daroussin 			if (obj_parser == NULL) {
98539ee7a7aSBaptiste Daroussin 				ucl_create_err (&parser->err, "unknown msgpack format: %x",
98639ee7a7aSBaptiste Daroussin 						(unsigned int)*p);
98739ee7a7aSBaptiste Daroussin 
98839ee7a7aSBaptiste Daroussin 				return false;
98939ee7a7aSBaptiste Daroussin 			}
99039ee7a7aSBaptiste Daroussin 			/* Now check length sanity */
99139ee7a7aSBaptiste Daroussin 			if (obj_parser->flags & MSGPACK_FLAG_FIXED) {
99239ee7a7aSBaptiste Daroussin 				if (obj_parser->len == 0) {
99339ee7a7aSBaptiste Daroussin 					/* We have an embedded size */
99439ee7a7aSBaptiste Daroussin 					len = *p & ~obj_parser->prefix;
99539ee7a7aSBaptiste Daroussin 				}
99639ee7a7aSBaptiste Daroussin 				else {
99739ee7a7aSBaptiste Daroussin 					if (remain < obj_parser->len) {
99839ee7a7aSBaptiste Daroussin 						ucl_create_err (&parser->err, "not enough data remain to "
99939ee7a7aSBaptiste Daroussin 								"read object's length: %u remain, %u needed",
100039ee7a7aSBaptiste Daroussin 								(unsigned)remain, obj_parser->len);
100139ee7a7aSBaptiste Daroussin 
100239ee7a7aSBaptiste Daroussin 						return false;
100339ee7a7aSBaptiste Daroussin 					}
100439ee7a7aSBaptiste Daroussin 
100539ee7a7aSBaptiste Daroussin 					len = obj_parser->len;
100639ee7a7aSBaptiste Daroussin 				}
100739ee7a7aSBaptiste Daroussin 
100839ee7a7aSBaptiste Daroussin 				if (!(obj_parser->flags & MSGPACK_FLAG_TYPEVALUE)) {
100939ee7a7aSBaptiste Daroussin 					/* We must pass value as the second byte */
101039ee7a7aSBaptiste Daroussin 					if (remain > 0) {
101139ee7a7aSBaptiste Daroussin 						p ++;
101239ee7a7aSBaptiste Daroussin 						remain --;
101339ee7a7aSBaptiste Daroussin 					}
101439ee7a7aSBaptiste Daroussin 				}
101539ee7a7aSBaptiste Daroussin 				else {
101639ee7a7aSBaptiste Daroussin 					/* Len is irrelevant now */
101739ee7a7aSBaptiste Daroussin 					len = 0;
101839ee7a7aSBaptiste Daroussin 				}
101939ee7a7aSBaptiste Daroussin 			}
102039ee7a7aSBaptiste Daroussin 			else {
102139ee7a7aSBaptiste Daroussin 				/* Length is not embedded */
1022a0409676SBaptiste Daroussin 				remain --;
1023a0409676SBaptiste Daroussin 
102439ee7a7aSBaptiste Daroussin 				if (remain < obj_parser->len) {
102539ee7a7aSBaptiste Daroussin 					ucl_create_err (&parser->err, "not enough data remain to "
102639ee7a7aSBaptiste Daroussin 							"read object's length: %u remain, %u needed",
102739ee7a7aSBaptiste Daroussin 							(unsigned)remain, obj_parser->len);
102839ee7a7aSBaptiste Daroussin 
102939ee7a7aSBaptiste Daroussin 					return false;
103039ee7a7aSBaptiste Daroussin 				}
103139ee7a7aSBaptiste Daroussin 
103239ee7a7aSBaptiste Daroussin 				p ++;
103339ee7a7aSBaptiste Daroussin 
103439ee7a7aSBaptiste Daroussin 				switch (obj_parser->len) {
103539ee7a7aSBaptiste Daroussin 				case 1:
103639ee7a7aSBaptiste Daroussin 					len = *p;
103739ee7a7aSBaptiste Daroussin 					break;
103839ee7a7aSBaptiste Daroussin 				case 2:
103939ee7a7aSBaptiste Daroussin 					len = FROM_BE16 (*(uint16_t *)p);
104039ee7a7aSBaptiste Daroussin 					break;
104139ee7a7aSBaptiste Daroussin 				case 4:
104239ee7a7aSBaptiste Daroussin 					len = FROM_BE32 (*(uint32_t *)p);
104339ee7a7aSBaptiste Daroussin 					break;
104439ee7a7aSBaptiste Daroussin 				case 8:
104539ee7a7aSBaptiste Daroussin 					len = FROM_BE64 (*(uint64_t *)p);
104639ee7a7aSBaptiste Daroussin 					break;
104739ee7a7aSBaptiste Daroussin 				default:
1048a0409676SBaptiste Daroussin 					ucl_create_err (&parser->err, "invalid length of the length field: %u",
1049a0409676SBaptiste Daroussin 							(unsigned)obj_parser->len);
1050a0409676SBaptiste Daroussin 
1051a0409676SBaptiste Daroussin 					return false;
105239ee7a7aSBaptiste Daroussin 				}
105339ee7a7aSBaptiste Daroussin 
105439ee7a7aSBaptiste Daroussin 				p += obj_parser->len;
105539ee7a7aSBaptiste Daroussin 				remain -= obj_parser->len;
105639ee7a7aSBaptiste Daroussin 			}
105739ee7a7aSBaptiste Daroussin 
105839ee7a7aSBaptiste Daroussin 			if (obj_parser->flags & MSGPACK_FLAG_ASSOC) {
105939ee7a7aSBaptiste Daroussin 				/* We have just read the new associative map */
106039ee7a7aSBaptiste Daroussin 				state = start_assoc;
106139ee7a7aSBaptiste Daroussin 			}
106239ee7a7aSBaptiste Daroussin 			else if (obj_parser->flags & MSGPACK_FLAG_CONTAINER){
106339ee7a7aSBaptiste Daroussin 				state = start_array;
106439ee7a7aSBaptiste Daroussin 			}
106539ee7a7aSBaptiste Daroussin 			else {
106639ee7a7aSBaptiste Daroussin 				state = next_state;
106739ee7a7aSBaptiste Daroussin 			}
106839ee7a7aSBaptiste Daroussin 
106939ee7a7aSBaptiste Daroussin 			break;
107039ee7a7aSBaptiste Daroussin 		case start_assoc:
107139ee7a7aSBaptiste Daroussin 			parser->cur_obj = ucl_object_new_full (UCL_OBJECT,
107239ee7a7aSBaptiste Daroussin 					parser->chunks->priority);
107339ee7a7aSBaptiste Daroussin 			/* Insert to the previous level container */
107439ee7a7aSBaptiste Daroussin 			if (parser->stack && !ucl_msgpack_insert_object (parser,
107539ee7a7aSBaptiste Daroussin 					key, keylen, parser->cur_obj)) {
107639ee7a7aSBaptiste Daroussin 				return false;
107739ee7a7aSBaptiste Daroussin 			}
107839ee7a7aSBaptiste Daroussin 			/* Get new container */
107939ee7a7aSBaptiste Daroussin 			container = ucl_msgpack_get_container (parser, obj_parser, len);
108039ee7a7aSBaptiste Daroussin 
108139ee7a7aSBaptiste Daroussin 			if (container == NULL) {
108239ee7a7aSBaptiste Daroussin 				return false;
108339ee7a7aSBaptiste Daroussin 			}
108439ee7a7aSBaptiste Daroussin 
108539ee7a7aSBaptiste Daroussin 			ret = obj_parser->func (parser, container, len, obj_parser->fmt,
108639ee7a7aSBaptiste Daroussin 					p, remain);
108739ee7a7aSBaptiste Daroussin 			CONSUME_RET;
108839ee7a7aSBaptiste Daroussin 			key = NULL;
108939ee7a7aSBaptiste Daroussin 			keylen = 0;
109039ee7a7aSBaptiste Daroussin 
109139ee7a7aSBaptiste Daroussin 			if (len > 0) {
109239ee7a7aSBaptiste Daroussin 				state = read_type;
109339ee7a7aSBaptiste Daroussin 				next_state = read_assoc_key;
109439ee7a7aSBaptiste Daroussin 			}
109539ee7a7aSBaptiste Daroussin 			else {
109639ee7a7aSBaptiste Daroussin 				/* Empty object */
109739ee7a7aSBaptiste Daroussin 				state = finish_assoc_value;
109839ee7a7aSBaptiste Daroussin 			}
109939ee7a7aSBaptiste Daroussin 			break;
110039ee7a7aSBaptiste Daroussin 
110139ee7a7aSBaptiste Daroussin 		case start_array:
110239ee7a7aSBaptiste Daroussin 			parser->cur_obj = ucl_object_new_full (UCL_ARRAY,
110339ee7a7aSBaptiste Daroussin 					parser->chunks->priority);
110439ee7a7aSBaptiste Daroussin 			/* Insert to the previous level container */
110539ee7a7aSBaptiste Daroussin 			if (parser->stack && !ucl_msgpack_insert_object (parser,
110639ee7a7aSBaptiste Daroussin 					key, keylen, parser->cur_obj)) {
110739ee7a7aSBaptiste Daroussin 				return false;
110839ee7a7aSBaptiste Daroussin 			}
110939ee7a7aSBaptiste Daroussin 			/* Get new container */
111039ee7a7aSBaptiste Daroussin 			container = ucl_msgpack_get_container (parser, obj_parser, len);
111139ee7a7aSBaptiste Daroussin 
111239ee7a7aSBaptiste Daroussin 			if (container == NULL) {
111339ee7a7aSBaptiste Daroussin 				return false;
111439ee7a7aSBaptiste Daroussin 			}
111539ee7a7aSBaptiste Daroussin 
111639ee7a7aSBaptiste Daroussin 			ret = obj_parser->func (parser, container, len, obj_parser->fmt,
111739ee7a7aSBaptiste Daroussin 								p, remain);
111839ee7a7aSBaptiste Daroussin 			CONSUME_RET;
111939ee7a7aSBaptiste Daroussin 
112039ee7a7aSBaptiste Daroussin 			if (len > 0) {
112139ee7a7aSBaptiste Daroussin 				state = read_type;
112239ee7a7aSBaptiste Daroussin 				next_state = read_array_value;
112339ee7a7aSBaptiste Daroussin 			}
112439ee7a7aSBaptiste Daroussin 			else {
112539ee7a7aSBaptiste Daroussin 				/* Empty array */
112639ee7a7aSBaptiste Daroussin 				state = finish_array_value;
112739ee7a7aSBaptiste Daroussin 			}
112839ee7a7aSBaptiste Daroussin 			break;
112939ee7a7aSBaptiste Daroussin 
113039ee7a7aSBaptiste Daroussin 		case read_array_value:
113139ee7a7aSBaptiste Daroussin 			/*
113239ee7a7aSBaptiste Daroussin 			 * p is now at the value start, len now contains length read and
113339ee7a7aSBaptiste Daroussin 			 * obj_parser contains the corresponding specific parser
113439ee7a7aSBaptiste Daroussin 			 */
113539ee7a7aSBaptiste Daroussin 			container = parser->stack;
113639ee7a7aSBaptiste Daroussin 
1137a0409676SBaptiste Daroussin 			if (parser->stack == NULL) {
1138a0409676SBaptiste Daroussin 				ucl_create_err (&parser->err,
1139a0409676SBaptiste Daroussin 						"read assoc value when no container represented");
114039ee7a7aSBaptiste Daroussin 				return false;
114139ee7a7aSBaptiste Daroussin 			}
114239ee7a7aSBaptiste Daroussin 
114339ee7a7aSBaptiste Daroussin 			ret = obj_parser->func (parser, container, len, obj_parser->fmt,
114439ee7a7aSBaptiste Daroussin 					p, remain);
114539ee7a7aSBaptiste Daroussin 			CONSUME_RET;
114639ee7a7aSBaptiste Daroussin 
114739ee7a7aSBaptiste Daroussin 
114839ee7a7aSBaptiste Daroussin 			/* Insert value to the container and check if we have finished array */
114939ee7a7aSBaptiste Daroussin 			if (!ucl_msgpack_insert_object (parser, NULL, 0,
115039ee7a7aSBaptiste Daroussin 					parser->cur_obj)) {
115139ee7a7aSBaptiste Daroussin 				return false;
115239ee7a7aSBaptiste Daroussin 			}
115339ee7a7aSBaptiste Daroussin 
115439ee7a7aSBaptiste Daroussin 			if (ucl_msgpack_is_container_finished (container)) {
115539ee7a7aSBaptiste Daroussin 				state = finish_array_value;
115639ee7a7aSBaptiste Daroussin 			}
115739ee7a7aSBaptiste Daroussin 			else {
115839ee7a7aSBaptiste Daroussin 				/* Read more elements */
115939ee7a7aSBaptiste Daroussin 				state = read_type;
116039ee7a7aSBaptiste Daroussin 				next_state = read_array_value;
116139ee7a7aSBaptiste Daroussin 			}
116239ee7a7aSBaptiste Daroussin 
116339ee7a7aSBaptiste Daroussin 			break;
116439ee7a7aSBaptiste Daroussin 
116539ee7a7aSBaptiste Daroussin 		case read_assoc_key:
116639ee7a7aSBaptiste Daroussin 			/*
116739ee7a7aSBaptiste Daroussin 			 * Keys must have string type for ucl msgpack
116839ee7a7aSBaptiste Daroussin 			 */
116939ee7a7aSBaptiste Daroussin 			if (!(obj_parser->flags & MSGPACK_FLAG_KEY)) {
117039ee7a7aSBaptiste Daroussin 				ucl_create_err (&parser->err, "bad type for key: %u, expected "
117139ee7a7aSBaptiste Daroussin 						"string", (unsigned)obj_parser->fmt);
117239ee7a7aSBaptiste Daroussin 
117339ee7a7aSBaptiste Daroussin 				return false;
117439ee7a7aSBaptiste Daroussin 			}
117539ee7a7aSBaptiste Daroussin 
117639ee7a7aSBaptiste Daroussin 			key = p;
117739ee7a7aSBaptiste Daroussin 			keylen = len;
117839ee7a7aSBaptiste Daroussin 
117939ee7a7aSBaptiste Daroussin 			if (keylen > remain || keylen == 0) {
118039ee7a7aSBaptiste Daroussin 				ucl_create_err (&parser->err, "too long or empty key");
118139ee7a7aSBaptiste Daroussin 				return false;
118239ee7a7aSBaptiste Daroussin 			}
118339ee7a7aSBaptiste Daroussin 
118439ee7a7aSBaptiste Daroussin 			p += len;
118539ee7a7aSBaptiste Daroussin 			remain -= len;
118639ee7a7aSBaptiste Daroussin 
118739ee7a7aSBaptiste Daroussin 			state = read_type;
118839ee7a7aSBaptiste Daroussin 			next_state = read_assoc_value;
118939ee7a7aSBaptiste Daroussin 			break;
119039ee7a7aSBaptiste Daroussin 
119139ee7a7aSBaptiste Daroussin 		case read_assoc_value:
119239ee7a7aSBaptiste Daroussin 			/*
119339ee7a7aSBaptiste Daroussin 			 * p is now at the value start, len now contains length read and
119439ee7a7aSBaptiste Daroussin 			 * obj_parser contains the corresponding specific parser
119539ee7a7aSBaptiste Daroussin 			 */
119639ee7a7aSBaptiste Daroussin 			container = parser->stack;
119739ee7a7aSBaptiste Daroussin 
119839ee7a7aSBaptiste Daroussin 			if (container == NULL) {
1199a0409676SBaptiste Daroussin 				ucl_create_err (&parser->err,
1200a0409676SBaptiste Daroussin 						"read assoc value when no container represented");
120139ee7a7aSBaptiste Daroussin 				return false;
120239ee7a7aSBaptiste Daroussin 			}
120339ee7a7aSBaptiste Daroussin 
120439ee7a7aSBaptiste Daroussin 			ret = obj_parser->func (parser, container, len, obj_parser->fmt,
120539ee7a7aSBaptiste Daroussin 					p, remain);
120639ee7a7aSBaptiste Daroussin 			CONSUME_RET;
120739ee7a7aSBaptiste Daroussin 
120839ee7a7aSBaptiste Daroussin 			assert (key != NULL && keylen > 0);
120939ee7a7aSBaptiste Daroussin 
121039ee7a7aSBaptiste Daroussin 			if (!ucl_msgpack_insert_object (parser, key, keylen,
121139ee7a7aSBaptiste Daroussin 					parser->cur_obj)) {
1212a0409676SBaptiste Daroussin 
121339ee7a7aSBaptiste Daroussin 				return false;
121439ee7a7aSBaptiste Daroussin 			}
121539ee7a7aSBaptiste Daroussin 
121639ee7a7aSBaptiste Daroussin 			key = NULL;
121739ee7a7aSBaptiste Daroussin 			keylen = 0;
121839ee7a7aSBaptiste Daroussin 
121939ee7a7aSBaptiste Daroussin 			if (ucl_msgpack_is_container_finished (container)) {
122039ee7a7aSBaptiste Daroussin 				state = finish_assoc_value;
122139ee7a7aSBaptiste Daroussin 			}
122239ee7a7aSBaptiste Daroussin 			else {
122339ee7a7aSBaptiste Daroussin 				/* Read more elements */
122439ee7a7aSBaptiste Daroussin 				state = read_type;
122539ee7a7aSBaptiste Daroussin 				next_state = read_assoc_key;
122639ee7a7aSBaptiste Daroussin 			}
122739ee7a7aSBaptiste Daroussin 			break;
122839ee7a7aSBaptiste Daroussin 
122939ee7a7aSBaptiste Daroussin 		case finish_array_value:
123039ee7a7aSBaptiste Daroussin 		case finish_assoc_value:
123139ee7a7aSBaptiste Daroussin 			GET_NEXT_STATE;
123239ee7a7aSBaptiste Daroussin 			state = read_type;
123339ee7a7aSBaptiste Daroussin 			break;
123439ee7a7aSBaptiste Daroussin 
123539ee7a7aSBaptiste Daroussin 		case error_state:
123639ee7a7aSBaptiste Daroussin 			ucl_create_err (&parser->err, "invalid state machine state");
123739ee7a7aSBaptiste Daroussin 
123839ee7a7aSBaptiste Daroussin 			return false;
123939ee7a7aSBaptiste Daroussin 		}
124039ee7a7aSBaptiste Daroussin 	}
124139ee7a7aSBaptiste Daroussin 
124239ee7a7aSBaptiste Daroussin 	/* Check the finishing state */
124339ee7a7aSBaptiste Daroussin 	switch (state) {
124439ee7a7aSBaptiste Daroussin 	case start_array:
124539ee7a7aSBaptiste Daroussin 	case start_assoc:
124639ee7a7aSBaptiste Daroussin 		/* Empty container at the end */
124739ee7a7aSBaptiste Daroussin 		if (len != 0) {
1248a0409676SBaptiste Daroussin 			ucl_create_err (&parser->err,
1249a0409676SBaptiste Daroussin 					"invalid non-empty container at the end; len=%zu",
1250048488c0SCy Schubert 					(size_t)len);
125139ee7a7aSBaptiste Daroussin 
125239ee7a7aSBaptiste Daroussin 			return false;
125339ee7a7aSBaptiste Daroussin 		}
125439ee7a7aSBaptiste Daroussin 
125539ee7a7aSBaptiste Daroussin 		parser->cur_obj = ucl_object_new_full (
125639ee7a7aSBaptiste Daroussin 				state == start_array ? UCL_ARRAY : UCL_OBJECT,
125739ee7a7aSBaptiste Daroussin 				parser->chunks->priority);
1258a0409676SBaptiste Daroussin 
1259a0409676SBaptiste Daroussin 		if (parser->stack == NULL) {
1260a0409676SBaptiste Daroussin 			ucl_create_err (&parser->err,
1261a0409676SBaptiste Daroussin 					"read assoc value when no container represented");
1262a0409676SBaptiste Daroussin 			return false;
1263a0409676SBaptiste Daroussin 		}
126439ee7a7aSBaptiste Daroussin 		/* Insert to the previous level container */
126539ee7a7aSBaptiste Daroussin 		if (!ucl_msgpack_insert_object (parser,
126639ee7a7aSBaptiste Daroussin 				key, keylen, parser->cur_obj)) {
126739ee7a7aSBaptiste Daroussin 			return false;
126839ee7a7aSBaptiste Daroussin 		}
126939ee7a7aSBaptiste Daroussin 		/* Get new container */
127039ee7a7aSBaptiste Daroussin 		container = ucl_msgpack_get_container (parser, obj_parser, len);
127139ee7a7aSBaptiste Daroussin 
127239ee7a7aSBaptiste Daroussin 		if (container == NULL) {
127339ee7a7aSBaptiste Daroussin 			return false;
127439ee7a7aSBaptiste Daroussin 		}
127539ee7a7aSBaptiste Daroussin 
127639ee7a7aSBaptiste Daroussin 		ret = obj_parser->func (parser, container, len, obj_parser->fmt,
127739ee7a7aSBaptiste Daroussin 				p, remain);
127839ee7a7aSBaptiste Daroussin 		break;
127939ee7a7aSBaptiste Daroussin 
128039ee7a7aSBaptiste Daroussin 	case read_array_value:
128139ee7a7aSBaptiste Daroussin 	case read_assoc_value:
128239ee7a7aSBaptiste Daroussin 		if (len != 0) {
128339ee7a7aSBaptiste Daroussin 			ucl_create_err (&parser->err, "unfinished value at the end");
128439ee7a7aSBaptiste Daroussin 
128539ee7a7aSBaptiste Daroussin 			return false;
128639ee7a7aSBaptiste Daroussin 		}
128739ee7a7aSBaptiste Daroussin 
128839ee7a7aSBaptiste Daroussin 		container = parser->stack;
128939ee7a7aSBaptiste Daroussin 
1290a0409676SBaptiste Daroussin 		if (parser->stack == NULL) {
1291a0409676SBaptiste Daroussin 			ucl_create_err (&parser->err,
1292a0409676SBaptiste Daroussin 					"read assoc value when no container represented");
129339ee7a7aSBaptiste Daroussin 			return false;
129439ee7a7aSBaptiste Daroussin 		}
129539ee7a7aSBaptiste Daroussin 
129639ee7a7aSBaptiste Daroussin 		ret = obj_parser->func (parser, container, len, obj_parser->fmt,
129739ee7a7aSBaptiste Daroussin 				p, remain);
129839ee7a7aSBaptiste Daroussin 		CONSUME_RET;
129939ee7a7aSBaptiste Daroussin 
130039ee7a7aSBaptiste Daroussin 
130139ee7a7aSBaptiste Daroussin 		/* Insert value to the container and check if we have finished array */
130239ee7a7aSBaptiste Daroussin 		if (!ucl_msgpack_insert_object (parser, NULL, 0,
130339ee7a7aSBaptiste Daroussin 				parser->cur_obj)) {
130439ee7a7aSBaptiste Daroussin 			return false;
130539ee7a7aSBaptiste Daroussin 		}
130639ee7a7aSBaptiste Daroussin 		break;
130739ee7a7aSBaptiste Daroussin 	case finish_array_value:
130839ee7a7aSBaptiste Daroussin 	case finish_assoc_value:
130939ee7a7aSBaptiste Daroussin 	case read_type:
131039ee7a7aSBaptiste Daroussin 		/* Valid finishing state */
131139ee7a7aSBaptiste Daroussin 		break;
131239ee7a7aSBaptiste Daroussin 	default:
131339ee7a7aSBaptiste Daroussin 		/* Invalid finishing state */
131439ee7a7aSBaptiste Daroussin 		ucl_create_err (&parser->err, "invalid state machine finishing state: %d",
131539ee7a7aSBaptiste Daroussin 				state);
131639ee7a7aSBaptiste Daroussin 
131739ee7a7aSBaptiste Daroussin 		return false;
131839ee7a7aSBaptiste Daroussin 	}
131939ee7a7aSBaptiste Daroussin 
132039ee7a7aSBaptiste Daroussin 	/* Rewind to the top level container */
132139ee7a7aSBaptiste Daroussin 	ucl_msgpack_get_next_container (parser);
1322a0409676SBaptiste Daroussin 
1323a0409676SBaptiste Daroussin 	if (parser->stack != NULL) {
1324a0409676SBaptiste Daroussin 		ucl_create_err (&parser->err, "incomplete container");
1325a0409676SBaptiste Daroussin 
1326a0409676SBaptiste Daroussin 		return false;
1327a0409676SBaptiste Daroussin 	}
132839ee7a7aSBaptiste Daroussin 
132939ee7a7aSBaptiste Daroussin 	return true;
133039ee7a7aSBaptiste Daroussin }
133139ee7a7aSBaptiste Daroussin 
133239ee7a7aSBaptiste Daroussin bool
ucl_parse_msgpack(struct ucl_parser * parser)133339ee7a7aSBaptiste Daroussin ucl_parse_msgpack (struct ucl_parser *parser)
133439ee7a7aSBaptiste Daroussin {
133539ee7a7aSBaptiste Daroussin 	ucl_object_t *container = NULL;
133639ee7a7aSBaptiste Daroussin 	const unsigned char *p;
133739ee7a7aSBaptiste Daroussin 	bool ret;
133839ee7a7aSBaptiste Daroussin 
133939ee7a7aSBaptiste Daroussin 	assert (parser != NULL);
134039ee7a7aSBaptiste Daroussin 	assert (parser->chunks != NULL);
134139ee7a7aSBaptiste Daroussin 	assert (parser->chunks->begin != NULL);
134239ee7a7aSBaptiste Daroussin 	assert (parser->chunks->remain != 0);
134339ee7a7aSBaptiste Daroussin 
134439ee7a7aSBaptiste Daroussin 	p = parser->chunks->begin;
134539ee7a7aSBaptiste Daroussin 
134639ee7a7aSBaptiste Daroussin 	if (parser->stack) {
134739ee7a7aSBaptiste Daroussin 		container = parser->stack->obj;
134839ee7a7aSBaptiste Daroussin 	}
134939ee7a7aSBaptiste Daroussin 
135039ee7a7aSBaptiste Daroussin 	/*
135139ee7a7aSBaptiste Daroussin 	 * When we start parsing message pack chunk, we must ensure that we
135239ee7a7aSBaptiste Daroussin 	 * have either a valid container or the top object inside message pack is
135339ee7a7aSBaptiste Daroussin 	 * of container type
135439ee7a7aSBaptiste Daroussin 	 */
135539ee7a7aSBaptiste Daroussin 	if (container == NULL) {
135639ee7a7aSBaptiste Daroussin 		if ((*p & 0x80) != 0x80 && !(*p >= 0xdc && *p <= 0xdf)) {
135739ee7a7aSBaptiste Daroussin 			ucl_create_err (&parser->err, "bad top level object for msgpack");
135839ee7a7aSBaptiste Daroussin 			return false;
135939ee7a7aSBaptiste Daroussin 		}
136039ee7a7aSBaptiste Daroussin 	}
136139ee7a7aSBaptiste Daroussin 
136239ee7a7aSBaptiste Daroussin 	ret = ucl_msgpack_consume (parser);
136339ee7a7aSBaptiste Daroussin 
136439ee7a7aSBaptiste Daroussin 	if (ret && parser->top_obj == NULL) {
136539ee7a7aSBaptiste Daroussin 		parser->top_obj = parser->cur_obj;
136639ee7a7aSBaptiste Daroussin 	}
136739ee7a7aSBaptiste Daroussin 
136839ee7a7aSBaptiste Daroussin 	return ret;
136939ee7a7aSBaptiste Daroussin }
137039ee7a7aSBaptiste Daroussin 
137139ee7a7aSBaptiste Daroussin static ssize_t
ucl_msgpack_parse_map(struct ucl_parser * parser,struct ucl_stack * container,size_t len,enum ucl_msgpack_format fmt,const unsigned char * pos,size_t remain)137239ee7a7aSBaptiste Daroussin ucl_msgpack_parse_map (struct ucl_parser *parser,
137339ee7a7aSBaptiste Daroussin 		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
137439ee7a7aSBaptiste Daroussin 		const unsigned char *pos, size_t remain)
137539ee7a7aSBaptiste Daroussin {
137639ee7a7aSBaptiste Daroussin 	container->obj = parser->cur_obj;
137739ee7a7aSBaptiste Daroussin 
137839ee7a7aSBaptiste Daroussin 	return 0;
137939ee7a7aSBaptiste Daroussin }
138039ee7a7aSBaptiste Daroussin 
138139ee7a7aSBaptiste Daroussin static ssize_t
ucl_msgpack_parse_array(struct ucl_parser * parser,struct ucl_stack * container,size_t len,enum ucl_msgpack_format fmt,const unsigned char * pos,size_t remain)138239ee7a7aSBaptiste Daroussin ucl_msgpack_parse_array (struct ucl_parser *parser,
138339ee7a7aSBaptiste Daroussin 		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
138439ee7a7aSBaptiste Daroussin 		const unsigned char *pos, size_t remain)
138539ee7a7aSBaptiste Daroussin {
138639ee7a7aSBaptiste Daroussin 	container->obj = parser->cur_obj;
138739ee7a7aSBaptiste Daroussin 
138839ee7a7aSBaptiste Daroussin 	return 0;
138939ee7a7aSBaptiste Daroussin }
139039ee7a7aSBaptiste Daroussin 
139139ee7a7aSBaptiste Daroussin static ssize_t
ucl_msgpack_parse_string(struct ucl_parser * parser,struct ucl_stack * container,size_t len,enum ucl_msgpack_format fmt,const unsigned char * pos,size_t remain)139239ee7a7aSBaptiste Daroussin ucl_msgpack_parse_string (struct ucl_parser *parser,
139339ee7a7aSBaptiste Daroussin 		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
139439ee7a7aSBaptiste Daroussin 		const unsigned char *pos, size_t remain)
139539ee7a7aSBaptiste Daroussin {
139639ee7a7aSBaptiste Daroussin 	ucl_object_t *obj;
139739ee7a7aSBaptiste Daroussin 
139839ee7a7aSBaptiste Daroussin 	if (len > remain) {
139939ee7a7aSBaptiste Daroussin 		return -1;
140039ee7a7aSBaptiste Daroussin 	}
140139ee7a7aSBaptiste Daroussin 
140239ee7a7aSBaptiste Daroussin 	obj = ucl_object_new_full (UCL_STRING, parser->chunks->priority);
140339ee7a7aSBaptiste Daroussin 	obj->value.sv = pos;
140439ee7a7aSBaptiste Daroussin 	obj->len = len;
140539ee7a7aSBaptiste Daroussin 
140639ee7a7aSBaptiste Daroussin 	if (fmt >= msgpack_bin8 && fmt <= msgpack_bin32) {
140739ee7a7aSBaptiste Daroussin 		obj->flags |= UCL_OBJECT_BINARY;
140839ee7a7aSBaptiste Daroussin 	}
140939ee7a7aSBaptiste Daroussin 
141039ee7a7aSBaptiste Daroussin 	if (!(parser->flags & UCL_PARSER_ZEROCOPY)) {
141139ee7a7aSBaptiste Daroussin 		if (obj->flags & UCL_OBJECT_BINARY) {
141239ee7a7aSBaptiste Daroussin 			obj->trash_stack[UCL_TRASH_VALUE] = malloc (len);
141339ee7a7aSBaptiste Daroussin 
141439ee7a7aSBaptiste Daroussin 			if (obj->trash_stack[UCL_TRASH_VALUE] != NULL) {
141539ee7a7aSBaptiste Daroussin 				memcpy (obj->trash_stack[UCL_TRASH_VALUE], pos, len);
141639ee7a7aSBaptiste Daroussin 			}
141739ee7a7aSBaptiste Daroussin 		}
141839ee7a7aSBaptiste Daroussin 		else {
141939ee7a7aSBaptiste Daroussin 			ucl_copy_value_trash (obj);
142039ee7a7aSBaptiste Daroussin 		}
142139ee7a7aSBaptiste Daroussin 	}
142239ee7a7aSBaptiste Daroussin 
142339ee7a7aSBaptiste Daroussin 	parser->cur_obj = obj;
142439ee7a7aSBaptiste Daroussin 
142539ee7a7aSBaptiste Daroussin 	return len;
142639ee7a7aSBaptiste Daroussin }
142739ee7a7aSBaptiste Daroussin 
142839ee7a7aSBaptiste Daroussin static ssize_t
ucl_msgpack_parse_int(struct ucl_parser * parser,struct ucl_stack * container,size_t len,enum ucl_msgpack_format fmt,const unsigned char * pos,size_t remain)142939ee7a7aSBaptiste Daroussin ucl_msgpack_parse_int (struct ucl_parser *parser,
143039ee7a7aSBaptiste Daroussin 		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
143139ee7a7aSBaptiste Daroussin 		const unsigned char *pos, size_t remain)
143239ee7a7aSBaptiste Daroussin {
143339ee7a7aSBaptiste Daroussin 	ucl_object_t *obj;
1434d9f0ce31SBaptiste Daroussin 	int8_t iv8;
1435d9f0ce31SBaptiste Daroussin 	int16_t iv16;
1436d9f0ce31SBaptiste Daroussin 	int32_t iv32;
1437d9f0ce31SBaptiste Daroussin 	int64_t iv64;
14386525738fSBaptiste Daroussin 	uint16_t uiv16;
14396525738fSBaptiste Daroussin 	uint32_t uiv32;
14406525738fSBaptiste Daroussin 	uint64_t uiv64;
14416525738fSBaptiste Daroussin 
144239ee7a7aSBaptiste Daroussin 
144339ee7a7aSBaptiste Daroussin 	if (len > remain) {
144439ee7a7aSBaptiste Daroussin 		return -1;
144539ee7a7aSBaptiste Daroussin 	}
144639ee7a7aSBaptiste Daroussin 
144739ee7a7aSBaptiste Daroussin 	obj = ucl_object_new_full (UCL_INT, parser->chunks->priority);
144839ee7a7aSBaptiste Daroussin 
144939ee7a7aSBaptiste Daroussin 	switch (fmt) {
145039ee7a7aSBaptiste Daroussin 	case msgpack_positive_fixint:
145139ee7a7aSBaptiste Daroussin 		obj->value.iv = (*pos & 0x7f);
145239ee7a7aSBaptiste Daroussin 		len = 1;
145339ee7a7aSBaptiste Daroussin 		break;
145439ee7a7aSBaptiste Daroussin 	case msgpack_negative_fixint:
145539ee7a7aSBaptiste Daroussin 		obj->value.iv = - (*pos & 0x1f);
145639ee7a7aSBaptiste Daroussin 		len = 1;
145739ee7a7aSBaptiste Daroussin 		break;
145839ee7a7aSBaptiste Daroussin 	case msgpack_uint8:
145939ee7a7aSBaptiste Daroussin 		obj->value.iv = (unsigned char)*pos;
146039ee7a7aSBaptiste Daroussin 		len = 1;
146139ee7a7aSBaptiste Daroussin 		break;
146239ee7a7aSBaptiste Daroussin 	case msgpack_int8:
1463d9f0ce31SBaptiste Daroussin 		memcpy (&iv8, pos, sizeof (iv8));
1464d9f0ce31SBaptiste Daroussin 		obj->value.iv = iv8;
146539ee7a7aSBaptiste Daroussin 		len = 1;
146639ee7a7aSBaptiste Daroussin 		break;
146739ee7a7aSBaptiste Daroussin 	case msgpack_int16:
1468d9f0ce31SBaptiste Daroussin 		memcpy (&iv16, pos, sizeof (iv16));
1469d9f0ce31SBaptiste Daroussin 		iv16 = FROM_BE16 (iv16);
1470d9f0ce31SBaptiste Daroussin 		obj->value.iv = iv16;
147139ee7a7aSBaptiste Daroussin 		len = 2;
147239ee7a7aSBaptiste Daroussin 		break;
147339ee7a7aSBaptiste Daroussin 	case msgpack_uint16:
14746525738fSBaptiste Daroussin 		memcpy (&uiv16, pos, sizeof (uiv16));
14756525738fSBaptiste Daroussin 		uiv16 = FROM_BE16 (uiv16);
14766525738fSBaptiste Daroussin 		obj->value.iv = uiv16;
147739ee7a7aSBaptiste Daroussin 		len = 2;
147839ee7a7aSBaptiste Daroussin 		break;
147939ee7a7aSBaptiste Daroussin 	case msgpack_int32:
1480d9f0ce31SBaptiste Daroussin 		memcpy (&iv32, pos, sizeof (iv32));
1481d9f0ce31SBaptiste Daroussin 		iv32 = FROM_BE32 (iv32);
1482d9f0ce31SBaptiste Daroussin 		obj->value.iv = iv32;
148339ee7a7aSBaptiste Daroussin 		len = 4;
148439ee7a7aSBaptiste Daroussin 		break;
148539ee7a7aSBaptiste Daroussin 	case msgpack_uint32:
14866525738fSBaptiste Daroussin 		memcpy(&uiv32, pos, sizeof(uiv32));
14876525738fSBaptiste Daroussin 		uiv32 = FROM_BE32(uiv32);
14886525738fSBaptiste Daroussin 		obj->value.iv = uiv32;
148939ee7a7aSBaptiste Daroussin 		len = 4;
149039ee7a7aSBaptiste Daroussin 		break;
149139ee7a7aSBaptiste Daroussin 	case msgpack_int64:
1492d9f0ce31SBaptiste Daroussin 		memcpy (&iv64, pos, sizeof (iv64));
1493d9f0ce31SBaptiste Daroussin 		iv64 = FROM_BE64 (iv64);
1494d9f0ce31SBaptiste Daroussin 		obj->value.iv = iv64;
149539ee7a7aSBaptiste Daroussin 		len = 8;
149639ee7a7aSBaptiste Daroussin 		break;
149739ee7a7aSBaptiste Daroussin 	case msgpack_uint64:
14986525738fSBaptiste Daroussin 		memcpy(&uiv64, pos, sizeof(uiv64));
14996525738fSBaptiste Daroussin 		uiv64 = FROM_BE64(uiv64);
15006525738fSBaptiste Daroussin 		obj->value.iv = uiv64;
150139ee7a7aSBaptiste Daroussin 		len = 8;
150239ee7a7aSBaptiste Daroussin 		break;
150339ee7a7aSBaptiste Daroussin 	default:
150439ee7a7aSBaptiste Daroussin 		assert (0);
150539ee7a7aSBaptiste Daroussin 		break;
150639ee7a7aSBaptiste Daroussin 	}
150739ee7a7aSBaptiste Daroussin 
150839ee7a7aSBaptiste Daroussin 	parser->cur_obj = obj;
150939ee7a7aSBaptiste Daroussin 
151039ee7a7aSBaptiste Daroussin 	return len;
151139ee7a7aSBaptiste Daroussin }
151239ee7a7aSBaptiste Daroussin 
151339ee7a7aSBaptiste Daroussin static ssize_t
ucl_msgpack_parse_float(struct ucl_parser * parser,struct ucl_stack * container,size_t len,enum ucl_msgpack_format fmt,const unsigned char * pos,size_t remain)151439ee7a7aSBaptiste Daroussin ucl_msgpack_parse_float (struct ucl_parser *parser,
151539ee7a7aSBaptiste Daroussin 		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
151639ee7a7aSBaptiste Daroussin 		const unsigned char *pos, size_t remain)
151739ee7a7aSBaptiste Daroussin {
151839ee7a7aSBaptiste Daroussin 	ucl_object_t *obj;
151939ee7a7aSBaptiste Daroussin 	union {
152039ee7a7aSBaptiste Daroussin 		uint32_t i;
152139ee7a7aSBaptiste Daroussin 		float f;
152239ee7a7aSBaptiste Daroussin 	} d;
15236525738fSBaptiste Daroussin 	uint64_t uiv64;
152439ee7a7aSBaptiste Daroussin 
152539ee7a7aSBaptiste Daroussin 	if (len > remain) {
152639ee7a7aSBaptiste Daroussin 		return -1;
152739ee7a7aSBaptiste Daroussin 	}
152839ee7a7aSBaptiste Daroussin 
152939ee7a7aSBaptiste Daroussin 	obj = ucl_object_new_full (UCL_FLOAT, parser->chunks->priority);
153039ee7a7aSBaptiste Daroussin 
153139ee7a7aSBaptiste Daroussin 	switch (fmt) {
153239ee7a7aSBaptiste Daroussin 	case msgpack_float32:
15336525738fSBaptiste Daroussin 		memcpy(&d.i, pos, sizeof(d.i));
15346525738fSBaptiste Daroussin 		d.i = FROM_BE32(d.i);
153539ee7a7aSBaptiste Daroussin 		/* XXX: can be slow */
153639ee7a7aSBaptiste Daroussin 		obj->value.dv = d.f;
153739ee7a7aSBaptiste Daroussin 		len = 4;
153839ee7a7aSBaptiste Daroussin 		break;
153939ee7a7aSBaptiste Daroussin 	case msgpack_float64:
15406525738fSBaptiste Daroussin 		memcpy(&uiv64, pos, sizeof(uiv64));
15416525738fSBaptiste Daroussin 		uiv64 = FROM_BE64(uiv64);
15426525738fSBaptiste Daroussin 		obj->value.iv = uiv64;
154339ee7a7aSBaptiste Daroussin 		len = 8;
154439ee7a7aSBaptiste Daroussin 		break;
154539ee7a7aSBaptiste Daroussin 	default:
154639ee7a7aSBaptiste Daroussin 		assert (0);
154739ee7a7aSBaptiste Daroussin 		break;
154839ee7a7aSBaptiste Daroussin 	}
154939ee7a7aSBaptiste Daroussin 
155039ee7a7aSBaptiste Daroussin 	parser->cur_obj = obj;
155139ee7a7aSBaptiste Daroussin 
155239ee7a7aSBaptiste Daroussin 	return len;
155339ee7a7aSBaptiste Daroussin }
155439ee7a7aSBaptiste Daroussin 
155539ee7a7aSBaptiste Daroussin static ssize_t
ucl_msgpack_parse_bool(struct ucl_parser * parser,struct ucl_stack * container,size_t len,enum ucl_msgpack_format fmt,const unsigned char * pos,size_t remain)155639ee7a7aSBaptiste Daroussin ucl_msgpack_parse_bool (struct ucl_parser *parser,
155739ee7a7aSBaptiste Daroussin 		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
155839ee7a7aSBaptiste Daroussin 		const unsigned char *pos, size_t remain)
155939ee7a7aSBaptiste Daroussin {
156039ee7a7aSBaptiste Daroussin 	ucl_object_t *obj;
156139ee7a7aSBaptiste Daroussin 
156239ee7a7aSBaptiste Daroussin 	if (len > remain) {
156339ee7a7aSBaptiste Daroussin 		return -1;
156439ee7a7aSBaptiste Daroussin 	}
156539ee7a7aSBaptiste Daroussin 
156639ee7a7aSBaptiste Daroussin 	obj = ucl_object_new_full (UCL_BOOLEAN, parser->chunks->priority);
156739ee7a7aSBaptiste Daroussin 
156839ee7a7aSBaptiste Daroussin 	switch (fmt) {
156939ee7a7aSBaptiste Daroussin 	case msgpack_true:
157039ee7a7aSBaptiste Daroussin 		obj->value.iv = true;
157139ee7a7aSBaptiste Daroussin 		break;
157239ee7a7aSBaptiste Daroussin 	case msgpack_false:
157339ee7a7aSBaptiste Daroussin 		obj->value.iv = false;
157439ee7a7aSBaptiste Daroussin 		break;
157539ee7a7aSBaptiste Daroussin 	default:
157639ee7a7aSBaptiste Daroussin 		assert (0);
157739ee7a7aSBaptiste Daroussin 		break;
157839ee7a7aSBaptiste Daroussin 	}
157939ee7a7aSBaptiste Daroussin 
158039ee7a7aSBaptiste Daroussin 	parser->cur_obj = obj;
158139ee7a7aSBaptiste Daroussin 
158239ee7a7aSBaptiste Daroussin 	return 1;
158339ee7a7aSBaptiste Daroussin }
158439ee7a7aSBaptiste Daroussin 
158539ee7a7aSBaptiste Daroussin static ssize_t
ucl_msgpack_parse_null(struct ucl_parser * parser,struct ucl_stack * container,size_t len,enum ucl_msgpack_format fmt,const unsigned char * pos,size_t remain)158639ee7a7aSBaptiste Daroussin ucl_msgpack_parse_null (struct ucl_parser *parser,
158739ee7a7aSBaptiste Daroussin 		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
158839ee7a7aSBaptiste Daroussin 		const unsigned char *pos, size_t remain)
158939ee7a7aSBaptiste Daroussin {
159039ee7a7aSBaptiste Daroussin 	ucl_object_t *obj;
159139ee7a7aSBaptiste Daroussin 
159239ee7a7aSBaptiste Daroussin 	if (len > remain) {
159339ee7a7aSBaptiste Daroussin 		return -1;
159439ee7a7aSBaptiste Daroussin 	}
159539ee7a7aSBaptiste Daroussin 
159639ee7a7aSBaptiste Daroussin 	obj = ucl_object_new_full (UCL_NULL, parser->chunks->priority);
159739ee7a7aSBaptiste Daroussin 	parser->cur_obj = obj;
159839ee7a7aSBaptiste Daroussin 
159939ee7a7aSBaptiste Daroussin 	return 1;
160039ee7a7aSBaptiste Daroussin }
160139ee7a7aSBaptiste Daroussin 
160239ee7a7aSBaptiste Daroussin static ssize_t
ucl_msgpack_parse_ignore(struct ucl_parser * parser,struct ucl_stack * container,size_t len,enum ucl_msgpack_format fmt,const unsigned char * pos,size_t remain)160339ee7a7aSBaptiste Daroussin ucl_msgpack_parse_ignore (struct ucl_parser *parser,
160439ee7a7aSBaptiste Daroussin 		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
160539ee7a7aSBaptiste Daroussin 		const unsigned char *pos, size_t remain)
160639ee7a7aSBaptiste Daroussin {
160739ee7a7aSBaptiste Daroussin 	if (len > remain) {
160839ee7a7aSBaptiste Daroussin 		return -1;
160939ee7a7aSBaptiste Daroussin 	}
161039ee7a7aSBaptiste Daroussin 
161139ee7a7aSBaptiste Daroussin 	switch (fmt) {
161239ee7a7aSBaptiste Daroussin 	case msgpack_fixext1:
161339ee7a7aSBaptiste Daroussin 		len = 2;
161439ee7a7aSBaptiste Daroussin 		break;
161539ee7a7aSBaptiste Daroussin 	case msgpack_fixext2:
161639ee7a7aSBaptiste Daroussin 		len = 3;
161739ee7a7aSBaptiste Daroussin 		break;
161839ee7a7aSBaptiste Daroussin 	case msgpack_fixext4:
161939ee7a7aSBaptiste Daroussin 		len = 5;
162039ee7a7aSBaptiste Daroussin 		break;
162139ee7a7aSBaptiste Daroussin 	case msgpack_fixext8:
162239ee7a7aSBaptiste Daroussin 		len = 9;
162339ee7a7aSBaptiste Daroussin 		break;
162439ee7a7aSBaptiste Daroussin 	case msgpack_fixext16:
162539ee7a7aSBaptiste Daroussin 		len = 17;
162639ee7a7aSBaptiste Daroussin 		break;
162739ee7a7aSBaptiste Daroussin 	case msgpack_ext8:
162839ee7a7aSBaptiste Daroussin 	case msgpack_ext16:
162939ee7a7aSBaptiste Daroussin 	case msgpack_ext32:
163039ee7a7aSBaptiste Daroussin 		len = len + 1;
163139ee7a7aSBaptiste Daroussin 		break;
163239ee7a7aSBaptiste Daroussin 	default:
163339ee7a7aSBaptiste Daroussin 		ucl_create_err (&parser->err, "bad type: %x", (unsigned)fmt);
163439ee7a7aSBaptiste Daroussin 		return -1;
163539ee7a7aSBaptiste Daroussin 	}
163639ee7a7aSBaptiste Daroussin 
163739ee7a7aSBaptiste Daroussin 	return len;
163839ee7a7aSBaptiste Daroussin }
1639