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 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 * 745 ucl_msgpack_get_parser_from_type (unsigned char t) 746 { 747 unsigned int i, shift, mask; 748 749 for (i = 0; i < sizeof (parsers) / sizeof (parsers[0]); i ++) { 750 shift = CHAR_BIT - parsers[i].prefixlen; 751 mask = parsers[i].prefix >> shift; 752 753 if (mask == (((unsigned int)t) >> shift)) { 754 return &parsers[i]; 755 } 756 } 757 758 return NULL; 759 } 760 761 static inline struct ucl_stack * 762 ucl_msgpack_get_container (struct ucl_parser *parser, 763 struct ucl_msgpack_parser *obj_parser, uint64_t len) 764 { 765 struct ucl_stack *stack; 766 767 assert (obj_parser != NULL); 768 769 if (obj_parser->flags & MSGPACK_FLAG_CONTAINER) { 770 /* 771 * Insert new container to the stack 772 */ 773 if (parser->stack == NULL) { 774 parser->stack = calloc (1, sizeof (struct ucl_stack)); 775 776 if (parser->stack == NULL) { 777 ucl_create_err (&parser->err, "no memory"); 778 return NULL; 779 } 780 781 parser->stack->chunk = parser->chunks; 782 } 783 else { 784 stack = calloc (1, sizeof (struct ucl_stack)); 785 786 if (stack == NULL) { 787 ucl_create_err (&parser->err, "no memory"); 788 return NULL; 789 } 790 791 stack->chunk = parser->chunks; 792 stack->next = parser->stack; 793 parser->stack = stack; 794 } 795 796 parser->stack->e.len = len; 797 798 #ifdef MSGPACK_DEBUG_PARSER 799 stack = parser->stack; 800 while (stack) { 801 fprintf(stderr, "+"); 802 stack = stack->next; 803 } 804 805 fprintf(stderr, "%s -> %d\n", obj_parser->flags & MSGPACK_FLAG_ASSOC ? "object" : "array", (int)len); 806 #endif 807 } 808 else { 809 /* 810 * Get the current stack top 811 */ 812 if (parser->stack) { 813 return parser->stack; 814 } 815 else { 816 ucl_create_err (&parser->err, "bad top level object for msgpack"); 817 return NULL; 818 } 819 } 820 821 return parser->stack; 822 } 823 824 static bool 825 ucl_msgpack_is_container_finished (struct ucl_stack *container) 826 { 827 assert (container != NULL); 828 829 830 if (container->e.len == 0) { 831 return true; 832 } 833 834 return false; 835 } 836 837 static bool 838 ucl_msgpack_insert_object (struct ucl_parser *parser, 839 const unsigned char *key, 840 size_t keylen, ucl_object_t *obj) 841 { 842 struct ucl_stack *container; 843 844 container = parser->stack; 845 assert (container != NULL); 846 assert (container->e.len > 0); 847 assert (obj != NULL); 848 assert (container->obj != NULL); 849 850 if (container->obj->type == UCL_ARRAY) { 851 ucl_array_append (container->obj, obj); 852 } 853 else if (container->obj->type == UCL_OBJECT) { 854 if (key == NULL || keylen == 0) { 855 ucl_create_err (&parser->err, "cannot insert object with no key"); 856 return false; 857 } 858 859 obj->key = key; 860 obj->keylen = keylen; 861 862 if (!(parser->flags & UCL_PARSER_ZEROCOPY)) { 863 ucl_copy_key_trash (obj); 864 } 865 866 ucl_parser_process_object_element (parser, obj); 867 } 868 else { 869 ucl_create_err (&parser->err, "bad container type"); 870 return false; 871 } 872 873 container->e.len--; 874 875 return true; 876 } 877 878 static struct ucl_stack * 879 ucl_msgpack_get_next_container (struct ucl_parser *parser) 880 { 881 struct ucl_stack *cur = NULL; 882 uint64_t len; 883 884 cur = parser->stack; 885 886 if (cur == NULL) { 887 return NULL; 888 } 889 890 len = cur->e.len; 891 892 if (len == 0) { 893 /* We need to switch to the previous container */ 894 parser->stack = cur->next; 895 parser->cur_obj = cur->obj; 896 free (cur); 897 898 #ifdef MSGPACK_DEBUG_PARSER 899 cur = parser->stack; 900 while (cur) { 901 fprintf(stderr, "-"); 902 cur = cur->next; 903 } 904 fprintf(stderr, "-%s -> %d\n", parser->cur_obj->type == UCL_OBJECT ? "object" : "array", (int)parser->cur_obj->len); 905 #endif 906 907 return ucl_msgpack_get_next_container (parser); 908 } 909 910 /* 911 * For UCL containers we don't know length, so we just insert the whole 912 * message pack blob into the top level container 913 */ 914 915 assert (cur->obj != NULL); 916 917 return cur; 918 } 919 920 #define CONSUME_RET do { \ 921 if (ret != -1) { \ 922 p += ret; \ 923 remain -= ret; \ 924 obj_parser = NULL; \ 925 assert (remain >= 0); \ 926 } \ 927 else { \ 928 ucl_create_err (&parser->err, \ 929 "cannot parse type %d of len %u", \ 930 (int)obj_parser->fmt, \ 931 (unsigned)len); \ 932 return false; \ 933 } \ 934 } while(0) 935 936 #define GET_NEXT_STATE do { \ 937 container = ucl_msgpack_get_next_container (parser); \ 938 if (container == NULL) { \ 939 ucl_create_err (&parser->err, \ 940 "empty container"); \ 941 return false; \ 942 } \ 943 next_state = container->obj->type == UCL_OBJECT ? \ 944 read_assoc_key : read_array_value; \ 945 } while(0) 946 947 static bool 948 ucl_msgpack_consume (struct ucl_parser *parser) 949 { 950 const unsigned char *p, *end, *key = NULL; 951 struct ucl_stack *container; 952 enum e_msgpack_parser_state { 953 read_type, 954 start_assoc, 955 start_array, 956 read_assoc_key, 957 read_assoc_value, 958 finish_assoc_value, 959 read_array_value, 960 finish_array_value, 961 error_state 962 } state = read_type, next_state = error_state; 963 struct ucl_msgpack_parser *obj_parser = NULL; 964 uint64_t len = 0; 965 ssize_t ret, remain, keylen = 0; 966 #ifdef MSGPACK_DEBUG_PARSER 967 uint64_t i; 968 enum e_msgpack_parser_state hist[256]; 969 #endif 970 971 p = parser->chunks->begin; 972 remain = parser->chunks->remain; 973 end = p + remain; 974 975 976 while (p < end) { 977 #ifdef MSGPACK_DEBUG_PARSER 978 hist[i++ % 256] = state; 979 #endif 980 switch (state) { 981 case read_type: 982 obj_parser = ucl_msgpack_get_parser_from_type (*p); 983 984 if (obj_parser == NULL) { 985 ucl_create_err (&parser->err, "unknown msgpack format: %x", 986 (unsigned int)*p); 987 988 return false; 989 } 990 /* Now check length sanity */ 991 if (obj_parser->flags & MSGPACK_FLAG_FIXED) { 992 if (obj_parser->len == 0) { 993 /* We have an embedded size */ 994 len = *p & ~obj_parser->prefix; 995 } 996 else { 997 if (remain < obj_parser->len) { 998 ucl_create_err (&parser->err, "not enough data remain to " 999 "read object's length: %u remain, %u needed", 1000 (unsigned)remain, obj_parser->len); 1001 1002 return false; 1003 } 1004 1005 len = obj_parser->len; 1006 } 1007 1008 if (!(obj_parser->flags & MSGPACK_FLAG_TYPEVALUE)) { 1009 /* We must pass value as the second byte */ 1010 if (remain > 0) { 1011 p ++; 1012 remain --; 1013 } 1014 } 1015 else { 1016 /* Len is irrelevant now */ 1017 len = 0; 1018 } 1019 } 1020 else { 1021 /* Length is not embedded */ 1022 remain --; 1023 1024 if (remain < obj_parser->len) { 1025 ucl_create_err (&parser->err, "not enough data remain to " 1026 "read object's length: %u remain, %u needed", 1027 (unsigned)remain, obj_parser->len); 1028 1029 return false; 1030 } 1031 1032 p ++; 1033 1034 switch (obj_parser->len) { 1035 case 1: 1036 len = *p; 1037 break; 1038 case 2: 1039 len = FROM_BE16 (*(uint16_t *)p); 1040 break; 1041 case 4: 1042 len = FROM_BE32 (*(uint32_t *)p); 1043 break; 1044 case 8: 1045 len = FROM_BE64 (*(uint64_t *)p); 1046 break; 1047 default: 1048 ucl_create_err (&parser->err, "invalid length of the length field: %u", 1049 (unsigned)obj_parser->len); 1050 1051 return false; 1052 } 1053 1054 p += obj_parser->len; 1055 remain -= obj_parser->len; 1056 } 1057 1058 if (obj_parser->flags & MSGPACK_FLAG_ASSOC) { 1059 /* We have just read the new associative map */ 1060 state = start_assoc; 1061 } 1062 else if (obj_parser->flags & MSGPACK_FLAG_CONTAINER){ 1063 state = start_array; 1064 } 1065 else { 1066 state = next_state; 1067 } 1068 1069 break; 1070 case start_assoc: 1071 parser->cur_obj = ucl_object_new_full (UCL_OBJECT, 1072 parser->chunks->priority); 1073 /* Insert to the previous level container */ 1074 if (parser->stack && !ucl_msgpack_insert_object (parser, 1075 key, keylen, parser->cur_obj)) { 1076 return false; 1077 } 1078 /* Get new container */ 1079 container = ucl_msgpack_get_container (parser, obj_parser, len); 1080 1081 if (container == NULL) { 1082 return false; 1083 } 1084 1085 ret = obj_parser->func (parser, container, len, obj_parser->fmt, 1086 p, remain); 1087 CONSUME_RET; 1088 key = NULL; 1089 keylen = 0; 1090 1091 if (len > 0) { 1092 state = read_type; 1093 next_state = read_assoc_key; 1094 } 1095 else { 1096 /* Empty object */ 1097 state = finish_assoc_value; 1098 } 1099 break; 1100 1101 case start_array: 1102 parser->cur_obj = ucl_object_new_full (UCL_ARRAY, 1103 parser->chunks->priority); 1104 /* Insert to the previous level container */ 1105 if (parser->stack && !ucl_msgpack_insert_object (parser, 1106 key, keylen, parser->cur_obj)) { 1107 return false; 1108 } 1109 /* Get new container */ 1110 container = ucl_msgpack_get_container (parser, obj_parser, len); 1111 1112 if (container == NULL) { 1113 return false; 1114 } 1115 1116 ret = obj_parser->func (parser, container, len, obj_parser->fmt, 1117 p, remain); 1118 CONSUME_RET; 1119 1120 if (len > 0) { 1121 state = read_type; 1122 next_state = read_array_value; 1123 } 1124 else { 1125 /* Empty array */ 1126 state = finish_array_value; 1127 } 1128 break; 1129 1130 case read_array_value: 1131 /* 1132 * p is now at the value start, len now contains length read and 1133 * obj_parser contains the corresponding specific parser 1134 */ 1135 container = parser->stack; 1136 1137 if (parser->stack == NULL) { 1138 ucl_create_err (&parser->err, 1139 "read assoc value when no container represented"); 1140 return false; 1141 } 1142 1143 ret = obj_parser->func (parser, container, len, obj_parser->fmt, 1144 p, remain); 1145 CONSUME_RET; 1146 1147 1148 /* Insert value to the container and check if we have finished array */ 1149 if (!ucl_msgpack_insert_object (parser, NULL, 0, 1150 parser->cur_obj)) { 1151 return false; 1152 } 1153 1154 if (ucl_msgpack_is_container_finished (container)) { 1155 state = finish_array_value; 1156 } 1157 else { 1158 /* Read more elements */ 1159 state = read_type; 1160 next_state = read_array_value; 1161 } 1162 1163 break; 1164 1165 case read_assoc_key: 1166 /* 1167 * Keys must have string type for ucl msgpack 1168 */ 1169 if (!(obj_parser->flags & MSGPACK_FLAG_KEY)) { 1170 ucl_create_err (&parser->err, "bad type for key: %u, expected " 1171 "string", (unsigned)obj_parser->fmt); 1172 1173 return false; 1174 } 1175 1176 key = p; 1177 keylen = len; 1178 1179 if (keylen > remain || keylen == 0) { 1180 ucl_create_err (&parser->err, "too long or empty key"); 1181 return false; 1182 } 1183 1184 p += len; 1185 remain -= len; 1186 1187 state = read_type; 1188 next_state = read_assoc_value; 1189 break; 1190 1191 case read_assoc_value: 1192 /* 1193 * p is now at the value start, len now contains length read and 1194 * obj_parser contains the corresponding specific parser 1195 */ 1196 container = parser->stack; 1197 1198 if (container == NULL) { 1199 ucl_create_err (&parser->err, 1200 "read assoc value when no container represented"); 1201 return false; 1202 } 1203 1204 ret = obj_parser->func (parser, container, len, obj_parser->fmt, 1205 p, remain); 1206 CONSUME_RET; 1207 1208 assert (key != NULL && keylen > 0); 1209 1210 if (!ucl_msgpack_insert_object (parser, key, keylen, 1211 parser->cur_obj)) { 1212 1213 return false; 1214 } 1215 1216 key = NULL; 1217 keylen = 0; 1218 1219 if (ucl_msgpack_is_container_finished (container)) { 1220 state = finish_assoc_value; 1221 } 1222 else { 1223 /* Read more elements */ 1224 state = read_type; 1225 next_state = read_assoc_key; 1226 } 1227 break; 1228 1229 case finish_array_value: 1230 case finish_assoc_value: 1231 GET_NEXT_STATE; 1232 state = read_type; 1233 break; 1234 1235 case error_state: 1236 ucl_create_err (&parser->err, "invalid state machine state"); 1237 1238 return false; 1239 } 1240 } 1241 1242 /* Check the finishing state */ 1243 switch (state) { 1244 case start_array: 1245 case start_assoc: 1246 /* Empty container at the end */ 1247 if (len != 0) { 1248 ucl_create_err (&parser->err, 1249 "invalid non-empty container at the end; len=%zu", 1250 (size_t)len); 1251 1252 return false; 1253 } 1254 1255 parser->cur_obj = ucl_object_new_full ( 1256 state == start_array ? UCL_ARRAY : UCL_OBJECT, 1257 parser->chunks->priority); 1258 1259 if (parser->stack == NULL) { 1260 ucl_create_err (&parser->err, 1261 "read assoc value when no container represented"); 1262 return false; 1263 } 1264 /* Insert to the previous level container */ 1265 if (!ucl_msgpack_insert_object (parser, 1266 key, keylen, parser->cur_obj)) { 1267 return false; 1268 } 1269 /* Get new container */ 1270 container = ucl_msgpack_get_container (parser, obj_parser, len); 1271 1272 if (container == NULL) { 1273 return false; 1274 } 1275 1276 ret = obj_parser->func (parser, container, len, obj_parser->fmt, 1277 p, remain); 1278 break; 1279 1280 case read_array_value: 1281 case read_assoc_value: 1282 if (len != 0) { 1283 ucl_create_err (&parser->err, "unfinished value at the end"); 1284 1285 return false; 1286 } 1287 1288 container = parser->stack; 1289 1290 if (parser->stack == NULL) { 1291 ucl_create_err (&parser->err, 1292 "read assoc value when no container represented"); 1293 return false; 1294 } 1295 1296 ret = obj_parser->func (parser, container, len, obj_parser->fmt, 1297 p, remain); 1298 CONSUME_RET; 1299 1300 1301 /* Insert value to the container and check if we have finished array */ 1302 if (!ucl_msgpack_insert_object (parser, NULL, 0, 1303 parser->cur_obj)) { 1304 return false; 1305 } 1306 break; 1307 case finish_array_value: 1308 case finish_assoc_value: 1309 case read_type: 1310 /* Valid finishing state */ 1311 break; 1312 default: 1313 /* Invalid finishing state */ 1314 ucl_create_err (&parser->err, "invalid state machine finishing state: %d", 1315 state); 1316 1317 return false; 1318 } 1319 1320 /* Rewind to the top level container */ 1321 ucl_msgpack_get_next_container (parser); 1322 1323 if (parser->stack != NULL) { 1324 ucl_create_err (&parser->err, "incomplete container"); 1325 1326 return false; 1327 } 1328 1329 return true; 1330 } 1331 1332 bool 1333 ucl_parse_msgpack (struct ucl_parser *parser) 1334 { 1335 ucl_object_t *container = NULL; 1336 const unsigned char *p; 1337 bool ret; 1338 1339 assert (parser != NULL); 1340 assert (parser->chunks != NULL); 1341 assert (parser->chunks->begin != NULL); 1342 assert (parser->chunks->remain != 0); 1343 1344 p = parser->chunks->begin; 1345 1346 if (parser->stack) { 1347 container = parser->stack->obj; 1348 } 1349 1350 /* 1351 * When we start parsing message pack chunk, we must ensure that we 1352 * have either a valid container or the top object inside message pack is 1353 * of container type 1354 */ 1355 if (container == NULL) { 1356 if ((*p & 0x80) != 0x80 && !(*p >= 0xdc && *p <= 0xdf)) { 1357 ucl_create_err (&parser->err, "bad top level object for msgpack"); 1358 return false; 1359 } 1360 } 1361 1362 ret = ucl_msgpack_consume (parser); 1363 1364 if (ret && parser->top_obj == NULL) { 1365 parser->top_obj = parser->cur_obj; 1366 } 1367 1368 return ret; 1369 } 1370 1371 static ssize_t 1372 ucl_msgpack_parse_map (struct ucl_parser *parser, 1373 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, 1374 const unsigned char *pos, size_t remain) 1375 { 1376 container->obj = parser->cur_obj; 1377 1378 return 0; 1379 } 1380 1381 static ssize_t 1382 ucl_msgpack_parse_array (struct ucl_parser *parser, 1383 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, 1384 const unsigned char *pos, size_t remain) 1385 { 1386 container->obj = parser->cur_obj; 1387 1388 return 0; 1389 } 1390 1391 static ssize_t 1392 ucl_msgpack_parse_string (struct ucl_parser *parser, 1393 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, 1394 const unsigned char *pos, size_t remain) 1395 { 1396 ucl_object_t *obj; 1397 1398 if (len > remain) { 1399 return -1; 1400 } 1401 1402 obj = ucl_object_new_full (UCL_STRING, parser->chunks->priority); 1403 obj->value.sv = pos; 1404 obj->len = len; 1405 1406 if (fmt >= msgpack_bin8 && fmt <= msgpack_bin32) { 1407 obj->flags |= UCL_OBJECT_BINARY; 1408 } 1409 1410 if (!(parser->flags & UCL_PARSER_ZEROCOPY)) { 1411 if (obj->flags & UCL_OBJECT_BINARY) { 1412 obj->trash_stack[UCL_TRASH_VALUE] = malloc (len); 1413 1414 if (obj->trash_stack[UCL_TRASH_VALUE] != NULL) { 1415 memcpy (obj->trash_stack[UCL_TRASH_VALUE], pos, len); 1416 } 1417 } 1418 else { 1419 ucl_copy_value_trash (obj); 1420 } 1421 } 1422 1423 parser->cur_obj = obj; 1424 1425 return len; 1426 } 1427 1428 static ssize_t 1429 ucl_msgpack_parse_int (struct ucl_parser *parser, 1430 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, 1431 const unsigned char *pos, size_t remain) 1432 { 1433 ucl_object_t *obj; 1434 int8_t iv8; 1435 int16_t iv16; 1436 int32_t iv32; 1437 int64_t iv64; 1438 uint16_t uiv16; 1439 uint32_t uiv32; 1440 uint64_t uiv64; 1441 1442 1443 if (len > remain) { 1444 return -1; 1445 } 1446 1447 obj = ucl_object_new_full (UCL_INT, parser->chunks->priority); 1448 1449 switch (fmt) { 1450 case msgpack_positive_fixint: 1451 obj->value.iv = (*pos & 0x7f); 1452 len = 1; 1453 break; 1454 case msgpack_negative_fixint: 1455 obj->value.iv = - (*pos & 0x1f); 1456 len = 1; 1457 break; 1458 case msgpack_uint8: 1459 obj->value.iv = (unsigned char)*pos; 1460 len = 1; 1461 break; 1462 case msgpack_int8: 1463 memcpy (&iv8, pos, sizeof (iv8)); 1464 obj->value.iv = iv8; 1465 len = 1; 1466 break; 1467 case msgpack_int16: 1468 memcpy (&iv16, pos, sizeof (iv16)); 1469 iv16 = FROM_BE16 (iv16); 1470 obj->value.iv = iv16; 1471 len = 2; 1472 break; 1473 case msgpack_uint16: 1474 memcpy (&uiv16, pos, sizeof (uiv16)); 1475 uiv16 = FROM_BE16 (uiv16); 1476 obj->value.iv = uiv16; 1477 len = 2; 1478 break; 1479 case msgpack_int32: 1480 memcpy (&iv32, pos, sizeof (iv32)); 1481 iv32 = FROM_BE32 (iv32); 1482 obj->value.iv = iv32; 1483 len = 4; 1484 break; 1485 case msgpack_uint32: 1486 memcpy(&uiv32, pos, sizeof(uiv32)); 1487 uiv32 = FROM_BE32(uiv32); 1488 obj->value.iv = uiv32; 1489 len = 4; 1490 break; 1491 case msgpack_int64: 1492 memcpy (&iv64, pos, sizeof (iv64)); 1493 iv64 = FROM_BE64 (iv64); 1494 obj->value.iv = iv64; 1495 len = 8; 1496 break; 1497 case msgpack_uint64: 1498 memcpy(&uiv64, pos, sizeof(uiv64)); 1499 uiv64 = FROM_BE64(uiv64); 1500 obj->value.iv = uiv64; 1501 len = 8; 1502 break; 1503 default: 1504 assert (0); 1505 break; 1506 } 1507 1508 parser->cur_obj = obj; 1509 1510 return len; 1511 } 1512 1513 static ssize_t 1514 ucl_msgpack_parse_float (struct ucl_parser *parser, 1515 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, 1516 const unsigned char *pos, size_t remain) 1517 { 1518 ucl_object_t *obj; 1519 union { 1520 uint32_t i; 1521 float f; 1522 } d; 1523 uint64_t uiv64; 1524 1525 if (len > remain) { 1526 return -1; 1527 } 1528 1529 obj = ucl_object_new_full (UCL_FLOAT, parser->chunks->priority); 1530 1531 switch (fmt) { 1532 case msgpack_float32: 1533 memcpy(&d.i, pos, sizeof(d.i)); 1534 d.i = FROM_BE32(d.i); 1535 /* XXX: can be slow */ 1536 obj->value.dv = d.f; 1537 len = 4; 1538 break; 1539 case msgpack_float64: 1540 memcpy(&uiv64, pos, sizeof(uiv64)); 1541 uiv64 = FROM_BE64(uiv64); 1542 obj->value.iv = uiv64; 1543 len = 8; 1544 break; 1545 default: 1546 assert (0); 1547 break; 1548 } 1549 1550 parser->cur_obj = obj; 1551 1552 return len; 1553 } 1554 1555 static ssize_t 1556 ucl_msgpack_parse_bool (struct ucl_parser *parser, 1557 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, 1558 const unsigned char *pos, size_t remain) 1559 { 1560 ucl_object_t *obj; 1561 1562 if (len > remain) { 1563 return -1; 1564 } 1565 1566 obj = ucl_object_new_full (UCL_BOOLEAN, parser->chunks->priority); 1567 1568 switch (fmt) { 1569 case msgpack_true: 1570 obj->value.iv = true; 1571 break; 1572 case msgpack_false: 1573 obj->value.iv = false; 1574 break; 1575 default: 1576 assert (0); 1577 break; 1578 } 1579 1580 parser->cur_obj = obj; 1581 1582 return 1; 1583 } 1584 1585 static ssize_t 1586 ucl_msgpack_parse_null (struct ucl_parser *parser, 1587 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, 1588 const unsigned char *pos, size_t remain) 1589 { 1590 ucl_object_t *obj; 1591 1592 if (len > remain) { 1593 return -1; 1594 } 1595 1596 obj = ucl_object_new_full (UCL_NULL, parser->chunks->priority); 1597 parser->cur_obj = obj; 1598 1599 return 1; 1600 } 1601 1602 static ssize_t 1603 ucl_msgpack_parse_ignore (struct ucl_parser *parser, 1604 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, 1605 const unsigned char *pos, size_t remain) 1606 { 1607 if (len > remain) { 1608 return -1; 1609 } 1610 1611 switch (fmt) { 1612 case msgpack_fixext1: 1613 len = 2; 1614 break; 1615 case msgpack_fixext2: 1616 len = 3; 1617 break; 1618 case msgpack_fixext4: 1619 len = 5; 1620 break; 1621 case msgpack_fixext8: 1622 len = 9; 1623 break; 1624 case msgpack_fixext16: 1625 len = 17; 1626 break; 1627 case msgpack_ext8: 1628 case msgpack_ext16: 1629 case msgpack_ext32: 1630 len = len + 1; 1631 break; 1632 default: 1633 ucl_create_err (&parser->err, "bad type: %x", (unsigned)fmt); 1634 return -1; 1635 } 1636 1637 return len; 1638 } 1639