2#include "cson_amalgamation_core.h"
17# ifdef JSON_PARSER_DLL_EXPORTS
18# define JSON_PARSER_DLL_API __declspec(dllexport)
20# define JSON_PARSER_DLL_API __declspec(dllimport)
23# define JSON_PARSER_DLL_API
26# define JSON_PARSER_DLL_API
31typedef __int64 JSON_int_t;
32#define JSON_PARSER_INTEGER_SSCANF_TOKEN "%I64d"
33#define JSON_PARSER_INTEGER_SPRINTF_TOKEN "%I64d"
34#elif (__STDC_VERSION__ >= 199901L) || (HAVE_LONG_LONG == 1)
35typedef long long JSON_int_t;
36#define JSON_PARSER_INTEGER_SSCANF_TOKEN "%lld"
37#define JSON_PARSER_INTEGER_SPRINTF_TOKEN "%lld"
39typedef long JSON_int_t;
40#define JSON_PARSER_INTEGER_SSCANF_TOKEN "%ld"
41#define JSON_PARSER_INTEGER_SPRINTF_TOKEN "%ld"
53 JSON_E_INVALID_KEYWORD,
54 JSON_E_INVALID_ESCAPE_SEQUENCE,
55 JSON_E_INVALID_UNICODE_SEQUENCE,
56 JSON_E_INVALID_NUMBER,
57 JSON_E_NESTING_DEPTH_REACHED,
58 JSON_E_UNBALANCED_COLLECTION,
60 JSON_E_EXPECTED_COLON,
83 JSON_int_t integer_value;
107typedef int (*JSON_parser_callback)(
void* ctx,
int type,
const JSON_value* value);
113typedef void* (*JSON_malloc_t)(
size_t n);
117typedef void (*JSON_free_t)(
void* mem);
178JSON_PARSER_DLL_API
void init_JSON_config(
JSON_config * config);
193JSON_PARSER_DLL_API
void delete_JSON_parser(
JSON_parser jc);
199JSON_PARSER_DLL_API
int JSON_parser_char(
JSON_parser jc,
int next_char);
207JSON_PARSER_DLL_API
int JSON_parser_done(
JSON_parser jc);
213JSON_PARSER_DLL_API
int JSON_parser_is_legal_white_space_string(
const char* s);
219JSON_PARSER_DLL_API
int JSON_parser_get_last_error(
JSON_parser jc);
225JSON_PARSER_DLL_API
int JSON_parser_reset(
JSON_parser jc);
318# pragma warning(disable:4996)
319# pragma warning(disable:4127)
329#ifndef JSON_PARSER_STACK_SIZE
330# define JSON_PARSER_STACK_SIZE 128
333#ifndef JSON_PARSER_PARSE_BUFFER_SIZE
334# define JSON_PARSER_PARSE_BUFFER_SIZE 3500
337typedef void* (*JSON_debug_malloc_t)(
size_t bytes,
const char* reason);
339#ifdef JSON_PARSER_DEBUG_MALLOC
340# define JSON_parser_malloc(func, bytes, reason) ((JSON_debug_malloc_t)func)(bytes, reason)
342# define JSON_parser_malloc(func, bytes, reason) func(bytes)
345typedef unsigned short UTF16;
348 JSON_parser_callback callback;
350 signed char state, before_comment_state, type, escaped, comment, allow_comments, handle_floats_manually, error;
352 UTF16 utf16_high_surrogate;
359 size_t parse_buffer_capacity;
360 size_t parse_buffer_count;
361 signed char static_stack[JSON_PARSER_STACK_SIZE];
362 char static_parse_buffer[JSON_PARSER_PARSE_BUFFER_SIZE];
363 JSON_malloc_t malloc;
367#define COUNTOF(x) (sizeof(x)/sizeof(x[0]))
412static const signed char ascii_class[128] = {
418 __, __, __, __, __, __, __, __,
419 __, C_WHITE, C_WHITE, __, __, C_WHITE, __, __,
420 __, __, __, __, __, __, __, __,
421 __, __, __, __, __, __, __, __,
423 C_SPACE, C_ETC, C_QUOTE, C_ETC, C_ETC, C_ETC, C_ETC, C_ETC,
424 C_ETC, C_ETC, C_STAR, C_PLUS, C_COMMA, C_MINUS, C_POINT, C_SLASH,
425 C_ZERO, C_DIGIT, C_DIGIT, C_DIGIT, C_DIGIT, C_DIGIT, C_DIGIT, C_DIGIT,
426 C_DIGIT, C_DIGIT, C_COLON, C_ETC, C_ETC, C_ETC, C_ETC, C_ETC,
428 C_ETC, C_ABCDF, C_ABCDF, C_ABCDF, C_ABCDF, C_E, C_ABCDF, C_ETC,
429 C_ETC, C_ETC, C_ETC, C_ETC, C_ETC, C_ETC, C_ETC, C_ETC,
430 C_ETC, C_ETC, C_ETC, C_ETC, C_ETC, C_ETC, C_ETC, C_ETC,
431 C_ETC, C_ETC, C_ETC, C_LSQRB, C_BACKS, C_RSQRB, C_ETC, C_ETC,
433 C_ETC, C_LOW_A, C_LOW_B, C_LOW_C, C_LOW_D, C_LOW_E, C_LOW_F, C_ETC,
434 C_ETC, C_ETC, C_ETC, C_ETC, C_LOW_L, C_ETC, C_LOW_N, C_ETC,
435 C_ETC, C_ETC, C_LOW_R, C_LOW_S, C_LOW_T, C_LOW_U, C_ETC, C_ETC,
436 C_ETC, C_ETC, C_ETC, C_LCURB, C_ETC, C_RCURB, C_ETC, C_ETC
501static const signed char state_transition_table[NR_STATES][NR_CLASSES] = {
510 {GO,GO,-6,__,-5,__,__,__,__,__,CB,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
511 {OK,OK,__,-8,__,-7,__,-3,__,__,CB,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
512 {OB,OB,__,-9,__,__,__,__,SB,__,CB,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
513 {KE,KE,__,__,__,__,__,__,SB,__,CB,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
514 {CO,CO,__,__,__,__,-2,__,__,__,CB,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
515 {VA,VA,-6,__,-5,__,__,__,SB,__,CB,__,MX,__,ZX,IX,__,__,__,__,__,FA,__,NU,__,__,TR,__,__,__,__,__},
516 {AR,AR,-6,__,-5,-7,__,__,SB,__,CB,__,MX,__,ZX,IX,__,__,__,__,__,FA,__,NU,__,__,TR,__,__,__,__,__},
517 {ST,__,ST,ST,ST,ST,ST,ST,-4,EX,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST},
518 {__,__,__,__,__,__,__,__,ST,ST,ST,__,__,__,__,__,__,ST,__,__,__,ST,__,ST,ST,__,ST,U1,__,__,__,__},
519 {__,__,__,__,__,__,__,__,__,__,__,__,__,__,U2,U2,U2,U2,U2,U2,U2,U2,__,__,__,__,__,__,U2,U2,__,__},
520 {__,__,__,__,__,__,__,__,__,__,__,__,__,__,U3,U3,U3,U3,U3,U3,U3,U3,__,__,__,__,__,__,U3,U3,__,__},
521 {__,__,__,__,__,__,__,__,__,__,__,__,__,__,U4,U4,U4,U4,U4,U4,U4,U4,__,__,__,__,__,__,U4,U4,__,__},
522 {__,__,__,__,__,__,__,__,__,__,__,__,__,__,UC,UC,UC,UC,UC,UC,UC,UC,__,__,__,__,__,__,UC,UC,__,__},
523 {__,__,__,__,__,__,__,__,__,__,__,__,__,__,ZE,IT,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
524 {OK,OK,__,-8,__,-7,__,-3,__,__,CB,__,__,DF,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
525 {OK,OK,__,-8,__,-7,__,-3,__,__,CB,__,__,DF,IT,IT,__,__,__,__,DE,__,__,__,__,__,__,__,__,DE,__,__},
526 {OK,OK,__,-8,__,-7,__,-3,__,__,CB,__,__,__,FR,FR,__,__,__,__,E1,__,__,__,__,__,__,__,__,E1,__,__},
527 {__,__,__,__,__,__,__,__,__,__,__,E2,E2,__,E3,E3,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
528 {__,__,__,__,__,__,__,__,__,__,__,__,__,__,E3,E3,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
529 {OK,OK,__,-8,__,-7,__,-3,__,__,__,__,__,__,E3,E3,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
530 {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,T2,__,__,__,__,__,__,__},
531 {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,T3,__,__,__,__},
532 {__,__,__,__,__,__,__,__,__,__,CB,__,__,__,__,__,__,__,__,__,OK,__,__,__,__,__,__,__,__,__,__,__},
533 {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,F2,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
534 {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,F3,__,__,__,__,__,__,__,__,__},
535 {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,F4,__,__,__,__,__,__},
536 {__,__,__,__,__,__,__,__,__,__,CB,__,__,__,__,__,__,__,__,__,OK,__,__,__,__,__,__,__,__,__,__,__},
537 {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,N2,__,__,__,__},
538 {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,N3,__,__,__,__,__,__,__,__,__},
539 {__,__,__,__,__,__,__,__,__,__,CB,__,__,__,__,__,__,__,__,__,__,__,OK,__,__,__,__,__,__,__,__,__},
540 {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,C2},
541 {C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C3},
542 {C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,CE,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C3},
543 {OK,OK,__,-8,__,-7,__,-3,__,__,__,__,__,__,FR,FR,__,__,__,__,E1,__,__,__,__,__,__,__,__,E1,__,__},
544 {__,__,__,__,__,__,__,__,__,D2,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
545 {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,U1,__,__,__,__},
563 switch (jc->current_char) {
564 case '{':
case '}':
case '[':
case ']':
565 jc->error = JSON_E_UNBALANCED_COLLECTION;
568 jc->error = JSON_E_INVALID_CHAR;
573 jc->error = JSON_E_EXPECTED_KEY;
576 jc->error = JSON_E_UNBALANCED_COLLECTION;
579 jc->error = JSON_E_EXPECTED_COLON;
582 jc->error = JSON_E_EXPECTED_KEY;
585 case U1:
case U2:
case U3:
case U4:
case D1:
case D2:
586 jc->error = JSON_E_INVALID_UNICODE_SEQUENCE;
589 case T1:
case T2:
case T3:
case F1:
case F2:
case F3:
case F4:
case N1:
case N2:
case N3:
590 jc->error = JSON_E_INVALID_KEYWORD;
593 case MI:
case ZE:
case IT:
case FR:
case E1:
case E2:
case E3:
594 jc->error = JSON_E_INVALID_NUMBER;
597 jc->error = JSON_E_INVALID_CHAR;
608 assert(jc->top <= jc->stack_capacity);
611 if (jc->top == jc->stack_capacity) {
612 const size_t bytes_to_copy = jc->stack_capacity *
sizeof(jc->stack[0]);
613 const size_t new_capacity = jc->stack_capacity * 2;
614 const size_t bytes_to_allocate = new_capacity *
sizeof(jc->stack[0]);
615 void* mem = JSON_parser_malloc(jc->malloc, bytes_to_allocate,
"stack");
617 jc->error = JSON_E_OUT_OF_MEMORY;
620 jc->stack_capacity = (int)new_capacity;
621 memcpy(mem, jc->stack, bytes_to_copy);
622 if (jc->stack != &jc->static_stack[0]) {
625 jc->stack = (
signed char*)mem;
628 if (jc->top == jc->depth) {
629 jc->error = JSON_E_NESTING_DEPTH_REACHED;
633 jc->stack[++jc->top] = (
signed char)mode;
645 if (jc->top < 0 || jc->stack[jc->top] != mode) {
653#define parse_buffer_clear(jc) \
655 jc->parse_buffer_count = 0;\
656 jc->parse_buffer[0] = 0;\
659#define parse_buffer_pop_back_char(jc)\
661 assert(jc->parse_buffer_count >= 1);\
662 --jc->parse_buffer_count;\
663 jc->parse_buffer[jc->parse_buffer_count] = 0;\
671 if (jc->stack != &jc->static_stack[0]) {
672 jc->free((
void*)jc->stack);
674 if (jc->parse_buffer != &jc->static_parse_buffer[0]) {
675 jc->free((
void*)jc->parse_buffer);
691 if (NULL == jc->parse_buffer) {
695 jc->stack_capacity = jc->depth;
696 if (jc->depth <= (
int)COUNTOF(jc->static_stack)) {
697 jc->stack = &jc->static_stack[0];
699 const size_t bytes_to_alloc = jc->stack_capacity *
sizeof(jc->stack[0]);
700 jc->stack = (
signed char*)JSON_parser_malloc(jc->malloc, bytes_to_alloc,
"stack");
701 if (jc->stack == NULL) {
706 jc->stack_capacity = (int)COUNTOF(jc->static_stack);
708 jc->stack = &jc->static_stack[0];
712 jc->parse_buffer = &jc->static_parse_buffer[0];
713 jc->parse_buffer_capacity = COUNTOF(jc->static_parse_buffer);
718 parse_buffer_clear(jc);
736 int use_std_malloc =
false;
742 if (NULL == config) {
744 init_JSON_config(&default_config);
745 config = &default_config;
749 use_std_malloc = NULL == config->
malloc || NULL == config->
free;
751 alloc = use_std_malloc ? malloc : config->
malloc;
753 jc = (
JSON_parser)JSON_parser_malloc(alloc,
sizeof(*jc),
"parser");
760 memset(jc, 0,
sizeof(*jc));
762 jc->free = use_std_malloc ? free : config->
free;
767 jc->decimal_point = *localeconv()->decimal_point;
769 jc->depth = config->
depth == 0 ? 1 : config->
depth;
772 if (!JSON_parser_reset(jc)) {
782 const size_t bytes_to_copy = jc->parse_buffer_count *
sizeof(jc->parse_buffer[0]);
783 const size_t new_capacity = jc->parse_buffer_capacity * 2;
784 const size_t bytes_to_allocate = new_capacity *
sizeof(jc->parse_buffer[0]);
785 void* mem = JSON_parser_malloc(jc->malloc, bytes_to_allocate,
"parse buffer");
788 jc->error = JSON_E_OUT_OF_MEMORY;
792 assert(new_capacity > 0);
793 memcpy(mem, jc->parse_buffer, bytes_to_copy);
795 if (jc->parse_buffer != &jc->static_parse_buffer[0]) {
796 jc->free(jc->parse_buffer);
799 jc->parse_buffer = (
char*)mem;
800 jc->parse_buffer_capacity = new_capacity;
805static int parse_buffer_reserve_for(
JSON_parser jc,
unsigned chars)
807 while (jc->parse_buffer_count + chars + 1 > jc->parse_buffer_capacity) {
808 if (!parse_buffer_grow(jc)) {
809 assert(jc->error == JSON_E_OUT_OF_MEMORY);
817#define parse_buffer_has_space_for(jc, count) \
818 (jc->parse_buffer_count + (count) + 1 <= jc->parse_buffer_capacity)
820#define parse_buffer_push_back_char(jc, c)\
822 assert(parse_buffer_has_space_for(jc, 1)); \
823 jc->parse_buffer[jc->parse_buffer_count++] = c;\
824 jc->parse_buffer[jc->parse_buffer_count] = 0;\
827#define assert_is_non_container_type(jc) \
829 jc->type == JSON_T_NULL || \
830 jc->type == JSON_T_FALSE || \
831 jc->type == JSON_T_TRUE || \
832 jc->type == JSON_T_FLOAT || \
833 jc->type == JSON_T_INTEGER || \
834 jc->type == JSON_T_STRING)
842 if (jc->type != JSON_T_NONE) {
843 assert_is_non_container_type(jc);
848 if (jc->handle_floats_manually) {
849 value.vu.str.value = jc->parse_buffer;
850 value.vu.str.length = jc->parse_buffer_count;
853 value.vu.float_value = strtod(jc->parse_buffer, NULL);
858 sscanf(jc->parse_buffer, JSON_PARSER_INTEGER_SSCANF_TOKEN, &value.vu.integer_value);
862 value.vu.str.value = jc->parse_buffer;
863 value.vu.str.length = jc->parse_buffer_count;
867 if (!(*jc->callback)(jc->ctx, jc->type, arg)) {
873 parse_buffer_clear(jc);
878#define IS_HIGH_SURROGATE(uc) (((uc) & 0xFC00) == 0xD800)
879#define IS_LOW_SURROGATE(uc) (((uc) & 0xFC00) == 0xDC00)
880#define DECODE_SURROGATE_PAIR(hi,lo) ((((hi) & 0x3FF) << 10) + ((lo) & 0x3FF) + 0x10000)
881static const unsigned char utf8_lead_bits[4] = { 0x00, 0xC0, 0xE0, 0xF0 };
890 assert(jc->parse_buffer_count >= 6);
892 p = &jc->parse_buffer[jc->parse_buffer_count - 4];
894 for (i = 12; i >= 0; i -= 4, ++p) {
899 }
else if (x >=
'A') {
911 jc->parse_buffer_count -= 6;
912 jc->parse_buffer[jc->parse_buffer_count] = 0;
914 if (uc == 0xffff || uc == 0xfffe) {
919 if (jc->utf16_high_surrogate) {
920 if (IS_LOW_SURROGATE(uc)) {
921 uc = DECODE_SURROGATE_PAIR(jc->utf16_high_surrogate, uc);
923 jc->utf16_high_surrogate = 0;
931 }
else if (uc < 0x800) {
933 }
else if (IS_HIGH_SURROGATE(uc)) {
935 jc->utf16_high_surrogate = (UTF16)uc;
937 }
else if (IS_LOW_SURROGATE(uc)) {
945 jc->parse_buffer[jc->parse_buffer_count++] = (char) ((uc >> (trail_bytes * 6)) | utf8_lead_bits[trail_bytes]);
947 for (i = trail_bytes * 6 - 6; i >= 0; i -= 6) {
948 jc->parse_buffer[jc->parse_buffer_count++] = (char) (((uc >> i) & 0x3F) | 0x80);
951 jc->parse_buffer[jc->parse_buffer_count] = 0;
956static int add_escaped_char_to_parse_buffer(
JSON_parser jc,
int next_char)
958 assert(parse_buffer_has_space_for(jc, 1));
962 parse_buffer_pop_back_char(jc);
965 parse_buffer_push_back_char(jc,
'\b');
968 parse_buffer_push_back_char(jc,
'\f');
971 parse_buffer_push_back_char(jc,
'\n');
974 parse_buffer_push_back_char(jc,
'\r');
977 parse_buffer_push_back_char(jc,
'\t');
980 parse_buffer_push_back_char(jc,
'"');
983 parse_buffer_push_back_char(jc,
'\\');
986 parse_buffer_push_back_char(jc,
'/');
989 parse_buffer_push_back_char(jc,
'\\');
990 parse_buffer_push_back_char(jc,
'u');
999static int add_char_to_parse_buffer(
JSON_parser jc,
int next_char,
int next_class)
1001 if (!parse_buffer_reserve_for(jc, 1)) {
1002 assert(JSON_E_OUT_OF_MEMORY == jc->error);
1007 if (!add_escaped_char_to_parse_buffer(jc, next_char)) {
1008 jc->error = JSON_E_INVALID_ESCAPE_SEQUENCE;
1011 }
else if (!jc->comment) {
1012 if ((jc->type != JSON_T_NONE) | !((next_class == C_SPACE) | (next_class == C_WHITE)) ) {
1013 parse_buffer_push_back_char(jc, (
char)next_char);
1020#define assert_type_isnt_string_null_or_bool(jc) \
1021 assert(jc->type != JSON_T_FALSE); \
1022 assert(jc->type != JSON_T_TRUE); \
1023 assert(jc->type != JSON_T_NULL); \
1024 assert(jc->type != JSON_T_STRING)
1036 int next_class, next_state;
1041 jc->current_char = next_char;
1046 if (next_char < 0) {
1047 jc->error = JSON_E_INVALID_CHAR;
1050 if (next_char >= 128) {
1053 next_class = ascii_class[next_char];
1054 if (next_class <= __) {
1060 if (!add_char_to_parse_buffer(jc, next_char, next_class)) {
1067 next_state = state_transition_table[jc->state][next_class];
1068 if (next_state >= 0) {
1072 jc->state = (
signed char)next_state;
1077 switch (next_state) {
1080 if(!decode_unicode_char(jc)) {
1081 jc->error = JSON_E_INVALID_UNICODE_SEQUENCE;
1085 if (jc->utf16_high_surrogate) {
1098 jc->type = JSON_T_INTEGER;
1103 jc->type = JSON_T_INTEGER;
1108 jc->type = JSON_T_INTEGER;
1114 assert_type_isnt_string_null_or_bool(jc);
1115 jc->type = JSON_T_FLOAT;
1121 assert_type_isnt_string_null_or_bool(jc);
1122 if (!jc->handle_floats_manually) {
1127 assert(jc->parse_buffer[jc->parse_buffer_count-1] ==
'.');
1128 jc->parse_buffer[jc->parse_buffer_count-1] = jc->decimal_point;
1130 jc->type = JSON_T_FLOAT;
1135 parse_buffer_clear(jc);
1136 assert(jc->type == JSON_T_NONE);
1137 jc->type = JSON_T_STRING;
1143 assert(jc->type == JSON_T_NONE);
1144 jc->type = JSON_T_NULL;
1149 assert(jc->type == JSON_T_NONE);
1150 jc->type = JSON_T_FALSE;
1155 assert(jc->type == JSON_T_NONE);
1156 jc->type = JSON_T_TRUE;
1163 assert(jc->parse_buffer_count == 0);
1164 assert(jc->type == JSON_T_NONE);
1165 jc->state = jc->before_comment_state;
1170 if (!jc->allow_comments) {
1173 parse_buffer_pop_back_char(jc);
1174 if (!parse_parse_buffer(jc)) {
1177 assert(jc->parse_buffer_count == 0);
1178 assert(jc->type != JSON_T_STRING);
1179 switch (jc->stack[jc->top]) {
1185 jc->before_comment_state = jc->state;
1188 jc->before_comment_state = OK;
1193 jc->before_comment_state = jc->state;
1196 jc->type = JSON_T_NONE;
1202 parse_buffer_clear(jc);
1203 if (jc->callback && !(*jc->callback)(jc->ctx, JSON_T_OBJECT_END, NULL)) {
1206 if (!pop(jc, MODE_KEY)) {
1213 parse_buffer_pop_back_char(jc);
1214 if (!parse_parse_buffer(jc)) {
1217 if (jc->callback && !(*jc->callback)(jc->ctx, JSON_T_OBJECT_END, NULL)) {
1220 if (!pop(jc, MODE_OBJECT)) {
1221 jc->error = JSON_E_UNBALANCED_COLLECTION;
1224 jc->type = JSON_T_NONE;
1229 parse_buffer_pop_back_char(jc);
1230 if (!parse_parse_buffer(jc)) {
1233 if (jc->callback && !(*jc->callback)(jc->ctx, JSON_T_ARRAY_END, NULL)) {
1236 if (!pop(jc, MODE_ARRAY)) {
1237 jc->error = JSON_E_UNBALANCED_COLLECTION;
1241 jc->type = JSON_T_NONE;
1246 parse_buffer_pop_back_char(jc);
1247 if (jc->callback && !(*jc->callback)(jc->ctx, JSON_T_OBJECT_BEGIN, NULL)) {
1250 if (!push(jc, MODE_KEY)) {
1253 assert(jc->type == JSON_T_NONE);
1258 parse_buffer_pop_back_char(jc);
1259 if (jc->callback && !(*jc->callback)(jc->ctx, JSON_T_ARRAY_BEGIN, NULL)) {
1262 if (!push(jc, MODE_ARRAY)) {
1265 assert(jc->type == JSON_T_NONE);
1270 parse_buffer_pop_back_char(jc);
1271 switch (jc->stack[jc->top]) {
1273 assert(jc->type == JSON_T_STRING);
1274 jc->type = JSON_T_NONE;
1279 value.vu.str.value = jc->parse_buffer;
1280 value.vu.str.length = jc->parse_buffer_count;
1281 if (!(*jc->callback)(jc->ctx, JSON_T_KEY, &value)) {
1285 parse_buffer_clear(jc);
1289 assert(jc->type == JSON_T_STRING);
1290 if (!parse_parse_buffer(jc)) {
1293 jc->type = JSON_T_NONE;
1302 parse_buffer_pop_back_char(jc);
1303 if (!parse_parse_buffer(jc)) {
1306 switch (jc->stack[jc->top]) {
1311 if (!pop(jc, MODE_OBJECT) || !push(jc, MODE_KEY)) {
1314 assert(jc->type != JSON_T_STRING);
1315 jc->type = JSON_T_NONE;
1319 assert(jc->type != JSON_T_STRING);
1320 jc->type = JSON_T_NONE;
1332 parse_buffer_pop_back_char(jc);
1333 if (!pop(jc, MODE_KEY) || !push(jc, MODE_OBJECT)) {
1336 assert(jc->type == JSON_T_NONE);
1353 if ((jc->state == OK || jc->state == GO) && pop(jc, MODE_DONE))
1358 jc->error = JSON_E_UNBALANCED_COLLECTION;
1363int JSON_parser_is_legal_white_space_string(
const char* s)
1374 if (c < 0 || c >= 128) {
1378 char_class = ascii_class[c];
1380 if (char_class != C_SPACE && char_class != C_WHITE) {
1397 memset(config, 0,
sizeof(*config));
1399 config->
depth = JSON_PARSER_STACK_SIZE - 1;
1401 config->
free = free;
1413# if _MSC_VER >= 1400
1414# pragma warning( push )
1415# pragma warning(disable:4996)
1416# pragma warning(disable:4244)
1424#define MARKER if(1) printf("MARKER: %s:%d:%s():\t",__FILE__,__LINE__,__func__); if(1) printf
1426static void noop_printf(
char const * fmt, ...) {}
1427#define MARKER if(0) printf
1430#if defined(__cplusplus)
1475#define cson_value_api_empty_m { \
1482static const cson_value_api cson_value_api_empty = cson_value_api_empty_m;
1485typedef unsigned int cson_counter_t;
1533#define cson_value_empty_m { &cson_value_api_empty, NULL, 0 }
1537static const cson_value cson_value_empty = cson_value_empty_m;
1538const cson_parse_opt cson_parse_opt_empty = cson_parse_opt_empty_m;
1541const cson_buffer cson_buffer_empty = cson_buffer_empty_m;
1544static void cson_value_destroy_zero_it(
cson_value * self );
1545static void cson_value_destroy_object(
cson_value * self );
1550static void cson_value_destroy_array(
cson_value * self );
1552static const cson_value_api cson_value_api_null = { CSON_TYPE_NULL, cson_value_destroy_zero_it };
1553static const cson_value_api cson_value_api_undef = { CSON_TYPE_UNDEF, cson_value_destroy_zero_it };
1554static const cson_value_api cson_value_api_bool = { CSON_TYPE_BOOL, cson_value_destroy_zero_it };
1555static const cson_value_api cson_value_api_integer = { CSON_TYPE_INTEGER, cson_value_destroy_zero_it };
1556static const cson_value_api cson_value_api_double = { CSON_TYPE_DOUBLE, cson_value_destroy_zero_it };
1557static const cson_value_api cson_value_api_string = { CSON_TYPE_STRING, cson_value_destroy_zero_it };
1558static const cson_value_api cson_value_api_array = { CSON_TYPE_ARRAY, cson_value_destroy_array };
1559static const cson_value_api cson_value_api_object = { CSON_TYPE_OBJECT, cson_value_destroy_object };
1561static const cson_value cson_value_undef = { &cson_value_api_undef, NULL, 0 };
1562static const cson_value cson_value_null_empty = { &cson_value_api_null, NULL, 0 };
1563static const cson_value cson_value_bool_empty = { &cson_value_api_bool, NULL, 0 };
1564static const cson_value cson_value_integer_empty = { &cson_value_api_integer, NULL, 0 };
1565static const cson_value cson_value_double_empty = { &cson_value_api_double, NULL, 0 };
1566static const cson_value cson_value_string_empty = { &cson_value_api_string, NULL, 0 };
1567static const cson_value cson_value_array_empty = { &cson_value_api_array, NULL, 0 };
1568static const cson_value cson_value_object_empty = { &cson_value_api_object, NULL, 0 };
1580 unsigned int length;
1582#define cson_string_empty_m {0}
1583static const cson_string cson_string_empty = cson_string_empty_m;
1590#define CSON_CAST(T,V) ((T*)((V)->value))
1597#define CSON_VCAST(V) ((cson_value *)(((unsigned char *)(V))-sizeof(cson_value)))
1605#if CSON_VOID_PTR_IS_BIG
1606# define CSON_INT(V) ((cson_int_t*)(&((V)->value)))
1608# define CSON_INT(V) ((cson_int_t*)(V)->value)
1611#define CSON_DBL(V) CSON_CAST(cson_double_t,(V))
1612#define CSON_STR(V) CSON_CAST(cson_string,(V))
1613#define CSON_OBJ(V) CSON_CAST(cson_object,(V))
1614#define CSON_ARRAY(V) CSON_CAST(cson_array,(V))
1620static struct CSON_EMPTY_HOLDER_
1624} CSON_EMPTY_HOLDER = {
1636enum CSON_INTERNAL_VALUES {
1644 CSON_VAL_STR_EMPTY = 6,
1645 CSON_INTERNAL_VALUES_LENGTH
1661{ &cson_value_api_undef, NULL, 0 },
1662{ &cson_value_api_null, NULL, 0 },
1663{ &cson_value_api_bool, &CSON_EMPTY_HOLDER.trueValue, 0 },
1664{ &cson_value_api_bool, NULL, 0 },
1665{ &cson_value_api_integer, NULL, 0 },
1666{ &cson_value_api_double, NULL, 0 },
1667{ &cson_value_api_string, &CSON_EMPTY_HOLDER.stringValue, 0 },
1679static char cson_value_is_builtin(
void const * m )
1681 if((m >= (
void const *)&CSON_EMPTY_HOLDER)
1682 && ( m < (
void const *)(&CSON_EMPTY_HOLDER+1)))
1685 ((m >= (
void const *)&CSON_SPECIAL_VALUES[0])
1686 && ( m < (
void const *)&CSON_SPECIAL_VALUES[CSON_INTERNAL_VALUES_LENGTH]) )
1691char const * cson_rc_string(
int rc)
1693 if(0 == rc)
return "OK";
1694#define CHECK(N) else if(cson_rc.N == rc ) return #N
1702 CHECK(InternalError);
1703 CHECK(UnsupportedError);
1704 CHECK(NotFoundError);
1705 CHECK(UnknownError);
1706 CHECK(Parse_INVALID_CHAR);
1707 CHECK(Parse_INVALID_KEYWORD);
1708 CHECK(Parse_INVALID_ESCAPE_SEQUENCE);
1709 CHECK(Parse_INVALID_UNICODE_SEQUENCE);
1710 CHECK(Parse_INVALID_NUMBER);
1711 CHECK(Parse_NESTING_DEPTH_REACHED);
1712 CHECK(Parse_UNBALANCED_COLLECTION);
1713 CHECK(Parse_EXPECTED_KEY);
1714 CHECK(Parse_EXPECTED_COLON);
1715 else return "UnknownError";
1723#define CSON_LOG_ALLOC 0
1734#if defined(CSON_FOSSIL_MODE)
1735extern void *fossil_malloc(
size_t n);
1736extern void fossil_free(
void *p);
1737extern void *fossil_realloc(
void *p,
size_t n);
1738# define CSON_MALLOC_IMPL fossil_malloc
1739# define CSON_FREE_IMPL fossil_free
1740# define CSON_REALLOC_IMPL fossil_realloc
1743#if !defined CSON_MALLOC_IMPL
1744# define CSON_MALLOC_IMPL malloc
1746#if !defined CSON_FREE_IMPL
1747# define CSON_FREE_IMPL free
1749#if !defined CSON_REALLOC_IMPL
1750# define CSON_REALLOC_IMPL realloc
1757#define CSON_SIMULATE_OOM 0
1758#if CSON_SIMULATE_OOM
1759static unsigned int cson_totalAlloced = 0;
1763static void * cson_malloc(
size_t n,
char const * descr )
1766 fprintf(stderr,
"Allocating %u bytes [%s].\n", (
unsigned int)n, descr);
1768#if CSON_SIMULATE_OOM
1769 cson_totalAlloced += n;
1770 if( cson_totalAlloced > CSON_SIMULATE_OOM )
1775 return CSON_MALLOC_IMPL(n);
1779static void cson_free(
void * p,
char const * descr )
1782 fprintf(stderr,
"Freeing @%p [%s].\n", p, descr);
1784 if( !cson_value_is_builtin(p) )
1786 CSON_FREE_IMPL( p );
1790static void * cson_realloc(
void * hint,
size_t n,
char const * descr )
1793 fprintf(stderr,
"%sllocating %u bytes [%s].\n",
1795 (unsigned int)n, descr);
1797#if CSON_SIMULATE_OOM
1798 cson_totalAlloced += n;
1799 if( cson_totalAlloced > CSON_SIMULATE_OOM )
1806 cson_free(hint, descr);
1811 return CSON_REALLOC_IMPL( hint, n );
1816#undef CSON_LOG_ALLOC
1817#undef CSON_SIMULATE_OOM
1836static void cson_value_clean(
cson_value * val );
1843static void cson_refcount_incr(
cson_value * cv )
1845 assert( NULL != cv );
1846 if( cson_value_is_builtin( cv ) )
1859int cson_value_refcount_set(
cson_value * cv,
unsigned short rc )
1861 if( NULL == cv )
return cson_rc.ArgError;
1870int cson_value_add_reference(
cson_value * cv )
1872 if( NULL == cv )
return cson_rc.ArgError;
1875 return cson_rc.RangeError;
1879 cson_refcount_incr( cv );
1891static cson_counter_t cson_refcount_decr(
cson_value * cv )
1893 if( (NULL == cv) || cson_value_is_builtin(cv) )
return 0;
1896 cson_value_clean(cv);
1897 cson_free(cv,
"cson_value::refcount=0");
1903unsigned int cson_string_length_bytes(
cson_string const * str )
1905 return str ? str->length : 0;
1924 if( !v || (&CSON_EMPTY_HOLDER.stringValue == v) )
return NULL;
1925 else return (
char *)((
unsigned char *)( v+1 ));
1927 static char empty[2] = {0,0};
1928 return ( NULL == v )
1931 ? (
char *) (((
unsigned char *)v) +
sizeof(
cson_string))
1940char const * cson_string_cstr(
cson_string const *v)
1946 if( ! v )
return NULL;
1947 else if( v == &CSON_EMPTY_HOLDER.stringValue )
return "";
1949 assert((0 < v->length) &&
"How do we have a non-singleton empty string?");
1950 return (
char const *)((
unsigned char const *)(v+1));
1956 ? (
char const *) ((
unsigned char const *)(v+1))
1967static char * cson_strdup(
char const * src,
size_t n )
1969 char * rc = (
char *)cson_malloc(n+1,
"cson_strdup");
1970 if( ! rc )
return NULL;
1971 memset( rc, 0, n+1 );
1973 return strncpy( rc, src, n );
1977int cson_string_cmp_cstr_n(
cson_string const * str,
char const * other,
unsigned int otherLen )
1979 if( ! other && !str )
return 0;
1980 else if( other && !str )
return 1;
1981 else if( str && !other )
return -1;
1982 else if( !otherLen )
return str->length ? 1 : 0;
1983 else if( !str->length )
return otherLen ? -1 : 0;
1986 unsigned const int max = (otherLen > str->length) ? otherLen : str->length;
1987 int const rc = strncmp( cson_string_cstr(str), other, max );
1988 return ( (0 == rc) && (otherLen != str->length) )
1989 ? (str->length < otherLen) ? -1 : 1
1994int cson_string_cmp_cstr(
cson_string const * lhs,
char const * rhs )
1996 return cson_string_cmp_cstr_n( lhs, rhs, (rhs&&*rhs) ? (
unsigned int)strlen(rhs) : 0 );
2000 return cson_string_cmp_cstr_n( lhs, cson_string_cstr(rhs), rhs ? rhs->length : 0 );
2008void cson_value_destroy_zero_it(
cson_value * self )
2012 *self = cson_value_undef;
2027#define cson_kvp_empty_m {NULL,NULL}
2028static const cson_kvp cson_kvp_empty = cson_kvp_empty_m;
2048#define CSON_OBJECT_PROPS_SORT 0
2062#define CSON_OBJECT_PROPS_SORT_USE_LENGTH 0
2064#if CSON_OBJECT_PROPS_SORT
2071static int cson_kvp_cmp(
void const * lhs,
void const * rhs )
2075 cson_string const * l = cson_string_value(lk->key);
2076 cson_string const * r = cson_string_value(rk->key);
2077#if CSON_OBJECT_PROPS_SORT_USE_LENGTH
2078 if( l->length < r->length )
return -1;
2079 else if( l->length > r->length )
return 1;
2080 else return strcmp( cson_string_cstr( l ), cson_string_cstr( r ) );
2082 return strcmp( cson_string_cstr( l ),
2083 cson_string_cstr( r ) );
2089#if CSON_OBJECT_PROPS_SORT
2090#error "Need to rework this for cson_string-to-cson_value refactoring"
2096static int cson_kvp_cmp_vs_cstr(
void const * lhs,
void const * rhs )
2098 char const * lk = (
char const *)lhs;
2102#if CSON_OBJECT_PROPS_SORT_USE_LENGTH
2103 unsigned int llen = strlen(lk);
2104 if( llen < rk->
key->length )
return -1;
2105 else if( llen > rk->key->length )
return 1;
2106 else return strcmp( lk, cson_string_cstr( rk->key ) );
2108 return strcmp( lk, cson_string_cstr( rk->key ) );
2118 unsigned int alloced;
2121#define cson_kvp_list_empty_m {NULL,0,0}
2122static const cson_kvp_list cson_kvp_list_empty = cson_kvp_list_empty_m;
2129#define cson_object_empty_m { cson_kvp_list_empty_m }
2130static const cson_object cson_object_empty = cson_object_empty_m;
2136 unsigned int alloced;
2139#define cson_value_list_empty_m {NULL,0,0}
2140static const cson_value_list cson_value_list_empty = cson_value_list_empty_m;
2147#define cson_array_empty_m { cson_value_list_empty_m }
2148static const cson_array cson_array_empty = cson_array_empty_m;
2159 unsigned int totalKeyCount;
2160 unsigned int totalValueCount;
2178static unsigned int cson_value_list_reserve(
cson_value_list * self,
unsigned int n );
2179static unsigned int cson_kvp_list_reserve(
cson_kvp_list * self,
unsigned int n );
2187 int (*visitor)(
cson_kvp * obj,
void * visitorState ),
2188 void * visitorState );
2190 int (*visitor)(
cson_value * obj,
void * visitorState ),
2191 void * visitorState );
2196# define LIST_T cson_value_list
2197# define VALUE_T cson_value *
2198# define VALUE_T_IS_PTR 1
2199# define LIST_T cson_kvp_list
2200# define VALUE_T cson_kvp *
2201# define VALUE_T_IS_PTR 1
2229static cson_value * cson_value_new(cson_type_id t,
size_t extra)
2231 static const size_t vsz =
sizeof(
cson_value);
2232 const size_t sz = vsz + extra;
2236 char const * reason =
"cson_value_new";
2239 case CSON_TYPE_ARRAY:
2240 assert( 0 == extra );
2241 def = cson_value_array_empty;
2243 reason =
"cson_value:array";
2245 case CSON_TYPE_DOUBLE:
2246 assert( 0 == extra );
2247 def = cson_value_double_empty;
2248 tx =
sizeof(cson_double_t);
2249 reason =
"cson_value:double";
2251 case CSON_TYPE_INTEGER:
2252 assert( 0 == extra );
2253 def = cson_value_integer_empty;
2254#if !CSON_VOID_PTR_IS_BIG
2255 tx =
sizeof(cson_int_t);
2257 reason =
"cson_value:int";
2259 case CSON_TYPE_STRING:
2260 assert( 0 != extra );
2261 def = cson_value_string_empty;
2263 reason =
"cson_value:string";
2265 case CSON_TYPE_OBJECT:
2266 assert( 0 == extra );
2267 def = cson_value_object_empty;
2269 reason =
"cson_value:object";
2272 assert(0 &&
"Unhandled type in cson_value_new()!");
2275 assert( def.
api->
typeID != CSON_TYPE_UNDEF );
2276 v = (
cson_value *)cson_malloc(sz+tx, reason);
2280 memset(v+1, 0, tx + extra);
2281 v->
value = (
void *)(v+1);
2289 cson_refcount_decr( v );
2294static char cson_value_is_a(
cson_value const * v, cson_type_id is )
2296 return (v && v->
api && (v->
api->
typeID == is)) ? 1 : 0;
2300cson_type_id cson_value_type_id(
cson_value const * v )
2302 return (v && v->
api) ? v->
api->
typeID : CSON_TYPE_UNDEF;
2305char cson_value_is_undef(
cson_value const * v )
2307 return ( !v || !v->
api || (v->
api==&cson_value_api_undef))
2310#define ISA(T,TID) char cson_value_is_##T( cson_value const * v ) { \
2312 return (v && (v->api == &cson_value_api_##T)) ? 1 : 0; \
2313 } static const char bogusPlaceHolderForEmacsIndention##TID = CSON_TYPE_##TID
2316ISA(integer,INTEGER);
2322char cson_value_is_number(
cson_value const * v )
2324 return cson_value_is_integer(v) || cson_value_is_double(v);
2332 if( ! cson_value_is_builtin( val ) )
2334 cson_counter_t
const rc = val->
refcount;
2336 *val = cson_value_undef;
2344 cson_value * v = cson_value_new(CSON_TYPE_ARRAY,0);
2349 *ar = cson_array_empty;
2356 cson_value * v = cson_value_new(CSON_TYPE_OBJECT,0);
2360 assert(NULL != obj);
2361 *obj = cson_object_empty;
2368 return cson_value_object_alloc();
2374 return cson_value_get_object( cson_value_new_object() );
2379 return cson_value_array_alloc();
2385 return cson_value_get_array( cson_value_new_array() );
2392static void cson_kvp_clean(
cson_kvp * kvp )
2398 cson_value_free(kvp->key);
2403 cson_value_free( kvp->value );
2411 return kvp ? cson_value_get_string(kvp->key) : NULL;
2415 return kvp ? kvp->value : NULL;
2422static void cson_kvp_free(
cson_kvp * kvp )
2426 cson_kvp_clean(kvp);
2427 cson_free(kvp,
"cson_kvp");
2438static void cson_value_destroy_object(
cson_value * self )
2440 if(self && self->
value) {
2442 assert( self->
value == obj );
2443 cson_kvp_list_clean( &obj->kvp, cson_kvp_free );
2444 *self = cson_value_undef;
2458static void cson_array_clean(
cson_array * ar,
char properlyCleanValues )
2464 for( ; i < ar->list.count; ++i )
2466 val = ar->list.list[i];
2469 ar->list.list[i] = NULL;
2470 if( properlyCleanValues )
2472 cson_value_free( val );
2476 cson_value_list_reserve(&ar->list,0);
2477 ar->list = cson_value_list_empty
2492static void cson_value_destroy_array(
cson_value * self )
2494 cson_array * ar = cson_value_get_array(self);
2496 assert( self->
value == ar );
2497 cson_array_clean( ar, 1 );
2498 *self = cson_value_undef;
2502int cson_buffer_fill_from(
cson_buffer * dest, cson_data_source_f src,
void * state )
2505 enum { BufSize = 1024 * 4 };
2508 unsigned int rlen = 0;
2509 if( ! dest || ! src )
return cson_rc.ArgError;
2514 rc = src( state, rbuf, &rlen );
2519 rc = cson_buffer_reserve( dest, (cson_size_t)(total + 1));
2520 if( 0 != rc )
break;
2522 memcpy( dest->
mem + dest->
used, rbuf, rlen );
2524 if( rlen < BufSize )
break;
2526 if( !rc && dest->
used )
2534int cson_data_source_FILE(
void * state,
void * dest,
unsigned int * n )
2536 FILE * f = (FILE*) state;
2537 if( ! state || ! n || !dest )
return cson_rc.ArgError;
2538 else if( !*n )
return cson_rc.RangeError;
2539 *n = (
unsigned int)fread( dest, 1, *n, f );
2542 return feof(f) ? 0 : cson_rc.IOError;
2547int cson_parse_FILE(
cson_value ** tgt, FILE * src,
2550 return cson_parse( tgt, cson_data_source_FILE, src, opt, err );
2554int cson_value_fetch_bool(
cson_value const * val,
char * v )
2560 if( ! val || !val->
api )
return cson_rc.ArgError;
2567 case CSON_TYPE_ARRAY:
2568 case CSON_TYPE_OBJECT:
2571 case CSON_TYPE_STRING: {
2572 char const * str = cson_string_cstr(cson_value_get_string(val));
2573 b = (str && *str) ? 1 : 0;
2576 case CSON_TYPE_UNDEF:
2577 case CSON_TYPE_NULL:
2579 case CSON_TYPE_BOOL:
2580 b = (NULL==val->
value) ? 0 : 1;
2582 case CSON_TYPE_INTEGER: {
2584 cson_value_fetch_integer( val, &i );
2588 case CSON_TYPE_DOUBLE: {
2589 cson_double_t d = 0.0;
2590 cson_value_fetch_double( val, &d );
2591 b = (0.0==d) ? 0 : 1;
2595 rc = cson_rc.TypeError;
2603char cson_value_get_bool(
cson_value const * val )
2606 cson_value_fetch_bool( val, &i );
2610int cson_value_fetch_integer(
cson_value const * val, cson_int_t * v )
2612 if( ! val || !val->
api )
return cson_rc.ArgError;
2619 case CSON_TYPE_UNDEF:
2620 case CSON_TYPE_NULL:
2623 case CSON_TYPE_BOOL: {
2625 cson_value_fetch_bool( val, &b );
2629 case CSON_TYPE_INTEGER: {
2630 cson_int_t
const * x = CSON_INT(val);
2633 assert( val == &CSON_SPECIAL_VALUES[CSON_VAL_INT_0] );
2638 case CSON_TYPE_DOUBLE: {
2639 cson_double_t d = 0.0;
2640 cson_value_fetch_double( val, &d );
2644 case CSON_TYPE_STRING:
2645 case CSON_TYPE_ARRAY:
2646 case CSON_TYPE_OBJECT:
2648 rc = cson_rc.TypeError;
2651 if(!rc && v) *v = i;
2656cson_int_t cson_value_get_integer(
cson_value const * val )
2659 cson_value_fetch_integer( val, &i );
2663int cson_value_fetch_double(
cson_value const * val, cson_double_t * v )
2665 if( ! val || !val->
api )
return cson_rc.ArgError;
2668 cson_double_t d = 0.0;
2672 case CSON_TYPE_UNDEF:
2673 case CSON_TYPE_NULL:
2676 case CSON_TYPE_BOOL: {
2678 cson_value_fetch_bool( val, &b );
2682 case CSON_TYPE_INTEGER: {
2684 cson_value_fetch_integer( val, &i );
2688 case CSON_TYPE_DOUBLE: {
2689 cson_double_t
const* dv = CSON_DBL(val);
2694 rc = cson_rc.TypeError;
2702cson_double_t cson_value_get_double(
cson_value const * val )
2704 cson_double_t i = 0.0;
2705 cson_value_fetch_double( val, &i );
2711 if( ! val || ! dest )
return cson_rc.ArgError;
2712 else if( ! cson_value_is_string(val) )
return cson_rc.TypeError;
2715 if( dest ) *dest = CSON_STR(val);
2723 cson_value_fetch_string( val, &rc );
2727char const * cson_value_get_cstr(
cson_value const * val )
2729 return cson_string_cstr( cson_value_get_string(val) );
2734 if( ! val )
return cson_rc.ArgError;
2735 else if( ! cson_value_is_object(val) )
return cson_rc.TypeError;
2738 if(obj) *obj = CSON_OBJ(val);
2745 cson_value_fetch_object( v, &obj );
2751 if( ! val )
return cson_rc.ArgError;
2752 else if( !cson_value_is_array(val) )
return cson_rc.TypeError;
2755 if(ar) *ar = CSON_ARRAY(val);
2763 cson_value_fetch_array( v, &ar );
2772 *kvp = cson_kvp_empty;
2781 if( !ar || !v )
return cson_rc.ArgError;
2782 else if( (ar->list.count+1) < ar->list.count )
return cson_rc.RangeError;
2785 if( !ar->list.alloced || (ar->list.count == ar->list.alloced-1))
2787 unsigned int const n = ar->list.count ? (ar->list.count*2) : 7;
2788 if( n > cson_value_list_reserve( &ar->list, n ) )
2790 return cson_rc.AllocError;
2793 return cson_array_set( ar, ar->list.count, v );
2817 if( !ar )
return NULL;
2818 else if( ! ar->list.count )
return NULL;
2821 unsigned int const ndx = --ar->list.count;
2823 ar->list.list[ndx] = NULL;
2826 cson_value_free( v );
2836 return v ? &CSON_SPECIAL_VALUES[CSON_VAL_TRUE] : &CSON_SPECIAL_VALUES[CSON_VAL_FALSE];
2841 return &CSON_SPECIAL_VALUES[CSON_VAL_TRUE];
2845 return &CSON_SPECIAL_VALUES[CSON_VAL_FALSE];
2850 return &CSON_SPECIAL_VALUES[CSON_VAL_NULL];
2855 return cson_value_new_integer(v);
2858cson_value * cson_value_new_integer( cson_int_t v )
2860 if( 0 == v )
return &CSON_SPECIAL_VALUES[CSON_VAL_INT_0];
2863 cson_value * c = cson_value_new(CSON_TYPE_INTEGER,0);
2864#if !defined(NDEBUG) && CSON_VOID_PTR_IS_BIG
2865 assert(
sizeof(cson_int_t) <=
sizeof(
void *) );
2875cson_value * cson_new_double( cson_double_t v )
2877 return cson_value_new_double(v);
2880cson_value * cson_value_new_double( cson_double_t v )
2882 if( 0.0 == v )
return &CSON_SPECIAL_VALUES[CSON_VAL_DBL_0];
2885 cson_value * c = cson_value_new(CSON_TYPE_DOUBLE,0);
2894cson_string * cson_new_string(
char const * str,
unsigned int len)
2896 if( !str || !*str || !len )
return &CSON_EMPTY_HOLDER.stringValue;
2899 cson_value * c = cson_value_new(CSON_TYPE_STRING, len + 1);
2905 *s = cson_string_empty;
2906 assert( NULL != s );
2908 dest = cson_string_str(s);
2909 assert( NULL != dest );
2910 memcpy( dest, str, len );
2917cson_value * cson_value_new_string(
char const * str,
unsigned int len )
2919 return cson_string_value( cson_new_string(str, len) );
2924 if( !ar)
return cson_rc.ArgError;
2925 if( pos >= ar->list.count )
return cson_rc.RangeError;
2928 if(v) *v = ar->list.list[pos];
2936 cson_array_value_fetch(ar, pos, &v);
2940int cson_array_length_fetch(
cson_array const * ar,
unsigned int * v )
2942 if( ! ar || !v )
return cson_rc.ArgError;
2945 if(v) *v = ar->list.count;
2950unsigned int cson_array_length_get(
cson_array const * ar )
2953 cson_array_length_fetch(ar, &i);
2957int cson_array_reserve(
cson_array * ar,
unsigned int size )
2959 if( ! ar )
return cson_rc.ArgError;
2960 else if( size <= ar->list.alloced )
2969 return (ar->list.alloced > cson_value_list_reserve( &ar->list, size ))
2970 ? cson_rc.AllocError
2978 if( !ar || !v )
return cson_rc.ArgError;
2979 else if( (ndx+1) < ndx)
return cson_rc.RangeError;
2982 unsigned const int len = cson_value_list_reserve( &ar->list, ndx+1 );
2983 if( len <= ndx )
return cson_rc.AllocError;
2989 if(old == v)
return 0;
2990 else cson_value_free(old);
2992 cson_refcount_incr( v );
2993 ar->list.list[ndx] = v;
2994 if( ndx >= ar->list.count )
2996 ar->list.count = ndx+1;
3011static cson_kvp * cson_object_search_impl(
cson_object const * obj,
char const *
key,
unsigned int * ndx )
3013 if( obj &&
key && *
key && obj->kvp.count)
3015#if CSON_OBJECT_PROPS_SORT
3017 bsearch(
key, obj->kvp.list,
3019 cson_kvp_cmp_vs_cstr );
3024 *ndx = (((
unsigned char const *)s - ((
unsigned char const *)obj->kvp.list))
3027 *ndx = s - obj->kvp.list;
3030 return s ? *s : NULL;
3035 const unsigned int klen = (
unsigned int)strlen(
key);
3036 for( ; i < li->count; ++i )
3040 assert( kvp && kvp->key );
3041 sKey = cson_value_get_string(kvp->key);
3043 if( sKey->length != klen )
continue;
3044 else if(0==strcmp(
key,cson_string_cstr(sKey)))
3057 cson_kvp * kvp = cson_object_search_impl( obj,
key, NULL );
3058 return kvp ? kvp->value : NULL;
3063 cson_kvp * kvp = cson_object_search_impl( obj, cson_string_cstr(
key), NULL );
3064 return kvp ? kvp->value : NULL;
3068#if CSON_OBJECT_PROPS_SORT
3069static void cson_object_sort_props(
cson_object * obj )
3071 assert( NULL != obj );
3072 if( obj->kvp.count )
3074 qsort( obj->kvp.list, obj->kvp.count,
sizeof(
cson_kvp*),
3083 if( ! obj || !
key || !*
key )
return cson_rc.ArgError;
3086 unsigned int ndx = 0;
3087 cson_kvp * kvp = cson_object_search_impl( obj,
key, &ndx );
3090 return cson_rc.NotFoundError;
3092 assert( obj->kvp.count > 0 );
3093 assert( obj->kvp.list[ndx] == kvp );
3094 cson_kvp_free( kvp );
3095 obj->kvp.list[ndx] = NULL;
3097 unsigned int i = ndx;
3098 for( ; i < obj->kvp.count; ++i )
3101 (i < (obj->kvp.alloced-1))
3102 ? obj->kvp.list[i+1]
3106 obj->kvp.list[--obj->kvp.count] = NULL;
3107#if CSON_OBJECT_PROPS_SORT
3108 cson_object_sort_props( obj );
3116 if( !obj || !
key )
return cson_rc.ArgError;
3117 else if( NULL == v )
return cson_object_unset( obj, cson_string_cstr(
key) );
3123 vKey = cson_string_value(
key);
3124 assert(vKey && (
key==CSON_STR(vKey)));
3125 if( vKey == CSON_VCAST(obj) ){
3126 return cson_rc.ArgError;
3128 cKey = cson_string_cstr(
key);
3129 kvp = cson_object_search_impl( obj, cKey, NULL );
3132 if( kvp->key != vKey ){
3133 cson_value_free( kvp->key );
3134 cson_refcount_incr(vKey);
3137 if(kvp->value != v){
3138 cson_value_free( kvp->value );
3139 cson_refcount_incr( v );
3144 if( !obj->kvp.alloced || (obj->kvp.count == obj->kvp.alloced-1))
3146 unsigned int const n = obj->kvp.count ? (obj->kvp.count*2) : 6;
3147 if( n > cson_kvp_list_reserve( &obj->kvp, n ) )
3149 return cson_rc.AllocError;
3154 kvp = cson_kvp_alloc();
3157 return cson_rc.AllocError;
3159 rc = cson_kvp_list_append( &obj->kvp, kvp );
3166 cson_refcount_incr(vKey);
3167 cson_refcount_incr(v);
3170#if CSON_OBJECT_PROPS_SORT
3171 cson_object_sort_props( obj );
3181 if( ! obj || !
key || !*
key )
return cson_rc.ArgError;
3182 else if( NULL == v )
3184 return cson_object_unset( obj,
key );
3189 if(!cs)
return cson_rc.AllocError;
3192 int const rc = cson_object_set_s(obj, cs, v);
3193 if(rc) cson_value_free(cson_string_value(cs));
3201 if( ! obj || !
key || !*
key )
return NULL;
3208 unsigned int ndx = 0;
3209 cson_kvp * kvp = cson_object_search_impl( obj,
key, &ndx );
3215 assert( obj->kvp.count > 0 );
3216 assert( obj->kvp.list[ndx] == kvp );
3220 cson_kvp_free( kvp );
3223 obj->kvp.list[ndx] = NULL;
3225 unsigned int i = ndx;
3226 for( ; i < obj->kvp.count; ++i )
3229 (i < (obj->kvp.alloced-1))
3230 ? obj->kvp.list[i+1]
3234 obj->kvp.list[--obj->kvp.count] = NULL;
3235#if CSON_OBJECT_PROPS_SORT
3236 cson_object_sort_props( obj );
3258 if( p->ckey && cson_value_is_object(p->node) )
3261 cson_object * obj = cson_value_get_object(p->node);
3263 assert( obj && (p->node->
value == obj) );
3269 if( !obj->kvp.alloced || (obj->kvp.count == obj->kvp.alloced-1))
3271 if( obj->kvp.alloced > cson_kvp_list_reserve( &obj->kvp, obj->kvp.count ? (obj->kvp.count*2) : 5 ) )
3273 cson_value_free(val);
3274 return cson_rc.AllocError;
3277 kvp = cson_kvp_alloc();
3280 cson_value_free(val);
3281 return cson_rc.AllocError;
3283 kvp->key = cson_string_value(p->ckey);
3285 cson_refcount_incr(kvp->key);
3288 cson_refcount_incr( val );
3289 rc = cson_kvp_list_append( &obj->kvp, kvp );
3292 cson_kvp_free( kvp );
3296 ++p->totalValueCount;
3302 if(val) cson_value_free(val);
3303 return p->errNo = cson_rc.InternalError;
3322 assert( cson_value_is_object( p->node ) );
3323 return cson_parser_set_key( p, val );
3325 else if( cson_value_is_array( p->node ) )
3327 cson_array * ar = cson_value_get_array( p->node );
3329 assert( ar && (ar == p->node->
value) );
3330 rc = cson_array_append( ar, val );
3333 cson_value_free(val);
3337 ++p->totalValueCount;
3343 assert( 0 &&
"Internal error in cson_parser code" );
3344 return p->errNo = cson_rc.InternalError;
3352static int cson_parse_callback(
void * cx,
int type,
JSON_value const * value )
3356#define ALLOC_V(T,V) cson_value * v = cson_value_new_##T(V); if( ! v ) { rc = cson_rc.AllocError; break; }
3358 case JSON_T_ARRAY_BEGIN:
3359 case JSON_T_OBJECT_BEGIN: {
3360 cson_value * obja = (JSON_T_ARRAY_BEGIN == type)
3361 ? cson_value_new_array()
3362 : cson_value_new_object();
3365 p->errNo = cson_rc.AllocError;
3368 if( 0 != rc )
break;
3371 p->root = p->node = obja;
3372 rc = cson_array_append( &p->stack, obja );
3375 cson_value_free( p->root );
3380 cson_refcount_incr( p->root )
3383 ++p->totalValueCount;
3388 rc = cson_array_append( &p->stack, obja );
3389 if(rc) cson_value_free( obja );
3392 rc = cson_parser_push_value( p, obja );
3393 if( 0 == rc ) p->node = obja;
3398 case JSON_T_ARRAY_END:
3399 case JSON_T_OBJECT_END: {
3400 if( 0 == p->stack.list.count )
3402 rc = cson_rc.RangeError;
3405#if CSON_OBJECT_PROPS_SORT
3406 if( cson_value_is_object(p->node) )
3412 cson_object * obj = cson_value_get_object(p->node);
3413 assert( NULL != obj );
3414 cson_object_sort_props( obj );
3426 --p->stack.list.count;
3427 assert( p->node == p->stack.list.list[p->stack.list.count] );
3428 cson_refcount_decr( p->node )
3435 p->stack.list.list[p->stack.list.count] = NULL;
3436 if( p->stack.list.count )
3438 p->node = p->stack.list.list[p->stack.list.count-1];
3448 cson_array_pop_back( &p->stack, 1 );
3449 if( p->stack.list.count )
3451 p->node = p->stack.list.list[p->stack.list.count-1];
3457 assert( p->node && (1==p->node->
refcount) );
3461 case JSON_T_INTEGER: {
3462 ALLOC_V(integer, value->vu.integer_value );
3463 rc = cson_parser_push_value( p, v );
3466 case JSON_T_FLOAT: {
3467 ALLOC_V(
double, value->vu.float_value );
3468 rc = cson_parser_push_value( p, v );
3472 rc = cson_parser_push_value( p, cson_value_null() );
3476 rc = cson_parser_push_value( p, cson_value_true() );
3479 case JSON_T_FALSE: {
3480 rc = cson_parser_push_value( p, cson_value_false() );
3485 p->ckey = cson_new_string( value->vu.str.value, (
unsigned int)value->vu.str.length );
3488 rc = cson_rc.AllocError;
3494 case JSON_T_STRING: {
3495 cson_value * v = cson_value_new_string( value->vu.str.value, (
unsigned int)value->vu.str.length );
3497 ? cson_rc.AllocError
3498 : cson_parser_push_value( p, v );
3503 rc = cson_rc.InternalError;
3507 return ((p->errNo = rc)) ? 0 : 1;
3514static int cson_json_err_to_rc( JSON_error jrc )
3518 case JSON_E_NONE:
return 0;
3519 case JSON_E_INVALID_CHAR:
return cson_rc.Parse_INVALID_CHAR;
3520 case JSON_E_INVALID_KEYWORD:
return cson_rc.Parse_INVALID_KEYWORD;
3521 case JSON_E_INVALID_ESCAPE_SEQUENCE:
return cson_rc.Parse_INVALID_ESCAPE_SEQUENCE;
3522 case JSON_E_INVALID_UNICODE_SEQUENCE:
return cson_rc.Parse_INVALID_UNICODE_SEQUENCE;
3523 case JSON_E_INVALID_NUMBER:
return cson_rc.Parse_INVALID_NUMBER;
3524 case JSON_E_NESTING_DEPTH_REACHED:
return cson_rc.Parse_NESTING_DEPTH_REACHED;
3525 case JSON_E_UNBALANCED_COLLECTION:
return cson_rc.Parse_UNBALANCED_COLLECTION;
3526 case JSON_E_EXPECTED_KEY:
return cson_rc.Parse_EXPECTED_KEY;
3527 case JSON_E_EXPECTED_COLON:
return cson_rc.Parse_EXPECTED_COLON;
3528 case JSON_E_OUT_OF_MEMORY:
return cson_rc.AllocError;
3530 return cson_rc.InternalError;
3550 if( ! p )
return cson_rc.ArgError;
3555 delete_JSON_parser(p->p);
3559 cson_value_free(cson_string_value(p->ckey));
3561 cson_array_clean( &p->stack, 1 );
3564 cson_value_free( p->root );
3566 *p = cson_parser_empty;
3572int cson_parse(
cson_value ** tgt, cson_data_source_f src,
void * state,
3575 unsigned char ch[2] = {0,0};
3578 unsigned int len = 1;
3581 if( ! tgt || ! src )
return cson_rc.ArgError;
3585 init_JSON_config( &jopt );
3590 jopt.
callback = cson_parse_callback;
3591 p.p = new_JSON_parser(&jopt);
3594 return cson_rc.AllocError;
3601 rc = src( state, ch, &len );
3602 if( 0 != rc )
break;
3603 else if( !len )
break;
3610 if( ! JSON_parser_char(p.p, ch[0]) )
3612 rc = cson_json_err_to_rc( JSON_parser_get_last_error(p.p) );
3613 if(0==rc) rc = p.errNo;
3614 if(0==rc) rc = cson_rc.InternalError;
3618 if(
'\n' != ch[0]) ++info.
col;
3628 cson_parser_clean(&p);
3631 if( ! JSON_parser_done(p.p) )
3633 rc = cson_json_err_to_rc( JSON_parser_get_last_error(p.p) );
3634 cson_parser_clean(&p);
3635 if(0==rc) rc = p.errNo;
3636 if(0==rc) rc = cson_rc.InternalError;
3642 cson_parser_clean(&p);
3645 assert( (1 == root->
refcount) &&
"Detected memory mismanagement in the parser." );
3658 rc = cson_rc.UnknownError;
3677static const unsigned char cson_utfTrans1[] = {
3678 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
3679 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
3680 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
3681 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
3682 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
3683 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
3684 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
3685 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x00, 0x00
3716#define READ_UTF8(zIn, zTerm, c) \
3719 c = cson_utfTrans1[c-0xc0]; \
3720 while( zIn!=zTerm && (*zIn & 0xc0)==0x80 ){ \
3721 c = (c<<6) + (0x3f & *(zIn++)); \
3724 || (c&0xFFFFF800)==0xD800 \
3725 || (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; } \
3727static int cson_utf8Read(
3728 const unsigned char *z,
3729 const unsigned char *zTerm,
3730 const unsigned char **pzNext
3733 READ_UTF8(z, zTerm, c);
3740# if _MSC_VER >= 1400
3741# pragma warning( pop )
3745unsigned int cson_string_length_utf8(
cson_string const * str )
3747 if( ! str )
return 0;
3750 char unsigned const * pos = (
char unsigned const *)cson_string_cstr(str);
3751 char unsigned const * end = pos + str->length;
3752 unsigned int rc = 0;
3753 for( ; (pos < end) && cson_utf8Read(pos, end, &pos);
3773static int cson_str_to_json(
char const * str,
unsigned int len,
3774 char escapeFwdSlash,
3775 cson_data_dest_f f,
void * state )
3777 if( NULL == f )
return cson_rc.ArgError;
3778 else if( !str || !*str || (0 == len) )
3780 return f( state,
"\"\"", 2 );
3784 unsigned char const * pos = (
unsigned char const *)str;
3785 unsigned char const * end = (
unsigned char const *)(str ? (str + len) : NULL);
3786 unsigned char const * next = NULL;
3788 unsigned char clen = 0;
3789 char escChar[3] = {
'\\',0,0};
3793 rc = f(state,
"\"", 1 );
3794 for( ; (pos < end) && (0 == rc); pos += clen )
3796 ch = cson_utf8Read(pos, end, &next);
3797 if( 0 == ch )
break;
3798 assert( next > pos );
3799 clen = (char)(
int)(next - pos);
3803#if defined(CSON_FOSSIL_MODE)
3823 assert( (*pos == ch) &&
"Invalid UTF8" );
3827 case '\t': escChar[1] =
't';
break;
3828 case '\r': escChar[1] =
'r';
break;
3829 case '\n': escChar[1] =
'n';
break;
3830 case '\f': escChar[1] =
'f';
break;
3831 case '\b': escChar[1] =
'b';
break;
3860 if( escapeFwdSlash ) escChar[1] =
'/';
3862 case '\\': escChar[1] =
'\\';
break;
3863 case '"': escChar[1] =
'"';
break;
3868 rc = f(state, escChar, 2);
3872 rc = f(state, (
char const *)pos, clen);
3878#if defined(CSON_FOSSIL_MODE)
3881 memset(ubuf,0,UBLen);
3882 rc = sprintf(ubuf,
"\\u%04x",ch);
3885 rc = cson_rc.RangeError;
3888 rc = f( state, ubuf, 6 );
3894 rc = f(state,
"\"", 1 );
3902 if( ! obj || !iter )
return cson_rc.ArgError;
3913 if( ! iter || !iter->obj )
return NULL;
3914 else if( iter->pos >= iter->obj->kvp.count )
return NULL;
3917 cson_kvp * rc = iter->obj->kvp.list[iter->pos++];
3918 while( (NULL==rc) && (iter->pos < iter->obj->kvp.count))
3920 rc = iter->obj->kvp.list[iter->pos++];
3926static int cson_output_null( cson_data_dest_f f,
void * state )
3928 if( !f )
return cson_rc.ArgError;
3931 return f(state,
"null", 4);
3935static int cson_output_bool(
cson_value const * src, cson_data_dest_f f,
void * state )
3937 if( !f )
return cson_rc.ArgError;
3940 char const v = cson_value_get_bool(src);
3941 return f(state, v ?
"true" :
"false", v ? 4 : 5);
3945static int cson_output_integer(
cson_value const * src, cson_data_dest_f f,
void * state )
3947 if( !f )
return cson_rc.ArgError;
3948 else if( !cson_value_is_integer(src) )
return cson_rc.TypeError;
3951 enum { BufLen = 100 };
3954 memset( b, 0, BufLen );
3955 rc = sprintf( b,
"%"CSON_INT_T_PFMT, cson_value_get_integer(src) )
3959 ? cson_rc.RangeError
3960 : f( state, b, (
unsigned int)rc )
3965static int cson_output_double(
cson_value const * src, cson_data_dest_f f,
void * state )
3967 if( !f )
return cson_rc.ArgError;
3968 else if( !cson_value_is_double(src) )
return cson_rc.TypeError;
3977 memset( b, 0, BufLen );
3978 rc = sprintf( b,
"%"CSON_DOUBLE_T_PFMT, cson_value_get_double(src) )
3981 if( rc<=0 )
return cson_rc.RangeError;
3984 unsigned int urc = (
unsigned int)rc;
3985 char * pos = b + urc - 1;
3986 for( ; (
'0' == *pos) && urc && (*(pos-1) !=
'.'); --pos, --urc )
3990 assert(urc && *pos);
3991 return f( state, b, urc );
3995 unsigned int urc = (
unsigned int)rc;
3996 return f( state, b, urc );
4002static int cson_output_string(
cson_value const * src,
char escapeFwdSlash, cson_data_dest_f f,
void * state )
4004 if( !f )
return cson_rc.ArgError;
4005 else if( ! cson_value_is_string(src) )
return cson_rc.TypeError;
4008 cson_string const * str = cson_value_get_string(src);
4009 assert( NULL != str );
4010 return cson_str_to_json(cson_string_cstr(str), str->length, escapeFwdSlash, f, state);
4026static int cson_output_indent( cson_data_dest_f f,
void * state,
4027 unsigned char blanks,
unsigned int depth )
4029 if( 0 == blanks )
return 0;
4036 enum { BufLen = 200 };
4041 char const ch = (1==blanks) ?
'\t' :
' ';
4042 int rc = f(state,
"\n", 1 );
4043 for( i = 0; (i < depth) && (0 == rc); ++i )
4045 for( x = 0; (x < blanks) && (0 == rc); ++x )
4047 rc = f(state, &ch, 1);
4054static int cson_output_array(
cson_value const * src, cson_data_dest_f f,
void * state,
4056static int cson_output_object(
cson_value const * src, cson_data_dest_f f,
void * state,
4064static int cson_output_impl(
cson_value const * src, cson_data_dest_f f,
void * state,
4067 if( ! src || !f || !src->
api )
return cson_rc.ArgError;
4074 case CSON_TYPE_UNDEF:
4075 case CSON_TYPE_NULL:
4076 rc = cson_output_null(f, state);
4078 case CSON_TYPE_BOOL:
4079 rc = cson_output_bool(src, f, state);
4081 case CSON_TYPE_INTEGER:
4082 rc = cson_output_integer(src, f, state);
4084 case CSON_TYPE_DOUBLE:
4085 rc = cson_output_double(src, f, state);
4087 case CSON_TYPE_STRING:
4088 rc = cson_output_string(src, fmt->escapeForwardSlashes, f, state);
4090 case CSON_TYPE_ARRAY:
4091 rc = cson_output_array( src, f, state, fmt, level );
4093 case CSON_TYPE_OBJECT:
4094 rc = cson_output_object( src, f, state, fmt, level );
4097 rc = cson_rc.TypeError;
4105static int cson_output_array(
cson_value const * src, cson_data_dest_f f,
void * state,
4108 if( !src || !f || !fmt )
return cson_rc.ArgError;
4109 else if( ! cson_value_is_array(src) )
return cson_rc.TypeError;
4110 else if( level > fmt->maxDepth )
return cson_rc.RangeError;
4116 char doIndent = fmt->indentation ? 1 : 0;
4117 cson_array const * ar = cson_value_get_array(src);
4118 assert( NULL != ar );
4119 if( 0 == ar->list.count )
4121 return f(state,
"[]", 2 );
4123 else if( (1 == ar->list.count) && !fmt->indentSingleMemberValues ) doIndent = 0;
4124 rc = f(state,
"[", 1);
4128 rc = cson_output_indent( f, state, fmt->indentation, level );
4130 for( i = 0; (i < ar->list.count) && (0 == rc); ++i )
4132 v = ar->list.list[i];
4135 rc = cson_output_impl( v, f, state, fmt, level );
4139 rc = cson_output_null( f, state );
4143 if(i < (ar->list.count-1))
4145 rc = f(state,
",", 1);
4149 ? cson_output_indent( f, state, fmt->indentation, level )
4156 if( doIndent && (0 == rc) )
4158 rc = cson_output_indent( f, state, fmt->indentation, level );
4166static int cson_output_object(
cson_value const * src, cson_data_dest_f f,
void * state,
4169 if( !src || !f || !fmt )
return cson_rc.ArgError;
4170 else if( ! cson_value_is_object(src) )
return cson_rc.TypeError;
4171 else if( level > fmt->maxDepth )
return cson_rc.RangeError;
4177 char doIndent = fmt->indentation ? 1 : 0;
4178 cson_object const * obj = cson_value_get_object(src);
4179 assert( (NULL != obj) && (NULL != fmt));
4180 if( 0 == obj->kvp.count )
4182 return f(state,
"{}", 2 );
4184 else if( (1 == obj->kvp.count) && !fmt->indentSingleMemberValues ) doIndent = 0;
4185 rc = f(state,
"{", 1);
4189 rc = cson_output_indent( f, state, fmt->indentation, level );
4191 for( i = 0; (i < obj->kvp.count) && (0 == rc); ++i )
4193 kvp = obj->kvp.list[i];
4194 if( kvp && kvp->key )
4196 cson_string const * sKey = cson_value_get_string(kvp->key);
4197 char const * cKey = cson_string_cstr(sKey);
4198 rc = cson_str_to_json(cKey, sKey->length,
4199 fmt->escapeForwardSlashes, f, state);
4202 rc = fmt->addSpaceAfterColon
4203 ? f(state,
": ", 2 )
4210 ? cson_output_impl( kvp->value, f, state, fmt, level )
4211 : cson_output_null( f, state );
4216 assert( 0 &&
"Possible internal error." );
4221 if(i < (obj->kvp.count-1))
4223 rc = f(state,
",", 1);
4227 ? cson_output_indent( f, state, fmt->indentation, level )
4234 if( doIndent && (0 == rc) )
4236 rc = cson_output_indent( f, state, fmt->indentation, level );
4244int cson_output(
cson_value const * src, cson_data_dest_f f,
4248 if(! fmt ) fmt = &cson_output_opt_empty;
4249 rc = cson_output_impl(src, f, state, fmt, 0 );
4250 if( (0 == rc) && fmt->addNewline )
4252 rc = f(state,
"\n", 1);
4257int cson_data_dest_FILE(
void * state,
void const * src,
unsigned int n )
4259 if( ! state )
return cson_rc.ArgError;
4260 else if( !src || !n )
return 0;
4263 return ( 1 == fwrite( src, n, 1, (FILE*) state ) )
4274 rc = cson_output( src, cson_data_dest_FILE, dest, fmt );
4281 rc = cson_output( src, cson_data_dest_FILE, dest, &opt );
4292 if( !src || !dest )
return cson_rc.ArgError;
4295 FILE * f = fopen(dest,
"wb");
4296 if( !f )
return cson_rc.IOError;
4299 int const rc = cson_output_FILE( src, f, fmt );
4306int cson_parse_filename(
cson_value ** tgt,
char const * src,
4309 if( !src || !tgt )
return cson_rc.ArgError;
4312 FILE * f = fopen(src,
"r");
4313 if( !f )
return cson_rc.IOError;
4316 int const rc = cson_parse_FILE( tgt, f, opt, err );
4339static int cson_data_source_StringSource(
void * state,
void * dest,
unsigned int * n )
4341 if( !state || !n || !dest )
return cson_rc.ArgError;
4342 else if( !*n )
return 0 ;
4347 unsigned char * tgt = (
unsigned char *)dest;
4348 for( i = 0; (i < *n) && (ss->
pos < ss->
end); ++i, ++ss->
pos, ++tgt )
4357int cson_parse_string(
cson_value ** tgt,
char const * src,
unsigned int len,
4360 if( ! tgt || !src )
return cson_rc.ArgError;
4361 else if( !*src || (len<2) )
return cson_rc.RangeError;
4367 return cson_parse( tgt, cson_data_source_StringSource, &ss, opt, err );
4377 return ( !tgt || !buf || !buf->mem || !buf->used )
4379 : cson_parse_string( tgt, (
char const *)buf->mem,
4380 buf->used, opt, err );
4383int cson_buffer_reserve(
cson_buffer * buf, cson_size_t n )
4385 if( ! buf )
return cson_rc.ArgError;
4388 cson_free(buf->mem,
"cson_buffer::mem");
4389 *buf = cson_buffer_empty;
4392 else if( buf->capacity >= n )
4398 unsigned char * x = (
unsigned char *)cson_realloc( buf->mem, n,
"cson_buffer::mem" );
4399 if( ! x )
return cson_rc.AllocError;
4400 memset( x + buf->used, 0, n - buf->used );
4403 ++buf->timesExpanded;
4408cson_size_t cson_buffer_fill(
cson_buffer * buf,
char c )
4410 if( !buf || !buf->capacity || !buf->mem )
return 0;
4413 memset( buf->mem, c, buf->capacity );
4414 return buf->capacity;
4424static int cson_data_dest_cson_buffer(
void * arg,
void const * data_,
unsigned int n )
4426 if( !arg )
return cson_rc.ArgError;
4427 else if( ! n )
return 0;
4431 char const * data = (
char const *)data_;
4432 cson_size_t npos = sb->
used + n;
4436 const cson_size_t oldCap = sb->
capacity;
4437 const cson_size_t asz = npos * 2;
4438 if( asz < npos )
return cson_rc.ArgError;
4439 else if( 0 != cson_buffer_reserve( sb, asz ) )
return cson_rc.AllocError;
4440 assert( (sb->
capacity > oldCap) &&
"Internal error in memory buffer management!" );
4442 memset( sb->
mem + oldCap, 0, (sb->
capacity - oldCap) );
4444 for( i = 0; i < n; ++i, ++sb->
used )
4456 int rc = cson_output( v, cson_data_dest_cson_buffer, buf, opt );
4459 rc = cson_buffer_reserve( buf, buf->used + 1 );
4462 buf->mem[buf->used] = 0;
4505static char cson_next_token(
char const ** inp,
char separator,
char const ** end )
4507 char const * pos = NULL;
4508 assert( inp && end && *inp );
4509 if( *inp == *end )
return 0;
4516 for( ; *pos && (*pos == separator); ++pos) { }
4518 for( ; *pos && (*pos != separator); ++pos) { }
4520 return (pos > *inp) ? 1 : 0;
4525 if( ! obj || !path )
return cson_rc.ArgError;
4526 else if( !*path || !*(1+path) )
return cson_rc.RangeError;
4527 else return cson_object_fetch_sub(obj, tgt, path+1, *path);
4532 if( ! obj || !path )
return cson_rc.ArgError;
4533 else if( !*path || !sep )
return cson_rc.RangeError;
4536 char const * beg = path;
4537 char const * end = NULL;
4539 unsigned int i, len;
4540 unsigned int tokenCount = 0;
4543 enum { BufSize = 128 };
4545 memset( buf, 0, BufSize );
4547 while( cson_next_token( &beg, sep, &end ) )
4549 if( beg == end )
break;
4557 if( 0 == tokenCount )
return cson_rc.RangeError;
4560 for( i = 0; i < tokenCount; ++i, beg=end, end=NULL )
4562 rc = cson_next_token( &beg, sep, &end );
4564 assert( beg != end );
4565 assert( end > beg );
4566 len = (
unsigned int)(end - beg);
4567 if( len > (BufSize-1) )
return cson_rc.RangeError;
4568 memset( buf, 0, len + 1 );
4569 memcpy( buf, beg, len );
4571 cv = cson_object_get( curObj, buf );
4572 if( NULL == cv )
return cson_rc.NotFoundError;
4573 else if( i == (tokenCount-1) )
4578 else if( cson_value_is_object(cv) )
4580 curObj = cson_value_get_object(cv);
4581 assert((NULL != curObj) &&
"Detected mis-management of internal memory!");
4586 return cson_rc.NotFoundError;
4589 assert( i == tokenCount );
4590 return cson_rc.NotFoundError;
4597 cson_object_fetch_sub( obj, &v, path, sep );
4604 cson_object_fetch_sub2( obj, &v, path );
4617#define TRY_SHARING 1
4620 else if( cson_value_is_object(v)
4621 || cson_value_is_array(v))
4623 rc = cson_value_clone( v );
4630 rc = cson_value_clone(v);
4633 cson_value_add_reference(rc);
4640 cson_array const * asrc = cson_value_get_array( orig );
4641 unsigned int alen = cson_array_length_get( asrc );
4644 assert( orig && asrc );
4645 destV = cson_value_new_array();
4646 if( NULL == destV )
return NULL;
4647 destA = cson_value_get_array( destV );
4649 if( 0 != cson_array_reserve( destA, alen ) )
4651 cson_value_free( destV );
4654 for( ; i < alen; ++i )
4659 cson_value * cl = cson_value_clone_ref( ch );
4662 cson_value_free( destV );
4665 if( 0 != cson_array_set( destA, i, cl ) )
4667 cson_value_free( cl );
4668 cson_value_free( destV );
4671 cson_value_free(cl);
4679 cson_object const * src = cson_value_get_object( orig );
4684 assert( orig && src );
4685 if( 0 != cson_object_iter_init( src, &iter ) )
4689 destV = cson_value_new_object();
4690 if( NULL == destV )
return NULL;
4691 dest = cson_value_get_object( destV );
4693 if( src->kvp.count > cson_kvp_list_reserve( &dest->kvp, src->kvp.count ) ){
4694 cson_value_free( destV );
4697 while( (kvp = cson_object_iter_next( &iter )) )
4701 assert( kvp->key && (kvp->key->
refcount>0) );
4702 key = cson_value_clone_ref(kvp->key);
4703 val =
key ? cson_value_clone_ref(kvp->value) : NULL;
4704 if( !
key || !val ){
4707 assert( CSON_STR(
key) );
4708 if( 0 != cson_object_set_s( dest, CSON_STR(
key), val ) )
4713 cson_value_free(
key);
4714 cson_value_free(val);
4717 cson_value_free(
key);
4718 cson_value_free(val);
4719 cson_value_free(destV);
4728 if( NULL == orig )
return NULL;
4733 case CSON_TYPE_UNDEF:
4734 assert(0 &&
"This should never happen.");
4736 case CSON_TYPE_NULL:
4737 return cson_value_null();
4738 case CSON_TYPE_BOOL:
4739 return cson_value_new_bool( cson_value_get_bool( orig ) );
4740 case CSON_TYPE_INTEGER:
4741 return cson_value_new_integer( cson_value_get_integer( orig ) );
4743 case CSON_TYPE_DOUBLE:
4744 return cson_value_new_double( cson_value_get_double( orig ) );
4746 case CSON_TYPE_STRING: {
4747 cson_string const * str = cson_value_get_string( orig );
4748 return cson_value_new_string( cson_string_cstr( str ),
4749 cson_string_length_bytes( str ) );
4751 case CSON_TYPE_ARRAY:
4752 return cson_value_clone_array( orig );
4753 case CSON_TYPE_OBJECT:
4754 return cson_value_clone_object( orig );
4756 assert( 0 &&
"We can't get this far." );
4763#define MT CSON_SPECIAL_VALUES[CSON_VAL_STR_EMPTY]
4765 ? ((s==MT.value) ? &MT : CSON_VCAST(s))
4787 if(x) cson_value_free(cson_object_value(x));
4791 if(x) cson_value_free(cson_array_value(x));
4796 if(x) cson_value_free(cson_string_value(x));
4800 if(x) cson_value_free(x);
4806char * cson_pod_to_string(
cson_value const * orig )
4808 if( ! orig )
return NULL;
4811 enum { BufSize = 64 };
4815 case CSON_TYPE_BOOL: {
4816 char const bv = cson_value_get_bool(orig);
4817 v = cson_strdup( bv ?
"true" :
"false",
4821 case CSON_TYPE_UNDEF:
4822 case CSON_TYPE_NULL: {
4823 v = cson_strdup(
"null", 4 );
4826 case CSON_TYPE_STRING: {
4827 cson_string const * jstr = cson_value_get_string(orig);
4828 unsigned const int slen = cson_string_length_bytes( jstr );
4829 assert( NULL != jstr );
4830 v = cson_strdup( cson_string_cstr( jstr ), slen );
4833 case CSON_TYPE_INTEGER: {
4834 char buf[BufSize] = {0};
4835 if( 0 < sprintf( v,
"%"CSON_INT_T_PFMT, cson_value_get_integer(orig)) )
4837 v = cson_strdup( buf, strlen(buf) );
4841 case CSON_TYPE_DOUBLE: {
4842 char buf[BufSize] = {0};
4843 if( 0 < sprintf( v,
"%"CSON_DOUBLE_T_PFMT, cson_value_get_double(orig)) )
4845 v = cson_strdup( buf, strlen(buf) );
4859char * cson_pod_to_string(
cson_value const * orig )
4861 if( ! orig )
return NULL;
4864 enum { BufSize = 64 };
4868 case CSON_TYPE_BOOL: {
4869 char const bv = cson_value_get_bool(orig);
4870 v = cson_strdup( bv ?
"true" :
"false",
4874 case CSON_TYPE_UNDEF:
4875 case CSON_TYPE_NULL: {
4876 v = cson_strdup(
"null", 4 );
4879 case CSON_TYPE_STRING: {
4880 cson_string const * jstr = cson_value_get_string(orig);
4881 unsigned const int slen = cson_string_length_bytes( jstr );
4882 assert( NULL != jstr );
4883 v = cson_strdup( cson_string_cstr( jstr ), slen );
4886 case CSON_TYPE_INTEGER: {
4887 char buf[BufSize] = {0};
4888 if( 0 < sprintf( v,
"%"CSON_INT_T_PFMT, cson_value_get_integer(orig)) )
4890 v = cson_strdup( buf, strlen(buf) );
4894 case CSON_TYPE_DOUBLE: {
4895 char buf[BufSize] = {0};
4896 if( 0 < sprintf( v,
"%"CSON_DOUBLE_T_PFMT, cson_value_get_double(orig)) )
4898 v = cson_strdup( buf, strlen(buf) );
4910unsigned int cson_value_msize(
cson_value const * v)
4913 else if( cson_value_is_builtin(v) )
return 0;
4916 assert(NULL != v->
api);
4918 case CSON_TYPE_INTEGER:
4919 assert( v != &CSON_SPECIAL_VALUES[CSON_VAL_INT_0]);
4920 rc +=
sizeof(cson_int_t);
4922 case CSON_TYPE_DOUBLE:
4923 assert( v != &CSON_SPECIAL_VALUES[CSON_VAL_DBL_0]);
4924 rc +=
sizeof(cson_double_t);
4926 case CSON_TYPE_STRING:
4928 + CSON_STR(v)->length + 1;
4930 case CSON_TYPE_ARRAY:{
4934 assert( NULL != ar );
4938 for( ; i < li->count; ++i ){
4940 if( e ) rc += cson_value_msize( e );
4944 case CSON_TYPE_OBJECT:{
4948 assert(NULL != obj);
4951 + (kl->alloced *
sizeof(
cson_kvp*));
4952 for( ; i < kl->count; ++i ){
4953 cson_kvp const * kvp = kl->list[i];
4954 assert(NULL != kvp);
4955 rc += cson_value_msize(kvp->key);
4956 rc += cson_value_msize(kvp->value);
4960 case CSON_TYPE_UNDEF:
4961 case CSON_TYPE_NULL:
4962 case CSON_TYPE_BOOL:
4963 assert( 0 &&
"Should have been caught by is-builtin check!" );
4966 assert(0 &&
"Invalid typeID!");
4977 char const replace = (flags & CSON_MERGE_REPLACE);
4978 char const recurse = !(flags & CSON_MERGE_NO_RECURSE);
4980 if((!dest || !src) || (dest==src))
return cson_rc.ArgError;
4981 rc = cson_object_iter_init( src, &iter );
4983 while( (kvp = cson_object_iter_next(&iter) ) )
4989 cson_object_set_s( dest,
key, val );
4992 else if(!replace && !recurse)
continue;
4993 else if(replace && !recurse){
4994 cson_object_set_s( dest,
key, val );
4998 if( cson_value_is_object(check) &&
4999 cson_value_is_object(val) ){
5000 rc = cson_object_merge( cson_value_get_object(check),
5001 cson_value_get_object(val),
5013static cson_value * cson_guess_arg_type(
char const *arg){
5015 if(!arg || !*arg)
return cson_value_null();
5016 else if((
'0'>*arg) || (
'9'<*arg)){
5020 long const val = strtol(arg, &end, 10);
5022 return cson_value_new_integer( (cson_int_t)val);
5024 else if(
'.' != *end ) {
5028 double const val = strtod(arg, &end);
5030 return cson_value_new_double(val);
5035 return cson_value_new_string(arg, (
unsigned int)strlen(arg));
5039int cson_parse_argv_flags(
int argc,
char const *
const * argv,
5044 if(argc<1 || !argc || !tgt)
return cson_rc.ArgError;
5045 o = *tgt ? *tgt : cson_new_object();
5046 if(count) *count = 0;
5047 for( i = 0; i < argc; ++i ){
5048 char const * arg = argv[i];
5049 char const *
key = arg;
5053 if(
'-' != *arg)
continue;
5057 while( *pos && (
'=' != *pos)) ++pos;
5058 k = cson_new_string(
key, (
unsigned int)(pos-
key));
5060 rc = cson_rc.AllocError;
5064 v = cson_value_true();
5066 assert(
'=' == *pos);
5068 v = cson_guess_arg_type(pos);
5070 if(0 != (rc=cson_object_set_s(o, k, v))){
5071 cson_free_string(k);
5075 else if(count) ++*count;
5078 if(rc) cson_free_object(o);
5084#if defined(__cplusplus)
5089#undef CSON_OBJECT_PROPS_SORT
5090#undef CSON_OBJECT_PROPS_SORT_USE_LENGTH
5098#undef CSON_MALLOC_IMPL
5099#undef CSON_FREE_IMPL
5100#undef CSON_REALLOC_IMPL
5104unsigned int cson_value_list_reserve(
cson_value_list * self,
unsigned int n )
5106 if( !self )
return 0;
5109 if(0 == self->alloced)
return 0;
5110 cson_free(self->list,
"cson_value_list_reserve");
5112 self->alloced = self->count = 0;
5115 else if( self->alloced >= n )
5117 return self->alloced;
5123 if( ! m )
return self->alloced;
5125 memset( m + self->alloced, 0, (
sizeof(
cson_value *)*(n-self->alloced)));
5133 if( !self || !cp )
return cson_rc.ArgError;
5134 else if( self->alloced > cson_value_list_reserve(self, self->count+1) )
5136 return cson_rc.AllocError;
5140 self->list[self->count++] = cp;
5146 int (*visitor)(
cson_value * obj,
void * visitorState ),
5150 void * visitorState )
5152 int rc = cson_rc.ArgError;
5153 if( self && visitor )
5156 for( rc = 0; (i < self->count) && (0 == rc); ++i )
5163 if(obj) rc = visitor( obj, visitorState );
5176 if( self && cleaner && self->count )
5179 for( ; i < self->count; ++i )
5186 if(obj) cleaner(obj);
5189 cson_value_list_reserve(self,0);
5191unsigned int cson_kvp_list_reserve(
cson_kvp_list * self,
unsigned int n )
5193 if( !self )
return 0;
5196 if(0 == self->alloced)
return 0;
5197 cson_free(self->list,
"cson_kvp_list_reserve");
5199 self->alloced = self->count = 0;
5202 else if( self->alloced >= n )
5204 return self->alloced;
5208 size_t const sz =
sizeof(
cson_kvp *) * n;
5209 cson_kvp * * m = (
cson_kvp **)cson_realloc( self->list, sz,
"cson_kvp_list_reserve" );
5210 if( ! m )
return self->alloced;
5212 memset( m + self->alloced, 0, (
sizeof(
cson_kvp *)*(n-self->alloced)));
5220 if( !self || !cp )
return cson_rc.ArgError;
5221 else if( self->alloced > cson_kvp_list_reserve(self, self->count+1) )
5223 return cson_rc.AllocError;
5227 self->list[self->count++] = cp;
5233 int (*visitor)(
cson_kvp * obj,
void * visitorState ),
5237 void * visitorState )
5239 int rc = cson_rc.ArgError;
5240 if( self && visitor )
5243 for( rc = 0; (i < self->count) && (0 == rc); ++i )
5250 if(obj) rc = visitor( obj, visitorState );
5263 if( self && cleaner && self->count )
5266 for( ; i < self->count; ++i )
5273 if(obj) cleaner(obj);
5276 cson_kvp_list_reserve(self,0);
The structure used to configure a JSON parser object.
JSON_free_t free
The memory deallocation routine, which must be semantically compatible with free(3).
JSON_parser_callback callback
Pointer to a callback, called when the parser has something to tell the user.
int allow_comments
To allow C style comments in JSON, set to non-zero.
int depth
Specifies the levels of nested JSON to allow.
int handle_floats_manually
To decode floating point numbers manually set this parameter to non-zero.
JSON_malloc_t malloc
The memory allocation routine, which must be semantically compatible with malloc(3).
void * callback_ctx
Callback context - client-specified data to pass to the callback function.
cson_array is an opaque handle to an Array value.
unsigned char * mem
The memory allocated for and owned by this buffer.
cson_size_t used
The number of bytes "used" by this object.
cson_size_t capacity
The number of bytes allocated for this object.
Internal type to hold state for a JSON input string.
char const * pos
Current iteration position.
char const * end
Logical EOF, one-past-the-end of str.
char const * str
Start of input string.
A key/value pair collection.
An iterator type for traversing object properties.
cson_object is an opaque handle to an Object value.
Client-configurable options for the cson_output() family of functions.
char addNewline
If true, a newline will be added to generated output, else not.
A class for holding JSON parser information.
unsigned int length
Length, in bytes.
unsigned int totalValueCount
The total number of object/array values successfully processed by the parser, including the root node...
unsigned int col
0-based column number.
int errorCode
Error code of the parse run (0 for no error).
unsigned int line
1-based line number.
unsigned int totalKeyCount
The total number of object keys successfully processed by the parser.
Client-configurable options for the cson_parse() family of functions.
char allowComments
Whether or not to allow C-style comments.
unsigned short maxDepth
Maximum object/array depth to traverse.
Strings are allocated as an instances of this class with N+1 trailing bytes, where N is the length of...
This type holds the "vtbl" for type-specific operations when working with cson_value objects.
void(* cleanup)(cson_value *self)
Must free any memory associated with self, but not free self.
const cson_type_id typeID
The logical JavaScript/JSON type associated with this object.
The core value type of this API.
cson_value_api const * api
The "vtbl" of type-specific operations.
cson_counter_t refcount
We use this to allow us to store cson_value instances in multiple containers or multiple times within...
void * value
The raw value.