1 /*
2 * Copyright (c) 2015, Vsevolod Stakhov
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY AUTHOR ''AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY
17 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 */
24
25
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29
30 #include "ucl.h"
31 #include "ucl_internal.h"
32
33 #ifdef HAVE_ENDIAN_H
34 #include <endian.h>
35 #elif defined(HAVE_SYS_ENDIAN_H)
36 #include <sys/endian.h>
37 #elif defined(HAVE_MACHINE_ENDIAN_H)
38 #include <machine/endian.h>
39 #endif
40
41 #if !defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)
42 #if __BYTE_ORDER == __LITTLE_ENDIAN
43 #define __LITTLE_ENDIAN__
44 #elif __BYTE_ORDER == __BIG_ENDIAN
45 #define __BIG_ENDIAN__
46 #elif _WIN32
47 #define __LITTLE_ENDIAN__
48 #endif
49 #endif
50
51 #define SWAP_LE_BE16(val) ((uint16_t) ( \
52 (uint16_t) ((uint16_t) (val) >> 8) | \
53 (uint16_t) ((uint16_t) (val) << 8)))
54
55 #if defined(__clang__) || (defined(__GNUC__) && __GNUC__ >= 4 && defined (__GNUC_MINOR__) && __GNUC_MINOR__ >= 3)
56 # define SWAP_LE_BE32(val) ((uint32_t)__builtin_bswap32 ((uint32_t)(val)))
57 # define SWAP_LE_BE64(val) ((uint64_t)__builtin_bswap64 ((uint64_t)(val)))
58 #else
59 #define SWAP_LE_BE32(val) ((uint32_t)( \
60 (((uint32_t)(val) & (uint32_t)0x000000ffU) << 24) | \
61 (((uint32_t)(val) & (uint32_t)0x0000ff00U) << 8) | \
62 (((uint32_t)(val) & (uint32_t)0x00ff0000U) >> 8) | \
63 (((uint32_t)(val) & (uint32_t)0xff000000U) >> 24)))
64
65 #define SWAP_LE_BE64(val) ((uint64_t)( \
66 (((uint64_t)(val) & \
67 (uint64_t)(0x00000000000000ffULL)) << 56) | \
68 (((uint64_t)(val) & \
69 (uint64_t)(0x000000000000ff00ULL)) << 40) | \
70 (((uint64_t)(val) & \
71 (uint64_t)(0x0000000000ff0000ULL)) << 24) | \
72 (((uint64_t)(val) & \
73 (uint64_t) (0x00000000ff000000ULL)) << 8) | \
74 (((uint64_t)(val) & \
75 (uint64_t)(0x000000ff00000000ULL)) >> 8) | \
76 (((uint64_t)(val) & \
77 (uint64_t)(0x0000ff0000000000ULL)) >> 24) | \
78 (((uint64_t)(val) & \
79 (uint64_t)(0x00ff000000000000ULL)) >> 40) | \
80 (((uint64_t)(val) & \
81 (uint64_t)(0xff00000000000000ULL)) >> 56)))
82 #endif
83
84 #ifdef __LITTLE_ENDIAN__
85 #define TO_BE16 SWAP_LE_BE16
86 #define TO_BE32 SWAP_LE_BE32
87 #define TO_BE64 SWAP_LE_BE64
88 #define FROM_BE16 SWAP_LE_BE16
89 #define FROM_BE32 SWAP_LE_BE32
90 #define FROM_BE64 SWAP_LE_BE64
91 #else
92 #define TO_BE16(val) (uint16_t)(val)
93 #define TO_BE32(val) (uint32_t)(val)
94 #define TO_BE64(val) (uint64_t)(val)
95 #define FROM_BE16(val) (uint16_t)(val)
96 #define FROM_BE32(val) (uint32_t)(val)
97 #define FROM_BE64(val) (uint64_t)(val)
98 #endif
99
100 void
ucl_emitter_print_int_msgpack(struct ucl_emitter_context * ctx,int64_t val)101 ucl_emitter_print_int_msgpack (struct ucl_emitter_context *ctx, int64_t val)
102 {
103 const struct ucl_emitter_functions *func = ctx->func;
104 unsigned char buf[sizeof(uint64_t) + 1];
105 const unsigned char mask_positive = 0x7f, mask_negative = 0xe0,
106 uint8_ch = 0xcc, uint16_ch = 0xcd, uint32_ch = 0xce, uint64_ch = 0xcf,
107 int8_ch = 0xd0, int16_ch = 0xd1, int32_ch = 0xd2, int64_ch = 0xd3;
108 unsigned len;
109
110 if (val >= 0) {
111 if (val <= 0x7f) {
112 /* Fixed num 7 bits */
113 len = 1;
114 buf[0] = mask_positive & val;
115 }
116 else if (val <= UINT8_MAX) {
117 len = 2;
118 buf[0] = uint8_ch;
119 buf[1] = val & 0xff;
120 }
121 else if (val <= UINT16_MAX) {
122 uint16_t v = TO_BE16 (val);
123
124 len = 3;
125 buf[0] = uint16_ch;
126 memcpy (&buf[1], &v, sizeof (v));
127 }
128 else if (val <= UINT32_MAX) {
129 uint32_t v = TO_BE32 (val);
130
131 len = 5;
132 buf[0] = uint32_ch;
133 memcpy (&buf[1], &v, sizeof (v));
134 }
135 else {
136 uint64_t v = TO_BE64 (val);
137
138 len = 9;
139 buf[0] = uint64_ch;
140 memcpy (&buf[1], &v, sizeof (v));
141 }
142 }
143 else {
144 uint64_t uval;
145 /* Bithack abs */
146 uval = ((val ^ (val >> 63)) - (val >> 63));
147
148 if (val > -(1 << 5)) {
149 len = 1;
150 buf[0] = (mask_negative | uval) & 0xff;
151 }
152 else if (uval <= INT8_MAX) {
153 uint8_t v = (uint8_t)val;
154 len = 2;
155 buf[0] = int8_ch;
156 buf[1] = v;
157 }
158 else if (uval <= INT16_MAX) {
159 uint16_t v = TO_BE16 (val);
160
161 len = 3;
162 buf[0] = int16_ch;
163 memcpy (&buf[1], &v, sizeof (v));
164 }
165 else if (uval <= INT32_MAX) {
166 uint32_t v = TO_BE32 (val);
167
168 len = 5;
169 buf[0] = int32_ch;
170 memcpy (&buf[1], &v, sizeof (v));
171 }
172 else {
173 uint64_t v = TO_BE64 (val);
174
175 len = 9;
176 buf[0] = int64_ch;
177 memcpy (&buf[1], &v, sizeof (v));
178 }
179 }
180
181 func->ucl_emitter_append_len (buf, len, func->ud);
182 }
183
184 void
ucl_emitter_print_double_msgpack(struct ucl_emitter_context * ctx,double val)185 ucl_emitter_print_double_msgpack (struct ucl_emitter_context *ctx, double val)
186 {
187 const struct ucl_emitter_functions *func = ctx->func;
188 union {
189 double d;
190 uint64_t i;
191 } u;
192 const unsigned char dbl_ch = 0xcb;
193 unsigned char buf[sizeof(double) + 1];
194
195 /* Convert to big endian */
196 u.d = val;
197 u.i = TO_BE64 (u.i);
198
199 buf[0] = dbl_ch;
200 memcpy (&buf[1], &u.d, sizeof (double));
201 func->ucl_emitter_append_len (buf, sizeof (buf), func->ud);
202 }
203
204 void
ucl_emitter_print_bool_msgpack(struct ucl_emitter_context * ctx,bool val)205 ucl_emitter_print_bool_msgpack (struct ucl_emitter_context *ctx, bool val)
206 {
207 const struct ucl_emitter_functions *func = ctx->func;
208 const unsigned char true_ch = 0xc3, false_ch = 0xc2;
209
210 func->ucl_emitter_append_character (val ? true_ch : false_ch, 1, func->ud);
211 }
212
213 void
ucl_emitter_print_string_msgpack(struct ucl_emitter_context * ctx,const char * s,size_t len)214 ucl_emitter_print_string_msgpack (struct ucl_emitter_context *ctx,
215 const char *s, size_t len)
216 {
217 const struct ucl_emitter_functions *func = ctx->func;
218 const unsigned char fix_mask = 0xA0, l8_ch = 0xd9, l16_ch = 0xda, l32_ch = 0xdb;
219 unsigned char buf[5];
220 unsigned blen;
221
222 if (len <= 0x1F) {
223 blen = 1;
224 buf[0] = (len | fix_mask) & 0xff;
225 }
226 else if (len <= 0xff) {
227 blen = 2;
228 buf[0] = l8_ch;
229 buf[1] = len & 0xff;
230 }
231 else if (len <= 0xffff) {
232 uint16_t bl = TO_BE16 (len);
233
234 blen = 3;
235 buf[0] = l16_ch;
236 memcpy (&buf[1], &bl, sizeof (bl));
237 }
238 else {
239 uint32_t bl = TO_BE32 (len);
240
241 blen = 5;
242 buf[0] = l32_ch;
243 memcpy (&buf[1], &bl, sizeof (bl));
244 }
245
246 func->ucl_emitter_append_len (buf, blen, func->ud);
247 func->ucl_emitter_append_len (s, len, func->ud);
248 }
249
250 void
ucl_emitter_print_binary_string_msgpack(struct ucl_emitter_context * ctx,const char * s,size_t len)251 ucl_emitter_print_binary_string_msgpack (struct ucl_emitter_context *ctx,
252 const char *s, size_t len)
253 {
254 const struct ucl_emitter_functions *func = ctx->func;
255 const unsigned char l8_ch = 0xc4, l16_ch = 0xc5, l32_ch = 0xc6;
256 unsigned char buf[5];
257 unsigned blen;
258
259 if (len <= 0xff) {
260 blen = 2;
261 buf[0] = l8_ch;
262 buf[1] = len & 0xff;
263 }
264 else if (len <= 0xffff) {
265 uint16_t bl = TO_BE16 (len);
266
267 blen = 3;
268 buf[0] = l16_ch;
269 memcpy (&buf[1], &bl, sizeof (bl));
270 }
271 else {
272 uint32_t bl = TO_BE32 (len);
273
274 blen = 5;
275 buf[0] = l32_ch;
276 memcpy (&buf[1], &bl, sizeof (bl));
277 }
278
279 func->ucl_emitter_append_len (buf, blen, func->ud);
280 func->ucl_emitter_append_len (s, len, func->ud);
281 }
282
283 void
ucl_emitter_print_null_msgpack(struct ucl_emitter_context * ctx)284 ucl_emitter_print_null_msgpack (struct ucl_emitter_context *ctx)
285 {
286 const struct ucl_emitter_functions *func = ctx->func;
287 const unsigned char nil = 0xc0;
288
289 func->ucl_emitter_append_character (nil, 1, func->ud);
290 }
291
292 void
ucl_emitter_print_key_msgpack(bool print_key,struct ucl_emitter_context * ctx,const ucl_object_t * obj)293 ucl_emitter_print_key_msgpack (bool print_key, struct ucl_emitter_context *ctx,
294 const ucl_object_t *obj)
295 {
296 if (print_key) {
297 ucl_emitter_print_string_msgpack (ctx, obj->key, obj->keylen);
298 }
299 }
300
301 void
ucl_emitter_print_array_msgpack(struct ucl_emitter_context * ctx,size_t len)302 ucl_emitter_print_array_msgpack (struct ucl_emitter_context *ctx, size_t len)
303 {
304 const struct ucl_emitter_functions *func = ctx->func;
305 const unsigned char fix_mask = 0x90, l16_ch = 0xdc, l32_ch = 0xdd;
306 unsigned char buf[5];
307 unsigned blen;
308
309 if (len <= 0xF) {
310 blen = 1;
311 buf[0] = (len | fix_mask) & 0xff;
312 }
313 else if (len <= 0xffff) {
314 uint16_t bl = TO_BE16 (len);
315
316 blen = 3;
317 buf[0] = l16_ch;
318 memcpy (&buf[1], &bl, sizeof (bl));
319 }
320 else {
321 uint32_t bl = TO_BE32 (len);
322
323 blen = 5;
324 buf[0] = l32_ch;
325 memcpy (&buf[1], &bl, sizeof (bl));
326 }
327
328 func->ucl_emitter_append_len (buf, blen, func->ud);
329 }
330
331 void
ucl_emitter_print_object_msgpack(struct ucl_emitter_context * ctx,size_t len)332 ucl_emitter_print_object_msgpack (struct ucl_emitter_context *ctx, size_t len)
333 {
334 const struct ucl_emitter_functions *func = ctx->func;
335 const unsigned char fix_mask = 0x80, l16_ch = 0xde, l32_ch = 0xdf;
336 unsigned char buf[5];
337 unsigned blen;
338
339 if (len <= 0xF) {
340 blen = 1;
341 buf[0] = (len | fix_mask) & 0xff;
342 }
343 else if (len <= 0xffff) {
344 uint16_t bl = TO_BE16 (len);
345
346 blen = 3;
347 buf[0] = l16_ch;
348 memcpy (&buf[1], &bl, sizeof (bl));
349 }
350 else {
351 uint32_t bl = TO_BE32 (len);
352
353 blen = 5;
354 buf[0] = l32_ch;
355 memcpy (&buf[1], &bl, sizeof (bl));
356 }
357
358 func->ucl_emitter_append_len (buf, blen, func->ud);
359 }
360
361
362 enum ucl_msgpack_format {
363 msgpack_positive_fixint = 0,
364 msgpack_fixmap,
365 msgpack_fixarray,
366 msgpack_fixstr,
367 msgpack_nil,
368 msgpack_false,
369 msgpack_true,
370 msgpack_bin8,
371 msgpack_bin16,
372 msgpack_bin32,
373 msgpack_ext8,
374 msgpack_ext16,
375 msgpack_ext32,
376 msgpack_float32,
377 msgpack_float64,
378 msgpack_uint8,
379 msgpack_uint16,
380 msgpack_uint32,
381 msgpack_uint64,
382 msgpack_int8,
383 msgpack_int16,
384 msgpack_int32,
385 msgpack_int64,
386 msgpack_fixext1,
387 msgpack_fixext2,
388 msgpack_fixext4,
389 msgpack_fixext8,
390 msgpack_fixext16,
391 msgpack_str8,
392 msgpack_str16,
393 msgpack_str32,
394 msgpack_array16,
395 msgpack_array32,
396 msgpack_map16,
397 msgpack_map32,
398 msgpack_negative_fixint,
399 msgpack_invalid
400 };
401
402 typedef ssize_t (*ucl_msgpack_parse_function)(struct ucl_parser *parser,
403 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
404 const unsigned char *pos, size_t remain);
405
406 static ssize_t ucl_msgpack_parse_map (struct ucl_parser *parser,
407 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
408 const unsigned char *pos, size_t remain);
409 static ssize_t ucl_msgpack_parse_array (struct ucl_parser *parser,
410 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
411 const unsigned char *pos, size_t remain);
412 static ssize_t ucl_msgpack_parse_string (struct ucl_parser *parser,
413 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
414 const unsigned char *pos, size_t remain);
415 static ssize_t ucl_msgpack_parse_int (struct ucl_parser *parser,
416 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
417 const unsigned char *pos, size_t remain);
418 static ssize_t ucl_msgpack_parse_float (struct ucl_parser *parser,
419 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
420 const unsigned char *pos, size_t remain);
421 static ssize_t ucl_msgpack_parse_bool (struct ucl_parser *parser,
422 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
423 const unsigned char *pos, size_t remain);
424 static ssize_t ucl_msgpack_parse_null (struct ucl_parser *parser,
425 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
426 const unsigned char *pos, size_t remain);
427 static ssize_t ucl_msgpack_parse_ignore (struct ucl_parser *parser,
428 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
429 const unsigned char *pos, size_t remain);
430
431 #define MSGPACK_FLAG_FIXED (1 << 0)
432 #define MSGPACK_FLAG_CONTAINER (1 << 1)
433 #define MSGPACK_FLAG_TYPEVALUE (1 << 2)
434 #define MSGPACK_FLAG_EXT (1 << 3)
435 #define MSGPACK_FLAG_ASSOC (1 << 4)
436 #define MSGPACK_FLAG_KEY (1 << 5)
437 #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 *
ucl_msgpack_get_parser_from_type(unsigned char t)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 *
ucl_msgpack_get_container(struct ucl_parser * parser,struct ucl_msgpack_parser * obj_parser,uint64_t len)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
ucl_msgpack_is_container_finished(struct ucl_stack * container)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
ucl_msgpack_insert_object(struct ucl_parser * parser,const unsigned char * key,size_t keylen,ucl_object_t * obj)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 *
ucl_msgpack_get_next_container(struct ucl_parser * parser)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
ucl_msgpack_consume(struct ucl_parser * parser)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
ucl_parse_msgpack(struct ucl_parser * parser)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
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)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
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)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
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)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
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)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
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)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
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)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
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)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
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)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 }
1627