diff --git a/include/rjp.h b/include/rjp.h index 9b2737a..53aab7e 100644 --- a/include/rjp.h +++ b/include/rjp.h @@ -75,6 +75,13 @@ typedef struct RJP_value{ enum RJP_type type; //flag to determine active member of union }RJP_value; +//Result of an rjp search operation +typedef struct RJP_search_res{ + RJP_value* value; //pointer to match + size_t searchindex; //index in the search list + size_t objindex; //index in the searched object +}RJP_search_res; + //Convert C string consisting of json data into RJP's format RJP_value* rjp_parse(const char* str); @@ -127,13 +134,13 @@ char* rjp_member_name(const RJP_value* member); //Return the object member's key name length excluding null terminator size_t rjp_member_name_length(RJP_value* member); //Search for an object member with given key -RJP_value* rjp_search_member(const RJP_value* object, const char* search, size_t* index, size_t skip); +RJP_search_res rjp_search_member(const RJP_value* object, const char* search, size_t skip); //Search for first occurance of multiple keys. Returns first occurance of each. //Assumes dest is large enough to hold maximum num items. -size_t rjp_search_members(const RJP_value* object, size_t num, const char** searches, RJP_value** dest, size_t skip); +size_t rjp_search_members(const RJP_value* object, size_t num, const char** searches, RJP_search_res* dest, size_t skip); //Search for multiple occurances of multiple keys. Returns pointer to list of matches. //Returned pointer must be freed using rjp_free -RJP_value** rjp_search_members_multi(const RJP_value* object, size_t num, const char** searches, size_t* rsize, size_t skip); +RJP_search_res* rjp_search_members_multi(const RJP_value* object, size_t num, const char** searches, size_t* rsize, size_t skip); //Access first element of a json array RJP_value* rjp_get_element(const RJP_value* array); //Access next element of a json array given the previous element diff --git a/src/rjp.c b/src/rjp.c index 167145b..33f9bc3 100644 --- a/src/rjp.c +++ b/src/rjp.c @@ -124,37 +124,38 @@ char* rjp_member_name(const RJP_value* member){ size_t rjp_member_name_length(RJP_value* member){ return ((RJP_object_member*)member)->name.length; } -RJP_value* rjp_search_member(const RJP_value* object, const char* search, size_t* index, size_t skip){ + +RJP_search_res rjp_search_member(const RJP_value* object, const char* search, size_t skip){ RJP_value* member = rjp_get_member(object); size_t i = 0; for(;i < skip && member;member = rjp_next_member(member),++i); for(;member;member = rjp_next_member(member),++i){ if(!strcmp(((RJP_object_member*)member)->name.value, search)){ - if(index){ - *index = i; - } - return member; + return (RJP_search_res){member, 0, i}; } } - return NULL; + return (RJP_search_res){0}; } -size_t rjp_search_members(const RJP_value* object, size_t num, const char** searches, RJP_value** dest, size_t skip){ + +size_t rjp_search_members(const RJP_value* object, size_t num, const char** searches, RJP_search_res* dest, size_t skip){ const char** tmp = rjp_alloc(num*sizeof(char*)); for(size_t i = 0;i < num;++i){ tmp[i] = searches[i]; - dest[i] = NULL; } RJP_value* member = rjp_get_member(object); - for(size_t i = 0;i < skip && member;member = rjp_next_member(member)); + size_t objindex = 0; + for(;objindex < skip && member;member = rjp_next_member(member),++objindex); size_t matches = 0; - for(;member;member = rjp_next_member(member)){ + for(;member;member = rjp_next_member(member),++objindex){ for(size_t i = 0;i < num;++i){ if(searches[i] == NULL) continue; if(!strcmp(((RJP_object_member*)member)->name.value, searches[i])){ - dest[i] = member; + dest[i].value = member; + dest[i].searchindex = i; + dest[i].objindex = objindex; searches[i] = NULL; ++matches; break; @@ -167,21 +168,25 @@ size_t rjp_search_members(const RJP_value* object, size_t num, const char** sear rjp_free(tmp); return matches; } -RJP_value** rjp_search_members_multi(const RJP_value* object, size_t num, const char** searches, size_t* rsize, size_t skip){ - RJP_value** ret = rjp_alloc(num*sizeof(RJP_value*)); +RJP_search_res* rjp_search_members_multi(const RJP_value* object, size_t num, const char** searches, size_t* rsize, size_t skip){ + RJP_search_res* ret = rjp_alloc(num*sizeof(RJP_search_res)); size_t ret_size = num; size_t j = 0; RJP_value* member = rjp_get_member(object); - for(size_t i = 0;i < skip && member;member = rjp_next_member(member)); + size_t objindex = 0; + for(;objindex < skip && member;member = rjp_next_member(member),++objindex); - for(;member;member = rjp_next_member(member)){ + for(;member;member = rjp_next_member(member),++objindex){ for(size_t i = 0;i < num;++i){ if(!strcmp(((RJP_object_member*)member)->name.value, searches[i])){ - ret[j++] = member; + ret[j].value = member; + ret[j].searchindex = i; + ret[j].objindex = objindex; + ++j; if(j == ret_size){ ret_size *= 2; - ret = rjp_realloc(ret, ret_size*sizeof(RJP_value*)); + ret = rjp_realloc(ret, ret_size*sizeof(RJP_search_res)); } break; }