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 <= 0xff) {
117 len = 2;
118 buf[0] = uint8_ch;
119 buf[1] = val & 0xff;
120 }
121 else if (val <= 0xffff) {
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 <= 0xffffffff) {
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 <= 0xff) {
153 len = 2;
154 buf[0] = int8_ch;
155 buf[1] = (unsigned char)val;
156 }
157 else if (uval <= 0xffff) {
158 uint16_t v = TO_BE16 (val);
159
160 len = 3;
161 buf[0] = int16_ch;
162 memcpy (&buf[1], &v, sizeof (v));
163 }
164 else if (uval <= 0xffffffff) {
165 uint32_t v = TO_BE32 (val);
166
167 len = 5;
168 buf[0] = int32_ch;
169 memcpy (&buf[1], &v, sizeof (v));
170 }
171 else {
172 uint64_t v = TO_BE64 (val);
173
174 len = 9;
175 buf[0] = int64_ch;
176 memcpy (&buf[1], &v, sizeof (v));
177 }
178 }
179
180 func->ucl_emitter_append_len (buf, len, func->ud);
181 }
182
183 void
ucl_emitter_print_double_msgpack(struct ucl_emitter_context * ctx,double val)184 ucl_emitter_print_double_msgpack (struct ucl_emitter_context *ctx, double val)
185 {
186 const struct ucl_emitter_functions *func = ctx->func;
187 union {
188 double d;
189 uint64_t i;
190 } u;
191 const unsigned char dbl_ch = 0xcb;
192 unsigned char buf[sizeof(double) + 1];
193
194 /* Convert to big endian */
195 u.d = val;
196 u.i = TO_BE64 (u.i);
197
198 buf[0] = dbl_ch;
199 memcpy (&buf[1], &u.d, sizeof (double));
200 func->ucl_emitter_append_len (buf, sizeof (buf), func->ud);
201 }
202
203 void
ucl_emitter_print_bool_msgpack(struct ucl_emitter_context * ctx,bool val)204 ucl_emitter_print_bool_msgpack (struct ucl_emitter_context *ctx, bool val)
205 {
206 const struct ucl_emitter_functions *func = ctx->func;
207 const unsigned char true_ch = 0xc3, false_ch = 0xc2;
208
209 func->ucl_emitter_append_character (val ? true_ch : false_ch, 1, func->ud);
210 }
211
212 void
ucl_emitter_print_string_msgpack(struct ucl_emitter_context * ctx,const char * s,size_t len)213 ucl_emitter_print_string_msgpack (struct ucl_emitter_context *ctx,
214 const char *s, size_t len)
215 {
216 const struct ucl_emitter_functions *func = ctx->func;
217 const unsigned char fix_mask = 0xA0, l8_ch = 0xd9, l16_ch = 0xda, l32_ch = 0xdb;
218 unsigned char buf[5];
219 unsigned blen;
220
221 if (len <= 0x1F) {
222 blen = 1;
223 buf[0] = (len | fix_mask) & 0xff;
224 }
225 else if (len <= 0xff) {
226 blen = 2;
227 buf[0] = l8_ch;
228 buf[1] = len & 0xff;
229 }
230 else if (len <= 0xffff) {
231 uint16_t bl = TO_BE16 (len);
232
233 blen = 3;
234 buf[0] = l16_ch;
235 memcpy (&buf[1], &bl, sizeof (bl));
236 }
237 else {
238 uint32_t bl = TO_BE32 (len);
239
240 blen = 5;
241 buf[0] = l32_ch;
242 memcpy (&buf[1], &bl, sizeof (bl));
243 }
244
245 func->ucl_emitter_append_len (buf, blen, func->ud);
246 func->ucl_emitter_append_len (s, len, func->ud);
247 }
248
249 void
ucl_emitter_print_binary_string_msgpack(struct ucl_emitter_context * ctx,const char * s,size_t len)250 ucl_emitter_print_binary_string_msgpack (struct ucl_emitter_context *ctx,
251 const char *s, size_t len)
252 {
253 const struct ucl_emitter_functions *func = ctx->func;
254 const unsigned char l8_ch = 0xc4, l16_ch = 0xc5, l32_ch = 0xc6;
255 unsigned char buf[5];
256 unsigned blen;
257
258 if (len <= 0xff) {
259 blen = 2;
260 buf[0] = l8_ch;
261 buf[1] = len & 0xff;
262 }
263 else if (len <= 0xffff) {
264 uint16_t bl = TO_BE16 (len);
265
266 blen = 3;
267 buf[0] = l16_ch;
268 memcpy (&buf[1], &bl, sizeof (bl));
269 }
270 else {
271 uint32_t bl = TO_BE32 (len);
272
273 blen = 5;
274 buf[0] = l32_ch;
275 memcpy (&buf[1], &bl, sizeof (bl));
276 }
277
278 func->ucl_emitter_append_len (buf, blen, func->ud);
279 func->ucl_emitter_append_len (s, len, func->ud);
280 }
281
282 void
ucl_emitter_print_null_msgpack(struct ucl_emitter_context * ctx)283 ucl_emitter_print_null_msgpack (struct ucl_emitter_context *ctx)
284 {
285 const struct ucl_emitter_functions *func = ctx->func;
286 const unsigned char nil = 0xc0;
287
288 func->ucl_emitter_append_character (nil, 1, func->ud);
289 }
290
291 void
ucl_emitter_print_key_msgpack(bool print_key,struct ucl_emitter_context * ctx,const ucl_object_t * obj)292 ucl_emitter_print_key_msgpack (bool print_key, struct ucl_emitter_context *ctx,
293 const ucl_object_t *obj)
294 {
295 if (print_key) {
296 ucl_emitter_print_string_msgpack (ctx, obj->key, obj->keylen);
297 }
298 }
299
300 void
ucl_emitter_print_array_msgpack(struct ucl_emitter_context * ctx,size_t len)301 ucl_emitter_print_array_msgpack (struct ucl_emitter_context *ctx, size_t len)
302 {
303 const struct ucl_emitter_functions *func = ctx->func;
304 const unsigned char fix_mask = 0x90, l16_ch = 0xdc, l32_ch = 0xdd;
305 unsigned char buf[5];
306 unsigned blen;
307
308 if (len <= 0xF) {
309 blen = 1;
310 buf[0] = (len | fix_mask) & 0xff;
311 }
312 else if (len <= 0xffff) {
313 uint16_t bl = TO_BE16 (len);
314
315 blen = 3;
316 buf[0] = l16_ch;
317 memcpy (&buf[1], &bl, sizeof (bl));
318 }
319 else {
320 uint32_t bl = TO_BE32 (len);
321
322 blen = 5;
323 buf[0] = l32_ch;
324 memcpy (&buf[1], &bl, sizeof (bl));
325 }
326
327 func->ucl_emitter_append_len (buf, blen, func->ud);
328 }
329
330 void
ucl_emitter_print_object_msgpack(struct ucl_emitter_context * ctx,size_t len)331 ucl_emitter_print_object_msgpack (struct ucl_emitter_context *ctx, size_t len)
332 {
333 const struct ucl_emitter_functions *func = ctx->func;
334 const unsigned char fix_mask = 0x80, l16_ch = 0xde, l32_ch = 0xdf;
335 unsigned char buf[5];
336 unsigned blen;
337
338 if (len <= 0xF) {
339 blen = 1;
340 buf[0] = (len | fix_mask) & 0xff;
341 }
342 else if (len <= 0xffff) {
343 uint16_t bl = TO_BE16 (len);
344
345 blen = 3;
346 buf[0] = l16_ch;
347 memcpy (&buf[1], &bl, sizeof (bl));
348 }
349 else {
350 uint32_t bl = TO_BE32 (len);
351
352 blen = 5;
353 buf[0] = l32_ch;
354 memcpy (&buf[1], &bl, sizeof (bl));
355 }
356
357 func->ucl_emitter_append_len (buf, blen, func->ud);
358 }
359
360
361 enum ucl_msgpack_format {
362 msgpack_positive_fixint = 0,
363 msgpack_fixmap,
364 msgpack_fixarray,
365 msgpack_fixstr,
366 msgpack_nil,
367 msgpack_false,
368 msgpack_true,
369 msgpack_bin8,
370 msgpack_bin16,
371 msgpack_bin32,
372 msgpack_ext8,
373 msgpack_ext16,
374 msgpack_ext32,
375 msgpack_float32,
376 msgpack_float64,
377 msgpack_uint8,
378 msgpack_uint16,
379 msgpack_uint32,
380 msgpack_uint64,
381 msgpack_int8,
382 msgpack_int16,
383 msgpack_int32,
384 msgpack_int64,
385 msgpack_fixext1,
386 msgpack_fixext2,
387 msgpack_fixext4,
388 msgpack_fixext8,
389 msgpack_fixext16,
390 msgpack_str8,
391 msgpack_str16,
392 msgpack_str32,
393 msgpack_array16,
394 msgpack_array32,
395 msgpack_map16,
396 msgpack_map32,
397 msgpack_negative_fixint,
398 msgpack_invalid
399 };
400
401 typedef ssize_t (*ucl_msgpack_parse_function)(struct ucl_parser *parser,
402 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
403 const unsigned char *pos, size_t remain);
404
405 static ssize_t ucl_msgpack_parse_map (struct ucl_parser *parser,
406 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
407 const unsigned char *pos, size_t remain);
408 static ssize_t ucl_msgpack_parse_array (struct ucl_parser *parser,
409 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
410 const unsigned char *pos, size_t remain);
411 static ssize_t ucl_msgpack_parse_string (struct ucl_parser *parser,
412 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
413 const unsigned char *pos, size_t remain);
414 static ssize_t ucl_msgpack_parse_int (struct ucl_parser *parser,
415 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
416 const unsigned char *pos, size_t remain);
417 static ssize_t ucl_msgpack_parse_float (struct ucl_parser *parser,
418 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
419 const unsigned char *pos, size_t remain);
420 static ssize_t ucl_msgpack_parse_bool (struct ucl_parser *parser,
421 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
422 const unsigned char *pos, size_t remain);
423 static ssize_t ucl_msgpack_parse_null (struct ucl_parser *parser,
424 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
425 const unsigned char *pos, size_t remain);
426 static ssize_t ucl_msgpack_parse_ignore (struct ucl_parser *parser,
427 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
428 const unsigned char *pos, size_t remain);
429
430 #define MSGPACK_FLAG_FIXED (1 << 0)
431 #define MSGPACK_FLAG_CONTAINER (1 << 1)
432 #define MSGPACK_FLAG_TYPEVALUE (1 << 2)
433 #define MSGPACK_FLAG_EXT (1 << 3)
434 #define MSGPACK_FLAG_ASSOC (1 << 4)
435 #define MSGPACK_FLAG_KEY (1 << 5)
436 #define MSGPACK_CONTAINER_BIT (1ULL << 62)
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 == (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 assert ((len & MSGPACK_CONTAINER_BIT) == 0);
771 /*
772 * Insert new container to the stack
773 */
774 if (parser->stack == NULL) {
775 parser->stack = calloc (1, sizeof (struct ucl_stack));
776
777 if (parser->stack == NULL) {
778 ucl_create_err (&parser->err, "no memory");
779 return NULL;
780 }
781 }
782 else {
783 stack = calloc (1, sizeof (struct ucl_stack));
784
785 if (stack == NULL) {
786 ucl_create_err (&parser->err, "no memory");
787 return NULL;
788 }
789
790 stack->next = parser->stack;
791 parser->stack = stack;
792 }
793
794 parser->stack->level = len | MSGPACK_CONTAINER_BIT;
795
796 #ifdef MSGPACK_DEBUG_PARSER
797 stack = parser->stack;
798 while (stack) {
799 fprintf(stderr, "+");
800 stack = stack->next;
801 }
802
803 fprintf(stderr, "%s -> %d\n", obj_parser->flags & MSGPACK_FLAG_ASSOC ? "object" : "array", (int)len);
804 #endif
805 }
806 else {
807 /*
808 * Get the current stack top
809 */
810 if (parser->stack) {
811 return parser->stack;
812 }
813 else {
814 ucl_create_err (&parser->err, "bad top level object for msgpack");
815 return NULL;
816 }
817 }
818
819 return parser->stack;
820 }
821
822 static bool
ucl_msgpack_is_container_finished(struct ucl_stack * container)823 ucl_msgpack_is_container_finished (struct ucl_stack *container)
824 {
825 uint64_t level;
826
827 assert (container != NULL);
828
829 if (container->level & MSGPACK_CONTAINER_BIT) {
830 level = container->level & ~MSGPACK_CONTAINER_BIT;
831
832 if (level == 0) {
833 return true;
834 }
835 }
836
837 return false;
838 }
839
840 static bool
ucl_msgpack_insert_object(struct ucl_parser * parser,const unsigned char * key,size_t keylen,ucl_object_t * obj)841 ucl_msgpack_insert_object (struct ucl_parser *parser,
842 const unsigned char *key,
843 size_t keylen, ucl_object_t *obj)
844 {
845 uint64_t level;
846 struct ucl_stack *container;
847
848 container = parser->stack;
849 assert (container != NULL);
850 assert (container->level > 0);
851 assert (obj != NULL);
852 assert (container->obj != NULL);
853
854 if (container->obj->type == UCL_ARRAY) {
855 ucl_array_append (container->obj, obj);
856 }
857 else if (container->obj->type == UCL_OBJECT) {
858 if (key == NULL || keylen == 0) {
859 ucl_create_err (&parser->err, "cannot insert object with no key");
860 return false;
861 }
862
863 obj->key = key;
864 obj->keylen = keylen;
865
866 if (!(parser->flags & UCL_PARSER_ZEROCOPY)) {
867 ucl_copy_key_trash (obj);
868 }
869
870 ucl_parser_process_object_element (parser, obj);
871 }
872 else {
873 ucl_create_err (&parser->err, "bad container type");
874 return false;
875 }
876
877 if (container->level & MSGPACK_CONTAINER_BIT) {
878 level = container->level & ~MSGPACK_CONTAINER_BIT;
879 container->level = (level - 1) | MSGPACK_CONTAINER_BIT;
880 }
881
882 return true;
883 }
884
885 static struct ucl_stack *
ucl_msgpack_get_next_container(struct ucl_parser * parser)886 ucl_msgpack_get_next_container (struct ucl_parser *parser)
887 {
888 struct ucl_stack *cur = NULL;
889 uint64_t level;
890
891 cur = parser->stack;
892
893 if (cur == NULL) {
894 return NULL;
895 }
896
897 if (cur->level & MSGPACK_CONTAINER_BIT) {
898 level = cur->level & ~MSGPACK_CONTAINER_BIT;
899
900 if (level == 0) {
901 /* We need to switch to the previous container */
902 parser->stack = cur->next;
903 parser->cur_obj = cur->obj;
904 free (cur);
905
906 #ifdef MSGPACK_DEBUG_PARSER
907 cur = parser->stack;
908 while (cur) {
909 fprintf(stderr, "-");
910 cur = cur->next;
911 }
912 fprintf(stderr, "-%s -> %d\n", parser->cur_obj->type == UCL_OBJECT ? "object" : "array", (int)parser->cur_obj->len);
913 #endif
914
915 return ucl_msgpack_get_next_container (parser);
916 }
917 }
918
919 /*
920 * For UCL containers we don't know length, so we just insert the whole
921 * message pack blob into the top level container
922 */
923
924 assert (cur->obj != NULL);
925
926 return cur;
927 }
928
929 #define CONSUME_RET do { \
930 if (ret != -1) { \
931 p += ret; \
932 remain -= ret; \
933 obj_parser = NULL; \
934 assert (remain >= 0); \
935 } \
936 else { \
937 ucl_create_err (&parser->err, \
938 "cannot parse type %d of len %u", \
939 (int)obj_parser->fmt, \
940 (unsigned)len); \
941 return false; \
942 } \
943 } while(0)
944
945 #define GET_NEXT_STATE do { \
946 container = ucl_msgpack_get_next_container (parser); \
947 if (container == NULL) { \
948 ucl_create_err (&parser->err, \
949 "empty container"); \
950 return false; \
951 } \
952 next_state = container->obj->type == UCL_OBJECT ? \
953 read_assoc_key : read_array_value; \
954 } while(0)
955
956 static bool
ucl_msgpack_consume(struct ucl_parser * parser)957 ucl_msgpack_consume (struct ucl_parser *parser)
958 {
959 const unsigned char *p, *end, *key = NULL;
960 struct ucl_stack *container;
961 enum e_msgpack_parser_state {
962 read_type,
963 start_assoc,
964 start_array,
965 read_assoc_key,
966 read_assoc_value,
967 finish_assoc_value,
968 read_array_value,
969 finish_array_value,
970 error_state
971 } state = read_type, next_state = error_state;
972 struct ucl_msgpack_parser *obj_parser;
973 uint64_t len;
974 ssize_t ret, remain, keylen = 0;
975 #ifdef MSGPACK_DEBUG_PARSER
976 uint64_t i;
977 enum e_msgpack_parser_state hist[256];
978 #endif
979
980 p = parser->chunks->begin;
981 remain = parser->chunks->remain;
982 end = p + remain;
983
984
985 while (p < end) {
986 #ifdef MSGPACK_DEBUG_PARSER
987 hist[i++ % 256] = state;
988 #endif
989 switch (state) {
990 case read_type:
991 obj_parser = ucl_msgpack_get_parser_from_type (*p);
992
993 if (obj_parser == NULL) {
994 ucl_create_err (&parser->err, "unknown msgpack format: %x",
995 (unsigned int)*p);
996
997 return false;
998 }
999 /* Now check length sanity */
1000 if (obj_parser->flags & MSGPACK_FLAG_FIXED) {
1001 if (obj_parser->len == 0) {
1002 /* We have an embedded size */
1003 len = *p & ~obj_parser->prefix;
1004 }
1005 else {
1006 if (remain < obj_parser->len) {
1007 ucl_create_err (&parser->err, "not enough data remain to "
1008 "read object's length: %u remain, %u needed",
1009 (unsigned)remain, obj_parser->len);
1010
1011 return false;
1012 }
1013
1014 len = obj_parser->len;
1015 }
1016
1017 if (!(obj_parser->flags & MSGPACK_FLAG_TYPEVALUE)) {
1018 /* We must pass value as the second byte */
1019 if (remain > 0) {
1020 p ++;
1021 remain --;
1022 }
1023 }
1024 else {
1025 /* Len is irrelevant now */
1026 len = 0;
1027 }
1028 }
1029 else {
1030 /* Length is not embedded */
1031 if (remain < obj_parser->len) {
1032 ucl_create_err (&parser->err, "not enough data remain to "
1033 "read object's length: %u remain, %u needed",
1034 (unsigned)remain, obj_parser->len);
1035
1036 return false;
1037 }
1038
1039 p ++;
1040 remain --;
1041
1042 switch (obj_parser->len) {
1043 case 1:
1044 len = *p;
1045 break;
1046 case 2:
1047 len = FROM_BE16 (*(uint16_t *)p);
1048 break;
1049 case 4:
1050 len = FROM_BE32 (*(uint32_t *)p);
1051 break;
1052 case 8:
1053 len = FROM_BE64 (*(uint64_t *)p);
1054 break;
1055 default:
1056 assert (0);
1057 break;
1058 }
1059
1060 p += obj_parser->len;
1061 remain -= obj_parser->len;
1062 }
1063
1064 if (obj_parser->flags & MSGPACK_FLAG_ASSOC) {
1065 /* We have just read the new associative map */
1066 state = start_assoc;
1067 }
1068 else if (obj_parser->flags & MSGPACK_FLAG_CONTAINER){
1069 state = start_array;
1070 }
1071 else {
1072 state = next_state;
1073 }
1074
1075 break;
1076 case start_assoc:
1077 parser->cur_obj = ucl_object_new_full (UCL_OBJECT,
1078 parser->chunks->priority);
1079 /* Insert to the previous level container */
1080 if (parser->stack && !ucl_msgpack_insert_object (parser,
1081 key, keylen, parser->cur_obj)) {
1082 return false;
1083 }
1084 /* Get new container */
1085 container = ucl_msgpack_get_container (parser, obj_parser, len);
1086
1087 if (container == NULL) {
1088 return false;
1089 }
1090
1091 ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1092 p, remain);
1093 CONSUME_RET;
1094 key = NULL;
1095 keylen = 0;
1096
1097 if (len > 0) {
1098 state = read_type;
1099 next_state = read_assoc_key;
1100 }
1101 else {
1102 /* Empty object */
1103 state = finish_assoc_value;
1104 }
1105 break;
1106
1107 case start_array:
1108 parser->cur_obj = ucl_object_new_full (UCL_ARRAY,
1109 parser->chunks->priority);
1110 /* Insert to the previous level container */
1111 if (parser->stack && !ucl_msgpack_insert_object (parser,
1112 key, keylen, parser->cur_obj)) {
1113 return false;
1114 }
1115 /* Get new container */
1116 container = ucl_msgpack_get_container (parser, obj_parser, len);
1117
1118 if (container == NULL) {
1119 return false;
1120 }
1121
1122 ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1123 p, remain);
1124 CONSUME_RET;
1125
1126 if (len > 0) {
1127 state = read_type;
1128 next_state = read_array_value;
1129 }
1130 else {
1131 /* Empty array */
1132 state = finish_array_value;
1133 }
1134 break;
1135
1136 case read_array_value:
1137 /*
1138 * p is now at the value start, len now contains length read and
1139 * obj_parser contains the corresponding specific parser
1140 */
1141 container = parser->stack;
1142
1143 if (container == NULL) {
1144 return false;
1145 }
1146
1147 ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1148 p, remain);
1149 CONSUME_RET;
1150
1151
1152 /* Insert value to the container and check if we have finished array */
1153 if (!ucl_msgpack_insert_object (parser, NULL, 0,
1154 parser->cur_obj)) {
1155 return false;
1156 }
1157
1158 if (ucl_msgpack_is_container_finished (container)) {
1159 state = finish_array_value;
1160 }
1161 else {
1162 /* Read more elements */
1163 state = read_type;
1164 next_state = read_array_value;
1165 }
1166
1167 break;
1168
1169 case read_assoc_key:
1170 /*
1171 * Keys must have string type for ucl msgpack
1172 */
1173 if (!(obj_parser->flags & MSGPACK_FLAG_KEY)) {
1174 ucl_create_err (&parser->err, "bad type for key: %u, expected "
1175 "string", (unsigned)obj_parser->fmt);
1176
1177 return false;
1178 }
1179
1180 key = p;
1181 keylen = len;
1182
1183 if (keylen > remain || keylen == 0) {
1184 ucl_create_err (&parser->err, "too long or empty key");
1185 return false;
1186 }
1187
1188 p += len;
1189 remain -= len;
1190
1191 state = read_type;
1192 next_state = read_assoc_value;
1193 break;
1194
1195 case read_assoc_value:
1196 /*
1197 * p is now at the value start, len now contains length read and
1198 * obj_parser contains the corresponding specific parser
1199 */
1200 container = parser->stack;
1201
1202 if (container == NULL) {
1203 return false;
1204 }
1205
1206 ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1207 p, remain);
1208 CONSUME_RET;
1209
1210 assert (key != NULL && keylen > 0);
1211
1212 if (!ucl_msgpack_insert_object (parser, key, keylen,
1213 parser->cur_obj)) {
1214 return false;
1215 }
1216
1217 key = NULL;
1218 keylen = 0;
1219
1220 if (ucl_msgpack_is_container_finished (container)) {
1221 state = finish_assoc_value;
1222 }
1223 else {
1224 /* Read more elements */
1225 state = read_type;
1226 next_state = read_assoc_key;
1227 }
1228 break;
1229
1230 case finish_array_value:
1231 case finish_assoc_value:
1232 GET_NEXT_STATE;
1233 state = read_type;
1234 break;
1235
1236 case error_state:
1237 ucl_create_err (&parser->err, "invalid state machine state");
1238
1239 return false;
1240 }
1241 }
1242
1243 /* Check the finishing state */
1244 switch (state) {
1245 case start_array:
1246 case start_assoc:
1247 /* Empty container at the end */
1248 if (len != 0) {
1249 ucl_create_err (&parser->err, "invalid non-empty container at the end");
1250
1251 return false;
1252 }
1253
1254 parser->cur_obj = ucl_object_new_full (
1255 state == start_array ? UCL_ARRAY : UCL_OBJECT,
1256 parser->chunks->priority);
1257 /* Insert to the previous level container */
1258 if (!ucl_msgpack_insert_object (parser,
1259 key, keylen, parser->cur_obj)) {
1260 return false;
1261 }
1262 /* Get new container */
1263 container = ucl_msgpack_get_container (parser, obj_parser, len);
1264
1265 if (container == NULL) {
1266 return false;
1267 }
1268
1269 ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1270 p, remain);
1271 break;
1272
1273 case read_array_value:
1274 case read_assoc_value:
1275 if (len != 0) {
1276 ucl_create_err (&parser->err, "unfinished value at the end");
1277
1278 return false;
1279 }
1280
1281 container = parser->stack;
1282
1283 if (container == NULL) {
1284 return false;
1285 }
1286
1287 ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1288 p, remain);
1289 CONSUME_RET;
1290
1291
1292 /* Insert value to the container and check if we have finished array */
1293 if (!ucl_msgpack_insert_object (parser, NULL, 0,
1294 parser->cur_obj)) {
1295 return false;
1296 }
1297 break;
1298 case finish_array_value:
1299 case finish_assoc_value:
1300 case read_type:
1301 /* Valid finishing state */
1302 break;
1303 default:
1304 /* Invalid finishing state */
1305 ucl_create_err (&parser->err, "invalid state machine finishing state: %d",
1306 state);
1307
1308 return false;
1309 }
1310
1311 /* Rewind to the top level container */
1312 ucl_msgpack_get_next_container (parser);
1313 assert (parser->stack == NULL ||
1314 (parser->stack->level & MSGPACK_CONTAINER_BIT) == 0);
1315
1316 return true;
1317 }
1318
1319 bool
ucl_parse_msgpack(struct ucl_parser * parser)1320 ucl_parse_msgpack (struct ucl_parser *parser)
1321 {
1322 ucl_object_t *container = NULL;
1323 const unsigned char *p;
1324 bool ret;
1325
1326 assert (parser != NULL);
1327 assert (parser->chunks != NULL);
1328 assert (parser->chunks->begin != NULL);
1329 assert (parser->chunks->remain != 0);
1330
1331 p = parser->chunks->begin;
1332
1333 if (parser->stack) {
1334 container = parser->stack->obj;
1335 }
1336
1337 /*
1338 * When we start parsing message pack chunk, we must ensure that we
1339 * have either a valid container or the top object inside message pack is
1340 * of container type
1341 */
1342 if (container == NULL) {
1343 if ((*p & 0x80) != 0x80 && !(*p >= 0xdc && *p <= 0xdf)) {
1344 ucl_create_err (&parser->err, "bad top level object for msgpack");
1345 return false;
1346 }
1347 }
1348
1349 ret = ucl_msgpack_consume (parser);
1350
1351 if (ret && parser->top_obj == NULL) {
1352 parser->top_obj = parser->cur_obj;
1353 }
1354
1355 return ret;
1356 }
1357
1358 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)1359 ucl_msgpack_parse_map (struct ucl_parser *parser,
1360 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1361 const unsigned char *pos, size_t remain)
1362 {
1363 container->obj = parser->cur_obj;
1364
1365 return 0;
1366 }
1367
1368 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)1369 ucl_msgpack_parse_array (struct ucl_parser *parser,
1370 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1371 const unsigned char *pos, size_t remain)
1372 {
1373 container->obj = parser->cur_obj;
1374
1375 return 0;
1376 }
1377
1378 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)1379 ucl_msgpack_parse_string (struct ucl_parser *parser,
1380 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1381 const unsigned char *pos, size_t remain)
1382 {
1383 ucl_object_t *obj;
1384
1385 if (len > remain) {
1386 return -1;
1387 }
1388
1389 obj = ucl_object_new_full (UCL_STRING, parser->chunks->priority);
1390 obj->value.sv = pos;
1391 obj->len = len;
1392
1393 if (fmt >= msgpack_bin8 && fmt <= msgpack_bin32) {
1394 obj->flags |= UCL_OBJECT_BINARY;
1395 }
1396
1397 if (!(parser->flags & UCL_PARSER_ZEROCOPY)) {
1398 if (obj->flags & UCL_OBJECT_BINARY) {
1399 obj->trash_stack[UCL_TRASH_VALUE] = malloc (len);
1400
1401 if (obj->trash_stack[UCL_TRASH_VALUE] != NULL) {
1402 memcpy (obj->trash_stack[UCL_TRASH_VALUE], pos, len);
1403 }
1404 }
1405 else {
1406 ucl_copy_value_trash (obj);
1407 }
1408 }
1409
1410 parser->cur_obj = obj;
1411
1412 return len;
1413 }
1414
1415 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)1416 ucl_msgpack_parse_int (struct ucl_parser *parser,
1417 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1418 const unsigned char *pos, size_t remain)
1419 {
1420 ucl_object_t *obj;
1421
1422 if (len > remain) {
1423 return -1;
1424 }
1425
1426 obj = ucl_object_new_full (UCL_INT, parser->chunks->priority);
1427
1428 switch (fmt) {
1429 case msgpack_positive_fixint:
1430 obj->value.iv = (*pos & 0x7f);
1431 len = 1;
1432 break;
1433 case msgpack_negative_fixint:
1434 obj->value.iv = - (*pos & 0x1f);
1435 len = 1;
1436 break;
1437 case msgpack_uint8:
1438 obj->value.iv = (unsigned char)*pos;
1439 len = 1;
1440 break;
1441 case msgpack_int8:
1442 obj->value.iv = (signed char)*pos;
1443 len = 1;
1444 break;
1445 case msgpack_int16:
1446 obj->value.iv = FROM_BE16 (*(int16_t *)pos);
1447 len = 2;
1448 break;
1449 case msgpack_uint16:
1450 obj->value.iv = FROM_BE16 (*(uint16_t *)pos);
1451 len = 2;
1452 break;
1453 case msgpack_int32:
1454 obj->value.iv = FROM_BE32 (*(int32_t *)pos);
1455 len = 4;
1456 break;
1457 case msgpack_uint32:
1458 obj->value.iv = FROM_BE32 (*(uint32_t *)pos);
1459 len = 4;
1460 break;
1461 case msgpack_int64:
1462 obj->value.iv = FROM_BE64 (*(int64_t *)pos);
1463 len = 8;
1464 break;
1465 case msgpack_uint64:
1466 obj->value.iv = FROM_BE64 (*(uint64_t *)pos);
1467 len = 8;
1468 break;
1469 default:
1470 assert (0);
1471 break;
1472 }
1473
1474 parser->cur_obj = obj;
1475
1476 return len;
1477 }
1478
1479 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)1480 ucl_msgpack_parse_float (struct ucl_parser *parser,
1481 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1482 const unsigned char *pos, size_t remain)
1483 {
1484 ucl_object_t *obj;
1485 union {
1486 uint32_t i;
1487 float f;
1488 } d;
1489
1490 if (len > remain) {
1491 return -1;
1492 }
1493
1494 obj = ucl_object_new_full (UCL_FLOAT, parser->chunks->priority);
1495
1496 switch (fmt) {
1497 case msgpack_float32:
1498 d.i = FROM_BE32 (*(uint32_t *)pos);
1499 /* XXX: can be slow */
1500 obj->value.dv = d.f;
1501 len = 4;
1502 break;
1503 case msgpack_float64:
1504 obj->value.iv = FROM_BE64 (*(uint64_t *)pos);
1505 len = 8;
1506 break;
1507 default:
1508 assert (0);
1509 break;
1510 }
1511
1512 parser->cur_obj = obj;
1513
1514 return len;
1515 }
1516
1517 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)1518 ucl_msgpack_parse_bool (struct ucl_parser *parser,
1519 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1520 const unsigned char *pos, size_t remain)
1521 {
1522 ucl_object_t *obj;
1523
1524 if (len > remain) {
1525 return -1;
1526 }
1527
1528 obj = ucl_object_new_full (UCL_BOOLEAN, parser->chunks->priority);
1529
1530 switch (fmt) {
1531 case msgpack_true:
1532 obj->value.iv = true;
1533 break;
1534 case msgpack_false:
1535 obj->value.iv = false;
1536 break;
1537 default:
1538 assert (0);
1539 break;
1540 }
1541
1542 parser->cur_obj = obj;
1543
1544 return 1;
1545 }
1546
1547 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)1548 ucl_msgpack_parse_null (struct ucl_parser *parser,
1549 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1550 const unsigned char *pos, size_t remain)
1551 {
1552 ucl_object_t *obj;
1553
1554 if (len > remain) {
1555 return -1;
1556 }
1557
1558 obj = ucl_object_new_full (UCL_NULL, parser->chunks->priority);
1559 parser->cur_obj = obj;
1560
1561 return 1;
1562 }
1563
1564 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)1565 ucl_msgpack_parse_ignore (struct ucl_parser *parser,
1566 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1567 const unsigned char *pos, size_t remain)
1568 {
1569 if (len > remain) {
1570 return -1;
1571 }
1572
1573 switch (fmt) {
1574 case msgpack_fixext1:
1575 len = 2;
1576 break;
1577 case msgpack_fixext2:
1578 len = 3;
1579 break;
1580 case msgpack_fixext4:
1581 len = 5;
1582 break;
1583 case msgpack_fixext8:
1584 len = 9;
1585 break;
1586 case msgpack_fixext16:
1587 len = 17;
1588 break;
1589 case msgpack_ext8:
1590 case msgpack_ext16:
1591 case msgpack_ext32:
1592 len = len + 1;
1593 break;
1594 default:
1595 ucl_create_err (&parser->err, "bad type: %x", (unsigned)fmt);
1596 return -1;
1597 }
1598
1599 return len;
1600 }
1601