]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/libucl/src/ucl_msgpack.c
dts: Import DTS for arm64
[FreeBSD/FreeBSD.git] / contrib / libucl / src / ucl_msgpack.c
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
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
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
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
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
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
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
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
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
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 #define MSGPACK_CONTAINER_BIT (1ULL << 62)
438
439 /*
440  * Search tree packed in array
441  */
442 struct ucl_msgpack_parser {
443         uint8_t prefix;                                         /* Prefix byte                                  */
444         uint8_t prefixlen;                                      /* Length of prefix in bits             */
445         uint8_t fmt;                                            /* The desired format                   */
446         uint8_t len;                                            /* Length of the object
447                                                                                   (either length bytes
448                                                                                   or length of value in case
449                                                                                   of fixed objects                              */
450         uint8_t flags;                                          /* Flags of the specified type  */
451         ucl_msgpack_parse_function func;        /* Parser function                              */
452 } parsers[] = {
453         {
454                         0xa0,
455                         3,
456                         msgpack_fixstr,
457                         0,
458                         MSGPACK_FLAG_FIXED|MSGPACK_FLAG_KEY,
459                         ucl_msgpack_parse_string
460         },
461         {
462                         0x0,
463                         1,
464                         msgpack_positive_fixint,
465                         0,
466                         MSGPACK_FLAG_FIXED|MSGPACK_FLAG_TYPEVALUE,
467                         ucl_msgpack_parse_int
468         },
469         {
470                         0xe0,
471                         3,
472                         msgpack_negative_fixint,
473                         0,
474                         MSGPACK_FLAG_FIXED|MSGPACK_FLAG_TYPEVALUE,
475                         ucl_msgpack_parse_int
476         },
477         {
478                         0x80,
479                         4,
480                         msgpack_fixmap,
481                         0,
482                         MSGPACK_FLAG_FIXED|MSGPACK_FLAG_CONTAINER|MSGPACK_FLAG_ASSOC,
483                         ucl_msgpack_parse_map
484         },
485         {
486                         0x90,
487                         4,
488                         msgpack_fixarray,
489                         0,
490                         MSGPACK_FLAG_FIXED|MSGPACK_FLAG_CONTAINER,
491                         ucl_msgpack_parse_array
492         },
493         {
494                         0xd9,
495                         8,
496                         msgpack_str8,
497                         1,
498                         MSGPACK_FLAG_KEY,
499                         ucl_msgpack_parse_string
500         },
501         {
502                         0xc4,
503                         8,
504                         msgpack_bin8,
505                         1,
506                         MSGPACK_FLAG_KEY,
507                         ucl_msgpack_parse_string
508         },
509         {
510                         0xcf,
511                         8,
512                         msgpack_uint64,
513                         8,
514                         MSGPACK_FLAG_FIXED,
515                         ucl_msgpack_parse_int
516         },
517         {
518                         0xd3,
519                         8,
520                         msgpack_int64,
521                         8,
522                         MSGPACK_FLAG_FIXED,
523                         ucl_msgpack_parse_int
524         },
525         {
526                         0xce,
527                         8,
528                         msgpack_uint32,
529                         4,
530                         MSGPACK_FLAG_FIXED,
531                         ucl_msgpack_parse_int
532         },
533         {
534                         0xd2,
535                         8,
536                         msgpack_int32,
537                         4,
538                         MSGPACK_FLAG_FIXED,
539                         ucl_msgpack_parse_int
540         },
541         {
542                         0xcb,
543                         8,
544                         msgpack_float64,
545                         8,
546                         MSGPACK_FLAG_FIXED,
547                         ucl_msgpack_parse_float
548         },
549         {
550                         0xca,
551                         8,
552                         msgpack_float32,
553                         4,
554                         MSGPACK_FLAG_FIXED,
555                         ucl_msgpack_parse_float
556         },
557         {
558                         0xc2,
559                         8,
560                         msgpack_false,
561                         1,
562                         MSGPACK_FLAG_FIXED | MSGPACK_FLAG_TYPEVALUE,
563                         ucl_msgpack_parse_bool
564         },
565         {
566                         0xc3,
567                         8,
568                         msgpack_true,
569                         1,
570                         MSGPACK_FLAG_FIXED | MSGPACK_FLAG_TYPEVALUE,
571                         ucl_msgpack_parse_bool
572         },
573         {
574                         0xcc,
575                         8,
576                         msgpack_uint8,
577                         1,
578                         MSGPACK_FLAG_FIXED,
579                         ucl_msgpack_parse_int
580         },
581         {
582                         0xcd,
583                         8,
584                         msgpack_uint16,
585                         2,
586                         MSGPACK_FLAG_FIXED,
587                         ucl_msgpack_parse_int
588         },
589         {
590                         0xd0,
591                         8,
592                         msgpack_int8,
593                         1,
594                         MSGPACK_FLAG_FIXED,
595                         ucl_msgpack_parse_int
596         },
597         {
598                         0xd1,
599                         8,
600                         msgpack_int16,
601                         2,
602                         MSGPACK_FLAG_FIXED,
603                         ucl_msgpack_parse_int
604         },
605         {
606                         0xc0,
607                         8,
608                         msgpack_nil,
609                         0,
610                         MSGPACK_FLAG_FIXED | MSGPACK_FLAG_TYPEVALUE,
611                         ucl_msgpack_parse_null
612         },
613         {
614                         0xda,
615                         8,
616                         msgpack_str16,
617                         2,
618                         MSGPACK_FLAG_KEY,
619                         ucl_msgpack_parse_string
620         },
621         {
622                         0xdb,
623                         8,
624                         msgpack_str32,
625                         4,
626                         MSGPACK_FLAG_KEY,
627                         ucl_msgpack_parse_string
628         },
629         {
630                         0xc5,
631                         8,
632                         msgpack_bin16,
633                         2,
634                         MSGPACK_FLAG_KEY,
635                         ucl_msgpack_parse_string
636         },
637         {
638                         0xc6,
639                         8,
640                         msgpack_bin32,
641                         4,
642                         MSGPACK_FLAG_KEY,
643                         ucl_msgpack_parse_string
644         },
645         {
646                         0xdc,
647                         8,
648                         msgpack_array16,
649                         2,
650                         MSGPACK_FLAG_CONTAINER,
651                         ucl_msgpack_parse_array
652         },
653         {
654                         0xdd,
655                         8,
656                         msgpack_array32,
657                         4,
658                         MSGPACK_FLAG_CONTAINER,
659                         ucl_msgpack_parse_array
660         },
661         {
662                         0xde,
663                         8,
664                         msgpack_map16,
665                         2,
666                         MSGPACK_FLAG_CONTAINER|MSGPACK_FLAG_ASSOC,
667                         ucl_msgpack_parse_map
668         },
669         {
670                         0xdf,
671                         8,
672                         msgpack_map32,
673                         4,
674                         MSGPACK_FLAG_CONTAINER|MSGPACK_FLAG_ASSOC,
675                         ucl_msgpack_parse_map
676         },
677         {
678                         0xc7,
679                         8,
680                         msgpack_ext8,
681                         1,
682                         MSGPACK_FLAG_EXT,
683                         ucl_msgpack_parse_ignore
684         },
685         {
686                         0xc8,
687                         8,
688                         msgpack_ext16,
689                         2,
690                         MSGPACK_FLAG_EXT,
691                         ucl_msgpack_parse_ignore
692         },
693         {
694                         0xc9,
695                         8,
696                         msgpack_ext32,
697                         4,
698                         MSGPACK_FLAG_EXT,
699                         ucl_msgpack_parse_ignore
700         },
701         {
702                         0xd4,
703                         8,
704                         msgpack_fixext1,
705                         1,
706                         MSGPACK_FLAG_FIXED | MSGPACK_FLAG_EXT,
707                         ucl_msgpack_parse_ignore
708         },
709         {
710                         0xd5,
711                         8,
712                         msgpack_fixext2,
713                         2,
714                         MSGPACK_FLAG_FIXED | MSGPACK_FLAG_EXT,
715                         ucl_msgpack_parse_ignore
716         },
717         {
718                         0xd6,
719                         8,
720                         msgpack_fixext4,
721                         4,
722                         MSGPACK_FLAG_FIXED | MSGPACK_FLAG_EXT,
723                         ucl_msgpack_parse_ignore
724         },
725         {
726                         0xd7,
727                         8,
728                         msgpack_fixext8,
729                         8,
730                         MSGPACK_FLAG_FIXED | MSGPACK_FLAG_EXT,
731                         ucl_msgpack_parse_ignore
732         },
733         {
734                         0xd8,
735                         8,
736                         msgpack_fixext16,
737                         16,
738                         MSGPACK_FLAG_FIXED | MSGPACK_FLAG_EXT,
739                         ucl_msgpack_parse_ignore
740         }
741 };
742
743 #undef MSGPACK_DEBUG_PARSER
744
745 static inline struct ucl_msgpack_parser *
746 ucl_msgpack_get_parser_from_type (unsigned char t)
747 {
748         unsigned int i, shift, mask;
749
750         for (i = 0; i < sizeof (parsers) / sizeof (parsers[0]); i ++) {
751                 shift = CHAR_BIT - parsers[i].prefixlen;
752                 mask = parsers[i].prefix >> shift;
753
754                 if (mask == (((unsigned int)t) >> shift)) {
755                         return &parsers[i];
756                 }
757         }
758
759         return NULL;
760 }
761
762 static inline struct ucl_stack *
763 ucl_msgpack_get_container (struct ucl_parser *parser,
764                 struct ucl_msgpack_parser *obj_parser, uint64_t len)
765 {
766         struct ucl_stack *stack;
767
768         assert (obj_parser != NULL);
769
770         if (obj_parser->flags & MSGPACK_FLAG_CONTAINER) {
771                 assert ((len & MSGPACK_CONTAINER_BIT) == 0);
772                 /*
773                  * Insert new container to the stack
774                  */
775                 if (parser->stack == NULL) {
776                         parser->stack = calloc (1, sizeof (struct ucl_stack));
777
778                         if (parser->stack == NULL) {
779                                 ucl_create_err (&parser->err, "no memory");
780                                 return NULL;
781                         }
782                 }
783                 else {
784                         stack = calloc (1, sizeof (struct ucl_stack));
785
786                         if (stack == NULL) {
787                                 ucl_create_err (&parser->err, "no memory");
788                                 return NULL;
789                         }
790
791                         stack->next = parser->stack;
792                         parser->stack = stack;
793                 }
794
795                 parser->stack->level = len | MSGPACK_CONTAINER_BIT;
796
797 #ifdef MSGPACK_DEBUG_PARSER
798                 stack = parser->stack;
799                 while (stack) {
800                         fprintf(stderr, "+");
801                         stack = stack->next;
802                 }
803
804                 fprintf(stderr, "%s -> %d\n", obj_parser->flags & MSGPACK_FLAG_ASSOC ? "object" : "array", (int)len);
805 #endif
806         }
807         else {
808                 /*
809                  * Get the current stack top
810                  */
811                 if (parser->stack) {
812                         return parser->stack;
813                 }
814                 else {
815                         ucl_create_err (&parser->err, "bad top level object for msgpack");
816                         return NULL;
817                 }
818         }
819
820         return parser->stack;
821 }
822
823 static bool
824 ucl_msgpack_is_container_finished (struct ucl_stack *container)
825 {
826         uint64_t level;
827
828         assert (container != NULL);
829
830         if (container->level & MSGPACK_CONTAINER_BIT) {
831                 level = container->level & ~MSGPACK_CONTAINER_BIT;
832
833                 if (level == 0) {
834                         return true;
835                 }
836         }
837
838         return false;
839 }
840
841 static bool
842 ucl_msgpack_insert_object (struct ucl_parser *parser,
843                 const unsigned char *key,
844                 size_t keylen, ucl_object_t *obj)
845 {
846         uint64_t level;
847         struct ucl_stack *container;
848
849         container = parser->stack;
850         assert (container != NULL);
851         assert (container->level > 0);
852         assert (obj != NULL);
853         assert (container->obj != NULL);
854
855         if (container->obj->type == UCL_ARRAY) {
856                 ucl_array_append (container->obj, obj);
857         }
858         else if (container->obj->type == UCL_OBJECT) {
859                 if (key == NULL || keylen == 0) {
860                         ucl_create_err (&parser->err, "cannot insert object with no key");
861                         return false;
862                 }
863
864                 obj->key = key;
865                 obj->keylen = keylen;
866
867                 if (!(parser->flags & UCL_PARSER_ZEROCOPY)) {
868                         ucl_copy_key_trash (obj);
869                 }
870
871                 ucl_parser_process_object_element (parser, obj);
872         }
873         else {
874                 ucl_create_err (&parser->err, "bad container type");
875                 return false;
876         }
877
878         if (container->level & MSGPACK_CONTAINER_BIT) {
879                 level = container->level & ~MSGPACK_CONTAINER_BIT;
880                 container->level = (level - 1) | MSGPACK_CONTAINER_BIT;
881         }
882
883         return true;
884 }
885
886 static struct ucl_stack *
887 ucl_msgpack_get_next_container (struct ucl_parser *parser)
888 {
889         struct ucl_stack *cur = NULL;
890         uint64_t level;
891
892         cur = parser->stack;
893
894         if (cur == NULL) {
895                 return NULL;
896         }
897
898         if (cur->level & MSGPACK_CONTAINER_BIT) {
899                 level = cur->level & ~MSGPACK_CONTAINER_BIT;
900
901                 if (level == 0) {
902                         /* We need to switch to the previous container */
903                         parser->stack = cur->next;
904                         parser->cur_obj = cur->obj;
905                         free (cur);
906
907 #ifdef MSGPACK_DEBUG_PARSER
908                         cur = parser->stack;
909                         while (cur) {
910                                 fprintf(stderr, "-");
911                                 cur = cur->next;
912                         }
913                         fprintf(stderr, "-%s -> %d\n", parser->cur_obj->type == UCL_OBJECT ? "object" : "array", (int)parser->cur_obj->len);
914 #endif
915
916                         return ucl_msgpack_get_next_container (parser);
917                 }
918         }
919
920         /*
921          * For UCL containers we don't know length, so we just insert the whole
922          * message pack blob into the top level container
923          */
924
925         assert (cur->obj != NULL);
926
927         return cur;
928 }
929
930 #define CONSUME_RET do {                                                                        \
931         if (ret != -1) {                                                                                \
932                 p += ret;                                                                                       \
933                 remain -= ret;                                                                          \
934                 obj_parser = NULL;                                                                      \
935                 assert (remain >= 0);                                                           \
936         }                                                                                                               \
937         else {                                                                                                  \
938                 ucl_create_err (&parser->err,                                           \
939                         "cannot parse type %d of len %u",                               \
940                         (int)obj_parser->fmt,                                                   \
941                         (unsigned)len);                                                                 \
942                 return false;                                                                           \
943         }                                                                                                               \
944 } while(0)
945
946 #define GET_NEXT_STATE do {                                                                     \
947         container = ucl_msgpack_get_next_container (parser);    \
948         if (container == NULL) {                                                                \
949                 ucl_create_err (&parser->err,                                           \
950                                         "empty container");                                             \
951                 return false;                                                                           \
952         }                                                                                                               \
953         next_state = container->obj->type == UCL_OBJECT ?               \
954                                         read_assoc_key : read_array_value;              \
955 } while(0)
956
957 static bool
958 ucl_msgpack_consume (struct ucl_parser *parser)
959 {
960         const unsigned char *p, *end, *key = NULL;
961         struct ucl_stack *container;
962         enum e_msgpack_parser_state {
963                 read_type,
964                 start_assoc,
965                 start_array,
966                 read_assoc_key,
967                 read_assoc_value,
968                 finish_assoc_value,
969                 read_array_value,
970                 finish_array_value,
971                 error_state
972         } state = read_type, next_state = error_state;
973         struct ucl_msgpack_parser *obj_parser = NULL;
974         uint64_t len = 0;
975         ssize_t ret, remain, keylen = 0;
976 #ifdef MSGPACK_DEBUG_PARSER
977         uint64_t i;
978         enum e_msgpack_parser_state hist[256];
979 #endif
980
981         p = parser->chunks->begin;
982         remain = parser->chunks->remain;
983         end = p + remain;
984
985
986         while (p < end) {
987 #ifdef MSGPACK_DEBUG_PARSER
988                 hist[i++ % 256] = state;
989 #endif
990                 switch (state) {
991                 case read_type:
992                         obj_parser = ucl_msgpack_get_parser_from_type (*p);
993
994                         if (obj_parser == NULL) {
995                                 ucl_create_err (&parser->err, "unknown msgpack format: %x",
996                                                 (unsigned int)*p);
997
998                                 return false;
999                         }
1000                         /* Now check length sanity */
1001                         if (obj_parser->flags & MSGPACK_FLAG_FIXED) {
1002                                 if (obj_parser->len == 0) {
1003                                         /* We have an embedded size */
1004                                         len = *p & ~obj_parser->prefix;
1005                                 }
1006                                 else {
1007                                         if (remain < obj_parser->len) {
1008                                                 ucl_create_err (&parser->err, "not enough data remain to "
1009                                                                 "read object's length: %u remain, %u needed",
1010                                                                 (unsigned)remain, obj_parser->len);
1011
1012                                                 return false;
1013                                         }
1014
1015                                         len = obj_parser->len;
1016                                 }
1017
1018                                 if (!(obj_parser->flags & MSGPACK_FLAG_TYPEVALUE)) {
1019                                         /* We must pass value as the second byte */
1020                                         if (remain > 0) {
1021                                                 p ++;
1022                                                 remain --;
1023                                         }
1024                                 }
1025                                 else {
1026                                         /* Len is irrelevant now */
1027                                         len = 0;
1028                                 }
1029                         }
1030                         else {
1031                                 /* Length is not embedded */
1032                                 if (remain < obj_parser->len) {
1033                                         ucl_create_err (&parser->err, "not enough data remain to "
1034                                                         "read object's length: %u remain, %u needed",
1035                                                         (unsigned)remain, obj_parser->len);
1036
1037                                         return false;
1038                                 }
1039
1040                                 p ++;
1041                                 remain --;
1042
1043                                 switch (obj_parser->len) {
1044                                 case 1:
1045                                         len = *p;
1046                                         break;
1047                                 case 2:
1048                                         len = FROM_BE16 (*(uint16_t *)p);
1049                                         break;
1050                                 case 4:
1051                                         len = FROM_BE32 (*(uint32_t *)p);
1052                                         break;
1053                                 case 8:
1054                                         len = FROM_BE64 (*(uint64_t *)p);
1055                                         break;
1056                                 default:
1057                                         assert (0);
1058                                         break;
1059                                 }
1060
1061                                 p += obj_parser->len;
1062                                 remain -= obj_parser->len;
1063                         }
1064
1065                         if (obj_parser->flags & MSGPACK_FLAG_ASSOC) {
1066                                 /* We have just read the new associative map */
1067                                 state = start_assoc;
1068                         }
1069                         else if (obj_parser->flags & MSGPACK_FLAG_CONTAINER){
1070                                 state = start_array;
1071                         }
1072                         else {
1073                                 state = next_state;
1074                         }
1075
1076                         break;
1077                 case start_assoc:
1078                         parser->cur_obj = ucl_object_new_full (UCL_OBJECT,
1079                                         parser->chunks->priority);
1080                         /* Insert to the previous level container */
1081                         if (parser->stack && !ucl_msgpack_insert_object (parser,
1082                                         key, keylen, parser->cur_obj)) {
1083                                 return false;
1084                         }
1085                         /* Get new container */
1086                         container = ucl_msgpack_get_container (parser, obj_parser, len);
1087
1088                         if (container == NULL) {
1089                                 return false;
1090                         }
1091
1092                         ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1093                                         p, remain);
1094                         CONSUME_RET;
1095                         key = NULL;
1096                         keylen = 0;
1097
1098                         if (len > 0) {
1099                                 state = read_type;
1100                                 next_state = read_assoc_key;
1101                         }
1102                         else {
1103                                 /* Empty object */
1104                                 state = finish_assoc_value;
1105                         }
1106                         break;
1107
1108                 case start_array:
1109                         parser->cur_obj = ucl_object_new_full (UCL_ARRAY,
1110                                         parser->chunks->priority);
1111                         /* Insert to the previous level container */
1112                         if (parser->stack && !ucl_msgpack_insert_object (parser,
1113                                         key, keylen, parser->cur_obj)) {
1114                                 return false;
1115                         }
1116                         /* Get new container */
1117                         container = ucl_msgpack_get_container (parser, obj_parser, len);
1118
1119                         if (container == NULL) {
1120                                 return false;
1121                         }
1122
1123                         ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1124                                                                 p, remain);
1125                         CONSUME_RET;
1126
1127                         if (len > 0) {
1128                                 state = read_type;
1129                                 next_state = read_array_value;
1130                         }
1131                         else {
1132                                 /* Empty array */
1133                                 state = finish_array_value;
1134                         }
1135                         break;
1136
1137                 case read_array_value:
1138                         /*
1139                          * p is now at the value start, len now contains length read and
1140                          * obj_parser contains the corresponding specific parser
1141                          */
1142                         container = parser->stack;
1143
1144                         if (container == NULL) {
1145                                 return false;
1146                         }
1147
1148                         ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1149                                         p, remain);
1150                         CONSUME_RET;
1151
1152
1153                         /* Insert value to the container and check if we have finished array */
1154                         if (!ucl_msgpack_insert_object (parser, NULL, 0,
1155                                         parser->cur_obj)) {
1156                                 return false;
1157                         }
1158
1159                         if (ucl_msgpack_is_container_finished (container)) {
1160                                 state = finish_array_value;
1161                         }
1162                         else {
1163                                 /* Read more elements */
1164                                 state = read_type;
1165                                 next_state = read_array_value;
1166                         }
1167
1168                         break;
1169
1170                 case read_assoc_key:
1171                         /*
1172                          * Keys must have string type for ucl msgpack
1173                          */
1174                         if (!(obj_parser->flags & MSGPACK_FLAG_KEY)) {
1175                                 ucl_create_err (&parser->err, "bad type for key: %u, expected "
1176                                                 "string", (unsigned)obj_parser->fmt);
1177
1178                                 return false;
1179                         }
1180
1181                         key = p;
1182                         keylen = len;
1183
1184                         if (keylen > remain || keylen == 0) {
1185                                 ucl_create_err (&parser->err, "too long or empty key");
1186                                 return false;
1187                         }
1188
1189                         p += len;
1190                         remain -= len;
1191
1192                         state = read_type;
1193                         next_state = read_assoc_value;
1194                         break;
1195
1196                 case read_assoc_value:
1197                         /*
1198                          * p is now at the value start, len now contains length read and
1199                          * obj_parser contains the corresponding specific parser
1200                          */
1201                         container = parser->stack;
1202
1203                         if (container == NULL) {
1204                                 return false;
1205                         }
1206
1207                         ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1208                                         p, remain);
1209                         CONSUME_RET;
1210
1211                         assert (key != NULL && keylen > 0);
1212
1213                         if (!ucl_msgpack_insert_object (parser, key, keylen,
1214                                         parser->cur_obj)) {
1215                                 return false;
1216                         }
1217
1218                         key = NULL;
1219                         keylen = 0;
1220
1221                         if (ucl_msgpack_is_container_finished (container)) {
1222                                 state = finish_assoc_value;
1223                         }
1224                         else {
1225                                 /* Read more elements */
1226                                 state = read_type;
1227                                 next_state = read_assoc_key;
1228                         }
1229                         break;
1230
1231                 case finish_array_value:
1232                 case finish_assoc_value:
1233                         GET_NEXT_STATE;
1234                         state = read_type;
1235                         break;
1236
1237                 case error_state:
1238                         ucl_create_err (&parser->err, "invalid state machine state");
1239
1240                         return false;
1241                 }
1242         }
1243
1244         /* Check the finishing state */
1245         switch (state) {
1246         case start_array:
1247         case start_assoc:
1248                 /* Empty container at the end */
1249                 if (len != 0) {
1250                         ucl_create_err (&parser->err, "invalid non-empty container at the end");
1251
1252                         return false;
1253                 }
1254
1255                 parser->cur_obj = ucl_object_new_full (
1256                                 state == start_array ? UCL_ARRAY : UCL_OBJECT,
1257                                 parser->chunks->priority);
1258                 /* Insert to the previous level container */
1259                 if (!ucl_msgpack_insert_object (parser,
1260                                 key, keylen, parser->cur_obj)) {
1261                         return false;
1262                 }
1263                 /* Get new container */
1264                 container = ucl_msgpack_get_container (parser, obj_parser, len);
1265
1266                 if (container == NULL) {
1267                         return false;
1268                 }
1269
1270                 ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1271                                 p, remain);
1272                 break;
1273
1274         case read_array_value:
1275         case read_assoc_value:
1276                 if (len != 0) {
1277                         ucl_create_err (&parser->err, "unfinished value at the end");
1278
1279                         return false;
1280                 }
1281
1282                 container = parser->stack;
1283
1284                 if (container == NULL) {
1285                         return false;
1286                 }
1287
1288                 ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1289                                 p, remain);
1290                 CONSUME_RET;
1291
1292
1293                 /* Insert value to the container and check if we have finished array */
1294                 if (!ucl_msgpack_insert_object (parser, NULL, 0,
1295                                 parser->cur_obj)) {
1296                         return false;
1297                 }
1298                 break;
1299         case finish_array_value:
1300         case finish_assoc_value:
1301         case read_type:
1302                 /* Valid finishing state */
1303                 break;
1304         default:
1305                 /* Invalid finishing state */
1306                 ucl_create_err (&parser->err, "invalid state machine finishing state: %d",
1307                                 state);
1308
1309                 return false;
1310         }
1311
1312         /* Rewind to the top level container */
1313         ucl_msgpack_get_next_container (parser);
1314         assert (parser->stack == NULL ||
1315                         (parser->stack->level & MSGPACK_CONTAINER_BIT) == 0);
1316
1317         return true;
1318 }
1319
1320 bool
1321 ucl_parse_msgpack (struct ucl_parser *parser)
1322 {
1323         ucl_object_t *container = NULL;
1324         const unsigned char *p;
1325         bool ret;
1326
1327         assert (parser != NULL);
1328         assert (parser->chunks != NULL);
1329         assert (parser->chunks->begin != NULL);
1330         assert (parser->chunks->remain != 0);
1331
1332         p = parser->chunks->begin;
1333
1334         if (parser->stack) {
1335                 container = parser->stack->obj;
1336         }
1337
1338         /*
1339          * When we start parsing message pack chunk, we must ensure that we
1340          * have either a valid container or the top object inside message pack is
1341          * of container type
1342          */
1343         if (container == NULL) {
1344                 if ((*p & 0x80) != 0x80 && !(*p >= 0xdc && *p <= 0xdf)) {
1345                         ucl_create_err (&parser->err, "bad top level object for msgpack");
1346                         return false;
1347                 }
1348         }
1349
1350         ret = ucl_msgpack_consume (parser);
1351
1352         if (ret && parser->top_obj == NULL) {
1353                 parser->top_obj = parser->cur_obj;
1354         }
1355
1356         return ret;
1357 }
1358
1359 static ssize_t
1360 ucl_msgpack_parse_map (struct ucl_parser *parser,
1361                 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1362                 const unsigned char *pos, size_t remain)
1363 {
1364         container->obj = parser->cur_obj;
1365
1366         return 0;
1367 }
1368
1369 static ssize_t
1370 ucl_msgpack_parse_array (struct ucl_parser *parser,
1371                 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1372                 const unsigned char *pos, size_t remain)
1373 {
1374         container->obj = parser->cur_obj;
1375
1376         return 0;
1377 }
1378
1379 static ssize_t
1380 ucl_msgpack_parse_string (struct ucl_parser *parser,
1381                 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1382                 const unsigned char *pos, size_t remain)
1383 {
1384         ucl_object_t *obj;
1385
1386         if (len > remain) {
1387                 return -1;
1388         }
1389
1390         obj = ucl_object_new_full (UCL_STRING, parser->chunks->priority);
1391         obj->value.sv = pos;
1392         obj->len = len;
1393
1394         if (fmt >= msgpack_bin8 && fmt <= msgpack_bin32) {
1395                 obj->flags |= UCL_OBJECT_BINARY;
1396         }
1397
1398         if (!(parser->flags & UCL_PARSER_ZEROCOPY)) {
1399                 if (obj->flags & UCL_OBJECT_BINARY) {
1400                         obj->trash_stack[UCL_TRASH_VALUE] = malloc (len);
1401
1402                         if (obj->trash_stack[UCL_TRASH_VALUE] != NULL) {
1403                                 memcpy (obj->trash_stack[UCL_TRASH_VALUE], pos, len);
1404                         }
1405                 }
1406                 else {
1407                         ucl_copy_value_trash (obj);
1408                 }
1409         }
1410
1411         parser->cur_obj = obj;
1412
1413         return len;
1414 }
1415
1416 static ssize_t
1417 ucl_msgpack_parse_int (struct ucl_parser *parser,
1418                 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1419                 const unsigned char *pos, size_t remain)
1420 {
1421         ucl_object_t *obj;
1422         int8_t iv8;
1423         int16_t iv16;
1424         int32_t iv32;
1425         int64_t iv64;
1426         uint16_t uiv16;
1427         uint32_t uiv32;
1428         uint64_t uiv64;
1429
1430
1431         if (len > remain) {
1432                 return -1;
1433         }
1434
1435         obj = ucl_object_new_full (UCL_INT, parser->chunks->priority);
1436
1437         switch (fmt) {
1438         case msgpack_positive_fixint:
1439                 obj->value.iv = (*pos & 0x7f);
1440                 len = 1;
1441                 break;
1442         case msgpack_negative_fixint:
1443                 obj->value.iv = - (*pos & 0x1f);
1444                 len = 1;
1445                 break;
1446         case msgpack_uint8:
1447                 obj->value.iv = (unsigned char)*pos;
1448                 len = 1;
1449                 break;
1450         case msgpack_int8:
1451                 memcpy (&iv8, pos, sizeof (iv8));
1452                 obj->value.iv = iv8;
1453                 len = 1;
1454                 break;
1455         case msgpack_int16:
1456                 memcpy (&iv16, pos, sizeof (iv16));
1457                 iv16 = FROM_BE16 (iv16);
1458                 obj->value.iv = iv16;
1459                 len = 2;
1460                 break;
1461         case msgpack_uint16:
1462                 memcpy (&uiv16, pos, sizeof (uiv16));
1463                 uiv16 = FROM_BE16 (uiv16);
1464                 obj->value.iv = uiv16;
1465                 len = 2;
1466                 break;
1467         case msgpack_int32:
1468                 memcpy (&iv32, pos, sizeof (iv32));
1469                 iv32 = FROM_BE32 (iv32);
1470                 obj->value.iv = iv32;
1471                 len = 4;
1472                 break;
1473         case msgpack_uint32:
1474                 memcpy(&uiv32, pos, sizeof(uiv32));
1475                 uiv32 = FROM_BE32(uiv32);
1476                 obj->value.iv = uiv32;
1477                 len = 4;
1478                 break;
1479         case msgpack_int64:
1480                 memcpy (&iv64, pos, sizeof (iv64));
1481                 iv64 = FROM_BE64 (iv64);
1482                 obj->value.iv = iv64;
1483                 len = 8;
1484                 break;
1485         case msgpack_uint64:
1486                 memcpy(&uiv64, pos, sizeof(uiv64));
1487                 uiv64 = FROM_BE64(uiv64);
1488                 obj->value.iv = uiv64;
1489                 len = 8;
1490                 break;
1491         default:
1492                 assert (0);
1493                 break;
1494         }
1495
1496         parser->cur_obj = obj;
1497
1498         return len;
1499 }
1500
1501 static ssize_t
1502 ucl_msgpack_parse_float (struct ucl_parser *parser,
1503                 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1504                 const unsigned char *pos, size_t remain)
1505 {
1506         ucl_object_t *obj;
1507         union {
1508                 uint32_t i;
1509                 float f;
1510         } d;
1511         uint64_t uiv64;
1512
1513         if (len > remain) {
1514                 return -1;
1515         }
1516
1517         obj = ucl_object_new_full (UCL_FLOAT, parser->chunks->priority);
1518
1519         switch (fmt) {
1520         case msgpack_float32:
1521                 memcpy(&d.i, pos, sizeof(d.i));
1522                 d.i = FROM_BE32(d.i);
1523                 /* XXX: can be slow */
1524                 obj->value.dv = d.f;
1525                 len = 4;
1526                 break;
1527         case msgpack_float64:
1528                 memcpy(&uiv64, pos, sizeof(uiv64));
1529                 uiv64 = FROM_BE64(uiv64);
1530                 obj->value.iv = uiv64;
1531                 len = 8;
1532                 break;
1533         default:
1534                 assert (0);
1535                 break;
1536         }
1537
1538         parser->cur_obj = obj;
1539
1540         return len;
1541 }
1542
1543 static ssize_t
1544 ucl_msgpack_parse_bool (struct ucl_parser *parser,
1545                 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1546                 const unsigned char *pos, size_t remain)
1547 {
1548         ucl_object_t *obj;
1549
1550         if (len > remain) {
1551                 return -1;
1552         }
1553
1554         obj = ucl_object_new_full (UCL_BOOLEAN, parser->chunks->priority);
1555
1556         switch (fmt) {
1557         case msgpack_true:
1558                 obj->value.iv = true;
1559                 break;
1560         case msgpack_false:
1561                 obj->value.iv = false;
1562                 break;
1563         default:
1564                 assert (0);
1565                 break;
1566         }
1567
1568         parser->cur_obj = obj;
1569
1570         return 1;
1571 }
1572
1573 static ssize_t
1574 ucl_msgpack_parse_null (struct ucl_parser *parser,
1575                 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1576                 const unsigned char *pos, size_t remain)
1577 {
1578         ucl_object_t *obj;
1579
1580         if (len > remain) {
1581                 return -1;
1582         }
1583
1584         obj = ucl_object_new_full (UCL_NULL, parser->chunks->priority);
1585         parser->cur_obj = obj;
1586
1587         return 1;
1588 }
1589
1590 static ssize_t
1591 ucl_msgpack_parse_ignore (struct ucl_parser *parser,
1592                 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1593                 const unsigned char *pos, size_t remain)
1594 {
1595         if (len > remain) {
1596                 return -1;
1597         }
1598
1599         switch (fmt) {
1600         case msgpack_fixext1:
1601                 len = 2;
1602                 break;
1603         case msgpack_fixext2:
1604                 len = 3;
1605                 break;
1606         case msgpack_fixext4:
1607                 len = 5;
1608                 break;
1609         case msgpack_fixext8:
1610                 len = 9;
1611                 break;
1612         case msgpack_fixext16:
1613                 len = 17;
1614                 break;
1615         case msgpack_ext8:
1616         case msgpack_ext16:
1617         case msgpack_ext32:
1618                 len = len + 1;
1619                 break;
1620         default:
1621                 ucl_create_err (&parser->err, "bad type: %x", (unsigned)fmt);
1622                 return -1;
1623         }
1624
1625         return len;
1626 }