1 /*- 2 * BSD LICENSE 3 * 4 * Copyright (c) Intel Corporation. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 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 16 * distribution. 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. 20 * 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. 32 */ 33 34 #include "json_internal.h" 35 36 struct spdk_json_write_ctx { 37 spdk_json_write_cb write_cb; 38 void *cb_ctx; 39 uint32_t flags; 40 uint32_t indent; 41 bool new_indent; 42 bool first_value; 43 bool failed; 44 size_t buf_filled; 45 uint8_t buf[4096]; 46 }; 47 48 static int emit_buf_full(struct spdk_json_write_ctx *w, const void *data, size_t size); 49 50 static int 51 fail(struct spdk_json_write_ctx *w) 52 { 53 w->failed = true; 54 return -1; 55 } 56 57 static int 58 flush_buf(struct spdk_json_write_ctx *w) 59 { 60 int rc; 61 62 rc = w->write_cb(w->cb_ctx, w->buf, w->buf_filled); 63 if (rc != 0) { 64 return fail(w); 65 } 66 67 w->buf_filled = 0; 68 69 return 0; 70 } 71 72 struct spdk_json_write_ctx * 73 spdk_json_write_begin(spdk_json_write_cb write_cb, void *cb_ctx, uint32_t flags) 74 { 75 struct spdk_json_write_ctx *w; 76 77 w = calloc(1, sizeof(*w)); 78 if (w == NULL) { 79 return w; 80 } 81 82 w->write_cb = write_cb; 83 w->cb_ctx = cb_ctx; 84 w->flags = flags; 85 w->indent = 0; 86 w->new_indent = false; 87 w->first_value = true; 88 w->failed = false; 89 w->buf_filled = 0; 90 91 return w; 92 } 93 94 int 95 spdk_json_write_end(struct spdk_json_write_ctx *w) 96 { 97 bool failed; 98 int rc; 99 100 if (w == NULL) { 101 return 0; 102 } 103 104 failed = w->failed; 105 106 rc = flush_buf(w); 107 if (rc != 0) { 108 failed = true; 109 } 110 111 free(w); 112 113 return failed ? -1 : 0; 114 } 115 116 static inline int 117 emit(struct spdk_json_write_ctx *w, const void *data, size_t size) 118 { 119 size_t buf_remain = sizeof(w->buf) - w->buf_filled; 120 121 if (spdk_unlikely(size > buf_remain)) { 122 /* Not enough space in buffer for the new data. */ 123 return emit_buf_full(w, data, size); 124 } 125 126 /* Copy the new data into buf. */ 127 memcpy(w->buf + w->buf_filled, data, size); 128 w->buf_filled += size; 129 return 0; 130 } 131 132 static int 133 emit_buf_full(struct spdk_json_write_ctx *w, const void *data, size_t size) 134 { 135 size_t buf_remain = sizeof(w->buf) - w->buf_filled; 136 int rc; 137 138 assert(size > buf_remain); 139 140 /* Copy as much of the new data as possible into the buffer and flush it. */ 141 memcpy(w->buf + w->buf_filled, data, buf_remain); 142 w->buf_filled += buf_remain; 143 144 rc = flush_buf(w); 145 if (rc != 0) { 146 return fail(w); 147 } 148 149 /* Recurse to emit the rest of the data. */ 150 return emit(w, data + buf_remain, size - buf_remain); 151 } 152 153 static int 154 emit_fmt(struct spdk_json_write_ctx *w, const void *data, size_t size) 155 { 156 if (w->flags & SPDK_JSON_WRITE_FLAG_FORMATTED) { 157 return emit(w, data, size); 158 } 159 return 0; 160 } 161 162 static int 163 emit_indent(struct spdk_json_write_ctx *w) 164 { 165 uint32_t i; 166 167 if (w->flags & SPDK_JSON_WRITE_FLAG_FORMATTED) { 168 for (i = 0; i < w->indent; i++) { 169 if (emit(w, " ", 2)) return fail(w); 170 } 171 } 172 return 0; 173 } 174 175 static int 176 begin_value(struct spdk_json_write_ctx *w) 177 { 178 // TODO: check for value state 179 if (w->new_indent) { 180 if (emit_fmt(w, "\n", 1)) return fail(w); 181 if (emit_indent(w)) return fail(w); 182 } 183 if (!w->first_value) { 184 if (emit(w, ",", 1)) return fail(w); 185 if (emit_fmt(w, "\n", 1)) return fail(w); 186 if (emit_indent(w)) return fail(w); 187 } 188 w->first_value = false; 189 w->new_indent = false; 190 return 0; 191 } 192 193 int 194 spdk_json_write_val_raw(struct spdk_json_write_ctx *w, const void *data, size_t len) 195 { 196 if (begin_value(w)) return fail(w); 197 return emit(w, data, len); 198 } 199 200 int 201 spdk_json_write_null(struct spdk_json_write_ctx *w) 202 { 203 if (begin_value(w)) return fail(w); 204 return emit(w, "null", 4); 205 } 206 207 int 208 spdk_json_write_bool(struct spdk_json_write_ctx *w, bool val) 209 { 210 if (begin_value(w)) return fail(w); 211 if (val) { 212 return emit(w, "true", 4); 213 } else { 214 return emit(w, "false", 5); 215 } 216 } 217 218 int 219 spdk_json_write_int32(struct spdk_json_write_ctx *w, int32_t val) 220 { 221 char buf[32]; 222 int count; 223 224 if (begin_value(w)) return fail(w); 225 count = snprintf(buf, sizeof(buf), "%" PRId32, val); 226 if (count <= 0 || (size_t)count >= sizeof(buf)) return fail(w); 227 return emit(w, buf, count); 228 } 229 230 int 231 spdk_json_write_uint32(struct spdk_json_write_ctx *w, uint32_t val) 232 { 233 char buf[32]; 234 int count; 235 236 if (begin_value(w)) return fail(w); 237 count = snprintf(buf, sizeof(buf), "%" PRIu32, val); 238 if (count <= 0 || (size_t)count >= sizeof(buf)) return fail(w); 239 return emit(w, buf, count); 240 } 241 242 int 243 spdk_json_write_int64(struct spdk_json_write_ctx *w, int64_t val) 244 { 245 char buf[32]; 246 int count; 247 248 if (begin_value(w)) return fail(w); 249 count = snprintf(buf, sizeof(buf), "%" PRId64, val); 250 if (count <= 0 || (size_t)count >= sizeof(buf)) return fail(w); 251 return emit(w, buf, count); 252 } 253 254 int 255 spdk_json_write_uint64(struct spdk_json_write_ctx *w, uint64_t val) 256 { 257 char buf[32]; 258 int count; 259 260 if (begin_value(w)) return fail(w); 261 count = snprintf(buf, sizeof(buf), "%" PRIu64, val); 262 if (count <= 0 || (size_t)count >= sizeof(buf)) return fail(w); 263 return emit(w, buf, count); 264 } 265 266 static void 267 write_hex_4(void *dest, uint16_t val) 268 { 269 uint8_t *p = dest; 270 char hex[] = "0123456789ABCDEF"; 271 272 p[0] = hex[(val >> 12)]; 273 p[1] = hex[(val >> 8) & 0xF]; 274 p[2] = hex[(val >> 4) & 0xF]; 275 p[3] = hex[val & 0xF]; 276 } 277 278 static inline int 279 write_codepoint(struct spdk_json_write_ctx *w, uint32_t codepoint) 280 { 281 static const uint8_t escapes[] = { 282 ['\b'] = 'b', 283 ['\f'] = 'f', 284 ['\n'] = 'n', 285 ['\r'] = 'r', 286 ['\t'] = 't', 287 ['"'] = '"', 288 ['\\'] = '\\', 289 /* 290 * Forward slash (/) is intentionally not converted to an escape 291 * (it is valid unescaped). 292 */ 293 }; 294 uint16_t high, low; 295 char out[13]; 296 size_t out_len; 297 298 if (codepoint < sizeof(escapes) && escapes[codepoint]) { 299 out[0] = '\\'; 300 out[1] = escapes[codepoint]; 301 out_len = 2; 302 } else if (codepoint >= 0x20 && codepoint < 0x7F) { 303 /* 304 * Encode plain ASCII directly (except 0x7F, since it is really 305 * a control character, despite the JSON spec not considering it one). 306 */ 307 out[0] = (uint8_t)codepoint; 308 out_len = 1; 309 } else if (codepoint < 0x10000) { 310 out[0] = '\\'; 311 out[1] = 'u'; 312 write_hex_4(&out[2], (uint16_t)codepoint); 313 out_len = 6; 314 } else { 315 utf16_encode_surrogate_pair(codepoint, &high, &low); 316 out[0] = '\\'; 317 out[1] = 'u'; 318 write_hex_4(&out[2], high); 319 out[6] = '\\'; 320 out[7] = 'u'; 321 write_hex_4(&out[8], low); 322 out_len = 12; 323 } 324 325 return emit(w, out, out_len); 326 } 327 328 static int 329 write_string_or_name(struct spdk_json_write_ctx *w, const char *val, size_t len) 330 { 331 const uint8_t *p = val; 332 const uint8_t *end = val + len; 333 334 if (emit(w, "\"", 1)) return fail(w); 335 336 while (p != end) { 337 int codepoint_len; 338 uint32_t codepoint; 339 340 codepoint_len = utf8_valid(p, end); 341 switch (codepoint_len) { 342 case 1: 343 codepoint = utf8_decode_unsafe_1(p); 344 break; 345 case 2: 346 codepoint = utf8_decode_unsafe_2(p); 347 break; 348 case 3: 349 codepoint = utf8_decode_unsafe_3(p); 350 break; 351 case 4: 352 codepoint = utf8_decode_unsafe_4(p); 353 break; 354 default: 355 return fail(w); 356 } 357 358 if (write_codepoint(w, codepoint)) return fail(w); 359 p += codepoint_len; 360 } 361 362 return emit(w, "\"", 1); 363 } 364 365 static int 366 write_string_or_name_utf16le(struct spdk_json_write_ctx *w, const uint16_t *val, size_t len) 367 { 368 const uint16_t *p = val; 369 const uint16_t *end = val + len; 370 371 if (emit(w, "\"", 1)) return fail(w); 372 373 while (p != end) { 374 int codepoint_len; 375 uint32_t codepoint; 376 377 codepoint_len = utf16le_valid(p, end); 378 switch (codepoint_len) { 379 case 1: 380 codepoint = from_le16(&p[0]); 381 break; 382 case 2: 383 codepoint = utf16_decode_surrogate_pair(from_le16(&p[0]), from_le16(&p[1])); 384 break; 385 default: 386 return fail(w); 387 } 388 389 if (write_codepoint(w, codepoint)) return fail(w); 390 p += codepoint_len; 391 } 392 393 return emit(w, "\"", 1); 394 } 395 396 int 397 spdk_json_write_string_raw(struct spdk_json_write_ctx *w, const char *val, size_t len) 398 { 399 if (begin_value(w)) return fail(w); 400 return write_string_or_name(w, val, len); 401 } 402 403 int 404 spdk_json_write_string(struct spdk_json_write_ctx *w, const char *val) 405 { 406 return spdk_json_write_string_raw(w, val, strlen(val)); 407 } 408 409 int 410 spdk_json_write_string_utf16le_raw(struct spdk_json_write_ctx *w, const uint16_t *val, size_t len) 411 { 412 if (begin_value(w)) return fail(w); 413 return write_string_or_name_utf16le(w, val, len); 414 } 415 416 int 417 spdk_json_write_string_utf16le(struct spdk_json_write_ctx *w, const uint16_t *val) 418 { 419 const uint16_t *p; 420 size_t len; 421 422 for (len = 0, p = val; *p; p++) { 423 len++; 424 } 425 426 return spdk_json_write_string_utf16le_raw(w, val, len); 427 } 428 429 int 430 spdk_json_write_string_fmt(struct spdk_json_write_ctx *w, const char *fmt, ...) 431 { 432 char *s; 433 va_list args; 434 int rc; 435 436 va_start(args, fmt); 437 s = spdk_vsprintf_alloc(fmt, args); 438 va_end(args); 439 440 if (s == NULL) { 441 return -1; 442 } 443 444 rc = spdk_json_write_string(w, s); 445 free(s); 446 return rc; 447 } 448 449 int 450 spdk_json_write_array_begin(struct spdk_json_write_ctx *w) 451 { 452 if (begin_value(w)) return fail(w); 453 w->first_value = true; 454 w->new_indent = true; 455 w->indent++; 456 if (emit(w, "[", 1)) return fail(w); 457 return 0; 458 } 459 460 int 461 spdk_json_write_array_end(struct spdk_json_write_ctx *w) 462 { 463 w->first_value = false; 464 if (w->indent == 0) return fail(w); 465 w->indent--; 466 if (!w->new_indent) { 467 if (emit_fmt(w, "\n", 1)) return fail(w); 468 if (emit_indent(w)) return fail(w); 469 } 470 w->new_indent = false; 471 return emit(w, "]", 1); 472 } 473 474 int 475 spdk_json_write_object_begin(struct spdk_json_write_ctx *w) 476 { 477 if (begin_value(w)) return fail(w); 478 w->first_value = true; 479 w->new_indent = true; 480 w->indent++; 481 if (emit(w, "{", 1)) return fail(w); 482 return 0; 483 } 484 485 int 486 spdk_json_write_object_end(struct spdk_json_write_ctx *w) 487 { 488 w->first_value = false; 489 w->indent--; 490 if (!w->new_indent) { 491 if (emit_fmt(w, "\n", 1)) return fail(w); 492 if (emit_indent(w)) return fail(w); 493 } 494 w->new_indent = false; 495 return emit(w, "}", 1); 496 } 497 498 int 499 spdk_json_write_name_raw(struct spdk_json_write_ctx *w, const char *name, size_t len) 500 { 501 /* TODO: check that container is an object */ 502 if (begin_value(w)) return fail(w); 503 if (write_string_or_name(w, name, len)) return fail(w); 504 w->first_value = true; 505 if (emit(w, ":", 1)) return fail(w); 506 return emit_fmt(w, " ", 1); 507 } 508 509 int 510 spdk_json_write_name(struct spdk_json_write_ctx *w, const char *name) 511 { 512 return spdk_json_write_name_raw(w, name, strlen(name)); 513 } 514 515 int 516 spdk_json_write_val(struct spdk_json_write_ctx *w, const struct spdk_json_val *val) 517 { 518 size_t num_values, i; 519 520 switch (val->type) { 521 case SPDK_JSON_VAL_NUMBER: 522 return spdk_json_write_val_raw(w, val->start, val->len); 523 524 case SPDK_JSON_VAL_STRING: 525 return spdk_json_write_string_raw(w, val->start, val->len); 526 527 case SPDK_JSON_VAL_NAME: 528 return spdk_json_write_name_raw(w, val->start, val->len); 529 530 case SPDK_JSON_VAL_TRUE: 531 return spdk_json_write_bool(w, true); 532 533 case SPDK_JSON_VAL_FALSE: 534 return spdk_json_write_bool(w, false); 535 536 case SPDK_JSON_VAL_NULL: 537 return spdk_json_write_null(w); 538 539 case SPDK_JSON_VAL_ARRAY_BEGIN: 540 case SPDK_JSON_VAL_OBJECT_BEGIN: 541 num_values = val[0].len; 542 543 if (val[0].type == SPDK_JSON_VAL_OBJECT_BEGIN) { 544 if (spdk_json_write_object_begin(w)) { 545 return fail(w); 546 } 547 } else { 548 if (spdk_json_write_array_begin(w)) { 549 return fail(w); 550 } 551 } 552 553 // Loop up to and including the _END value 554 for (i = 0; i < num_values + 1;) { 555 if (spdk_json_write_val(w, &val[i + 1])) { 556 return fail(w); 557 } 558 if (val[i + 1].type == SPDK_JSON_VAL_ARRAY_BEGIN || 559 val[i + 1].type == SPDK_JSON_VAL_OBJECT_BEGIN) { 560 i += val[i + 1].len + 2; 561 } else { 562 i++; 563 } 564 } 565 return 0; 566 567 case SPDK_JSON_VAL_ARRAY_END: 568 return spdk_json_write_array_end(w); 569 570 case SPDK_JSON_VAL_OBJECT_END: 571 return spdk_json_write_object_end(w); 572 573 case SPDK_JSON_VAL_INVALID: 574 // Handle INVALID to make the compiler happy (and catch other unhandled types) 575 return fail(w); 576 } 577 578 return fail(w); 579 } 580