|
39 | 39 | #define snprintf _snprintf
|
40 | 40 | #endif
|
41 | 41 |
|
| 42 | +#include "utf8proc.h" |
| 43 | + |
42 | 44 | const static json_serialize_opts default_opts =
|
43 | 45 | {
|
44 | 46 | json_serialize_mode_single_line,
|
@@ -458,20 +460,95 @@ json_value * json_object_merge (json_value * objectA, json_value * objectB)
|
458 | 460 | static size_t measure_string (unsigned int length,
|
459 | 461 | const json_char * str)
|
460 | 462 | {
|
| 463 | + ssize_t i = 0; |
| 464 | + int32_t c = -1; |
| 465 | + size_t measured_length = 0; |
461 | 466 |
|
462 |
| - /* TODO encoding |
463 |
| - */ |
464 |
| - return strlen (str); |
| 467 | + for(;;) |
| 468 | + { |
| 469 | + i += utf8proc_iterate ((const uint8_t *) str + i, length - i, &c); |
| 470 | + |
| 471 | + if(c == -1) |
| 472 | + break; |
| 473 | + |
| 474 | + switch (c) |
| 475 | + { |
| 476 | + case '"': |
| 477 | + case '\\': |
| 478 | + case '/': |
| 479 | + case '\b': |
| 480 | + case '\f': |
| 481 | + case '\n': |
| 482 | + case '\r': |
| 483 | + case '\t': |
| 484 | + |
| 485 | + measured_length += 2; |
| 486 | + break; |
| 487 | + |
| 488 | + case 0: |
| 489 | + |
| 490 | + measured_length += 6; |
| 491 | + break; |
| 492 | + |
| 493 | + default: |
| 494 | + |
| 495 | + measured_length += utf8proc_measure_char (c); |
| 496 | + break; |
| 497 | + }; |
| 498 | + }; |
| 499 | + |
| 500 | + return measured_length; |
465 | 501 | }
|
466 | 502 |
|
| 503 | +#define PRINT_ESCAPED(c) do { \ |
| 504 | + *buf ++ = '\\'; \ |
| 505 | + *buf ++ = (c); \ |
| 506 | +} while(0); \ |
| 507 | + |
467 | 508 | static size_t serialize_string (json_char * buf,
|
468 | 509 | unsigned int length,
|
469 | 510 | const json_char * str)
|
470 | 511 | {
|
471 |
| - /* TODO encoding |
472 |
| - */ |
473 |
| - memcpy (buf, str, length); |
474 |
| - return length; |
| 512 | + ssize_t i = 0; |
| 513 | + int32_t c = -1; |
| 514 | + json_char * orig_buf; |
| 515 | + |
| 516 | + orig_buf = buf; |
| 517 | + |
| 518 | + for(;;) |
| 519 | + { |
| 520 | + i += utf8proc_iterate ((const uint8_t *) str + i, length - i, &c); |
| 521 | + |
| 522 | + if(c == -1) |
| 523 | + break; |
| 524 | + |
| 525 | + switch (c) |
| 526 | + { |
| 527 | + case '"': PRINT_ESCAPED ('\"'); continue; |
| 528 | + case '\\': PRINT_ESCAPED ('\\'); continue; |
| 529 | + case '/': PRINT_ESCAPED ('/'); continue; |
| 530 | + case '\b': PRINT_ESCAPED ('b'); continue; |
| 531 | + case '\f': PRINT_ESCAPED ('f'); continue; |
| 532 | + case '\n': PRINT_ESCAPED ('n'); continue; |
| 533 | + case '\r': PRINT_ESCAPED ('r'); continue; |
| 534 | + case '\t': PRINT_ESCAPED ('t'); continue; |
| 535 | + |
| 536 | + case 0: |
| 537 | + |
| 538 | + PRINT_ESCAPED ('u'); |
| 539 | + sprintf (buf, "%04x", c); |
| 540 | + buf += 4; |
| 541 | + |
| 542 | + break; |
| 543 | + |
| 544 | + default: |
| 545 | + |
| 546 | + buf += utf8proc_encode_char (c, (uint8_t *) buf); |
| 547 | + break; |
| 548 | + }; |
| 549 | + }; |
| 550 | + |
| 551 | + return buf - orig_buf; |
475 | 552 | }
|
476 | 553 |
|
477 | 554 | size_t json_measure (json_value * value)
|
|
0 commit comments