Skip to content
Snippets Groups Projects
api.c 9.87 KiB
Newer Older
  • Learn to ignore specific revisions
  • #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);
    
    
    		return -1;
    
    	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, ']');
    
    		if (close_brace) {
    
    			int str_len;
    
    			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);
    
    			*open_brace = '\0';
    
    			ptr = close_brace;
    
    	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)
    
    {
    	struct json_object *j_val;
    
    	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));
    
    	break;
    	default:
    
    int add_array(struct json_object *ptr, int *idx, int len, char *val, enum json_type type, char *key)
    
    	struct json_object *tmp, *tmp1;
    
    	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);
    	}
    
    	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));
    
    
    	if (json_type_object == type) {
    
    		printf("%s %d\n", __func__, __LINE__);
    
    		/* TODO: does this actually work? what would be the test case for this? */
    
    		if (len < 1) {
    
    			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);
    			}
    
    		} else {
    
    			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)
    {
    
    	struct json_object *ptr, *tmp;
    
    	const char *delimiter = ".";
    
    	char fmt_cpy[1024] = {0}, parsed_key[32] = {0};
    
    	char *p, *key = fmt;
    
    	int idx[32];
    	int len;
    
    
    	if (!*src) {
    		printf("lets allocate new object\n");
    		*src = json_object_new_object();
    	}
    
    
    	printf("format = %s\n", fmt);
    	printf("set val = %s\n", val);
    
    
    
    	strcpy(fmt_cpy, fmt);
    	p = strtok(fmt_cpy,delimiter);
    
    
    		key = p;
    
    		/* 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)) {
    
    				ptr = json_object_new_object();
    
    				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();
    
    Jakob Olsson's avatar
    Jakob Olsson committed
    				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));
    
    	printf("%s %d key=%s\n", __func__, __LINE__, parsed_key);
    
    add_key:
    printf("%s %d\n", __func__, __LINE__);
    
    	add_val(ptr, key, val, type);
    
    
    	return 0;
    }
    
    int set(char *fmt, struct json_object *src, struct json_object *val)
    {
    	const char *delimiter = ".";
    
    	char fmt_cpy[1024] = {0};
    
    	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);
    
    
    	strcpy(fmt_cpy, fmt);
    
    
    	/* 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 = ".";
    
    	char fmt_cpy[1024] = {0};
    
    	strcpy(fmt_cpy, fmt);
    
    	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");
    
    Jakob Olsson's avatar
    Jakob Olsson committed
    	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));