From 044120a4d9ce8bb83eddf47e8d24e340b07002eb Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Wed, 17 Jun 2020 13:36:49 +0000 Subject: [PATCH] improved decimal handling in lib/json.c --- mio/bin/t03.c | 14 +++++++---- mio/lib/json.c | 58 ++++++++++++++++++++++++++++++++++++---------- mio/lib/mio-json.h | 2 +- 3 files changed, 56 insertions(+), 18 deletions(-) diff --git a/mio/bin/t03.c b/mio/bin/t03.c index b237545..76a4ff0 100644 --- a/mio/bin/t03.c +++ b/mio/bin/t03.c @@ -129,7 +129,7 @@ static int on_json_inst (mio_json_t* json, mio_json_inst_t inst, mio_oow_t level static int write_json_element (mio_jsonwr_t* jsonwr, const mio_bch_t* dptr, mio_oow_t dlen, void* ctx) { - write (1, dptr, dlen); + fwrite (dptr, 1, dlen, stdout); return 0; } @@ -148,6 +148,7 @@ int main (int argc, char* argv[]) mio_json_t* json = MIO_NULL; char buf[128]; mio_oow_t rem; + size_t size; json = mio_json_open(mio, 0); @@ -157,18 +158,21 @@ int main (int argc, char* argv[]) while (!feof(stdin) || rem > 0) { int x; - size_t size; if (!feof(stdin)) { size = fread(&buf[rem], 1, sizeof(buf) - rem, stdin); if (size <= 0) break; } - else size = 0; + else + { + size = rem; + rem = 0; + } if ((x = mio_json_feed(json, buf, size + rem, &rem, 1)) <= -1) { - printf ("**** ERROR ****\n"); + mio_logbfmt (mio, MIO_LOG_STDOUT, "**** ERROR - %js ****\n", mio_geterrmsg(mio)); break; } @@ -178,7 +182,7 @@ int main (int argc, char* argv[]) mio_logbfmt (mio, MIO_LOG_STDOUT, "\n-----------------------------------\n"); } - //printf ("--> x %d input %d left-over %d\n", (int)x, (int)size, (int)rem); + /*printf ("--> x %d input %d left-over %d => [%.*s]\n", (int)x, (int)size, (int)rem, (int)rem, &buf[size - rem]);*/ if (rem > 0) memcpy (buf, &buf[size - rem], rem); } diff --git a/mio/lib/json.c b/mio/lib/json.c index fc57df8..8cf2825 100644 --- a/mio/lib/json.c +++ b/mio/lib/json.c @@ -330,17 +330,51 @@ static int handle_string_value_char (mio_json_t* json, mio_ooci_t c) static int handle_numeric_value_char (mio_json_t* json, mio_ooci_t c) { - if (mio_is_ooch_digit(c) || (json->tok.len == 0 && (c == '+' || c == '-'))) + switch (json->state_stack->u.nv.progress) { - if (add_char_to_token(json, c, 0) <= -1) return -1; - return 1; - } - else if (!json->state_stack->u.nv.dotted && c == '.' && - json->tok.len > 0 && mio_is_ooch_digit(json->tok.ptr[json->tok.len - 1])) - { - if (add_char_to_token(json, c, 0) <= -1) return -1; - json->state_stack->u.nv.dotted = 1; - return 1; + case 0: /* integer part */ + if (mio_is_ooch_digit(c) || (json->tok.len == 0 && (c == '+' || c == '-'))) + { + if (add_char_to_token(json, c, 0) <= -1) return -1; + return 1; + } + else if ((c == '.' || c == 'e' || c == 'E') && json->tok.len > 0 && mio_is_ooch_digit(json->tok.ptr[json->tok.len - 1])) + { + if (add_char_to_token(json, c, 0) <= -1) return -1; + json->state_stack->u.nv.progress = (c == '.'? 1: 2); + return 1; + } + break; + + case 1: /* decimal part */ + if (mio_is_ooch_digit(c)) + { + if (add_char_to_token(json, c, 0) <= -1) return -1; + return 1; + } + else if (c == 'e' || c == 'E') + { + if (add_char_to_token(json, c, 0) <= -1) return -1; + json->state_stack->u.nv.progress = 2; + return 1; + } + break; + + case 2: /* exponent part (ok to have a sign) */ + if (c == '+' || c == '-') + { + if (add_char_to_token(json, c, 0) <= -1) return -1; + json->state_stack->u.nv.progress = 3; + return 1; + } + /* fall thru */ + case 3: /* exponent part (no sign expected) */ + if (mio_is_ooch_digit(c)) + { + if (add_char_to_token(json, c, 0) <= -1) return -1; + return 1; + } + break; } pop_read_state (json); @@ -453,7 +487,7 @@ static int handle_char_in_array (mio_json_t* json, mio_ooci_t c) { if (push_read_state(json, MIO_JSON_STATE_IN_NUMERIC_VALUE) <= -1) return -1; clear_token (json); - json->state_stack->u.nv.dotted = 0; + json->state_stack->u.nv.progress = 0; return 0; /* start over */ } else if (mio_is_ooch_alpha(c)) @@ -539,7 +573,7 @@ static int handle_char_in_object (mio_json_t* json, mio_ooci_t c) { if (push_read_state(json, MIO_JSON_STATE_IN_NUMERIC_VALUE) <= -1) return -1; clear_token (json); - json->state_stack->u.nv.dotted = 0; + json->state_stack->u.nv.progress = 0; return 0; /* start over */ } else if (mio_is_ooch_alpha(c)) diff --git a/mio/lib/mio-json.h b/mio/lib/mio-json.h index f1bb77d..26007da 100644 --- a/mio/lib/mio-json.h +++ b/mio/lib/mio-json.h @@ -114,7 +114,7 @@ struct mio_json_state_node_t } cv; struct { - int dotted; + int progress; } nv; } u; mio_json_state_node_t* next;