1290067Sbapt/* 2290067Sbapt * Copyright (c) 2015, Vsevolod Stakhov 3290067Sbapt * All rights reserved. 4290067Sbapt * 5290067Sbapt * Redistribution and use in source and binary forms, with or without 6290067Sbapt * modification, are permitted provided that the following conditions are met: 7290067Sbapt * * Redistributions of source code must retain the above copyright 8290067Sbapt * notice, this list of conditions and the following disclaimer. 9290067Sbapt * * Redistributions in binary form must reproduce the above copyright 10290067Sbapt * notice, this list of conditions and the following disclaimer in the 11290067Sbapt * documentation and/or other materials provided with the distribution. 12290067Sbapt * 13290067Sbapt * THIS SOFTWARE IS PROVIDED BY AUTHOR ''AS IS'' AND ANY 14290067Sbapt * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15290067Sbapt * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16290067Sbapt * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY 17290067Sbapt * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18290067Sbapt * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19290067Sbapt * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 20290067Sbapt * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21290067Sbapt * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 22290067Sbapt * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23290067Sbapt */ 24290067Sbapt 25290067Sbapt 26290067Sbapt#ifdef HAVE_CONFIG_H 27290067Sbapt#include "config.h" 28290067Sbapt#endif 29290067Sbapt 30290067Sbapt#include "ucl.h" 31290067Sbapt#include "ucl_internal.h" 32290067Sbapt 33290067Sbapt#ifdef HAVE_ENDIAN_H 34290067Sbapt#include <endian.h> 35290067Sbapt#elif defined(HAVE_SYS_ENDIAN_H) 36290067Sbapt#include <sys/endian.h> 37290067Sbapt#elif defined(HAVE_MACHINE_ENDIAN_H) 38290067Sbapt#include <machine/endian.h> 39290067Sbapt#endif 40290067Sbapt 41290067Sbapt#if !defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__) 42290067Sbapt #if __BYTE_ORDER == __LITTLE_ENDIAN 43290067Sbapt #define __LITTLE_ENDIAN__ 44290067Sbapt #elif __BYTE_ORDER == __BIG_ENDIAN 45290067Sbapt #define __BIG_ENDIAN__ 46290067Sbapt #elif _WIN32 47290067Sbapt #define __LITTLE_ENDIAN__ 48290067Sbapt #endif 49290067Sbapt#endif 50290067Sbapt 51290067Sbapt#define SWAP_LE_BE16(val) ((uint16_t) ( \ 52290067Sbapt (uint16_t) ((uint16_t) (val) >> 8) | \ 53290067Sbapt (uint16_t) ((uint16_t) (val) << 8))) 54290067Sbapt 55290067Sbapt#if defined(__clang__) || (defined(__GNUC__) && __GNUC__ >= 4 && defined (__GNUC_MINOR__) && __GNUC_MINOR__ >= 3) 56290067Sbapt# define SWAP_LE_BE32(val) ((uint32_t)__builtin_bswap32 ((uint32_t)(val))) 57290067Sbapt# define SWAP_LE_BE64(val) ((uint64_t)__builtin_bswap64 ((uint64_t)(val))) 58290067Sbapt#else 59290067Sbapt #define SWAP_LE_BE32(val) ((uint32_t)( \ 60290067Sbapt (((uint32_t)(val) & (uint32_t)0x000000ffU) << 24) | \ 61290067Sbapt (((uint32_t)(val) & (uint32_t)0x0000ff00U) << 8) | \ 62290067Sbapt (((uint32_t)(val) & (uint32_t)0x00ff0000U) >> 8) | \ 63290067Sbapt (((uint32_t)(val) & (uint32_t)0xff000000U) >> 24))) 64290067Sbapt 65290067Sbapt #define SWAP_LE_BE64(val) ((uint64_t)( \ 66290067Sbapt (((uint64_t)(val) & \ 67290067Sbapt (uint64_t)(0x00000000000000ffULL)) << 56) | \ 68290067Sbapt (((uint64_t)(val) & \ 69290067Sbapt (uint64_t)(0x000000000000ff00ULL)) << 40) | \ 70290067Sbapt (((uint64_t)(val) & \ 71290067Sbapt (uint64_t)(0x0000000000ff0000ULL)) << 24) | \ 72290067Sbapt (((uint64_t)(val) & \ 73290067Sbapt (uint64_t) (0x00000000ff000000ULL)) << 8) | \ 74290067Sbapt (((uint64_t)(val) & \ 75290067Sbapt (uint64_t)(0x000000ff00000000ULL)) >> 8) | \ 76290067Sbapt (((uint64_t)(val) & \ 77290067Sbapt (uint64_t)(0x0000ff0000000000ULL)) >> 24) | \ 78290067Sbapt (((uint64_t)(val) & \ 79290067Sbapt (uint64_t)(0x00ff000000000000ULL)) >> 40) | \ 80290067Sbapt (((uint64_t)(val) & \ 81290067Sbapt (uint64_t)(0xff00000000000000ULL)) >> 56))) 82290067Sbapt#endif 83290067Sbapt 84290067Sbapt#ifdef __LITTLE_ENDIAN__ 85290067Sbapt#define TO_BE16 SWAP_LE_BE16 86290067Sbapt#define TO_BE32 SWAP_LE_BE32 87290067Sbapt#define TO_BE64 SWAP_LE_BE64 88290067Sbapt#define FROM_BE16 SWAP_LE_BE16 89290067Sbapt#define FROM_BE32 SWAP_LE_BE32 90290067Sbapt#define FROM_BE64 SWAP_LE_BE64 91290067Sbapt#else 92290067Sbapt#define TO_BE16(val) (uint16_t)(val) 93290067Sbapt#define TO_BE32(val) (uint32_t)(val) 94290067Sbapt#define TO_BE64(val) (uint64_t)(val) 95290067Sbapt#define FROM_BE16(val) (uint16_t)(val) 96290067Sbapt#define FROM_BE32(val) (uint32_t)(val) 97290067Sbapt#define FROM_BE64(val) (uint64_t)(val) 98290067Sbapt#endif 99290067Sbapt 100290067Sbaptvoid 101290067Sbaptucl_emitter_print_int_msgpack (struct ucl_emitter_context *ctx, int64_t val) 102290067Sbapt{ 103290067Sbapt const struct ucl_emitter_functions *func = ctx->func; 104290067Sbapt unsigned char buf[sizeof(uint64_t) + 1]; 105290067Sbapt const unsigned char mask_positive = 0x7f, mask_negative = 0xe0, 106290067Sbapt uint8_ch = 0xcc, uint16_ch = 0xcd, uint32_ch = 0xce, uint64_ch = 0xcf, 107290067Sbapt int8_ch = 0xd0, int16_ch = 0xd1, int32_ch = 0xd2, int64_ch = 0xd3; 108290067Sbapt unsigned len; 109290067Sbapt 110290067Sbapt if (val >= 0) { 111290067Sbapt if (val <= 0x7f) { 112290067Sbapt /* Fixed num 7 bits */ 113290067Sbapt len = 1; 114290067Sbapt buf[0] = mask_positive & val; 115290067Sbapt } 116298166Sbapt else if (val <= UINT8_MAX) { 117290067Sbapt len = 2; 118290067Sbapt buf[0] = uint8_ch; 119290067Sbapt buf[1] = val & 0xff; 120290067Sbapt } 121298166Sbapt else if (val <= UINT16_MAX) { 122290067Sbapt uint16_t v = TO_BE16 (val); 123290067Sbapt 124290067Sbapt len = 3; 125290067Sbapt buf[0] = uint16_ch; 126290067Sbapt memcpy (&buf[1], &v, sizeof (v)); 127290067Sbapt } 128298166Sbapt else if (val <= UINT32_MAX) { 129290067Sbapt uint32_t v = TO_BE32 (val); 130290067Sbapt 131290067Sbapt len = 5; 132290067Sbapt buf[0] = uint32_ch; 133290067Sbapt memcpy (&buf[1], &v, sizeof (v)); 134290067Sbapt } 135290067Sbapt else { 136290067Sbapt uint64_t v = TO_BE64 (val); 137290067Sbapt 138290067Sbapt len = 9; 139290067Sbapt buf[0] = uint64_ch; 140290067Sbapt memcpy (&buf[1], &v, sizeof (v)); 141290067Sbapt } 142290067Sbapt } 143290067Sbapt else { 144290067Sbapt uint64_t uval; 145290067Sbapt /* Bithack abs */ 146290067Sbapt uval = ((val ^ (val >> 63)) - (val >> 63)); 147290067Sbapt 148290067Sbapt if (val > -(1 << 5)) { 149290067Sbapt len = 1; 150290067Sbapt buf[0] = (mask_negative | uval) & 0xff; 151290067Sbapt } 152298166Sbapt else if (uval <= INT8_MAX) { 153298166Sbapt uint8_t v = (uint8_t)val; 154290067Sbapt len = 2; 155290067Sbapt buf[0] = int8_ch; 156298166Sbapt buf[1] = v; 157290067Sbapt } 158298166Sbapt else if (uval <= INT16_MAX) { 159290067Sbapt uint16_t v = TO_BE16 (val); 160290067Sbapt 161290067Sbapt len = 3; 162290067Sbapt buf[0] = int16_ch; 163290067Sbapt memcpy (&buf[1], &v, sizeof (v)); 164290067Sbapt } 165298166Sbapt else if (uval <= INT32_MAX) { 166290067Sbapt uint32_t v = TO_BE32 (val); 167290067Sbapt 168290067Sbapt len = 5; 169290067Sbapt buf[0] = int32_ch; 170290067Sbapt memcpy (&buf[1], &v, sizeof (v)); 171290067Sbapt } 172290067Sbapt else { 173290067Sbapt uint64_t v = TO_BE64 (val); 174290067Sbapt 175290067Sbapt len = 9; 176290067Sbapt buf[0] = int64_ch; 177290067Sbapt memcpy (&buf[1], &v, sizeof (v)); 178290067Sbapt } 179290067Sbapt } 180290067Sbapt 181290067Sbapt func->ucl_emitter_append_len (buf, len, func->ud); 182290067Sbapt} 183290067Sbapt 184290067Sbaptvoid 185290067Sbaptucl_emitter_print_double_msgpack (struct ucl_emitter_context *ctx, double val) 186290067Sbapt{ 187290067Sbapt const struct ucl_emitter_functions *func = ctx->func; 188290067Sbapt union { 189290067Sbapt double d; 190290067Sbapt uint64_t i; 191290067Sbapt } u; 192290067Sbapt const unsigned char dbl_ch = 0xcb; 193290067Sbapt unsigned char buf[sizeof(double) + 1]; 194290067Sbapt 195290067Sbapt /* Convert to big endian */ 196290067Sbapt u.d = val; 197290067Sbapt u.i = TO_BE64 (u.i); 198290067Sbapt 199290067Sbapt buf[0] = dbl_ch; 200290067Sbapt memcpy (&buf[1], &u.d, sizeof (double)); 201290067Sbapt func->ucl_emitter_append_len (buf, sizeof (buf), func->ud); 202290067Sbapt} 203290067Sbapt 204290067Sbaptvoid 205290067Sbaptucl_emitter_print_bool_msgpack (struct ucl_emitter_context *ctx, bool val) 206290067Sbapt{ 207290067Sbapt const struct ucl_emitter_functions *func = ctx->func; 208290067Sbapt const unsigned char true_ch = 0xc3, false_ch = 0xc2; 209290067Sbapt 210290067Sbapt func->ucl_emitter_append_character (val ? true_ch : false_ch, 1, func->ud); 211290067Sbapt} 212290067Sbapt 213290067Sbaptvoid 214290067Sbaptucl_emitter_print_string_msgpack (struct ucl_emitter_context *ctx, 215290067Sbapt const char *s, size_t len) 216290067Sbapt{ 217290067Sbapt const struct ucl_emitter_functions *func = ctx->func; 218290067Sbapt const unsigned char fix_mask = 0xA0, l8_ch = 0xd9, l16_ch = 0xda, l32_ch = 0xdb; 219290067Sbapt unsigned char buf[5]; 220290067Sbapt unsigned blen; 221290067Sbapt 222290067Sbapt if (len <= 0x1F) { 223290067Sbapt blen = 1; 224290067Sbapt buf[0] = (len | fix_mask) & 0xff; 225290067Sbapt } 226290067Sbapt else if (len <= 0xff) { 227290067Sbapt blen = 2; 228290067Sbapt buf[0] = l8_ch; 229290067Sbapt buf[1] = len & 0xff; 230290067Sbapt } 231290067Sbapt else if (len <= 0xffff) { 232290067Sbapt uint16_t bl = TO_BE16 (len); 233290067Sbapt 234290067Sbapt blen = 3; 235290067Sbapt buf[0] = l16_ch; 236290067Sbapt memcpy (&buf[1], &bl, sizeof (bl)); 237290067Sbapt } 238290067Sbapt else { 239290067Sbapt uint32_t bl = TO_BE32 (len); 240290067Sbapt 241290067Sbapt blen = 5; 242290067Sbapt buf[0] = l32_ch; 243290067Sbapt memcpy (&buf[1], &bl, sizeof (bl)); 244290067Sbapt } 245290067Sbapt 246290067Sbapt func->ucl_emitter_append_len (buf, blen, func->ud); 247290067Sbapt func->ucl_emitter_append_len (s, len, func->ud); 248290067Sbapt} 249290067Sbapt 250290067Sbaptvoid 251290067Sbaptucl_emitter_print_binary_string_msgpack (struct ucl_emitter_context *ctx, 252290067Sbapt const char *s, size_t len) 253290067Sbapt{ 254290067Sbapt const struct ucl_emitter_functions *func = ctx->func; 255290067Sbapt const unsigned char l8_ch = 0xc4, l16_ch = 0xc5, l32_ch = 0xc6; 256290067Sbapt unsigned char buf[5]; 257290067Sbapt unsigned blen; 258290067Sbapt 259290067Sbapt if (len <= 0xff) { 260290067Sbapt blen = 2; 261290067Sbapt buf[0] = l8_ch; 262290067Sbapt buf[1] = len & 0xff; 263290067Sbapt } 264290067Sbapt else if (len <= 0xffff) { 265290067Sbapt uint16_t bl = TO_BE16 (len); 266290067Sbapt 267290067Sbapt blen = 3; 268290067Sbapt buf[0] = l16_ch; 269290067Sbapt memcpy (&buf[1], &bl, sizeof (bl)); 270290067Sbapt } 271290067Sbapt else { 272290067Sbapt uint32_t bl = TO_BE32 (len); 273290067Sbapt 274290067Sbapt blen = 5; 275290067Sbapt buf[0] = l32_ch; 276290067Sbapt memcpy (&buf[1], &bl, sizeof (bl)); 277290067Sbapt } 278290067Sbapt 279290067Sbapt func->ucl_emitter_append_len (buf, blen, func->ud); 280290067Sbapt func->ucl_emitter_append_len (s, len, func->ud); 281290067Sbapt} 282290067Sbapt 283290067Sbaptvoid 284290067Sbaptucl_emitter_print_null_msgpack (struct ucl_emitter_context *ctx) 285290067Sbapt{ 286290067Sbapt const struct ucl_emitter_functions *func = ctx->func; 287290067Sbapt const unsigned char nil = 0xc0; 288290067Sbapt 289290067Sbapt func->ucl_emitter_append_character (nil, 1, func->ud); 290290067Sbapt} 291290067Sbapt 292290067Sbaptvoid 293290067Sbaptucl_emitter_print_key_msgpack (bool print_key, struct ucl_emitter_context *ctx, 294290067Sbapt const ucl_object_t *obj) 295290067Sbapt{ 296290067Sbapt if (print_key) { 297290067Sbapt ucl_emitter_print_string_msgpack (ctx, obj->key, obj->keylen); 298290067Sbapt } 299290067Sbapt} 300290067Sbapt 301290067Sbaptvoid 302290067Sbaptucl_emitter_print_array_msgpack (struct ucl_emitter_context *ctx, size_t len) 303290067Sbapt{ 304290067Sbapt const struct ucl_emitter_functions *func = ctx->func; 305290067Sbapt const unsigned char fix_mask = 0x90, l16_ch = 0xdc, l32_ch = 0xdd; 306290067Sbapt unsigned char buf[5]; 307290067Sbapt unsigned blen; 308290067Sbapt 309290067Sbapt if (len <= 0xF) { 310290067Sbapt blen = 1; 311290067Sbapt buf[0] = (len | fix_mask) & 0xff; 312290067Sbapt } 313290067Sbapt else if (len <= 0xffff) { 314290067Sbapt uint16_t bl = TO_BE16 (len); 315290067Sbapt 316290067Sbapt blen = 3; 317290067Sbapt buf[0] = l16_ch; 318290067Sbapt memcpy (&buf[1], &bl, sizeof (bl)); 319290067Sbapt } 320290067Sbapt else { 321290067Sbapt uint32_t bl = TO_BE32 (len); 322290067Sbapt 323290067Sbapt blen = 5; 324290067Sbapt buf[0] = l32_ch; 325290067Sbapt memcpy (&buf[1], &bl, sizeof (bl)); 326290067Sbapt } 327290067Sbapt 328290067Sbapt func->ucl_emitter_append_len (buf, blen, func->ud); 329290067Sbapt} 330290067Sbapt 331290067Sbaptvoid 332290067Sbaptucl_emitter_print_object_msgpack (struct ucl_emitter_context *ctx, size_t len) 333290067Sbapt{ 334290067Sbapt const struct ucl_emitter_functions *func = ctx->func; 335290067Sbapt const unsigned char fix_mask = 0x80, l16_ch = 0xde, l32_ch = 0xdf; 336290067Sbapt unsigned char buf[5]; 337290067Sbapt unsigned blen; 338290067Sbapt 339290067Sbapt if (len <= 0xF) { 340290067Sbapt blen = 1; 341290067Sbapt buf[0] = (len | fix_mask) & 0xff; 342290067Sbapt } 343290067Sbapt else if (len <= 0xffff) { 344290067Sbapt uint16_t bl = TO_BE16 (len); 345290067Sbapt 346290067Sbapt blen = 3; 347290067Sbapt buf[0] = l16_ch; 348290067Sbapt memcpy (&buf[1], &bl, sizeof (bl)); 349290067Sbapt } 350290067Sbapt else { 351290067Sbapt uint32_t bl = TO_BE32 (len); 352290067Sbapt 353290067Sbapt blen = 5; 354290067Sbapt buf[0] = l32_ch; 355290067Sbapt memcpy (&buf[1], &bl, sizeof (bl)); 356290067Sbapt } 357290067Sbapt 358290067Sbapt func->ucl_emitter_append_len (buf, blen, func->ud); 359290067Sbapt} 360290067Sbapt 361290067Sbapt 362290067Sbaptenum ucl_msgpack_format { 363290067Sbapt msgpack_positive_fixint = 0, 364290067Sbapt msgpack_fixmap, 365290067Sbapt msgpack_fixarray, 366290067Sbapt msgpack_fixstr, 367290067Sbapt msgpack_nil, 368290067Sbapt msgpack_false, 369290067Sbapt msgpack_true, 370290067Sbapt msgpack_bin8, 371290067Sbapt msgpack_bin16, 372290067Sbapt msgpack_bin32, 373290067Sbapt msgpack_ext8, 374290067Sbapt msgpack_ext16, 375290067Sbapt msgpack_ext32, 376290067Sbapt msgpack_float32, 377290067Sbapt msgpack_float64, 378290067Sbapt msgpack_uint8, 379290067Sbapt msgpack_uint16, 380290067Sbapt msgpack_uint32, 381290067Sbapt msgpack_uint64, 382290067Sbapt msgpack_int8, 383290067Sbapt msgpack_int16, 384290067Sbapt msgpack_int32, 385290067Sbapt msgpack_int64, 386290067Sbapt msgpack_fixext1, 387290067Sbapt msgpack_fixext2, 388290067Sbapt msgpack_fixext4, 389290067Sbapt msgpack_fixext8, 390290067Sbapt msgpack_fixext16, 391290067Sbapt msgpack_str8, 392290067Sbapt msgpack_str16, 393290067Sbapt msgpack_str32, 394290067Sbapt msgpack_array16, 395290067Sbapt msgpack_array32, 396290067Sbapt msgpack_map16, 397290067Sbapt msgpack_map32, 398290067Sbapt msgpack_negative_fixint, 399290067Sbapt msgpack_invalid 400290067Sbapt}; 401290067Sbapt 402290067Sbapttypedef ssize_t (*ucl_msgpack_parse_function)(struct ucl_parser *parser, 403290067Sbapt struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, 404290067Sbapt const unsigned char *pos, size_t remain); 405290067Sbapt 406290067Sbaptstatic ssize_t ucl_msgpack_parse_map (struct ucl_parser *parser, 407290067Sbapt struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, 408290067Sbapt const unsigned char *pos, size_t remain); 409290067Sbaptstatic ssize_t ucl_msgpack_parse_array (struct ucl_parser *parser, 410290067Sbapt struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, 411290067Sbapt const unsigned char *pos, size_t remain); 412290067Sbaptstatic ssize_t ucl_msgpack_parse_string (struct ucl_parser *parser, 413290067Sbapt struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, 414290067Sbapt const unsigned char *pos, size_t remain); 415290067Sbaptstatic ssize_t ucl_msgpack_parse_int (struct ucl_parser *parser, 416290067Sbapt struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, 417290067Sbapt const unsigned char *pos, size_t remain); 418290067Sbaptstatic ssize_t ucl_msgpack_parse_float (struct ucl_parser *parser, 419290067Sbapt struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, 420290067Sbapt const unsigned char *pos, size_t remain); 421290067Sbaptstatic ssize_t ucl_msgpack_parse_bool (struct ucl_parser *parser, 422290067Sbapt struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, 423290067Sbapt const unsigned char *pos, size_t remain); 424290067Sbaptstatic ssize_t ucl_msgpack_parse_null (struct ucl_parser *parser, 425290067Sbapt struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, 426290067Sbapt const unsigned char *pos, size_t remain); 427290067Sbaptstatic ssize_t ucl_msgpack_parse_ignore (struct ucl_parser *parser, 428290067Sbapt struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, 429290067Sbapt const unsigned char *pos, size_t remain); 430290067Sbapt 431290067Sbapt#define MSGPACK_FLAG_FIXED (1 << 0) 432290067Sbapt#define MSGPACK_FLAG_CONTAINER (1 << 1) 433290067Sbapt#define MSGPACK_FLAG_TYPEVALUE (1 << 2) 434290067Sbapt#define MSGPACK_FLAG_EXT (1 << 3) 435290067Sbapt#define MSGPACK_FLAG_ASSOC (1 << 4) 436290067Sbapt#define MSGPACK_FLAG_KEY (1 << 5) 437290067Sbapt#define MSGPACK_CONTAINER_BIT (1ULL << 62) 438290067Sbapt 439290067Sbapt/* 440290067Sbapt * Search tree packed in array 441290067Sbapt */ 442290067Sbaptstruct ucl_msgpack_parser { 443290067Sbapt uint8_t prefix; /* Prefix byte */ 444290067Sbapt uint8_t prefixlen; /* Length of prefix in bits */ 445290067Sbapt uint8_t fmt; /* The desired format */ 446290067Sbapt uint8_t len; /* Length of the object 447290067Sbapt (either length bytes 448290067Sbapt or length of value in case 449290067Sbapt of fixed objects */ 450290067Sbapt uint8_t flags; /* Flags of the specified type */ 451290067Sbapt ucl_msgpack_parse_function func; /* Parser function */ 452290067Sbapt} parsers[] = { 453290067Sbapt { 454290067Sbapt 0xa0, 455290067Sbapt 3, 456290067Sbapt msgpack_fixstr, 457290067Sbapt 0, 458290067Sbapt MSGPACK_FLAG_FIXED|MSGPACK_FLAG_KEY, 459290067Sbapt ucl_msgpack_parse_string 460290067Sbapt }, 461290067Sbapt { 462290067Sbapt 0x0, 463290067Sbapt 1, 464290067Sbapt msgpack_positive_fixint, 465290067Sbapt 0, 466290067Sbapt MSGPACK_FLAG_FIXED|MSGPACK_FLAG_TYPEVALUE, 467290067Sbapt ucl_msgpack_parse_int 468290067Sbapt }, 469290067Sbapt { 470290067Sbapt 0xe0, 471290067Sbapt 3, 472290067Sbapt msgpack_negative_fixint, 473290067Sbapt 0, 474290067Sbapt MSGPACK_FLAG_FIXED|MSGPACK_FLAG_TYPEVALUE, 475290067Sbapt ucl_msgpack_parse_int 476290067Sbapt }, 477290067Sbapt { 478290067Sbapt 0x80, 479290067Sbapt 4, 480290067Sbapt msgpack_fixmap, 481290067Sbapt 0, 482290067Sbapt MSGPACK_FLAG_FIXED|MSGPACK_FLAG_CONTAINER|MSGPACK_FLAG_ASSOC, 483290067Sbapt ucl_msgpack_parse_map 484290067Sbapt }, 485290067Sbapt { 486290067Sbapt 0x90, 487290067Sbapt 4, 488290067Sbapt msgpack_fixarray, 489290067Sbapt 0, 490290067Sbapt MSGPACK_FLAG_FIXED|MSGPACK_FLAG_CONTAINER, 491290067Sbapt ucl_msgpack_parse_array 492290067Sbapt }, 493290067Sbapt { 494290067Sbapt 0xd9, 495290067Sbapt 8, 496290067Sbapt msgpack_str8, 497290067Sbapt 1, 498290067Sbapt MSGPACK_FLAG_KEY, 499290067Sbapt ucl_msgpack_parse_string 500290067Sbapt }, 501290067Sbapt { 502290067Sbapt 0xc4, 503290067Sbapt 8, 504290067Sbapt msgpack_bin8, 505290067Sbapt 1, 506290067Sbapt MSGPACK_FLAG_KEY, 507290067Sbapt ucl_msgpack_parse_string 508290067Sbapt }, 509290067Sbapt { 510290067Sbapt 0xcf, 511290067Sbapt 8, 512290067Sbapt msgpack_uint64, 513290067Sbapt 8, 514290067Sbapt MSGPACK_FLAG_FIXED, 515290067Sbapt ucl_msgpack_parse_int 516290067Sbapt }, 517290067Sbapt { 518290067Sbapt 0xd3, 519290067Sbapt 8, 520290067Sbapt msgpack_int64, 521290067Sbapt 8, 522290067Sbapt MSGPACK_FLAG_FIXED, 523290067Sbapt ucl_msgpack_parse_int 524290067Sbapt }, 525290067Sbapt { 526290067Sbapt 0xce, 527290067Sbapt 8, 528290067Sbapt msgpack_uint32, 529290067Sbapt 4, 530290067Sbapt MSGPACK_FLAG_FIXED, 531290067Sbapt ucl_msgpack_parse_int 532290067Sbapt }, 533290067Sbapt { 534290067Sbapt 0xd2, 535290067Sbapt 8, 536290067Sbapt msgpack_int32, 537290067Sbapt 4, 538290067Sbapt MSGPACK_FLAG_FIXED, 539290067Sbapt ucl_msgpack_parse_int 540290067Sbapt }, 541290067Sbapt { 542290067Sbapt 0xcb, 543290067Sbapt 8, 544290067Sbapt msgpack_float64, 545290067Sbapt 8, 546290067Sbapt MSGPACK_FLAG_FIXED, 547290067Sbapt ucl_msgpack_parse_float 548290067Sbapt }, 549290067Sbapt { 550290067Sbapt 0xca, 551290067Sbapt 8, 552290067Sbapt msgpack_float32, 553290067Sbapt 4, 554290067Sbapt MSGPACK_FLAG_FIXED, 555290067Sbapt ucl_msgpack_parse_float 556290067Sbapt }, 557290067Sbapt { 558290067Sbapt 0xc2, 559290067Sbapt 8, 560290067Sbapt msgpack_false, 561290067Sbapt 1, 562290067Sbapt MSGPACK_FLAG_FIXED | MSGPACK_FLAG_TYPEVALUE, 563290067Sbapt ucl_msgpack_parse_bool 564290067Sbapt }, 565290067Sbapt { 566290067Sbapt 0xc3, 567290067Sbapt 8, 568290067Sbapt msgpack_true, 569290067Sbapt 1, 570290067Sbapt MSGPACK_FLAG_FIXED | MSGPACK_FLAG_TYPEVALUE, 571290067Sbapt ucl_msgpack_parse_bool 572290067Sbapt }, 573290067Sbapt { 574290067Sbapt 0xcc, 575290067Sbapt 8, 576290067Sbapt msgpack_uint8, 577290067Sbapt 1, 578290067Sbapt MSGPACK_FLAG_FIXED, 579290067Sbapt ucl_msgpack_parse_int 580290067Sbapt }, 581290067Sbapt { 582290067Sbapt 0xcd, 583290067Sbapt 8, 584290067Sbapt msgpack_uint16, 585290067Sbapt 2, 586290067Sbapt MSGPACK_FLAG_FIXED, 587290067Sbapt ucl_msgpack_parse_int 588290067Sbapt }, 589290067Sbapt { 590290067Sbapt 0xd0, 591290067Sbapt 8, 592290067Sbapt msgpack_int8, 593290067Sbapt 1, 594290067Sbapt MSGPACK_FLAG_FIXED, 595290067Sbapt ucl_msgpack_parse_int 596290067Sbapt }, 597290067Sbapt { 598290067Sbapt 0xd1, 599290067Sbapt 8, 600290067Sbapt msgpack_int16, 601290067Sbapt 2, 602290067Sbapt MSGPACK_FLAG_FIXED, 603290067Sbapt ucl_msgpack_parse_int 604290067Sbapt }, 605290067Sbapt { 606290067Sbapt 0xc0, 607290067Sbapt 8, 608290067Sbapt msgpack_nil, 609290067Sbapt 0, 610290067Sbapt MSGPACK_FLAG_FIXED | MSGPACK_FLAG_TYPEVALUE, 611290067Sbapt ucl_msgpack_parse_null 612290067Sbapt }, 613290067Sbapt { 614290067Sbapt 0xda, 615290067Sbapt 8, 616290067Sbapt msgpack_str16, 617290067Sbapt 2, 618290067Sbapt MSGPACK_FLAG_KEY, 619290067Sbapt ucl_msgpack_parse_string 620290067Sbapt }, 621290067Sbapt { 622290067Sbapt 0xdb, 623290067Sbapt 8, 624290067Sbapt msgpack_str32, 625290067Sbapt 4, 626290067Sbapt MSGPACK_FLAG_KEY, 627290067Sbapt ucl_msgpack_parse_string 628290067Sbapt }, 629290067Sbapt { 630290067Sbapt 0xc5, 631290067Sbapt 8, 632290067Sbapt msgpack_bin16, 633290067Sbapt 2, 634290067Sbapt MSGPACK_FLAG_KEY, 635290067Sbapt ucl_msgpack_parse_string 636290067Sbapt }, 637290067Sbapt { 638290067Sbapt 0xc6, 639290067Sbapt 8, 640290067Sbapt msgpack_bin32, 641290067Sbapt 4, 642290067Sbapt MSGPACK_FLAG_KEY, 643290067Sbapt ucl_msgpack_parse_string 644290067Sbapt }, 645290067Sbapt { 646290067Sbapt 0xdc, 647290067Sbapt 8, 648290067Sbapt msgpack_array16, 649290067Sbapt 2, 650290067Sbapt MSGPACK_FLAG_CONTAINER, 651290067Sbapt ucl_msgpack_parse_array 652290067Sbapt }, 653290067Sbapt { 654290067Sbapt 0xdd, 655290067Sbapt 8, 656290067Sbapt msgpack_array32, 657290067Sbapt 4, 658290067Sbapt MSGPACK_FLAG_CONTAINER, 659290067Sbapt ucl_msgpack_parse_array 660290067Sbapt }, 661290067Sbapt { 662290067Sbapt 0xde, 663290067Sbapt 8, 664290067Sbapt msgpack_map16, 665290067Sbapt 2, 666290067Sbapt MSGPACK_FLAG_CONTAINER|MSGPACK_FLAG_ASSOC, 667290067Sbapt ucl_msgpack_parse_map 668290067Sbapt }, 669290067Sbapt { 670290067Sbapt 0xdf, 671290067Sbapt 8, 672290067Sbapt msgpack_map32, 673290067Sbapt 4, 674290067Sbapt MSGPACK_FLAG_CONTAINER|MSGPACK_FLAG_ASSOC, 675290067Sbapt ucl_msgpack_parse_map 676290067Sbapt }, 677290067Sbapt { 678290067Sbapt 0xc7, 679290067Sbapt 8, 680290067Sbapt msgpack_ext8, 681290067Sbapt 1, 682290067Sbapt MSGPACK_FLAG_EXT, 683290067Sbapt ucl_msgpack_parse_ignore 684290067Sbapt }, 685290067Sbapt { 686290067Sbapt 0xc8, 687290067Sbapt 8, 688290067Sbapt msgpack_ext16, 689290067Sbapt 2, 690290067Sbapt MSGPACK_FLAG_EXT, 691290067Sbapt ucl_msgpack_parse_ignore 692290067Sbapt }, 693290067Sbapt { 694290067Sbapt 0xc9, 695290067Sbapt 8, 696290067Sbapt msgpack_ext32, 697290067Sbapt 4, 698290067Sbapt MSGPACK_FLAG_EXT, 699290067Sbapt ucl_msgpack_parse_ignore 700290067Sbapt }, 701290067Sbapt { 702290067Sbapt 0xd4, 703290067Sbapt 8, 704290067Sbapt msgpack_fixext1, 705290067Sbapt 1, 706290067Sbapt MSGPACK_FLAG_FIXED | MSGPACK_FLAG_EXT, 707290067Sbapt ucl_msgpack_parse_ignore 708290067Sbapt }, 709290067Sbapt { 710290067Sbapt 0xd5, 711290067Sbapt 8, 712290067Sbapt msgpack_fixext2, 713290067Sbapt 2, 714290067Sbapt MSGPACK_FLAG_FIXED | MSGPACK_FLAG_EXT, 715290067Sbapt ucl_msgpack_parse_ignore 716290067Sbapt }, 717290067Sbapt { 718290067Sbapt 0xd6, 719290067Sbapt 8, 720290067Sbapt msgpack_fixext4, 721290067Sbapt 4, 722290067Sbapt MSGPACK_FLAG_FIXED | MSGPACK_FLAG_EXT, 723290067Sbapt ucl_msgpack_parse_ignore 724290067Sbapt }, 725290067Sbapt { 726290067Sbapt 0xd7, 727290067Sbapt 8, 728290067Sbapt msgpack_fixext8, 729290067Sbapt 8, 730290067Sbapt MSGPACK_FLAG_FIXED | MSGPACK_FLAG_EXT, 731290067Sbapt ucl_msgpack_parse_ignore 732290067Sbapt }, 733290067Sbapt { 734290067Sbapt 0xd8, 735290067Sbapt 8, 736290067Sbapt msgpack_fixext16, 737290067Sbapt 16, 738290067Sbapt MSGPACK_FLAG_FIXED | MSGPACK_FLAG_EXT, 739290067Sbapt ucl_msgpack_parse_ignore 740290067Sbapt } 741290067Sbapt}; 742290067Sbapt 743290067Sbapt#undef MSGPACK_DEBUG_PARSER 744290067Sbapt 745290067Sbaptstatic inline struct ucl_msgpack_parser * 746290067Sbaptucl_msgpack_get_parser_from_type (unsigned char t) 747290067Sbapt{ 748290067Sbapt unsigned int i, shift, mask; 749290067Sbapt 750290067Sbapt for (i = 0; i < sizeof (parsers) / sizeof (parsers[0]); i ++) { 751290067Sbapt shift = CHAR_BIT - parsers[i].prefixlen; 752290067Sbapt mask = parsers[i].prefix >> shift; 753290067Sbapt 754298166Sbapt if (mask == (((unsigned int)t) >> shift)) { 755290067Sbapt return &parsers[i]; 756290067Sbapt } 757290067Sbapt } 758290067Sbapt 759290067Sbapt return NULL; 760290067Sbapt} 761290067Sbapt 762290067Sbaptstatic inline struct ucl_stack * 763290067Sbaptucl_msgpack_get_container (struct ucl_parser *parser, 764290067Sbapt struct ucl_msgpack_parser *obj_parser, uint64_t len) 765290067Sbapt{ 766290067Sbapt struct ucl_stack *stack; 767290067Sbapt 768290067Sbapt assert (obj_parser != NULL); 769290067Sbapt 770290067Sbapt if (obj_parser->flags & MSGPACK_FLAG_CONTAINER) { 771290067Sbapt assert ((len & MSGPACK_CONTAINER_BIT) == 0); 772290067Sbapt /* 773290067Sbapt * Insert new container to the stack 774290067Sbapt */ 775290067Sbapt if (parser->stack == NULL) { 776290067Sbapt parser->stack = calloc (1, sizeof (struct ucl_stack)); 777290067Sbapt 778290067Sbapt if (parser->stack == NULL) { 779290067Sbapt ucl_create_err (&parser->err, "no memory"); 780290067Sbapt return NULL; 781290067Sbapt } 782290067Sbapt } 783290067Sbapt else { 784290067Sbapt stack = calloc (1, sizeof (struct ucl_stack)); 785290067Sbapt 786290067Sbapt if (stack == NULL) { 787290067Sbapt ucl_create_err (&parser->err, "no memory"); 788290067Sbapt return NULL; 789290067Sbapt } 790290067Sbapt 791290067Sbapt stack->next = parser->stack; 792290067Sbapt parser->stack = stack; 793290067Sbapt } 794290067Sbapt 795290067Sbapt parser->stack->level = len | MSGPACK_CONTAINER_BIT; 796290067Sbapt 797290067Sbapt#ifdef MSGPACK_DEBUG_PARSER 798290067Sbapt stack = parser->stack; 799290067Sbapt while (stack) { 800290067Sbapt fprintf(stderr, "+"); 801290067Sbapt stack = stack->next; 802290067Sbapt } 803290067Sbapt 804290067Sbapt fprintf(stderr, "%s -> %d\n", obj_parser->flags & MSGPACK_FLAG_ASSOC ? "object" : "array", (int)len); 805290067Sbapt#endif 806290067Sbapt } 807290067Sbapt else { 808290067Sbapt /* 809290067Sbapt * Get the current stack top 810290067Sbapt */ 811290067Sbapt if (parser->stack) { 812290067Sbapt return parser->stack; 813290067Sbapt } 814290067Sbapt else { 815290067Sbapt ucl_create_err (&parser->err, "bad top level object for msgpack"); 816290067Sbapt return NULL; 817290067Sbapt } 818290067Sbapt } 819290067Sbapt 820290067Sbapt return parser->stack; 821290067Sbapt} 822290067Sbapt 823290067Sbaptstatic bool 824290067Sbaptucl_msgpack_is_container_finished (struct ucl_stack *container) 825290067Sbapt{ 826290067Sbapt uint64_t level; 827290067Sbapt 828290067Sbapt assert (container != NULL); 829290067Sbapt 830290067Sbapt if (container->level & MSGPACK_CONTAINER_BIT) { 831290067Sbapt level = container->level & ~MSGPACK_CONTAINER_BIT; 832290067Sbapt 833290067Sbapt if (level == 0) { 834290067Sbapt return true; 835290067Sbapt } 836290067Sbapt } 837290067Sbapt 838290067Sbapt return false; 839290067Sbapt} 840290067Sbapt 841290067Sbaptstatic bool 842290067Sbaptucl_msgpack_insert_object (struct ucl_parser *parser, 843290067Sbapt const unsigned char *key, 844290067Sbapt size_t keylen, ucl_object_t *obj) 845290067Sbapt{ 846290067Sbapt uint64_t level; 847290067Sbapt struct ucl_stack *container; 848290067Sbapt 849290067Sbapt container = parser->stack; 850290067Sbapt assert (container != NULL); 851290067Sbapt assert (container->level > 0); 852290067Sbapt assert (obj != NULL); 853290067Sbapt assert (container->obj != NULL); 854290067Sbapt 855290067Sbapt if (container->obj->type == UCL_ARRAY) { 856290067Sbapt ucl_array_append (container->obj, obj); 857290067Sbapt } 858290067Sbapt else if (container->obj->type == UCL_OBJECT) { 859290067Sbapt if (key == NULL || keylen == 0) { 860290067Sbapt ucl_create_err (&parser->err, "cannot insert object with no key"); 861290067Sbapt return false; 862290067Sbapt } 863290067Sbapt 864290067Sbapt obj->key = key; 865290067Sbapt obj->keylen = keylen; 866290067Sbapt 867290067Sbapt if (!(parser->flags & UCL_PARSER_ZEROCOPY)) { 868290067Sbapt ucl_copy_key_trash (obj); 869290067Sbapt } 870290067Sbapt 871290067Sbapt ucl_parser_process_object_element (parser, obj); 872290067Sbapt } 873290067Sbapt else { 874290067Sbapt ucl_create_err (&parser->err, "bad container type"); 875290067Sbapt return false; 876290067Sbapt } 877290067Sbapt 878290067Sbapt if (container->level & MSGPACK_CONTAINER_BIT) { 879290067Sbapt level = container->level & ~MSGPACK_CONTAINER_BIT; 880290067Sbapt container->level = (level - 1) | MSGPACK_CONTAINER_BIT; 881290067Sbapt } 882290067Sbapt 883290067Sbapt return true; 884290067Sbapt} 885290067Sbapt 886290067Sbaptstatic struct ucl_stack * 887290067Sbaptucl_msgpack_get_next_container (struct ucl_parser *parser) 888290067Sbapt{ 889290067Sbapt struct ucl_stack *cur = NULL; 890290067Sbapt uint64_t level; 891290067Sbapt 892290067Sbapt cur = parser->stack; 893290067Sbapt 894290067Sbapt if (cur == NULL) { 895290067Sbapt return NULL; 896290067Sbapt } 897290067Sbapt 898290067Sbapt if (cur->level & MSGPACK_CONTAINER_BIT) { 899290067Sbapt level = cur->level & ~MSGPACK_CONTAINER_BIT; 900290067Sbapt 901290067Sbapt if (level == 0) { 902290067Sbapt /* We need to switch to the previous container */ 903290067Sbapt parser->stack = cur->next; 904290067Sbapt parser->cur_obj = cur->obj; 905290067Sbapt free (cur); 906290067Sbapt 907290067Sbapt#ifdef MSGPACK_DEBUG_PARSER 908290067Sbapt cur = parser->stack; 909290067Sbapt while (cur) { 910290067Sbapt fprintf(stderr, "-"); 911290067Sbapt cur = cur->next; 912290067Sbapt } 913290067Sbapt fprintf(stderr, "-%s -> %d\n", parser->cur_obj->type == UCL_OBJECT ? "object" : "array", (int)parser->cur_obj->len); 914290067Sbapt#endif 915290067Sbapt 916290067Sbapt return ucl_msgpack_get_next_container (parser); 917290067Sbapt } 918290067Sbapt } 919290067Sbapt 920290067Sbapt /* 921290067Sbapt * For UCL containers we don't know length, so we just insert the whole 922290067Sbapt * message pack blob into the top level container 923290067Sbapt */ 924290067Sbapt 925290067Sbapt assert (cur->obj != NULL); 926290067Sbapt 927290067Sbapt return cur; 928290067Sbapt} 929290067Sbapt 930290067Sbapt#define CONSUME_RET do { \ 931290067Sbapt if (ret != -1) { \ 932290067Sbapt p += ret; \ 933290067Sbapt remain -= ret; \ 934290067Sbapt obj_parser = NULL; \ 935290067Sbapt assert (remain >= 0); \ 936290067Sbapt } \ 937290067Sbapt else { \ 938290067Sbapt ucl_create_err (&parser->err, \ 939290067Sbapt "cannot parse type %d of len %u", \ 940290067Sbapt (int)obj_parser->fmt, \ 941290067Sbapt (unsigned)len); \ 942290067Sbapt return false; \ 943290067Sbapt } \ 944290067Sbapt} while(0) 945290067Sbapt 946290067Sbapt#define GET_NEXT_STATE do { \ 947290067Sbapt container = ucl_msgpack_get_next_container (parser); \ 948290067Sbapt if (container == NULL) { \ 949290067Sbapt ucl_create_err (&parser->err, \ 950290067Sbapt "empty container"); \ 951290067Sbapt return false; \ 952290067Sbapt } \ 953290067Sbapt next_state = container->obj->type == UCL_OBJECT ? \ 954290067Sbapt read_assoc_key : read_array_value; \ 955290067Sbapt} while(0) 956290067Sbapt 957290067Sbaptstatic bool 958290067Sbaptucl_msgpack_consume (struct ucl_parser *parser) 959290067Sbapt{ 960290067Sbapt const unsigned char *p, *end, *key = NULL; 961290067Sbapt struct ucl_stack *container; 962290067Sbapt enum e_msgpack_parser_state { 963290067Sbapt read_type, 964290067Sbapt start_assoc, 965290067Sbapt start_array, 966290067Sbapt read_assoc_key, 967290067Sbapt read_assoc_value, 968290067Sbapt finish_assoc_value, 969290067Sbapt read_array_value, 970290067Sbapt finish_array_value, 971290067Sbapt error_state 972290067Sbapt } state = read_type, next_state = error_state; 973298166Sbapt struct ucl_msgpack_parser *obj_parser = NULL; 974298166Sbapt uint64_t len = 0; 975290067Sbapt ssize_t ret, remain, keylen = 0; 976290067Sbapt#ifdef MSGPACK_DEBUG_PARSER 977290067Sbapt uint64_t i; 978290067Sbapt enum e_msgpack_parser_state hist[256]; 979290067Sbapt#endif 980290067Sbapt 981290067Sbapt p = parser->chunks->begin; 982290067Sbapt remain = parser->chunks->remain; 983290067Sbapt end = p + remain; 984290067Sbapt 985290067Sbapt 986290067Sbapt while (p < end) { 987290067Sbapt#ifdef MSGPACK_DEBUG_PARSER 988290067Sbapt hist[i++ % 256] = state; 989290067Sbapt#endif 990290067Sbapt switch (state) { 991290067Sbapt case read_type: 992290067Sbapt obj_parser = ucl_msgpack_get_parser_from_type (*p); 993290067Sbapt 994290067Sbapt if (obj_parser == NULL) { 995290067Sbapt ucl_create_err (&parser->err, "unknown msgpack format: %x", 996290067Sbapt (unsigned int)*p); 997290067Sbapt 998290067Sbapt return false; 999290067Sbapt } 1000290067Sbapt /* Now check length sanity */ 1001290067Sbapt if (obj_parser->flags & MSGPACK_FLAG_FIXED) { 1002290067Sbapt if (obj_parser->len == 0) { 1003290067Sbapt /* We have an embedded size */ 1004290067Sbapt len = *p & ~obj_parser->prefix; 1005290067Sbapt } 1006290067Sbapt else { 1007290067Sbapt if (remain < obj_parser->len) { 1008290067Sbapt ucl_create_err (&parser->err, "not enough data remain to " 1009290067Sbapt "read object's length: %u remain, %u needed", 1010290067Sbapt (unsigned)remain, obj_parser->len); 1011290067Sbapt 1012290067Sbapt return false; 1013290067Sbapt } 1014290067Sbapt 1015290067Sbapt len = obj_parser->len; 1016290067Sbapt } 1017290067Sbapt 1018290067Sbapt if (!(obj_parser->flags & MSGPACK_FLAG_TYPEVALUE)) { 1019290067Sbapt /* We must pass value as the second byte */ 1020290067Sbapt if (remain > 0) { 1021290067Sbapt p ++; 1022290067Sbapt remain --; 1023290067Sbapt } 1024290067Sbapt } 1025290067Sbapt else { 1026290067Sbapt /* Len is irrelevant now */ 1027290067Sbapt len = 0; 1028290067Sbapt } 1029290067Sbapt } 1030290067Sbapt else { 1031290067Sbapt /* Length is not embedded */ 1032290067Sbapt if (remain < obj_parser->len) { 1033290067Sbapt ucl_create_err (&parser->err, "not enough data remain to " 1034290067Sbapt "read object's length: %u remain, %u needed", 1035290067Sbapt (unsigned)remain, obj_parser->len); 1036290067Sbapt 1037290067Sbapt return false; 1038290067Sbapt } 1039290067Sbapt 1040290067Sbapt p ++; 1041290067Sbapt remain --; 1042290067Sbapt 1043290067Sbapt switch (obj_parser->len) { 1044290067Sbapt case 1: 1045290067Sbapt len = *p; 1046290067Sbapt break; 1047290067Sbapt case 2: 1048290067Sbapt len = FROM_BE16 (*(uint16_t *)p); 1049290067Sbapt break; 1050290067Sbapt case 4: 1051290067Sbapt len = FROM_BE32 (*(uint32_t *)p); 1052290067Sbapt break; 1053290067Sbapt case 8: 1054290067Sbapt len = FROM_BE64 (*(uint64_t *)p); 1055290067Sbapt break; 1056290067Sbapt default: 1057290067Sbapt assert (0); 1058290067Sbapt break; 1059290067Sbapt } 1060290067Sbapt 1061290067Sbapt p += obj_parser->len; 1062290067Sbapt remain -= obj_parser->len; 1063290067Sbapt } 1064290067Sbapt 1065290067Sbapt if (obj_parser->flags & MSGPACK_FLAG_ASSOC) { 1066290067Sbapt /* We have just read the new associative map */ 1067290067Sbapt state = start_assoc; 1068290067Sbapt } 1069290067Sbapt else if (obj_parser->flags & MSGPACK_FLAG_CONTAINER){ 1070290067Sbapt state = start_array; 1071290067Sbapt } 1072290067Sbapt else { 1073290067Sbapt state = next_state; 1074290067Sbapt } 1075290067Sbapt 1076290067Sbapt break; 1077290067Sbapt case start_assoc: 1078290067Sbapt parser->cur_obj = ucl_object_new_full (UCL_OBJECT, 1079290067Sbapt parser->chunks->priority); 1080290067Sbapt /* Insert to the previous level container */ 1081290067Sbapt if (parser->stack && !ucl_msgpack_insert_object (parser, 1082290067Sbapt key, keylen, parser->cur_obj)) { 1083290067Sbapt return false; 1084290067Sbapt } 1085290067Sbapt /* Get new container */ 1086290067Sbapt container = ucl_msgpack_get_container (parser, obj_parser, len); 1087290067Sbapt 1088290067Sbapt if (container == NULL) { 1089290067Sbapt return false; 1090290067Sbapt } 1091290067Sbapt 1092290067Sbapt ret = obj_parser->func (parser, container, len, obj_parser->fmt, 1093290067Sbapt p, remain); 1094290067Sbapt CONSUME_RET; 1095290067Sbapt key = NULL; 1096290067Sbapt keylen = 0; 1097290067Sbapt 1098290067Sbapt if (len > 0) { 1099290067Sbapt state = read_type; 1100290067Sbapt next_state = read_assoc_key; 1101290067Sbapt } 1102290067Sbapt else { 1103290067Sbapt /* Empty object */ 1104290067Sbapt state = finish_assoc_value; 1105290067Sbapt } 1106290067Sbapt break; 1107290067Sbapt 1108290067Sbapt case start_array: 1109290067Sbapt parser->cur_obj = ucl_object_new_full (UCL_ARRAY, 1110290067Sbapt parser->chunks->priority); 1111290067Sbapt /* Insert to the previous level container */ 1112290067Sbapt if (parser->stack && !ucl_msgpack_insert_object (parser, 1113290067Sbapt key, keylen, parser->cur_obj)) { 1114290067Sbapt return false; 1115290067Sbapt } 1116290067Sbapt /* Get new container */ 1117290067Sbapt container = ucl_msgpack_get_container (parser, obj_parser, len); 1118290067Sbapt 1119290067Sbapt if (container == NULL) { 1120290067Sbapt return false; 1121290067Sbapt } 1122290067Sbapt 1123290067Sbapt ret = obj_parser->func (parser, container, len, obj_parser->fmt, 1124290067Sbapt p, remain); 1125290067Sbapt CONSUME_RET; 1126290067Sbapt 1127290067Sbapt if (len > 0) { 1128290067Sbapt state = read_type; 1129290067Sbapt next_state = read_array_value; 1130290067Sbapt } 1131290067Sbapt else { 1132290067Sbapt /* Empty array */ 1133290067Sbapt state = finish_array_value; 1134290067Sbapt } 1135290067Sbapt break; 1136290067Sbapt 1137290067Sbapt case read_array_value: 1138290067Sbapt /* 1139290067Sbapt * p is now at the value start, len now contains length read and 1140290067Sbapt * obj_parser contains the corresponding specific parser 1141290067Sbapt */ 1142290067Sbapt container = parser->stack; 1143290067Sbapt 1144290067Sbapt if (container == NULL) { 1145290067Sbapt return false; 1146290067Sbapt } 1147290067Sbapt 1148290067Sbapt ret = obj_parser->func (parser, container, len, obj_parser->fmt, 1149290067Sbapt p, remain); 1150290067Sbapt CONSUME_RET; 1151290067Sbapt 1152290067Sbapt 1153290067Sbapt /* Insert value to the container and check if we have finished array */ 1154290067Sbapt if (!ucl_msgpack_insert_object (parser, NULL, 0, 1155290067Sbapt parser->cur_obj)) { 1156290067Sbapt return false; 1157290067Sbapt } 1158290067Sbapt 1159290067Sbapt if (ucl_msgpack_is_container_finished (container)) { 1160290067Sbapt state = finish_array_value; 1161290067Sbapt } 1162290067Sbapt else { 1163290067Sbapt /* Read more elements */ 1164290067Sbapt state = read_type; 1165290067Sbapt next_state = read_array_value; 1166290067Sbapt } 1167290067Sbapt 1168290067Sbapt break; 1169290067Sbapt 1170290067Sbapt case read_assoc_key: 1171290067Sbapt /* 1172290067Sbapt * Keys must have string type for ucl msgpack 1173290067Sbapt */ 1174290067Sbapt if (!(obj_parser->flags & MSGPACK_FLAG_KEY)) { 1175290067Sbapt ucl_create_err (&parser->err, "bad type for key: %u, expected " 1176290067Sbapt "string", (unsigned)obj_parser->fmt); 1177290067Sbapt 1178290067Sbapt return false; 1179290067Sbapt } 1180290067Sbapt 1181290067Sbapt key = p; 1182290067Sbapt keylen = len; 1183290067Sbapt 1184290067Sbapt if (keylen > remain || keylen == 0) { 1185290067Sbapt ucl_create_err (&parser->err, "too long or empty key"); 1186290067Sbapt return false; 1187290067Sbapt } 1188290067Sbapt 1189290067Sbapt p += len; 1190290067Sbapt remain -= len; 1191290067Sbapt 1192290067Sbapt state = read_type; 1193290067Sbapt next_state = read_assoc_value; 1194290067Sbapt break; 1195290067Sbapt 1196290067Sbapt case read_assoc_value: 1197290067Sbapt /* 1198290067Sbapt * p is now at the value start, len now contains length read and 1199290067Sbapt * obj_parser contains the corresponding specific parser 1200290067Sbapt */ 1201290067Sbapt container = parser->stack; 1202290067Sbapt 1203290067Sbapt if (container == NULL) { 1204290067Sbapt return false; 1205290067Sbapt } 1206290067Sbapt 1207290067Sbapt ret = obj_parser->func (parser, container, len, obj_parser->fmt, 1208290067Sbapt p, remain); 1209290067Sbapt CONSUME_RET; 1210290067Sbapt 1211290067Sbapt assert (key != NULL && keylen > 0); 1212290067Sbapt 1213290067Sbapt if (!ucl_msgpack_insert_object (parser, key, keylen, 1214290067Sbapt parser->cur_obj)) { 1215290067Sbapt return false; 1216290067Sbapt } 1217290067Sbapt 1218290067Sbapt key = NULL; 1219290067Sbapt keylen = 0; 1220290067Sbapt 1221290067Sbapt if (ucl_msgpack_is_container_finished (container)) { 1222290067Sbapt state = finish_assoc_value; 1223290067Sbapt } 1224290067Sbapt else { 1225290067Sbapt /* Read more elements */ 1226290067Sbapt state = read_type; 1227290067Sbapt next_state = read_assoc_key; 1228290067Sbapt } 1229290067Sbapt break; 1230290067Sbapt 1231290067Sbapt case finish_array_value: 1232290067Sbapt case finish_assoc_value: 1233290067Sbapt GET_NEXT_STATE; 1234290067Sbapt state = read_type; 1235290067Sbapt break; 1236290067Sbapt 1237290067Sbapt case error_state: 1238290067Sbapt ucl_create_err (&parser->err, "invalid state machine state"); 1239290067Sbapt 1240290067Sbapt return false; 1241290067Sbapt } 1242290067Sbapt } 1243290067Sbapt 1244290067Sbapt /* Check the finishing state */ 1245290067Sbapt switch (state) { 1246290067Sbapt case start_array: 1247290067Sbapt case start_assoc: 1248290067Sbapt /* Empty container at the end */ 1249290067Sbapt if (len != 0) { 1250290067Sbapt ucl_create_err (&parser->err, "invalid non-empty container at the end"); 1251290067Sbapt 1252290067Sbapt return false; 1253290067Sbapt } 1254290067Sbapt 1255290067Sbapt parser->cur_obj = ucl_object_new_full ( 1256290067Sbapt state == start_array ? UCL_ARRAY : UCL_OBJECT, 1257290067Sbapt parser->chunks->priority); 1258290067Sbapt /* Insert to the previous level container */ 1259290067Sbapt if (!ucl_msgpack_insert_object (parser, 1260290067Sbapt key, keylen, parser->cur_obj)) { 1261290067Sbapt return false; 1262290067Sbapt } 1263290067Sbapt /* Get new container */ 1264290067Sbapt container = ucl_msgpack_get_container (parser, obj_parser, len); 1265290067Sbapt 1266290067Sbapt if (container == NULL) { 1267290067Sbapt return false; 1268290067Sbapt } 1269290067Sbapt 1270290067Sbapt ret = obj_parser->func (parser, container, len, obj_parser->fmt, 1271290067Sbapt p, remain); 1272290067Sbapt break; 1273290067Sbapt 1274290067Sbapt case read_array_value: 1275290067Sbapt case read_assoc_value: 1276290067Sbapt if (len != 0) { 1277290067Sbapt ucl_create_err (&parser->err, "unfinished value at the end"); 1278290067Sbapt 1279290067Sbapt return false; 1280290067Sbapt } 1281290067Sbapt 1282290067Sbapt container = parser->stack; 1283290067Sbapt 1284290067Sbapt if (container == NULL) { 1285290067Sbapt return false; 1286290067Sbapt } 1287290067Sbapt 1288290067Sbapt ret = obj_parser->func (parser, container, len, obj_parser->fmt, 1289290067Sbapt p, remain); 1290290067Sbapt CONSUME_RET; 1291290067Sbapt 1292290067Sbapt 1293290067Sbapt /* Insert value to the container and check if we have finished array */ 1294290067Sbapt if (!ucl_msgpack_insert_object (parser, NULL, 0, 1295290067Sbapt parser->cur_obj)) { 1296290067Sbapt return false; 1297290067Sbapt } 1298290067Sbapt break; 1299290067Sbapt case finish_array_value: 1300290067Sbapt case finish_assoc_value: 1301290067Sbapt case read_type: 1302290067Sbapt /* Valid finishing state */ 1303290067Sbapt break; 1304290067Sbapt default: 1305290067Sbapt /* Invalid finishing state */ 1306290067Sbapt ucl_create_err (&parser->err, "invalid state machine finishing state: %d", 1307290067Sbapt state); 1308290067Sbapt 1309290067Sbapt return false; 1310290067Sbapt } 1311290067Sbapt 1312290067Sbapt /* Rewind to the top level container */ 1313290067Sbapt ucl_msgpack_get_next_container (parser); 1314290067Sbapt assert (parser->stack == NULL || 1315290067Sbapt (parser->stack->level & MSGPACK_CONTAINER_BIT) == 0); 1316290067Sbapt 1317290067Sbapt return true; 1318290067Sbapt} 1319290067Sbapt 1320290067Sbaptbool 1321290067Sbaptucl_parse_msgpack (struct ucl_parser *parser) 1322290067Sbapt{ 1323290067Sbapt ucl_object_t *container = NULL; 1324290067Sbapt const unsigned char *p; 1325290067Sbapt bool ret; 1326290067Sbapt 1327290067Sbapt assert (parser != NULL); 1328290067Sbapt assert (parser->chunks != NULL); 1329290067Sbapt assert (parser->chunks->begin != NULL); 1330290067Sbapt assert (parser->chunks->remain != 0); 1331290067Sbapt 1332290067Sbapt p = parser->chunks->begin; 1333290067Sbapt 1334290067Sbapt if (parser->stack) { 1335290067Sbapt container = parser->stack->obj; 1336290067Sbapt } 1337290067Sbapt 1338290067Sbapt /* 1339290067Sbapt * When we start parsing message pack chunk, we must ensure that we 1340290067Sbapt * have either a valid container or the top object inside message pack is 1341290067Sbapt * of container type 1342290067Sbapt */ 1343290067Sbapt if (container == NULL) { 1344290067Sbapt if ((*p & 0x80) != 0x80 && !(*p >= 0xdc && *p <= 0xdf)) { 1345290067Sbapt ucl_create_err (&parser->err, "bad top level object for msgpack"); 1346290067Sbapt return false; 1347290067Sbapt } 1348290067Sbapt } 1349290067Sbapt 1350290067Sbapt ret = ucl_msgpack_consume (parser); 1351290067Sbapt 1352290067Sbapt if (ret && parser->top_obj == NULL) { 1353290067Sbapt parser->top_obj = parser->cur_obj; 1354290067Sbapt } 1355290067Sbapt 1356290067Sbapt return ret; 1357290067Sbapt} 1358290067Sbapt 1359290067Sbaptstatic ssize_t 1360290067Sbaptucl_msgpack_parse_map (struct ucl_parser *parser, 1361290067Sbapt struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, 1362290067Sbapt const unsigned char *pos, size_t remain) 1363290067Sbapt{ 1364290067Sbapt container->obj = parser->cur_obj; 1365290067Sbapt 1366290067Sbapt return 0; 1367290067Sbapt} 1368290067Sbapt 1369290067Sbaptstatic ssize_t 1370290067Sbaptucl_msgpack_parse_array (struct ucl_parser *parser, 1371290067Sbapt struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, 1372290067Sbapt const unsigned char *pos, size_t remain) 1373290067Sbapt{ 1374290067Sbapt container->obj = parser->cur_obj; 1375290067Sbapt 1376290067Sbapt return 0; 1377290067Sbapt} 1378290067Sbapt 1379290067Sbaptstatic ssize_t 1380290067Sbaptucl_msgpack_parse_string (struct ucl_parser *parser, 1381290067Sbapt struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, 1382290067Sbapt const unsigned char *pos, size_t remain) 1383290067Sbapt{ 1384290067Sbapt ucl_object_t *obj; 1385290067Sbapt 1386290067Sbapt if (len > remain) { 1387290067Sbapt return -1; 1388290067Sbapt } 1389290067Sbapt 1390290067Sbapt obj = ucl_object_new_full (UCL_STRING, parser->chunks->priority); 1391290067Sbapt obj->value.sv = pos; 1392290067Sbapt obj->len = len; 1393290067Sbapt 1394290067Sbapt if (fmt >= msgpack_bin8 && fmt <= msgpack_bin32) { 1395290067Sbapt obj->flags |= UCL_OBJECT_BINARY; 1396290067Sbapt } 1397290067Sbapt 1398290067Sbapt if (!(parser->flags & UCL_PARSER_ZEROCOPY)) { 1399290067Sbapt if (obj->flags & UCL_OBJECT_BINARY) { 1400290067Sbapt obj->trash_stack[UCL_TRASH_VALUE] = malloc (len); 1401290067Sbapt 1402290067Sbapt if (obj->trash_stack[UCL_TRASH_VALUE] != NULL) { 1403290067Sbapt memcpy (obj->trash_stack[UCL_TRASH_VALUE], pos, len); 1404290067Sbapt } 1405290067Sbapt } 1406290067Sbapt else { 1407290067Sbapt ucl_copy_value_trash (obj); 1408290067Sbapt } 1409290067Sbapt } 1410290067Sbapt 1411290067Sbapt parser->cur_obj = obj; 1412290067Sbapt 1413290067Sbapt return len; 1414290067Sbapt} 1415290067Sbapt 1416290067Sbaptstatic ssize_t 1417290067Sbaptucl_msgpack_parse_int (struct ucl_parser *parser, 1418290067Sbapt struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, 1419290067Sbapt const unsigned char *pos, size_t remain) 1420290067Sbapt{ 1421290067Sbapt ucl_object_t *obj; 1422298166Sbapt int8_t iv8; 1423298166Sbapt int16_t iv16; 1424298166Sbapt int32_t iv32; 1425298166Sbapt int64_t iv64; 1426301339Sbapt uint16_t uiv16; 1427301339Sbapt uint32_t uiv32; 1428301339Sbapt uint64_t uiv64; 1429290067Sbapt 1430301339Sbapt 1431290067Sbapt if (len > remain) { 1432290067Sbapt return -1; 1433290067Sbapt } 1434290067Sbapt 1435290067Sbapt obj = ucl_object_new_full (UCL_INT, parser->chunks->priority); 1436290067Sbapt 1437290067Sbapt switch (fmt) { 1438290067Sbapt case msgpack_positive_fixint: 1439290067Sbapt obj->value.iv = (*pos & 0x7f); 1440290067Sbapt len = 1; 1441290067Sbapt break; 1442290067Sbapt case msgpack_negative_fixint: 1443290067Sbapt obj->value.iv = - (*pos & 0x1f); 1444290067Sbapt len = 1; 1445290067Sbapt break; 1446290067Sbapt case msgpack_uint8: 1447290067Sbapt obj->value.iv = (unsigned char)*pos; 1448290067Sbapt len = 1; 1449290067Sbapt break; 1450290067Sbapt case msgpack_int8: 1451298166Sbapt memcpy (&iv8, pos, sizeof (iv8)); 1452298166Sbapt obj->value.iv = iv8; 1453290067Sbapt len = 1; 1454290067Sbapt break; 1455290067Sbapt case msgpack_int16: 1456298166Sbapt memcpy (&iv16, pos, sizeof (iv16)); 1457298166Sbapt iv16 = FROM_BE16 (iv16); 1458298166Sbapt obj->value.iv = iv16; 1459290067Sbapt len = 2; 1460290067Sbapt break; 1461290067Sbapt case msgpack_uint16: 1462301339Sbapt memcpy (&uiv16, pos, sizeof (uiv16)); 1463301339Sbapt uiv16 = FROM_BE16 (uiv16); 1464301339Sbapt obj->value.iv = uiv16; 1465290067Sbapt len = 2; 1466290067Sbapt break; 1467290067Sbapt case msgpack_int32: 1468298166Sbapt memcpy (&iv32, pos, sizeof (iv32)); 1469298166Sbapt iv32 = FROM_BE32 (iv32); 1470298166Sbapt obj->value.iv = iv32; 1471290067Sbapt len = 4; 1472290067Sbapt break; 1473290067Sbapt case msgpack_uint32: 1474301339Sbapt memcpy(&uiv32, pos, sizeof(uiv32)); 1475301339Sbapt uiv32 = FROM_BE32(uiv32); 1476301339Sbapt obj->value.iv = uiv32; 1477290067Sbapt len = 4; 1478290067Sbapt break; 1479290067Sbapt case msgpack_int64: 1480298166Sbapt memcpy (&iv64, pos, sizeof (iv64)); 1481298166Sbapt iv64 = FROM_BE64 (iv64); 1482298166Sbapt obj->value.iv = iv64; 1483290067Sbapt len = 8; 1484290067Sbapt break; 1485290067Sbapt case msgpack_uint64: 1486301339Sbapt memcpy(&uiv64, pos, sizeof(uiv64)); 1487301339Sbapt uiv64 = FROM_BE64(uiv64); 1488301339Sbapt obj->value.iv = uiv64; 1489290067Sbapt len = 8; 1490290067Sbapt break; 1491290067Sbapt default: 1492290067Sbapt assert (0); 1493290067Sbapt break; 1494290067Sbapt } 1495290067Sbapt 1496290067Sbapt parser->cur_obj = obj; 1497290067Sbapt 1498290067Sbapt return len; 1499290067Sbapt} 1500290067Sbapt 1501290067Sbaptstatic ssize_t 1502290067Sbaptucl_msgpack_parse_float (struct ucl_parser *parser, 1503290067Sbapt struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, 1504290067Sbapt const unsigned char *pos, size_t remain) 1505290067Sbapt{ 1506290067Sbapt ucl_object_t *obj; 1507290067Sbapt union { 1508290067Sbapt uint32_t i; 1509290067Sbapt float f; 1510290067Sbapt } d; 1511301339Sbapt uint64_t uiv64; 1512290067Sbapt 1513290067Sbapt if (len > remain) { 1514290067Sbapt return -1; 1515290067Sbapt } 1516290067Sbapt 1517290067Sbapt obj = ucl_object_new_full (UCL_FLOAT, parser->chunks->priority); 1518290067Sbapt 1519290067Sbapt switch (fmt) { 1520290067Sbapt case msgpack_float32: 1521301339Sbapt memcpy(&d.i, pos, sizeof(d.i)); 1522301339Sbapt d.i = FROM_BE32(d.i); 1523290067Sbapt /* XXX: can be slow */ 1524290067Sbapt obj->value.dv = d.f; 1525290067Sbapt len = 4; 1526290067Sbapt break; 1527290067Sbapt case msgpack_float64: 1528301339Sbapt memcpy(&uiv64, pos, sizeof(uiv64)); 1529301339Sbapt uiv64 = FROM_BE64(uiv64); 1530301339Sbapt obj->value.iv = uiv64; 1531290067Sbapt len = 8; 1532290067Sbapt break; 1533290067Sbapt default: 1534290067Sbapt assert (0); 1535290067Sbapt break; 1536290067Sbapt } 1537290067Sbapt 1538290067Sbapt parser->cur_obj = obj; 1539290067Sbapt 1540290067Sbapt return len; 1541290067Sbapt} 1542290067Sbapt 1543290067Sbaptstatic ssize_t 1544290067Sbaptucl_msgpack_parse_bool (struct ucl_parser *parser, 1545290067Sbapt struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, 1546290067Sbapt const unsigned char *pos, size_t remain) 1547290067Sbapt{ 1548290067Sbapt ucl_object_t *obj; 1549290067Sbapt 1550290067Sbapt if (len > remain) { 1551290067Sbapt return -1; 1552290067Sbapt } 1553290067Sbapt 1554290067Sbapt obj = ucl_object_new_full (UCL_BOOLEAN, parser->chunks->priority); 1555290067Sbapt 1556290067Sbapt switch (fmt) { 1557290067Sbapt case msgpack_true: 1558290067Sbapt obj->value.iv = true; 1559290067Sbapt break; 1560290067Sbapt case msgpack_false: 1561290067Sbapt obj->value.iv = false; 1562290067Sbapt break; 1563290067Sbapt default: 1564290067Sbapt assert (0); 1565290067Sbapt break; 1566290067Sbapt } 1567290067Sbapt 1568290067Sbapt parser->cur_obj = obj; 1569290067Sbapt 1570290067Sbapt return 1; 1571290067Sbapt} 1572290067Sbapt 1573290067Sbaptstatic ssize_t 1574290067Sbaptucl_msgpack_parse_null (struct ucl_parser *parser, 1575290067Sbapt struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, 1576290067Sbapt const unsigned char *pos, size_t remain) 1577290067Sbapt{ 1578290067Sbapt ucl_object_t *obj; 1579290067Sbapt 1580290067Sbapt if (len > remain) { 1581290067Sbapt return -1; 1582290067Sbapt } 1583290067Sbapt 1584290067Sbapt obj = ucl_object_new_full (UCL_NULL, parser->chunks->priority); 1585290067Sbapt parser->cur_obj = obj; 1586290067Sbapt 1587290067Sbapt return 1; 1588290067Sbapt} 1589290067Sbapt 1590290067Sbaptstatic ssize_t 1591290067Sbaptucl_msgpack_parse_ignore (struct ucl_parser *parser, 1592290067Sbapt struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, 1593290067Sbapt const unsigned char *pos, size_t remain) 1594290067Sbapt{ 1595290067Sbapt if (len > remain) { 1596290067Sbapt return -1; 1597290067Sbapt } 1598290067Sbapt 1599290067Sbapt switch (fmt) { 1600290067Sbapt case msgpack_fixext1: 1601290067Sbapt len = 2; 1602290067Sbapt break; 1603290067Sbapt case msgpack_fixext2: 1604290067Sbapt len = 3; 1605290067Sbapt break; 1606290067Sbapt case msgpack_fixext4: 1607290067Sbapt len = 5; 1608290067Sbapt break; 1609290067Sbapt case msgpack_fixext8: 1610290067Sbapt len = 9; 1611290067Sbapt break; 1612290067Sbapt case msgpack_fixext16: 1613290067Sbapt len = 17; 1614290067Sbapt break; 1615290067Sbapt case msgpack_ext8: 1616290067Sbapt case msgpack_ext16: 1617290067Sbapt case msgpack_ext32: 1618290067Sbapt len = len + 1; 1619290067Sbapt break; 1620290067Sbapt default: 1621290067Sbapt ucl_create_err (&parser->err, "bad type: %x", (unsigned)fmt); 1622290067Sbapt return -1; 1623290067Sbapt } 1624290067Sbapt 1625290067Sbapt return len; 1626290067Sbapt} 1627