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 } 1627