46 if (token->allocated) { |
46 if (token->allocated) { |
47 cx_strfree(&token->content); |
47 cx_strfree(&token->content); |
48 } |
48 } |
49 } |
49 } |
50 |
50 |
51 |
|
52 static int token_isliteral(const char *content, size_t length) { |
|
53 if (length == 4) { |
|
54 if (!memcmp(content, "true", 4)) { |
|
55 return 1; |
|
56 } else if (!memcmp(content, "null", 4)) { |
|
57 return 1; |
|
58 } |
|
59 } else if (length == 5 && !memcmp(content, "false", 5)) { |
|
60 return 1; |
|
61 } |
|
62 return 0; |
|
63 } |
|
64 |
|
65 static int num_isexp(const char *content, size_t length, size_t pos) { |
51 static int num_isexp(const char *content, size_t length, size_t pos) { |
66 if (pos >= length) { |
52 if (pos >= length) { |
67 return 0; |
53 return 0; |
68 } |
54 } |
69 |
55 |
121 json->uncompleted = (CxJsonToken){0}; |
107 json->uncompleted = (CxJsonToken){0}; |
122 CxJsonTokenType ttype; |
108 CxJsonTokenType ttype; |
123 if (isstring) { |
109 if (isstring) { |
124 ttype = CX_JSON_TOKEN_STRING; |
110 ttype = CX_JSON_TOKEN_STRING; |
125 } else { |
111 } else { |
126 if (token_isliteral(str.ptr, str.length)) { |
112 cxstring s = cx_strcast(str); |
|
113 if (!cx_strcmp(s, CX_STR("true")) || !cx_strcmp(s, CX_STR("false")) |
|
114 || !cx_strcmp(s, CX_STR("null"))) { |
127 ttype = CX_JSON_TOKEN_LITERAL; |
115 ttype = CX_JSON_TOKEN_LITERAL; |
128 } else { |
116 } else { |
129 ttype = token_numbertype(str.ptr, str.length); |
117 ttype = token_numbertype(str.ptr, str.length); |
130 } |
118 } |
131 } |
119 } |
381 } |
369 } |
382 |
370 |
383 return v; |
371 return v; |
384 } |
372 } |
385 |
373 |
386 static int json_obj_add_entry(CxJson *json, char *name) { |
374 static int json_obj_add_entry(const CxJson *json, char *name) { |
387 CxJsonObjValue kv = {name, NULL}; |
375 CxJsonObjValue kv = {name, NULL}; |
388 assert(json->vbuf_size > 0); |
376 assert(json->vbuf_size > 0); |
389 CxJsonValue *parent = json->vbuf[json->vbuf_size - 1]; |
377 CxJsonValue *parent = json->vbuf[json->vbuf_size - 1]; |
390 assert(parent != NULL); |
378 assert(parent != NULL); |
391 assert(parent->type == CX_JSON_OBJECT); |
379 assert(parent->type == CX_JSON_OBJECT); |
674 } |
662 } |
675 } |
663 } |
676 cxFree(value->allocator, value); |
664 cxFree(value->allocator, value); |
677 } |
665 } |
678 |
666 |
679 CxJsonValue *cxJsonArrGet(CxJsonValue *value, size_t index) { |
667 CxJsonValue *cxJsonArrGet(const CxJsonValue *value, size_t index) { |
680 if (index >= value->value.array.array_size) { |
668 if (index >= value->value.array.array_size) { |
681 return &cx_json_value_nothing; |
669 return &cx_json_value_nothing; |
682 } |
670 } |
683 return value->value.array.array[index]; |
671 return value->value.array.array[index]; |
684 } |
672 } |
685 |
673 |
686 CxJsonValue *cxJsonObjGet(CxJsonValue *value, const char *name) { |
674 CxJsonValue *cxJsonObjGet(const CxJsonValue *value, const char *name) { |
687 CxJsonObject *obj = &(value->value.object); |
675 const CxJsonObject *obj = &(value->value.object); |
688 // TODO: think about sorting the object so that we can use binary search here |
676 // TODO: think about sorting the object so that we can use binary search here |
689 for (size_t i = 0; i < obj->values_size; i++) { |
677 for (size_t i = 0; i < obj->values_size; i++) { |
690 // TODO: we might want to store names as cxmutstr |
|
691 if (0 == strcmp(name, obj->values[i].name)) { |
678 if (0 == strcmp(name, obj->values[i].name)) { |
692 return obj->values[i].value; |
679 return obj->values[i].value; |
693 } |
680 } |
694 } |
681 } |
695 return &cx_json_value_nothing; |
682 return &cx_json_value_nothing; |