LCOV - code coverage report
Current view: top level - external/libucl/src - ucl_msgpack.c (source / functions) Hit Total Coverage
Test: rapport Lines: 0 602 0.0 %
Date: 2021-12-10 16:22:55 Functions: 0 24 0.0 %
Branches: 0 274 0.0 %

           Branch data     Line data    Source code
       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                 :          0 : ucl_emitter_print_int_msgpack (struct ucl_emitter_context *ctx, int64_t val)
     102                 :            : {
     103                 :          0 :         const struct ucl_emitter_functions *func = ctx->func;
     104                 :            :         unsigned char buf[sizeof(uint64_t) + 1];
     105                 :          0 :         const unsigned char mask_positive = 0x7f, mask_negative = 0xe0,
     106                 :          0 :                 uint8_ch = 0xcc, uint16_ch = 0xcd, uint32_ch = 0xce, uint64_ch = 0xcf,
     107                 :          0 :                 int8_ch = 0xd0, int16_ch = 0xd1, int32_ch = 0xd2, int64_ch = 0xd3;
     108                 :            :         unsigned len;
     109                 :            : 
     110         [ #  # ]:          0 :         if (val >= 0) {
     111         [ #  # ]:          0 :                 if (val <= 0x7f) {
     112                 :            :                         /* Fixed num 7 bits */
     113                 :          0 :                         len = 1;
     114                 :          0 :                         buf[0] = mask_positive & val;
     115                 :          0 :                 }
     116         [ #  # ]:          0 :                 else if (val <= UINT8_MAX) {
     117                 :          0 :                         len = 2;
     118                 :          0 :                         buf[0] = uint8_ch;
     119                 :          0 :                         buf[1] = val & 0xff;
     120                 :          0 :                 }
     121         [ #  # ]:          0 :                 else if (val <= UINT16_MAX) {
     122                 :          0 :                         uint16_t v = TO_BE16 (val);
     123                 :            : 
     124                 :          0 :                         len = 3;
     125                 :          0 :                         buf[0] = uint16_ch;
     126                 :          0 :                         memcpy (&buf[1], &v, sizeof (v));
     127                 :          0 :                 }
     128         [ #  # ]:          0 :                 else if (val <= UINT32_MAX) {
     129                 :          0 :                         uint32_t v = TO_BE32 (val);
     130                 :            : 
     131                 :          0 :                         len = 5;
     132                 :          0 :                         buf[0] = uint32_ch;
     133                 :          0 :                         memcpy (&buf[1], &v, sizeof (v));
     134                 :          0 :                 }
     135                 :            :                 else {
     136                 :          0 :                         uint64_t v = TO_BE64 (val);
     137                 :            : 
     138                 :          0 :                         len = 9;
     139                 :          0 :                         buf[0] = uint64_ch;
     140                 :          0 :                         memcpy (&buf[1], &v, sizeof (v));
     141                 :            :                 }
     142                 :          0 :         }
     143                 :            :         else {
     144                 :            :                 uint64_t uval;
     145                 :            :                 /* Bithack abs */
     146                 :          0 :                 uval = ((val ^ (val >> 63)) - (val >> 63));
     147                 :            : 
     148         [ #  # ]:          0 :                 if (val > -(1 << 5)) {
     149                 :          0 :                         len = 1;
     150                 :          0 :                         buf[0] = (mask_negative | uval) & 0xff;
     151                 :          0 :                 }
     152         [ #  # ]:          0 :                 else if (uval <= INT8_MAX) {
     153                 :          0 :                         uint8_t v = (uint8_t)val;
     154                 :          0 :                         len = 2;
     155                 :          0 :                         buf[0] = int8_ch;
     156                 :          0 :                         buf[1] = v;
     157                 :          0 :                 }
     158         [ #  # ]:          0 :                 else if (uval <= INT16_MAX) {
     159                 :          0 :                         uint16_t v = TO_BE16 (val);
     160                 :            : 
     161                 :          0 :                         len = 3;
     162                 :          0 :                         buf[0] = int16_ch;
     163                 :          0 :                         memcpy (&buf[1], &v, sizeof (v));
     164                 :          0 :                 }
     165         [ #  # ]:          0 :                 else if (uval <= INT32_MAX) {
     166                 :          0 :                         uint32_t v = TO_BE32 (val);
     167                 :            : 
     168                 :          0 :                         len = 5;
     169                 :          0 :                         buf[0] = int32_ch;
     170                 :          0 :                         memcpy (&buf[1], &v, sizeof (v));
     171                 :          0 :                 }
     172                 :            :                 else {
     173                 :          0 :                         uint64_t v = TO_BE64 (val);
     174                 :            : 
     175                 :          0 :                         len = 9;
     176                 :          0 :                         buf[0] = int64_ch;
     177                 :          0 :                         memcpy (&buf[1], &v, sizeof (v));
     178                 :            :                 }
     179                 :            :         }
     180                 :            : 
     181                 :          0 :         func->ucl_emitter_append_len (buf, len, func->ud);
     182                 :          0 : }
     183                 :            : 
     184                 :            : void
     185                 :          0 : ucl_emitter_print_double_msgpack (struct ucl_emitter_context *ctx, double val)
     186                 :            : {
     187                 :          0 :         const struct ucl_emitter_functions *func = ctx->func;
     188                 :            :         union {
     189                 :            :                 double d;
     190                 :            :                 uint64_t i;
     191                 :            :         } u;
     192                 :          0 :         const unsigned char dbl_ch = 0xcb;
     193                 :            :         unsigned char buf[sizeof(double) + 1];
     194                 :            : 
     195                 :            :         /* Convert to big endian */
     196                 :          0 :         u.d = val;
     197                 :          0 :         u.i = TO_BE64 (u.i);
     198                 :            : 
     199                 :          0 :         buf[0] = dbl_ch;
     200                 :          0 :         memcpy (&buf[1], &u.d, sizeof (double));
     201                 :          0 :         func->ucl_emitter_append_len (buf, sizeof (buf), func->ud);
     202                 :          0 : }
     203                 :            : 
     204                 :            : void
     205                 :          0 : ucl_emitter_print_bool_msgpack (struct ucl_emitter_context *ctx, bool val)
     206                 :            : {
     207                 :          0 :         const struct ucl_emitter_functions *func = ctx->func;
     208                 :          0 :         const unsigned char true_ch = 0xc3, false_ch = 0xc2;
     209                 :            : 
     210                 :          0 :         func->ucl_emitter_append_character (val ? true_ch : false_ch, 1, func->ud);
     211                 :          0 : }
     212                 :            : 
     213                 :            : void
     214                 :          0 : ucl_emitter_print_string_msgpack (struct ucl_emitter_context *ctx,
     215                 :            :                 const char *s, size_t len)
     216                 :            : {
     217                 :          0 :         const struct ucl_emitter_functions *func = ctx->func;
     218                 :          0 :         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         [ #  # ]:          0 :         if (len <= 0x1F) {
     223                 :          0 :                 blen = 1;
     224                 :          0 :                 buf[0] = (len | fix_mask) & 0xff;
     225                 :          0 :         }
     226         [ #  # ]:          0 :         else if (len <= 0xff) {
     227                 :          0 :                 blen = 2;
     228                 :          0 :                 buf[0] = l8_ch;
     229                 :          0 :                 buf[1] = len & 0xff;
     230                 :          0 :         }
     231         [ #  # ]:          0 :         else if (len <= 0xffff) {
     232                 :          0 :                 uint16_t bl = TO_BE16 (len);
     233                 :            : 
     234                 :          0 :                 blen = 3;
     235                 :          0 :                 buf[0] = l16_ch;
     236                 :          0 :                 memcpy (&buf[1], &bl, sizeof (bl));
     237                 :          0 :         }
     238                 :            :         else {
     239                 :          0 :                 uint32_t bl = TO_BE32 (len);
     240                 :            : 
     241                 :          0 :                 blen = 5;
     242                 :          0 :                 buf[0] = l32_ch;
     243                 :          0 :                 memcpy (&buf[1], &bl, sizeof (bl));
     244                 :            :         }
     245                 :            : 
     246                 :          0 :         func->ucl_emitter_append_len (buf, blen, func->ud);
     247                 :          0 :         func->ucl_emitter_append_len (s, len, func->ud);
     248                 :          0 : }
     249                 :            : 
     250                 :            : void
     251                 :          0 : ucl_emitter_print_binary_string_msgpack (struct ucl_emitter_context *ctx,
     252                 :            :                 const char *s, size_t len)
     253                 :            : {
     254                 :          0 :         const struct ucl_emitter_functions *func = ctx->func;
     255                 :          0 :         const unsigned char l8_ch = 0xc4, l16_ch = 0xc5, l32_ch = 0xc6;
     256                 :            :         unsigned char buf[5];
     257                 :            :         unsigned blen;
     258                 :            : 
     259         [ #  # ]:          0 :         if (len <= 0xff) {
     260                 :          0 :                 blen = 2;
     261                 :          0 :                 buf[0] = l8_ch;
     262                 :          0 :                 buf[1] = len & 0xff;
     263                 :          0 :         }
     264         [ #  # ]:          0 :         else if (len <= 0xffff) {
     265                 :          0 :                 uint16_t bl = TO_BE16 (len);
     266                 :            : 
     267                 :          0 :                 blen = 3;
     268                 :          0 :                 buf[0] = l16_ch;
     269                 :          0 :                 memcpy (&buf[1], &bl, sizeof (bl));
     270                 :          0 :         }
     271                 :            :         else {
     272                 :          0 :                 uint32_t bl = TO_BE32 (len);
     273                 :            : 
     274                 :          0 :                 blen = 5;
     275                 :          0 :                 buf[0] = l32_ch;
     276                 :          0 :                 memcpy (&buf[1], &bl, sizeof (bl));
     277                 :            :         }
     278                 :            : 
     279                 :          0 :         func->ucl_emitter_append_len (buf, blen, func->ud);
     280                 :          0 :         func->ucl_emitter_append_len (s, len, func->ud);
     281                 :          0 : }
     282                 :            : 
     283                 :            : void
     284                 :          0 : ucl_emitter_print_null_msgpack (struct ucl_emitter_context *ctx)
     285                 :            : {
     286                 :          0 :         const struct ucl_emitter_functions *func = ctx->func;
     287                 :          0 :         const unsigned char nil = 0xc0;
     288                 :            : 
     289                 :          0 :         func->ucl_emitter_append_character (nil, 1, func->ud);
     290                 :          0 : }
     291                 :            : 
     292                 :            : void
     293                 :          0 : ucl_emitter_print_key_msgpack (bool print_key, struct ucl_emitter_context *ctx,
     294                 :            :                 const ucl_object_t *obj)
     295                 :            : {
     296         [ #  # ]:          0 :         if (print_key) {
     297                 :          0 :                 ucl_emitter_print_string_msgpack (ctx, obj->key, obj->keylen);
     298                 :          0 :         }
     299                 :          0 : }
     300                 :            : 
     301                 :            : void
     302                 :          0 : ucl_emitter_print_array_msgpack (struct ucl_emitter_context *ctx, size_t len)
     303                 :            : {
     304                 :          0 :         const struct ucl_emitter_functions *func = ctx->func;
     305                 :          0 :         const unsigned char fix_mask = 0x90, l16_ch = 0xdc, l32_ch = 0xdd;
     306                 :            :         unsigned char buf[5];
     307                 :            :         unsigned blen;
     308                 :            : 
     309         [ #  # ]:          0 :         if (len <= 0xF) {
     310                 :          0 :                 blen = 1;
     311                 :          0 :                 buf[0] = (len | fix_mask) & 0xff;
     312                 :          0 :         }
     313         [ #  # ]:          0 :         else if (len <= 0xffff) {
     314                 :          0 :                 uint16_t bl = TO_BE16 (len);
     315                 :            : 
     316                 :          0 :                 blen = 3;
     317                 :          0 :                 buf[0] = l16_ch;
     318                 :          0 :                 memcpy (&buf[1], &bl, sizeof (bl));
     319                 :          0 :         }
     320                 :            :         else {
     321                 :          0 :                 uint32_t bl = TO_BE32 (len);
     322                 :            : 
     323                 :          0 :                 blen = 5;
     324                 :          0 :                 buf[0] = l32_ch;
     325                 :          0 :                 memcpy (&buf[1], &bl, sizeof (bl));
     326                 :            :         }
     327                 :            : 
     328                 :          0 :         func->ucl_emitter_append_len (buf, blen, func->ud);
     329                 :          0 : }
     330                 :            : 
     331                 :            : void
     332                 :          0 : ucl_emitter_print_object_msgpack (struct ucl_emitter_context *ctx, size_t len)
     333                 :            : {
     334                 :          0 :         const struct ucl_emitter_functions *func = ctx->func;
     335                 :          0 :         const unsigned char fix_mask = 0x80, l16_ch = 0xde, l32_ch = 0xdf;
     336                 :            :         unsigned char buf[5];
     337                 :            :         unsigned blen;
     338                 :            : 
     339         [ #  # ]:          0 :         if (len <= 0xF) {
     340                 :          0 :                 blen = 1;
     341                 :          0 :                 buf[0] = (len | fix_mask) & 0xff;
     342                 :          0 :         }
     343         [ #  # ]:          0 :         else if (len <= 0xffff) {
     344                 :          0 :                 uint16_t bl = TO_BE16 (len);
     345                 :            : 
     346                 :          0 :                 blen = 3;
     347                 :          0 :                 buf[0] = l16_ch;
     348                 :          0 :                 memcpy (&buf[1], &bl, sizeof (bl));
     349                 :          0 :         }
     350                 :            :         else {
     351                 :          0 :                 uint32_t bl = TO_BE32 (len);
     352                 :            : 
     353                 :          0 :                 blen = 5;
     354                 :          0 :                 buf[0] = l32_ch;
     355                 :          0 :                 memcpy (&buf[1], &bl, sizeof (bl));
     356                 :            :         }
     357                 :            : 
     358                 :          0 :         func->ucl_emitter_append_len (buf, blen, func->ud);
     359                 :          0 : }
     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                 :          0 : ucl_msgpack_get_parser_from_type (unsigned char t)
     746                 :            : {
     747                 :            :         unsigned int i, shift, mask;
     748                 :            : 
     749         [ #  # ]:          0 :         for (i = 0; i < sizeof (parsers) / sizeof (parsers[0]); i ++) {
     750                 :          0 :                 shift = CHAR_BIT - parsers[i].prefixlen;
     751                 :          0 :                 mask = parsers[i].prefix >> shift;
     752                 :            : 
     753         [ #  # ]:          0 :                 if (mask == (((unsigned int)t) >> shift)) {
     754                 :          0 :                         return &parsers[i];
     755                 :            :                 }
     756                 :          0 :         }
     757                 :            : 
     758                 :          0 :         return NULL;
     759                 :          0 : }
     760                 :            : 
     761                 :            : static inline struct ucl_stack *
     762                 :          0 : 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         [ #  # ]:          0 :         assert (obj_parser != NULL);
     768                 :            : 
     769         [ #  # ]:          0 :         if (obj_parser->flags & MSGPACK_FLAG_CONTAINER) {
     770                 :            :                 /*
     771                 :            :                  * Insert new container to the stack
     772                 :            :                  */
     773         [ #  # ]:          0 :                 if (parser->stack == NULL) {
     774                 :          0 :                         parser->stack = calloc (1, sizeof (struct ucl_stack));
     775                 :            : 
     776         [ #  # ]:          0 :                         if (parser->stack == NULL) {
     777                 :          0 :                                 ucl_create_err (&parser->err, "no memory");
     778                 :          0 :                                 return NULL;
     779                 :            :                         }
     780                 :            : 
     781                 :          0 :                         parser->stack->chunk = parser->chunks;
     782                 :          0 :                 }
     783                 :            :                 else {
     784                 :          0 :                         stack = calloc (1, sizeof (struct ucl_stack));
     785                 :            : 
     786         [ #  # ]:          0 :                         if (stack == NULL) {
     787                 :          0 :                                 ucl_create_err (&parser->err, "no memory");
     788                 :          0 :                                 return NULL;
     789                 :            :                         }
     790                 :            : 
     791                 :          0 :                         stack->chunk = parser->chunks;
     792                 :          0 :                         stack->next = parser->stack;
     793                 :          0 :                         parser->stack = stack;
     794                 :            :                 }
     795                 :            : 
     796                 :          0 :                 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                 :          0 :         }
     808                 :            :         else {
     809                 :            :                 /*
     810                 :            :                  * Get the current stack top
     811                 :            :                  */
     812         [ #  # ]:          0 :                 if (parser->stack) {
     813                 :          0 :                         return parser->stack;
     814                 :            :                 }
     815                 :            :                 else {
     816                 :          0 :                         ucl_create_err (&parser->err, "bad top level object for msgpack");
     817                 :          0 :                         return NULL;
     818                 :            :                 }
     819                 :            :         }
     820                 :            : 
     821                 :          0 :         return parser->stack;
     822                 :          0 : }
     823                 :            : 
     824                 :            : static bool
     825                 :          0 : ucl_msgpack_is_container_finished (struct ucl_stack *container)
     826                 :            : {
     827         [ #  # ]:          0 :         assert (container != NULL);
     828                 :            : 
     829                 :            : 
     830         [ #  # ]:          0 :         if (container->e.len == 0) {
     831                 :          0 :                 return true;
     832                 :            :         }
     833                 :            : 
     834                 :          0 :         return false;
     835                 :          0 : }
     836                 :            : 
     837                 :            : static bool
     838                 :          0 : 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                 :          0 :         container = parser->stack;
     845         [ #  # ]:          0 :         assert (container != NULL);
     846         [ #  # ]:          0 :         assert (container->e.len > 0);
     847         [ #  # ]:          0 :         assert (obj != NULL);
     848         [ #  # ]:          0 :         assert (container->obj != NULL);
     849                 :            : 
     850         [ #  # ]:          0 :         if (container->obj->type == UCL_ARRAY) {
     851                 :          0 :                 ucl_array_append (container->obj, obj);
     852                 :          0 :         }
     853         [ #  # ]:          0 :         else if (container->obj->type == UCL_OBJECT) {
     854   [ #  #  #  # ]:          0 :                 if (key == NULL || keylen == 0) {
     855                 :          0 :                         ucl_create_err (&parser->err, "cannot insert object with no key");
     856                 :          0 :                         return false;
     857                 :            :                 }
     858                 :            : 
     859                 :          0 :                 obj->key = key;
     860                 :          0 :                 obj->keylen = keylen;
     861                 :            : 
     862         [ #  # ]:          0 :                 if (!(parser->flags & UCL_PARSER_ZEROCOPY)) {
     863                 :          0 :                         ucl_copy_key_trash (obj);
     864                 :          0 :                 }
     865                 :            : 
     866                 :          0 :                 ucl_parser_process_object_element (parser, obj);
     867                 :          0 :         }
     868                 :            :         else {
     869                 :          0 :                 ucl_create_err (&parser->err, "bad container type");
     870                 :          0 :                 return false;
     871                 :            :         }
     872                 :            : 
     873                 :          0 :         container->e.len--;
     874                 :            : 
     875                 :          0 :         return true;
     876                 :          0 : }
     877                 :            : 
     878                 :            : static struct ucl_stack *
     879                 :          0 : ucl_msgpack_get_next_container (struct ucl_parser *parser)
     880                 :            : {
     881                 :          0 :         struct ucl_stack *cur = NULL;
     882                 :            :         uint64_t len;
     883                 :            : 
     884                 :          0 :         cur = parser->stack;
     885                 :            : 
     886         [ #  # ]:          0 :         if (cur == NULL) {
     887                 :          0 :                 return NULL;
     888                 :            :         }
     889                 :            : 
     890                 :          0 :         len = cur->e.len;
     891                 :            : 
     892         [ #  # ]:          0 :         if (len == 0) {
     893                 :            :                 /* We need to switch to the previous container */
     894                 :          0 :                 parser->stack = cur->next;
     895                 :          0 :                 parser->cur_obj = cur->obj;
     896                 :          0 :                 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                 :          0 :                 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         [ #  # ]:          0 :         assert (cur->obj != NULL);
     916                 :            : 
     917                 :          0 :         return cur;
     918                 :          0 : }
     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                 :          0 : ucl_msgpack_consume (struct ucl_parser *parser)
     949                 :            : {
     950                 :          0 :         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                 :          0 :         } state = read_type, next_state = error_state;
     963                 :          0 :         struct ucl_msgpack_parser *obj_parser = NULL;
     964                 :          0 :         uint64_t len = 0;
     965                 :          0 :         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                 :          0 :         p = parser->chunks->begin;
     972                 :          0 :         remain = parser->chunks->remain;
     973                 :          0 :         end = p + remain;
     974                 :            : 
     975                 :            : 
     976         [ #  # ]:          0 :         while (p < end) {
     977                 :            : #ifdef MSGPACK_DEBUG_PARSER
     978                 :            :                 hist[i++ % 256] = state;
     979                 :            : #endif
     980   [ #  #  #  #  :          0 :                 switch (state) {
             #  #  #  #  
                      # ]
     981                 :            :                 case read_type:
     982                 :          0 :                         obj_parser = ucl_msgpack_get_parser_from_type (*p);
     983                 :            : 
     984         [ #  # ]:          0 :                         if (obj_parser == NULL) {
     985                 :          0 :                                 ucl_create_err (&parser->err, "unknown msgpack format: %x",
     986                 :          0 :                                                 (unsigned int)*p);
     987                 :            : 
     988                 :          0 :                                 return false;
     989                 :            :                         }
     990                 :            :                         /* Now check length sanity */
     991         [ #  # ]:          0 :                         if (obj_parser->flags & MSGPACK_FLAG_FIXED) {
     992         [ #  # ]:          0 :                                 if (obj_parser->len == 0) {
     993                 :            :                                         /* We have an embedded size */
     994                 :          0 :                                         len = *p & ~obj_parser->prefix;
     995                 :          0 :                                 }
     996                 :            :                                 else {
     997         [ #  # ]:          0 :                                         if (remain < obj_parser->len) {
     998                 :          0 :                                                 ucl_create_err (&parser->err, "not enough data remain to "
     999                 :            :                                                                 "read object's length: %u remain, %u needed",
    1000                 :          0 :                                                                 (unsigned)remain, obj_parser->len);
    1001                 :            : 
    1002                 :          0 :                                                 return false;
    1003                 :            :                                         }
    1004                 :            : 
    1005                 :          0 :                                         len = obj_parser->len;
    1006                 :            :                                 }
    1007                 :            : 
    1008         [ #  # ]:          0 :                                 if (!(obj_parser->flags & MSGPACK_FLAG_TYPEVALUE)) {
    1009                 :            :                                         /* We must pass value as the second byte */
    1010         [ #  # ]:          0 :                                         if (remain > 0) {
    1011                 :          0 :                                                 p ++;
    1012                 :          0 :                                                 remain --;
    1013                 :          0 :                                         }
    1014                 :          0 :                                 }
    1015                 :            :                                 else {
    1016                 :            :                                         /* Len is irrelevant now */
    1017                 :          0 :                                         len = 0;
    1018                 :            :                                 }
    1019                 :          0 :                         }
    1020                 :            :                         else {
    1021                 :            :                                 /* Length is not embedded */
    1022                 :          0 :                                 remain --;
    1023                 :            : 
    1024         [ #  # ]:          0 :                                 if (remain < obj_parser->len) {
    1025                 :          0 :                                         ucl_create_err (&parser->err, "not enough data remain to "
    1026                 :            :                                                         "read object's length: %u remain, %u needed",
    1027                 :          0 :                                                         (unsigned)remain, obj_parser->len);
    1028                 :            : 
    1029                 :          0 :                                         return false;
    1030                 :            :                                 }
    1031                 :            : 
    1032                 :          0 :                                 p ++;
    1033                 :            : 
    1034   [ #  #  #  #  :          0 :                                 switch (obj_parser->len) {
                      # ]
    1035                 :            :                                 case 1:
    1036                 :          0 :                                         len = *p;
    1037                 :          0 :                                         break;
    1038                 :            :                                 case 2:
    1039                 :          0 :                                         len = FROM_BE16 (*(uint16_t *)p);
    1040                 :          0 :                                         break;
    1041                 :            :                                 case 4:
    1042                 :          0 :                                         len = FROM_BE32 (*(uint32_t *)p);
    1043                 :          0 :                                         break;
    1044                 :            :                                 case 8:
    1045                 :          0 :                                         len = FROM_BE64 (*(uint64_t *)p);
    1046                 :          0 :                                         break;
    1047                 :            :                                 default:
    1048                 :          0 :                                         ucl_create_err (&parser->err, "invalid length of the length field: %u",
    1049                 :          0 :                                                         (unsigned)obj_parser->len);
    1050                 :            : 
    1051                 :          0 :                                         return false;
    1052                 :            :                                 }
    1053                 :            : 
    1054                 :          0 :                                 p += obj_parser->len;
    1055                 :          0 :                                 remain -= obj_parser->len;
    1056                 :            :                         }
    1057                 :            : 
    1058         [ #  # ]:          0 :                         if (obj_parser->flags & MSGPACK_FLAG_ASSOC) {
    1059                 :            :                                 /* We have just read the new associative map */
    1060                 :          0 :                                 state = start_assoc;
    1061                 :          0 :                         }
    1062         [ #  # ]:          0 :                         else if (obj_parser->flags & MSGPACK_FLAG_CONTAINER){
    1063                 :          0 :                                 state = start_array;
    1064                 :          0 :                         }
    1065                 :            :                         else {
    1066                 :          0 :                                 state = next_state;
    1067                 :            :                         }
    1068                 :            : 
    1069                 :          0 :                         break;
    1070                 :            :                 case start_assoc:
    1071                 :          0 :                         parser->cur_obj = ucl_object_new_full (UCL_OBJECT,
    1072                 :          0 :                                         parser->chunks->priority);
    1073                 :            :                         /* Insert to the previous level container */
    1074   [ #  #  #  #  :          0 :                         if (parser->stack && !ucl_msgpack_insert_object (parser,
                   #  # ]
    1075                 :          0 :                                         key, keylen, parser->cur_obj)) {
    1076                 :          0 :                                 return false;
    1077                 :            :                         }
    1078                 :            :                         /* Get new container */
    1079                 :          0 :                         container = ucl_msgpack_get_container (parser, obj_parser, len);
    1080                 :            : 
    1081         [ #  # ]:          0 :                         if (container == NULL) {
    1082                 :          0 :                                 return false;
    1083                 :            :                         }
    1084                 :            : 
    1085                 :          0 :                         ret = obj_parser->func (parser, container, len, obj_parser->fmt,
    1086                 :          0 :                                         p, remain);
    1087   [ #  #  #  # ]:          0 :                         CONSUME_RET;
    1088                 :          0 :                         key = NULL;
    1089                 :          0 :                         keylen = 0;
    1090                 :            : 
    1091         [ #  # ]:          0 :                         if (len > 0) {
    1092                 :          0 :                                 state = read_type;
    1093                 :          0 :                                 next_state = read_assoc_key;
    1094                 :          0 :                         }
    1095                 :            :                         else {
    1096                 :            :                                 /* Empty object */
    1097                 :          0 :                                 state = finish_assoc_value;
    1098                 :            :                         }
    1099                 :          0 :                         break;
    1100                 :            : 
    1101                 :            :                 case start_array:
    1102                 :          0 :                         parser->cur_obj = ucl_object_new_full (UCL_ARRAY,
    1103                 :          0 :                                         parser->chunks->priority);
    1104                 :            :                         /* Insert to the previous level container */
    1105   [ #  #  #  #  :          0 :                         if (parser->stack && !ucl_msgpack_insert_object (parser,
                   #  # ]
    1106                 :          0 :                                         key, keylen, parser->cur_obj)) {
    1107                 :          0 :                                 return false;
    1108                 :            :                         }
    1109                 :            :                         /* Get new container */
    1110                 :          0 :                         container = ucl_msgpack_get_container (parser, obj_parser, len);
    1111                 :            : 
    1112         [ #  # ]:          0 :                         if (container == NULL) {
    1113                 :          0 :                                 return false;
    1114                 :            :                         }
    1115                 :            : 
    1116                 :          0 :                         ret = obj_parser->func (parser, container, len, obj_parser->fmt,
    1117                 :          0 :                                                                 p, remain);
    1118   [ #  #  #  # ]:          0 :                         CONSUME_RET;
    1119                 :            : 
    1120         [ #  # ]:          0 :                         if (len > 0) {
    1121                 :          0 :                                 state = read_type;
    1122                 :          0 :                                 next_state = read_array_value;
    1123                 :          0 :                         }
    1124                 :            :                         else {
    1125                 :            :                                 /* Empty array */
    1126                 :          0 :                                 state = finish_array_value;
    1127                 :            :                         }
    1128                 :          0 :                         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                 :          0 :                         container = parser->stack;
    1136                 :            : 
    1137         [ #  # ]:          0 :                         if (parser->stack == NULL) {
    1138                 :          0 :                                 ucl_create_err (&parser->err,
    1139                 :            :                                                 "read assoc value when no container represented");
    1140                 :          0 :                                 return false;
    1141                 :            :                         }
    1142                 :            : 
    1143                 :          0 :                         ret = obj_parser->func (parser, container, len, obj_parser->fmt,
    1144                 :          0 :                                         p, remain);
    1145   [ #  #  #  # ]:          0 :                         CONSUME_RET;
    1146                 :            : 
    1147                 :            : 
    1148                 :            :                         /* Insert value to the container and check if we have finished array */
    1149   [ #  #  #  # ]:          0 :                         if (!ucl_msgpack_insert_object (parser, NULL, 0,
    1150                 :          0 :                                         parser->cur_obj)) {
    1151                 :          0 :                                 return false;
    1152                 :            :                         }
    1153                 :            : 
    1154         [ #  # ]:          0 :                         if (ucl_msgpack_is_container_finished (container)) {
    1155                 :          0 :                                 state = finish_array_value;
    1156                 :          0 :                         }
    1157                 :            :                         else {
    1158                 :            :                                 /* Read more elements */
    1159                 :          0 :                                 state = read_type;
    1160                 :          0 :                                 next_state = read_array_value;
    1161                 :            :                         }
    1162                 :            : 
    1163                 :          0 :                         break;
    1164                 :            : 
    1165                 :            :                 case read_assoc_key:
    1166                 :            :                         /*
    1167                 :            :                          * Keys must have string type for ucl msgpack
    1168                 :            :                          */
    1169         [ #  # ]:          0 :                         if (!(obj_parser->flags & MSGPACK_FLAG_KEY)) {
    1170                 :          0 :                                 ucl_create_err (&parser->err, "bad type for key: %u, expected "
    1171                 :          0 :                                                 "string", (unsigned)obj_parser->fmt);
    1172                 :            : 
    1173                 :          0 :                                 return false;
    1174                 :            :                         }
    1175                 :            : 
    1176                 :          0 :                         key = p;
    1177                 :          0 :                         keylen = len;
    1178                 :            : 
    1179   [ #  #  #  # ]:          0 :                         if (keylen > remain || keylen == 0) {
    1180                 :          0 :                                 ucl_create_err (&parser->err, "too long or empty key");
    1181                 :          0 :                                 return false;
    1182                 :            :                         }
    1183                 :            : 
    1184                 :          0 :                         p += len;
    1185                 :          0 :                         remain -= len;
    1186                 :            : 
    1187                 :          0 :                         state = read_type;
    1188                 :          0 :                         next_state = read_assoc_value;
    1189                 :          0 :                         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                 :          0 :                         container = parser->stack;
    1197                 :            : 
    1198         [ #  # ]:          0 :                         if (container == NULL) {
    1199                 :          0 :                                 ucl_create_err (&parser->err,
    1200                 :            :                                                 "read assoc value when no container represented");
    1201                 :          0 :                                 return false;
    1202                 :            :                         }
    1203                 :            : 
    1204                 :          0 :                         ret = obj_parser->func (parser, container, len, obj_parser->fmt,
    1205                 :          0 :                                         p, remain);
    1206   [ #  #  #  # ]:          0 :                         CONSUME_RET;
    1207                 :            : 
    1208         [ #  # ]:          0 :                         assert (key != NULL && keylen > 0);
    1209                 :            : 
    1210   [ #  #  #  # ]:          0 :                         if (!ucl_msgpack_insert_object (parser, key, keylen,
    1211                 :          0 :                                         parser->cur_obj)) {
    1212                 :            : 
    1213                 :          0 :                                 return false;
    1214                 :            :                         }
    1215                 :            : 
    1216                 :          0 :                         key = NULL;
    1217                 :          0 :                         keylen = 0;
    1218                 :            : 
    1219         [ #  # ]:          0 :                         if (ucl_msgpack_is_container_finished (container)) {
    1220                 :          0 :                                 state = finish_assoc_value;
    1221                 :          0 :                         }
    1222                 :            :                         else {
    1223                 :            :                                 /* Read more elements */
    1224                 :          0 :                                 state = read_type;
    1225                 :          0 :                                 next_state = read_assoc_key;
    1226                 :            :                         }
    1227                 :          0 :                         break;
    1228                 :            : 
    1229                 :            :                 case finish_array_value:
    1230                 :            :                 case finish_assoc_value:
    1231         [ #  # ]:          0 :                         GET_NEXT_STATE;
    1232                 :          0 :                         state = read_type;
    1233                 :          0 :                         break;
    1234                 :            : 
    1235                 :            :                 case error_state:
    1236                 :          0 :                         ucl_create_err (&parser->err, "invalid state machine state");
    1237                 :            : 
    1238                 :          0 :                         return false;
    1239                 :            :                 }
    1240                 :            :         }
    1241                 :            : 
    1242                 :            :         /* Check the finishing state */
    1243   [ #  #  #  # ]:          0 :         switch (state) {
    1244                 :            :         case start_array:
    1245                 :            :         case start_assoc:
    1246                 :            :                 /* Empty container at the end */
    1247         [ #  # ]:          0 :                 if (len != 0) {
    1248                 :          0 :                         ucl_create_err (&parser->err,
    1249                 :            :                                         "invalid non-empty container at the end; len=%zu",
    1250                 :          0 :                                         (uintmax_t)len);
    1251                 :            : 
    1252                 :          0 :                         return false;
    1253                 :            :                 }
    1254                 :            : 
    1255                 :          0 :                 parser->cur_obj = ucl_object_new_full (
    1256                 :          0 :                                 state == start_array ? UCL_ARRAY : UCL_OBJECT,
    1257                 :          0 :                                 parser->chunks->priority);
    1258                 :            : 
    1259         [ #  # ]:          0 :                 if (parser->stack == NULL) {
    1260                 :          0 :                         ucl_create_err (&parser->err,
    1261                 :            :                                         "read assoc value when no container represented");
    1262                 :          0 :                         return false;
    1263                 :            :                 }
    1264                 :            :                 /* Insert to the previous level container */
    1265   [ #  #  #  # ]:          0 :                 if (!ucl_msgpack_insert_object (parser,
    1266                 :          0 :                                 key, keylen, parser->cur_obj)) {
    1267                 :          0 :                         return false;
    1268                 :            :                 }
    1269                 :            :                 /* Get new container */
    1270                 :          0 :                 container = ucl_msgpack_get_container (parser, obj_parser, len);
    1271                 :            : 
    1272         [ #  # ]:          0 :                 if (container == NULL) {
    1273                 :          0 :                         return false;
    1274                 :            :                 }
    1275                 :            : 
    1276                 :          0 :                 ret = obj_parser->func (parser, container, len, obj_parser->fmt,
    1277                 :          0 :                                 p, remain);
    1278                 :          0 :                 break;
    1279                 :            : 
    1280                 :            :         case read_array_value:
    1281                 :            :         case read_assoc_value:
    1282         [ #  # ]:          0 :                 if (len != 0) {
    1283                 :          0 :                         ucl_create_err (&parser->err, "unfinished value at the end");
    1284                 :            : 
    1285                 :          0 :                         return false;
    1286                 :            :                 }
    1287                 :            : 
    1288                 :          0 :                 container = parser->stack;
    1289                 :            : 
    1290         [ #  # ]:          0 :                 if (parser->stack == NULL) {
    1291                 :          0 :                         ucl_create_err (&parser->err,
    1292                 :            :                                         "read assoc value when no container represented");
    1293                 :          0 :                         return false;
    1294                 :            :                 }
    1295                 :            : 
    1296                 :          0 :                 ret = obj_parser->func (parser, container, len, obj_parser->fmt,
    1297                 :          0 :                                 p, remain);
    1298   [ #  #  #  # ]:          0 :                 CONSUME_RET;
    1299                 :            : 
    1300                 :            : 
    1301                 :            :                 /* Insert value to the container and check if we have finished array */
    1302   [ #  #  #  # ]:          0 :                 if (!ucl_msgpack_insert_object (parser, NULL, 0,
    1303                 :          0 :                                 parser->cur_obj)) {
    1304                 :          0 :                         return false;
    1305                 :            :                 }
    1306                 :          0 :                 break;
    1307                 :            :         case finish_array_value:
    1308                 :            :         case finish_assoc_value:
    1309                 :            :         case read_type:
    1310                 :            :                 /* Valid finishing state */
    1311                 :          0 :                 break;
    1312                 :            :         default:
    1313                 :            :                 /* Invalid finishing state */
    1314                 :          0 :                 ucl_create_err (&parser->err, "invalid state machine finishing state: %d",
    1315                 :          0 :                                 state);
    1316                 :            : 
    1317                 :          0 :                 return false;
    1318                 :            :         }
    1319                 :            : 
    1320                 :            :         /* Rewind to the top level container */
    1321                 :          0 :         ucl_msgpack_get_next_container (parser);
    1322                 :            : 
    1323         [ #  # ]:          0 :         if (parser->stack != NULL) {
    1324                 :          0 :                 ucl_create_err (&parser->err, "incomplete container");
    1325                 :            : 
    1326                 :          0 :                 return false;
    1327                 :            :         }
    1328                 :            : 
    1329                 :          0 :         return true;
    1330                 :          0 : }
    1331                 :            : 
    1332                 :            : bool
    1333                 :          0 : ucl_parse_msgpack (struct ucl_parser *parser)
    1334                 :            : {
    1335                 :          0 :         ucl_object_t *container = NULL;
    1336                 :            :         const unsigned char *p;
    1337                 :            :         bool ret;
    1338                 :            : 
    1339         [ #  # ]:          0 :         assert (parser != NULL);
    1340         [ #  # ]:          0 :         assert (parser->chunks != NULL);
    1341         [ #  # ]:          0 :         assert (parser->chunks->begin != NULL);
    1342         [ #  # ]:          0 :         assert (parser->chunks->remain != 0);
    1343                 :            : 
    1344                 :          0 :         p = parser->chunks->begin;
    1345                 :            : 
    1346         [ #  # ]:          0 :         if (parser->stack) {
    1347                 :          0 :                 container = parser->stack->obj;
    1348                 :          0 :         }
    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         [ #  # ]:          0 :         if (container == NULL) {
    1356   [ #  #  #  #  :          0 :                 if ((*p & 0x80) != 0x80 && !(*p >= 0xdc && *p <= 0xdf)) {
                   #  # ]
    1357                 :          0 :                         ucl_create_err (&parser->err, "bad top level object for msgpack");
    1358                 :          0 :                         return false;
    1359                 :            :                 }
    1360                 :          0 :         }
    1361                 :            : 
    1362                 :          0 :         ret = ucl_msgpack_consume (parser);
    1363                 :            : 
    1364   [ #  #  #  # ]:          0 :         if (ret && parser->top_obj == NULL) {
    1365                 :          0 :                 parser->top_obj = parser->cur_obj;
    1366                 :          0 :         }
    1367                 :            : 
    1368                 :          0 :         return ret;
    1369                 :          0 : }
    1370                 :            : 
    1371                 :            : static ssize_t
    1372                 :          0 : 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                 :          0 :         container->obj = parser->cur_obj;
    1377                 :            : 
    1378                 :          0 :         return 0;
    1379                 :            : }
    1380                 :            : 
    1381                 :            : static ssize_t
    1382                 :          0 : 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                 :          0 :         container->obj = parser->cur_obj;
    1387                 :            : 
    1388                 :          0 :         return 0;
    1389                 :            : }
    1390                 :            : 
    1391                 :            : static ssize_t
    1392                 :          0 : 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         [ #  # ]:          0 :         if (len > remain) {
    1399                 :          0 :                 return -1;
    1400                 :            :         }
    1401                 :            : 
    1402                 :          0 :         obj = ucl_object_new_full (UCL_STRING, parser->chunks->priority);
    1403                 :          0 :         obj->value.sv = pos;
    1404                 :          0 :         obj->len = len;
    1405                 :            : 
    1406   [ #  #  #  # ]:          0 :         if (fmt >= msgpack_bin8 && fmt <= msgpack_bin32) {
    1407                 :          0 :                 obj->flags |= UCL_OBJECT_BINARY;
    1408                 :          0 :         }
    1409                 :            : 
    1410         [ #  # ]:          0 :         if (!(parser->flags & UCL_PARSER_ZEROCOPY)) {
    1411         [ #  # ]:          0 :                 if (obj->flags & UCL_OBJECT_BINARY) {
    1412                 :          0 :                         obj->trash_stack[UCL_TRASH_VALUE] = malloc (len);
    1413                 :            : 
    1414         [ #  # ]:          0 :                         if (obj->trash_stack[UCL_TRASH_VALUE] != NULL) {
    1415                 :          0 :                                 memcpy (obj->trash_stack[UCL_TRASH_VALUE], pos, len);
    1416                 :          0 :                         }
    1417                 :          0 :                 }
    1418                 :            :                 else {
    1419                 :          0 :                         ucl_copy_value_trash (obj);
    1420                 :            :                 }
    1421                 :          0 :         }
    1422                 :            : 
    1423                 :          0 :         parser->cur_obj = obj;
    1424                 :            : 
    1425                 :          0 :         return len;
    1426                 :          0 : }
    1427                 :            : 
    1428                 :            : static ssize_t
    1429                 :          0 : 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         [ #  # ]:          0 :         if (len > remain) {
    1444                 :          0 :                 return -1;
    1445                 :            :         }
    1446                 :            : 
    1447                 :          0 :         obj = ucl_object_new_full (UCL_INT, parser->chunks->priority);
    1448                 :            : 
    1449   [ #  #  #  #  :          0 :         switch (fmt) {
          #  #  #  #  #  
                   #  # ]
    1450                 :            :         case msgpack_positive_fixint:
    1451                 :          0 :                 obj->value.iv = (*pos & 0x7f);
    1452                 :          0 :                 len = 1;
    1453                 :          0 :                 break;
    1454                 :            :         case msgpack_negative_fixint:
    1455                 :          0 :                 obj->value.iv = - (*pos & 0x1f);
    1456                 :          0 :                 len = 1;
    1457                 :          0 :                 break;
    1458                 :            :         case msgpack_uint8:
    1459                 :          0 :                 obj->value.iv = (unsigned char)*pos;
    1460                 :          0 :                 len = 1;
    1461                 :          0 :                 break;
    1462                 :            :         case msgpack_int8:
    1463                 :          0 :                 memcpy (&iv8, pos, sizeof (iv8));
    1464                 :          0 :                 obj->value.iv = iv8;
    1465                 :          0 :                 len = 1;
    1466                 :          0 :                 break;
    1467                 :            :         case msgpack_int16:
    1468                 :          0 :                 memcpy (&iv16, pos, sizeof (iv16));
    1469                 :          0 :                 iv16 = FROM_BE16 (iv16);
    1470                 :          0 :                 obj->value.iv = iv16;
    1471                 :          0 :                 len = 2;
    1472                 :          0 :                 break;
    1473                 :            :         case msgpack_uint16:
    1474                 :          0 :                 memcpy (&uiv16, pos, sizeof (uiv16));
    1475                 :          0 :                 uiv16 = FROM_BE16 (uiv16);
    1476                 :          0 :                 obj->value.iv = uiv16;
    1477                 :          0 :                 len = 2;
    1478                 :          0 :                 break;
    1479                 :            :         case msgpack_int32:
    1480                 :          0 :                 memcpy (&iv32, pos, sizeof (iv32));
    1481                 :          0 :                 iv32 = FROM_BE32 (iv32);
    1482                 :          0 :                 obj->value.iv = iv32;
    1483                 :          0 :                 len = 4;
    1484                 :          0 :                 break;
    1485                 :            :         case msgpack_uint32:
    1486                 :          0 :                 memcpy(&uiv32, pos, sizeof(uiv32));
    1487                 :          0 :                 uiv32 = FROM_BE32(uiv32);
    1488                 :          0 :                 obj->value.iv = uiv32;
    1489                 :          0 :                 len = 4;
    1490                 :          0 :                 break;
    1491                 :            :         case msgpack_int64:
    1492                 :          0 :                 memcpy (&iv64, pos, sizeof (iv64));
    1493                 :          0 :                 iv64 = FROM_BE64 (iv64);
    1494                 :          0 :                 obj->value.iv = iv64;
    1495                 :          0 :                 len = 8;
    1496                 :          0 :                 break;
    1497                 :            :         case msgpack_uint64:
    1498                 :          0 :                 memcpy(&uiv64, pos, sizeof(uiv64));
    1499                 :          0 :                 uiv64 = FROM_BE64(uiv64);
    1500                 :          0 :                 obj->value.iv = uiv64;
    1501                 :          0 :                 len = 8;
    1502                 :          0 :                 break;
    1503                 :            :         default:
    1504                 :          0 :                 assert (0);
    1505                 :            :                 break;
    1506                 :            :         }
    1507                 :            : 
    1508                 :          0 :         parser->cur_obj = obj;
    1509                 :            : 
    1510                 :          0 :         return len;
    1511                 :          0 : }
    1512                 :            : 
    1513                 :            : static ssize_t
    1514                 :          0 : 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         [ #  # ]:          0 :         if (len > remain) {
    1526                 :          0 :                 return -1;
    1527                 :            :         }
    1528                 :            : 
    1529                 :          0 :         obj = ucl_object_new_full (UCL_FLOAT, parser->chunks->priority);
    1530                 :            : 
    1531      [ #  #  # ]:          0 :         switch (fmt) {
    1532                 :            :         case msgpack_float32:
    1533                 :          0 :                 memcpy(&d.i, pos, sizeof(d.i));
    1534                 :          0 :                 d.i = FROM_BE32(d.i);
    1535                 :            :                 /* XXX: can be slow */
    1536                 :          0 :                 obj->value.dv = d.f;
    1537                 :          0 :                 len = 4;
    1538                 :          0 :                 break;
    1539                 :            :         case msgpack_float64:
    1540                 :          0 :                 memcpy(&uiv64, pos, sizeof(uiv64));
    1541                 :          0 :                 uiv64 = FROM_BE64(uiv64);
    1542                 :          0 :                 obj->value.iv = uiv64;
    1543                 :          0 :                 len = 8;
    1544                 :          0 :                 break;
    1545                 :            :         default:
    1546                 :          0 :                 assert (0);
    1547                 :            :                 break;
    1548                 :            :         }
    1549                 :            : 
    1550                 :          0 :         parser->cur_obj = obj;
    1551                 :            : 
    1552                 :          0 :         return len;
    1553                 :          0 : }
    1554                 :            : 
    1555                 :            : static ssize_t
    1556                 :          0 : 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         [ #  # ]:          0 :         if (len > remain) {
    1563                 :          0 :                 return -1;
    1564                 :            :         }
    1565                 :            : 
    1566                 :          0 :         obj = ucl_object_new_full (UCL_BOOLEAN, parser->chunks->priority);
    1567                 :            : 
    1568      [ #  #  # ]:          0 :         switch (fmt) {
    1569                 :            :         case msgpack_true:
    1570                 :          0 :                 obj->value.iv = true;
    1571                 :          0 :                 break;
    1572                 :            :         case msgpack_false:
    1573                 :          0 :                 obj->value.iv = false;
    1574                 :          0 :                 break;
    1575                 :            :         default:
    1576                 :          0 :                 assert (0);
    1577                 :            :                 break;
    1578                 :            :         }
    1579                 :            : 
    1580                 :          0 :         parser->cur_obj = obj;
    1581                 :            : 
    1582                 :          0 :         return 1;
    1583                 :          0 : }
    1584                 :            : 
    1585                 :            : static ssize_t
    1586                 :          0 : 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         [ #  # ]:          0 :         if (len > remain) {
    1593                 :          0 :                 return -1;
    1594                 :            :         }
    1595                 :            : 
    1596                 :          0 :         obj = ucl_object_new_full (UCL_NULL, parser->chunks->priority);
    1597                 :          0 :         parser->cur_obj = obj;
    1598                 :            : 
    1599                 :          0 :         return 1;
    1600                 :          0 : }
    1601                 :            : 
    1602                 :            : static ssize_t
    1603                 :          0 : 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         [ #  # ]:          0 :         if (len > remain) {
    1608                 :          0 :                 return -1;
    1609                 :            :         }
    1610                 :            : 
    1611   [ #  #  #  #  :          0 :         switch (fmt) {
                #  #  # ]
    1612                 :            :         case msgpack_fixext1:
    1613                 :          0 :                 len = 2;
    1614                 :          0 :                 break;
    1615                 :            :         case msgpack_fixext2:
    1616                 :          0 :                 len = 3;
    1617                 :          0 :                 break;
    1618                 :            :         case msgpack_fixext4:
    1619                 :          0 :                 len = 5;
    1620                 :          0 :                 break;
    1621                 :            :         case msgpack_fixext8:
    1622                 :          0 :                 len = 9;
    1623                 :          0 :                 break;
    1624                 :            :         case msgpack_fixext16:
    1625                 :          0 :                 len = 17;
    1626                 :          0 :                 break;
    1627                 :            :         case msgpack_ext8:
    1628                 :            :         case msgpack_ext16:
    1629                 :            :         case msgpack_ext32:
    1630                 :          0 :                 len = len + 1;
    1631                 :          0 :                 break;
    1632                 :            :         default:
    1633                 :          0 :                 ucl_create_err (&parser->err, "bad type: %x", (unsigned)fmt);
    1634                 :          0 :                 return -1;
    1635                 :            :         }
    1636                 :            : 
    1637                 :          0 :         return len;
    1638                 :          0 : }

Generated by: LCOV version 1.15