LCOV - code coverage report
Current view: top level - lib/json - json_util.c (source / functions) Hit Total Coverage
Test: ut_cov_unit.info Lines: 288 325 88.6 %
Date: 2024-07-10 22:17:11 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           0 :         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          24 :         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          27 :         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          30 :         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          34 :         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             :         char *out_end;
     405             : 
     406          10 :         if (values == NULL || values->type != SPDK_JSON_VAL_ARRAY_BEGIN) {
     407           1 :                 return -1;
     408             :         }
     409             : 
     410           9 :         *out_size = 0;
     411           9 :         field = out;
     412           9 :         out_end = field + max_size * stride;
     413          20 :         for (i = 0; i < values->len;) {
     414          14 :                 const struct spdk_json_val *v = &values[i + 1];
     415             : 
     416          14 :                 if (field == out_end) {
     417           1 :                         return -1;
     418             :                 }
     419             : 
     420          13 :                 if (decode_func(v, field)) {
     421           2 :                         return -1;
     422             :                 }
     423             : 
     424          11 :                 i += spdk_json_val_len(v);
     425          11 :                 field += stride;
     426          11 :                 (*out_size)++;
     427             :         }
     428             : 
     429           6 :         return 0;
     430             : }
     431             : 
     432             : int
     433          11 : spdk_json_decode_bool(const struct spdk_json_val *val, void *out)
     434             : {
     435          11 :         bool *f = out;
     436             : 
     437          11 :         if (val->type != SPDK_JSON_VAL_TRUE && val->type != SPDK_JSON_VAL_FALSE) {
     438           1 :                 return -1;
     439             :         }
     440             : 
     441          10 :         *f = val->type == SPDK_JSON_VAL_TRUE;
     442          10 :         return 0;
     443             : }
     444             : 
     445             : int
     446           0 : spdk_json_decode_uint8(const struct spdk_json_val *val, void *out)
     447             : {
     448           0 :         uint8_t *i = out;
     449             : 
     450           0 :         return spdk_json_number_to_uint8(val, i);
     451             : }
     452             : 
     453             : int
     454          13 : spdk_json_decode_uint16(const struct spdk_json_val *val, void *out)
     455             : {
     456          13 :         uint16_t *i = out;
     457             : 
     458          13 :         return spdk_json_number_to_uint16(val, i);
     459             : }
     460             : 
     461             : int
     462          15 : spdk_json_decode_int32(const struct spdk_json_val *val, void *out)
     463             : {
     464          15 :         int32_t *i = out;
     465             : 
     466          15 :         return spdk_json_number_to_int32(val, i);
     467             : }
     468             : 
     469             : int
     470          30 : spdk_json_decode_uint32(const struct spdk_json_val *val, void *out)
     471             : {
     472          30 :         uint32_t *i = out;
     473             : 
     474          30 :         return spdk_json_number_to_uint32(val, i);
     475             : }
     476             : 
     477             : int
     478          21 : spdk_json_decode_uint64(const struct spdk_json_val *val, void *out)
     479             : {
     480          21 :         uint64_t *i = out;
     481             : 
     482          21 :         return spdk_json_number_to_uint64(val, i);
     483             : }
     484             : 
     485             : int
     486          32 : spdk_json_decode_string(const struct spdk_json_val *val, void *out)
     487             : {
     488          32 :         char **s = out;
     489             : 
     490          32 :         free(*s);
     491             : 
     492          32 :         *s = spdk_json_strdup(val);
     493             : 
     494          32 :         if (*s) {
     495          25 :                 return 0;
     496             :         } else {
     497           7 :                 return -1;
     498             :         }
     499             : }
     500             : 
     501             : int
     502           4 : spdk_json_decode_uuid(const struct spdk_json_val *val, void *out)
     503             : {
     504           4 :         struct spdk_uuid *uuid = out;
     505           4 :         char *str = NULL;
     506             :         int rc;
     507             : 
     508           4 :         rc = spdk_json_decode_string(val, &str);
     509           4 :         if (rc != 0) {
     510           1 :                 return rc;
     511             :         }
     512             : 
     513           3 :         rc = spdk_uuid_parse(uuid, str);
     514           3 :         free(str);
     515             : 
     516           3 :         return rc == 0 ? 0 : -1;
     517             : }
     518             : 
     519             : static struct spdk_json_val *
     520          11 : json_first(struct spdk_json_val *object, enum spdk_json_val_type type)
     521             : {
     522             :         /* 'object' must be JSON object or array. 'type' might be combination of these two. */
     523          11 :         assert((type & (SPDK_JSON_VAL_ARRAY_BEGIN | SPDK_JSON_VAL_OBJECT_BEGIN)) != 0);
     524             : 
     525          11 :         assert(object != NULL);
     526             : 
     527          11 :         if ((object->type & type) == 0) {
     528           1 :                 return NULL;
     529             :         }
     530             : 
     531          10 :         object++;
     532          10 :         if (object->len == 0) {
     533           0 :                 return NULL;
     534             :         }
     535             : 
     536          10 :         return object;
     537             : }
     538             : 
     539             : static struct spdk_json_val *
     540          25 : json_value(struct spdk_json_val *key)
     541             : {
     542          25 :         return key->type == SPDK_JSON_VAL_NAME ? key + 1 : NULL;
     543             : }
     544             : 
     545             : int
     546           7 : spdk_json_find(struct spdk_json_val *object, const char *key_name, struct spdk_json_val **key,
     547             :                struct spdk_json_val **val, enum spdk_json_val_type type)
     548             : {
     549           7 :         struct spdk_json_val *_key = NULL;
     550           7 :         struct spdk_json_val *_val = NULL;
     551             :         struct spdk_json_val *it_first, *it;
     552             : 
     553           7 :         assert(object != NULL);
     554             : 
     555           7 :         it_first = json_first(object, SPDK_JSON_VAL_OBJECT_BEGIN);
     556           7 :         if (!it_first) {
     557           1 :                 SPDK_JSON_DEBUG("Not enclosed in {}\n");
     558           1 :                 return -EPROTOTYPE;
     559             :         }
     560             : 
     561          18 :         for (it = it_first;
     562             :              it != NULL;
     563          12 :              it = spdk_json_next(it)) {
     564          13 :                 if (it->type != SPDK_JSON_VAL_NAME) {
     565           0 :                         continue;
     566             :                 }
     567             : 
     568          13 :                 if (spdk_json_strequal(it, key_name) != true) {
     569           8 :                         continue;
     570             :                 }
     571             : 
     572           5 :                 if (_key) {
     573           0 :                         SPDK_JSON_DEBUG("Duplicate key '%s'", key_name);
     574           0 :                         return -EINVAL;
     575             :                 }
     576             : 
     577           5 :                 _key = it;
     578           5 :                 _val = json_value(_key);
     579             : 
     580           5 :                 if (type != SPDK_JSON_VAL_ANY && (_val->type & type) == 0) {
     581           1 :                         SPDK_JSON_DEBUG("key '%s' type is %#x but expected one of %#x\n", key_name, _val->type, type);
     582           1 :                         return -EDOM;
     583             :                 }
     584             :         }
     585             : 
     586           5 :         if (key) {
     587           5 :                 *key = _key;
     588             :         }
     589             : 
     590           5 :         if (val) {
     591           5 :                 *val = _val;
     592             :         }
     593             : 
     594           5 :         return _val ? 0 : -ENOENT;
     595             : }
     596             : 
     597             : int
     598           0 : spdk_json_find_string(struct spdk_json_val *object, const char *key_name,
     599             :                       struct spdk_json_val **key, struct spdk_json_val **val)
     600             : {
     601           0 :         return spdk_json_find(object, key_name, key, val, SPDK_JSON_VAL_STRING);
     602             : }
     603             : 
     604             : int
     605           0 : spdk_json_find_array(struct spdk_json_val *object, const char *key_name,
     606             :                      struct spdk_json_val **key, struct spdk_json_val **val)
     607             : {
     608           0 :         return spdk_json_find(object, key_name, key, val, SPDK_JSON_VAL_ARRAY_BEGIN);
     609             : }
     610             : 
     611             : struct spdk_json_val *
     612           2 : spdk_json_object_first(struct spdk_json_val *object)
     613             : {
     614           2 :         struct spdk_json_val *first = json_first(object, SPDK_JSON_VAL_OBJECT_BEGIN);
     615             : 
     616             :         /* Empty object? */
     617           2 :         return first && first->type != SPDK_JSON_VAL_OBJECT_END ? first : NULL;
     618             : }
     619             : 
     620             : struct spdk_json_val *
     621           2 : spdk_json_array_first(struct spdk_json_val *array_begin)
     622             : {
     623           2 :         struct spdk_json_val *first = json_first(array_begin, SPDK_JSON_VAL_ARRAY_BEGIN);
     624             : 
     625             :         /* Empty array? */
     626           2 :         return first && first->type != SPDK_JSON_VAL_ARRAY_END ? first : NULL;
     627             : }
     628             : 
     629             : static struct spdk_json_val *
     630          13 : json_skip_object_or_array(struct spdk_json_val *val)
     631             : {
     632             :         unsigned lvl;
     633             :         enum spdk_json_val_type end_type;
     634             :         struct spdk_json_val *it;
     635             : 
     636          13 :         if (val->type == SPDK_JSON_VAL_OBJECT_BEGIN) {
     637           5 :                 end_type = SPDK_JSON_VAL_OBJECT_END;
     638           8 :         } else if (val->type == SPDK_JSON_VAL_ARRAY_BEGIN) {
     639           8 :                 end_type = SPDK_JSON_VAL_ARRAY_END;
     640             :         } else {
     641           0 :                 SPDK_JSON_DEBUG("Expected JSON object (%#x) or array (%#x) but got %#x\n",
     642             :                                 SPDK_JSON_VAL_OBJECT_BEGIN, SPDK_JSON_VAL_ARRAY_BEGIN, val->type);
     643           0 :                 return NULL;
     644             :         }
     645             : 
     646          13 :         lvl = 1;
     647          88 :         for (it = val + 1; it->type != SPDK_JSON_VAL_INVALID && lvl != 0; it++) {
     648          75 :                 if (it->type == val->type) {
     649           7 :                         lvl++;
     650          68 :                 } else if (it->type == end_type) {
     651          20 :                         lvl--;
     652             :                 }
     653             :         }
     654             : 
     655             :         /* if lvl != 0 we have invalid JSON object */
     656          13 :         if (lvl != 0) {
     657           0 :                 SPDK_JSON_DEBUG("Can't find end of object (type: %#x): lvl (%u) != 0)\n", val->type, lvl);
     658           0 :                 it = NULL;
     659             :         }
     660             : 
     661          13 :         return it;
     662             : }
     663             : 
     664             : struct spdk_json_val *
     665          40 : spdk_json_next(struct spdk_json_val *it)
     666             : {
     667             :         struct spdk_json_val *val, *next;
     668             : 
     669          40 :         switch (it->type) {
     670          17 :         case SPDK_JSON_VAL_NAME:
     671          17 :                 val = json_value(it);
     672          17 :                 next = spdk_json_next(val);
     673          17 :                 break;
     674             : 
     675             :         /* We are in the middle of an array - get to next entry */
     676          10 :         case SPDK_JSON_VAL_NULL:
     677             :         case SPDK_JSON_VAL_TRUE:
     678             :         case SPDK_JSON_VAL_FALSE:
     679             :         case SPDK_JSON_VAL_NUMBER:
     680             :         case SPDK_JSON_VAL_STRING:
     681          10 :                 val = it + 1;
     682          10 :                 return val;
     683             : 
     684          13 :         case SPDK_JSON_VAL_ARRAY_BEGIN:
     685             :         case SPDK_JSON_VAL_OBJECT_BEGIN:
     686          13 :                 next = json_skip_object_or_array(it);
     687          13 :                 break;
     688             : 
     689             :         /* Can't go to the next object if started from the end of array or object */
     690           0 :         case SPDK_JSON_VAL_ARRAY_END:
     691             :         case SPDK_JSON_VAL_OBJECT_END:
     692             :         case SPDK_JSON_VAL_INVALID:
     693           0 :                 return NULL;
     694           0 :         default:
     695           0 :                 assert(false);
     696             :                 return NULL;
     697             : 
     698             :         }
     699             : 
     700             :         /* EOF ? */
     701          30 :         if (next == NULL) {
     702           7 :                 return NULL;
     703             :         }
     704             : 
     705          23 :         switch (next->type) {
     706           9 :         case SPDK_JSON_VAL_ARRAY_END:
     707             :         case SPDK_JSON_VAL_OBJECT_END:
     708             :         case SPDK_JSON_VAL_INVALID:
     709           9 :                 return NULL;
     710          14 :         default:
     711             :                 /* Next value */
     712          14 :                 return next;
     713             :         }
     714             : }
     715             : 
     716           9 : SPDK_LOG_REGISTER_COMPONENT(json_util)

Generated by: LCOV version 1.15