LCOV - code coverage report
Current view: top level - lib/json - json_util.c (source / functions) Hit Total Coverage
Test: ut_cov_unit.info Lines: 284 320 88.8 %
Date: 2024-12-14 21:01:04 Functions: 28 32 87.5 %

          Line data    Source code
       1             : /*   SPDX-License-Identifier: BSD-3-Clause
       2             :  *   Copyright (C) 2016 Intel Corporation.
       3             :  *   All rights reserved.
       4             :  */
       5             : 
       6             : #include "spdk/json.h"
       7             : 
       8             : #include "spdk_internal/utf.h"
       9             : #include "spdk/log.h"
      10             : 
      11             : #define SPDK_JSON_DEBUG(...) SPDK_DEBUGLOG(json_util, __VA_ARGS__)
      12             : 
      13             : size_t
      14          89 : spdk_json_val_len(const struct spdk_json_val *val)
      15             : {
      16          89 :         if (val == NULL) {
      17           0 :                 return 0;
      18             :         }
      19             : 
      20          89 :         if (val->type == SPDK_JSON_VAL_ARRAY_BEGIN || val->type == SPDK_JSON_VAL_OBJECT_BEGIN) {
      21          14 :                 return val->len + 2;
      22             :         }
      23             : 
      24          75 :         return 1;
      25             : }
      26             : 
      27             : bool
      28         237 : spdk_json_strequal(const struct spdk_json_val *val, const char *str)
      29             : {
      30             :         size_t len;
      31             : 
      32         237 :         if (val->type != SPDK_JSON_VAL_STRING && val->type != SPDK_JSON_VAL_NAME) {
      33           1 :                 return false;
      34             :         }
      35             : 
      36         236 :         len = strlen(str);
      37         236 :         if (val->len != len) {
      38         106 :                 return false;
      39             :         }
      40             : 
      41         130 :         return memcmp(val->start, str, len) == 0;
      42             : }
      43             : 
      44             : char *
      45          32 : spdk_json_strdup(const struct spdk_json_val *val)
      46             : {
      47             :         size_t len;
      48             :         char *s;
      49             : 
      50          32 :         if (val->type != SPDK_JSON_VAL_STRING && val->type != SPDK_JSON_VAL_NAME) {
      51           5 :                 return NULL;
      52             :         }
      53             : 
      54          27 :         len = val->len;
      55             : 
      56          27 :         if (memchr(val->start, '\0', len)) {
      57             :                 /* String contains embedded NUL, so it is not a valid C string. */
      58           2 :                 return NULL;
      59             :         }
      60             : 
      61          25 :         s = malloc(len + 1);
      62          25 :         if (s == NULL) {
      63           0 :                 return s;
      64             :         }
      65             : 
      66          25 :         memcpy(s, val->start, len);
      67          25 :         s[len] = '\0';
      68             : 
      69          25 :         return s;
      70             : }
      71             : 
      72             : struct spdk_json_num {
      73             :         bool negative;
      74             :         uint64_t significand;
      75             :         int64_t exponent;
      76             : };
      77             : 
      78             : static int
      79         115 : json_number_split(const struct spdk_json_val *val, struct spdk_json_num *num)
      80             : {
      81             :         const char *iter;
      82             :         size_t remaining;
      83             :         uint64_t *pval;
      84         115 :         uint64_t frac_digits = 0;
      85         115 :         uint64_t exponent_u64 = 0;
      86         115 :         bool exponent_negative = false;
      87             :         enum {
      88             :                 NUM_STATE_INT,
      89             :                 NUM_STATE_FRAC,
      90             :                 NUM_STATE_EXP,
      91             :         } state;
      92             : 
      93         115 :         memset(num, 0, sizeof(*num));
      94             : 
      95         115 :         if (val->type != SPDK_JSON_VAL_NUMBER) {
      96           8 :                 return -EINVAL;
      97             :         }
      98             : 
      99         107 :         remaining = val->len;
     100         107 :         if (remaining == 0) {
     101           0 :                 return -EINVAL;
     102             :         }
     103             : 
     104         107 :         iter = val->start;
     105         107 :         if (*iter == '-') {
     106          15 :                 num->negative = true;
     107          15 :                 iter++;
     108          15 :                 remaining--;
     109             :         }
     110             : 
     111         107 :         state = NUM_STATE_INT;
     112         107 :         pval = &num->significand;
     113         666 :         while (remaining--) {
     114         560 :                 char c = *iter++;
     115             : 
     116         560 :                 if (c == '.') {
     117          27 :                         state = NUM_STATE_FRAC;
     118         533 :                 } else if (c == 'e' || c == 'E') {
     119          46 :                         state = NUM_STATE_EXP;
     120          46 :                         pval = &exponent_u64;
     121         487 :                 } else if (c == '-') {
     122          21 :                         assert(state == NUM_STATE_EXP);
     123          21 :                         exponent_negative = true;
     124         466 :                 } else if (c == '+') {
     125           0 :                         assert(state == NUM_STATE_EXP);
     126             :                         /* exp_negative = false; */ /* already false by default */
     127             :                 } else {
     128             :                         uint64_t new_val;
     129             : 
     130         466 :                         assert(c >= '0' && c <= '9');
     131         466 :                         new_val = *pval * 10 + c - '0';
     132         466 :                         if (new_val < *pval) {
     133           1 :                                 return -ERANGE;
     134             :                         }
     135             : 
     136         465 :                         if (state == NUM_STATE_FRAC) {
     137          60 :                                 frac_digits++;
     138             :                         }
     139             : 
     140         465 :                         *pval = new_val;
     141             :                 }
     142             :         }
     143             : 
     144         106 :         if (exponent_negative) {
     145          21 :                 if (exponent_u64 > 9223372036854775808ULL) { /* abs(INT64_MIN) */
     146           0 :                         return -ERANGE;
     147             :                 }
     148          21 :                 num->exponent = (int64_t) - exponent_u64;
     149             :         } else {
     150          85 :                 if (exponent_u64 > INT64_MAX) {
     151           0 :                         return -ERANGE;
     152             :                 }
     153          85 :                 num->exponent = exponent_u64;
     154             :         }
     155         106 :         num->exponent -= frac_digits;
     156             : 
     157             :         /* Apply as much of the exponent as possible without overflow or truncation */
     158         106 :         if (num->exponent < 0) {
     159          82 :                 while (num->exponent && num->significand >= 10 && num->significand % 10 == 0) {
     160          41 :                         num->significand /= 10;
     161          41 :                         num->exponent++;
     162             :                 }
     163             :         } else { /* positive exponent */
     164         133 :                 while (num->exponent) {
     165          71 :                         uint64_t new_val = num->significand * 10;
     166             : 
     167          71 :                         if (new_val < num->significand) {
     168           3 :                                 break;
     169             :                         }
     170             : 
     171          68 :                         num->significand = new_val;
     172          68 :                         num->exponent--;
     173             :                 }
     174             :         }
     175             : 
     176         106 :         return 0;
     177             : }
     178             : 
     179             : int
     180           0 : spdk_json_number_to_uint8(const struct spdk_json_val *val, uint8_t *num)
     181             : {
     182             :         struct spdk_json_num split_num;
     183             :         int rc;
     184             : 
     185           0 :         rc = json_number_split(val, &split_num);
     186           0 :         if (rc) {
     187           0 :                 return rc;
     188             :         }
     189             : 
     190           0 :         if (split_num.exponent || split_num.negative) {
     191           0 :                 return -ERANGE;
     192             :         }
     193             : 
     194           0 :         if (split_num.significand > UINT8_MAX) {
     195           0 :                 return -ERANGE;
     196             :         }
     197           0 :         *num = (uint8_t)split_num.significand;
     198           0 :         return 0;
     199             : }
     200             : 
     201             : int
     202          24 : spdk_json_number_to_uint16(const struct spdk_json_val *val, uint16_t *num)
     203             : {
     204             :         struct spdk_json_num split_num;
     205             :         int rc;
     206             : 
     207          24 :         rc = json_number_split(val, &split_num);
     208          24 :         if (rc) {
     209           1 :                 return rc;
     210             :         }
     211             : 
     212          23 :         if (split_num.exponent || split_num.negative) {
     213          10 :                 return -ERANGE;
     214             :         }
     215             : 
     216          13 :         if (split_num.significand > UINT16_MAX) {
     217           2 :                 return -ERANGE;
     218             :         }
     219          11 :         *num = (uint16_t)split_num.significand;
     220          11 :         return 0;
     221             : }
     222             : 
     223             : int
     224          27 : spdk_json_number_to_int32(const struct spdk_json_val *val, int32_t *num)
     225             : {
     226             :         struct spdk_json_num split_num;
     227             :         int rc;
     228             : 
     229          27 :         rc = json_number_split(val, &split_num);
     230          27 :         if (rc) {
     231           2 :                 return rc;
     232             :         }
     233             : 
     234          25 :         if (split_num.exponent) {
     235           9 :                 return -ERANGE;
     236             :         }
     237             : 
     238          16 :         if (split_num.negative) {
     239           5 :                 if (split_num.significand > 2147483648) { /* abs(INT32_MIN) */
     240           1 :                         return -ERANGE;
     241             :                 }
     242           4 :                 *num = (int32_t) - (int64_t)split_num.significand;
     243           4 :                 return 0;
     244             :         }
     245             : 
     246             :         /* positive */
     247          11 :         if (split_num.significand > INT32_MAX) {
     248           1 :                 return -ERANGE;
     249             :         }
     250          10 :         *num = (int32_t)split_num.significand;
     251          10 :         return 0;
     252             : }
     253             : 
     254             : int
     255          30 : spdk_json_number_to_uint32(const struct spdk_json_val *val, uint32_t *num)
     256             : {
     257             :         struct spdk_json_num split_num;
     258             :         int rc;
     259             : 
     260          30 :         rc = json_number_split(val, &split_num);
     261          30 :         if (rc) {
     262           4 :                 return rc;
     263             :         }
     264             : 
     265          26 :         if (split_num.exponent || split_num.negative) {
     266           6 :                 return -ERANGE;
     267             :         }
     268             : 
     269          20 :         if (split_num.significand > UINT32_MAX) {
     270           1 :                 return -ERANGE;
     271             :         }
     272          19 :         *num = (uint32_t)split_num.significand;
     273          19 :         return 0;
     274             : }
     275             : 
     276             : int
     277          34 : spdk_json_number_to_uint64(const struct spdk_json_val *val, uint64_t *num)
     278             : {
     279             :         struct spdk_json_num split_num;
     280             :         int rc;
     281             : 
     282          34 :         rc = json_number_split(val, &split_num);
     283          34 :         if (rc) {
     284           2 :                 return rc;
     285             :         }
     286             : 
     287          32 :         if (split_num.exponent || split_num.negative) {
     288          12 :                 return -ERANGE;
     289             :         }
     290             : 
     291          20 :         *num = split_num.significand;
     292          20 :         return 0;
     293             : }
     294             : 
     295             : static int
     296          25 : _json_decode_object(const struct spdk_json_val *values,
     297             :                     const struct spdk_json_object_decoder *decoders, size_t num_decoders, void *out, bool relaxed)
     298             : {
     299             :         uint32_t i;
     300          25 :         bool invalid = false;
     301             :         size_t decidx;
     302             :         bool *seen;
     303             : 
     304          25 :         if (values == NULL || values->type != SPDK_JSON_VAL_OBJECT_BEGIN) {
     305           1 :                 return -1;
     306             :         }
     307             : 
     308          24 :         seen = calloc(sizeof(bool), num_decoders);
     309          24 :         if (seen == NULL) {
     310           0 :                 return -1;
     311             :         }
     312             : 
     313         102 :         for (i = 0; i < values->len;) {
     314          78 :                 const struct spdk_json_val *name = &values[i + 1];
     315          78 :                 const struct spdk_json_val *v = &values[i + 2];
     316          78 :                 bool found = false;
     317             : 
     318         194 :                 for (decidx = 0; decidx < num_decoders; decidx++) {
     319         193 :                         const struct spdk_json_object_decoder *dec = &decoders[decidx];
     320         193 :                         if (spdk_json_strequal(name, dec->name)) {
     321          77 :                                 void *field = (void *)((uintptr_t)out + dec->offset);
     322             : 
     323          77 :                                 found = true;
     324             : 
     325          77 :                                 if (seen[decidx]) {
     326             :                                         /* duplicate field name */
     327           1 :                                         invalid = true;
     328           1 :                                         SPDK_JSON_DEBUG("Duplicate key '%s'\n", dec->name);
     329             :                                 } else {
     330          76 :                                         seen[decidx] = true;
     331          76 :                                         if (dec->decode_func(v, field)) {
     332           1 :                                                 invalid = true;
     333           1 :                                                 SPDK_JSON_DEBUG("Decoder failed to decode key '%s'\n", dec->name);
     334             :                                                 /* keep going to fill out any other valid keys */
     335             :                                         }
     336             :                                 }
     337          77 :                                 break;
     338             :                         }
     339             :                 }
     340             : 
     341          78 :                 if (!relaxed && !found) {
     342           1 :                         invalid = true;
     343           1 :                         SPDK_JSON_DEBUG("Decoder not found for key '%.*s'\n", name->len, (char *)name->start);
     344             :                 }
     345             : 
     346          78 :                 i += 1 + spdk_json_val_len(v);
     347             :         }
     348             : 
     349         107 :         for (decidx = 0; decidx < num_decoders; decidx++) {
     350          86 :                 if (!decoders[decidx].optional && !seen[decidx]) {
     351             :                         /* required field is missing */
     352           3 :                         invalid = true;
     353           3 :                         break;
     354             :                 }
     355             :         }
     356             : 
     357          24 :         free(seen);
     358          24 :         return invalid ? -1 : 0;
     359             : }
     360             : 
     361             : void
     362           1 : spdk_json_free_object(const struct spdk_json_object_decoder *decoders, size_t num_decoders,
     363             :                       void *obj)
     364             : {
     365           1 :         struct spdk_json_val invalid_val = {
     366             :                 .start = "",
     367             :                 .len = 0,
     368             :                 .type = SPDK_JSON_VAL_INVALID
     369             :         };
     370             :         size_t decidx;
     371             : 
     372           5 :         for (decidx = 0; decidx < num_decoders; decidx++) {
     373           4 :                 const struct spdk_json_object_decoder *dec = &decoders[decidx];
     374           4 :                 void *field = (void *)((uintptr_t)obj + dec->offset);
     375             : 
     376             :                 /* decoding an invalid value will free the
     377             :                  * previous memory without allocating it again.
     378             :                  */
     379           4 :                 dec->decode_func(&invalid_val, field);
     380             :         }
     381           1 : }
     382             : 
     383             : 
     384             : int
     385          24 : spdk_json_decode_object(const struct spdk_json_val *values,
     386             :                         const struct spdk_json_object_decoder *decoders, size_t num_decoders, void *out)
     387             : {
     388          24 :         return _json_decode_object(values, decoders, num_decoders, out, false);
     389             : }
     390             : 
     391             : int
     392           1 : spdk_json_decode_object_relaxed(const struct spdk_json_val *values,
     393             :                                 const struct spdk_json_object_decoder *decoders, size_t num_decoders, void *out)
     394             : {
     395           1 :         return _json_decode_object(values, decoders, num_decoders, out, true);
     396             : }
     397             : 
     398             : int
     399          10 : spdk_json_decode_array(const struct spdk_json_val *values, spdk_json_decode_fn decode_func,
     400             :                        void *out, size_t max_size, size_t *out_size, size_t stride)
     401             : {
     402             :         uint32_t i;
     403             :         char *field;
     404             : 
     405          10 :         if (values == NULL || values->type != SPDK_JSON_VAL_ARRAY_BEGIN) {
     406           1 :                 return -1;
     407             :         }
     408             : 
     409           9 :         *out_size = 0;
     410           9 :         field = out;
     411          20 :         for (i = 0; i < values->len;) {
     412          14 :                 const struct spdk_json_val *v = &values[i + 1];
     413             : 
     414          14 :                 if (*out_size == max_size) {
     415           1 :                         return -1;
     416             :                 }
     417             : 
     418          13 :                 if (decode_func(v, field)) {
     419           2 :                         return -1;
     420             :                 }
     421             : 
     422          11 :                 i += spdk_json_val_len(v);
     423          11 :                 field += stride;
     424          11 :                 (*out_size)++;
     425             :         }
     426             : 
     427           6 :         return 0;
     428             : }
     429             : 
     430             : int
     431          11 : spdk_json_decode_bool(const struct spdk_json_val *val, void *out)
     432             : {
     433          11 :         bool *f = out;
     434             : 
     435          11 :         if (val->type != SPDK_JSON_VAL_TRUE && val->type != SPDK_JSON_VAL_FALSE) {
     436           1 :                 return -1;
     437             :         }
     438             : 
     439          10 :         *f = val->type == SPDK_JSON_VAL_TRUE;
     440          10 :         return 0;
     441             : }
     442             : 
     443             : int
     444           0 : spdk_json_decode_uint8(const struct spdk_json_val *val, void *out)
     445             : {
     446           0 :         uint8_t *i = out;
     447             : 
     448           0 :         return spdk_json_number_to_uint8(val, i);
     449             : }
     450             : 
     451             : int
     452          13 : spdk_json_decode_uint16(const struct spdk_json_val *val, void *out)
     453             : {
     454          13 :         uint16_t *i = out;
     455             : 
     456          13 :         return spdk_json_number_to_uint16(val, i);
     457             : }
     458             : 
     459             : int
     460          15 : spdk_json_decode_int32(const struct spdk_json_val *val, void *out)
     461             : {
     462          15 :         int32_t *i = out;
     463             : 
     464          15 :         return spdk_json_number_to_int32(val, i);
     465             : }
     466             : 
     467             : int
     468          30 : spdk_json_decode_uint32(const struct spdk_json_val *val, void *out)
     469             : {
     470          30 :         uint32_t *i = out;
     471             : 
     472          30 :         return spdk_json_number_to_uint32(val, i);
     473             : }
     474             : 
     475             : int
     476          21 : spdk_json_decode_uint64(const struct spdk_json_val *val, void *out)
     477             : {
     478          21 :         uint64_t *i = out;
     479             : 
     480          21 :         return spdk_json_number_to_uint64(val, i);
     481             : }
     482             : 
     483             : int
     484          32 : spdk_json_decode_string(const struct spdk_json_val *val, void *out)
     485             : {
     486          32 :         char **s = out;
     487             : 
     488          32 :         free(*s);
     489             : 
     490          32 :         *s = spdk_json_strdup(val);
     491             : 
     492          32 :         if (*s) {
     493          25 :                 return 0;
     494             :         } else {
     495           7 :                 return -1;
     496             :         }
     497             : }
     498             : 
     499             : int
     500           4 : spdk_json_decode_uuid(const struct spdk_json_val *val, void *out)
     501             : {
     502           4 :         struct spdk_uuid *uuid = out;
     503           4 :         char *str = NULL;
     504             :         int rc;
     505             : 
     506           4 :         rc = spdk_json_decode_string(val, &str);
     507           4 :         if (rc != 0) {
     508           1 :                 return rc;
     509             :         }
     510             : 
     511           3 :         rc = spdk_uuid_parse(uuid, str);
     512           3 :         free(str);
     513             : 
     514           3 :         return rc == 0 ? 0 : -1;
     515             : }
     516             : 
     517             : static struct spdk_json_val *
     518          11 : json_first(struct spdk_json_val *object, enum spdk_json_val_type type)
     519             : {
     520             :         /* 'object' must be JSON object or array. 'type' might be combination of these two. */
     521          11 :         assert((type & (SPDK_JSON_VAL_ARRAY_BEGIN | SPDK_JSON_VAL_OBJECT_BEGIN)) != 0);
     522             : 
     523          11 :         assert(object != NULL);
     524             : 
     525          11 :         if ((object->type & type) == 0) {
     526           1 :                 return NULL;
     527             :         }
     528             : 
     529          10 :         object++;
     530          10 :         if (object->len == 0) {
     531           0 :                 return NULL;
     532             :         }
     533             : 
     534          10 :         return object;
     535             : }
     536             : 
     537             : static struct spdk_json_val *
     538          25 : json_value(struct spdk_json_val *key)
     539             : {
     540          25 :         return key->type == SPDK_JSON_VAL_NAME ? key + 1 : NULL;
     541             : }
     542             : 
     543             : int
     544           7 : spdk_json_find(struct spdk_json_val *object, const char *key_name, struct spdk_json_val **key,
     545             :                struct spdk_json_val **val, enum spdk_json_val_type type)
     546             : {
     547           7 :         struct spdk_json_val *_key = NULL;
     548           7 :         struct spdk_json_val *_val = NULL;
     549             :         struct spdk_json_val *it_first, *it;
     550             : 
     551           7 :         assert(object != NULL);
     552             : 
     553           7 :         it_first = json_first(object, SPDK_JSON_VAL_OBJECT_BEGIN);
     554           7 :         if (!it_first) {
     555           1 :                 SPDK_JSON_DEBUG("Not enclosed in {}\n");
     556           1 :                 return -EPROTOTYPE;
     557             :         }
     558             : 
     559           6 :         for (it = it_first;
     560          18 :              it != NULL;
     561          12 :              it = spdk_json_next(it)) {
     562          13 :                 if (it->type != SPDK_JSON_VAL_NAME) {
     563           0 :                         continue;
     564             :                 }
     565             : 
     566          13 :                 if (spdk_json_strequal(it, key_name) != true) {
     567           8 :                         continue;
     568             :                 }
     569             : 
     570           5 :                 if (_key) {
     571           0 :                         SPDK_JSON_DEBUG("Duplicate key '%s'", key_name);
     572           0 :                         return -EINVAL;
     573             :                 }
     574             : 
     575           5 :                 _key = it;
     576           5 :                 _val = json_value(_key);
     577             : 
     578           5 :                 if (type != SPDK_JSON_VAL_ANY && (_val->type & type) == 0) {
     579           1 :                         SPDK_JSON_DEBUG("key '%s' type is %#x but expected one of %#x\n", key_name, _val->type, type);
     580           1 :                         return -EDOM;
     581             :                 }
     582             :         }
     583             : 
     584           5 :         if (key) {
     585           5 :                 *key = _key;
     586             :         }
     587             : 
     588           5 :         if (val) {
     589           5 :                 *val = _val;
     590             :         }
     591             : 
     592           5 :         return _val ? 0 : -ENOENT;
     593             : }
     594             : 
     595             : int
     596           0 : spdk_json_find_string(struct spdk_json_val *object, const char *key_name,
     597             :                       struct spdk_json_val **key, struct spdk_json_val **val)
     598             : {
     599           0 :         return spdk_json_find(object, key_name, key, val, SPDK_JSON_VAL_STRING);
     600             : }
     601             : 
     602             : int
     603           0 : spdk_json_find_array(struct spdk_json_val *object, const char *key_name,
     604             :                      struct spdk_json_val **key, struct spdk_json_val **val)
     605             : {
     606           0 :         return spdk_json_find(object, key_name, key, val, SPDK_JSON_VAL_ARRAY_BEGIN);
     607             : }
     608             : 
     609             : struct spdk_json_val *
     610           2 : spdk_json_object_first(struct spdk_json_val *object)
     611             : {
     612           2 :         struct spdk_json_val *first = json_first(object, SPDK_JSON_VAL_OBJECT_BEGIN);
     613             : 
     614             :         /* Empty object? */
     615           2 :         return first && first->type != SPDK_JSON_VAL_OBJECT_END ? first : NULL;
     616             : }
     617             : 
     618             : struct spdk_json_val *
     619           2 : spdk_json_array_first(struct spdk_json_val *array_begin)
     620             : {
     621           2 :         struct spdk_json_val *first = json_first(array_begin, SPDK_JSON_VAL_ARRAY_BEGIN);
     622             : 
     623             :         /* Empty array? */
     624           2 :         return first && first->type != SPDK_JSON_VAL_ARRAY_END ? first : NULL;
     625             : }
     626             : 
     627             : static struct spdk_json_val *
     628          13 : json_skip_object_or_array(struct spdk_json_val *val)
     629             : {
     630             :         unsigned lvl;
     631             :         enum spdk_json_val_type end_type;
     632             :         struct spdk_json_val *it;
     633             : 
     634          13 :         if (val->type == SPDK_JSON_VAL_OBJECT_BEGIN) {
     635           5 :                 end_type = SPDK_JSON_VAL_OBJECT_END;
     636           8 :         } else if (val->type == SPDK_JSON_VAL_ARRAY_BEGIN) {
     637           8 :                 end_type = SPDK_JSON_VAL_ARRAY_END;
     638             :         } else {
     639           0 :                 SPDK_JSON_DEBUG("Expected JSON object (%#x) or array (%#x) but got %#x\n",
     640             :                                 SPDK_JSON_VAL_OBJECT_BEGIN, SPDK_JSON_VAL_ARRAY_BEGIN, val->type);
     641           0 :                 return NULL;
     642             :         }
     643             : 
     644          13 :         lvl = 1;
     645          88 :         for (it = val + 1; it->type != SPDK_JSON_VAL_INVALID && lvl != 0; it++) {
     646          75 :                 if (it->type == val->type) {
     647           7 :                         lvl++;
     648          68 :                 } else if (it->type == end_type) {
     649          20 :                         lvl--;
     650             :                 }
     651             :         }
     652             : 
     653             :         /* if lvl != 0 we have invalid JSON object */
     654          13 :         if (lvl != 0) {
     655           0 :                 SPDK_JSON_DEBUG("Can't find end of object (type: %#x): lvl (%u) != 0)\n", val->type, lvl);
     656           0 :                 it = NULL;
     657             :         }
     658             : 
     659          13 :         return it;
     660             : }
     661             : 
     662             : struct spdk_json_val *
     663          40 : spdk_json_next(struct spdk_json_val *it)
     664             : {
     665             :         struct spdk_json_val *val, *next;
     666             : 
     667          40 :         switch (it->type) {
     668          17 :         case SPDK_JSON_VAL_NAME:
     669          17 :                 val = json_value(it);
     670          17 :                 next = spdk_json_next(val);
     671          17 :                 break;
     672             : 
     673             :         /* We are in the middle of an array - get to next entry */
     674          10 :         case SPDK_JSON_VAL_NULL:
     675             :         case SPDK_JSON_VAL_TRUE:
     676             :         case SPDK_JSON_VAL_FALSE:
     677             :         case SPDK_JSON_VAL_NUMBER:
     678             :         case SPDK_JSON_VAL_STRING:
     679          10 :                 val = it + 1;
     680          10 :                 return val;
     681             : 
     682          13 :         case SPDK_JSON_VAL_ARRAY_BEGIN:
     683             :         case SPDK_JSON_VAL_OBJECT_BEGIN:
     684          13 :                 next = json_skip_object_or_array(it);
     685          13 :                 break;
     686             : 
     687             :         /* Can't go to the next object if started from the end of array or object */
     688           0 :         case SPDK_JSON_VAL_ARRAY_END:
     689             :         case SPDK_JSON_VAL_OBJECT_END:
     690             :         case SPDK_JSON_VAL_INVALID:
     691           0 :                 return NULL;
     692           0 :         default:
     693           0 :                 assert(false);
     694             :                 return NULL;
     695             : 
     696             :         }
     697             : 
     698             :         /* EOF ? */
     699          30 :         if (next == NULL) {
     700           7 :                 return NULL;
     701             :         }
     702             : 
     703          23 :         switch (next->type) {
     704           9 :         case SPDK_JSON_VAL_ARRAY_END:
     705             :         case SPDK_JSON_VAL_OBJECT_END:
     706             :         case SPDK_JSON_VAL_INVALID:
     707           9 :                 return NULL;
     708          14 :         default:
     709             :                 /* Next value */
     710          14 :                 return next;
     711             :         }
     712             : }
     713             : 
     714          10 : SPDK_LOG_REGISTER_COMPONENT(json_util)

Generated by: LCOV version 1.15