4 * Copyright (c) Intel Corporation.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include "spdk/json.h"
36 #include "spdk_internal/utf.h"
37 #include "spdk_internal/log.h"
39 #define SPDK_JSON_DEBUG(...) SPDK_DEBUGLOG(SPDK_LOG_JSON_UTIL, __VA_ARGS__)
42 spdk_json_val_len(const struct spdk_json_val
*val
)
48 if (val
->type
== SPDK_JSON_VAL_ARRAY_BEGIN
|| val
->type
== SPDK_JSON_VAL_OBJECT_BEGIN
) {
56 spdk_json_strequal(const struct spdk_json_val
*val
, const char *str
)
60 if (val
->type
!= SPDK_JSON_VAL_STRING
&& val
->type
!= SPDK_JSON_VAL_NAME
) {
65 if (val
->len
!= len
) {
69 return memcmp(val
->start
, str
, len
) == 0;
73 spdk_json_strdup(const struct spdk_json_val
*val
)
78 if (val
->type
!= SPDK_JSON_VAL_STRING
&& val
->type
!= SPDK_JSON_VAL_NAME
) {
84 if (memchr(val
->start
, '\0', len
)) {
85 /* String contains embedded NUL, so it is not a valid C string. */
94 memcpy(s
, val
->start
, len
);
100 struct spdk_json_num
{
102 uint64_t significand
;
107 spdk_json_number_split(const struct spdk_json_val
*val
, struct spdk_json_num
*num
)
112 uint64_t frac_digits
= 0;
113 uint64_t exponent_u64
= 0;
114 bool exponent_negative
= false;
121 memset(num
, 0, sizeof(*num
));
123 if (val
->type
!= SPDK_JSON_VAL_NUMBER
) {
127 remaining
= val
->len
;
128 if (remaining
== 0) {
134 num
->negative
= true;
139 state
= NUM_STATE_INT
;
140 pval
= &num
->significand
;
141 while (remaining
--) {
145 state
= NUM_STATE_FRAC
;
146 } else if (c
== 'e' || c
== 'E') {
147 state
= NUM_STATE_EXP
;
148 pval
= &exponent_u64
;
149 } else if (c
== '-') {
150 assert(state
== NUM_STATE_EXP
);
151 exponent_negative
= true;
152 } else if (c
== '+') {
153 assert(state
== NUM_STATE_EXP
);
154 /* exp_negative = false; */ /* already false by default */
158 assert(c
>= '0' && c
<= '9');
159 new_val
= *pval
* 10 + c
- '0';
160 if (new_val
< *pval
) {
164 if (state
== NUM_STATE_FRAC
) {
172 if (exponent_negative
) {
173 if (exponent_u64
> 9223372036854775808ULL) { /* abs(INT64_MIN) */
176 num
->exponent
= (int64_t) - exponent_u64
;
178 if (exponent_u64
> INT64_MAX
) {
181 num
->exponent
= exponent_u64
;
183 num
->exponent
-= frac_digits
;
185 /* Apply as much of the exponent as possible without overflow or truncation */
186 if (num
->exponent
< 0) {
187 while (num
->exponent
&& num
->significand
>= 10 && num
->significand
% 10 == 0) {
188 num
->significand
/= 10;
191 } else { /* positive exponent */
192 while (num
->exponent
) {
193 uint64_t new_val
= num
->significand
* 10;
195 if (new_val
< num
->significand
) {
199 num
->significand
= new_val
;
208 spdk_json_number_to_uint16(const struct spdk_json_val
*val
, uint16_t *num
)
210 struct spdk_json_num split_num
;
213 rc
= spdk_json_number_split(val
, &split_num
);
218 if (split_num
.exponent
|| split_num
.negative
) {
222 if (split_num
.significand
> UINT16_MAX
) {
225 *num
= (uint16_t)split_num
.significand
;
230 spdk_json_number_to_int32(const struct spdk_json_val
*val
, int32_t *num
)
232 struct spdk_json_num split_num
;
235 rc
= spdk_json_number_split(val
, &split_num
);
240 if (split_num
.exponent
) {
244 if (split_num
.negative
) {
245 if (split_num
.significand
> 2147483648) { /* abs(INT32_MIN) */
248 *num
= (int32_t) - (int64_t)split_num
.significand
;
253 if (split_num
.significand
> INT32_MAX
) {
256 *num
= (int32_t)split_num
.significand
;
261 spdk_json_number_to_uint32(const struct spdk_json_val
*val
, uint32_t *num
)
263 struct spdk_json_num split_num
;
266 rc
= spdk_json_number_split(val
, &split_num
);
271 if (split_num
.exponent
|| split_num
.negative
) {
275 if (split_num
.significand
> UINT32_MAX
) {
278 *num
= (uint32_t)split_num
.significand
;
283 spdk_json_number_to_uint64(const struct spdk_json_val
*val
, uint64_t *num
)
285 struct spdk_json_num split_num
;
288 rc
= spdk_json_number_split(val
, &split_num
);
293 if (split_num
.exponent
|| split_num
.negative
) {
297 *num
= split_num
.significand
;
302 spdk_json_decode_object(const struct spdk_json_val
*values
,
303 const struct spdk_json_object_decoder
*decoders
, size_t num_decoders
, void *out
)
306 bool invalid
= false;
310 if (values
== NULL
|| values
->type
!= SPDK_JSON_VAL_OBJECT_BEGIN
) {
314 seen
= calloc(sizeof(bool), num_decoders
);
319 for (i
= 0; i
< values
->len
;) {
320 const struct spdk_json_val
*name
= &values
[i
+ 1];
321 const struct spdk_json_val
*v
= &values
[i
+ 2];
324 for (decidx
= 0; decidx
< num_decoders
; decidx
++) {
325 const struct spdk_json_object_decoder
*dec
= &decoders
[decidx
];
326 if (spdk_json_strequal(name
, dec
->name
)) {
327 void *field
= (void *)((uintptr_t)out
+ dec
->offset
);
332 /* duplicate field name */
334 SPDK_JSON_DEBUG("Duplicate key '%s'\n", dec
->name
);
337 if (dec
->decode_func(v
, field
)) {
339 SPDK_JSON_DEBUG("Decoder failed to decode key '%s'\n", dec
->name
);
340 /* keep going to fill out any other valid keys */
349 SPDK_JSON_DEBUG("Decoder not found for key '%.*s'\n", name
->len
, (char *)name
->start
);
352 i
+= 1 + spdk_json_val_len(v
);
355 for (decidx
= 0; decidx
< num_decoders
; decidx
++) {
356 if (!decoders
[decidx
].optional
&& !seen
[decidx
]) {
357 /* required field is missing */
364 return invalid
? -1 : 0;
368 spdk_json_decode_array(const struct spdk_json_val
*values
, spdk_json_decode_fn decode_func
,
369 void *out
, size_t max_size
, size_t *out_size
, size_t stride
)
375 if (values
== NULL
|| values
->type
!= SPDK_JSON_VAL_ARRAY_BEGIN
) {
381 out_end
= field
+ max_size
* stride
;
382 for (i
= 0; i
< values
->len
;) {
383 const struct spdk_json_val
*v
= &values
[i
+ 1];
385 if (field
== out_end
) {
389 if (decode_func(v
, field
)) {
393 i
+= spdk_json_val_len(v
);
402 spdk_json_decode_bool(const struct spdk_json_val
*val
, void *out
)
406 if (val
->type
!= SPDK_JSON_VAL_TRUE
&& val
->type
!= SPDK_JSON_VAL_FALSE
) {
410 *f
= val
->type
== SPDK_JSON_VAL_TRUE
;
415 spdk_json_decode_uint16(const struct spdk_json_val
*val
, void *out
)
419 return spdk_json_number_to_uint16(val
, i
);
423 spdk_json_decode_int32(const struct spdk_json_val
*val
, void *out
)
427 return spdk_json_number_to_int32(val
, i
);
431 spdk_json_decode_uint32(const struct spdk_json_val
*val
, void *out
)
435 return spdk_json_number_to_uint32(val
, i
);
439 spdk_json_decode_uint64(const struct spdk_json_val
*val
, void *out
)
443 return spdk_json_number_to_uint64(val
, i
);
447 spdk_json_decode_string(const struct spdk_json_val
*val
, void *out
)
453 *s
= spdk_json_strdup(val
);
462 static struct spdk_json_val
*
463 spdk_json_first(struct spdk_json_val
*object
, enum spdk_json_val_type type
)
465 /* 'object' must be JSON object or array. 'type' might be combination of these two. */
466 assert((type
& (SPDK_JSON_VAL_ARRAY_BEGIN
| SPDK_JSON_VAL_OBJECT_BEGIN
)) != 0);
468 assert(object
!= NULL
);
470 if ((object
->type
& type
) == 0) {
475 if (object
->len
== 0) {
482 static struct spdk_json_val
*
483 spdk_json_value(struct spdk_json_val
*key
)
485 return key
->type
== SPDK_JSON_VAL_NAME
? key
+ 1 : NULL
;
489 spdk_json_find(struct spdk_json_val
*object
, const char *key_name
, struct spdk_json_val
**key
,
490 struct spdk_json_val
**val
, enum spdk_json_val_type type
)
492 struct spdk_json_val
*_key
= NULL
;
493 struct spdk_json_val
*_val
= NULL
;
494 struct spdk_json_val
*it
;
496 assert(object
!= NULL
);
498 for (it
= spdk_json_first(object
, SPDK_JSON_VAL_ARRAY_BEGIN
| SPDK_JSON_VAL_OBJECT_BEGIN
);
500 it
= spdk_json_next(it
)) {
501 if (it
->type
!= SPDK_JSON_VAL_NAME
) {
505 if (spdk_json_strequal(it
, key_name
) != true) {
510 SPDK_JSON_DEBUG("Duplicate key '%s'", key_name
);
515 _val
= spdk_json_value(_key
);
517 if (type
!= SPDK_JSON_VAL_INVALID
&& (_val
->type
& type
) == 0) {
518 SPDK_JSON_DEBUG("key '%s' type is %#x but expected one of %#x\n", key_name
, _val
->type
, type
);
531 return _val
? 0 : -ENOENT
;
535 spdk_json_find_string(struct spdk_json_val
*object
, const char *key_name
,
536 struct spdk_json_val
**key
, struct spdk_json_val
**val
)
538 return spdk_json_find(object
, key_name
, key
, val
, SPDK_JSON_VAL_STRING
);
542 spdk_json_find_array(struct spdk_json_val
*object
, const char *key_name
,
543 struct spdk_json_val
**key
, struct spdk_json_val
**val
)
545 return spdk_json_find(object
, key_name
, key
, val
, SPDK_JSON_VAL_ARRAY_BEGIN
);
548 struct spdk_json_val
*
549 spdk_json_object_first(struct spdk_json_val
*object
)
551 struct spdk_json_val
*first
= spdk_json_first(object
, SPDK_JSON_VAL_OBJECT_BEGIN
);
554 return first
&& first
->type
!= SPDK_JSON_VAL_OBJECT_END
? first
: NULL
;
557 struct spdk_json_val
*
558 spdk_json_array_first(struct spdk_json_val
*array_begin
)
560 struct spdk_json_val
*first
= spdk_json_first(array_begin
, SPDK_JSON_VAL_ARRAY_BEGIN
);
563 return first
&& first
->type
!= SPDK_JSON_VAL_ARRAY_END
? first
: NULL
;
566 static struct spdk_json_val
*
567 spdk_json_skip_object_or_array(struct spdk_json_val
*val
)
570 enum spdk_json_val_type end_type
;
571 struct spdk_json_val
*it
;
573 if (val
->type
== SPDK_JSON_VAL_OBJECT_BEGIN
) {
574 end_type
= SPDK_JSON_VAL_OBJECT_END
;
575 } else if (val
->type
== SPDK_JSON_VAL_ARRAY_BEGIN
) {
576 end_type
= SPDK_JSON_VAL_ARRAY_END
;
578 SPDK_JSON_DEBUG("Expected JSON object (%#x) or array (%#x) but got %#x\n",
579 SPDK_JSON_VAL_OBJECT_BEGIN
, SPDK_JSON_VAL_ARRAY_BEGIN
, val
->type
);
584 for (it
= val
+ 1; it
->type
!= SPDK_JSON_VAL_INVALID
&& lvl
!= 0; it
++) {
585 if (it
->type
== val
->type
) {
587 } else if (it
->type
== end_type
) {
592 /* if lvl != 0 we have invalid JSON object */
594 SPDK_JSON_DEBUG("Can't find end of object (type: %#x): lvl (%u) != 0)\n", val
->type
, lvl
);
601 struct spdk_json_val
*
602 spdk_json_next(struct spdk_json_val
*it
)
604 struct spdk_json_val
*val
, *next
;
607 case SPDK_JSON_VAL_NAME
:
608 val
= spdk_json_value(it
);
609 next
= spdk_json_next(val
);
612 /* We are in the middle of an array - get to next entry */
613 case SPDK_JSON_VAL_NULL
:
614 case SPDK_JSON_VAL_TRUE
:
615 case SPDK_JSON_VAL_FALSE
:
616 case SPDK_JSON_VAL_NUMBER
:
617 case SPDK_JSON_VAL_STRING
:
621 case SPDK_JSON_VAL_ARRAY_BEGIN
:
622 case SPDK_JSON_VAL_OBJECT_BEGIN
:
623 next
= spdk_json_skip_object_or_array(it
);
626 /* Can't go to the next object if started from the end of array or object */
627 case SPDK_JSON_VAL_ARRAY_END
:
628 case SPDK_JSON_VAL_OBJECT_END
:
629 case SPDK_JSON_VAL_INVALID
:
642 switch (next
->type
) {
643 case SPDK_JSON_VAL_ARRAY_END
:
644 case SPDK_JSON_VAL_OBJECT_END
:
645 case SPDK_JSON_VAL_INVALID
:
653 SPDK_LOG_REGISTER_COMPONENT("json_util", SPDK_LOG_JSON_UTIL
)