diff options
author | Katharina Fey <kookie@spacekookie.de> | 2016-08-27 01:07:35 +0200 |
---|---|---|
committer | Katharina Fey <kookie@spacekookie.de> | 2019-06-04 20:21:03 +0200 |
commit | caad27814fab468f66de0a3138e3900342d3acde (patch) | |
tree | cc16cc6c4152bb80d36c35f8e61feb071faa2c4f | |
parent | b3acb65150078e93a64263324dbf432e7b7d2442 (diff) |
API Changes.
- Renaming the recursive field to "list" functions
- Renaming main file to dtree for less confusion
- Allowing for long values to be stored - not just integers
- Adjusting quick access functions to use new API
-rw-r--r-- | include/dtree/dtree.h (renamed from include/dtree/dyn_tree.h) | 44 | ||||
-rw-r--r-- | lib/dtree.c (renamed from lib/dyn_tree.c) | 69 |
2 files changed, 103 insertions, 10 deletions
diff --git a/include/dtree/dyn_tree.h b/include/dtree/dtree.h index 42aa378..b46b000 100644 --- a/include/dtree/dyn_tree.h +++ b/include/dtree/dtree.h @@ -46,6 +46,7 @@ typedef struct dtree { dt_uni_t type; short encset; size_t size, used; + short copy; union { char *literal; long numeral; @@ -97,7 +98,7 @@ dt_err dtree_resettype(dtree *data); * @param length TRUE string length to use. * @return */ -dt_err dtree_addliteral(dtree *data, const char *literal, size_t length); +dt_err dtree_addliteral(dtree *data, const char *literal); /** @@ -107,7 +108,7 @@ dt_err dtree_addliteral(dtree *data, const char *literal, size_t length); * @param numeral Number to store * @return */ -dt_err dtree_addnumeral(dtree *data, int numeral); +dt_err dtree_addnumeral(dtree *data, long numeral); /** @@ -128,7 +129,7 @@ dt_err dtree_addpair(dtree *data, dtree *(*key), dtree *(*value)); * @param new_data Reference pointer to a new dtree node * @return */ -dt_err dtree_addrecursive(dtree *data, dtree *(*new_data)); +dt_err dtree_addlist(dtree *data, dtree *(*new_data)); /** @@ -149,6 +150,7 @@ dt_err dtree_addrecursive(dtree *data, dtree *(*new_data)); */ dt_err dtree_addpointer(dtree *data, void *ptr); + /** * This function takes two nodes as arguments. The nodes MUST be * related or an error will be thrown. Both nodes will still @@ -165,6 +167,7 @@ dt_err dtree_addpointer(dtree *data, void *ptr); */ dt_err dtree_split_trees(dtree *data, dtree *sp); + /** * This function is very simmilar to dt_err "dtree_addrecursive" * with the difference that it doesn't allocate new memory but instead @@ -196,6 +199,32 @@ dt_err dtree_merge_trees(dtree *data, dtree *merge); */ dt_err dtree_search_payload(dtree *data, dtree *(*found), void *payload, dt_uni_t type); + +/** + * Performs a deep copy of a data node hirarchy. Does not copy externally + * pointed structures. Does garuantee safety of hirarchy. + * + * @param data + * @param copy + * @return + */ +dt_err dtree_deep_copy(dtree *data, dtree *(*copy)); + + +/** + * Performs a copy operation on a single node. Copies the payload on a pointer + * level which means that strings and numbers will be duplicated whereas external + * pointers and lists will only be references to the original content. + * + * Freeing the copy has no effect on the original payloads stored in other + * nodes. + * + * @param data + * @param copy + * @return + */ +dt_err dtree_copy(dtree *data, dtree *(*copy)); + /** * A retrieve function to get data back from a node that doesn't require * you to manually access parts of the struct. @@ -228,6 +257,7 @@ const char *dtree_dtype(dtree *data); */ void dtree_print(dtree *data); + /** * Will free the data reference and all of it's children. It will however NOT * touch pointers to objects that weren't allocated by libdyntree! @@ -237,6 +267,7 @@ void dtree_print(dtree *data); */ dt_err dtree_free_shallow(dtree *data); + /** * Like #{dtree_free_shallow} but will also remove structs that * weren't allocated by libdyntree @@ -246,6 +277,7 @@ dt_err dtree_free_shallow(dtree *data); */ dt_err dtree_free(dtree *data); + /************************** * * Error handling functions @@ -312,7 +344,7 @@ static dtree *dtree_alloc_literal(const char *string) { dtree *node; dtree_malloc(&node); - dtree_addliteral(node, string, REAL_STRLEN(string)); + dtree_addliteral(node, string); return node; } @@ -363,7 +395,7 @@ static dtree *dtree_allocpair_new(dtree **key, dtree **val) * @param count * @return */ -static dtree **dtree_alloc_reclist(dtree **root, unsigned int count) +static dtree **dtree_alloc_listlist(dtree **root, unsigned int count) { dtree **nodes = malloc(sizeof(dtree**) * count); @@ -371,7 +403,7 @@ static dtree **dtree_alloc_reclist(dtree **root, unsigned int count) int i; for(i = 0; i < count; i++) - dtree_addrecursive(*root, &nodes[i]); + dtree_addlist(*root, &nodes[i]); return nodes; } diff --git a/lib/dyn_tree.c b/lib/dtree.c index 49cfd78..746ca13 100644 --- a/lib/dyn_tree.c +++ b/lib/dtree.c @@ -1,5 +1,5 @@ // Include our header file -#include <dtree/dyn_tree.h> +#include <dtree/dtree.h> // Runtime includes #include <stdlib.h> @@ -10,6 +10,10 @@ #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 recursive_search(dtree**, dtree *, dtree *); @@ -55,12 +59,14 @@ dt_err dtree_resettype(dtree *data) return SUCCESS; } -dt_err dtree_addliteral(dtree *data, const char *literal, size_t length) +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); @@ -96,7 +102,7 @@ dt_err dtree_addpointer(dtree *data, void *ptr) } -dt_err dtree_addnumeral(dtree *data, int numeral) +dt_err dtree_addnumeral(dtree *data, long numeral) { /* Make sure we are a literal or unset data object */ if(data->type != UNSET) @@ -110,7 +116,7 @@ dt_err dtree_addnumeral(dtree *data, int numeral) } -dt_err dtree_addrecursive(dtree *data, dtree *(*new_data)) +dt_err dtree_addlist(dtree *data, dtree *(*new_data)) { /* Make sure we are a literal or unset data object */ if(data->type != UNSET) @@ -261,6 +267,61 @@ dt_err dtree_merge_trees(dtree *data, dtree *merge) } +dt_err dtree_deep_copy(dtree *data, dtree *(*copy)) +{ + if(data == NULL) return INVALID_PARAMS; + + return SUCCESS; +} + +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 NUMERAL: + err = dtree_addnumeral(*copy, data->payload.numeral); + break; + + case RECURSIVE: + (*copy)->type = RECURSIVE; + (*copy)->payload.recursive = (dtree**) malloc(sizeof(dtree*) * data->size); + memcpy((*copy)->payload.recursive, data->payload.recursive, sizeof(dtree*) * data->used); + break; + + case PAIR: + (*copy)->type = PAIR; + (*copy)->payload.recursive = (dtree**) malloc(sizeof(dtree*) * data->size); + memcpy((*copy)->payload.recursive, data->payload.recursive, 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; |