--- a/src/json.c Fri Dec 27 12:23:14 2024 +0100 +++ b/src/json.c Fri Dec 27 13:01:31 2024 +0100 @@ -289,35 +289,6 @@ return result; } -static int parse_number(cxmutstr str, void *value, bool asint) { - char *endptr = NULL; - if (str.length > 30) { - return 1; - } - // the buffer guarantees that we are working on a copied string - char c = str.ptr[str.length]; - str.ptr[str.length] = 0; - - if (asint) { - errno = 0; - long long v = strtoll(str.ptr, &endptr, 10); - if (errno == ERANGE) { - return 1; - } - *((int64_t*)value) = (int64_t) v; - } else { - // TODO: proper JSON spec number parser - // TODO: also return an error when loss of precision is high - double v = strtod(str.ptr, &endptr); - *((double*)value) = v; - } - - // recover from the hack - str.ptr[str.length] = c; - - return endptr != &str.ptr[str.length]; -} - static CxJsonValue* create_json_value(CxJson *json, CxJsonValueType type) { CxJsonValue *v = cxMalloc(json->allocator, sizeof(CxJsonValue)); if (v == NULL) { @@ -400,8 +371,6 @@ json->vbuf = json->vbuf_internal; json->vbuf_capacity = cx_nmemb(json->vbuf_internal); - - cxBufferInit(&json->buffer, NULL, 256, NULL, CX_BUFFER_AUTO_EXTEND); } void cxJsonDestroy(CxJson *json) { @@ -417,16 +386,16 @@ } int cxJsonFilln(CxJson *json, const char *buf, size_t size) { - // we use the UCX buffer to write the data - // but reset the position immediately to enable parsing - size_t old_pos = json->buffer.pos; - cxBufferSeek(&json->buffer, 0, SEEK_END); - size_t written = cxBufferWrite(buf, 1, size, &json->buffer); - if (0 == cxBufferTerminate(&json->buffer)) { - written++; + if (cxBufferEof(&json->buffer)) { + // reinitialize the buffer + cxBufferDestroy(&json->buffer); + cxBufferInit(&json->buffer, (char*) buf, size, + NULL, CX_BUFFER_AUTO_EXTEND | CX_BUFFER_COPY_ON_WRITE); + json->buffer.size = size; + return 0; + } else { + return size != cxBufferAppend(buf, 1, size, &json->buffer); } - json->buffer.pos = old_pos; - return written != size + 1; } static void json_add_state(CxJson *json, int state) { @@ -508,8 +477,14 @@ if (NULL == (vbuf = create_json_value(json, type))) { return_rec(CX_JSON_VALUE_ALLOC_FAILED); } - if (parse_number(token.content, &vbuf->value,type == CX_JSON_INTEGER)) { - return_rec(CX_JSON_FORMAT_ERROR_NUMBER); + if (type == CX_JSON_INTEGER) { + if (cx_strtoi64(token.content, &vbuf->value.integer, 10)) { + return_rec(CX_JSON_FORMAT_ERROR_NUMBER); + } + } else { + if (cx_strtod(token.content, &vbuf->value.number)) { + return_rec(CX_JSON_FORMAT_ERROR_NUMBER); + } } return_rec(CX_JSON_NO_ERROR); } @@ -600,6 +575,11 @@ } CxJsonStatus cxJsonNext(CxJson *json, CxJsonValue **value) { + // check if buffer has been filled + if (json->buffer.space == NULL) { + return CX_JSON_NULL_DATA; + } + // initialize output value *value = &cx_json_value_nothing; @@ -607,7 +587,6 @@ CxJsonStatus result; do { result = json_parse(json); - cxBufferShiftLeft(&json->buffer, json->buffer.pos); if (result == CX_JSON_NO_ERROR && json->states_size == 1) { // final state reached assert(json->states[0] == JP_STATE_VALUE_END);