aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKatharina Fey <kookie@spacekookie.de>2016-08-22 11:15:16 +0200
committerKatharina Fey <kookie@spacekookie.de>2016-08-22 11:15:16 +0200
commit1fdedc5f41a36b774a7a691edb5c8722f2529f82 (patch)
treec2607cdaa9cd8957d2ec5f860dfa68e2f38f47e8
parent40a3881a694a9e33104dba706e9ec15eba5e67d7 (diff)
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.
-rw-r--r--include/dtree/dyn_tree.h2
-rw-r--r--lib/dyn_tree.c2
-rw-r--r--lib/dyn_utils.c247
-rw-r--r--test/main.c91
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 <dtree/dyn_tree.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+/*** 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; // "<key>"
+ 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