aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/dtree.c816
-rw-r--r--lib/dtree_utils.c278
-rw-r--r--lib/eztree.c77
-rw-r--r--lib/jsmn.c339
-rw-r--r--lib/jsmn.h98
5 files changed, 0 insertions, 1608 deletions
diff --git a/lib/dtree.c b/lib/dtree.c
deleted file mode 100644
index 11090d8..0000000
--- a/lib/dtree.c
+++ /dev/null
@@ -1,816 +0,0 @@
-// Include our header file
-#include <dtree/dtree.h>
-
-// Runtime includes
-#include <stdlib.h>
-#include <stdio.h>
-#include <memory.h>
-#include <stdbool.h>
-
-#define RDB_REC_DEF_SIZE 2
-#define RDB_REC_MULTIPLY 2
-
-#define ORIGINAL (short) 0
-#define SHALLOW (short) 1
-#define DEEP (short) 2
-
-/*** Forward declared functions ***/
-
-int list_search(dtree**, dtree *, dtree *);
-
-void list_print(dtree *data, const char *offset);
-
-/******/
-
-
-dt_err dtree_malloc(dtree *(*data))
-{
- (*data) = (dtree*) malloc(sizeof(dtree));
- if(*data == NULL) {
- printf("Creating dtree object FAILED");
- return MALLOC_FAILED;
- }
-
- memset(*data, 0, sizeof(dtree));
-
- (*data)->type = UNSET;
- return SUCCESS;
-}
-
-dt_err dtree_resettype(dtree *data)
-{
- if(data->type == LITERAL) {
- if(data->payload.literal) free(data->payload.literal);
-
- } else if(data->type == LIST || data->type == PAIR) {
-
- /* Iterate over all children and clear them */
- int i;
- dt_err err;
- for(i = 0; i < data->size; i++) {
- err = dtree_free(data->payload.list[i]);
- if(err) return err;
- }
- }
-
- /* Set the data type to unset */
- data->type = UNSET;
- data->encset = 0;
- data->size = 0;
- data->used = 0;
-
- /* Forcibly clean union memory to avoid bleeding data */
- memset(&data->payload, 0, sizeof(data->payload));
-
- return SUCCESS;
-}
-
-dt_err dtree_addliteral(dtree *data, const char *literal)
-{
- /* Make sure we are a literal or unset data object */
- if(data->type != UNSET)
- if(data->type != LITERAL) return INVALID_PAYLOAD;
-
- size_t length = REAL_STRLEN(literal);
-
- /* Get rid of previous data */
- if(data->payload.literal) free(data->payload.literal);
-
- /* Allocate space for the data */
- char *tmp = (char *) malloc(sizeof(char) * length);
- if(tmp == NULL) {
- printf("Allocating space for literal data FAILED");
- return MALLOC_FAILED;
- }
-
- /* Copy the string over and store it in the union */
- strcpy(tmp, literal);
- data->payload.literal = tmp;
- data->type = LITERAL;
- data->size = length;
- data->used = length;
-
- return SUCCESS;
-}
-
-
-dt_err dtree_addpointer(dtree *data, void *ptr)
-{
- if(data->type != UNSET)
- if(data->type != POINTER) return INVALID_PAYLOAD;
-
- data->payload.pointer = ptr;
- data->type = POINTER;
- data->size = sizeof(ptr);
- data->used = sizeof(ptr);
-
- return SUCCESS;
-}
-
-
-dt_err dtree_addnumeral(dtree *data, long numeral)
-{
- /* Make sure we are a literal or unset data object */
- if(data->type != UNSET)
- if(data->type != NUMERIC) return INVALID_PAYLOAD;
-
- data->payload.numeral = numeral;
- data->type = NUMERIC;
- data->size = sizeof(int);
- data->used = sizeof(int);
- return SUCCESS;
-}
-
-
-dt_err dtree_addboolean(dtree *data, bool b)
-{
- /* Make sure we are a literal or unset data object */
- if(data->type != UNSET)
- if(data->type != BOOLEAN) return INVALID_PAYLOAD;
-
- data->payload.boolean = b;
- data->type = BOOLEAN;
- data->size = sizeof(bool);
- data->used = sizeof(bool);
- return SUCCESS;
-}
-
-
-dt_err dtree_addlist(dtree *data, dtree *(*new_data))
-{
- /* Make sure we are a literal or unset data object */
- if(data->type != UNSET)
- if(data->type != LIST) return INVALID_PAYLOAD;
-
- dt_err err;
-
- /* This means elements already exist */
- if(data->size > 0) {
-
- /* Used should never > size */
- if(data->used >= data->size) {
- data->size += RDB_REC_MULTIPLY;
-
- // TODO Use Realloc
- dtree **tmp = (dtree**) malloc(sizeof(dtree*) * data->size);
- memcpy(tmp, data->payload.list, sizeof(dtree*) * data->used);
-
- /* Free the list WITHOUT the children! */
- free(data->payload.list);
- data->payload.list = tmp;
- }
-
- /* This means the data object is new */
- } else {
- dtree **tmp = (dtree**) malloc(sizeof(dtree*) * RDB_REC_DEF_SIZE);
- data->payload.list = tmp;
- data->type = LIST;
- data->used = 0;
- data->size = RDB_REC_DEF_SIZE;
- }
-
- err = dtree_malloc(new_data);
- if(err) return err;
-
- /* Reference the slot, assign it, then move our ctr */
- data->payload.list[data->used++] = *new_data;
-
- return SUCCESS;
-}
-
-
-dt_err dtree_addpair(dtree *data, dtree *(*key), dtree *(*value))
-{
- /* Make sure we are a literal or unset data object */
- if(data->type != UNSET) return INVALID_PAYLOAD;
-
- dt_err err;
-
- /* Malloc two nodes */
- err = dtree_malloc(key);
- if(err) goto cleanup;
-
- err = dtree_malloc(value);
- if(err) goto cleanup;
-
- /** Malloc space for PAIR */
- data->size = 2;
- dtree **tmp = (dtree**) malloc(sizeof(dtree*) * data->size);
- if(!tmp) goto cleanup;
-
- data->payload.list = tmp;
-
- { /* Assign data to new array */
- data->payload.list[data->used] = *key;
- data->used++;
- data->payload.list[data->used] = *value;
- data->used++;
- }
-
- /* Assign our new type and return */
- data->type = PAIR;
- return SUCCESS;
-
- /* Code we run when we can't allocate structs anymore */
- cleanup:
- free(*key);
- free(*value);
- free(tmp);
- return MALLOC_FAILED;
-}
-
-
-dt_err dtree_split_trees(dtree *data, dtree *sp)
-{
- /* Make sure we are a literal or unset data object */
- if(data->type == UNSET) return INVALID_PAYLOAD;
-
- /* Check that sp is really a child of data */
- dtree *dp;
- int ret = list_search(&dp, data, sp);
- if(ret != 0) return DATA_NOT_RELATED;
- if(dp == NULL) return NODE_NOT_FOUND;
-
- /* Find the exact list reference and remove it */
- int i;
- for(i = 0; i < dp->used; i++) {
- if(dp->payload.list[i] == NULL) continue;
-
- /* Manually remove the entry */
- if(dp->payload.list[i] == sp) {
- dp->used--;
- dp->payload.list[i] = NULL;
- }
- }
-
- return SUCCESS;
-}
-
-
-dt_err dtree_merge_trees(dtree *data, dtree *merge)
-{
- /* REALLY make sure the type is correct */
- if(data->type == UNSET) return INVALID_PARAMS;
- if(!(data->type == LIST || data->type == PAIR))
- return INVALID_PAYLOAD;
-
- /* This means elements already exist */
- if(data->size > 0) {
-
- /* Used should never > size */
- if(data->used >= data->size) {
- data->size += RDB_REC_MULTIPLY;
-
- dtree **tmp = (dtree**) malloc(sizeof(dtree*) * data->size);
- memcpy(tmp, data->payload.list, sizeof(dtree*) * data->used);
-
- /* Free the list WITHOUT the children! */
- free(data->payload.list);
- data->payload.list = tmp;
- }
-
- /* This means the data object is new */
- } else {
- dtree **tmp = (dtree**) malloc(sizeof(dtree*) * data->size);
- data->payload.list = tmp;
- data->type = LIST;
- data->used = 0;
- data->size = RDB_REC_DEF_SIZE;
- }
-
- /* Reference the slot, assign it, then move our ctr */
- data->payload.list[data->used] = merge;
- data->used++;
-
- return SUCCESS;
-}
-
-
-dt_err dtree_copy_deep(dtree *data, dtree *(*copy))
-{
- if(data == NULL) return INVALID_PARAMS;
- dt_err err = SUCCESS;
-
- int it_type = -1;
- dt_uni_t type = data->type;
-
- /* Check if we're the first call */
- if((*copy) == NULL) dtree_malloc(copy);
- (*copy)->copy = DEEP;
-
- switch(type) {
- case LITERAL:
- dtree_addliteral(*copy, data->payload.literal);
- break;
-
- case NUMERIC:
- dtree_addnumeral(*copy, data->payload.numeral);
- break;
-
- case BOOLEAN:
- dtree_addboolean(*copy, data->payload.boolean);
- break;
-
- case LIST:
- {
- int i;
- int num = (int) data->used;
-
- for(i = 0; i < num; i++) {
- dtree *node = data->payload.list[i];
-
- dtree *new;
- dtree_addlist(*copy, &new);
- dtree_copy_deep(node, &new);
- }
-
- break;
- }
-
- case PAIR:
- {
- dtree *key, *val;
- dtree_addpair(*copy, &key, &val);
-
- dtree *orig_key = data->payload.list[0];
- dtree *orig_val = data->payload.list[1];
-
- dtree_copy_deep(orig_key, &key);
- dtree_copy_deep(orig_val, &val);
-
- break;
- }
-
- case POINTER:
- dtree_addpointer(*copy, data->payload.pointer);
- break;
-
- default:
- err = INVALID_PAYLOAD;
- break;
- }
-
- return err;
-}
-
-
-dt_err dtree_parent(dtree *root, dtree *data, dtree **parent)
-{
- if(root == NULL || data == NULL) return INVALID_PARAMS;
-
- /* Blank the search pointer for easy error checking */
- (*parent) = NULL;
-
- switch(root->type) {
-
- /* Dead-end data stores automatically return @{NODE_NOT_FOUND} */
- case POINTER:
- case LITERAL:
- case BOOLEAN:
- case NUMERIC:
- return NODE_NOT_FOUND;
-
- case PAIR:
- case LIST:
- {
- int i;
- for(i = 0; i < root->used; i++) {
-
- /* Check if the node we're looking at is what we're searching for */
- if(root->payload.list[i] == data) {
- (*parent) = root;
- return SUCCESS;
- }
-
- dt_err err = dtree_parent(root->payload.list[i], data, parent);
- if(err == SUCCESS) return SUCCESS;
- }
- }
- break;
-
- default:
- return INVALID_PAYLOAD;
- }
-
- return NODE_NOT_FOUND;
-}
-
-
-dt_err dtree_copy(dtree *data, dtree *(*copy))
-{
- if(data == NULL) return INVALID_PARAMS;
- dt_err err = SUCCESS;
-
- /* Allocate a new node */
- err = dtree_malloc(copy);
- if(err) goto exit;
-
- /* Mark as shallow copy */
- (*copy)->copy = SHALLOW;
-
- /* Find out how to handle specific payloads */
- switch(data->type) {
- case LITERAL:
- err = dtree_addliteral(*copy, data->payload.literal);
- break;
-
- case NUMERIC:
- err = dtree_addnumeral(*copy, data->payload.numeral);
- break;
-
- case BOOLEAN:
- err = dtree_addboolean(*copy, data->payload.boolean);
- break;
-
- case LIST:
- (*copy)->type = LIST;
- (*copy)->payload.list = (dtree**) malloc(sizeof(dtree*) * data->size);
- memcpy((*copy)->payload.list, data->payload.list, sizeof(dtree*) * data->used);
- break;
-
- case PAIR:
- (*copy)->type = PAIR;
- (*copy)->payload.list = (dtree**) malloc(sizeof(dtree*) * data->size);
- memcpy((*copy)->payload.list, data->payload.list, sizeof(dtree*) * data->used);
- break;
-
- case POINTER:
- (*copy)->type = POINTER;
- memcpy((*copy)->payload.pointer, data->payload.pointer, sizeof(void*));
- break;
-
- default:
- return INVALID_PAYLOAD;
- }
-
- exit:
- return err;
-}
-
-
-dt_err dtree_search_payload(dtree *data, dtree *(*found), void *payload, dt_uni_t type)
-{
- if(data == NULL) return INVALID_PARAMS;
-
- /* Make sure our pointer is clean */
- *found = NULL;
-
- if(data->type == LIST|| data->type == PAIR) {
-
- int i;
- for(i = 0; i < data->used; i++) {
- dt_err err = dtree_search_payload(data->payload.list[i], found, payload, type);
- if(err == SUCCESS) return SUCCESS;
- }
-
- } else {
-
- /* Check the type aligns */
- if(data->type != type) return NODE_NOT_FOUND;
-
- switch(type) {
- case LITERAL:
- if(strcmp(data->payload.literal, (char*) payload) == 0)
- *found = data;
- break;
-
- case NUMERIC:
- if(data->payload.numeral == (long) payload)
- *found = data;
- break;
-
- case BOOLEAN:
- if(data->payload.boolean == (bool) payload)
- *found = data;
- break;
-
- case POINTER:
- if(data->payload.pointer == payload)
- *found = data;
- break;
-
- default: return NODE_NOT_FOUND;
- }
-
- }
-
- return (*found == NULL) ? NODE_NOT_FOUND : SUCCESS;
-}
-
-// FIXME: This is horrible. Do via context?
-static int reached = 0;
-dt_err dtree_search_keypayload(dtree *data, dtree *(*found), void *payload, dt_uni_t type, int depth)
-{
- if(data == NULL) return INVALID_PARAMS;
- if(reached++ >= depth) return QUERY_TOO_DEEP;
-
- /* Make sure our pointer is clean */
- *found = NULL;
-
- /* We can only search LISTed values or PAIRs */
- if(data->type == PAIR) {
- dtree *key = data->payload.list[0];
-
- dt_uni_t tt;
- int hit = -1;
-
- if(strcmp(key->payload.literal, (char*) payload) == 0) {
- tt = LITERAL;
- hit = 0;
- }
-
- if(key->payload.numeral == (long) payload) {
- tt = NUMERIC;
- hit = 0;
- }
-
- if(key->payload.boolean == (bool) payload) {
- tt = BOOLEAN;
- hit = 0;
- }
-
- if(hit == 0) *found = data->payload.list[1];
-
- } else if(data->type == LIST) {
-
- int i;
- for(i = 0; i < data->used; i++) {
- dtree_search_keypayload(data->payload.list[i], found, payload, type, depth);
- }
-
- } else {
-
-
- }
-
- if(data->type == LIST|| data->type == PAIR) {
-
- int i;
- for(i = 0; i < data->used; i++) {
- dt_err err = dtree_search_payload(data->payload.list[i], found, payload, type);
- if(err == SUCCESS) return SUCCESS;
- }
-
- } else {
-
- /* Check the type aligns */
- if(data->type != type) return NODE_NOT_FOUND;
-
- switch(type) {
- case LITERAL:
- if(strcmp(data->payload.literal, (char*) payload) == 0)
- *found = data;
- break;
-
- case NUMERIC:
- if(data->payload.numeral == (long) payload)
- *found = data;
- break;
-
- case BOOLEAN:
- if(data->payload.boolean == (bool) payload)
- *found = data;
-
- case POINTER:
- if(data->payload.pointer == payload)
- *found = data;
- break;
-
- default: return NODE_NOT_FOUND;
- }
-
- }
-
- return (*found == NULL) ? NODE_NOT_FOUND : SUCCESS;
-}
-
-
-void list_print(dtree *data, const char *offset)
-{
- dt_uni_t type = data->type;
-
- switch(type) {
- case UNSET:
- printf("[NULL]\n");
- break;
-
- case LITERAL:
- printf("%s['%s']\n", offset, data->payload.literal);
- break;
-
- case NUMERIC:
- printf("%s[%lu]\n", offset, data->payload.numeral);
- break;
-
- case BOOLEAN:
- printf("%s['%s']\n", offset, (data->payload.boolean) ? "TRUE" : "FALSE");
- break;
-
- case PAIR:
- {
- dt_uni_t k_type = data->payload.list[0]->type;
- dt_uni_t v_type = data->payload.list[1]->type;
-
- if(k_type == LITERAL) printf("%s['%s']", offset, data->payload.list[0]->payload.literal);
- if(k_type == NUMERIC) printf("%s[%lu]", offset, data->payload.list[0]->payload.numeral);
- if(k_type == BOOLEAN) printf("%s[%s]", offset, (data->payload.list[0]->payload.boolean) ? "TRUE" : "FALSE");
-
- char new_offset[REAL_STRLEN(offset) + 2];
- strcpy(new_offset, offset);
- strcat(new_offset, " ");
-
- if(k_type == LIST || k_type == PAIR) list_print(data->payload.list[0], new_offset);
-
- /* Print the value now */
- if(v_type == LITERAL) printf(" => ['%s']\n", data->payload.list[1]->payload.literal);
- if(v_type== NUMERIC) printf(" => [%lu]\n", data->payload.list[1]->payload.numeral);
- if(v_type == BOOLEAN) printf(" => [%s]\n", (data->payload.list[1]->payload.boolean) ? "TRUE" : "FALSE");
-
- if(v_type == LIST || k_type == PAIR) list_print(data->payload.list[1], new_offset);
-
- break;
- }
-
- case LIST:
- {
- int i;
- printf("%s[LIST]\n", offset);
- for(i = 0; i < data->used; i++) {
- dt_uni_t t = data->payload.list[i]->type;
-
- /* Calculate the new offset */
- char new_offset[REAL_STRLEN(offset) + 2];
- strcpy(new_offset, offset);
- strcat(new_offset, " ");
-
- switch(t) {
- case LITERAL:
- case BOOLEAN:
- case NUMERIC:
- list_print(data->payload.list[i], new_offset);
- continue;
-
- case LIST:
- list_print(data->payload.list[i], new_offset);
- continue;
-
- case PAIR:
- printf("%s[PAIR] <==> ", new_offset);
- list_print(data->payload.list[i], new_offset);
- continue;
-
- default:
- break;
- }
- }
- break;
- }
-
- default:
- break;
-
- }
-}
-
-
-void dtree_print(dtree *data)
-{
- list_print(data, "");
-}
-
-dt_err dtree_get(dtree *data, void *(*val))
-{
- if(data->type == LITERAL) *val = data->payload.literal;
- if(data->type == NUMERIC) *val = &data->payload.numeral;
- if(data->type == BOOLEAN) *val = &data->payload.boolean;
- if(data->type == LIST || data->type == PAIR) *val = (dtree*) data->payload.list;
- return SUCCESS;
-}
-
-
-dt_err dtree_free(dtree *data)
-{
- if(data == NULL) return SUCCESS;
- if(data->copy == SHALLOW) return NODE_NOT_ORIGINAL;
-
- if(data->type == LITERAL) {
- if(data->payload.literal) free(data->payload.literal);
-
- } else if(data->type == LIST || data->type == PAIR) {
- int i;
- dt_err err;
- for(i = 0; i < data->used; i++) {
-
- err = dtree_free(data->payload.list[i]);
- if(err) return err;
- }
-
- free(data->payload.list);
-
- } else if(data->type == POINTER) {
- if(data->copy != SHALLOW && data->payload.pointer)
- free(data->payload.pointer);
- }
-
- free(data);
- return SUCCESS;
-}
-
-
-dt_err dtree_free_shallow(dtree *data)
-{
- if(data == NULL) return SUCCESS;
-
- if(data->type == LITERAL) {
- if(data->payload.literal) free(data->payload.literal);
- } else if(data->type == LIST || data->type == PAIR) {
- int i;
- dt_err err;
- for(i = 0; i < data->size; i++) {
- err = dtree_free(data->payload.list[i]);
- if(err) return err;
- }
-
- free(data->payload.list);
- }
-
- free(data);
- return SUCCESS;
-}
-
-
-const char *dtree_dtype(dtree *data)
-{
- switch(data->type) {
- case LITERAL: return "Literal";
- case NUMERIC: return "Numeric";
- case BOOLEAN: return "Boolean";
- case LIST: return "List";
- case PAIR: return "Pair";
- case POINTER: return "Pointer";
- default: return "Unknown";
- }
-}
-
-
-/**************** PRIVATE UTILITY FUNCTIONS ******************/
-
-
-/**
- * Steps down the list hirarchy of a dyntree node to
- * find a sub-child target. Returns 0 if it can be found.
- *
- * @param data
- * @param target
- * @return
- */
-int list_search(dtree **direct_parent, dtree *data, dtree *target)
-{
- /* Check if data is actually valid */
- if(data == NULL) return 1;
-
- /* Compare the pointers :) */
- if(data == target) return 0;
-
- int res = 1;
- if(data->type == LIST || data->type == PAIR) {
- int i;
- for(i = 0; i < data->used; i++) {
- res = list_search(direct_parent, data->payload.list[i], target);
- if(res == 0) {
-
- /* Save the node that contains our child for later */
- (*direct_parent) = data;
- return res;
- }
- }
- }
-
- return res;
-}
-
-
-/**
- * Small utility function that checks if a datablock is valid to write into.
- * Potentially releases previously owned memory to prevent memory leaks
- *
- * @param data The dtree object to check
- * @return
- */
-dt_err data_check(dtree *data)
-{
- /* Check if the data block has children */
- if(data->type == LIST)
- {
- printf("Won't override heap payload with data!");
- return INVALID_PAYLOAD;
- }
-
- /* Free the existing string */
- if(data->type == LITERAL)
- {
- if(data->payload.literal) free(data->payload.literal);
- }
-
- return SUCCESS;
-}
diff --git a/lib/dtree_utils.c b/lib/dtree_utils.c
deleted file mode 100644
index b163236..0000000
--- a/lib/dtree_utils.c
+++ /dev/null
@@ -1,278 +0,0 @@
-#include <dtree/dtree.h>
-#include <stdio.h>
-#include <malloc.h>
-#include <stdlib.h>
-#include <jansson.h>
-
-#include "jsmn.h"
-
-
-#define DTREE_TOK_BOOLEAN (1 << 1)
-#define DTREE_TOK_NUMERICAL (1 << 2)
-#define DTREE_TOK_LITERAL (1 << 3)
-
-#define TOK_PAIR_KEYED (1 << 11)
-
-
-char *tok_to_str(jsmntype_t *tok)
-{
- switch(*tok) {
- case JSMN_UNDEFINED: return "UNDEFINED";
- case JSMN_OBJECT: return "OBJECT";
- case JSMN_ARRAY: return "ARRAY";
- case JSMN_STRING: return "STRING";
- case JSMN_PRIMITIVE: return "PRIMITIVE";
- default: return "UNKNOWN";
- }
-}
-
-
-int digest_payload(const char *token)
-{
- char* end;
- size_t len = strlen(token);
-
- if(len == strlen("true") || len == strlen("false"))
- if(strcmp(token, "true") == 0 || strcmp(token, "false") == 0)
- return DTREE_TOK_BOOLEAN;
-
- /* It could still be a number! */
- strtol(token, &end, 10);
- if (!*end) return DTREE_TOK_NUMERICAL;
-
- return DTREE_TOK_LITERAL;
-}
-
-
-dt_err dtree_decode_json(dtree *(*data), const char *json_data, size_t len)
-{
- jsmn_parser parse;
- jsmn_init(&parse);
-
- // FIXME: Variable amount of tokens?
- unsigned int no_tokens = 1024 * 32;
- jsmntok_t *tokens = malloc(sizeof(jsmntok_t) * no_tokens);
- memset(tokens, 0, sizeof(jsmntok_t) * no_tokens);
-
- int ret = jsmn_parse(&parse, json_data, strlen(json_data), tokens, no_tokens);
-
- unsigned int idx = 0;
- jsmntok_t tok;
-
- /** Prepare dtree nodes */
- dtree *root, *curr;
- dtree_malloc(&root);
- curr = root;
-
- struct bounds {
- int low, high;
- };
-
- struct pair {
- short state;
- char key[1024];
- union value {
- char string[1024];
- unsigned long num;
- } value;
- };
-
- /* Save some space to store token bounds */
- struct bounds *bounds = malloc(sizeof(struct bounds) * len);
- memset(bounds, 0, sizeof(struct bounds) * len);
-
- /* Have a structure to record array types in the tree */
- bool *is_array = malloc(sizeof(bool) * len);
- memset(is_array, 0, sizeof(bool) * len);
-
- /* Set the currently focused node */
- int focused = -1;
-
- struct pair c_pair;
- memset(&c_pair, 0, sizeof(struct pair));
-
- while(tok = tokens[idx++], tok.type != NULL) {
-
- size_t tok_len = (size_t) tok.end - tok.start;
- char token[tok_len + 1];
- memset(token, 0, tok_len + 1);
- memcpy(token, json_data + tok.start, tok_len);
-
- /** Check if we need to move the boundry scope (again) */
- if(focused > 0 && tok.end >= bounds[focused].high) {
- focused--;
-
- /**
- * We need to check if our direct parent is a PAIR or LIST type
- *
- * If it is a PAIR, it means we need to extract 2-stage parents
- * If it is a LIST, it means we can leave it at 1.
- */
- dtree *parent, *pair_parent;
- dtree_parent(root, curr, &parent);
-
- if(parent->type == PAIR){
- dtree_parent(root, parent, &parent); // Override the PARENT variable
- }
-
- /* Assign the new root node - old scope restored */
- curr = parent;
- }
-
- switch(tok.type) {
-
- /**
- * When we encounter a new json object, shift our "focus" over by one so we can
- * record in what range this object is going to accumilate tokens.
- *
- * We then create a new child node under the current root node and switch the
- * curr root pointer over to that child.
- *
- * When we reach the end of the token scope, we need to re-reference the parent as
- * current root and switch over our boundry scope as well. This is done before the
- * parsing switch statement.
- */
- case JSMN_ARRAY:
- case JSMN_OBJECT:
- {
- focused++;
- bounds[focused].low = tok.start;
- bounds[focused].high = tok.end;
-
- /* This is not elegant at all! */
- if(tok.type == JSMN_ARRAY) is_array[focused] = true;
-
- /* Then we check if our parent is an array */
- if(focused - 1 >= 0 && is_array[focused - 1]) {
-
- /** If our parent is an array we need to add a new object to our parent (CURR) **/
- dtree *obj;
- dtree_addlist(curr, &obj);
-
- /* Then switch over our current value */
- curr = obj;
-
- }
-
- /**
- * Most of the time, we will create a new object under the key of
- * a pair. This is the case, when the c_pair state buffer has been
- * set to KEYED. In this case we allocate a new pair node for key
- * and value and set that value to the new root.
- */
- if(c_pair.state == TOK_PAIR_KEYED) {
-
- /* Create pair nodes & new_root which becomes curr */
- dtree *pair, *key, *val;
- dtree_addlist(curr, &pair);
- dtree_addpair(pair, &key, &val);
-
- /* Assign key and new_root as a value of the pair */
- dtree_addliteral(key, c_pair.key);
-
- /* Move curr root pointer */
- curr = val;
-
- /* Blank c_pair data for next tokens */
- memset(&c_pair, 0, sizeof(struct pair));
- }
-
- /* Skip to next token */
- continue;
- }
-
- case JSMN_PRIMITIVE:
- case JSMN_STRING:
- {
-
- /**
- * First check if we are currently dealing with an array. If we are
- * the way that we create nodes changes. Every token is immediately added
- * to the currently focused list node
- */
- if(is_array[focused]) {
-
- dtree *val;
- dtree_addlist(curr, &val);
-
- /* Parse payload and asign to value node */
- switch(digest_payload(token)) {
- case DTREE_TOK_LITERAL:
- dtree_addliteral(val, token);
- break;
-
- case DTREE_TOK_NUMERICAL:
- dtree_addnumeral(val, atol(token));
- break;
-
- case DTREE_TOK_BOOLEAN:
- dtree_addboolean(val, (strcpy(token, "true") == 0) ? true : false);
- break;
-
- default: continue;
- }
-
- /* Blank c_pair data for next tokens */
- memset(&c_pair, 0, sizeof(struct pair));
-
- } else {
-
- /**
- * Here we need to check if we are adding a string as a key
- * or as a value. This is simply done by checking for the existance
- * of a key in the c_pair (current pair) variable.
- *
- * We know the token positions so we can manualy copy from the json stream
- */
- if(c_pair.state == 0) {
- memcpy(c_pair.key, json_data + tok.start, (size_t) tok.end - tok.start);
- c_pair.state = TOK_PAIR_KEYED;
-
- } else if(c_pair.state == TOK_PAIR_KEYED){
-
- /** Create a PAIR node under current root */
- dtree *pair, *key, *val;
- dtree_addlist(curr, &pair);
- dtree_addpair(pair, &key, &val);
-
- /* Key is always literal */
- dtree_addliteral(key, c_pair.key);
-
- /* Parse payload and asign to value node */
- switch(digest_payload(token)) {
- case DTREE_TOK_LITERAL:
- dtree_addliteral(val, token);
- break;
-
- case DTREE_TOK_NUMERICAL:
- dtree_addnumeral(val, atol(token));
- break;
-
- case DTREE_TOK_BOOLEAN:
- dtree_addboolean(val, (strcpy(token, "true") == 0) ? true : false);
- break;
-
- default: continue;
- }
-
- /* Blank c_pair data for next tokens */
- memset(&c_pair, 0, sizeof(struct pair));
- }
-
- }
-
- /* Skip to next token */
- continue;
- }
-
-
-
- default:
- continue;
- }
- }
-
- /* Switch over data pointer and return */
- (*data) = root;
- return SUCCESS;
-} \ No newline at end of file
diff --git a/lib/eztree.c b/lib/eztree.c
deleted file mode 100644
index ba8506a..0000000
--- a/lib/eztree.c
+++ /dev/null
@@ -1,77 +0,0 @@
-// Include eztree header file
-#include <dtree/eztree.h>
-
-dtree *eztree_new_literal(const char *string)
-{
- dtree *node;
- dtree_malloc(&node);
- dtree_addliteral(node, string);
- return node;
-}
-
-
-dtree *eztree_new_numeric(const long num)
-{
- dtree *node;
- dtree_malloc(&node);
- dtree_addnumeral(node, num);
- return node;
-}
-
-
-dtree *eztree_new_pair(const char *kdata, void *vdata, short type)
-{
- dtree *root, *key, *val;
-
- /* Allocate nodes */
- dtree_malloc(&root);
- dtree_addpair(root, &key, &val);
-
- /* Fill the data */
- dtree_addliteral(key, kdata);
- switch(type) {
- case EZTREE_LITERAL:
- dtree_addliteral(val, (char*) vdata);
- break;
-
- case EZTREE_NUMERIC:
- // FIXME: This might be dangerous on 32bit
- dtree_addnumeral(val, (long) vdata);
- break;
-
- case EZTREE_NESTED:
- {
- dtree *tmp;
- dtree_addlist(val, &tmp);
-
- /* Manually override data */
- memcpy(val->payload.list[0], vdata, sizeof(vdata));
- break;
- }
-
- default: break;
- }
-
- return root;
-}
-
-//
-//dtree *eztree_new_list(dtree **list, size_t size)
-//{
-// /* Prepare our buffer */
-// memset(list, 0, sizeof(dtree*) * size);
-//
-// /* Prepare root node */
-// dtree *root;
-// dtree_malloc(&root);
-//
-// /* Add apropriate number of children to root node */
-// int i;
-// for(i = 0; i < size; i++) {
-// dtree *tmp;
-// dtree_addlist(root, &tmp);
-// list[i] = tmp;
-// }
-//
-// return root;
-//} \ No newline at end of file
diff --git a/lib/jsmn.c b/lib/jsmn.c
deleted file mode 100644
index a006d60..0000000
--- a/lib/jsmn.c
+++ /dev/null
@@ -1,339 +0,0 @@
-/*
- * Copyright (c) 2010 Serge A. Zaitsev
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "jsmn.h"
-
-/**
- * Allocates a fresh unused token from the token pull.
- */
-static jsmntok_t *jsmn_alloc_token(jsmn_parser *parser,
- jsmntok_t *tokens, size_t num_tokens) {
- jsmntok_t *tok;
- if (parser->toknext >= num_tokens) {
- return NULL;
- }
- tok = &tokens[parser->toknext++];
- tok->start = tok->end = -1;
- tok->size = 0;
-#ifdef JSMN_PARENT_LINKS
- tok->parent = -1;
-#endif
- return tok;
-}
-
-/**
- * Fills token type and boundaries.
- */
-static void jsmn_fill_token(jsmntok_t *token, jsmntype_t type,
- int start, int end) {
- token->type = type;
- token->start = start;
- token->end = end;
- token->size = 0;
-}
-
-/**
- * Fills next available token with JSON primitive.
- */
-static int jsmn_parse_primitive(jsmn_parser *parser, const char *js,
- size_t len, jsmntok_t *tokens, size_t num_tokens) {
- jsmntok_t *token;
- int start;
-
- start = parser->pos;
-
- for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) {
- switch (js[parser->pos]) {
-#ifndef JSMN_STRICT
- /* In strict mode primitive must be followed by "," or "}" or "]" */
- case ':':
-#endif
- case '\t' : case '\r' : case '\n' : case ' ' :
- case ',' : case ']' : case '}' :
- goto found;
-
- default: break;
- }
- if (js[parser->pos] < 32 || js[parser->pos] >= 127) {
- parser->pos = (unsigned int) start;
- return JSMN_ERROR_INVAL;
- }
-
- }
-#ifdef JSMN_STRICT
- /* In strict mode primitive must be followed by a comma/object/array */
- parser->pos = start;
- return JSMN_ERROR_PART;
-#endif
-
-found:
- if (tokens == NULL) {
- parser->pos--;
- return 0;
- }
- token = jsmn_alloc_token(parser, tokens, num_tokens);
- if (token == NULL) {
- parser->pos = (unsigned int) start;
- return JSMN_ERROR_NOMEM;
- }
- jsmn_fill_token(token, JSMN_PRIMITIVE, start, parser->pos);
-#ifdef JSMN_PARENT_LINKS
- token->parent = parser->toksuper;
-#endif
- parser->pos--;
- return 0;
-}
-
-/**
- * Fills next token with JSON string.
- */
-static int jsmn_parse_string(jsmn_parser *parser, const char *js,
- size_t len, jsmntok_t *tokens, size_t num_tokens) {
- jsmntok_t *token;
-
- int start = parser->pos;
-
- parser->pos++;
-
- /* Skip starting quote */
- for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) {
- char c = js[parser->pos];
-
- /* Quote: end of string */
- if (c == '\"') {
- if (tokens == NULL) {
- return 0;
- }
- token = jsmn_alloc_token(parser, tokens, num_tokens);
- if (token == NULL) {
- parser->pos = (unsigned int) start;
- return JSMN_ERROR_NOMEM;
- }
- jsmn_fill_token(token, JSMN_STRING, start+1, parser->pos);
-#ifdef JSMN_PARENT_LINKS
- token->parent = parser->toksuper;
-#endif
- return 0;
- }
-
- /* Backslash: Quoted symbol expected */
- if (c == '\\' && parser->pos + 1 < len) {
- int i;
- parser->pos++;
- switch (js[parser->pos]) {
- /* Allowed escaped symbols */
- case '\"': case '/' : case '\\' : case 'b' :
- case 'f' : case 'r' : case 'n' : case 't' :
- break;
- /* Allows escaped symbol \uXXXX */
- case 'u':
- parser->pos++;
- for(i = 0; i < 4 && parser->pos < len && js[parser->pos] != '\0'; i++) {
- /* If it isn't a hex character we have an error */
- if(!((js[parser->pos] >= 48 && js[parser->pos] <= 57) || /* 0-9 */
- (js[parser->pos] >= 65 && js[parser->pos] <= 70) || /* A-F */
- (js[parser->pos] >= 97 && js[parser->pos] <= 102))) { /* a-f */
- parser->pos = (unsigned int) start;
- return JSMN_ERROR_INVAL;
- }
- parser->pos++;
- }
- parser->pos--;
- break;
- /* Unexpected symbol */
- default:
- parser->pos = (unsigned int) start;
- return JSMN_ERROR_INVAL;
- }
- }
- }
- parser->pos = (unsigned int) start;
- return JSMN_ERROR_PART;
-}
-
-/**
- * Parse JSON string and fill tokens.
- */
-int jsmn_parse(jsmn_parser *parser, const char *js, size_t len,
- jsmntok_t *tokens, unsigned int num_tokens) {
- int r;
- int i;
- jsmntok_t *token;
- int count = parser->toknext;
-
- for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) {
- char c;
- jsmntype_t type;
-
- c = js[parser->pos];
- switch (c) {
- case '{': case '[':
- count++;
- if (tokens == NULL) {
- break;
- }
- token = jsmn_alloc_token(parser, tokens, num_tokens);
- if (token == NULL)
- return JSMN_ERROR_NOMEM;
- if (parser->toksuper != -1) {
- tokens[parser->toksuper].size++;
-#ifdef JSMN_PARENT_LINKS
- token->parent = parser->toksuper;
-#endif
- }
- token->type = (c == '{' ? JSMN_OBJECT : JSMN_ARRAY);
- token->start = parser->pos;
- parser->toksuper = parser->toknext - 1;
- break;
- case '}': case ']':
- if (tokens == NULL)
- break;
- type = (c == '}' ? JSMN_OBJECT : JSMN_ARRAY);
-#ifdef JSMN_PARENT_LINKS
- if (parser->toknext < 1) {
- return JSMN_ERROR_INVAL;
- }
- token = &tokens[parser->toknext - 1];
- for (;;) {
- if (token->start != -1 && token->end == -1) {
- if (token->type != type) {
- return JSMN_ERROR_INVAL;
- }
- token->end = parser->pos + 1;
- parser->toksuper = token->parent;
- break;
- }
- if (token->parent == -1) {
- if(token->type != type || parser->toksuper == -1) {
- return JSMN_ERROR_INVAL;
- }
- break;
- }
- token = &tokens[token->parent];
- }
-#else
- for (i = parser->toknext - 1; i >= 0; i--) {
- token = &tokens[i];
- if (token->start != -1 && token->end == -1) {
- if (token->type != type) {
- return JSMN_ERROR_INVAL;
- }
- parser->toksuper = -1;
- token->end = parser->pos + 1;
- break;
- }
- }
- /* Error if unmatched closing bracket */
- if (i == -1) return JSMN_ERROR_INVAL;
- for (; i >= 0; i--) {
- token = &tokens[i];
- if (token->start != -1 && token->end == -1) {
- parser->toksuper = i;
- break;
- }
- }
-#endif
- break;
- case '\"':
- r = jsmn_parse_string(parser, js, len, tokens, num_tokens);
- if (r < 0) return r;
- count++;
- if (parser->toksuper != -1 && tokens != NULL)
- tokens[parser->toksuper].size++;
- break;
- case '\t' : case '\r' : case '\n' : case ' ':
- break;
- case ':':
- parser->toksuper = parser->toknext - 1;
- break;
- case ',':
- if (tokens != NULL && parser->toksuper != -1 &&
- tokens[parser->toksuper].type != JSMN_ARRAY &&
- tokens[parser->toksuper].type != JSMN_OBJECT) {
-#ifdef JSMN_PARENT_LINKS
- parser->toksuper = tokens[parser->toksuper].parent;
-#else
- for (i = parser->toknext - 1; i >= 0; i--) {
- if (tokens[i].type == JSMN_ARRAY || tokens[i].type == JSMN_OBJECT) {
- if (tokens[i].start != -1 && tokens[i].end == -1) {
- parser->toksuper = i;
- break;
- }
- }
- }
-#endif
- }
- break;
-#ifdef JSMN_STRICT
- /* In strict mode primitives are: numbers and booleans */
- case '-': case '0': case '1' : case '2': case '3' : case '4':
- case '5': case '6': case '7' : case '8': case '9':
- case 't': case 'f': case 'n' :
- /* And they must not be keys of the object */
- if (tokens != NULL && parser->toksuper != -1) {
- jsmntok_t *t = &tokens[parser->toksuper];
- if (t->type == JSMN_OBJECT ||
- (t->type == JSMN_STRING && t->size != 0)) {
- return JSMN_ERROR_INVAL;
- }
- }
-#else
- /* In non-strict mode every unquoted value is a primitive */
- default:
-#endif
- r = jsmn_parse_primitive(parser, js, len, tokens, num_tokens);
- if (r < 0) return r;
- count++;
- if (parser->toksuper != -1 && tokens != NULL)
- tokens[parser->toksuper].size++;
- break;
-
-#ifdef JSMN_STRICT
- /* Unexpected char in strict mode */
- default:
- return JSMN_ERROR_INVAL;
-#endif
- }
- }
-
- if (tokens != NULL) {
- for (i = parser->toknext - 1; i >= 0; i--) {
- /* Unmatched opened object or array */
- if (tokens[i].start != -1 && tokens[i].end == -1) {
- return JSMN_ERROR_PART;
- }
- }
- }
-
- return count;
-}
-
-/**
- * Creates a new parser based over a given buffer with an array of tokens
- * available.
- */
-void jsmn_init(jsmn_parser *parser) {
- parser->pos = 0;
- parser->toknext = 0;
- parser->toksuper = -1;
-}
-
diff --git a/lib/jsmn.h b/lib/jsmn.h
deleted file mode 100644
index 2f588e8..0000000
--- a/lib/jsmn.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (c) 2010 Serge A. Zaitsev
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#ifndef __JSMN_H_
-#define __JSMN_H_
-
-#include <stddef.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * JSON type identifier. Basic types are:
- * o Object
- * o Array
- * o String
- * o Other primitive: number, boolean (true/false) or null
- */
-typedef enum {
- JSMN_UNDEFINED = 0,
- JSMN_OBJECT = 1,
- JSMN_ARRAY = 2,
- JSMN_STRING = 3,
- JSMN_PRIMITIVE = 4
-} jsmntype_t;
-
-enum jsmnerr {
- /* Not enough tokens were provided */
- JSMN_ERROR_NOMEM = -1,
- /* Invalid character inside JSON string */
- JSMN_ERROR_INVAL = -2,
- /* The string is not a full JSON packet, more bytes expected */
- JSMN_ERROR_PART = -3
-};
-
-/**
- * JSON token description.
- * type type (object, array, string etc.)
- * start start position in JSON data string
- * end end position in JSON data string
- */
-typedef struct {
- jsmntype_t type;
- int start;
- int end;
- int size;
-#ifdef JSMN_PARENT_LINKS
- int parent;
-#endif
-} jsmntok_t;
-
-/**
- * JSON parser. Contains an array of token blocks available. Also stores
- * the string being parsed now and current position in that string
- */
-typedef struct {
- unsigned int pos; /* offset in the JSON string */
- unsigned int toknext; /* next token to allocate */
- int toksuper; /* superior token node, e.g parent object or array */
-} jsmn_parser;
-
-/**
- * Create JSON parser over an array of tokens
- */
-void jsmn_init(jsmn_parser *parser);
-
-/**
- * Run JSON parser. It parses a JSON data string into and array of tokens, each describing
- * a single JSON object.
- */
-int jsmn_parse(jsmn_parser *parser, const char *js, size_t len,
- jsmntok_t *tokens, unsigned int num_tokens);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __JSMN_H_ */