enhanced mio_json_instcb_t to accept a position with a parent container

This commit is contained in:
hyung-hwan 2020-06-06 18:53:09 +00:00
parent fef7c29e70
commit 2174c1bd9b
3 changed files with 104 additions and 47 deletions

View File

@ -30,56 +30,93 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
static int on_json_inst (mio_json_t* json, mio_json_inst_t inst, mio_oow_t level, const mio_oocs_t* str, void* ctx) static int on_json_inst (mio_json_t* json, mio_json_inst_t inst, mio_oow_t level, mio_oow_t index, const mio_oocs_t* str, void* ctx)
{ {
mio_t* mio = mio_json_getmio(json); mio_t* mio = mio_json_getmio(json);
mio_oow_t i; mio_oow_t i;
switch (inst) switch (inst)
{ {
case MIO_JSON_INST_START_ARRAY: case MIO_JSON_INST_START_ARRAY:
/* for (i = 0; i < level; i++) mio_logbfmt (mio, MIO_LOG_STDOUT, "\t"); */ if (level > 0)
{
if (index > 0) mio_logbfmt (mio, MIO_LOG_STDOUT, ",\n");
for (i = 0; i < level; i++) mio_logbfmt (mio, MIO_LOG_STDOUT, "\t");
}
mio_logbfmt (mio, MIO_LOG_STDOUT, "[\n"); mio_logbfmt (mio, MIO_LOG_STDOUT, "[\n");
break; break;
case MIO_JSON_INST_END_ARRAY: case MIO_JSON_INST_END_ARRAY:
mio_logbfmt (mio, MIO_LOG_STDOUT, "\n");
for (i = 0; i < level; i++) mio_logbfmt (mio, MIO_LOG_STDOUT, "\t"); for (i = 0; i < level; i++) mio_logbfmt (mio, MIO_LOG_STDOUT, "\t");
mio_logbfmt (mio, MIO_LOG_STDOUT, "]\n"); mio_logbfmt (mio, MIO_LOG_STDOUT, "]");
break; break;
case MIO_JSON_INST_START_DIC: case MIO_JSON_INST_START_DIC:
/*for (i = 0; i < level; i++) mio_logbfmt (mio, MIO_LOG_STDOUT, "\t"); */ if (level > 0)
{
if (index > 0) mio_logbfmt (mio, MIO_LOG_STDOUT, ",\n");
for (i = 0; i < level; i++) mio_logbfmt (mio, MIO_LOG_STDOUT, "\t");
}
mio_logbfmt (mio, MIO_LOG_STDOUT, "{\n"); mio_logbfmt (mio, MIO_LOG_STDOUT, "{\n");
break; break;
case MIO_JSON_INST_END_DIC: case MIO_JSON_INST_END_DIC:
mio_logbfmt (mio, MIO_LOG_STDOUT, "\n");
for (i = 0; i < level; i++) mio_logbfmt (mio, MIO_LOG_STDOUT, "\t"); for (i = 0; i < level; i++) mio_logbfmt (mio, MIO_LOG_STDOUT, "\t");
mio_logbfmt (mio, MIO_LOG_STDOUT, "}\n"); mio_logbfmt (mio, MIO_LOG_STDOUT, "}");
break; break;
case MIO_JSON_INST_KEY: case MIO_JSON_INST_KEY:
if (index > 0) mio_logbfmt (mio, MIO_LOG_STDOUT, ",\n");
for (i = 0; i < level; i++) mio_logbfmt (mio, MIO_LOG_STDOUT, "\t"); for (i = 0; i < level; i++) mio_logbfmt (mio, MIO_LOG_STDOUT, "\t");
mio_logbfmt (mio, MIO_LOG_STDOUT, "%.*js: ", str->len, str->ptr); mio_logbfmt (mio, MIO_LOG_STDOUT, "%.*js: ", str->len, str->ptr);
break; break;
case MIO_JSON_INST_NIL: case MIO_JSON_INST_NIL:
mio_logbfmt (mio, MIO_LOG_STDOUT, "null\n"); if (level > 0)
{
if (index > 0) mio_logbfmt (mio, MIO_LOG_STDOUT, ",\n");
for (i = 0; i < level; i++) mio_logbfmt (mio, MIO_LOG_STDOUT, "\t");
}
mio_logbfmt (mio, MIO_LOG_STDOUT, "null");
break; break;
case MIO_JSON_INST_TRUE: case MIO_JSON_INST_TRUE:
mio_logbfmt (mio, MIO_LOG_STDOUT, "true\n"); if (level > 0)
{
if (index > 0) mio_logbfmt (mio, MIO_LOG_STDOUT, ",\n");
for (i = 0; i < level; i++) mio_logbfmt (mio, MIO_LOG_STDOUT, "\t");
}
mio_logbfmt (mio, MIO_LOG_STDOUT, "true");
break; break;
case MIO_JSON_INST_FALSE: case MIO_JSON_INST_FALSE:
mio_logbfmt (mio, MIO_LOG_STDOUT, "false\n"); if (level > 0)
{
if (index > 0) mio_logbfmt (mio, MIO_LOG_STDOUT, ",\n");
for (i = 0; i < level; i++) mio_logbfmt (mio, MIO_LOG_STDOUT, "\t");
}
mio_logbfmt (mio, MIO_LOG_STDOUT, "false");
break; break;
case MIO_JSON_INST_NUMBER: case MIO_JSON_INST_NUMBER:
mio_logbfmt (mio, MIO_LOG_STDOUT, "%.*js\n", str->len, str->ptr); if (level > 0)
{
if (index > 0) mio_logbfmt (mio, MIO_LOG_STDOUT, ",\n");
for (i = 0; i < level; i++) mio_logbfmt (mio, MIO_LOG_STDOUT, "\t");
}
mio_logbfmt (mio, MIO_LOG_STDOUT, "%.*js", str->len, str->ptr);
break; break;
case MIO_JSON_INST_STRING: case MIO_JSON_INST_STRING:
mio_logbfmt (mio, MIO_LOG_STDOUT, "\"%.*js\"\n", str->len, str->ptr); /* TODO: escaping */ if (level > 0)
{
if (index > 0) mio_logbfmt (mio, MIO_LOG_STDOUT, ",\n");
for (i = 0; i < level; i++) mio_logbfmt (mio, MIO_LOG_STDOUT, "\t");
}
mio_logbfmt (mio, MIO_LOG_STDOUT, "\"%.*js\"", str->len, str->ptr); /* TODO: escaping */
break; break;
default: default:
@ -135,6 +172,7 @@ int main (int argc, char* argv[])
if (rem > 0) memcpy (buf, &buf[size - rem], rem); if (rem > 0) memcpy (buf, &buf[size - rem], rem);
} }
mio_logbfmt (mio, MIO_LOG_STDOUT, "\n");
mio_json_close (json); mio_json_close (json);
} }

