LCOV - code coverage report
Current view: top level - lib/json - json_write.c (source / functions) Hit Total Coverage
Test: ut_cov_unit.info Lines: 300 393 76.3 %
Date: 2024-12-14 00:46:58 Functions: 42 57 73.7 %

          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             : 
      10             : struct spdk_json_write_ctx {
      11             :         spdk_json_write_cb write_cb;
      12             :         void *cb_ctx;
      13             :         uint32_t flags;
      14             :         uint32_t indent;
      15             :         bool new_indent;
      16             :         bool first_value;
      17             :         bool failed;
      18             :         size_t buf_filled;
      19             :         uint8_t buf[4096];
      20             : };
      21             : 
      22             : static int emit_buf_full(struct spdk_json_write_ctx *w, const void *data, size_t size);
      23             : 
      24             : static int
      25          48 : fail(struct spdk_json_write_ctx *w)
      26             : {
      27          48 :         w->failed = true;
      28          48 :         return -1;
      29             : }
      30             : 
      31             : static int
      32         194 : flush_buf(struct spdk_json_write_ctx *w)
      33             : {
      34             :         int rc;
      35             : 
      36         194 :         rc = w->write_cb(w->cb_ctx, w->buf, w->buf_filled);
      37         194 :         if (rc != 0) {
      38           0 :                 return fail(w);
      39             :         }
      40             : 
      41         194 :         w->buf_filled = 0;
      42             : 
      43         194 :         return 0;
      44             : }
      45             : 
      46             : struct spdk_json_write_ctx *
      47         194 : spdk_json_write_begin(spdk_json_write_cb write_cb, void *cb_ctx, uint32_t flags)
      48             : {
      49             :         struct spdk_json_write_ctx *w;
      50             : 
      51         194 :         w = calloc(1, sizeof(*w));
      52         194 :         if (w == NULL) {
      53           0 :                 return w;
      54             :         }
      55             : 
      56         194 :         w->write_cb = write_cb;
      57         194 :         w->cb_ctx = cb_ctx;
      58         194 :         w->flags = flags;
      59         194 :         w->indent = 0;
      60         194 :         w->new_indent = false;
      61         194 :         w->first_value = true;
      62         194 :         w->failed = false;
      63         194 :         w->buf_filled = 0;
      64             : 
      65         194 :         return w;
      66             : }
      67             : 
      68             : int
      69         194 : spdk_json_write_end(struct spdk_json_write_ctx *w)
      70             : {
      71             :         bool failed;
      72             :         int rc;
      73             : 
      74         194 :         if (w == NULL) {
      75           0 :                 return 0;
      76             :         }
      77             : 
      78         194 :         failed = w->failed;
      79             : 
      80         194 :         rc = flush_buf(w);
      81         194 :         if (rc != 0) {
      82           0 :                 failed = true;
      83             :         }
      84             : 
      85         194 :         free(w);
      86             : 
      87         194 :         return failed ? -1 : 0;
      88             : }
      89             : 
      90             : static inline int
      91        2540 : emit(struct spdk_json_write_ctx *w, const void *data, size_t size)
      92             : {
      93        2540 :         size_t buf_remain = sizeof(w->buf) - w->buf_filled;
      94             : 
      95        2540 :         if (spdk_unlikely(size > buf_remain)) {
      96             :                 /* Not enough space in buffer for the new data. */
      97           0 :                 return emit_buf_full(w, data, size);
      98             :         }
      99             : 
     100             :         /* Copy the new data into buf. */
     101        2540 :         memcpy(w->buf + w->buf_filled, data, size);
     102        2540 :         w->buf_filled += size;
     103        2540 :         return 0;
     104             : }
     105             : 
     106             : static int
     107           0 : emit_buf_full(struct spdk_json_write_ctx *w, const void *data, size_t size)
     108             : {
     109           0 :         size_t buf_remain = sizeof(w->buf) - w->buf_filled;
     110             :         int rc;
     111             : 
     112           0 :         assert(size > buf_remain);
     113             : 
     114             :         /* Copy as much of the new data as possible into the buffer and flush it. */
     115           0 :         memcpy(w->buf + w->buf_filled, data, buf_remain);
     116           0 :         w->buf_filled += buf_remain;
     117             : 
     118           0 :         rc = flush_buf(w);
     119           0 :         if (rc != 0) {
     120           0 :                 return fail(w);
     121             :         }
     122             : 
     123             :         /* Recurse to emit the rest of the data. */
     124           0 :         return emit(w, data + buf_remain, size - buf_remain);
     125             : }
     126             : 
     127             : static int
     128         389 : emit_fmt(struct spdk_json_write_ctx *w, const void *data, size_t size)
     129             : {
     130         389 :         if (w->flags & SPDK_JSON_WRITE_FLAG_FORMATTED) {
     131           0 :                 return emit(w, data, size);
     132             :         }
     133         389 :         return 0;
     134             : }
     135             : 
     136             : static int
     137         254 : emit_indent(struct spdk_json_write_ctx *w)
     138             : {
     139             :         uint32_t i;
     140             : 
     141         254 :         if (w->flags & SPDK_JSON_WRITE_FLAG_FORMATTED) {
     142           0 :                 for (i = 0; i < w->indent; i++) {
     143           0 :                         if (emit(w, "  ", 2)) { return fail(w); }
     144             :                 }
     145             :         }
     146         254 :         return 0;
     147             : }
     148             : 
     149             : static int
     150         508 : begin_value(struct spdk_json_write_ctx *w)
     151             : {
     152             :         /* TODO: check for value state */
     153         508 :         if (w->new_indent) {
     154          76 :                 if (emit_fmt(w, "\n", 1)) { return fail(w); }
     155          76 :                 if (emit_indent(w)) { return fail(w); }
     156             :         }
     157         508 :         if (!w->first_value) {
     158         104 :                 if (emit(w, ",", 1)) { return fail(w); }
     159         104 :                 if (emit_fmt(w, "\n", 1)) { return fail(w); }
     160         104 :                 if (emit_indent(w)) { return fail(w); }
     161             :         }
     162         508 :         w->first_value = false;
     163         508 :         w->new_indent = false;
     164         508 :         return 0;
     165             : }
     166             : 
     167             : int
     168           7 : spdk_json_write_val_raw(struct spdk_json_write_ctx *w, const void *data, size_t len)
     169             : {
     170           7 :         if (begin_value(w)) { return fail(w); }
     171           7 :         return emit(w, data, len);
     172             : }
     173             : 
     174             : int
     175          13 : spdk_json_write_null(struct spdk_json_write_ctx *w)
     176             : {
     177          13 :         if (begin_value(w)) { return fail(w); }
     178          13 :         return emit(w, "null", 4);
     179             : }
     180             : 
     181             : int
     182          15 : spdk_json_write_bool(struct spdk_json_write_ctx *w, bool val)
     183             : {
     184          15 :         if (begin_value(w)) { return fail(w); }
     185          15 :         if (val) {
     186          10 :                 return emit(w, "true", 4);
     187             :         } else {
     188           5 :                 return emit(w, "false", 5);
     189             :         }
     190             : }
     191             : 
     192             : int
     193           0 : spdk_json_write_uint8(struct spdk_json_write_ctx *w, uint8_t val)
     194             : {
     195           0 :         char buf[32];
     196             :         int count;
     197             : 
     198           0 :         if (begin_value(w)) { return fail(w); }
     199           0 :         count = snprintf(buf, sizeof(buf), "%" PRIu8, val);
     200           0 :         if (count <= 0 || (size_t)count >= sizeof(buf)) { return fail(w); }
     201           0 :         return emit(w, buf, count);
     202             : }
     203             : 
     204             : int
     205           0 : spdk_json_write_uint16(struct spdk_json_write_ctx *w, uint16_t val)
     206             : {
     207           0 :         char buf[32];
     208             :         int count;
     209             : 
     210           0 :         if (begin_value(w)) { return fail(w); }
     211           0 :         count = snprintf(buf, sizeof(buf), "%" PRIu16, val);
     212           0 :         if (count <= 0 || (size_t)count >= sizeof(buf)) { return fail(w); }
     213           0 :         return emit(w, buf, count);
     214             : }
     215             : 
     216             : int
     217          54 : spdk_json_write_int32(struct spdk_json_write_ctx *w, int32_t val)
     218             : {
     219          54 :         char buf[32];
     220             :         int count;
     221             : 
     222          54 :         if (begin_value(w)) { return fail(w); }
     223          54 :         count = snprintf(buf, sizeof(buf), "%" PRId32, val);
     224          54 :         if (count <= 0 || (size_t)count >= sizeof(buf)) { return fail(w); }
     225          54 :         return emit(w, buf, count);
     226             : }
     227             : 
     228             : int
     229           9 : spdk_json_write_uint32(struct spdk_json_write_ctx *w, uint32_t val)
     230             : {
     231           9 :         char buf[32];
     232             :         int count;
     233             : 
     234           9 :         if (begin_value(w)) { return fail(w); }
     235           9 :         count = snprintf(buf, sizeof(buf), "%" PRIu32, val);
     236           9 :         if (count <= 0 || (size_t)count >= sizeof(buf)) { return fail(w); }
     237           9 :         return emit(w, buf, count);
     238             : }
     239             : 
     240             : int
     241           6 : spdk_json_write_int64(struct spdk_json_write_ctx *w, int64_t val)
     242             : {
     243           6 :         char buf[32];
     244             :         int count;
     245             : 
     246           6 :         if (begin_value(w)) { return fail(w); }
     247           6 :         count = snprintf(buf, sizeof(buf), "%" PRId64, val);
     248           6 :         if (count <= 0 || (size_t)count >= sizeof(buf)) { return fail(w); }
     249           6 :         return emit(w, buf, count);
     250             : }
     251             : 
     252             : int
     253          13 : spdk_json_write_uint64(struct spdk_json_write_ctx *w, uint64_t val)
     254             : {
     255          13 :         char buf[32];
     256             :         int count;
     257             : 
     258          13 :         if (begin_value(w)) { return fail(w); }
     259          13 :         count = snprintf(buf, sizeof(buf), "%" PRIu64, val);
     260          13 :         if (count <= 0 || (size_t)count >= sizeof(buf)) { return fail(w); }
     261          13 :         return emit(w, buf, count);
     262             : }
     263             : 
     264             : int
     265          16 : spdk_json_write_uint128(struct spdk_json_write_ctx *w, uint64_t low_val, uint64_t high_val)
     266             : {
     267          16 :         char buf[128] = {'\0'};
     268          16 :         uint64_t low = low_val, high = high_val;
     269          16 :         int count = 0;
     270             : 
     271          16 :         if (begin_value(w)) { return fail(w); }
     272             : 
     273          16 :         if (high != 0) {
     274           8 :                 char temp_buf[128] = {'\0'};
     275             :                 uint64_t seg;
     276           8 :                 unsigned __int128 total = (unsigned __int128)low +
     277           8 :                                           ((unsigned __int128)high << 64);
     278             : 
     279          28 :                 while (total) {
     280          20 :                         seg = total % 10000000000;
     281          20 :                         total = total / 10000000000;
     282          20 :                         if (total) {
     283          12 :                                 count = snprintf(temp_buf, 128, "%010" PRIu64 "%s", seg, buf);
     284             :                         } else {
     285           8 :                                 count = snprintf(temp_buf, 128, "%" PRIu64 "%s", seg, buf);
     286             :                         }
     287             : 
     288          20 :                         if (count <= 0 || (size_t)count >= sizeof(temp_buf)) {
     289           0 :                                 return fail(w);
     290             :                         }
     291             : 
     292          20 :                         snprintf(buf, 128, "%s", temp_buf);
     293             :                 }
     294             :         } else {
     295           8 :                 count = snprintf(buf, sizeof(buf), "%" PRIu64, low);
     296             : 
     297           8 :                 if (count <= 0 || (size_t)count >= sizeof(buf)) { return fail(w); }
     298             :         }
     299             : 
     300          16 :         return emit(w, buf, count);
     301             : }
     302             : 
     303             : int
     304           8 : spdk_json_write_named_uint128(struct spdk_json_write_ctx *w, const char *name,
     305             :                               uint64_t low_val, uint64_t high_val)
     306             : {
     307           8 :         int rc = spdk_json_write_name(w, name);
     308             : 
     309           8 :         return rc ? rc : spdk_json_write_uint128(w, low_val, high_val);
     310             : }
     311             : 
     312             : int
     313           4 : spdk_json_write_double(struct spdk_json_write_ctx *w, double val)
     314             : {
     315           4 :         char buf[32];
     316             :         int count;
     317             : 
     318           4 :         if (begin_value(w)) { return fail(w); }
     319           4 :         count = snprintf(buf, sizeof(buf), "%.20e", val);
     320           4 :         if (count <= 0 || (size_t)count >= sizeof(buf)) { return fail(w); }
     321           4 :         return emit(w, buf, count);
     322             : }
     323             : 
     324             : static void
     325         126 : write_hex_2(void *dest, uint8_t val)
     326             : {
     327         126 :         char *p = dest;
     328         126 :         char hex[] = "0123456789ABCDEF";
     329             : 
     330         126 :         p[0] = hex[val >> 4];
     331         126 :         p[1] = hex[val & 0xf];
     332         126 : }
     333             : 
     334             : static void
     335          63 : write_hex_4(void *dest, uint16_t val)
     336             : {
     337          63 :         write_hex_2(dest, (uint8_t)(val >> 8));
     338          63 :         write_hex_2((char *)dest + 2, (uint8_t)(val & 0xff));
     339          63 : }
     340             : 
     341             : static inline int
     342        1472 : write_codepoint(struct spdk_json_write_ctx *w, uint32_t codepoint)
     343             : {
     344             :         static const uint8_t escapes[] = {
     345             :                 ['\b'] = 'b',
     346             :                 ['\f'] = 'f',
     347             :                 ['\n'] = 'n',
     348             :                 ['\r'] = 'r',
     349             :                 ['\t'] = 't',
     350             :                 ['"'] = '"',
     351             :                 ['\\'] = '\\',
     352             :                 /*
     353             :                  * Forward slash (/) is intentionally not converted to an escape
     354             :                  *  (it is valid unescaped).
     355             :                  */
     356             :         };
     357        1472 :         uint16_t high, low;
     358        1472 :         char out[13];
     359             :         size_t out_len;
     360             : 
     361        1472 :         if (codepoint < sizeof(escapes) && escapes[codepoint]) {
     362           8 :                 out[0] = '\\';
     363           8 :                 out[1] = escapes[codepoint];
     364           8 :                 out_len = 2;
     365        1464 :         } else if (codepoint >= 0x20 && codepoint < 0x7F) {
     366             :                 /*
     367             :                  * Encode plain ASCII directly (except 0x7F, since it is really
     368             :                  *  a control character, despite the JSON spec not considering it one).
     369             :                  */
     370        1417 :                 out[0] = (uint8_t)codepoint;
     371        1417 :                 out_len = 1;
     372          47 :         } else if (codepoint < 0x10000) {
     373          31 :                 out[0] = '\\';
     374          31 :                 out[1] = 'u';
     375          31 :                 write_hex_4(&out[2], (uint16_t)codepoint);
     376          31 :                 out_len = 6;
     377             :         } else {
     378          16 :                 utf16_encode_surrogate_pair(codepoint, &high, &low);
     379          16 :                 out[0] = '\\';
     380          16 :                 out[1] = 'u';
     381          16 :                 write_hex_4(&out[2], high);
     382          16 :                 out[6] = '\\';
     383          16 :                 out[7] = 'u';
     384          16 :                 write_hex_4(&out[8], low);
     385          16 :                 out_len = 12;
     386             :         }
     387             : 
     388        1472 :         return emit(w, out, out_len);
     389             : }
     390             : 
     391             : static int
     392         283 : write_string_or_name(struct spdk_json_write_ctx *w, const char *val, size_t len)
     393             : {
     394         283 :         const uint8_t *p = val;
     395         283 :         const uint8_t *end = val + len;
     396             : 
     397         283 :         if (emit(w, "\"", 1)) { return fail(w); }
     398             : 
     399        1745 :         while (p != end) {
     400             :                 int codepoint_len;
     401             :                 uint32_t codepoint;
     402             : 
     403        1507 :                 codepoint_len = utf8_valid(p, end);
     404        1507 :                 switch (codepoint_len) {
     405        1421 :                 case 1:
     406        1421 :                         codepoint = utf8_decode_unsafe_1(p);
     407        1421 :                         break;
     408           6 :                 case 2:
     409           6 :                         codepoint = utf8_decode_unsafe_2(p);
     410           6 :                         break;
     411          20 :                 case 3:
     412          20 :                         codepoint = utf8_decode_unsafe_3(p);
     413          20 :                         break;
     414          15 :                 case 4:
     415          15 :                         codepoint = utf8_decode_unsafe_4(p);
     416          15 :                         break;
     417          45 :                 default:
     418          45 :                         return fail(w);
     419             :                 }
     420             : 
     421        1462 :                 if (write_codepoint(w, codepoint)) { return fail(w); }
     422        1462 :                 p += codepoint_len;
     423             :         }
     424             : 
     425         238 :         return emit(w, "\"", 1);
     426             : }
     427             : 
     428             : static int
     429           5 : write_string_or_name_utf16le(struct spdk_json_write_ctx *w, const uint16_t *val, size_t len)
     430             : {
     431           5 :         const uint16_t *p = val;
     432           5 :         const uint16_t *end = val + len;
     433             : 
     434           5 :         if (emit(w, "\"", 1)) { return fail(w); }
     435             : 
     436          15 :         while (p != end) {
     437             :                 int codepoint_len;
     438             :                 uint32_t codepoint;
     439             : 
     440          13 :                 codepoint_len = utf16le_valid(p, end);
     441          13 :                 switch (codepoint_len) {
     442           9 :                 case 1:
     443           9 :                         codepoint = from_le16(&p[0]);
     444           9 :                         break;
     445           1 :                 case 2:
     446           1 :                         codepoint = utf16_decode_surrogate_pair(from_le16(&p[0]), from_le16(&p[1]));
     447           1 :                         break;
     448           3 :                 default:
     449           3 :                         return fail(w);
     450             :                 }
     451             : 
     452          10 :                 if (write_codepoint(w, codepoint)) { return fail(w); }
     453          10 :                 p += codepoint_len;
     454             :         }
     455             : 
     456           2 :         return emit(w, "\"", 1);
     457             : }
     458             : 
     459             : int
     460         148 : spdk_json_write_string_raw(struct spdk_json_write_ctx *w, const char *val, size_t len)
     461             : {
     462         148 :         if (begin_value(w)) { return fail(w); }
     463         148 :         return write_string_or_name(w, val, len);
     464             : }
     465             : 
     466             : int
     467          43 : spdk_json_write_string(struct spdk_json_write_ctx *w, const char *val)
     468             : {
     469          43 :         return spdk_json_write_string_raw(w, val, strlen(val));
     470             : }
     471             : 
     472             : int
     473           5 : spdk_json_write_string_utf16le_raw(struct spdk_json_write_ctx *w, const uint16_t *val, size_t len)
     474             : {
     475           5 :         if (begin_value(w)) { return fail(w); }
     476           5 :         return write_string_or_name_utf16le(w, val, len);
     477             : }
     478             : 
     479             : int
     480           0 : spdk_json_write_string_utf16le(struct spdk_json_write_ctx *w, const uint16_t *val)
     481             : {
     482             :         const uint16_t *p;
     483             :         size_t len;
     484             : 
     485           0 :         for (len = 0, p = val; *p; p++) {
     486           0 :                 len++;
     487             :         }
     488             : 
     489           0 :         return spdk_json_write_string_utf16le_raw(w, val, len);
     490             : }
     491             : 
     492             : int
     493           0 : spdk_json_write_string_fmt(struct spdk_json_write_ctx *w, const char *fmt, ...)
     494             : {
     495           0 :         va_list args;
     496             :         int rc;
     497             : 
     498           0 :         va_start(args, fmt);
     499           0 :         rc = spdk_json_write_string_fmt_v(w, fmt, args);
     500           0 :         va_end(args);
     501             : 
     502           0 :         return rc;
     503             : }
     504             : 
     505             : int
     506           0 : spdk_json_write_string_fmt_v(struct spdk_json_write_ctx *w, const char *fmt, va_list args)
     507             : {
     508             :         char *s;
     509             :         int rc;
     510             : 
     511           0 :         s = spdk_vsprintf_alloc(fmt, args);
     512           0 :         if (s == NULL) {
     513           0 :                 return -1;
     514             :         }
     515             : 
     516           0 :         rc = spdk_json_write_string(w, s);
     517           0 :         free(s);
     518           0 :         return rc;
     519             : }
     520             : 
     521             : int
     522           0 : spdk_json_write_bytearray(struct spdk_json_write_ctx *w, const void *val, size_t len)
     523             : {
     524           0 :         const uint8_t *v = val;
     525             :         size_t i;
     526             :         char *s;
     527             :         int rc;
     528             : 
     529           0 :         s = malloc(2 * len + 1);
     530           0 :         if (s == NULL) {
     531           0 :                 return -1;
     532             :         }
     533             : 
     534           0 :         for (i = 0; i < len; ++i) {
     535           0 :                 write_hex_2(&s[2 * i], *v++);
     536             :         }
     537           0 :         s[2 * len] = '\0';
     538             : 
     539           0 :         rc = spdk_json_write_string(w, s);
     540           0 :         free(s);
     541           0 :         return rc;
     542             : }
     543             : 
     544             : int
     545           1 : spdk_json_write_uuid(struct spdk_json_write_ctx *w, const struct spdk_uuid *uuid)
     546             : {
     547           1 :         char str[SPDK_UUID_STRING_LEN];
     548             : 
     549           1 :         spdk_uuid_fmt_lower(str, sizeof(str), uuid);
     550             : 
     551           1 :         return spdk_json_write_string(w, str);
     552             : }
     553             : 
     554             : int
     555          33 : spdk_json_write_array_begin(struct spdk_json_write_ctx *w)
     556             : {
     557          33 :         if (begin_value(w)) { return fail(w); }
     558          33 :         w->first_value = true;
     559          33 :         w->new_indent = true;
     560          33 :         w->indent++;
     561          33 :         if (emit(w, "[", 1)) { return fail(w); }
     562          33 :         return 0;
     563             : }
     564             : 
     565             : int
     566          33 : spdk_json_write_array_end(struct spdk_json_write_ctx *w)
     567             : {
     568          33 :         w->first_value = false;
     569          33 :         if (w->indent == 0) { return fail(w); }
     570          33 :         w->indent--;
     571          33 :         if (!w->new_indent) {
     572          28 :                 if (emit_fmt(w, "\n", 1)) { return fail(w); }
     573          28 :                 if (emit_indent(w)) { return fail(w); }
     574             :         }
     575          33 :         w->new_indent = false;
     576          33 :         return emit(w, "]", 1);
     577             : }
     578             : 
     579             : int
     580          50 : spdk_json_write_object_begin(struct spdk_json_write_ctx *w)
     581             : {
     582          50 :         if (begin_value(w)) { return fail(w); }
     583          50 :         w->first_value = true;
     584          50 :         w->new_indent = true;
     585          50 :         w->indent++;
     586          50 :         if (emit(w, "{", 1)) { return fail(w); }
     587          50 :         return 0;
     588             : }
     589             : 
     590             : int
     591          48 : spdk_json_write_object_end(struct spdk_json_write_ctx *w)
     592             : {
     593          48 :         w->first_value = false;
     594          48 :         w->indent--;
     595          48 :         if (!w->new_indent) {
     596          46 :                 if (emit_fmt(w, "\n", 1)) { return fail(w); }
     597          46 :                 if (emit_indent(w)) { return fail(w); }
     598             :         }
     599          48 :         w->new_indent = false;
     600          48 :         return emit(w, "}", 1);
     601             : }
     602             : 
     603             : int
     604         135 : spdk_json_write_name_raw(struct spdk_json_write_ctx *w, const char *name, size_t len)
     605             : {
     606             :         /* TODO: check that container is an object */
     607         135 :         if (begin_value(w)) { return fail(w); }
     608         135 :         if (write_string_or_name(w, name, len)) { return fail(w); }
     609         135 :         w->first_value = true;
     610         135 :         if (emit(w, ":", 1)) { return fail(w); }
     611         135 :         return emit_fmt(w, " ", 1);
     612             : }
     613             : 
     614             : int
     615         103 : spdk_json_write_name(struct spdk_json_write_ctx *w, const char *name)
     616             : {
     617         103 :         return spdk_json_write_name_raw(w, name, strlen(name));
     618             : }
     619             : 
     620             : int
     621          24 : spdk_json_write_val(struct spdk_json_write_ctx *w, const struct spdk_json_val *val)
     622             : {
     623             :         size_t num_values, i;
     624             : 
     625          24 :         switch (val->type) {
     626           7 :         case SPDK_JSON_VAL_NUMBER:
     627           7 :                 return spdk_json_write_val_raw(w, val->start, val->len);
     628             : 
     629           1 :         case SPDK_JSON_VAL_STRING:
     630           1 :                 return spdk_json_write_string_raw(w, val->start, val->len);
     631             : 
     632           6 :         case SPDK_JSON_VAL_NAME:
     633           6 :                 return spdk_json_write_name_raw(w, val->start, val->len);
     634             : 
     635           1 :         case SPDK_JSON_VAL_TRUE:
     636           1 :                 return spdk_json_write_bool(w, true);
     637             : 
     638           1 :         case SPDK_JSON_VAL_FALSE:
     639           1 :                 return spdk_json_write_bool(w, false);
     640             : 
     641           2 :         case SPDK_JSON_VAL_NULL:
     642           2 :                 return spdk_json_write_null(w);
     643             : 
     644           3 :         case SPDK_JSON_VAL_ARRAY_BEGIN:
     645             :         case SPDK_JSON_VAL_OBJECT_BEGIN:
     646           3 :                 num_values = val[0].len;
     647             : 
     648           3 :                 if (val[0].type == SPDK_JSON_VAL_OBJECT_BEGIN) {
     649           2 :                         if (spdk_json_write_object_begin(w)) {
     650           0 :                                 return fail(w);
     651             :                         }
     652             :                 } else {
     653           1 :                         if (spdk_json_write_array_begin(w)) {
     654           0 :                                 return fail(w);
     655             :                         }
     656             :                 }
     657             : 
     658             :                 /* Loop up to and including the _END value */
     659          21 :                 for (i = 0; i < num_values + 1;) {
     660          18 :                         if (spdk_json_write_val(w, &val[i + 1])) {
     661           0 :                                 return fail(w);
     662             :                         }
     663          18 :                         if (val[i + 1].type == SPDK_JSON_VAL_ARRAY_BEGIN ||
     664          17 :                             val[i + 1].type == SPDK_JSON_VAL_OBJECT_BEGIN) {
     665           2 :                                 i += val[i + 1].len + 2;
     666             :                         } else {
     667          16 :                                 i++;
     668             :                         }
     669             :                 }
     670           3 :                 return 0;
     671             : 
     672           1 :         case SPDK_JSON_VAL_ARRAY_END:
     673           1 :                 return spdk_json_write_array_end(w);
     674             : 
     675           2 :         case SPDK_JSON_VAL_OBJECT_END:
     676           2 :                 return spdk_json_write_object_end(w);
     677             : 
     678           0 :         case SPDK_JSON_VAL_INVALID:
     679             :                 /* Handle INVALID to make the compiler happy (and catch other unhandled types) */
     680           0 :                 return fail(w);
     681             :         }
     682             : 
     683           0 :         return fail(w);
     684             : }
     685             : 
     686             : int
     687           0 : spdk_json_write_named_null(struct spdk_json_write_ctx *w, const char *name)
     688             : {
     689           0 :         int rc = spdk_json_write_name(w, name);
     690           0 :         return rc ? rc : spdk_json_write_null(w);
     691             : }
     692             : 
     693             : int
     694           4 : spdk_json_write_named_bool(struct spdk_json_write_ctx *w, const char *name, bool val)
     695             : {
     696           4 :         int rc = spdk_json_write_name(w, name);
     697             : 
     698           4 :         return rc ? rc : spdk_json_write_bool(w, val);
     699             : }
     700             : 
     701             : int
     702           0 : spdk_json_write_named_uint8(struct spdk_json_write_ctx *w, const char *name, uint8_t val)
     703             : {
     704           0 :         int rc = spdk_json_write_name(w, name);
     705             : 
     706           0 :         return rc ? rc : spdk_json_write_uint8(w, val);
     707             : }
     708             : 
     709             : int
     710           0 : spdk_json_write_named_uint16(struct spdk_json_write_ctx *w, const char *name, uint16_t val)
     711             : {
     712           0 :         int rc = spdk_json_write_name(w, name);
     713             : 
     714           0 :         return rc ? rc : spdk_json_write_uint16(w, val);
     715             : }
     716             : 
     717             : int
     718           9 : spdk_json_write_named_int32(struct spdk_json_write_ctx *w, const char *name, int32_t val)
     719             : {
     720           9 :         int rc = spdk_json_write_name(w, name);
     721             : 
     722           9 :         return rc ? rc : spdk_json_write_int32(w, val);
     723             : }
     724             : 
     725             : int
     726           4 : spdk_json_write_named_uint32(struct spdk_json_write_ctx *w, const char *name, uint32_t val)
     727             : {
     728           4 :         int rc = spdk_json_write_name(w, name);
     729             : 
     730           4 :         return rc ? rc : spdk_json_write_uint32(w, val);
     731             : }
     732             : 
     733             : int
     734           0 : spdk_json_write_named_int64(struct spdk_json_write_ctx *w, const char *name, int64_t val)
     735             : {
     736           0 :         int rc = spdk_json_write_name(w, name);
     737             : 
     738           0 :         return rc ? rc : spdk_json_write_int64(w, val);
     739             : }
     740             : 
     741             : int
     742           8 : spdk_json_write_named_uint64(struct spdk_json_write_ctx *w, const char *name, uint64_t val)
     743             : {
     744           8 :         int rc = spdk_json_write_name(w, name);
     745             : 
     746           8 :         return rc ? rc : spdk_json_write_uint64(w, val);
     747             : }
     748             : 
     749             : int
     750           0 : spdk_json_write_named_double(struct spdk_json_write_ctx *w, const char *name, double val)
     751             : {
     752           0 :         int rc = spdk_json_write_name(w, name);
     753             : 
     754           0 :         return rc ? rc : spdk_json_write_double(w, val);
     755             : }
     756             : 
     757             : int
     758          27 : spdk_json_write_named_string(struct spdk_json_write_ctx *w, const char *name, const char *val)
     759             : {
     760          27 :         int rc = spdk_json_write_name(w, name);
     761             : 
     762          27 :         return rc ? rc : spdk_json_write_string(w, val);
     763             : }
     764             : 
     765             : int
     766           0 : spdk_json_write_named_string_fmt(struct spdk_json_write_ctx *w, const char *name,
     767             :                                  const char *fmt, ...)
     768             : {
     769           0 :         va_list args;
     770             :         int rc;
     771             : 
     772           0 :         va_start(args, fmt);
     773           0 :         rc = spdk_json_write_named_string_fmt_v(w, name, fmt, args);
     774           0 :         va_end(args);
     775             : 
     776           0 :         return rc;
     777             : }
     778             : 
     779             : int
     780           9 : spdk_json_write_named_string_fmt_v(struct spdk_json_write_ctx *w, const char *name,
     781             :                                    const char *fmt, va_list args)
     782             : {
     783             :         char *s;
     784             :         int rc;
     785             : 
     786           9 :         rc = spdk_json_write_name(w, name);
     787           9 :         if (rc) {
     788           0 :                 return rc;
     789             :         }
     790             : 
     791           9 :         s = spdk_vsprintf_alloc(fmt, args);
     792             : 
     793           9 :         if (s == NULL) {
     794           0 :                 return -1;
     795             :         }
     796             : 
     797           9 :         rc = spdk_json_write_string(w, s);
     798           9 :         free(s);
     799           9 :         return rc;
     800             : }
     801             : 
     802             : int
     803           0 : spdk_json_write_named_bytearray(struct spdk_json_write_ctx *w, const char *name, const void *val,
     804             :                                 size_t len)
     805             : {
     806           0 :         int rc = spdk_json_write_name(w, name);
     807             : 
     808           0 :         return rc ? rc : spdk_json_write_bytearray(w, val, len);
     809             : }
     810             : 
     811             : int
     812           4 : spdk_json_write_named_array_begin(struct spdk_json_write_ctx *w, const char *name)
     813             : {
     814           4 :         int rc = spdk_json_write_name(w, name);
     815             : 
     816           4 :         return rc ? rc : spdk_json_write_array_begin(w);
     817             : }
     818             : 
     819             : int
     820           9 : spdk_json_write_named_object_begin(struct spdk_json_write_ctx *w, const char *name)
     821             : {
     822           9 :         int rc = spdk_json_write_name(w, name);
     823             : 
     824           9 :         return rc ? rc : spdk_json_write_object_begin(w);
     825             : }
     826             : 
     827             : int
     828           0 : spdk_json_write_named_uuid(struct spdk_json_write_ctx *w, const char *name,
     829             :                            const struct spdk_uuid *uuid)
     830             : {
     831           0 :         int rc = spdk_json_write_name(w, name);
     832             : 
     833           0 :         return rc ? rc : spdk_json_write_uuid(w, uuid);
     834             : }

Generated by: LCOV version 1.15