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