diff --git a/api.c b/api.c index 6fcd5901ccefc45618fe4c1abbb7f36e6bed7df1..77b443cb6f32204a333112837344e198a3a54fa8 100644 --- a/api.c +++ b/api.c @@ -68,20 +68,25 @@ out: int get_idx(char *key) { + if(!key) + return -2; + char *open_brace = strchr(key, '['); - printf("open_brace=%s\n", open_brace); + if (open_brace) { char *close_brace = strchr(open_brace, ']'); + if (close_brace) { - int len = close_brace - open_brace; - printf("len=%d\n", len); - char *idx_str = calloc(1, len); + int len, idx; + char *idx_str; + + len = close_brace - open_brace; + idx_str = calloc(1, len); strncpy(idx_str, open_brace + 1, len-1); - printf("idx_str = %s\n", idx_str); - int idx = atoi(idx_str); - printf("idx = %d\n", idx); + idx = atoi(idx_str); + *open_brace = '\0'; - printf("key=%s\n", key); + free(idx_str); return idx; } } @@ -89,11 +94,10 @@ int get_idx(char *key) return -2; } -int add_array(struct json_object *ptr, int idx, char *val, enum json_type type, char *key) +struct json_object *dummy_val(char *val, enum json_type type) { - struct json_object *tmp; struct json_object *j_val; - printf("%s %d\n", __func__, __LINE__); + switch(type) { case json_type_array: j_val = json_tokener_parse(val); @@ -111,23 +115,34 @@ int add_array(struct json_object *ptr, int idx, char *val, enum json_type type, j_val = json_object_new_double(atof(val)); break; case json_type_int: - j_val = json_object_new_double(atoi(val)); + j_val = json_object_new_int(atoi(val)); break; default: - return -1; + return NULL; break; } -printf("%s %d\n", __func__, __LINE__); + + return j_val; +} + +int add_array(struct json_object *ptr, int idx, char *val, enum json_type type, char *key) +{ + struct json_object *tmp; + struct json_object *j_val; + + j_val = dummy_val(val, type); + if (!j_val) + return -1; + json_object_object_get_ex(ptr, key, &tmp); - if (json_object_is_type(tmp, json_type_array)) { - if (tmp && idx != -1) { + if (tmp && json_object_is_type(tmp, json_type_array)) { + if (idx != -1) json_object_array_put_idx(tmp, idx, j_val); - } else if (tmp && idx == -1) { + else { printf("%s %d\n", __func__, __LINE__); json_object_array_add(tmp, j_val); } } else { - printf("%s %d\n", __func__, __LINE__); tmp = json_object_new_array(); json_object_array_add(tmp, j_val); printf("%s %d type=%s, ptr_type=%s\n", __func__, __LINE__, json_type_to_name(json_object_get_type(tmp)), json_type_to_name(json_object_get_type(ptr))); @@ -136,7 +151,7 @@ printf("%s %d\n", __func__, __LINE__); printf("key=%s\n", key); json_object_object_add(ptr, key, tmp); } -printf("%s %d\n", __func__, __LINE__); + return 0; } @@ -157,10 +172,13 @@ int set_by_string(char *fmt, struct json_object **src, char *val, enum json_type printf("set val = %s\n", val); ptr = tmp = *src; - + if (!fmt) + goto add_key; + printf("%s %d\n", __func__, __LINE__); strcpy(buffer, fmt); - + printf("%s %d\n", __func__, __LINE__); p = strtok(buffer,delimiter); + printf("%s %d\n", __func__, __LINE__); while (p != NULL) { prev = p; p = strtok(NULL, delimiter); @@ -172,19 +190,25 @@ int set_by_string(char *fmt, struct json_object **src, char *val, enum json_type json_object_object_get_ex(tmp, prev, &ptr); /* if we need to step further and currently marked value isnt an object, we need to overwrite it */ if (!json_object_is_type(ptr, json_type_object) && !json_object_is_type(ptr, json_type_array)) { - printf("lets create new object hahah! key = %s\n", prev); ptr = json_object_new_object(); json_object_object_add(tmp, prev, ptr); } printf("p=%s\n", p); - /* TODO: if prev contains [x], get idx of x */ - printf("%s %d\n", __func__, __LINE__); /* TODO: make enums for rv of get_idx */ if (idx != -2) { + printf("%s %d\n", __func__, __LINE__); if (ptr && json_object_get_type(ptr) == json_type_array) { printf("%s %d\n", __func__, __LINE__); - ptr = json_object_array_get_idx(ptr, idx); + if (idx > -1 && idx < json_object_array_length(ptr)) + ptr = json_object_array_get_idx(ptr, idx); + else { + printf("%s %d\n", __func__, __LINE__); + json_object_array_add(ptr, json_object_new_object()); + printf("ptr=%s\n", json_object_get_string(ptr)); + ptr = json_object_array_get_idx(ptr, json_object_array_length(ptr) - 1); + printf("ptr=%s\n", json_object_get_string(ptr)); + } } else { ptr = json_object_new_array(); printf("%s %d type=%s, ptr_type=%s\n", __func__, __LINE__, json_type_to_name(json_object_get_type(tmp)), json_type_to_name(json_object_get_type(ptr))); @@ -192,6 +216,8 @@ int set_by_string(char *fmt, struct json_object **src, char *val, enum json_type printf("ptr=%s\n", json_object_get_string(ptr)); printf("prev=%s\n", prev); json_object_object_add(tmp, prev, ptr); + json_object_array_add(ptr, json_object_new_object()); + ptr = json_object_array_get_idx(ptr, json_object_array_length(ptr) - 1); //json_object_array_add(tmp, ptr); } } @@ -199,24 +225,30 @@ int set_by_string(char *fmt, struct json_object **src, char *val, enum json_type /* create prev object if it does not exist */ if (!ptr) { ptr = json_object_new_object(); - printf("%s %d\n", __func__, __LINE__); if (json_object_get_type(tmp) == json_type_array) json_object_array_add(tmp, ptr); else if (json_object_get_type(tmp) == json_type_object) json_object_object_add(tmp, prev, ptr); + printf("%s %d: ptr=%s\n", __func__, __LINE__, json_object_get_string(ptr)); + printf("%s %d: tmp=%s\n", __func__, __LINE__, json_object_get_string(tmp)); } } tmp = ptr; } + printf("%s %d prev=%s\n", __func__, __LINE__, prev); + json_object_object_get_ex(ptr, prev, &tar); +add_key: +printf("%s %d\n", __func__, __LINE__); switch(type) { case json_type_object: { struct json_object *parsed_val = json_tokener_parse(val); + printf("%s %d\n", __func__, __LINE__); if (!parsed_val) { fprintf(stderr, "Invalid object format\n"); return -1; @@ -225,13 +257,18 @@ int set_by_string(char *fmt, struct json_object **src, char *val, enum json_type return -1; } + printf("%s %d\n", __func__, __LINE__); /* TODO: does this actually work? what would be the test case for this? */ idx = get_idx(prev); + printf("%s %d\n", __func__, __LINE__); if (idx == -2) { + if (prev) + ptr = json_object_new_object(); json_object_object_foreach(parsed_val, key1, val1) - json_object_object_add(*src, key1, val1); + json_object_object_add(ptr, key1, val1); + if (prev) + json_object_object_add(tmp, prev, ptr); } else { - printf("%s %d\n", __func__, __LINE__); add_array(ptr, idx, val, type, prev); } } @@ -246,11 +283,12 @@ int set_by_string(char *fmt, struct json_object **src, char *val, enum json_type } break; case json_type_int: - printf("%s %d\n", __func__, __LINE__); + printf("%s %d prev = %s\n", __func__, __LINE__, prev); idx = get_idx(prev); - if (idx == -2) + if (idx == -2) { + printf("%s %d ptr=%s, idx=%d\n", __func__, __LINE__, json_object_get_string(ptr), idx); json_object_object_add(ptr, prev, json_object_new_int(atoi(val))); - else { + } else { printf("%s %d\n", __func__, __LINE__); add_array(ptr, idx, val, type, prev); } @@ -273,12 +311,11 @@ int set_by_string(char *fmt, struct json_object **src, char *val, enum json_type case json_type_double: idx = get_idx(prev); if (idx == -2) - json_object_object_add(ptr, prev, json_object_new_int(atof(val))); + json_object_object_add(ptr, prev, json_object_new_double(atof(val))); else { printf("%s %d\n", __func__, __LINE__); add_array(ptr, idx, val, type, prev); } - break; case json_type_boolean: { @@ -368,7 +405,7 @@ int main() printf("%s\n", json_object_get_string(ptr)); - set_by_string("test.apdfgj[1].test", &obj, "gå och häng dig", json_type_string); + set_by_string("test.asd[-1].test.tested", &obj, "{\"api_test\":\"hej\"}", json_type_object); printf("result: %s\n", json_object_get_string(obj)); diff --git a/test/api_test.c b/test/api_test.c index f7af316f2ec7e5ca7c7711e26870d0019bc90bd5..54756c001d5f8a1debae97127911060fbd8f03a7 100644 --- a/test/api_test.c +++ b/test/api_test.c @@ -43,18 +43,21 @@ static void test_build_from_scratch(void **state) struct json_object *file = path_to_obj("/home/jakob/git/json-editor-api/test.json"); struct json_object *jobj = NULL; - set_by_string("", &jobj, "{ \"test\":\"success\", \"nested\": { \"api\":\"test2\"} }", json_type_object); + set_by_string(NULL, &jobj, "{ \"test\":\"success\", \"nested\": { \"api\":\"test2\"} }", json_type_object); - assert_int_equal(1, json_object_equal(file, jobj)); + printf("file_obj=%s\n", json_object_get_string(file)); + printf("modify_obj=%s\n", json_object_get_string(jobj)); + assert_int_equal(1, json_object_equal(file, jobj)); } static void test_json_add_object(void **state) { (void) state; - //struct json_object *obj = json_object_new_object(); - json_object_object_add(file_obj, "test2", json_object_new_string("success")); + struct json_object *obj = json_object_new_object(); + json_object_object_add(obj, "test2", json_object_new_string("success")); + json_object_object_add(file_obj, "string", obj); //json_object_object_add(file_obj, "string", json_object_new_string("1")); set_by_string("string", &modify_obj, "{\"test2\":\"success\"}", json_type_object); @@ -138,7 +141,7 @@ static void test_json_add_multi_obj(void **state) json_object_object_add(file_obj, "string", json_object_new_string("1")); json_object_object_add(file_obj, "integer", json_object_new_int(1)); - set_by_string("", &modify_obj, "{ \"nested0\": {\"nested1\": {\"integer\": 1}}, \"ints\": [1, 2, 3], \"string\":\"1\", \"integer\": 1}", json_type_object); + set_by_string(NULL, &modify_obj, "{ \"nested0\": {\"nested1\": {\"integer\": 1}}, \"ints\": [1, 2, 3], \"string\":\"1\", \"integer\": 1}", json_type_object); printf("file_obj=%s\n", json_object_get_string(file_obj)); printf("modify_obj=%s\n", json_object_get_string(modify_obj)); @@ -226,6 +229,72 @@ static void test_json_add_int_nested(void **state) assert_int_equal(1, json_object_equal(modify_obj, file_obj)); } +static void test_json_add_array_int(void **state) +{ + (void) state; + + struct json_object *arr = json_object_new_array(); + + json_object_array_add(arr, json_object_new_int(1)); + json_object_object_add(file_obj, "array", arr); + + set_by_string("array[-1]", &modify_obj, "1", json_type_int); + + printf("file_obj=%s\n", json_object_get_string(file_obj)); + printf("modify_obj=%s\n", json_object_get_string(modify_obj)); + + assert_int_equal(1, json_object_equal(modify_obj, file_obj)); +} + +static void test_json_add_array_object(void **state) +{ + (void) state; + + struct json_object *arr = json_object_new_array(); + struct json_object *obj = json_object_new_object(); + + json_object_object_add(obj, "integer", json_object_new_int(1)); + json_object_object_add(obj, "string", json_object_new_string("test")); + + json_object_array_add(arr, obj); + json_object_array_add(arr, json_object_get(obj)); // array will now hold two references to the same object (will double free otherwise) + json_object_object_add(file_obj, "array", arr); + + set_by_string("array[-1].integer", &modify_obj, "1", json_type_int); + set_by_string("array[0].string", &modify_obj, "test", json_type_string); + set_by_string("array[-1]", &modify_obj, "{\"integer\": 1, \"string\":\"test\"}", json_type_object); + + printf("file_obj=%s\n", json_object_get_string(file_obj)); + printf("modify_obj=%s\n", json_object_get_string(modify_obj)); + + assert_int_equal(1, json_object_equal(modify_obj, file_obj)); +} + +static void test_json_add_array_nested_object(void **state) +{ + (void) state; + + struct json_object *arr = json_object_new_array(); + struct json_object *obj = json_object_new_object(); + struct json_object *nested = json_object_new_object(); + struct json_object *nested1 = json_object_new_object(); + + json_object_object_add(nested, "integer", json_object_new_int(1)); + json_object_object_add(nested1, "nested1", nested); + json_object_object_add(obj, "nested", nested1); + json_object_array_add(arr, obj); + json_object_array_add(arr, json_object_get(obj)); + json_object_object_add(file_obj, "array", arr); + + set_by_string("array[-1].nested.nested1.integer", &modify_obj, "1", json_type_int); + set_by_string("array[-1].nested.nested1", &modify_obj, "{\"integer\": 1}", json_type_object); + + printf("file_obj=%s\n", json_object_get_string(file_obj)); + printf("modify_obj=%s\n", json_object_get_string(modify_obj)); + + assert_int_equal(1, json_object_equal(modify_obj, file_obj)); +} + static int setup (void** state) { file_obj = path_to_obj("/home/jakob/git/json-editor-api/test.json"); modify_obj = path_to_obj("/home/jakob/git/json-editor-api/test.json"); @@ -251,6 +320,9 @@ int main(void) { cmocka_unit_test_setup_teardown(test_json_add_multi_types, setup, teardown), cmocka_unit_test_setup_teardown(test_json_add_multi_obj, setup, teardown), cmocka_unit_test_setup_teardown(test_json_overwrite_string, setup, teardown), + cmocka_unit_test_setup_teardown(test_json_add_array_int, setup, teardown), + cmocka_unit_test_setup_teardown(test_json_add_array_object, setup, teardown), + cmocka_unit_test_setup_teardown(test_json_add_array_nested_object, setup, teardown), }; return cmocka_run_group_tests(tests, NULL, NULL);