12#include "../nyx_node_internal.h"
26 JSON_TOKEN_CURLY_OPEN,
27 JSON_TOKEN_CURLY_CLOSE,
28 JSON_TOKEN_SQUARE_OPEN,
29 JSON_TOKEN_SQUARE_CLOSE,
42 json_token_type_t token_type;
53 json_token_t curr_token;
62 tokenizer_next(parser)
72 (parser->curr_token.token_type == (t))
77 if(CHECK(JSON_TOKEN_NUMBER) || CHECK(JSON_TOKEN_STRING)) \
79 nyx_memory_free(PEEK().value); \
81 PEEK().value = NULL; \
84 PEEK().token_type = (t) \
90 size_t result = (size_t) (e) - (size_t) (s); \
92 while(result > 0 && (isspace((unsigned char) *((s) + 0)) || *((s) + 0) == '"')) { \
97 while(result > 0 && (isspace((unsigned char) *((e) - 1)) || *((e) - 1) == '"')) { \
119 case '\"': *p++ =
'\"'; s++;
break;
120 case '\\': *p++ =
'\\'; s++;
break;
121 case '/': *p++ =
'/' ; s++;
break;
122 case 'b': *p++ =
'\b'; s++;
break;
123 case 'f': *p++ =
'\f'; s++;
break;
124 case 'n': *p++ =
'\n'; s++;
break;
125 case 'r': *p++ =
'\r'; s++;
break;
126 case 't': *p++ =
'\t'; s++;
break;
138 uint32_t unicode_char = (uint32_t) strtol(hex, NULL, 16);
140 p += nyx_unicode_to_utf8(p, unicode_char);
141 s += 0x0000000000000000000000000000000004;
172static void tokenizer_next(json_parser_t *parser)
180 while(parser->size > 0 && isspace((
unsigned char) *parser->buff))
188 if(parser->size == 0)
190 parser->curr_token.token_type = JSON_TOKEN_EOF;
197 STR_t start = parser->buff;
198 STR_t end = parser->buff;
200 json_token_type_t type;
202 switch(*parser->buff)
207 type = JSON_TOKEN_EOF;
215 type = JSON_TOKEN_CURLY_OPEN;
223 type = JSON_TOKEN_CURLY_CLOSE;
231 type = JSON_TOKEN_SQUARE_OPEN;
239 type = JSON_TOKEN_SQUARE_CLOSE;
247 type = JSON_TOKEN_COLON;
255 type = JSON_TOKEN_COMMA;
263 while(parser->size >= 1 && *end !=
'"')
267 type = JSON_TOKEN_ERROR;
271 if(parser->size >= 2 && (
285 type = JSON_TOKEN_ERROR;
290 type = JSON_TOKEN_STRING;
296 if(*end ==
'-' || isdigit((
unsigned char) *end))
300 while(parser->size >= 1 && (*end ==
'-' || *end ==
'+' || *end ==
'.' || *end ==
'e' || *end ==
'E' || isdigit((
unsigned char) *end)))
305 type = JSON_TOKEN_NUMBER;
307 else if(parser->size >= 4 && strncmp(end,
"null", 4) == 0)
311 type = JSON_TOKEN_NULL;
313 else if(parser->size >= 4 && strncmp(end,
"true", 4) == 0)
317 type = JSON_TOKEN_TRUE;
319 else if(parser->size >= 5 && strncmp(end,
"false", 5) == 0)
323 type = JSON_TOKEN_FALSE;
327 type = JSON_TOKEN_ERROR;
336 if(type == JSON_TOKEN_NUMBER)
341 size_t length = TRIM(s, e);
348 else if(type == JSON_TOKEN_STRING)
353 size_t length = TRIM(s, e);
357 if(jsoncpy(p, s, e) ==
false)
360 parser->curr_token.value = NULL;
361 type = JSON_TOKEN_ERROR;
369 parser->curr_token.token_type = type;
378static nyx_dict_t *json_parse_dict(json_parser_t *parser);
380static nyx_list_t *json_parse_list(json_parser_t *parser);
384static nyx_null_t *json_parse_null(json_parser_t *parser)
386 if(CHECK(JSON_TOKEN_NULL) ==
false)
393 return nyx_null_new();
400 if(CHECK(JSON_TOKEN_TRUE) ==
false)
407 return nyx_boolean_from(
true);
414 if(CHECK(JSON_TOKEN_FALSE) ==
false)
421 return nyx_boolean_from(
false);
426static nyx_number_t *json_parse_number(json_parser_t *parser)
428 if(CHECK(JSON_TOKEN_NUMBER) ==
false)
433 str_t value = PEEK().value;
446static nyx_string_t *json_parse_string(json_parser_t *parser)
448 if(CHECK(JSON_TOKEN_STRING) ==
false)
453 str_t value = PEEK().value;
466static nyx_dict_t *json_parse_dict(json_parser_t *parser)
472 if(CHECK(JSON_TOKEN_CURLY_OPEN) ==
false)
481 while(CHECK(JSON_TOKEN_CURLY_CLOSE) ==
false)
485 if(CHECK(JSON_TOKEN_STRING) ==
false)
492 str_t key = PEEK().value;
496 if(CHECK(JSON_TOKEN_COLON) ==
false)
509 if(CHECK(JSON_TOKEN_NULL)) {
510 value = json_parse_null(parser);
512 else if(CHECK(JSON_TOKEN_TRUE)) {
513 value = json_parse_true(parser);
515 else if(CHECK(JSON_TOKEN_FALSE)) {
516 value = json_parse_false(parser);
518 else if(CHECK(JSON_TOKEN_NUMBER)) {
519 value = json_parse_number(parser);
521 else if(CHECK(JSON_TOKEN_STRING)) {
522 value = json_parse_string(parser);
524 else if(CHECK(JSON_TOKEN_CURLY_OPEN)) {
525 value = json_parse_dict(parser);
527 else if(CHECK(JSON_TOKEN_SQUARE_OPEN)) {
528 value = json_parse_list(parser);
540 nyx_dict_set(result, key, value);
542 nyx_object_unref(value);
550 if(CHECK(JSON_TOKEN_COMMA))
554 if(CHECK(JSON_TOKEN_CURLY_CLOSE) ==
true)
561 if(CHECK(JSON_TOKEN_CURLY_CLOSE) ==
false)
572 if(CHECK(JSON_TOKEN_CURLY_CLOSE) ==
false)
584 RELEASE(JSON_TOKEN_ERROR);
586 nyx_dict_free(result);
593static nyx_list_t *json_parse_list(json_parser_t *parser)
599 if(CHECK(JSON_TOKEN_SQUARE_OPEN) ==
false)
608 while(CHECK(JSON_TOKEN_SQUARE_CLOSE) ==
false)
614 if(CHECK(JSON_TOKEN_NULL)) {
615 value = json_parse_null(parser);
617 else if(CHECK(JSON_TOKEN_TRUE)) {
618 value = json_parse_true(parser);
620 else if(CHECK(JSON_TOKEN_FALSE)) {
621 value = json_parse_false(parser);
623 else if(CHECK(JSON_TOKEN_NUMBER)) {
624 value = json_parse_number(parser);
626 else if(CHECK(JSON_TOKEN_STRING)) {
627 value = json_parse_string(parser);
629 else if(CHECK(JSON_TOKEN_CURLY_OPEN)) {
630 value = json_parse_dict(parser);
632 else if(CHECK(JSON_TOKEN_SQUARE_OPEN)) {
633 value = json_parse_list(parser);
643 nyx_list_push(result, value);
645 nyx_object_unref(value);
649 if(CHECK(JSON_TOKEN_COMMA))
653 if(CHECK(JSON_TOKEN_SQUARE_CLOSE) ==
true)
660 if(CHECK(JSON_TOKEN_SQUARE_CLOSE) ==
false)
671 if(CHECK(JSON_TOKEN_SQUARE_CLOSE) ==
false)
683 RELEASE(JSON_TOKEN_ERROR);
685 nyx_list_free(result);
703 json_parser_t *parser = &(json_parser_t) {
708 .token_type = JSON_TOKEN_ERROR,
720 if(CHECK(JSON_TOKEN_NULL)) {
723 else if(CHECK(JSON_TOKEN_TRUE)) {
726 else if(CHECK(JSON_TOKEN_FALSE)) {
729 else if(CHECK(JSON_TOKEN_NUMBER)) {
732 else if(CHECK(JSON_TOKEN_STRING)) {
735 else if(CHECK(JSON_TOKEN_CURLY_OPEN)) {
738 else if(CHECK(JSON_TOKEN_SQUARE_OPEN)) {
744 if(result == NULL || CHECK(JSON_TOKEN_EOF) ==
false)
746 if(parser->curr_token.value != NULL)
750 parser->curr_token.value = NULL;
753 nyx_object_unref(result);
772 return nyx_object_parse_buff(
Struct describing a JSON boolean object.
Struct describing a JSON dict object.
Struct describing a JSON list object.
#define STR_t
Alias for const char *.
__NYX_NULLABLE__ buff_t nyx_memory_alloc(__NYX_ZEROABLE__ size_t size)
Similar to libc malloc except that a memory overflow causes the node to stop.
__NYX_ZEROABLE__ size_t nyx_memory_free(__NYX_NULLABLE__ buff_t buff)
Similar to libc free except that it returns the amount of memory freed.
#define buff_t
Alias for void *.
#define BUFF_t
Alias for const void *.
__NYX_NULLABLE__ str_t nyx_string_ndup(__NYX_NULLABLE__ STR_t s, __NYX_ZEROABLE__ size_t n)
Similar to libc strndup.
#define str_t
Alias for char *.
Struct describing a JSON null object.
Struct describing a JSON number object.
Struct describing a JSON object.
Struct describing a JSON string object.