1290067Sbapt/*
2290067Sbapt * Copyright (c) 2015, Vsevolod Stakhov
3290067Sbapt * All rights reserved.
4290067Sbapt *
5290067Sbapt * Redistribution and use in source and binary forms, with or without
6290067Sbapt * modification, are permitted provided that the following conditions are met:
7290067Sbapt *	 * Redistributions of source code must retain the above copyright
8290067Sbapt *	   notice, this list of conditions and the following disclaimer.
9290067Sbapt *	 * Redistributions in binary form must reproduce the above copyright
10290067Sbapt *	   notice, this list of conditions and the following disclaimer in the
11290067Sbapt *	   documentation and/or other materials provided with the distribution.
12290067Sbapt *
13290067Sbapt * THIS SOFTWARE IS PROVIDED BY AUTHOR ''AS IS'' AND ANY
14290067Sbapt * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15290067Sbapt * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16290067Sbapt * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY
17290067Sbapt * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18290067Sbapt * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19290067Sbapt * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20290067Sbapt * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21290067Sbapt * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22290067Sbapt * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23290067Sbapt */
24290067Sbapt
25290067Sbapt
26290067Sbapt#ifdef HAVE_CONFIG_H
27290067Sbapt#include "config.h"
28290067Sbapt#endif
29290067Sbapt
30290067Sbapt#include "ucl.h"
31290067Sbapt#include "ucl_internal.h"
32290067Sbapt
33290067Sbapt#ifdef HAVE_ENDIAN_H
34290067Sbapt#include <endian.h>
35290067Sbapt#elif defined(HAVE_SYS_ENDIAN_H)
36290067Sbapt#include <sys/endian.h>
37290067Sbapt#elif defined(HAVE_MACHINE_ENDIAN_H)
38290067Sbapt#include <machine/endian.h>
39290067Sbapt#endif
40290067Sbapt
41290067Sbapt#if !defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)
42290067Sbapt	#if __BYTE_ORDER == __LITTLE_ENDIAN
43290067Sbapt		#define __LITTLE_ENDIAN__
44290067Sbapt	#elif __BYTE_ORDER == __BIG_ENDIAN
45290067Sbapt		#define __BIG_ENDIAN__
46290067Sbapt	#elif _WIN32
47290067Sbapt		#define __LITTLE_ENDIAN__
48290067Sbapt	#endif
49290067Sbapt#endif
50290067Sbapt
51290067Sbapt#define SWAP_LE_BE16(val)	((uint16_t) ( 		\
52290067Sbapt		(uint16_t) ((uint16_t) (val) >> 8) |	\
53290067Sbapt		(uint16_t) ((uint16_t) (val) << 8)))
54290067Sbapt
55290067Sbapt#if defined(__clang__) || (defined(__GNUC__) && __GNUC__ >= 4 && defined (__GNUC_MINOR__) && __GNUC_MINOR__ >= 3)
56290067Sbapt#	define SWAP_LE_BE32(val) ((uint32_t)__builtin_bswap32 ((uint32_t)(val)))
57290067Sbapt#	define SWAP_LE_BE64(val) ((uint64_t)__builtin_bswap64 ((uint64_t)(val)))
58290067Sbapt#else
59290067Sbapt	#define SWAP_LE_BE32(val)	((uint32_t)( \
60290067Sbapt		(((uint32_t)(val) & (uint32_t)0x000000ffU) << 24) | \
61290067Sbapt		(((uint32_t)(val) & (uint32_t)0x0000ff00U) <<  8) | \
62290067Sbapt		(((uint32_t)(val) & (uint32_t)0x00ff0000U) >>  8) | \
63290067Sbapt		(((uint32_t)(val) & (uint32_t)0xff000000U) >> 24)))
64290067Sbapt
65290067Sbapt	#define SWAP_LE_BE64(val)	((uint64_t)( 			\
66290067Sbapt		  (((uint64_t)(val) &							\
67290067Sbapt		(uint64_t)(0x00000000000000ffULL)) << 56) |		\
68290067Sbapt		  (((uint64_t)(val) &							\
69290067Sbapt		(uint64_t)(0x000000000000ff00ULL)) << 40) |		\
70290067Sbapt		  (((uint64_t)(val) &							\
71290067Sbapt		(uint64_t)(0x0000000000ff0000ULL)) << 24) |		\
72290067Sbapt		  (((uint64_t)(val) &							\
73290067Sbapt		(uint64_t) (0x00000000ff000000ULL)) <<  8) |	\
74290067Sbapt		  (((uint64_t)(val) &							\
75290067Sbapt		(uint64_t)(0x000000ff00000000ULL)) >>  8) |		\
76290067Sbapt		  (((uint64_t)(val) &							\
77290067Sbapt		(uint64_t)(0x0000ff0000000000ULL)) >> 24) |		\
78290067Sbapt		  (((uint64_t)(val) &							\
79290067Sbapt		(uint64_t)(0x00ff000000000000ULL)) >> 40) |		\
80290067Sbapt		  (((uint64_t)(val) &							\
81290067Sbapt		(uint64_t)(0xff00000000000000ULL)) >> 56)))
82290067Sbapt#endif
83290067Sbapt
84290067Sbapt#ifdef __LITTLE_ENDIAN__
85290067Sbapt#define TO_BE16 SWAP_LE_BE16
86290067Sbapt#define TO_BE32 SWAP_LE_BE32
87290067Sbapt#define TO_BE64 SWAP_LE_BE64
88290067Sbapt#define FROM_BE16 SWAP_LE_BE16
89290067Sbapt#define FROM_BE32 SWAP_LE_BE32
90290067Sbapt#define FROM_BE64 SWAP_LE_BE64
91290067Sbapt#else
92290067Sbapt#define TO_BE16(val) (uint16_t)(val)
93290067Sbapt#define TO_BE32(val) (uint32_t)(val)
94290067Sbapt#define TO_BE64(val) (uint64_t)(val)
95290067Sbapt#define FROM_BE16(val) (uint16_t)(val)
96290067Sbapt#define FROM_BE32(val) (uint32_t)(val)
97290067Sbapt#define FROM_BE64(val) (uint64_t)(val)
98290067Sbapt#endif
99290067Sbapt
100290067Sbaptvoid
101290067Sbaptucl_emitter_print_int_msgpack (struct ucl_emitter_context *ctx, int64_t val)
102290067Sbapt{
103290067Sbapt	const struct ucl_emitter_functions *func = ctx->func;
104290067Sbapt	unsigned char buf[sizeof(uint64_t) + 1];
105290067Sbapt	const unsigned char mask_positive = 0x7f, mask_negative = 0xe0,
106290067Sbapt		uint8_ch = 0xcc, uint16_ch = 0xcd, uint32_ch = 0xce, uint64_ch = 0xcf,
107290067Sbapt		int8_ch = 0xd0, int16_ch = 0xd1, int32_ch = 0xd2, int64_ch = 0xd3;
108290067Sbapt	unsigned len;
109290067Sbapt
110290067Sbapt	if (val >= 0) {
111290067Sbapt		if (val <= 0x7f) {
112290067Sbapt			/* Fixed num 7 bits */
113290067Sbapt			len = 1;
114290067Sbapt			buf[0] = mask_positive & val;
115290067Sbapt		}
116298166Sbapt		else if (val <= UINT8_MAX) {
117290067Sbapt			len = 2;
118290067Sbapt			buf[0] = uint8_ch;
119290067Sbapt			buf[1] = val & 0xff;
120290067Sbapt		}
121298166Sbapt		else if (val <= UINT16_MAX) {
122290067Sbapt			uint16_t v = TO_BE16 (val);
123290067Sbapt
124290067Sbapt			len = 3;
125290067Sbapt			buf[0] = uint16_ch;
126290067Sbapt			memcpy (&buf[1], &v, sizeof (v));
127290067Sbapt		}
128298166Sbapt		else if (val <= UINT32_MAX) {
129290067Sbapt			uint32_t v = TO_BE32 (val);
130290067Sbapt
131290067Sbapt			len = 5;
132290067Sbapt			buf[0] = uint32_ch;
133290067Sbapt			memcpy (&buf[1], &v, sizeof (v));
134290067Sbapt		}
135290067Sbapt		else {
136290067Sbapt			uint64_t v = TO_BE64 (val);
137290067Sbapt
138290067Sbapt			len = 9;
139290067Sbapt			buf[0] = uint64_ch;
140290067Sbapt			memcpy (&buf[1], &v, sizeof (v));
141290067Sbapt		}
142290067Sbapt	}
143290067Sbapt	else {
144290067Sbapt		uint64_t uval;
145290067Sbapt		/* Bithack abs */
146290067Sbapt		uval = ((val ^ (val >> 63)) - (val >> 63));
147290067Sbapt
148290067Sbapt		if (val > -(1 << 5)) {
149290067Sbapt			len = 1;
150290067Sbapt			buf[0] = (mask_negative | uval) & 0xff;
151290067Sbapt		}
152298166Sbapt		else if (uval <= INT8_MAX) {
153298166Sbapt			uint8_t v = (uint8_t)val;
154290067Sbapt			len = 2;
155290067Sbapt			buf[0] = int8_ch;
156298166Sbapt			buf[1] = v;
157290067Sbapt		}
158298166Sbapt		else if (uval <= INT16_MAX) {
159290067Sbapt			uint16_t v = TO_BE16 (val);
160290067Sbapt
161290067Sbapt			len = 3;
162290067Sbapt			buf[0] = int16_ch;
163290067Sbapt			memcpy (&buf[1], &v, sizeof (v));
164290067Sbapt		}
165298166Sbapt		else if (uval <= INT32_MAX) {
166290067Sbapt			uint32_t v = TO_BE32 (val);
167290067Sbapt
168290067Sbapt			len = 5;
169290067Sbapt			buf[0] = int32_ch;
170290067Sbapt			memcpy (&buf[1], &v, sizeof (v));
171290067Sbapt		}
172290067Sbapt		else {
173290067Sbapt			uint64_t v = TO_BE64 (val);
174290067Sbapt
175290067Sbapt			len = 9;
176290067Sbapt			buf[0] = int64_ch;
177290067Sbapt			memcpy (&buf[1], &v, sizeof (v));
178290067Sbapt		}
179290067Sbapt	}
180290067Sbapt
181290067Sbapt	func->ucl_emitter_append_len (buf, len, func->ud);
182290067Sbapt}
183290067Sbapt
184290067Sbaptvoid
185290067Sbaptucl_emitter_print_double_msgpack (struct ucl_emitter_context *ctx, double val)
186290067Sbapt{
187290067Sbapt	const struct ucl_emitter_functions *func = ctx->func;
188290067Sbapt	union {
189290067Sbapt		double d;
190290067Sbapt		uint64_t i;
191290067Sbapt	} u;
192290067Sbapt	const unsigned char dbl_ch = 0xcb;
193290067Sbapt	unsigned char buf[sizeof(double) + 1];
194290067Sbapt
195290067Sbapt	/* Convert to big endian */
196290067Sbapt	u.d = val;
197290067Sbapt	u.i = TO_BE64 (u.i);
198290067Sbapt
199290067Sbapt	buf[0] = dbl_ch;
200290067Sbapt	memcpy (&buf[1], &u.d, sizeof (double));
201290067Sbapt	func->ucl_emitter_append_len (buf, sizeof (buf), func->ud);
202290067Sbapt}
203290067Sbapt
204290067Sbaptvoid
205290067Sbaptucl_emitter_print_bool_msgpack (struct ucl_emitter_context *ctx, bool val)
206290067Sbapt{
207290067Sbapt	const struct ucl_emitter_functions *func = ctx->func;
208290067Sbapt	const unsigned char true_ch = 0xc3, false_ch = 0xc2;
209290067Sbapt
210290067Sbapt	func->ucl_emitter_append_character (val ? true_ch : false_ch, 1, func->ud);
211290067Sbapt}
212290067Sbapt
213290067Sbaptvoid
214290067Sbaptucl_emitter_print_string_msgpack (struct ucl_emitter_context *ctx,
215290067Sbapt		const char *s, size_t len)
216290067Sbapt{
217290067Sbapt	const struct ucl_emitter_functions *func = ctx->func;
218290067Sbapt	const unsigned char fix_mask = 0xA0, l8_ch = 0xd9, l16_ch = 0xda, l32_ch = 0xdb;
219290067Sbapt	unsigned char buf[5];
220290067Sbapt	unsigned blen;
221290067Sbapt
222290067Sbapt	if (len <= 0x1F) {
223290067Sbapt		blen = 1;
224290067Sbapt		buf[0] = (len | fix_mask) & 0xff;
225290067Sbapt	}
226290067Sbapt	else if (len <= 0xff) {
227290067Sbapt		blen = 2;
228290067Sbapt		buf[0] = l8_ch;
229290067Sbapt		buf[1] = len & 0xff;
230290067Sbapt	}
231290067Sbapt	else if (len <= 0xffff) {
232290067Sbapt		uint16_t bl = TO_BE16 (len);
233290067Sbapt
234290067Sbapt		blen = 3;
235290067Sbapt		buf[0] = l16_ch;
236290067Sbapt		memcpy (&buf[1], &bl, sizeof (bl));
237290067Sbapt	}
238290067Sbapt	else {
239290067Sbapt		uint32_t bl = TO_BE32 (len);
240290067Sbapt
241290067Sbapt		blen = 5;
242290067Sbapt		buf[0] = l32_ch;
243290067Sbapt		memcpy (&buf[1], &bl, sizeof (bl));
244290067Sbapt	}
245290067Sbapt
246290067Sbapt	func->ucl_emitter_append_len (buf, blen, func->ud);
247290067Sbapt	func->ucl_emitter_append_len (s, len, func->ud);
248290067Sbapt}
249290067Sbapt
250290067Sbaptvoid
251290067Sbaptucl_emitter_print_binary_string_msgpack (struct ucl_emitter_context *ctx,
252290067Sbapt		const char *s, size_t len)
253290067Sbapt{
254290067Sbapt	const struct ucl_emitter_functions *func = ctx->func;
255290067Sbapt	const unsigned char l8_ch = 0xc4, l16_ch = 0xc5, l32_ch = 0xc6;
256290067Sbapt	unsigned char buf[5];
257290067Sbapt	unsigned blen;
258290067Sbapt
259290067Sbapt	if (len <= 0xff) {
260290067Sbapt		blen = 2;
261290067Sbapt		buf[0] = l8_ch;
262290067Sbapt		buf[1] = len & 0xff;
263290067Sbapt	}
264290067Sbapt	else if (len <= 0xffff) {
265290067Sbapt		uint16_t bl = TO_BE16 (len);
266290067Sbapt
267290067Sbapt		blen = 3;
268290067Sbapt		buf[0] = l16_ch;
269290067Sbapt		memcpy (&buf[1], &bl, sizeof (bl));
270290067Sbapt	}
271290067Sbapt	else {
272290067Sbapt		uint32_t bl = TO_BE32 (len);
273290067Sbapt
274290067Sbapt		blen = 5;
275290067Sbapt		buf[0] = l32_ch;
276290067Sbapt		memcpy (&buf[1], &bl, sizeof (bl));
277290067Sbapt	}
278290067Sbapt
279290067Sbapt	func->ucl_emitter_append_len (buf, blen, func->ud);
280290067Sbapt	func->ucl_emitter_append_len (s, len, func->ud);
281290067Sbapt}
282290067Sbapt
283290067Sbaptvoid
284290067Sbaptucl_emitter_print_null_msgpack (struct ucl_emitter_context *ctx)
285290067Sbapt{
286290067Sbapt	const struct ucl_emitter_functions *func = ctx->func;
287290067Sbapt	const unsigned char nil = 0xc0;
288290067Sbapt
289290067Sbapt	func->ucl_emitter_append_character (nil, 1, func->ud);
290290067Sbapt}
291290067Sbapt
292290067Sbaptvoid
293290067Sbaptucl_emitter_print_key_msgpack (bool print_key, struct ucl_emitter_context *ctx,
294290067Sbapt		const ucl_object_t *obj)
295290067Sbapt{
296290067Sbapt	if (print_key) {
297290067Sbapt		ucl_emitter_print_string_msgpack (ctx, obj->key, obj->keylen);
298290067Sbapt	}
299290067Sbapt}
300290067Sbapt
301290067Sbaptvoid
302290067Sbaptucl_emitter_print_array_msgpack (struct ucl_emitter_context *ctx, size_t len)
303290067Sbapt{
304290067Sbapt	const struct ucl_emitter_functions *func = ctx->func;
305290067Sbapt	const unsigned char fix_mask = 0x90, l16_ch = 0xdc, l32_ch = 0xdd;
306290067Sbapt	unsigned char buf[5];
307290067Sbapt	unsigned blen;
308290067Sbapt
309290067Sbapt	if (len <= 0xF) {
310290067Sbapt		blen = 1;
311290067Sbapt		buf[0] = (len | fix_mask) & 0xff;
312290067Sbapt	}
313290067Sbapt	else if (len <= 0xffff) {
314290067Sbapt		uint16_t bl = TO_BE16 (len);
315290067Sbapt
316290067Sbapt		blen = 3;
317290067Sbapt		buf[0] = l16_ch;
318290067Sbapt		memcpy (&buf[1], &bl, sizeof (bl));
319290067Sbapt	}
320290067Sbapt	else {
321290067Sbapt		uint32_t bl = TO_BE32 (len);
322290067Sbapt
323290067Sbapt		blen = 5;
324290067Sbapt		buf[0] = l32_ch;
325290067Sbapt		memcpy (&buf[1], &bl, sizeof (bl));
326290067Sbapt	}
327290067Sbapt
328290067Sbapt	func->ucl_emitter_append_len (buf, blen, func->ud);
329290067Sbapt}
330290067Sbapt
331290067Sbaptvoid
332290067Sbaptucl_emitter_print_object_msgpack (struct ucl_emitter_context *ctx, size_t len)
333290067Sbapt{
334290067Sbapt	const struct ucl_emitter_functions *func = ctx->func;
335290067Sbapt	const unsigned char fix_mask = 0x80, l16_ch = 0xde, l32_ch = 0xdf;
336290067Sbapt	unsigned char buf[5];
337290067Sbapt	unsigned blen;
338290067Sbapt
339290067Sbapt	if (len <= 0xF) {
340290067Sbapt		blen = 1;
341290067Sbapt		buf[0] = (len | fix_mask) & 0xff;
342290067Sbapt	}
343290067Sbapt	else if (len <= 0xffff) {
344290067Sbapt		uint16_t bl = TO_BE16 (len);
345290067Sbapt
346290067Sbapt		blen = 3;
347290067Sbapt		buf[0] = l16_ch;
348290067Sbapt		memcpy (&buf[1], &bl, sizeof (bl));
349290067Sbapt	}
350290067Sbapt	else {
351290067Sbapt		uint32_t bl = TO_BE32 (len);
352290067Sbapt
353290067Sbapt		blen = 5;
354290067Sbapt		buf[0] = l32_ch;
355290067Sbapt		memcpy (&buf[1], &bl, sizeof (bl));
356290067Sbapt	}
357290067Sbapt
358290067Sbapt	func->ucl_emitter_append_len (buf, blen, func->ud);
359290067Sbapt}
360290067Sbapt
361290067Sbapt
362290067Sbaptenum ucl_msgpack_format {
363290067Sbapt	msgpack_positive_fixint = 0,
364290067Sbapt	msgpack_fixmap,
365290067Sbapt	msgpack_fixarray,
366290067Sbapt	msgpack_fixstr,
367290067Sbapt	msgpack_nil,
368290067Sbapt	msgpack_false,
369290067Sbapt	msgpack_true,
370290067Sbapt	msgpack_bin8,
371290067Sbapt	msgpack_bin16,
372290067Sbapt	msgpack_bin32,
373290067Sbapt	msgpack_ext8,
374290067Sbapt	msgpack_ext16,
375290067Sbapt	msgpack_ext32,
376290067Sbapt	msgpack_float32,
377290067Sbapt	msgpack_float64,
378290067Sbapt	msgpack_uint8,
379290067Sbapt	msgpack_uint16,
380290067Sbapt	msgpack_uint32,
381290067Sbapt	msgpack_uint64,
382290067Sbapt	msgpack_int8,
383290067Sbapt	msgpack_int16,
384290067Sbapt	msgpack_int32,
385290067Sbapt	msgpack_int64,
386290067Sbapt	msgpack_fixext1,
387290067Sbapt	msgpack_fixext2,
388290067Sbapt	msgpack_fixext4,
389290067Sbapt	msgpack_fixext8,
390290067Sbapt	msgpack_fixext16,
391290067Sbapt	msgpack_str8,
392290067Sbapt	msgpack_str16,
393290067Sbapt	msgpack_str32,
394290067Sbapt	msgpack_array16,
395290067Sbapt	msgpack_array32,
396290067Sbapt	msgpack_map16,
397290067Sbapt	msgpack_map32,
398290067Sbapt	msgpack_negative_fixint,
399290067Sbapt	msgpack_invalid
400290067Sbapt};
401290067Sbapt
402290067Sbapttypedef ssize_t (*ucl_msgpack_parse_function)(struct ucl_parser *parser,
403290067Sbapt		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
404290067Sbapt		const unsigned char *pos, size_t remain);
405290067Sbapt
406290067Sbaptstatic ssize_t ucl_msgpack_parse_map (struct ucl_parser *parser,
407290067Sbapt		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
408290067Sbapt		const unsigned char *pos, size_t remain);
409290067Sbaptstatic ssize_t ucl_msgpack_parse_array (struct ucl_parser *parser,
410290067Sbapt		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
411290067Sbapt		const unsigned char *pos, size_t remain);
412290067Sbaptstatic ssize_t ucl_msgpack_parse_string (struct ucl_parser *parser,
413290067Sbapt		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
414290067Sbapt		const unsigned char *pos, size_t remain);
415290067Sbaptstatic ssize_t ucl_msgpack_parse_int (struct ucl_parser *parser,
416290067Sbapt		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
417290067Sbapt		const unsigned char *pos, size_t remain);
418290067Sbaptstatic ssize_t ucl_msgpack_parse_float (struct ucl_parser *parser,
419290067Sbapt		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
420290067Sbapt		const unsigned char *pos, size_t remain);
421290067Sbaptstatic ssize_t ucl_msgpack_parse_bool (struct ucl_parser *parser,
422290067Sbapt		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
423290067Sbapt		const unsigned char *pos, size_t remain);
424290067Sbaptstatic ssize_t ucl_msgpack_parse_null (struct ucl_parser *parser,
425290067Sbapt		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
426290067Sbapt		const unsigned char *pos, size_t remain);
427290067Sbaptstatic ssize_t ucl_msgpack_parse_ignore (struct ucl_parser *parser,
428290067Sbapt		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
429290067Sbapt		const unsigned char *pos, size_t remain);
430290067Sbapt
431290067Sbapt#define MSGPACK_FLAG_FIXED (1 << 0)
432290067Sbapt#define MSGPACK_FLAG_CONTAINER (1 << 1)
433290067Sbapt#define MSGPACK_FLAG_TYPEVALUE (1 << 2)
434290067Sbapt#define MSGPACK_FLAG_EXT (1 << 3)
435290067Sbapt#define MSGPACK_FLAG_ASSOC (1 << 4)
436290067Sbapt#define MSGPACK_FLAG_KEY (1 << 5)
437290067Sbapt#define MSGPACK_CONTAINER_BIT (1ULL << 62)
438290067Sbapt
439290067Sbapt/*
440290067Sbapt * Search tree packed in array
441290067Sbapt */
442290067Sbaptstruct ucl_msgpack_parser {
443290067Sbapt	uint8_t prefix;						/* Prefix byte					*/
444290067Sbapt	uint8_t prefixlen;					/* Length of prefix in bits		*/
445290067Sbapt	uint8_t fmt;						/* The desired format 			*/
446290067Sbapt	uint8_t len;						/* Length of the object
447290067Sbapt										  (either length bytes
448290067Sbapt										  or length of value in case
449290067Sbapt										  of fixed objects 				*/
450290067Sbapt	uint8_t flags;						/* Flags of the specified type	*/
451290067Sbapt	ucl_msgpack_parse_function func;	/* Parser function				*/
452290067Sbapt} parsers[] = {
453290067Sbapt	{
454290067Sbapt			0xa0,
455290067Sbapt			3,
456290067Sbapt			msgpack_fixstr,
457290067Sbapt			0,
458290067Sbapt			MSGPACK_FLAG_FIXED|MSGPACK_FLAG_KEY,
459290067Sbapt			ucl_msgpack_parse_string
460290067Sbapt	},
461290067Sbapt	{
462290067Sbapt			0x0,
463290067Sbapt			1,
464290067Sbapt			msgpack_positive_fixint,
465290067Sbapt			0,
466290067Sbapt			MSGPACK_FLAG_FIXED|MSGPACK_FLAG_TYPEVALUE,
467290067Sbapt			ucl_msgpack_parse_int
468290067Sbapt	},
469290067Sbapt	{
470290067Sbapt			0xe0,
471290067Sbapt			3,
472290067Sbapt			msgpack_negative_fixint,
473290067Sbapt			0,
474290067Sbapt			MSGPACK_FLAG_FIXED|MSGPACK_FLAG_TYPEVALUE,
475290067Sbapt			ucl_msgpack_parse_int
476290067Sbapt	},
477290067Sbapt	{
478290067Sbapt			0x80,
479290067Sbapt			4,
480290067Sbapt			msgpack_fixmap,
481290067Sbapt			0,
482290067Sbapt			MSGPACK_FLAG_FIXED|MSGPACK_FLAG_CONTAINER|MSGPACK_FLAG_ASSOC,
483290067Sbapt			ucl_msgpack_parse_map
484290067Sbapt	},
485290067Sbapt	{
486290067Sbapt			0x90,
487290067Sbapt			4,
488290067Sbapt			msgpack_fixarray,
489290067Sbapt			0,
490290067Sbapt			MSGPACK_FLAG_FIXED|MSGPACK_FLAG_CONTAINER,
491290067Sbapt			ucl_msgpack_parse_array
492290067Sbapt	},
493290067Sbapt	{
494290067Sbapt			0xd9,
495290067Sbapt			8,
496290067Sbapt			msgpack_str8,
497290067Sbapt			1,
498290067Sbapt			MSGPACK_FLAG_KEY,
499290067Sbapt			ucl_msgpack_parse_string
500290067Sbapt	},
501290067Sbapt	{
502290067Sbapt			0xc4,
503290067Sbapt			8,
504290067Sbapt			msgpack_bin8,
505290067Sbapt			1,
506290067Sbapt			MSGPACK_FLAG_KEY,
507290067Sbapt			ucl_msgpack_parse_string
508290067Sbapt	},
509290067Sbapt	{
510290067Sbapt			0xcf,
511290067Sbapt			8,
512290067Sbapt			msgpack_uint64,
513290067Sbapt			8,
514290067Sbapt			MSGPACK_FLAG_FIXED,
515290067Sbapt			ucl_msgpack_parse_int
516290067Sbapt	},
517290067Sbapt	{
518290067Sbapt			0xd3,
519290067Sbapt			8,
520290067Sbapt			msgpack_int64,
521290067Sbapt			8,
522290067Sbapt			MSGPACK_FLAG_FIXED,
523290067Sbapt			ucl_msgpack_parse_int
524290067Sbapt	},
525290067Sbapt	{
526290067Sbapt			0xce,
527290067Sbapt			8,
528290067Sbapt			msgpack_uint32,
529290067Sbapt			4,
530290067Sbapt			MSGPACK_FLAG_FIXED,
531290067Sbapt			ucl_msgpack_parse_int
532290067Sbapt	},
533290067Sbapt	{
534290067Sbapt			0xd2,
535290067Sbapt			8,
536290067Sbapt			msgpack_int32,
537290067Sbapt			4,
538290067Sbapt			MSGPACK_FLAG_FIXED,
539290067Sbapt			ucl_msgpack_parse_int
540290067Sbapt	},
541290067Sbapt	{
542290067Sbapt			0xcb,
543290067Sbapt			8,
544290067Sbapt			msgpack_float64,
545290067Sbapt			8,
546290067Sbapt			MSGPACK_FLAG_FIXED,
547290067Sbapt			ucl_msgpack_parse_float
548290067Sbapt	},
549290067Sbapt	{
550290067Sbapt			0xca,
551290067Sbapt			8,
552290067Sbapt			msgpack_float32,
553290067Sbapt			4,
554290067Sbapt			MSGPACK_FLAG_FIXED,
555290067Sbapt			ucl_msgpack_parse_float
556290067Sbapt	},
557290067Sbapt	{
558290067Sbapt			0xc2,
559290067Sbapt			8,
560290067Sbapt			msgpack_false,
561290067Sbapt			1,
562290067Sbapt			MSGPACK_FLAG_FIXED | MSGPACK_FLAG_TYPEVALUE,
563290067Sbapt			ucl_msgpack_parse_bool
564290067Sbapt	},
565290067Sbapt	{
566290067Sbapt			0xc3,
567290067Sbapt			8,
568290067Sbapt			msgpack_true,
569290067Sbapt			1,
570290067Sbapt			MSGPACK_FLAG_FIXED | MSGPACK_FLAG_TYPEVALUE,
571290067Sbapt			ucl_msgpack_parse_bool
572290067Sbapt	},
573290067Sbapt	{
574290067Sbapt			0xcc,
575290067Sbapt			8,
576290067Sbapt			msgpack_uint8,
577290067Sbapt			1,
578290067Sbapt			MSGPACK_FLAG_FIXED,
579290067Sbapt			ucl_msgpack_parse_int
580290067Sbapt	},
581290067Sbapt	{
582290067Sbapt			0xcd,
583290067Sbapt			8,
584290067Sbapt			msgpack_uint16,
585290067Sbapt			2,
586290067Sbapt			MSGPACK_FLAG_FIXED,
587290067Sbapt			ucl_msgpack_parse_int
588290067Sbapt	},
589290067Sbapt	{
590290067Sbapt			0xd0,
591290067Sbapt			8,
592290067Sbapt			msgpack_int8,
593290067Sbapt			1,
594290067Sbapt			MSGPACK_FLAG_FIXED,
595290067Sbapt			ucl_msgpack_parse_int
596290067Sbapt	},
597290067Sbapt	{
598290067Sbapt			0xd1,
599290067Sbapt			8,
600290067Sbapt			msgpack_int16,
601290067Sbapt			2,
602290067Sbapt			MSGPACK_FLAG_FIXED,
603290067Sbapt			ucl_msgpack_parse_int
604290067Sbapt	},
605290067Sbapt	{
606290067Sbapt			0xc0,
607290067Sbapt			8,
608290067Sbapt			msgpack_nil,
609290067Sbapt			0,
610290067Sbapt			MSGPACK_FLAG_FIXED | MSGPACK_FLAG_TYPEVALUE,
611290067Sbapt			ucl_msgpack_parse_null
612290067Sbapt	},
613290067Sbapt	{
614290067Sbapt			0xda,
615290067Sbapt			8,
616290067Sbapt			msgpack_str16,
617290067Sbapt			2,
618290067Sbapt			MSGPACK_FLAG_KEY,
619290067Sbapt			ucl_msgpack_parse_string
620290067Sbapt	},
621290067Sbapt	{
622290067Sbapt			0xdb,
623290067Sbapt			8,
624290067Sbapt			msgpack_str32,
625290067Sbapt			4,
626290067Sbapt			MSGPACK_FLAG_KEY,
627290067Sbapt			ucl_msgpack_parse_string
628290067Sbapt	},
629290067Sbapt	{
630290067Sbapt			0xc5,
631290067Sbapt			8,
632290067Sbapt			msgpack_bin16,
633290067Sbapt			2,
634290067Sbapt			MSGPACK_FLAG_KEY,
635290067Sbapt			ucl_msgpack_parse_string
636290067Sbapt	},
637290067Sbapt	{
638290067Sbapt			0xc6,
639290067Sbapt			8,
640290067Sbapt			msgpack_bin32,
641290067Sbapt			4,
642290067Sbapt			MSGPACK_FLAG_KEY,
643290067Sbapt			ucl_msgpack_parse_string
644290067Sbapt	},
645290067Sbapt	{
646290067Sbapt			0xdc,
647290067Sbapt			8,
648290067Sbapt			msgpack_array16,
649290067Sbapt			2,
650290067Sbapt			MSGPACK_FLAG_CONTAINER,
651290067Sbapt			ucl_msgpack_parse_array
652290067Sbapt	},
653290067Sbapt	{
654290067Sbapt			0xdd,
655290067Sbapt			8,
656290067Sbapt			msgpack_array32,
657290067Sbapt			4,
658290067Sbapt			MSGPACK_FLAG_CONTAINER,
659290067Sbapt			ucl_msgpack_parse_array
660290067Sbapt	},
661290067Sbapt	{
662290067Sbapt			0xde,
663290067Sbapt			8,
664290067Sbapt			msgpack_map16,
665290067Sbapt			2,
666290067Sbapt			MSGPACK_FLAG_CONTAINER|MSGPACK_FLAG_ASSOC,
667290067Sbapt			ucl_msgpack_parse_map
668290067Sbapt	},
669290067Sbapt	{
670290067Sbapt			0xdf,
671290067Sbapt			8,
672290067Sbapt			msgpack_map32,
673290067Sbapt			4,
674290067Sbapt			MSGPACK_FLAG_CONTAINER|MSGPACK_FLAG_ASSOC,
675290067Sbapt			ucl_msgpack_parse_map
676290067Sbapt	},
677290067Sbapt	{
678290067Sbapt			0xc7,
679290067Sbapt			8,
680290067Sbapt			msgpack_ext8,
681290067Sbapt			1,
682290067Sbapt			MSGPACK_FLAG_EXT,
683290067Sbapt			ucl_msgpack_parse_ignore
684290067Sbapt	},
685290067Sbapt	{
686290067Sbapt			0xc8,
687290067Sbapt			8,
688290067Sbapt			msgpack_ext16,
689290067Sbapt			2,
690290067Sbapt			MSGPACK_FLAG_EXT,
691290067Sbapt			ucl_msgpack_parse_ignore
692290067Sbapt	},
693290067Sbapt	{
694290067Sbapt			0xc9,
695290067Sbapt			8,
696290067Sbapt			msgpack_ext32,
697290067Sbapt			4,
698290067Sbapt			MSGPACK_FLAG_EXT,
699290067Sbapt			ucl_msgpack_parse_ignore
700290067Sbapt	},
701290067Sbapt	{
702290067Sbapt			0xd4,
703290067Sbapt			8,
704290067Sbapt			msgpack_fixext1,
705290067Sbapt			1,
706290067Sbapt			MSGPACK_FLAG_FIXED | MSGPACK_FLAG_EXT,
707290067Sbapt			ucl_msgpack_parse_ignore
708290067Sbapt	},
709290067Sbapt	{
710290067Sbapt			0xd5,
711290067Sbapt			8,
712290067Sbapt			msgpack_fixext2,
713290067Sbapt			2,
714290067Sbapt			MSGPACK_FLAG_FIXED | MSGPACK_FLAG_EXT,
715290067Sbapt			ucl_msgpack_parse_ignore
716290067Sbapt	},
717290067Sbapt	{
718290067Sbapt			0xd6,
719290067Sbapt			8,
720290067Sbapt			msgpack_fixext4,
721290067Sbapt			4,
722290067Sbapt			MSGPACK_FLAG_FIXED | MSGPACK_FLAG_EXT,
723290067Sbapt			ucl_msgpack_parse_ignore
724290067Sbapt	},
725290067Sbapt	{
726290067Sbapt			0xd7,
727290067Sbapt			8,
728290067Sbapt			msgpack_fixext8,
729290067Sbapt			8,
730290067Sbapt			MSGPACK_FLAG_FIXED | MSGPACK_FLAG_EXT,
731290067Sbapt			ucl_msgpack_parse_ignore
732290067Sbapt	},
733290067Sbapt	{
734290067Sbapt			0xd8,
735290067Sbapt			8,
736290067Sbapt			msgpack_fixext16,
737290067Sbapt			16,
738290067Sbapt			MSGPACK_FLAG_FIXED | MSGPACK_FLAG_EXT,
739290067Sbapt			ucl_msgpack_parse_ignore
740290067Sbapt	}
741290067Sbapt};
742290067Sbapt
743290067Sbapt#undef MSGPACK_DEBUG_PARSER
744290067Sbapt
745290067Sbaptstatic inline struct ucl_msgpack_parser *
746290067Sbaptucl_msgpack_get_parser_from_type (unsigned char t)
747290067Sbapt{
748290067Sbapt	unsigned int i, shift, mask;
749290067Sbapt
750290067Sbapt	for (i = 0; i < sizeof (parsers) / sizeof (parsers[0]); i ++) {
751290067Sbapt		shift = CHAR_BIT - parsers[i].prefixlen;
752290067Sbapt		mask = parsers[i].prefix >> shift;
753290067Sbapt
754298166Sbapt		if (mask == (((unsigned int)t) >> shift)) {
755290067Sbapt			return &parsers[i];
756290067Sbapt		}
757290067Sbapt	}
758290067Sbapt
759290067Sbapt	return NULL;
760290067Sbapt}
761290067Sbapt
762290067Sbaptstatic inline struct ucl_stack *
763290067Sbaptucl_msgpack_get_container (struct ucl_parser *parser,
764290067Sbapt		struct ucl_msgpack_parser *obj_parser, uint64_t len)
765290067Sbapt{
766290067Sbapt	struct ucl_stack *stack;
767290067Sbapt
768290067Sbapt	assert (obj_parser != NULL);
769290067Sbapt
770290067Sbapt	if (obj_parser->flags & MSGPACK_FLAG_CONTAINER) {
771290067Sbapt		assert ((len & MSGPACK_CONTAINER_BIT) == 0);
772290067Sbapt		/*
773290067Sbapt		 * Insert new container to the stack
774290067Sbapt		 */
775290067Sbapt		if (parser->stack == NULL) {
776290067Sbapt			parser->stack = calloc (1, sizeof (struct ucl_stack));
777290067Sbapt
778290067Sbapt			if (parser->stack == NULL) {
779290067Sbapt				ucl_create_err (&parser->err, "no memory");
780290067Sbapt				return NULL;
781290067Sbapt			}
782290067Sbapt		}
783290067Sbapt		else {
784290067Sbapt			stack = calloc (1, sizeof (struct ucl_stack));
785290067Sbapt
786290067Sbapt			if (stack == NULL) {
787290067Sbapt				ucl_create_err (&parser->err, "no memory");
788290067Sbapt				return NULL;
789290067Sbapt			}
790290067Sbapt
791290067Sbapt			stack->next = parser->stack;
792290067Sbapt			parser->stack = stack;
793290067Sbapt		}
794290067Sbapt
795290067Sbapt		parser->stack->level = len | MSGPACK_CONTAINER_BIT;
796290067Sbapt
797290067Sbapt#ifdef MSGPACK_DEBUG_PARSER
798290067Sbapt		stack = parser->stack;
799290067Sbapt		while (stack) {
800290067Sbapt			fprintf(stderr, "+");
801290067Sbapt			stack = stack->next;
802290067Sbapt		}
803290067Sbapt
804290067Sbapt		fprintf(stderr, "%s -> %d\n", obj_parser->flags & MSGPACK_FLAG_ASSOC ? "object" : "array", (int)len);
805290067Sbapt#endif
806290067Sbapt	}
807290067Sbapt	else {
808290067Sbapt		/*
809290067Sbapt		 * Get the current stack top
810290067Sbapt		 */
811290067Sbapt		if (parser->stack) {
812290067Sbapt			return parser->stack;
813290067Sbapt		}
814290067Sbapt		else {
815290067Sbapt			ucl_create_err (&parser->err, "bad top level object for msgpack");
816290067Sbapt			return NULL;
817290067Sbapt		}
818290067Sbapt	}
819290067Sbapt
820290067Sbapt	return parser->stack;
821290067Sbapt}
822290067Sbapt
823290067Sbaptstatic bool
824290067Sbaptucl_msgpack_is_container_finished (struct ucl_stack *container)
825290067Sbapt{
826290067Sbapt	uint64_t level;
827290067Sbapt
828290067Sbapt	assert (container != NULL);
829290067Sbapt
830290067Sbapt	if (container->level & MSGPACK_CONTAINER_BIT) {
831290067Sbapt		level = container->level & ~MSGPACK_CONTAINER_BIT;
832290067Sbapt
833290067Sbapt		if (level == 0) {
834290067Sbapt			return true;
835290067Sbapt		}
836290067Sbapt	}
837290067Sbapt
838290067Sbapt	return false;
839290067Sbapt}
840290067Sbapt
841290067Sbaptstatic bool
842290067Sbaptucl_msgpack_insert_object (struct ucl_parser *parser,
843290067Sbapt		const unsigned char *key,
844290067Sbapt		size_t keylen, ucl_object_t *obj)
845290067Sbapt{
846290067Sbapt	uint64_t level;
847290067Sbapt	struct ucl_stack *container;
848290067Sbapt
849290067Sbapt	container = parser->stack;
850290067Sbapt	assert (container != NULL);
851290067Sbapt	assert (container->level > 0);
852290067Sbapt	assert (obj != NULL);
853290067Sbapt	assert (container->obj != NULL);
854290067Sbapt
855290067Sbapt	if (container->obj->type == UCL_ARRAY) {
856290067Sbapt		ucl_array_append (container->obj, obj);
857290067Sbapt	}
858290067Sbapt	else if (container->obj->type == UCL_OBJECT) {
859290067Sbapt		if (key == NULL || keylen == 0) {
860290067Sbapt			ucl_create_err (&parser->err, "cannot insert object with no key");
861290067Sbapt			return false;
862290067Sbapt		}
863290067Sbapt
864290067Sbapt		obj->key = key;
865290067Sbapt		obj->keylen = keylen;
866290067Sbapt
867290067Sbapt		if (!(parser->flags & UCL_PARSER_ZEROCOPY)) {
868290067Sbapt			ucl_copy_key_trash (obj);
869290067Sbapt		}
870290067Sbapt
871290067Sbapt		ucl_parser_process_object_element (parser, obj);
872290067Sbapt	}
873290067Sbapt	else {
874290067Sbapt		ucl_create_err (&parser->err, "bad container type");
875290067Sbapt		return false;
876290067Sbapt	}
877290067Sbapt
878290067Sbapt	if (container->level & MSGPACK_CONTAINER_BIT) {
879290067Sbapt		level = container->level & ~MSGPACK_CONTAINER_BIT;
880290067Sbapt		container->level = (level - 1) | MSGPACK_CONTAINER_BIT;
881290067Sbapt	}
882290067Sbapt
883290067Sbapt	return true;
884290067Sbapt}
885290067Sbapt
886290067Sbaptstatic struct ucl_stack *
887290067Sbaptucl_msgpack_get_next_container (struct ucl_parser *parser)
888290067Sbapt{
889290067Sbapt	struct ucl_stack *cur = NULL;
890290067Sbapt	uint64_t level;
891290067Sbapt
892290067Sbapt	cur = parser->stack;
893290067Sbapt
894290067Sbapt	if (cur == NULL) {
895290067Sbapt		return NULL;
896290067Sbapt	}
897290067Sbapt
898290067Sbapt	if (cur->level & MSGPACK_CONTAINER_BIT) {
899290067Sbapt		level = cur->level & ~MSGPACK_CONTAINER_BIT;
900290067Sbapt
901290067Sbapt		if (level == 0) {
902290067Sbapt			/* We need to switch to the previous container */
903290067Sbapt			parser->stack = cur->next;
904290067Sbapt			parser->cur_obj = cur->obj;
905290067Sbapt			free (cur);
906290067Sbapt
907290067Sbapt#ifdef MSGPACK_DEBUG_PARSER
908290067Sbapt			cur = parser->stack;
909290067Sbapt			while (cur) {
910290067Sbapt				fprintf(stderr, "-");
911290067Sbapt				cur = cur->next;
912290067Sbapt			}
913290067Sbapt			fprintf(stderr, "-%s -> %d\n", parser->cur_obj->type == UCL_OBJECT ? "object" : "array", (int)parser->cur_obj->len);
914290067Sbapt#endif
915290067Sbapt
916290067Sbapt			return ucl_msgpack_get_next_container (parser);
917290067Sbapt		}
918290067Sbapt	}
919290067Sbapt
920290067Sbapt	/*
921290067Sbapt	 * For UCL containers we don't know length, so we just insert the whole
922290067Sbapt	 * message pack blob into the top level container
923290067Sbapt	 */
924290067Sbapt
925290067Sbapt	assert (cur->obj != NULL);
926290067Sbapt
927290067Sbapt	return cur;
928290067Sbapt}
929290067Sbapt
930290067Sbapt#define CONSUME_RET do {									\
931290067Sbapt	if (ret != -1) {										\
932290067Sbapt		p += ret;											\
933290067Sbapt		remain -= ret;										\
934290067Sbapt		obj_parser = NULL;									\
935290067Sbapt		assert (remain >= 0);								\
936290067Sbapt	}														\
937290067Sbapt	else {													\
938290067Sbapt		ucl_create_err (&parser->err,						\
939290067Sbapt			"cannot parse type %d of len %u",				\
940290067Sbapt			(int)obj_parser->fmt,							\
941290067Sbapt			(unsigned)len);									\
942290067Sbapt		return false;										\
943290067Sbapt	}														\
944290067Sbapt} while(0)
945290067Sbapt
946290067Sbapt#define GET_NEXT_STATE do {									\
947290067Sbapt	container = ucl_msgpack_get_next_container (parser);	\
948290067Sbapt	if (container == NULL) {								\
949290067Sbapt		ucl_create_err (&parser->err,						\
950290067Sbapt					"empty container");						\
951290067Sbapt		return false;										\
952290067Sbapt	}														\
953290067Sbapt	next_state = container->obj->type == UCL_OBJECT ? 		\
954290067Sbapt					read_assoc_key : read_array_value;		\
955290067Sbapt} while(0)
956290067Sbapt
957290067Sbaptstatic bool
958290067Sbaptucl_msgpack_consume (struct ucl_parser *parser)
959290067Sbapt{
960290067Sbapt	const unsigned char *p, *end, *key = NULL;
961290067Sbapt	struct ucl_stack *container;
962290067Sbapt	enum e_msgpack_parser_state {
963290067Sbapt		read_type,
964290067Sbapt		start_assoc,
965290067Sbapt		start_array,
966290067Sbapt		read_assoc_key,
967290067Sbapt		read_assoc_value,
968290067Sbapt		finish_assoc_value,
969290067Sbapt		read_array_value,
970290067Sbapt		finish_array_value,
971290067Sbapt		error_state
972290067Sbapt	} state = read_type, next_state = error_state;
973298166Sbapt	struct ucl_msgpack_parser *obj_parser = NULL;
974298166Sbapt	uint64_t len = 0;
975290067Sbapt	ssize_t ret, remain, keylen = 0;
976290067Sbapt#ifdef MSGPACK_DEBUG_PARSER
977290067Sbapt	uint64_t i;
978290067Sbapt	enum e_msgpack_parser_state hist[256];
979290067Sbapt#endif
980290067Sbapt
981290067Sbapt	p = parser->chunks->begin;
982290067Sbapt	remain = parser->chunks->remain;
983290067Sbapt	end = p + remain;
984290067Sbapt
985290067Sbapt
986290067Sbapt	while (p < end) {
987290067Sbapt#ifdef MSGPACK_DEBUG_PARSER
988290067Sbapt		hist[i++ % 256] = state;
989290067Sbapt#endif
990290067Sbapt		switch (state) {
991290067Sbapt		case read_type:
992290067Sbapt			obj_parser = ucl_msgpack_get_parser_from_type (*p);
993290067Sbapt
994290067Sbapt			if (obj_parser == NULL) {
995290067Sbapt				ucl_create_err (&parser->err, "unknown msgpack format: %x",
996290067Sbapt						(unsigned int)*p);
997290067Sbapt
998290067Sbapt				return false;
999290067Sbapt			}
1000290067Sbapt			/* Now check length sanity */
1001290067Sbapt			if (obj_parser->flags & MSGPACK_FLAG_FIXED) {
1002290067Sbapt				if (obj_parser->len == 0) {
1003290067Sbapt					/* We have an embedded size */
1004290067Sbapt					len = *p & ~obj_parser->prefix;
1005290067Sbapt				}
1006290067Sbapt				else {
1007290067Sbapt					if (remain < obj_parser->len) {
1008290067Sbapt						ucl_create_err (&parser->err, "not enough data remain to "
1009290067Sbapt								"read object's length: %u remain, %u needed",
1010290067Sbapt								(unsigned)remain, obj_parser->len);
1011290067Sbapt
1012290067Sbapt						return false;
1013290067Sbapt					}
1014290067Sbapt
1015290067Sbapt					len = obj_parser->len;
1016290067Sbapt				}
1017290067Sbapt
1018290067Sbapt				if (!(obj_parser->flags & MSGPACK_FLAG_TYPEVALUE)) {
1019290067Sbapt					/* We must pass value as the second byte */
1020290067Sbapt					if (remain > 0) {
1021290067Sbapt						p ++;
1022290067Sbapt						remain --;
1023290067Sbapt					}
1024290067Sbapt				}
1025290067Sbapt				else {
1026290067Sbapt					/* Len is irrelevant now */
1027290067Sbapt					len = 0;
1028290067Sbapt				}
1029290067Sbapt			}
1030290067Sbapt			else {
1031290067Sbapt				/* Length is not embedded */
1032290067Sbapt				if (remain < obj_parser->len) {
1033290067Sbapt					ucl_create_err (&parser->err, "not enough data remain to "
1034290067Sbapt							"read object's length: %u remain, %u needed",
1035290067Sbapt							(unsigned)remain, obj_parser->len);
1036290067Sbapt
1037290067Sbapt					return false;
1038290067Sbapt				}
1039290067Sbapt
1040290067Sbapt				p ++;
1041290067Sbapt				remain --;
1042290067Sbapt
1043290067Sbapt				switch (obj_parser->len) {
1044290067Sbapt				case 1:
1045290067Sbapt					len = *p;
1046290067Sbapt					break;
1047290067Sbapt				case 2:
1048290067Sbapt					len = FROM_BE16 (*(uint16_t *)p);
1049290067Sbapt					break;
1050290067Sbapt				case 4:
1051290067Sbapt					len = FROM_BE32 (*(uint32_t *)p);
1052290067Sbapt					break;
1053290067Sbapt				case 8:
1054290067Sbapt					len = FROM_BE64 (*(uint64_t *)p);
1055290067Sbapt					break;
1056290067Sbapt				default:
1057290067Sbapt					assert (0);
1058290067Sbapt					break;
1059290067Sbapt				}
1060290067Sbapt
1061290067Sbapt				p += obj_parser->len;
1062290067Sbapt				remain -= obj_parser->len;
1063290067Sbapt			}
1064290067Sbapt
1065290067Sbapt			if (obj_parser->flags & MSGPACK_FLAG_ASSOC) {
1066290067Sbapt				/* We have just read the new associative map */
1067290067Sbapt				state = start_assoc;
1068290067Sbapt			}
1069290067Sbapt			else if (obj_parser->flags & MSGPACK_FLAG_CONTAINER){
1070290067Sbapt				state = start_array;
1071290067Sbapt			}
1072290067Sbapt			else {
1073290067Sbapt				state = next_state;
1074290067Sbapt			}
1075290067Sbapt
1076290067Sbapt			break;
1077290067Sbapt		case start_assoc:
1078290067Sbapt			parser->cur_obj = ucl_object_new_full (UCL_OBJECT,
1079290067Sbapt					parser->chunks->priority);
1080290067Sbapt			/* Insert to the previous level container */
1081290067Sbapt			if (parser->stack && !ucl_msgpack_insert_object (parser,
1082290067Sbapt					key, keylen, parser->cur_obj)) {
1083290067Sbapt				return false;
1084290067Sbapt			}
1085290067Sbapt			/* Get new container */
1086290067Sbapt			container = ucl_msgpack_get_container (parser, obj_parser, len);
1087290067Sbapt
1088290067Sbapt			if (container == NULL) {
1089290067Sbapt				return false;
1090290067Sbapt			}
1091290067Sbapt
1092290067Sbapt			ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1093290067Sbapt					p, remain);
1094290067Sbapt			CONSUME_RET;
1095290067Sbapt			key = NULL;
1096290067Sbapt			keylen = 0;
1097290067Sbapt
1098290067Sbapt			if (len > 0) {
1099290067Sbapt				state = read_type;
1100290067Sbapt				next_state = read_assoc_key;
1101290067Sbapt			}
1102290067Sbapt			else {
1103290067Sbapt				/* Empty object */
1104290067Sbapt				state = finish_assoc_value;
1105290067Sbapt			}
1106290067Sbapt			break;
1107290067Sbapt
1108290067Sbapt		case start_array:
1109290067Sbapt			parser->cur_obj = ucl_object_new_full (UCL_ARRAY,
1110290067Sbapt					parser->chunks->priority);
1111290067Sbapt			/* Insert to the previous level container */
1112290067Sbapt			if (parser->stack && !ucl_msgpack_insert_object (parser,
1113290067Sbapt					key, keylen, parser->cur_obj)) {
1114290067Sbapt				return false;
1115290067Sbapt			}
1116290067Sbapt			/* Get new container */
1117290067Sbapt			container = ucl_msgpack_get_container (parser, obj_parser, len);
1118290067Sbapt
1119290067Sbapt			if (container == NULL) {
1120290067Sbapt				return false;
1121290067Sbapt			}
1122290067Sbapt
1123290067Sbapt			ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1124290067Sbapt								p, remain);
1125290067Sbapt			CONSUME_RET;
1126290067Sbapt
1127290067Sbapt			if (len > 0) {
1128290067Sbapt				state = read_type;
1129290067Sbapt				next_state = read_array_value;
1130290067Sbapt			}
1131290067Sbapt			else {
1132290067Sbapt				/* Empty array */
1133290067Sbapt				state = finish_array_value;
1134290067Sbapt			}
1135290067Sbapt			break;
1136290067Sbapt
1137290067Sbapt		case read_array_value:
1138290067Sbapt			/*
1139290067Sbapt			 * p is now at the value start, len now contains length read and
1140290067Sbapt			 * obj_parser contains the corresponding specific parser
1141290067Sbapt			 */
1142290067Sbapt			container = parser->stack;
1143290067Sbapt
1144290067Sbapt			if (container == NULL) {
1145290067Sbapt				return false;
1146290067Sbapt			}
1147290067Sbapt
1148290067Sbapt			ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1149290067Sbapt					p, remain);
1150290067Sbapt			CONSUME_RET;
1151290067Sbapt
1152290067Sbapt
1153290067Sbapt			/* Insert value to the container and check if we have finished array */
1154290067Sbapt			if (!ucl_msgpack_insert_object (parser, NULL, 0,
1155290067Sbapt					parser->cur_obj)) {
1156290067Sbapt				return false;
1157290067Sbapt			}
1158290067Sbapt
1159290067Sbapt			if (ucl_msgpack_is_container_finished (container)) {
1160290067Sbapt				state = finish_array_value;
1161290067Sbapt			}
1162290067Sbapt			else {
1163290067Sbapt				/* Read more elements */
1164290067Sbapt				state = read_type;
1165290067Sbapt				next_state = read_array_value;
1166290067Sbapt			}
1167290067Sbapt
1168290067Sbapt			break;
1169290067Sbapt
1170290067Sbapt		case read_assoc_key:
1171290067Sbapt			/*
1172290067Sbapt			 * Keys must have string type for ucl msgpack
1173290067Sbapt			 */
1174290067Sbapt			if (!(obj_parser->flags & MSGPACK_FLAG_KEY)) {
1175290067Sbapt				ucl_create_err (&parser->err, "bad type for key: %u, expected "
1176290067Sbapt						"string", (unsigned)obj_parser->fmt);
1177290067Sbapt
1178290067Sbapt				return false;
1179290067Sbapt			}
1180290067Sbapt
1181290067Sbapt			key = p;
1182290067Sbapt			keylen = len;
1183290067Sbapt
1184290067Sbapt			if (keylen > remain || keylen == 0) {
1185290067Sbapt				ucl_create_err (&parser->err, "too long or empty key");
1186290067Sbapt				return false;
1187290067Sbapt			}
1188290067Sbapt
1189290067Sbapt			p += len;
1190290067Sbapt			remain -= len;
1191290067Sbapt
1192290067Sbapt			state = read_type;
1193290067Sbapt			next_state = read_assoc_value;
1194290067Sbapt			break;
1195290067Sbapt
1196290067Sbapt		case read_assoc_value:
1197290067Sbapt			/*
1198290067Sbapt			 * p is now at the value start, len now contains length read and
1199290067Sbapt			 * obj_parser contains the corresponding specific parser
1200290067Sbapt			 */
1201290067Sbapt			container = parser->stack;
1202290067Sbapt
1203290067Sbapt			if (container == NULL) {
1204290067Sbapt				return false;
1205290067Sbapt			}
1206290067Sbapt
1207290067Sbapt			ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1208290067Sbapt					p, remain);
1209290067Sbapt			CONSUME_RET;
1210290067Sbapt
1211290067Sbapt			assert (key != NULL && keylen > 0);
1212290067Sbapt
1213290067Sbapt			if (!ucl_msgpack_insert_object (parser, key, keylen,
1214290067Sbapt					parser->cur_obj)) {
1215290067Sbapt				return false;
1216290067Sbapt			}
1217290067Sbapt
1218290067Sbapt			key = NULL;
1219290067Sbapt			keylen = 0;
1220290067Sbapt
1221290067Sbapt			if (ucl_msgpack_is_container_finished (container)) {
1222290067Sbapt				state = finish_assoc_value;
1223290067Sbapt			}
1224290067Sbapt			else {
1225290067Sbapt				/* Read more elements */
1226290067Sbapt				state = read_type;
1227290067Sbapt				next_state = read_assoc_key;
1228290067Sbapt			}
1229290067Sbapt			break;
1230290067Sbapt
1231290067Sbapt		case finish_array_value:
1232290067Sbapt		case finish_assoc_value:
1233290067Sbapt			GET_NEXT_STATE;
1234290067Sbapt			state = read_type;
1235290067Sbapt			break;
1236290067Sbapt
1237290067Sbapt		case error_state:
1238290067Sbapt			ucl_create_err (&parser->err, "invalid state machine state");
1239290067Sbapt
1240290067Sbapt			return false;
1241290067Sbapt		}
1242290067Sbapt	}
1243290067Sbapt
1244290067Sbapt	/* Check the finishing state */
1245290067Sbapt	switch (state) {
1246290067Sbapt	case start_array:
1247290067Sbapt	case start_assoc:
1248290067Sbapt		/* Empty container at the end */
1249290067Sbapt		if (len != 0) {
1250290067Sbapt			ucl_create_err (&parser->err, "invalid non-empty container at the end");
1251290067Sbapt
1252290067Sbapt			return false;
1253290067Sbapt		}
1254290067Sbapt
1255290067Sbapt		parser->cur_obj = ucl_object_new_full (
1256290067Sbapt				state == start_array ? UCL_ARRAY : UCL_OBJECT,
1257290067Sbapt				parser->chunks->priority);
1258290067Sbapt		/* Insert to the previous level container */
1259290067Sbapt		if (!ucl_msgpack_insert_object (parser,
1260290067Sbapt				key, keylen, parser->cur_obj)) {
1261290067Sbapt			return false;
1262290067Sbapt		}
1263290067Sbapt		/* Get new container */
1264290067Sbapt		container = ucl_msgpack_get_container (parser, obj_parser, len);
1265290067Sbapt
1266290067Sbapt		if (container == NULL) {
1267290067Sbapt			return false;
1268290067Sbapt		}
1269290067Sbapt
1270290067Sbapt		ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1271290067Sbapt				p, remain);
1272290067Sbapt		break;
1273290067Sbapt
1274290067Sbapt	case read_array_value:
1275290067Sbapt	case read_assoc_value:
1276290067Sbapt		if (len != 0) {
1277290067Sbapt			ucl_create_err (&parser->err, "unfinished value at the end");
1278290067Sbapt
1279290067Sbapt			return false;
1280290067Sbapt		}
1281290067Sbapt
1282290067Sbapt		container = parser->stack;
1283290067Sbapt
1284290067Sbapt		if (container == NULL) {
1285290067Sbapt			return false;
1286290067Sbapt		}
1287290067Sbapt
1288290067Sbapt		ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1289290067Sbapt				p, remain);
1290290067Sbapt		CONSUME_RET;
1291290067Sbapt
1292290067Sbapt
1293290067Sbapt		/* Insert value to the container and check if we have finished array */
1294290067Sbapt		if (!ucl_msgpack_insert_object (parser, NULL, 0,
1295290067Sbapt				parser->cur_obj)) {
1296290067Sbapt			return false;
1297290067Sbapt		}
1298290067Sbapt		break;
1299290067Sbapt	case finish_array_value:
1300290067Sbapt	case finish_assoc_value:
1301290067Sbapt	case read_type:
1302290067Sbapt		/* Valid finishing state */
1303290067Sbapt		break;
1304290067Sbapt	default:
1305290067Sbapt		/* Invalid finishing state */
1306290067Sbapt		ucl_create_err (&parser->err, "invalid state machine finishing state: %d",
1307290067Sbapt				state);
1308290067Sbapt
1309290067Sbapt		return false;
1310290067Sbapt	}
1311290067Sbapt
1312290067Sbapt	/* Rewind to the top level container */
1313290067Sbapt	ucl_msgpack_get_next_container (parser);
1314290067Sbapt	assert (parser->stack == NULL ||
1315290067Sbapt			(parser->stack->level & MSGPACK_CONTAINER_BIT) == 0);
1316290067Sbapt
1317290067Sbapt	return true;
1318290067Sbapt}
1319290067Sbapt
1320290067Sbaptbool
1321290067Sbaptucl_parse_msgpack (struct ucl_parser *parser)
1322290067Sbapt{
1323290067Sbapt	ucl_object_t *container = NULL;
1324290067Sbapt	const unsigned char *p;
1325290067Sbapt	bool ret;
1326290067Sbapt
1327290067Sbapt	assert (parser != NULL);
1328290067Sbapt	assert (parser->chunks != NULL);
1329290067Sbapt	assert (parser->chunks->begin != NULL);
1330290067Sbapt	assert (parser->chunks->remain != 0);
1331290067Sbapt
1332290067Sbapt	p = parser->chunks->begin;
1333290067Sbapt
1334290067Sbapt	if (parser->stack) {
1335290067Sbapt		container = parser->stack->obj;
1336290067Sbapt	}
1337290067Sbapt
1338290067Sbapt	/*
1339290067Sbapt	 * When we start parsing message pack chunk, we must ensure that we
1340290067Sbapt	 * have either a valid container or the top object inside message pack is
1341290067Sbapt	 * of container type
1342290067Sbapt	 */
1343290067Sbapt	if (container == NULL) {
1344290067Sbapt		if ((*p & 0x80) != 0x80 && !(*p >= 0xdc && *p <= 0xdf)) {
1345290067Sbapt			ucl_create_err (&parser->err, "bad top level object for msgpack");
1346290067Sbapt			return false;
1347290067Sbapt		}
1348290067Sbapt	}
1349290067Sbapt
1350290067Sbapt	ret = ucl_msgpack_consume (parser);
1351290067Sbapt
1352290067Sbapt	if (ret && parser->top_obj == NULL) {
1353290067Sbapt		parser->top_obj = parser->cur_obj;
1354290067Sbapt	}
1355290067Sbapt
1356290067Sbapt	return ret;
1357290067Sbapt}
1358290067Sbapt
1359290067Sbaptstatic ssize_t
1360290067Sbaptucl_msgpack_parse_map (struct ucl_parser *parser,
1361290067Sbapt		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1362290067Sbapt		const unsigned char *pos, size_t remain)
1363290067Sbapt{
1364290067Sbapt	container->obj = parser->cur_obj;
1365290067Sbapt
1366290067Sbapt	return 0;
1367290067Sbapt}
1368290067Sbapt
1369290067Sbaptstatic ssize_t
1370290067Sbaptucl_msgpack_parse_array (struct ucl_parser *parser,
1371290067Sbapt		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1372290067Sbapt		const unsigned char *pos, size_t remain)
1373290067Sbapt{
1374290067Sbapt	container->obj = parser->cur_obj;
1375290067Sbapt
1376290067Sbapt	return 0;
1377290067Sbapt}
1378290067Sbapt
1379290067Sbaptstatic ssize_t
1380290067Sbaptucl_msgpack_parse_string (struct ucl_parser *parser,
1381290067Sbapt		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1382290067Sbapt		const unsigned char *pos, size_t remain)
1383290067Sbapt{
1384290067Sbapt	ucl_object_t *obj;
1385290067Sbapt
1386290067Sbapt	if (len > remain) {
1387290067Sbapt		return -1;
1388290067Sbapt	}
1389290067Sbapt
1390290067Sbapt	obj = ucl_object_new_full (UCL_STRING, parser->chunks->priority);
1391290067Sbapt	obj->value.sv = pos;
1392290067Sbapt	obj->len = len;
1393290067Sbapt
1394290067Sbapt	if (fmt >= msgpack_bin8 && fmt <= msgpack_bin32) {
1395290067Sbapt		obj->flags |= UCL_OBJECT_BINARY;
1396290067Sbapt	}
1397290067Sbapt
1398290067Sbapt	if (!(parser->flags & UCL_PARSER_ZEROCOPY)) {
1399290067Sbapt		if (obj->flags & UCL_OBJECT_BINARY) {
1400290067Sbapt			obj->trash_stack[UCL_TRASH_VALUE] = malloc (len);
1401290067Sbapt
1402290067Sbapt			if (obj->trash_stack[UCL_TRASH_VALUE] != NULL) {
1403290067Sbapt				memcpy (obj->trash_stack[UCL_TRASH_VALUE], pos, len);
1404290067Sbapt			}
1405290067Sbapt		}
1406290067Sbapt		else {
1407290067Sbapt			ucl_copy_value_trash (obj);
1408290067Sbapt		}
1409290067Sbapt	}
1410290067Sbapt
1411290067Sbapt	parser->cur_obj = obj;
1412290067Sbapt
1413290067Sbapt	return len;
1414290067Sbapt}
1415290067Sbapt
1416290067Sbaptstatic ssize_t
1417290067Sbaptucl_msgpack_parse_int (struct ucl_parser *parser,
1418290067Sbapt		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1419290067Sbapt		const unsigned char *pos, size_t remain)
1420290067Sbapt{
1421290067Sbapt	ucl_object_t *obj;
1422298166Sbapt	int8_t iv8;
1423298166Sbapt	int16_t iv16;
1424298166Sbapt	int32_t iv32;
1425298166Sbapt	int64_t iv64;
1426301339Sbapt	uint16_t uiv16;
1427301339Sbapt	uint32_t uiv32;
1428301339Sbapt	uint64_t uiv64;
1429290067Sbapt
1430301339Sbapt
1431290067Sbapt	if (len > remain) {
1432290067Sbapt		return -1;
1433290067Sbapt	}
1434290067Sbapt
1435290067Sbapt	obj = ucl_object_new_full (UCL_INT, parser->chunks->priority);
1436290067Sbapt
1437290067Sbapt	switch (fmt) {
1438290067Sbapt	case msgpack_positive_fixint:
1439290067Sbapt		obj->value.iv = (*pos & 0x7f);
1440290067Sbapt		len = 1;
1441290067Sbapt		break;
1442290067Sbapt	case msgpack_negative_fixint:
1443290067Sbapt		obj->value.iv = - (*pos & 0x1f);
1444290067Sbapt		len = 1;
1445290067Sbapt		break;
1446290067Sbapt	case msgpack_uint8:
1447290067Sbapt		obj->value.iv = (unsigned char)*pos;
1448290067Sbapt		len = 1;
1449290067Sbapt		break;
1450290067Sbapt	case msgpack_int8:
1451298166Sbapt		memcpy (&iv8, pos, sizeof (iv8));
1452298166Sbapt		obj->value.iv = iv8;
1453290067Sbapt		len = 1;
1454290067Sbapt		break;
1455290067Sbapt	case msgpack_int16:
1456298166Sbapt		memcpy (&iv16, pos, sizeof (iv16));
1457298166Sbapt		iv16 = FROM_BE16 (iv16);
1458298166Sbapt		obj->value.iv = iv16;
1459290067Sbapt		len = 2;
1460290067Sbapt		break;
1461290067Sbapt	case msgpack_uint16:
1462301339Sbapt		memcpy (&uiv16, pos, sizeof (uiv16));
1463301339Sbapt		uiv16 = FROM_BE16 (uiv16);
1464301339Sbapt		obj->value.iv = uiv16;
1465290067Sbapt		len = 2;
1466290067Sbapt		break;
1467290067Sbapt	case msgpack_int32:
1468298166Sbapt		memcpy (&iv32, pos, sizeof (iv32));
1469298166Sbapt		iv32 = FROM_BE32 (iv32);
1470298166Sbapt		obj->value.iv = iv32;
1471290067Sbapt		len = 4;
1472290067Sbapt		break;
1473290067Sbapt	case msgpack_uint32:
1474301339Sbapt		memcpy(&uiv32, pos, sizeof(uiv32));
1475301339Sbapt		uiv32 = FROM_BE32(uiv32);
1476301339Sbapt		obj->value.iv = uiv32;
1477290067Sbapt		len = 4;
1478290067Sbapt		break;
1479290067Sbapt	case msgpack_int64:
1480298166Sbapt		memcpy (&iv64, pos, sizeof (iv64));
1481298166Sbapt		iv64 = FROM_BE64 (iv64);
1482298166Sbapt		obj->value.iv = iv64;
1483290067Sbapt		len = 8;
1484290067Sbapt		break;
1485290067Sbapt	case msgpack_uint64:
1486301339Sbapt		memcpy(&uiv64, pos, sizeof(uiv64));
1487301339Sbapt		uiv64 = FROM_BE64(uiv64);
1488301339Sbapt		obj->value.iv = uiv64;
1489290067Sbapt		len = 8;
1490290067Sbapt		break;
1491290067Sbapt	default:
1492290067Sbapt		assert (0);
1493290067Sbapt		break;
1494290067Sbapt	}
1495290067Sbapt
1496290067Sbapt	parser->cur_obj = obj;
1497290067Sbapt
1498290067Sbapt	return len;
1499290067Sbapt}
1500290067Sbapt
1501290067Sbaptstatic ssize_t
1502290067Sbaptucl_msgpack_parse_float (struct ucl_parser *parser,
1503290067Sbapt		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1504290067Sbapt		const unsigned char *pos, size_t remain)
1505290067Sbapt{
1506290067Sbapt	ucl_object_t *obj;
1507290067Sbapt	union {
1508290067Sbapt		uint32_t i;
1509290067Sbapt		float f;
1510290067Sbapt	} d;
1511301339Sbapt	uint64_t uiv64;
1512290067Sbapt
1513290067Sbapt	if (len > remain) {
1514290067Sbapt		return -1;
1515290067Sbapt	}
1516290067Sbapt
1517290067Sbapt	obj = ucl_object_new_full (UCL_FLOAT, parser->chunks->priority);
1518290067Sbapt
1519290067Sbapt	switch (fmt) {
1520290067Sbapt	case msgpack_float32:
1521301339Sbapt		memcpy(&d.i, pos, sizeof(d.i));
1522301339Sbapt		d.i = FROM_BE32(d.i);
1523290067Sbapt		/* XXX: can be slow */
1524290067Sbapt		obj->value.dv = d.f;
1525290067Sbapt		len = 4;
1526290067Sbapt		break;
1527290067Sbapt	case msgpack_float64:
1528301339Sbapt		memcpy(&uiv64, pos, sizeof(uiv64));
1529301339Sbapt		uiv64 = FROM_BE64(uiv64);
1530301339Sbapt		obj->value.iv = uiv64;
1531290067Sbapt		len = 8;
1532290067Sbapt		break;
1533290067Sbapt	default:
1534290067Sbapt		assert (0);
1535290067Sbapt		break;
1536290067Sbapt	}
1537290067Sbapt
1538290067Sbapt	parser->cur_obj = obj;
1539290067Sbapt
1540290067Sbapt	return len;
1541290067Sbapt}
1542290067Sbapt
1543290067Sbaptstatic ssize_t
1544290067Sbaptucl_msgpack_parse_bool (struct ucl_parser *parser,
1545290067Sbapt		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1546290067Sbapt		const unsigned char *pos, size_t remain)
1547290067Sbapt{
1548290067Sbapt	ucl_object_t *obj;
1549290067Sbapt
1550290067Sbapt	if (len > remain) {
1551290067Sbapt		return -1;
1552290067Sbapt	}
1553290067Sbapt
1554290067Sbapt	obj = ucl_object_new_full (UCL_BOOLEAN, parser->chunks->priority);
1555290067Sbapt
1556290067Sbapt	switch (fmt) {
1557290067Sbapt	case msgpack_true:
1558290067Sbapt		obj->value.iv = true;
1559290067Sbapt		break;
1560290067Sbapt	case msgpack_false:
1561290067Sbapt		obj->value.iv = false;
1562290067Sbapt		break;
1563290067Sbapt	default:
1564290067Sbapt		assert (0);
1565290067Sbapt		break;
1566290067Sbapt	}
1567290067Sbapt
1568290067Sbapt	parser->cur_obj = obj;
1569290067Sbapt
1570290067Sbapt	return 1;
1571290067Sbapt}
1572290067Sbapt
1573290067Sbaptstatic ssize_t
1574290067Sbaptucl_msgpack_parse_null (struct ucl_parser *parser,
1575290067Sbapt		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1576290067Sbapt		const unsigned char *pos, size_t remain)
1577290067Sbapt{
1578290067Sbapt	ucl_object_t *obj;
1579290067Sbapt
1580290067Sbapt	if (len > remain) {
1581290067Sbapt		return -1;
1582290067Sbapt	}
1583290067Sbapt
1584290067Sbapt	obj = ucl_object_new_full (UCL_NULL, parser->chunks->priority);
1585290067Sbapt	parser->cur_obj = obj;
1586290067Sbapt
1587290067Sbapt	return 1;
1588290067Sbapt}
1589290067Sbapt
1590290067Sbaptstatic ssize_t
1591290067Sbaptucl_msgpack_parse_ignore (struct ucl_parser *parser,
1592290067Sbapt		struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1593290067Sbapt		const unsigned char *pos, size_t remain)
1594290067Sbapt{
1595290067Sbapt	if (len > remain) {
1596290067Sbapt		return -1;
1597290067Sbapt	}
1598290067Sbapt
1599290067Sbapt	switch (fmt) {
1600290067Sbapt	case msgpack_fixext1:
1601290067Sbapt		len = 2;
1602290067Sbapt		break;
1603290067Sbapt	case msgpack_fixext2:
1604290067Sbapt		len = 3;
1605290067Sbapt		break;
1606290067Sbapt	case msgpack_fixext4:
1607290067Sbapt		len = 5;
1608290067Sbapt		break;
1609290067Sbapt	case msgpack_fixext8:
1610290067Sbapt		len = 9;
1611290067Sbapt		break;
1612290067Sbapt	case msgpack_fixext16:
1613290067Sbapt		len = 17;
1614290067Sbapt		break;
1615290067Sbapt	case msgpack_ext8:
1616290067Sbapt	case msgpack_ext16:
1617290067Sbapt	case msgpack_ext32:
1618290067Sbapt		len = len + 1;
1619290067Sbapt		break;
1620290067Sbapt	default:
1621290067Sbapt		ucl_create_err (&parser->err, "bad type: %x", (unsigned)fmt);
1622290067Sbapt		return -1;
1623290067Sbapt	}
1624290067Sbapt
1625290067Sbapt	return len;
1626290067Sbapt}
1627