added the new option MIO_JSON_PERMITWORDKEY

This commit is contained in:
hyung-hwan 2021-07-14 05:18:19 +00:00
parent d6b196fbf1
commit 72422be8b8
8 changed files with 77 additions and 22 deletions

View File

@ -114,6 +114,13 @@ static int write_json_element (mio_jsonwr_t* jsonwr, const mio_bch_t* dptr, mio_
int main (int argc, char* argv[])
{
mio_t* mio = MIO_NULL;
mio_bitmask_t o = 0;
int i;
for (i = 1; i < argc; i++)
{
if (strcmp(argv[i], "--permit-word-key") == 0) o |= MIO_JSON_PERMITWORDKEY;
}
mio = mio_open(MIO_NULL, 0, MIO_NULL, 512, MIO_NULL);
if (!mio)
@ -131,6 +138,7 @@ int main (int argc, char* argv[])
json = mio_json_open(mio, 0);
mio_json_setoption (json, o);
mio_json_setinstcb (json, on_json_inst, &pending);
rem = 0;
@ -152,7 +160,7 @@ int main (int argc, char* argv[])
if ((x = mio_json_feed(json, buf, size + rem, &rem, 1)) <= -1)
{
mio_logbfmt (mio, MIO_LOG_STDOUT, "**** ERROR - %js ****\n", mio_geterrmsg(mio));
break;
goto done;
}
if (x > 0)
@ -167,7 +175,10 @@ int main (int argc, char* argv[])
}
mio_logbfmt (mio, MIO_LOG_STDOUT, "\n");
if (pending) mio_logbfmt (mio, MIO_LOG_STDOUT, "**** ERROR - incomplete ****\n");
//if (pending) mio_logbfmt (mio, MIO_LOG_STDOUT, "**** ERROR - incomplete ****\n");
if (json->state_stack != &json->state_top) mio_logbfmt (mio, MIO_LOG_STDOUT, "**** ERROR - incomplete ****\n");
done:
mio_json_close (json);
}

View File

@ -434,14 +434,14 @@ mio_htrd_errnum_t mio_htrd_geterrnum (mio_htrd_t* htrd)
return htrd->errnum;
}
int mio_htrd_getopt (mio_htrd_t* htrd)
mio_bitmask_t mio_htrd_getoption (mio_htrd_t* htrd)
{
return htrd->option;
}
void mio_htrd_setopt (mio_htrd_t* htrd, int opts)
void mio_htrd_setoption (mio_htrd_t* htrd, mio_bitmask_t mask)
{
htrd->option = opts;
htrd->option = mask;
}
const mio_htrd_recbs_t* mio_htrd_getrecbs (mio_htrd_t* htrd)

View File