View File

@ -108,6 +108,7 @@ static int push_read_state (mio_json_t* json, mio_json_state_t state)
ss->state = state; ss->state = state;
ss->level = json->state_stack->level; /* copy from the parent */ ss->level = json->state_stack->level; /* copy from the parent */
ss->index = 0;
ss->next = json->state_stack; ss->next = json->state_stack;
json->state_stack = ss; json->state_stack = ss;
@ -144,18 +145,53 @@ static void pop_all_read_states (mio_json_t* json)
static int invoke_data_inst (mio_json_t* json, mio_json_inst_t inst) static int invoke_data_inst (mio_json_t* json, mio_json_inst_t inst)
{ {
if (json->state_stack->state == MIO_JSON_STATE_IN_DIC && json->state_stack->u.id.state == 1) mio_json_state_node_t* ss;
{ int is_dic_val = 0;
if (inst != MIO_JSON_INST_STRING)
{
mio_seterrbfmt (json->mio, MIO_EINVAL, "dictionary key not a string - %.*js", json->tok.len, json->tok.ptr);
return -1;
}
inst = MIO_JSON_INST_KEY; ss = json->state_stack;
if (ss->state == MIO_JSON_STATE_IN_DIC)
{
if (ss->u.id.state == 1) /* got colon */
{
/* this is called after the reader has seen a colon.
* the data item must be used as a key */
if (inst != MIO_JSON_INST_STRING)
{
mio_seterrbfmt (json->mio, MIO_EINVAL, "dictionary key not a string - %.*js", json->tok.len, json->tok.ptr);
return -1;
}
inst = MIO_JSON_INST_KEY;
}
else
{
/* if this variable is non-zero, level is set to 0 regardless of actual level */
is_dic_val = 1;
}
} }
return json->instcb(json, inst, json->state_stack->level, &json->tok, json->rctx); switch (inst)
{
case MIO_JSON_INST_START_ARRAY:
if (push_read_state(json, MIO_JSON_STATE_IN_ARRAY) <= -1) return -1;
json->state_stack->u.ia.got_value = 0;
json->state_stack->level++;
if (ss->state != MIO_JSON_STATE_IN_DIC || ss->u.id.state == 1) ss->index++;
return json->instcb(json, inst, (is_dic_val? 0: json->state_stack->level - 1), ss->index - 1, MIO_NULL, json->rctx);
case MIO_JSON_INST_START_DIC:
if (push_read_state(json, MIO_JSON_STATE_IN_DIC) <= -1) return -1;
json->state_stack->u.id.state = 0;
json->state_stack->level++;
if (ss->state != MIO_JSON_STATE_IN_DIC || ss->u.id.state == 1) ss->index++;
return json->instcb(json, inst, (is_dic_val? 0: json->state_stack->level - 1), ss->index - 1, MIO_NULL, json->rctx);
default:
if (ss->state != MIO_JSON_STATE_IN_DIC || ss->u.id.state == 1) ss->index++;
return json->instcb(json, inst, (is_dic_val? 0: json->state_stack->level), ss->index - 1, &json->tok, json->rctx);
}
} }
static int handle_string_value_char (mio_json_t* json, mio_ooci_t c) static int handle_string_value_char (mio_json_t* json, mio_ooci_t c)
@ -331,21 +367,14 @@ static int handle_word_value_char (mio_json_t* json, mio_ooci_t c)
static int handle_start_char (mio_json_t* json, mio_ooci_t c) static int handle_start_char (mio_json_t* json, mio_ooci_t c)
{ {
printf ("HANDLE START CHAR [%c]\n", c);
if (c == '[') if (c == '[')
{ {
if (push_read_state(json, MIO_JSON_STATE_IN_ARRAY) <= -1) return -1; if (invoke_data_inst(json, MIO_JSON_INST_START_ARRAY) <= -1) return -1;
json->state_stack->u.ia.got_value = 0;
if (json->instcb(json, MIO_JSON_INST_START_ARRAY, json->state_stack->level, MIO_NULL, json->rctx) <= -1) return -1;
json->state_stack->level++;
return 1; return 1;
} }
else if (c == '{') else if (c == '{')
{ {
if (push_read_state(json, MIO_JSON_STATE_IN_DIC) <= -1) return -1; if (invoke_data_inst(json, MIO_JSON_INST_START_DIC) <= -1) return -1;
json->state_stack->u.id.state = 0;
if (json->instcb(json, MIO_JSON_INST_START_DIC, json->state_stack->level, MIO_NULL, json->rctx) <= -1) return -1;
json->state_stack->level++;
return 1; return 1;
} }
#if 0 #if 0
@ -367,7 +396,7 @@ static int handle_char_in_array (mio_json_t* json, mio_ooci_t c)
{ {
if (c == ']') if (c == ']')
{ {
if (json->instcb(json, MIO_JSON_INST_END_ARRAY, json->state_stack->level - 1, MIO_NULL, json->rctx) <= -1) return -1; if (json->instcb(json, MIO_JSON_INST_END_ARRAY, json->state_stack->level - 1, json->state_stack->index, MIO_NULL, json->rctx) <= -1) return -1;
pop_read_state (json); pop_read_state (json);
return 1; return 1;
} }
@ -417,18 +446,12 @@ static int handle_char_in_array (mio_json_t* json, mio_ooci_t c)
} }
else if (c == '[') else if (c == '[')
{ {
if (push_read_state(json, MIO_JSON_STATE_IN_ARRAY) <= -1) return -1; if (invoke_data_inst(json, MIO_JSON_INST_START_ARRAY) <= -1) return -1;
json->state_stack->u.ia.got_value = 0;
if (json->instcb(json, MIO_JSON_INST_START_ARRAY, json->state_stack->level, MIO_NULL, json->rctx) <= -1) return -1;
json->state_stack->level++;
return 1; return 1;
} }
else if (c == '{') else if (c == '{')
{ {
if (push_read_state(json, MIO_JSON_STATE_IN_DIC) <= -1) return -1; if (invoke_data_inst(json, MIO_JSON_INST_START_DIC) <= -1) return -1;
json->state_stack->u.id.state = 0;
if (json->instcb(json, MIO_JSON_INST_START_DIC, json->state_stack->level, MIO_NULL, json->rctx) <= -1) return -1;
json->state_stack->level++;
return 1; return 1;
} }
else else
@ -443,7 +466,7 @@ static int handle_char_in_dic (mio_json_t* json, mio_ooci_t c)
{ {
if (c == '}') if (c == '}')
{ {
if (json->instcb(json, MIO_JSON_INST_END_DIC, json->state_stack->level - 1, MIO_NULL, json->rctx) <= -1) return -1; if (json->instcb(json, MIO_JSON_INST_END_DIC, json->state_stack->level - 1, json->state_stack->index, MIO_NULL, json->rctx) <= -1) return -1;
pop_read_state (json); pop_read_state (json);
return 1; return 1;
} }
@ -508,18 +531,12 @@ static int handle_char_in_dic (mio_json_t* json, mio_ooci_t c)
} }
else if (c == '[') else if (c == '[')
{ {
if (push_read_state(json, MIO_JSON_STATE_IN_ARRAY) <= -1) return -1; if (invoke_data_inst(json, MIO_JSON_INST_START_ARRAY) <= -1) return -1;
json->state_stack->u.ia.got_value = 0;
json->state_stack->level++;
if (json->instcb(json, MIO_JSON_INST_START_ARRAY, json->state_stack->level, MIO_NULL, json->rctx) <= -1) return -1;
return 1; return 1;
} }
else if (c == '{') else if (c == '{')
{ {
if (push_read_state(json, MIO_JSON_STATE_IN_DIC) <= -1) return -1; if (invoke_data_inst(json, MIO_JSON_INST_START_DIC) <= -1) return -1;
json->state_stack->u.id.state = 0;
json->state_stack->level++;
if (json->instcb(json, MIO_JSON_INST_START_DIC, json->state_stack->level, MIO_NULL, json->rctx) <= -1) return -1;
return 1; return 1;
} }
else else

View File

@ -70,6 +70,7 @@ typedef int (*mio_json_instcb_t) (
mio_json_t* json, mio_json_t* json,
mio_json_inst_t inst, mio_json_inst_t inst,
mio_oow_t level, mio_oow_t level,
mio_oow_t index,
const mio_oocs_t* str, const mio_oocs_t* str,
void* ctx void* ctx
); );
@ -80,6 +81,7 @@ struct mio_json_state_node_t
{ {
mio_json_state_t state; mio_json_state_t state;
mio_oow_t level; mio_oow_t level;
mio_oow_t index;
union union
{ {
struct struct