Skip to content

Commit

Permalink
ejson 0.9.3: update valk found logic
Browse files Browse the repository at this point in the history
  • Loading branch information
ziyht committed Apr 14, 2019
1 parent 5177e7b commit 61126ea
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 75 deletions.
88 changes: 15 additions & 73 deletions src/libs/etools/ejson.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
#define _CRT_SECURE_NO_WARNINGS
#endif

#define EJSON_VERSION "ejson 0.9.2" // fix bugs of ejson_take
#define EJSON_VERSION "ejson 0.9.3" // update valk found logic

#include <stdio.h>
#include <stdlib.h>
Expand Down Expand Up @@ -302,9 +302,6 @@ static eobj __objByKeys(_ejsr r, constr keys_, bool raw, bool rm)
#define _getObjByRawk(r, rawk) __objByRawk(r, rawk, 0)
#define _rmObjByRawk( r, rawk) __objByRawk(r, rawk, 1)

static __always_inline cstr split (cstr key, char c) { cstr p = strchr(key, c); is1_elsret(p, *p = '\0';return p + 1;, NULL); }
static __always_inline cstr splitdot(cstr key ) { cstr p = strchr(key, '.'); is1_elsret(p, *p = '\0';return p + 1;, NULL); }

static eobj __objByRawk(_ejsr r, constr keys_, bool rm)
{
_ejsn n;
Expand All @@ -316,7 +313,7 @@ static eobj __objByRawk(_ejsr r, constr keys_, bool rm)
return _n_o(n);
}

int __getAKey(constr p, cstr key, constr* _p)
static __always_inline int __getAKey(constr p, cstr key, constr* _p)
{
int i = 0;

Expand Down Expand Up @@ -357,11 +354,10 @@ int __getAKey(constr p, cstr key, constr* _p)

key[i] = '\0';


return i;
}

static eobj __objByKeys2(_ejsr r, constr keys_, bool rm)
static eobj __objByKeys(_ejsr r, constr keys_, bool rm)
{
char key[256]; constr p; int len; int id;

Expand All @@ -383,20 +379,24 @@ static eobj __objByKeys2(_ejsr r, constr keys_, bool rm)

switch (_r_typeo(r))
{
case EOBJ: n = _obj_find(r, key, len);

is0_ret(n, 0);

case EOBJ: is0_ret(n = _obj_find(r, key, len), 0);
break;

case EARR: {
cstr endp;

case EARR: id = atoi(key);
is1_ret(len == 0, 0);

n = _arr_find(r, id);
id = strtol(key, &endp, 10);

is0_ret(n, 0);
//! must parse over then is a valid number
if(*endp)
return 0;
}

break;
is0_ret(n = _arr_find(r, id), 0);

break;
}

}while(*p);
Expand All @@ -409,64 +409,6 @@ static eobj __objByKeys2(_ejsr r, constr keys_, bool rm)
return _n_o(n);
}

static eobj __objByKeys(_ejsr r, constr keys_, bool rm)
{
char keys[512]; cstr fk, sk, last_fk; // first key, second key, last first key
_ejsn n;
cstr _idx; uint idx;

is1_ret(!_r_o(r) || _r_typec(r) != EJSON, 0);

strncpy(keys, keys_, 512);
fk = keys;
sk = splitdot(fk);

do{
_idx = split(fk, '[');

if(*fk)
{
n = _obj_find(r, fk, strlen(fk));
is0_exeret(n, eerrfmt("can not find %s in %s", fk, fk == keys ? "." : keys), NULL); // not found, return
}
else
n = (_ejsn)r;

while( _idx )
{
is0_exeret(_n_typeo(n) == EARR, eerrfmt("%s is %s obj", keys, __eobj_typeS(_n_o(n), true));, NULL);

*(_idx - 1) = '['; // restore
is1_exeret(*_idx < '0' || *_idx > '9', eerrfmt("invalid keys: %s", keys), NULL);

idx = atoi(_idx);
_idx = split(_idx, '[');

r = (_ejsr)n;
n = _arr_find(r, idx);
is0_exeret(n, eerrfmt("can not find %s in %s", fk, fk == keys ? "." : keys), NULL);
}

is0_exeret(n, eerrfmt("can not find %s in %s", fk, fk == keys ? "." : keys), NULL); // not found, return

// -- found and return it
is0_exeret(sk, is1_exeret(rm, switch (_r_typeo(r)) {
case EOBJ: _obj_takeN(r, n); break;
case EARR: _arr_takeN(r, n); break;
default : return 0; }, _n_o(n)), _n_o(n));

r = (_ejsr)n;
last_fk = fk;
fk = sk;
sk = splitdot(fk);
if(last_fk != keys) *(last_fk - 1) = '.';
}while(_n_typeo(r) == EOBJ);

eerrfmt("%s is %s obj", keys, __eobj_typeS(_n_o(n), true));

return 0;
}

