Branch data 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 : 290972 : spdk_json_val_len(const struct spdk_json_val *val)
15 : : {
16 [ - + ]: 290972 : if (val == NULL) {
17 : 0 : return 0;
18 : : }
19 : :
20 [ + + + + ]: 290972 : if (val->type == SPDK_JSON_VAL_ARRAY_BEGIN || val->type == SPDK_JSON_VAL_OBJECT_BEGIN) {
21 : 52714 : return val->len + 2;
22 : : }
23 : :
24 : 238258 : return 1;
25 : : }
26 : :
27 : : bool
28 : 45041318 : spdk_json_strequal(const struct spdk_json_val *val, const char *str)
29 : : {
30 : : size_t len;
31 : :
32 [ + + + + ]: 45041318 : if (val->type != SPDK_JSON_VAL_STRING && val->type != SPDK_JSON_VAL_NAME) {
33 : 4 : return false;
34 : : }
35 : :
36 [ - + ]: 45041314 : len = strlen(str);
37 [ + + ]: 45041314 : if (val->len != len) {
38 : 42182566 : return false;
39 : : }
40 : :
41 [ - + - + ]: 2858754 : return memcmp(val->start, str, len) == 0;
42 : : }
43 : :
44 : : char *
45 : 53937 : spdk_json_strdup(const struct spdk_json_val *val)
46 : : {
47 : : size_t len;
48 : : char *s;
49 : :
50 [ + + + - ]: 53937 : if (val->type != SPDK_JSON_VAL_STRING && val->type != SPDK_JSON_VAL_NAME) {
51 : 20 : return NULL;
52 : : }
53 : :
54 : 53917 : len = val->len;
55 : :
56 [ + + + + ]: 53917 : if (memchr(val->start, '\0', len)) {
57 : : /* String contains embedded NUL, so it is not a valid C string. */
58 : 8 : return NULL;
59 : : }
60 : :
61 : 53909 : s = malloc(len + 1);
62 [ - + ]: 53909 : if (s == NULL) {
63 : 0 : return s;
64 : : }
65 : :
66 [ - + - + ]: 53909 : memcpy(s, val->start, len);
67 : 53909 : s[len] = '\0';
68 : :
69 : 53909 : 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 : 27268 : 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 : 27268 : uint64_t frac_digits = 0;
85 : 27268 : uint64_t exponent_u64 = 0;
86 : 27268 : bool exponent_negative = false;
87 : : enum {
88 : : NUM_STATE_INT,
89 : : NUM_STATE_FRAC,
90 : : NUM_STATE_EXP,
91 : : } state;
92 : :
93 [ - + ]: 27268 : memset(num, 0, sizeof(*num));
94 : :
95 [ + + ]: 27268 : if (val->type != SPDK_JSON_VAL_NUMBER) {
96 : 32 : return -EINVAL;
97 : : }
98 : :
99 : 27236 : remaining = val->len;
100 [ - + ]: 27236 : if (remaining == 0) {
101 : 0 : return -EINVAL;
102 : : }
103 : :
104 : 27236 : iter = val->start;
105 [ + + ]: 27236 : if (*iter == '-') {
106 : 97 : num->negative = true;
107 : 97 : iter++;
108 : 97 : remaining--;
109 : : }
110 : :
111 : 27236 : state = NUM_STATE_INT;
112 : 27236 : pval = &num->significand;
113 [ + + ]: 101101 : while (remaining--) {
114 : 73869 : char c = *iter++;
115 : :
116 [ + + ]: 73869 : if (c == '.') {
117 : 108 : state = NUM_STATE_FRAC;
118 [ + + + + ]: 73761 : } else if (c == 'e' || c == 'E') {
119 : 184 : state = NUM_STATE_EXP;
120 : 184 : pval = &exponent_u64;
121 [ + + ]: 73577 : } else if (c == '-') {
122 [ - + ]: 84 : assert(state == NUM_STATE_EXP);
123 : 84 : exponent_negative = true;
124 [ - + ]: 73493 : } 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 [ + - + + ]: 73493 : assert(c >= '0' && c <= '9');
131 : 73493 : new_val = *pval * 10 + c - '0';
132 [ + + ]: 73493 : if (new_val < *pval) {
133 : 4 : return -ERANGE;
134 : : }
135 : :
136 [ + + ]: 73489 : if (state == NUM_STATE_FRAC) {
137 : 240 : frac_digits++;
138 : : }
139 : :
140 : 73489 : *pval = new_val;
141 : : }
142 : : }
143 : :
144 [ + + ]: 27232 : if (exponent_negative) {
145 [ - + ]: 84 : if (exponent_u64 > 9223372036854775808ULL) { /* abs(INT64_MIN) */
146 : 0 : return -ERANGE;
147 : : }
148 : 84 : num->exponent = (int64_t) - exponent_u64;
149 : : } else {
150 [ - + ]: 27148 : if (exponent_u64 > INT64_MAX) {
151 : 0 : return -ERANGE;
152 : : }
153 : 27148 : num->exponent = exponent_u64;
154 : : }
155 : 27232 : num->exponent -= frac_digits;
156 : :
157 : : /* Apply as much of the exponent as possible without overflow or truncation */
158 [ + + ]: 27232 : if (num->exponent < 0) {
159 [ + + + + : 328 : while (num->exponent && num->significand >= 10 && num->significand % 10 == 0) {
+ + ]
160 : 164 : num->significand /= 10;
161 : 164 : num->exponent++;
162 : : }
163 : : } else { /* positive exponent */
164 [ + + ]: 27340 : while (num->exponent) {
165 : 284 : uint64_t new_val = num->significand * 10;
166 : :
167 [ + + ]: 284 : if (new_val < num->significand) {
168 : 12 : break;
169 : : }
170 : :
171 : 272 : num->significand = new_val;
172 : 272 : num->exponent--;
173 : : }
174 : : }
175 : :
176 : 27232 : return 0;
177 : : }
178 : :
179 : : int
180 : 454 : spdk_json_number_to_uint8(const struct spdk_json_val *val, uint8_t *num)
181 : : {
182 : 249 : struct spdk_json_num split_num;
183 : : int rc;
184 : :
185 : 454 : rc = json_number_split(val, &split_num);
186 [ - + ]: 454 : if (rc) {
187 : 0 : return rc;
188 : : }
189 : :
190 [ + - - + : 454 : if (split_num.exponent || split_num.negative) {
- + ]
191 : 0 : return -ERANGE;
192 : : }
193 : :
194 [ - + ]: 454 : if (split_num.significand > UINT8_MAX) {
195 : 0 : return -ERANGE;
196 : : }
197 : 454 : *num = (uint8_t)split_num.significand;
198 : 454 : return 0;
199 : : }
200 : :
201 : : int
202 : 283 : spdk_json_number_to_uint16(const struct spdk_json_val *val, uint16_t *num)
203 : : {
204 : 131 : struct spdk_json_num split_num;
205 : : int rc;
206 : :
207 : 283 : rc = json_number_split(val, &split_num);
208 [ + + ]: 283 : if (rc) {
209 : 4 : return rc;
210 : : }
211 : :
212 [ + + + + : 279 : if (split_num.exponent || split_num.negative) {
+ + ]
213 : 40 : return -ERANGE;
214 : : }
215 : :
216 [ + + ]: 239 : if (split_num.significand > UINT16_MAX) {
217 : 8 : return -ERANGE;
218 : : }
219 : 231 : *num = (uint16_t)split_num.significand;
220 : 231 : return 0;
221 : : }
222 : :
223 : : int
224 : 2120 : spdk_json_number_to_int32(const struct spdk_json_val *val, int32_t *num)
225 : : {
226 : 593 : struct spdk_json_num split_num;
227 : : int rc;
228 : :
229 : 2120 : rc = json_number_split(val, &split_num);
230 [ + + ]: 2120 : if (rc) {
231 : 8 : return rc;
232 : : }
233 : :
234 [ + + ]: 2112 : if (split_num.exponent) {
235 : 36 : return -ERANGE;
236 : : }
237 : :
238 [ + + + + ]: 2076 : if (split_num.negative) {
239 [ + + ]: 55 : if (split_num.significand > 2147483648) { /* abs(INT32_MIN) */
240 : 4 : return -ERANGE;
241 : : }
242 : 51 : *num = (int32_t) - (int64_t)split_num.significand;
243 : 51 : return 0;
244 : : }
245 : :
246 : : /* positive */
247 [ + + ]: 2021 : if (split_num.significand > INT32_MAX) {
248 : 4 : return -ERANGE;
249 : : }
250 : 2017 : *num = (int32_t)split_num.significand;
251 : 2017 : return 0;
252 : : }
253 : :
254 : : int
255 : 16557 : spdk_json_number_to_uint32(const struct spdk_json_val *val, uint32_t *num)
256 : : {
257 : 5752 : struct spdk_json_num split_num;
258 : : int rc;
259 : :
260 : 16557 : rc = json_number_split(val, &split_num);
261 [ + + ]: 16557 : if (rc) {
262 : 16 : return rc;
263 : : }
264 : :
265 [ + + + + : 16541 : if (split_num.exponent || split_num.negative) {
+ + ]
266 : 26 : return -ERANGE;
267 : : }
268 : :
269 [ + + ]: 16515 : if (split_num.significand > UINT32_MAX) {
270 : 4 : return -ERANGE;
271 : : }
272 : 16511 : *num = (uint32_t)split_num.significand;
273 : 16511 : return 0;
274 : : }
275 : :
276 : : int
277 : 7854 : spdk_json_number_to_uint64(const struct spdk_json_val *val, uint64_t *num)
278 : : {
279 : 3409 : struct spdk_json_num split_num;
280 : : int rc;
281 : :
282 : 7854 : rc = json_number_split(val, &split_num);
283 [ + + ]: 7854 : if (rc) {
284 : 8 : return rc;
285 : : }
286 : :
287 [ + + + + : 7846 : if (split_num.exponent || split_num.negative) {
+ + ]
288 : 48 : return -ERANGE;
289 : : }
290 : :
291 : 7798 : *num = split_num.significand;
292 : 7798 : return 0;
293 : : }
294 : :
295 : : static int
296 : 96123 : _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 : 96123 : bool invalid = false;
301 : : size_t decidx;
302 : : bool *seen;
303 : :
304 [ + - + + ]: 96123 : if (values == NULL || values->type != SPDK_JSON_VAL_OBJECT_BEGIN) {
305 : 4 : return -1;
306 : : }
307 : :
308 : 96119 : seen = calloc(sizeof(bool), num_decoders);
309 [ - + ]: 96119 : if (seen == NULL) {
310 : 0 : return -1;
311 : : }
312 : :
313 [ + + ]: 380639 : for (i = 0; i < values->len;) {
314 : 284520 : const struct spdk_json_val *name = &values[i + 1];
315 : 284520 : const struct spdk_json_val *v = &values[i + 2];
316 : 284520 : bool found = false;
317 : :
318 [ + + ]: 784937 : for (decidx = 0; decidx < num_decoders; decidx++) {
319 : 779912 : const struct spdk_json_object_decoder *dec = &decoders[decidx];
320 [ + + ]: 779912 : if (spdk_json_strequal(name, dec->name)) {
321 : 279495 : void *field = (void *)((uintptr_t)out + dec->offset);
322 : :
323 : 279495 : found = true;
324 : :
325 [ + + + + ]: 279495 : if (seen[decidx]) {
326 : : /* duplicate field name */
327 : 4 : invalid = true;
328 [ - + - + ]: 4 : SPDK_JSON_DEBUG("Duplicate key '%s'\n", dec->name);
329 : : } else {
330 : 279491 : seen[decidx] = true;
331 [ + + ]: 279491 : if (dec->decode_func(v, field)) {
332 : 6 : invalid = true;
333 [ - + - + ]: 6 : 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 : 279495 : break;
338 : : }
339 : : }
340 : :
341 [ + + + + ]: 284520 : if (!relaxed && !found) {
342 : 4 : invalid = true;
343 [ - + - + ]: 4 : SPDK_JSON_DEBUG("Decoder not found for key '%.*s'\n", name->len, (char *)name->start);
344 : : }
345 : :
346 : 284520 : i += 1 + spdk_json_val_len(v);
347 : : }
348 : :
349 [ + + ]: 484232 : for (decidx = 0; decidx < num_decoders; decidx++) {
350 [ + + + + : 388125 : if (!decoders[decidx].optional && !seen[decidx]) {
- + + + ]
351 : : /* required field is missing */
352 : 12 : invalid = true;
353 : 12 : break;
354 : : }
355 : : }
356 : :
357 : 96119 : free(seen);
358 [ + + ]: 96119 : return invalid ? -1 : 0;
359 : : }
360 : :
361 : : void
362 : 4 : spdk_json_free_object(const struct spdk_json_object_decoder *decoders, size_t num_decoders,
363 : : void *obj)
364 : : {
365 : 4 : struct spdk_json_val invalid_val = {
366 : : .start = "",
367 : : .len = 0,
368 : : .type = SPDK_JSON_VAL_INVALID
369 : : };
370 : : size_t decidx;
371 : :
372 [ + + ]: 20 : for (decidx = 0; decidx < num_decoders; decidx++) {
373 : 16 : const struct spdk_json_object_decoder *dec = &decoders[decidx];
374 : 16 : 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 : 16 : dec->decode_func(&invalid_val, field);
380 : : }
381 : 4 : }
382 : :
383 : :
384 : : int
385 : 94539 : 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 : 94539 : return _json_decode_object(values, decoders, num_decoders, out, false);
389 : : }
390 : :
391 : : int
392 : 1584 : 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 : 1584 : return _json_decode_object(values, decoders, num_decoders, out, true);
396 : : }
397 : :
398 : : int
399 : 1309 : 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 [ + - + + ]: 1309 : if (values == NULL || values->type != SPDK_JSON_VAL_ARRAY_BEGIN) {
407 : 4 : return -1;
408 : : }
409 : :
410 : 1305 : *out_size = 0;
411 : 1305 : field = out;
412 : 1305 : out_end = field + max_size * stride;
413 [ + + ]: 3948 : for (i = 0; i < values->len;) {
414 : 2655 : const struct spdk_json_val *v = &values[i + 1];
415 : :
416 [ + + ]: 2655 : if (field == out_end) {
417 : 4 : return -1;
418 : : }
419 : :
420 [ + + ]: 2651 : if (decode_func(v, field)) {
421 : 8 : return -1;
422 : : }
423 : :
424 : 2643 : i += spdk_json_val_len(v);
425 : 2643 : field += stride;
426 : 2643 : (*out_size)++;
427 : : }
428 : :
429 : 1293 : return 0;
430 : : }
431 : :
432 : : int
433 : 7515 : spdk_json_decode_bool(const struct spdk_json_val *val, void *out)
434 : : {
435 : 7515 : bool *f = out;
436 : :
437 [ + + + + ]: 7515 : if (val->type != SPDK_JSON_VAL_TRUE && val->type != SPDK_JSON_VAL_FALSE) {
438 : 4 : return -1;
439 : : }
440 : :
441 : 7511 : *f = val->type == SPDK_JSON_VAL_TRUE;
442 : 7511 : return 0;
443 : : }
444 : :
445 : : int
446 : 454 : spdk_json_decode_uint8(const struct spdk_json_val *val, void *out)
447 : : {
448 : 454 : uint8_t *i = out;
449 : :
450 : 454 : return spdk_json_number_to_uint8(val, i);
451 : : }
452 : :
453 : : int
454 : 213 : spdk_json_decode_uint16(const struct spdk_json_val *val, void *out)
455 : : {
456 : 213 : uint16_t *i = out;
457 : :
458 : 213 : return spdk_json_number_to_uint16(val, i);
459 : : }
460 : :
461 : : int
462 : 2072 : spdk_json_decode_int32(const struct spdk_json_val *val, void *out)
463 : : {
464 : 2072 : int32_t *i = out;
465 : :
466 : 2072 : return spdk_json_number_to_int32(val, i);
467 : : }
468 : :
469 : : int
470 : 16557 : spdk_json_decode_uint32(const struct spdk_json_val *val, void *out)
471 : : {
472 : 16557 : uint32_t *i = out;
473 : :
474 : 16557 : return spdk_json_number_to_uint32(val, i);
475 : : }
476 : :
477 : : int
478 : 6591 : spdk_json_decode_uint64(const struct spdk_json_val *val, void *out)
479 : : {
480 : 6591 : uint64_t *i = out;
481 : :
482 : 6591 : return spdk_json_number_to_uint64(val, i);
483 : : }
484 : :
485 : : int
486 : 53908 : spdk_json_decode_string(const struct spdk_json_val *val, void *out)
487 : : {
488 : 53908 : char **s = out;
489 : :
490 : 53908 : free(*s);
491 : :
492 : 53908 : *s = spdk_json_strdup(val);
493 : :
494 [ + + ]: 53908 : if (*s) {
495 : 53880 : return 0;
496 : : } else {
497 : 28 : return -1;
498 : : }
499 : : }
500 : :
501 : : int
502 : 1210 : spdk_json_decode_uuid(const struct spdk_json_val *val, void *out)
503 : : {
504 : 1210 : struct spdk_uuid *uuid = out;
505 : 1210 : char *str = NULL;
506 : : int rc;
507 : :
508 : 1210 : rc = spdk_json_decode_string(val, &str);
509 [ + + ]: 1210 : if (rc != 0) {
510 : 4 : return rc;
511 : : }
512 : :
513 : 1206 : rc = spdk_uuid_parse(uuid, str);
514 : 1206 : free(str);
515 : :
516 [ + + ]: 1206 : return rc == 0 ? 0 : -1;
517 : : }
518 : :
519 : : static struct spdk_json_val *
520 : 8799 : 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 [ - + ]: 8799 : assert((type & (SPDK_JSON_VAL_ARRAY_BEGIN | SPDK_JSON_VAL_OBJECT_BEGIN)) != 0);
524 : :
525 [ - + ]: 8799 : assert(object != NULL);
526 : :
527 [ + + ]: 8799 : if ((object->type & type) == 0) {
528 : 65 : return NULL;
529 : : }
530 : :
531 : 8734 : object++;
532 [ - + ]: 8734 : if (object->len == 0) {
533 : 0 : return NULL;
534 : : }
535 : :
536 : 8734 : return object;
537 : : }
538 : :
539 : : static struct spdk_json_val *
540 : 3174 : json_value(struct spdk_json_val *key)
541 : : {
542 [ + - ]: 3174 : return key->type == SPDK_JSON_VAL_NAME ? key + 1 : NULL;
543 : : }
544 : :
545 : : int
546 : 1589 : 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 : 1589 : struct spdk_json_val *_key = NULL;
550 : 1589 : struct spdk_json_val *_val = NULL;
551 : : struct spdk_json_val *it_first, *it;
552 : :
553 [ - + ]: 1589 : assert(object != NULL);
554 : :
555 : 1589 : it_first = json_first(object, SPDK_JSON_VAL_OBJECT_BEGIN);
556 [ + + ]: 1589 : if (!it_first) {
557 [ - + - + ]: 27 : SPDK_JSON_DEBUG("Not enclosed in {}\n");
558 : 27 : return -EPROTOTYPE;
559 : : }
560 : :
561 [ + + ]: 1776 : for (it = it_first;
562 [ + + ]: 2727 : it != NULL;
563 : 1584 : it = spdk_json_next(it)) {
564 [ - + ]: 1611 : if (it->type != SPDK_JSON_VAL_NAME) {
565 : 0 : continue;
566 : : }
567 : :
568 [ + + ]: 1611 : if (spdk_json_strequal(it, key_name) != true) {
569 : 53 : continue;
570 : : }
571 : :
572 [ - + ]: 1558 : if (_key) {
573 [ # # # # ]: 0 : SPDK_JSON_DEBUG("Duplicate key '%s'", key_name);
574 : 0 : return -EINVAL;
575 : : }
576 : :
577 : 1558 : _key = it;
578 : 1558 : _val = json_value(_key);
579 : :
580 [ + + + + ]: 1558 : if (type != SPDK_JSON_VAL_ANY && (_val->type & type) == 0) {
581 [ - + - + ]: 27 : SPDK_JSON_DEBUG("key '%s' type is %#x but expected one of %#x\n", key_name, _val->type, type);
582 : 27 : return -EDOM;
583 : : }
584 : : }
585 : :
586 [ + + ]: 1535 : if (key) {
587 : 20 : *key = _key;
588 : : }
589 : :
590 [ + - ]: 1535 : if (val) {
591 : 1535 : *val = _val;
592 : : }
593 : :
594 [ + + ]: 1535 : 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 : 1561 : 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 : 1561 : return spdk_json_find(object, key_name, key, val, SPDK_JSON_VAL_ARRAY_BEGIN);
609 : : }
610 : :
611 : : struct spdk_json_val *
612 : 8 : spdk_json_object_first(struct spdk_json_val *object)
613 : : {
614 : 8 : struct spdk_json_val *first = json_first(object, SPDK_JSON_VAL_OBJECT_BEGIN);
615 : :
616 : : /* Empty object? */
617 [ + - + - ]: 8 : return first && first->type != SPDK_JSON_VAL_OBJECT_END ? first : NULL;
618 : : }
619 : :
620 : : struct spdk_json_val *
621 : 7202 : spdk_json_array_first(struct spdk_json_val *array_begin)
622 : : {
623 : 7202 : struct spdk_json_val *first = json_first(array_begin, SPDK_JSON_VAL_ARRAY_BEGIN);
624 : :
625 : : /* Empty array? */
626 [ + + + + ]: 7202 : return first && first->type != SPDK_JSON_VAL_ARRAY_END ? first : NULL;
627 : : }
628 : :
629 : : static struct spdk_json_val *
630 : 14292 : 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 [ + + ]: 14292 : if (val->type == SPDK_JSON_VAL_OBJECT_BEGIN) {
637 : 12724 : end_type = SPDK_JSON_VAL_OBJECT_END;
638 [ + - ]: 1568 : } else if (val->type == SPDK_JSON_VAL_ARRAY_BEGIN) {
639 : 1568 : 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 : 14292 : lvl = 1;
647 [ + - + + ]: 400563 : for (it = val + 1; it->type != SPDK_JSON_VAL_INVALID && lvl != 0; it++) {
648 [ + + ]: 386271 : if (it->type == val->type) {
649 : 25857 : lvl++;
650 [ + + ]: 360414 : } else if (it->type == end_type) {
651 : 40149 : lvl--;
652 : : }
653 : : }
654 : :
655 : : /* if lvl != 0 we have invalid JSON object */
656 [ - + ]: 14292 : 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 : 14292 : return it;
662 : : }
663 : :
664 : : struct spdk_json_val *
665 : 15936 : spdk_json_next(struct spdk_json_val *it)
666 : : {
667 : : struct spdk_json_val *val, *next;
668 : :
669 [ + + + - : 15936 : switch (it->type) {
- ]
670 : 1604 : case SPDK_JSON_VAL_NAME:
671 : 1604 : val = json_value(it);
672 : 1604 : next = spdk_json_next(val);
673 : 1604 : break;
674 : :
675 : : /* We are in the middle of an array - get to next entry */
676 : 40 : 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 : 40 : val = it + 1;
682 : 40 : return val;
683 : :
684 : 14292 : case SPDK_JSON_VAL_ARRAY_BEGIN:
685 : : case SPDK_JSON_VAL_OBJECT_BEGIN:
686 : 14292 : next = json_skip_object_or_array(it);
687 : 14292 : 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 [ + + ]: 15896 : if (next == NULL) {
702 : 1543 : return NULL;
703 : : }
704 : :
705 [ + + ]: 14353 : switch (next->type) {
706 : 6699 : case SPDK_JSON_VAL_ARRAY_END:
707 : : case SPDK_JSON_VAL_OBJECT_END:
708 : : case SPDK_JSON_VAL_INVALID:
709 : 6699 : return NULL;
710 : 7654 : default:
711 : : /* Next value */
712 : 7654 : return next;
713 : : }
714 : : }
715 : :
716 : 3709 : SPDK_LOG_REGISTER_COMPONENT(json_util)
|