aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKatharina Fey <kookie@spacekookie.de>2016-08-27 01:07:35 +0200
committerKatharina Fey <kookie@spacekookie.de>2019-06-04 20:21:03 +0200
commitcaad27814fab468f66de0a3138e3900342d3acde (patch)
treecc16cc6c4152bb80d36c35f8e61feb071faa2c4f
parentb3acb65150078e93a64263324dbf432e7b7d2442 (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;