Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdbool.h>
#include <pthread.h>
#include <libubox/blobmsg.h>
#include <libubox/blobmsg_json.h>
#include <json-c/json.h>
#include "api.h"
/* will allocate memory! remember to free! */
char *get_file(const char *path)
{
FILE *f;
size_t len, nread;
char *buffer;
f = fopen(path, "r");
if (!f)
goto out;
if (fseek(f, 0, SEEK_END))
goto out_close;
len = ftell(f);
if (len < 0)
goto out_close;
if (fseek(f, 0, SEEK_SET))
goto out_close;
buffer = calloc(1, len);
if (!buffer)
goto out_close;
nread = fread(buffer, sizeof(char), len, f);
if (nread < len)
goto out_free;
fclose(f);
return buffer;
out_free:
free(buffer);
out_close:
fclose(f);
out:
return NULL;
}
struct json_object *path_to_obj(const char *path)
{
struct json_object *obj;
char *file_str;
file_str = get_file(path);
if (!file_str)
goto out;
obj = json_tokener_parse(file_str);
free(file_str);
return obj;
out:
return NULL;
}
int get_idx(char *key, int *idx, char *out)
char *open_brace;
int len = 0;
char buffer[64] = {0};
char *ptr;
printf("%s %d key=%s\n", __func__, __LINE__, key);
strncpy(buffer, key, sizeof(buffer) - 1);
ptr = (char *)buffer;
printf("%s %d ptr=%s\n", __func__, __LINE__, ptr);
while((open_brace = strchr(ptr, '['))) {
char *close_brace = strchr(open_brace, ']');
str_len = close_brace - open_brace;
idx_str = calloc(1, str_len);
strncpy(idx_str, open_brace + 1, str_len-1);
idx[len++] = atoi(idx_str);
strncpy(out, buffer, 31);
printf("%s %d, out=%s, buffer=%s", __func__, __LINE__, out, buffer);
return len;
struct json_object *dummy_val(char *val, enum json_type type)
switch(type) {
case json_type_array:
j_val = json_tokener_parse(val);
break;
case json_type_boolean:
;;
break;
case json_type_object:
j_val = json_tokener_parse(val);
break;
case json_type_string:
j_val = json_object_new_string(val);
break;
case json_type_double:
j_val = json_object_new_double(atof(val));
break;
case json_type_int:
j_val = json_object_new_int(atoi(val));
return j_val;
}
int add_array(struct json_object *ptr, int *idx, int len, char *val, enum json_type type, char *key)
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 (!tmp || !json_object_is_type(tmp, json_type_array)) {
tmp = json_object_new_array();
json_object_object_add(ptr, key, tmp);
}
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
for (int i = 0; i < len; i++) {
struct json_object *tmp1;
tmp1 = json_object_array_get_idx(tmp, idx[i]);
printf("%s %d ptr = %s, tmp = %s\n", __func__, __LINE__, json_object_get_string(ptr), json_object_get_string(tmp));
if (i < len -1) {
if (!tmp1 || !json_object_is_type(tmp1, json_type_array)) {
tmp1 = json_object_new_array();
if (idx[i] > -1)
json_object_array_put_idx(tmp, idx[i], tmp1);
else
json_object_array_add(tmp, tmp1);
}
tmp = tmp1;
} else {
printf("%s %d ptr = %s, tmp = %s, tmp1=%s\n", __func__, __LINE__, json_object_get_string(ptr), json_object_get_string(tmp), json_object_get_string(tmp1));
if (idx[i] > -1)
json_object_array_put_idx(tmp, idx[i], j_val);
else
json_object_array_add(tmp, j_val);
}
}
printf("%s %d ptr = %s, tmp = %s\n", __func__, __LINE__, json_object_get_string(ptr), json_object_get_string(tmp));
int add_val(struct json_object *ptr, char *key, char *val, enum json_type type)
{
struct json_object *j_val;
int idx[32];
int len;
char parsed_key[32] = {0};
len = get_idx(key, idx, parsed_key);
printf("%s %d parsed_key=%s\n", __func__, __LINE__, parsed_key);
j_val = dummy_val(val, type);
if (!j_val || !json_object_is_type(j_val, type)) {
fprintf(stderr, "Invalid input value!\n");
return -1;
}
printf("%s %d val=%s, j_val=%s, ptr=%s\n", __func__, __LINE__, val, json_object_get_string(j_val), json_object_get_string(ptr));
printf("%s %d\n", __func__, __LINE__);
/* TODO: does this actually work? what would be the test case for this? */
struct json_object *tmp = ptr;
if (key)
ptr = json_object_new_object();
json_object_object_foreach(j_val, key1, val1)
json_object_object_add(ptr, key1, val1);
if (key) {
printf("%s %d\n", __func__, __LINE__);
json_object_object_add(tmp, parsed_key, ptr);
}
printf("%s %d\n", __func__, __LINE__);
add_array(ptr, idx, len, val, type, parsed_key);
if (len < 1 || type == json_type_array)
json_object_object_add(ptr, parsed_key, j_val);
else {
add_array(ptr, idx, len, val, type, parsed_key);
}
int set_by_string(char *fmt, struct json_object **src, char *val, enum json_type type)
{
const char *delimiter = ".";
char fmt_cpy[1024] = {0}, parsed_key[32] = {0};
if (!*src) {
printf("lets allocate new object\n");
*src = json_object_new_object();
}
printf("format = %s\n", fmt);
printf("set val = %s\n", val);
ptr = tmp = *src;
if (!fmt)
goto add_key;
strcpy(fmt_cpy, fmt);
p = strtok(fmt_cpy,delimiter);
while (p != NULL) {
p = strtok(NULL, delimiter);
/* if next key exists, parse key, let switch-case add/alter last key */
/* TODO: pretty wonky order with get idx first to overwrite braces?*/
memset(idx, 0, sizeof(idx));
len = get_idx(key, idx, parsed_key);
printf("parsed_key=%s\n", parsed_key);
printf("len=%d\n", len);
/* if we need to step further and currently marked value isnt an object, we need to overwrite it */
json_object_object_get_ex(tmp, parsed_key, &ptr);
if (!json_object_is_type(ptr, json_type_object) && !json_object_is_type(ptr, json_type_array)) {
json_object_object_add(tmp, parsed_key, ptr);
/* TODO: make enums for rv of get_idx */
if (len > 0) {
for (int i = 0; i < len; i++) {
printf("%s %d, ptr = %s\n", __func__, __LINE__, json_object_get_string(ptr));
if (ptr && json_object_get_type(ptr) == json_type_array) {
printf("%s %d\n", __func__, __LINE__);
if (idx[i] > -1 && idx[i] < json_object_array_length(ptr))
ptr = json_object_array_get_idx(ptr, idx[i]);
else {
printf("%s %d\n", __func__, __LINE__);
if (i == len - 1)
json_object_array_add(ptr, json_object_new_object());
else if (i < len -1)
json_object_array_add(ptr, json_object_new_array());
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)));
printf("tmp=%s\n", json_object_get_string(tmp));
printf("ptr=%s\n", json_object_get_string(ptr));
printf("key=%s\n", key);
json_object_object_add(tmp, parsed_key, ptr);
if (i == len - 1) {
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);
}
}
/* create key object if it does not exist */
if (!ptr) {
ptr = json_object_new_object();
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, parsed_key, 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 key=%s\n", __func__, __LINE__, parsed_key);
add_key:
printf("%s %d\n", __func__, __LINE__);
return 0;
}
int set(char *fmt, struct json_object *src, struct json_object *val)
{
const char *delimiter = ".";
char *p;
if (json_object_get_type(val) != json_type_object) {
fprintf(stderr, "object must be of type object!\n");
return -1;
}
src = get(fmt, src);
/* TODO: put this in some separate function */
for (p = strtok(fmt_cpy,delimiter); p != NULL; p = strtok(NULL, delimiter)) {
struct json_object *ptr, *tmp = src;
json_object_object_get_ex(tmp, p, &ptr);
if (!ptr) {
ptr = json_object_new_object();
json_object_object_add(tmp, p, ptr);
}
tmp = ptr;
}
json_object_object_foreach(val, key, val1)
json_object_object_add(src, key, val1);
return 0;
}
struct json_object *get(char *fmt, struct json_object *src)
{
struct json_object *ptr, *tmp = src;
const char *delimiter = ".";
for (char *p = strtok(fmt_cpy,delimiter); p != NULL; p = strtok(NULL, delimiter)) {
json_object_object_get_ex(tmp, p, &ptr);
tmp = ptr;
}
return ptr;
}
int main()
{
struct json_object *obj = path_to_obj("/home/jakob/git/json-editor/test.json");
struct json_object *ptr;
printf("%s %d\n", __func__, __LINE__);
struct json_object *arr = json_object_new_array();
struct json_object *obj_arr = json_object_new_object();
json_object_object_add(obj_arr, "test_arr", arr);
printf("tets_arr = %s\n", json_object_get_string(obj_arr));
printf("original obj=%s\n", json_object_get_string(obj));
ptr = get("nested", obj);
printf("%s\n", json_object_get_string(ptr));
set_by_string("test.asd[-1].test.tested", &obj, "{\"api_test\":\"hej\"}", json_type_object);
printf("result: %s\n", json_object_get_string(obj));
json_object_put(obj);
return 0;
}