From 1fdedc5f41a36b774a7a691edb5c8722f2529f82 Mon Sep 17 00:00:00 2001 From: Katharina Fey Date: Mon, 22 Aug 2016 11:15:16 +0200 Subject: First release candidate for version 1.0 - Adding preliminary json encode functionality - Adding new executable with test functions Code needs further testing but should be functional. --- include/dtree/dyn_tree.h | 2 +- lib/dyn_tree.c | 2 +- lib/dyn_utils.c | 247 ++++++++++++++++++++++++++++++++++++++++++++++- test/main.c | 91 ++++++++++++++++- 4 files changed, 335 insertions(+), 7 deletions(-) diff --git a/include/dtree/dyn_tree.h b/include/dtree/dyn_tree.h index 64b463b..4155af4 100644 --- a/include/dtree/dyn_tree.h +++ b/include/dtree/dyn_tree.h @@ -282,7 +282,7 @@ dt_err dtree_encode_set(dtree *data, short setting); * @param json_data * @return */ -dt_err dtree_encode_json(dtree *data, char *(*json_data)); +dt_err dtree_encode_json(dtree *data, char *json_data); /** diff --git a/lib/dyn_tree.c b/lib/dyn_tree.c index 5035849..c01d9f6 100644 --- a/lib/dyn_tree.c +++ b/lib/dyn_tree.c @@ -10,7 +10,7 @@ #define RDB_REC_DEF_SIZE 2 #define RDB_REC_MULTIPLY 2 -/***Forward declared functions ***/ +/*** Forward declared functions ***/ int recursive_search(dtree**, dtree *, dtree *); diff --git a/lib/dyn_utils.c b/lib/dyn_utils.c index 81e6d1d..8e24c3f 100644 --- a/lib/dyn_utils.c +++ b/lib/dyn_utils.c @@ -1,6 +1,251 @@ #include +#include +#include + + +/*** Forward declared functions ***/ + +#define TRUE 1 +#define FALSE 0 + +static int json_len = 0; + +int human(short mm) { + if(mm == DYNTREE_JSON_HUMAN) return 1; + return 0; +} + +int parse_key_value(dtree *key, char *buffer, short mode) +{ + if(key->type != LITERAL) 5; + + size_t key_len = key->used; + int base = 3; + + /* Make an array that will survive function switch */ + char lit[key_len + base + 1]; + + strcpy(buffer, "\""); + strcat(buffer, key->payload.literal); + strcat(buffer, "\":"); + strcat(buffer, "\0"); + return 0; +} + +const char *parse_value_list(dtree *value, char *buffer, char *global, short mode, int depth, int last) +{ + if(value == NULL) return "[ERROR]"; + + /* The new offset we need (in \t) */ + + int no_len = depth + 1; + char new_offset[no_len]; + int i; + for(i = 0; i < depth + 1; i++) + strcat(new_offset, "\t"); + + int base; +// if(human(mode)) base = 4 + no_len; // "" + base = 2; + if(!last) base++; + + switch(value->type) { + case LITERAL: + { + size_t key_len = value->used; + + strcpy(buffer, "\""); + strcat(buffer, value->payload.literal); + strcat(buffer, "\""); + strcat(buffer, "\0"); + + if(last == 0) strcat(buffer, ","); + break; + } + + case NUMERAL: + { + char str[15]; + sprintf(str, "%ld", value->payload.numeral); + int val_len = (int) strlen((char*) str); + + strcat(buffer, str); + if(last == 0) strcat(buffer, ","); + strcat(buffer, "\0"); + + break; + } + + case RECURSIVE: + { + if(value->used > 0) { + + dt_uni_t test = value->payload.recursive[0]->type; + + if(test == LITERAL || test == NUMERAL) { + fflush(stdout); + + int j; + for(j = 0; j < value->used; j++) { + dtree *child = value->payload.recursive[j]; + + char vall[1024]; + parse_value_list(child, vall, global, mode, depth + 1, (i == value->used - 1) ? TRUE : FALSE); + fflush(stdout); + } + + fflush(stdout); + + } else if(test == PAIR) { + fflush(stdout); +// *global = realloc(*global, sizeof(char) * strlen(*global) + 1); + append(global, "{"); + + int j; + for(j = 0; j < value->used; j++) { + dtree *child = value->payload.recursive[j]; + + if(child->type == PAIR) { + dtree *key = child->payload.recursive[0]; + dtree *val = child->payload.recursive[1]; + + char kkey[1024]; + + parse_key_value(key, kkey, mode); + fflush(stdout); +// *global = realloc(*global, sizeof(char) * strlen(*global) + strlen(kkey)); + append(global, kkey); + + char vval[1024]; + parse_value_list(val, vval, global, mode, 1, (j == child->used - 1) ? TRUE : FALSE); + fflush(stdout); + +// *global = realloc(*global, sizeof(char) * strlen(*global) + strlen(vval)); + append(global, vval); + } + } + + fflush(stdout); +// *global = realloc(*global, sizeof(char) * strlen(*global) + 1); + append(global, "}"); + } + + } else { + fflush(stdout); + } + } + + default: INVALID_PAYLOAD; + } + + return ""; +} + +void append(char *buffer, char *message) +{ + int msg_len = (int) strlen(message); + sprintf(buffer + json_len, message); + json_len += msg_len; +} + +/******/ + const char *rdb_error_getmsg(dt_err *e) { -} \ No newline at end of file +} + +dt_err dtree_encode_set(dtree *data, short setting) +{ + if(data == NULL) return INVALID_PARAMS; + + /* Check if setting is valid */ + switch(setting) { + case DYNTREE_ENCODE_NONE: + case DYNTREE_JSON_MINIFIED: + case DYNTREE_JSON_HUMAN: + break; + + default: return INVALID_PARAMS; + } + + data->encset = setting; + return SUCCESS; +} + + +dt_err dtree_encode_json(dtree *data, char *json_data) +{ + if(data == NULL) return INVALID_PARAMS; + + json_len = 0; + + /* Check if setting is valid */ + switch(data->encset) { + case DYNTREE_JSON_MINIFIED: + case DYNTREE_JSON_HUMAN: + break; + + default: return INVALID_PARAMS; + } + + /* Assume mode for all children */ + short mode = data->encset; + + char *open = "{"; + char *close = "}"; + + if(data->type == RECURSIVE) { + + fflush(stdout); + append(json_data, open); + + /* Iterate through all it's children */ + int i; + for(i = 0; i < data->used; i++) { + dtree *child = data->payload.recursive[i]; + + if(child->type == PAIR) { + dtree *key = child->payload.recursive[0]; + dtree *val = child->payload.recursive[1]; + + char kkey[1024]; + parse_key_value(key, kkey, mode);; + fflush(stdout); + append(json_data, kkey); + memset(kkey, 0, 1024); + + char vval[1024]; + parse_value_list(val, vval, json_data, mode, 1, (i == data->used - 1) ? TRUE : FALSE); + fflush(stdout); + + append(json_data, vval); + memset(vval, 0, 1024); + + } else if(child->type == RECURSIVE) { + dt_err err = dtree_encode_json(child, json_data); + if(err) return err; + } + } + + } else { + return INVALID_PAYLOAD; + } + fflush(stdout); + + /* Add closing } and null terminator to finish */ + append(json_data, close); + append(json_data, "\0"); + + return SUCCESS; +} + + +dt_err dtree_decode_json(dtree *(*data), const char *json_data) +{ + +} + + +/**************** PRIVATE UTILITY FUNCTIONS ******************/ \ No newline at end of file diff --git a/test/main.c b/test/main.c index 51e626a..f508247 100644 --- a/test/main.c +++ b/test/main.c @@ -10,10 +10,12 @@ dt_err split_and_merge(); dt_err search_for_payload(); +dt_err json_encode(char *json); + #define TEST(function) \ printf("Running '%s'...", #function); \ fflush(stdout); \ - err = function(); \ + err = function; \ printf(" %s\n", (err == 0) ? "OK!" : "FAILED!"); \ if(err) goto end; @@ -23,12 +25,20 @@ int main(void) printf("=== libdyntree test suite ===\n"); /* Search inside trees */ - TEST(search_for_payload) + TEST(search_for_payload()) /* Split and merge trees */ - TEST(split_and_merge) + TEST(split_and_merge()) + + /* Try to encode a structure into json */ + char json[512]; // Provide a buffer that is big enough + TEST(json_encode(json)) + + printf("Json string: %s\n", json); + end: + exit: printf("==== done ====\n"); return err; } @@ -110,4 +120,77 @@ dt_err search_for_payload() exit: dtree_free(root); return err; -} \ No newline at end of file +} + +dt_err json_encode(char *json) +{ + dt_err err; + + dtree *root, *a, *b, *c, *found; + err = dtree_malloc(&root); + if(err) goto exit; + + dtree *key, *val; + err = dtree_addrecursive(root, &a); + if(err) goto exit; + err = dtree_addrecursive(root, &b); + if(err) goto exit; + err = dtree_addrecursive(root, &c); + if(err) goto exit; + + err = dtree_addpair(a, &key, &val); + if(err) goto exit; + err = dtree_addliteral(key, "Server Address", REAL_STRLEN("Server Address")); + if(err) goto exit; + err = dtree_addliteral(val, "https://github.com", REAL_STRLEN("https://github.com")); + if(err) goto exit; + + key = val = NULL; + + err = dtree_addpair(b, &key, &val); + if(err) goto exit; + err = dtree_addliteral(key, "Server Port", REAL_STRLEN("Server Port")); + if(err) goto exit; + err = dtree_addnumeral(val, 8080); + if(err) goto exit; + + key = val = NULL; + + err = dtree_addpair(c, &key, &val); + if(err) goto exit; + err = dtree_addliteral(key, "Users", REAL_STRLEN("Users")); + if(err) goto exit; + + dtree *sbrec, *sbrec2; + err = dtree_addrecursive(val, &sbrec); + if(err) goto exit; + err = dtree_addrecursive(val, &sbrec2); + if(err) goto exit; + + dtree *subkey, *subval; + err = dtree_addpair(sbrec, &subkey, &subval); + if(err) goto exit; + err = dtree_addliteral(subkey, "spacekookie", REAL_STRLEN("spacekookie")); + if(err) goto exit; + err = dtree_addliteral(subval, "Admin", REAL_STRLEN("Admin")); + if(err) goto exit; + + key = val = NULL; + + dtree *subkey2, *subval2; + err = dtree_addpair(sbrec2, &subkey2, &subval2); + if(err) goto exit; + err = dtree_addliteral(subkey2, "jane", REAL_STRLEN("jane")); + if(err) goto exit; + err = dtree_addliteral(subval2, "normal", REAL_STRLEN("normal")); + if(err) goto exit; + + err = dtree_encode_set(root, DYNTREE_JSON_MINIFIED); + if(err) goto exit; + err = dtree_encode_json(root, json); + if(err) goto exit; + + exit: + dtree_free(root); + return err; +} \ No newline at end of file -- cgit v1.2.3