#endif
/// -------------------- str strip helper -------------------------

Expand Down
15 changes: 13 additions & 2 deletions src/libs/etools/ejson.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,8 @@ eobj ejson_addkO(eobj r, constr keys, constr key, eobj o ); // add an exis
* can not be splited
*
* 2. for k APIs, we consider keys as a continues key
* chan like "fruits[0].name", then we will found the first
* obj in arr 'fruits' and the the obj 'name' of it.
* chan like "fruits[0].name", then we will found: 'fruits'
* -> '0' -> 'name'.
*
* {
* "fruits[0].name" : "tomato",
Expand All @@ -130,6 +130,17 @@ eobj ejson_addkO(eobj r, constr keys, constr key, eobj o ); // add an exis
* ^---------------------------------- k found this
* }
*
* 3. for k APIs, you can split a key with '.' or '[]',
* they are simply the same:
*
* fruits[0].name : fruits -> 0 -> name
* fruits.0[name] : fruits -> 0 -> name
* fruits.0.[name] : fruits -> 0 -> "" -> name
*
* 4. for k APIs, the key in '[]' can not be split again
*
* fruits[0.name] : fruits -> 0.name
*
* -----------------------------------------------------
*/
eobj ejson_valr (eobj r, constr rawk); // Returns the eobj with the specific rawk
Expand Down
18 changes: 18 additions & 0 deletions src/libs/etools/testing/ejson/t4_valk.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,24 @@ static int t4_valk_case2()
e = ejson_valk(r, "[0].2.3[0][1]" ); eunexpc_ptr(e, 0); eexpect_num(ejson_type(e), EOBJ);
e = ejson_valk(r, "[0].2.3[0][1].4" ); eunexpc_ptr(e, 0); eexpect_num(ejson_type(e), ESTR);

e = ejson_valk(r, "0" ); eunexpc_ptr(e, 0); eexpect_num(ejson_type(e), EOBJ);
e = ejson_valk(r, "0.2" ); eunexpc_ptr(e, 0); eexpect_num(ejson_type(e), EOBJ);
e = ejson_valk(r, "0.2.3" ); eunexpc_ptr(e, 0); eexpect_num(ejson_type(e), EARR);
e = ejson_valk(r, "0.2.3.0" ); eunexpc_ptr(e, 0); eexpect_num(ejson_type(e), EARR);
e = ejson_valk(r, "0.2.3.0.0" ); eunexpc_ptr(e, 0); eexpect_num(ejson_type(e), EARR);
e = ejson_valk(r, "0.2.3.0.0.0" ); eunexpc_ptr(e, 0); eexpect_num(ejson_type(e), ESTR);
e = ejson_valk(r, "0.2.3.0.1" ); eunexpc_ptr(e, 0); eexpect_num(ejson_type(e), EOBJ);
e = ejson_valk(r, "0.2.3.0.1.4" ); eunexpc_ptr(e, 0); eexpect_num(ejson_type(e), ESTR);

e = ejson_valk(r, "[0]" ); eunexpc_ptr(e, 0); eexpect_num(ejson_type(e), EOBJ);
e = ejson_valk(r, "[0][2]" ); eunexpc_ptr(e, 0); eexpect_num(ejson_type(e), EOBJ);
e = ejson_valk(r, "[0][2][3]" ); eunexpc_ptr(e, 0); eexpect_num(ejson_type(e), EARR);
e = ejson_valk(r, "[0][2][3][0]" ); eunexpc_ptr(e, 0); eexpect_num(ejson_type(e), EARR);
e = ejson_valk(r, "[0][2][3][0][0]" ); eunexpc_ptr(e, 0); eexpect_num(ejson_type(e), EARR);
e = ejson_valk(r, "[0][2][3][0][0][0]"); eunexpc_ptr(e, 0); eexpect_num(ejson_type(e), ESTR);
e = ejson_valk(r, "[0][2][3][0][1]" ); eunexpc_ptr(e, 0); eexpect_num(ejson_type(e), EOBJ);
e = ejson_valk(r, "[0][2][3][0][1][4]"); eunexpc_ptr(e, 0); eexpect_num(ejson_type(e), ESTR);

ejson_free(r);

return ETEST_OK;
Expand Down

0 comments on commit 61126ea

Please sign in to comment.