@ -963,7 +963,7 @@ int mio_svc_htts_docgi (mio_svc_htts_t* htts, mio_dev_sck_t* csck, mio_htre_t* r
cgi->peer_htrd = mio_htrd_open(mio, MIO_SIZEOF(*cgi_peer));
if (MIO_UNLIKELY(!cgi->peer_htrd)) goto oops;
mio_htrd_setopt (cgi->peer_htrd, MIO_HTRD_SKIPINITIALLINE | MIO_HTRD_RESPONSE);
mio_htrd_setoption (cgi->peer_htrd, MIO_HTRD_SKIPINITIALLINE | MIO_HTRD_RESPONSE);
mio_htrd_setrecbs (cgi->peer_htrd, &cgi_peer_htrd_recbs);
cgi_peer = mio_htrd_getxtn(cgi->peer_htrd);

View File

@ -64,7 +64,7 @@ static int init_client (mio_svc_htts_cli_t* cli, mio_dev_sck_t* sck)
/* With MIO_HTRD_TRAILERS, htrd stores trailers in a separate place.
* Otherwise, it is merged to the headers. */
/*mio_htrd_setopt (cli->htrd, MIO_HTRD_REQUEST | MIO_HTRD_TRAILERS);*/
/*mio_htrd_setoption (cli->htrd, MIO_HTRD_REQUEST | MIO_HTRD_TRAILERS);*/
cli->sbuf = mio_becs_open(sck->mio, 0, 2048);
if (MIO_UNLIKELY(!cli->sbuf)) goto oops;

View File

@ -889,7 +889,7 @@ int mio_svc_htts_dothr (mio_svc_htts_t* htts, mio_dev_sck_t* csck, mio_htre_t* r
thr_state->peer_htrd = mio_htrd_open(mio, MIO_SIZEOF(*thr_peer));
if (MIO_UNLIKELY(!thr_state->peer_htrd)) goto oops;
mio_htrd_setopt (thr_state->peer_htrd, MIO_HTRD_SKIPINITIALLINE | MIO_HTRD_RESPONSE);
mio_htrd_setoption (thr_state->peer_htrd, MIO_HTRD_SKIPINITIALLINE | MIO_HTRD_RESPONSE);
mio_htrd_setrecbs (thr_state->peer_htrd, &thr_peer_htrd_recbs);
thr_peer = mio_htrd_getxtn(thr_state->peer_htrd);

View File

@ -31,6 +31,9 @@
#define MIO_JSON_TOKEN_NAME_ALIGN 64
/* this must not overlap with MIO_JSON_INST_XXXX enumerators in mio-json.h */
#define __INST_WORD_STRING 9999
/* ========================================================================= */
static void clear_token (mio_json_t* json)
@ -178,7 +181,7 @@ static int invoke_data_inst (mio_json_t* json, mio_json_inst_t inst)
/* 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)
if (inst != MIO_JSON_INST_STRING && inst != __INST_WORD_STRING)
{
mio_seterrbfmt (json->mio, MIO_EINVAL, "object key not a string - %.*js", json->tok.len, json->tok.ptr);
return -1;
@ -193,6 +196,12 @@ static int invoke_data_inst (mio_json_t* json, mio_json_inst_t inst)
}
}
if (inst == __INST_WORD_STRING)
{
mio_seterrbfmt (json->mio, MIO_EINVAL, "invalid word value - %.*js", json->tok.len, json->tok.ptr);
return -1;
}
switch (inst)
{
case MIO_JSON_INST_START_ARRAY:
@ -392,8 +401,12 @@ static int handle_numeric_value_char (mio_json_t* json, mio_ooci_t c)
static int handle_word_value_char (mio_json_t* json, mio_ooci_t c)
{
mio_json_inst_t inst;
int ok;
if (mio_is_ooch_alpha(c))
ok = (json->option & MIO_JSON_PERMITWORDKEY)?
(mio_is_ooch_alpha(c) || mio_is_ooch_digit(c) || c == '_'):
mio_is_ooch_alpha(c);
if (ok)
{
if (add_char_to_token(json, c, 0) <= -1) return -1;
return 1;
@ -404,6 +417,7 @@ static int handle_word_value_char (mio_json_t* json, mio_ooci_t c)
if (mio_comp_oochars_bcstr(json->tok.ptr, json->tok.len, "null", 0) == 0) inst = MIO_JSON_INST_NIL;
else if (mio_comp_oochars_bcstr(json->tok.ptr, json->tok.len, "true", 0) == 0) inst = MIO_JSON_INST_TRUE;
else if (mio_comp_oochars_bcstr(json->tok.ptr, json->tok.len, "false", 0) == 0) inst = MIO_JSON_INST_FALSE;
else if (json->option & MIO_JSON_PERMITWORDKEY) inst = __INST_WORD_STRING; /* internal only */
else
{
mio_seterrbfmt (json->mio, MIO_EINVAL, "invalid word value - %.*js", json->tok.len, json->tok.ptr);
@ -801,6 +815,16 @@ void mio_json_fini (mio_json_t* json)
}
/* ========================================================================= */
mio_bitmask_t mio_json_getoption (mio_json_t* json)
{
return json->option;
}
void mio_json_setoption (mio_json_t* json, mio_bitmask_t mask)
{
json->option = mask;
}
void mio_json_setinstcb (mio_json_t* json, mio_json_instcb_t instcb, void* ctx)
{
json->instcb = instcb;

View File

@ -52,13 +52,13 @@ typedef enum mio_htrd_errnum_t mio_htrd_errnum_t;
*/
enum mio_htrd_option_t
{
MIO_HTRD_SKIPEMPTYLINES = (1 << 0), /**< skip leading empty lines before the initial line */
MIO_HTRD_SKIPINITIALLINE = (1 << 1), /**< skip processing an initial line */
MIO_HTRD_CANONQPATH = (1 << 2), /**< canonicalize the query path */
MIO_HTRD_REQUEST = (1 << 3), /**< parse input as a request */
MIO_HTRD_RESPONSE = (1 << 4), /**< parse input as a response */
MIO_HTRD_TRAILERS = (1 << 5), /**< store trailers in a separate table */
MIO_HTRD_STRICT = (1 << 6) /**< be more picky */
MIO_HTRD_SKIPEMPTYLINES = ((mio_bitmask_t)1 << 0), /**< skip leading empty lines before the initial line */
MIO_HTRD_SKIPINITIALLINE = ((mio_bitmask_t)1 << 1), /**< skip processing an initial line */
MIO_HTRD_CANONQPATH = ((mio_bitmask_t)1 << 2), /**< canonicalize the query path */
MIO_HTRD_REQUEST = ((mio_bitmask_t)1 << 3), /**< parse input as a request */
MIO_HTRD_RESPONSE = ((mio_bitmask_t)1 << 4), /**< parse input as a response */
MIO_HTRD_TRAILERS = ((mio_bitmask_t)1 << 5), /**< store trailers in a separate table */
MIO_HTRD_STRICT = ((mio_bitmask_t)1 << 6) /**< be more picky */
};
typedef enum mio_htrd_option_t mio_htrd_option_t;
@ -76,7 +76,7 @@ struct mio_htrd_t
{
mio_t* mio;
mio_htrd_errnum_t errnum;
int option;
mio_bitmask_t option;
int flags;
mio_htrd_recbs_t recbs;
@ -153,13 +153,13 @@ MIO_EXPORT void mio_htrd_clear (
mio_htrd_t* htrd
);
MIO_EXPORT int mio_htrd_getopt (
MIO_EXPORT mio_bitmask_t mio_htrd_getoption (
mio_htrd_t* htrd
);
MIO_EXPORT void mio_htrd_setopt (
mio_htrd_t* htrd,
int opts
MIO_EXPORT void mio_htrd_setoption (
mio_htrd_t* htrd,
mio_bitmask_t mask
);
MIO_EXPORT const mio_htrd_recbs_t* mio_htrd_getrecbs (

View File

@ -120,16 +120,27 @@ struct mio_json_state_node_t
mio_json_state_node_t* next;
};
enum mio_json_option_t
{
/* allow an unquoted word as an object key */
MIO_JSON_PERMITWORDKEY = ((mio_bitmask_t)1 << 0),
};
typedef enum mio_json_option_t mio_json_option_t;
struct mio_json_t
{
mio_t* mio;
mio_json_instcb_t instcb;
void* rctx;
mio_bitmask_t option;
mio_json_state_node_t state_top;
mio_json_state_node_t* state_stack;
mio_oocs_t tok;
mio_oow_t tok_capa;
};
/* ========================================================================= */
@ -208,6 +219,15 @@ static MIO_INLINE void* mio_json_getxtn (mio_json_t* json) { return (void*)(json
#define mio_json_getxtn(json) ((void*)((mio_json_t*)(json) + 1))
#endif
MIO_EXPORT mio_bitmask_t mio_json_getoption (
mio_json_t* json
);
MIO_EXPORT void mio_json_setoption (
mio_json_t* json,
mio_bitmask_t mask
);
MIO_EXPORT void mio_json_setinstcb (
mio_json_t* json,
mio_json_instcb_t instcb,