diff --git a/src/json/tld-json.c b/src/json/tld-json.c index 0aefa4e..82327d3 100644 --- a/src/json/tld-json.c +++ b/src/json/tld-json.c @@ -9,8 +9,9 @@ #define TLD_JSON_IMPORT #include "tld-json.h" - -static int tld_json_get_arr_str(tld_json_arr *n, char *key, tld_strbuf *res); +static int tld_json_get_ret_val(tld_json_val *v, tld_json_ret **ret); +static int tld_json_get_arr_str(tld_json_arr *n, char *key, tld_json_ret** res); +/* static int tld_json_get_arr_str(tld_json_arr *n, char *key, tld_strbuf *res); */ static int tld_json_parse_obj(tld_json_arr *lex, tld_json_obj **out); static int tld_json_parse_arr(tld_json_arr *lex, tld_json_arr **out); static int tld_json_lex(tld_strbuf *t, tld_json_arr **out); @@ -22,46 +23,103 @@ int print_arr(tld_json_arr* n); /* static int tld_json_parse_arr(tld_json_arr *lex, tld_json_arr **out); */ /* static int tld_json_parse_node(tld_json_arr *lex,tld_json_obj** out); */ -int tld_json_obj_get_str(tld_json_obj *n, char *key, tld_strbuf* res) +int tld_json_obj_get(tld_json_obj *n, char *key, tld_json_ret **ret) { - if(n){ for(int i = 0; i < n->n;i++){ + if(strncmp((char*)n->key[i]->str, key, n->key[i]->len)==0){ - if(n->v[i]->type == TLD_JSON_STR){ - /* fprintf(stdout, "%d %s key: %s\n",i ,TLD_STR(n->key[i]),key); */ - tld_append(res, TLD_STR( n->v[i]->value.str)); - } + RUN(tld_json_get_ret_val(n->v[i], ret)); + break; } if(n->v[i]->type == TLD_JSON_ARR){ - if(!TLD_STRLEN(res)){ - tld_json_get_arr_str(n->v[i]->value.arr,key,res); - } + + tld_json_get_arr_str(n->v[i]->value.arr,key,ret); + }else if(n->v[i]->type == TLD_JSON_OBJ){ - if(!TLD_STRLEN(res)){ - tld_json_obj_get_str(n->v[i]->value.obj, key,res); - } + + tld_json_obj_get(n->v[i]->value.obj, key,ret); + } } } return OK; -/* ERROR: */ -/* return FAIL; */ +ERROR: + return FAIL; } -int tld_json_get_arr_str(tld_json_arr *n, char *key, tld_strbuf* res) +/* int tld_json_obj_get_str(tld_json_obj *n, char *key, tld_strbuf* res) */ +/* { */ +/* if(n){ */ +/* for(int i = 0; i < n->n;i++){ */ +/* LOG_MSG("%s %d --- in get %s", TLD_STR(n->key[i]),n->key[i]->len,key); */ +/* if(strncmp((char*)n->key[i]->str, key, n->key[i]->len)==0){ */ +/* LOG_MSG("FOUNE!!!! type: %d", n->v[i]->type); */ +/* if(n->v[i]->type == TLD_JSON_STR){ */ +/* /\* fprintf(stdout, "%d %s key: %s\n",i ,TLD_STR(n->key[i]),key); *\/ */ +/* tld_append(res, TLD_STR( n->v[i]->value.str)); */ +/* }else if(n->v[i]->type == TLD_JSON_ARR){ */ +/* tld_json_arr *arr = n->v[i]->value.arr; */ +/* LOG_MSG("num entries: %d",arr->n); */ +/* for(int j = 0; j < arr->n;j++){ */ +/* switch (arr->v[j]->type) { */ +/* case TLD_JSON_BOOL_TRUE: */ +/* fprintf(stdout,"true\n" ); */ +/* break; */ +/* case TLD_JSON_BOOL_FALSE: */ +/* fprintf(stdout,"false\n" ); */ +/* break; */ +/* case TLD_JSON_INT: */ +/* fprintf(stdout,"%d\n",arr->v[j]->value.i_num ); */ +/* break; */ +/* case TLD_JSON_DBL: */ +/* fprintf(stdout,"%f\n",arr->v[j]->value.d_num ); */ +/* break; */ +/* case TLD_JSON_OBJ: */ +/* case TLD_JSON_ARR: */ +/* case TLD_JSON_STR: */ +/* case TLD_JSON_UNDEF: */ +/* LOG_MSG("Dunno what to do!"); */ +/* break; */ +/* } */ + + + + +/* } */ +/* /\* n->v[i]->value *\/ */ +/* }else{ */ +/* LOG_MSG("Got a different value %d !",n->v[i]->type); */ +/* } */ +/* } */ +/* if(n->v[i]->type == TLD_JSON_ARR){ */ +/* if(!TLD_STRLEN(res)){ */ +/* tld_json_get_arr_str(n->v[i]->value.arr,key,res); */ +/* } */ +/* }else if(n->v[i]->type == TLD_JSON_OBJ){ */ +/* if(!TLD_STRLEN(res)){ */ +/* tld_json_obj_get_str(n->v[i]->value.obj, key,res); */ +/* } */ +/* } */ +/* } */ +/* } */ + +/* return OK; */ +/* /\* ERROR: *\/ */ +/* /\* return FAIL; *\/ */ +/* } */ + +int tld_json_get_arr_str(tld_json_arr *n, char *key, tld_json_ret** res) { if(n){ for(int i = 0; i < n->n;i++){ if(n->v[i]->type == TLD_JSON_ARR){ - if(!TLD_STRLEN(res)){ - tld_json_get_arr_str(n->v[i]->value.arr,key,res); - } + + tld_json_get_arr_str(n->v[i]->value.arr,key,res); }else if(n->v[i]->type == TLD_JSON_OBJ){ - if(!TLD_STRLEN(res)){ - tld_json_obj_get_str(n->v[i]->value.obj, key,res); - } + tld_json_obj_get(n->v[i]->value.obj, key,res); + } } @@ -75,7 +133,7 @@ int tld_json_parse(tld_strbuf *t, tld_json_obj **out) tld_json_val* tok = NULL; tld_json_obj* n = NULL; tld_json_lex(t, &lex); - /* print_arr(lex); */ + print_arr(lex); tok = lex->v[lex->read_head]; lex->read_head++; @@ -109,6 +167,7 @@ static int tld_json_parse_obj(tld_json_arr *lex, tld_json_obj **out) tld_json_val* tok = NULL; tld_json_obj* n = NULL; + RUN(tld_json_obj_alloc(&n)); tok = lex->v[lex->read_head]; @@ -145,6 +204,7 @@ static int tld_json_parse_obj(tld_json_arr *lex, tld_json_obj **out) lex->read_head++; if(is_open_arr(val)){ /* do array strugg */ + tld_append(n->key[n->n], TLD_STR(key->value.str)); n->v[n->n]->type = TLD_JSON_ARR; RUN(tld_json_parse_arr(lex, &n->v[n->n]->value.arr)); n->n++; @@ -394,6 +454,7 @@ int tld_json_obj_print(tld_json_obj *n, FILE *out) if(n){ fprintf(out,"Object:\n"); for(int i = 0; i < n->n;i++){ + fprintf(out,"NAME: %s\n",TLD_STR(n->key[i])); if(n->v[i]->type == TLD_JSON_ARR){ tld_json_arr_print(n->v[i]->value.arr, out); }else if(n->v[i]->type == TLD_JSON_OBJ){ @@ -622,3 +683,142 @@ int tld_json_val_copy(tld_json_val *t, tld_json_val *s) return FAIL; } +int tld_json_get_ret_val(tld_json_val* v, tld_json_ret **ret) +{ + tld_json_ret* r = NULL; + tld_json_arr *arr = NULL; + int max; + int max_idx; + int n_elem = 0; + int type[8]; + RUN(tld_json_ret_alloc(&r)); + switch (v->type) { + case TLD_JSON_OBJ: + + case TLD_JSON_STR: + r->type = TLD_JSON_RET_STR; + tld_strbuf_alloc(&r->value.string,16); + tld_append(r->value.string, TLD_STR(v->value.str)); + break; + case TLD_JSON_DBL: + r->type = TLD_JSON_RET_DBL; + r->value.d_num = v->value.d_num; + break; + case TLD_JSON_INT: + r->type = TLD_JSON_RET_INT; + r->value.d_num = v->value.i_num; + break; + case TLD_JSON_BOOL_TRUE: + r->type = TLD_JSON_RET_BOOL; + r->value.b_num = 1; + break; + case TLD_JSON_BOOL_FALSE: + r->type = TLD_JSON_RET_BOOL; + r->value.b_num = 0; + break; + case TLD_JSON_UNDEF: + ERROR_MSG("Node has no type!"); + break; + case TLD_JSON_ARR: + arr = v->value.arr; + n_elem = arr->n; + r->n = n_elem; + r->n_alloc = n_elem; + for(int i = 0; i < 8;i++){ + type[i] = 0; + } + for(int i = 0; i < n_elem;i++){ + type[arr->v[i]->type]++; + } + max = -1; + max_idx = -1; + for(int i = 0; i < 8;i++){ + if(type[i] > max){ + max = type[i]; + max_idx = i; + } + } + type[TLD_JSON_BOOL_TRUE] = type[TLD_JSON_BOOL_TRUE] + type[TLD_JSON_BOOL_FALSE]; + if(type[TLD_JSON_BOOL_TRUE] > max){ + max = type[TLD_JSON_BOOL_TRUE]; + max_idx = TLD_JSON_BOOL_TRUE; + } + + if(max != n_elem){ + ERROR_MSG("Mixed types (?) in json arr!"); + } + switch (max_idx) { + case TLD_JSON_DBL: + r->type = TLD_JSON_RET_DBL_ARR; + galloc(&r->value.dbl_arr, n_elem); + for(int i = 0; i < n_elem;i++){ + r->value.dbl_arr[i] = arr->v[i]->value.d_num; + } + break; + case TLD_JSON_INT: + r->type = TLD_JSON_RET_INT_ARR; + galloc(&r->value.int_arr, n_elem); + for(int i = 0; i < n_elem;i++){ + r->value.int_arr[i] = arr->v[i]->value.i_num; + } + break; + case TLD_JSON_BOOL_TRUE: + case TLD_JSON_BOOL_FALSE: + r->type = TLD_JSON_RET_BOOL_ARR; + galloc(&r->value.bool_arr, n_elem); + for(int i = 0; i < n_elem;i++){ + r->value.int_arr[i] = arr->v[i]->value.b_num; + } + break; + default: + ERROR_MSG("Cannot parse %d json type.",max_idx); + break; + } + break; + } + *ret = r; + return OK; +ERROR: + return FAIL; +} + +int tld_json_ret_alloc(tld_json_ret** ret) +{ + tld_json_ret* n = NULL; + MMALLOC(n, sizeof(tld_json_ret)); + n->type = TLD_JSON_RET_UNDEF; + n->n = 0; + n->n_alloc = 0; + *ret = n; + return OK; +ERROR: + tld_json_ret_free(n); + return FAIL; +} + +void tld_json_ret_free(tld_json_ret* n) +{ + if(n){ + switch (n->type) { + case TLD_JSON_RET_UNDEF: + case TLD_JSON_RET_BOOL: + case TLD_JSON_RET_DBL: + case TLD_JSON_RET_INT: + break; + case TLD_JSON_RET_STR: + tld_strbuf_free(n->value.string); + break; + case TLD_JSON_RET_BOOL_ARR: + gfree(n->value.bool_arr); + break; + case TLD_JSON_RET_DBL_ARR: + gfree(n->value.dbl_arr); + break; + case TLD_JSON_RET_INT_ARR: + gfree(n->value.int_arr); + break; + } + + MFREE(n); + } +} diff --git a/src/json/tld-json.h b/src/json/tld-json.h index d1c9bdc..2f1b0af 100644 --- a/src/json/tld-json.h +++ b/src/json/tld-json.h @@ -16,13 +16,16 @@ EXTERN int tld_json_parse(tld_strbuf *t, tld_json_obj **out); -EXTERN int tld_json_obj_get_str(tld_json_obj *n, char *key, tld_strbuf* res); - +/* EXTERN int tld_json_obj_get_str(tld_json_obj *n, char *key, tld_strbuf* res); */ +EXTERN int tld_json_obj_get(tld_json_obj *n, char *key, tld_json_ret **ret); EXTERN void tld_json_obj_free(tld_json_obj *n); EXTERN int tld_json_obj_print(tld_json_obj *n, FILE *out); EXTERN int tld_json_arr_print(tld_json_arr *n, FILE *out); + +EXTERN int tld_json_ret_alloc(tld_json_ret** ret); +EXTERN void tld_json_ret_free(tld_json_ret* n); #undef TLD_JSON_IMPORT #undef EXTERN diff --git a/src/json/tld-json_misc.c b/src/json/tld-json_misc.c index 94777f9..e6dca92 100644 --- a/src/json/tld-json_misc.c +++ b/src/json/tld-json_misc.c @@ -3,8 +3,6 @@ #define TLD_JSON_MISC_IMPORT #include "tld-json_misc.h" - - int detect_type(char*s, int len, tld_json_type* type) { tld_json_type l_type = TLD_JSON_UNDEF; diff --git a/src/json/tld-json_struct.h b/src/json/tld-json_struct.h index bb099ab..1299f0e 100644 --- a/src/json/tld-json_struct.h +++ b/src/json/tld-json_struct.h @@ -32,8 +32,8 @@ typedef struct tld_json_val{ tld_json_arr* arr; tld_strbuf* str; double d_num; - uint32_t i_num; - uint8_t b_num; + int32_t i_num; + int8_t b_num; } value; } tld_json_val; @@ -53,6 +53,32 @@ typedef struct tld_json_arr { int n_alloc; } tld_json_arr; +typedef enum tld_json_ret_type { + TLD_JSON_RET_DBL_ARR, + TLD_JSON_RET_INT_ARR, + TLD_JSON_RET_BOOL_ARR, + TLD_JSON_RET_STR, + TLD_JSON_RET_DBL, + TLD_JSON_RET_INT, + TLD_JSON_RET_BOOL, + TLD_JSON_RET_UNDEF +} tld_json_ret_type; + +typedef struct tld_json_ret{ + tld_json_ret_type type; + union{ + tld_strbuf* string; + double* dbl_arr; + int* int_arr; + uint8_t* bool_arr; + double d_num; + int32_t i_num; + int8_t b_num; + } value; + int n; + int n_alloc; +} tld_json_ret; + #undef TLD_JSON_STRUCT_IMPORT #undef EXTERN diff --git a/tests/utests/unit_json.c b/tests/utests/unit_json.c index 1e87aad..7a66d39 100644 --- a/tests/utests/unit_json.c +++ b/tests/utests/unit_json.c @@ -3,6 +3,7 @@ int test_file_parser(char *infile); int test_obj_parser(void); int test_parser(void); +int test_parser_list(void); int main(int argc, char *argv[]) { @@ -14,7 +15,7 @@ int main(int argc, char *argv[]) /* exit(0); */ test_parser(); } - + test_parser_list(); return EXIT_SUCCESS; ERROR: return EXIT_FAILURE; @@ -47,16 +48,17 @@ int test_file_parser(char *infile) tld_json_parse(buf, &n); - tld_strbuf* res = NULL; - tld_strbuf_alloc(&res, 16); + /* tld_strbuf* res = NULL; */ + tld_json_ret* res = NULL; + /* tld_strbuf_alloc(&res, 16); */ - tld_json_obj_get_str(n, "name",res); + tld_json_obj_get(n, "name",&res); - LOG_MSG("RESULT:::: %s", TLD_STR(res)); + LOG_MSG("RESULT:::: %s", TLD_STR(res->value.string)); tld_json_obj_free(n); tld_strbuf_free(buf); - tld_strbuf_free(res); + tld_json_ret_free(res); return OK; ERROR: if(f_ptr){ @@ -89,10 +91,43 @@ int test_obj_parser(void) } +int test_parser_list(void) +{ + char test[] = "{\n\ +\"embedding\":[ 0.31691884994506836,5.225735664367676,1.9427547454833984]\n\ +}\n"; -int test_parser(void) + tld_strbuf * buf = NULL; + tld_json_ret* ret = NULL; + tld_json_obj *n = NULL; + tld_strbuf_alloc(&buf, 1024); + tld_append(buf, test); + fprintf(stdout,"%s - input ", TLD_STR(buf)); + tld_json_parse(buf, &n); + + /* LOG_MSG("Printing objecT:"); */ + /* tld_json_obj_print(n, stdout); */ + buf->len = 0; + tld_json_obj_get(n, "embedding", &ret); + if(ret->type == TLD_JSON_RET_DBL_ARR){ + for(int i = 0; i < ret->n;i++){ + fprintf(stdout,"%d %f - parsed\n",i,ret->value.dbl_arr[i]); + } + }else{ + ERROR_MSG("TYPE:::: %d", ret->type); + } + /* LOG_MSG("%s", TLD_STR(ret->value.string)); */ + /* tld_json_get_arr_str(tld_json_arr *n, char *key, tld_strbuf* res) */ + tld_json_obj_free(n); + tld_strbuf_free(buf); + + return OK; +ERROR: + return FAIL; +} +int test_parser(void) { char test[] = "{\n\ \"squadName\": \"Super hero squad\",\n\