Przeglądaj źródła

use size_t for offsets, improve the nodestore API

Julius Pfrommer 9 lat temu
rodzic
commit
210ea01a80

+ 21 - 41
include/ua_types.h

@@ -22,6 +22,7 @@ extern "C" {
 
 #include <stdint.h>
 #include <stdbool.h>
+#include <stddef.h>
 #include "ua_config.h"
 
 /**
@@ -332,9 +333,6 @@ UA_TYPE_HANDLING_FUNCTIONS(UA_DiagnosticInfo)
 UA_StatusCode UA_EXPORT UA_String_copycstring(char const *src, UA_String *dst);
 UA_StatusCode UA_EXPORT UA_String_copyprintf(char const *fmt, UA_String *dst, ...);
 UA_Boolean UA_EXPORT UA_String_equal(const UA_String *string1, const UA_String *string2);
-void UA_EXPORT UA_String_printf(char const *label, const UA_String *string);
-void UA_EXPORT UA_String_printx(char const *label, const UA_String *string);
-void UA_EXPORT UA_String_printx_hex(char const *label, const UA_String *string);
 
 /* DateTime */
 UA_DateTime UA_EXPORT UA_DateTime_now(void);
@@ -360,9 +358,6 @@ UA_Guid UA_EXPORT UA_Guid_random(UA_UInt32 *seed);
 /* ByteString */
 UA_Boolean UA_EXPORT UA_ByteString_equal(const UA_ByteString *string1, const UA_ByteString *string2);
 UA_StatusCode UA_EXPORT UA_ByteString_newMembers(UA_ByteString *p, UA_Int32 length);
-void UA_EXPORT UA_ByteString_printf(char *label, const UA_ByteString *string);
-void UA_EXPORT UA_ByteString_printx(char *label, const UA_ByteString *string);
-void UA_EXPORT UA_ByteString_printx_hex(char *label, const UA_ByteString *string);
 
 /* NodeId */
 UA_Boolean UA_EXPORT UA_NodeId_equal(const UA_NodeId *n1, const UA_NodeId *n2);
@@ -404,48 +399,33 @@ UA_StatusCode UA_EXPORT UA_Variant_copySetArray(UA_Variant *v, const void *array
 #define UA_MAX_TYPE_MEMBERS 13 // Maximum number of members per complex type
 
 #ifndef _WIN32
+# define UA_BITFIELD(SIZE) : SIZE
+#else
+# define UA_BITFIELD(SIZE)
+#endif
+
 typedef struct {
-    UA_UInt16 memberTypeIndex : 9; ///< Index of the member in the datatypetable
-    UA_Boolean namespaceZero : 1; /**< The type of the member is defined in namespace zero. In this
-                                       implementation, types from custom namespace may contain
-                                       members from the same namespace or ns0 only.*/
-    UA_Byte padding : 5; /**< How much padding is there before this member element? For arrays this
-                              is split into 2 bytes padding for for the length index (max 4 bytes)
-                              and 3 bytes padding for the pointer (max 8 bytes) */
-    UA_Boolean isArray : 1; ///< The member is an array of the given type
+    UA_UInt16 memberTypeIndex UA_BITFIELD(9); ///< Index of the member in the datatypetable
+    UA_Boolean namespaceZero UA_BITFIELD(1); /**< The type of the member is defined in namespace
+                                                  zero. In this implementation, types from custom
+                                                  namespace may contain members from the same
+                                                  namespace or ns0 only.*/
+    UA_Byte padding UA_BITFIELD(5); /**< How much padding is there before this member element? For
+                                         arrays this is split into 2 bytes padding for for the
+                                         length index (max 4 bytes) and 3 bytes padding for the
+                                         pointer (max 8 bytes) */
+    UA_Boolean isArray UA_BITFIELD(1); ///< The member is an array of the given type
 } UA_DataTypeMember;
     
 struct UA_DataType {
-    UA_UInt16 memSize; ///< Size of the struct in memory
-    UA_UInt16 typeIndex : 13; ///< Index of the type in the datatytypetable
-    UA_Boolean namespaceZero : 1; ///< The type is defined in namespace zero.
-    UA_Boolean fixedSize : 1; ///< The type (and its members) contains no pointers
-    UA_Boolean zeroCopyable : 1; ///< Can the type be copied directly off the stream?
+    size_t memSize UA_BITFIELD(16); ///< Size of the struct in memory
+    size_t typeIndex UA_BITFIELD(13); ///< Index of the type in the datatytypetable
+    UA_Boolean namespaceZero UA_BITFIELD(1); ///< The type is defined in namespace zero.
+    UA_Boolean fixedSize UA_BITFIELD(1); ///< The type (and its members) contains no pointers
+    UA_Boolean zeroCopyable UA_BITFIELD(1); ///< Can the type be copied directly off the stream?
     UA_Byte membersSize; ///< How many members does the type have?
     UA_DataTypeMember members[UA_MAX_TYPE_MEMBERS];
 };
-#else
-typedef struct {
-	UA_UInt16 memberTypeIndex; ///< Index of the member in the datatypetable
-	UA_Boolean namespaceZero; /**< The type of the member is defined in namespace zero. In this
-								  implementation, types from custom namespace may contain
-								  members from the same namespace or ns0 only.*/
-	UA_Byte padding; /**< How much padding is there before this member element? For arrays this
-						 is split into 2 bytes padding for for the length index (max 4 bytes)
-						 and 3 bytes padding for the pointer (max 8 bytes) */
-	UA_Boolean isArray; ///< The member is an array of the given type
-} UA_DataTypeMember;
-
-struct UA_DataType {
-	UA_UInt16 memSize; ///< Size of the struct in memory
-	UA_UInt16 typeIndex; ///< Index of the type in the datatytypetable
-	UA_Boolean namespaceZero; ///< The type is defined in namespace zero.
-	UA_Boolean fixedSize; ///< The type (and its members) contains no pointers
-	UA_Boolean zeroCopyable; ///< Can the type be copied directly off the stream?
-	UA_Byte membersSize; ///< How many members does the type have?
-	UA_DataTypeMember members[UA_MAX_TYPE_MEMBERS];
-};
-#endif
 
 void UA_EXPORT * UA_new(const UA_DataType *dataType);
 void UA_EXPORT UA_init(void *p, const UA_DataType *dataType);

+ 18 - 51
src/server/ua_nodestore.c

@@ -165,8 +165,7 @@ static void deleteEntry(struct nodeEntry *entry) {
 
 /** Copies the node into the entry. Then free the original node (but not its content). */
 static struct nodeEntry * nodeEntryFromNode(UA_Node *node) {
-    UA_UInt32 nodesize = 0;
-    
+    size_t nodesize = 0;
     switch(node->nodeClass) {
     case UA_NODECLASS_OBJECT:
         nodesize = sizeof(UA_ObjectNode);
@@ -241,69 +240,55 @@ void UA_NodeStore_delete(UA_NodeStore *ns) {
     UA_free(ns);
 }
 
-UA_StatusCode UA_NodeStore_insert(UA_NodeStore *ns, const UA_Node **node, UA_Boolean getManaged) {
+UA_StatusCode UA_NodeStore_insert(UA_NodeStore *ns, UA_Node *node, const UA_Node **inserted) {
     if(ns->size * 3 <= ns->count * 4) {
         if(expand(ns) != UA_STATUSCODE_GOOD)
             return UA_STATUSCODE_BADINTERNALERROR;
     }
     
-    /* The node is const so the user gets a const pointer back. Still, we want
-       to make small changes to the node internally, then add it to the hashmap
-       and return a new const pointer. */
-#if defined(__GNUC__) || defined(__clang__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wcast-qual"
-#endif
-    UA_Node *editableNode = (UA_Node*)*node;
-#if defined(__GNUC__) || defined(__clang__)
-#pragma GCC diagnostic pop
-#endif
-
     // get a free slot
     struct nodeEntry **slot;
-    UA_NodeId *nodeId = &editableNode->nodeId;
-    if(UA_NodeId_isNull(nodeId)) {
+    if(UA_NodeId_isNull(&node->nodeId)) {
         // find a unique nodeid that is not taken
-        nodeId->identifierType = UA_NODEIDTYPE_NUMERIC;
-        nodeId->namespaceIndex = 1; // namespace 1 is always in the local nodestore
+        node->nodeId.identifierType = UA_NODEIDTYPE_NUMERIC;
+        node->nodeId.namespaceIndex = 1; // namespace 1 is always in the local nodestore
         UA_Int32 identifier = ns->count+1; // start value
         UA_Int32 size = ns->size;
         hash_t increase = mod2(identifier, size);
         while(UA_TRUE) {
-            nodeId->identifier.numeric = identifier;
-            if(!containsNodeId(ns, nodeId, &slot))
+            node->nodeId.identifier.numeric = identifier;
+            if(!containsNodeId(ns, &node->nodeId, &slot))
                 break;
             identifier += increase;
             if(identifier >= size)
                 identifier -= size;
         }
     } else {
-        if(containsNodeId(ns, nodeId, &slot))
+        if(containsNodeId(ns, &node->nodeId, &slot))
             return UA_STATUSCODE_BADNODEIDEXISTS;
     }
     
-    struct nodeEntry *entry = nodeEntryFromNode(editableNode);
+    struct nodeEntry *entry = nodeEntryFromNode(node);
     if(!entry)
         return UA_STATUSCODE_BADOUTOFMEMORY;
 
     *slot = entry;
     ns->count++;
 
-    if(getManaged) {
+    if(inserted) {
         entry->refcount = ALIVE_BIT + 1;
-        *node = &entry->node;
+        *inserted = &entry->node;
     } else {
         entry->refcount = ALIVE_BIT;
-        *node = UA_NULL;
     }
 
     return UA_STATUSCODE_GOOD;
 }
 
-UA_StatusCode UA_NodeStore_replace(UA_NodeStore *ns, const UA_Node *oldNode,
-                                   const UA_Node **node, UA_Boolean getManaged) {
+UA_StatusCode UA_NodeStore_replace(UA_NodeStore *ns, const UA_Node *oldNode, UA_Node *node,
+                                   const UA_Node **inserted) {
     struct nodeEntry **slot;
-    const UA_NodeId *nodeId = &(*node)->nodeId;
+    const UA_NodeId *nodeId = &node->nodeId;
     if(!containsNodeId(ns, nodeId, &slot))
         return UA_STATUSCODE_BADNODEIDUNKNOWN;
 
@@ -312,28 +297,18 @@ UA_StatusCode UA_NodeStore_replace(UA_NodeStore *ns, const UA_Node *oldNode,
     if(&(*slot)->node != oldNode)
         return UA_STATUSCODE_BADINTERNALERROR;
 
-    /* We need to able to free the new node when copying it into the entry. */
-#if defined(__GNUC__) || defined(__clang__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wcast-qual"
-#endif
-    struct nodeEntry *entry = nodeEntryFromNode((UA_Node *)*node);
-#if defined(__GNUC__) || defined(__clang__)
-#pragma GCC diagnostic pop
-#endif
-
+    struct nodeEntry *entry = nodeEntryFromNode(node);
     if(!entry)
         return UA_STATUSCODE_BADOUTOFMEMORY;
 
     (*slot)->refcount &= ~ALIVE_BIT; // mark dead
     *slot = entry;
 
-    if(getManaged) {
+    if(inserted) {
         entry->refcount = ALIVE_BIT + 1;
-        *node = &entry->node;
+        *inserted = &entry->node;
     } else {
         entry->refcount = ALIVE_BIT;
-        *node = UA_NULL;
     }
     return UA_STATUSCODE_GOOD;
 }
@@ -374,15 +349,7 @@ void UA_NodeStore_iterate(const UA_NodeStore *ns, UA_NodeStore_nodeVisitor visit
 void UA_NodeStore_release(const UA_Node *managed) {
     /* We know what we are doing here and remove a compiler warning. Nobody has
        a reference to the const pointer, so we can free it. */
-#if defined(__GNUC__) || defined(__clang__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wcast-qual"
-#pragma GCC diagnostic ignored "-Wcast-align"
-#endif
-    struct nodeEntry *entry = (struct nodeEntry *) ((UA_Byte*)managed - offsetof(struct nodeEntry, node));
-#if defined(__GNUC__) || defined(__clang__)
-#pragma GCC diagnostic pop
-#endif
+    struct nodeEntry *entry = (struct nodeEntry *) ((uintptr_t)managed - offsetof(struct nodeEntry, node));
     entry->refcount--;
     deleteEntry(entry);
 }

+ 10 - 10
src/server/ua_nodestore.h

@@ -35,20 +35,20 @@ UA_NodeStore * UA_NodeStore_new(void);
 void UA_NodeStore_delete(UA_NodeStore *ns);
 
 /**
- * Inserts a new node into the namespace. With the getManaged flag, the node
- * pointer is replaced with the managed pointer. Otherwise, it is set to
- * UA_NULL. If the nodeid is zero, then a fresh numeric nodeid from namespace 1
- * is assigned.
+ * Inserts a new node into the namespace. If the nodeid is zero, then a fresh
+ * numeric nodeid from namespace 1 is assigned. The memory of the original node
+ * is freed and the content is moved to a managed (immutable) node. If inserted
+ * is not NULL, then a pointer to the managed node is returned (and must be
+ * released).
  */
-UA_StatusCode UA_NodeStore_insert(UA_NodeStore *ns, const UA_Node **node, UA_Boolean getManaged);
+UA_StatusCode UA_NodeStore_insert(UA_NodeStore *ns, UA_Node *node, const UA_Node **inserted);
 
 /**
- * Replace an existing node in the nodestore. With the getManaged flag, the node
- * pointer is replaced with the managed pointer. Otherwise, it is set to
- * UA_NULL. If the return value is UA_STATUSCODE_BADINTERNALERROR, try again.
- * Presumably the oldNode was already replaced by another thread.
+ * Replace an existing node in the nodestore. If the node was already replaced,
+ * UA_STATUSCODE_BADINTERNALERROR is returned. If inserted is not NULL, a
+ * pointer to the managed (immutable) node is returned.
  */
-UA_StatusCode UA_NodeStore_replace(UA_NodeStore *ns, const UA_Node *oldNode, const UA_Node **node, UA_Boolean getManaged);
+UA_StatusCode UA_NodeStore_replace(UA_NodeStore *ns, const UA_Node *oldNode, UA_Node *node, const UA_Node **inserted);
 
 /**
  * Remove a node from the namespace. Always succeeds, even if the node was not

+ 31 - 92
src/server/ua_nodestore_concurrent.c

@@ -66,15 +66,7 @@ static int compare(struct cds_lfht_node *htn, const void *orig) {
    section) increased the refcount, we only need to wait for the refcount
    to reach zero. */
 static void markDead(struct rcu_head *head) {
-#if defined(__GNUC__) || defined(__clang__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wcast-align"
-#endif
-    struct nodeEntry *entry = caa_container_of(head, struct nodeEntry, rcu_head);
-#if defined(__GNUC__) || defined(__clang__)
-#pragma GCC diagnostic pop
-#endif
-
+    struct nodeEntry *entry = (struct nodeEntry*) ((uintptr_t)head - offsetof(struct nodeEntry, rcu_head)); 
     uatomic_and(&entry->refcount, ~ALIVE_BIT); // set the alive bit to zero
     if(uatomic_read(&entry->refcount) > 0)
         return;
@@ -85,20 +77,11 @@ static void markDead(struct rcu_head *head) {
 
 /* Free the entry if it is dead and nobody uses it anymore */
 void UA_NodeStore_release(const UA_Node *managed) {
-#if defined(__GNUC__) || defined(__clang__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wcast-align"
-#endif
-    struct nodeEntry *entry = caa_container_of(managed, struct nodeEntry, node); // pointer to the first entry
-#if defined(__GNUC__) || defined(__clang__)
-#pragma GCC diagnostic pop
-#endif
-
-    if(uatomic_add_return(&entry->refcount, -1) > 0)
-        return;
-
-    node_deleteMembers(&entry->node);
-    UA_free(entry);
+    struct nodeEntry *entry = (struct nodeEntry*) ((uintptr_t)managed - offsetof(struct nodeEntry, node)); 
+    if(uatomic_add_return(&entry->refcount, -1) == 0) {
+        node_deleteMembers(&entry->node);
+        UA_free(entry);
+    }
 }
 
 UA_NodeStore * UA_NodeStore_new() {
@@ -123,14 +106,7 @@ void UA_NodeStore_delete(UA_NodeStore *ns) {
     cds_lfht_first(ht, &iter);
     while(iter.node) {
         if(!cds_lfht_del(ht, iter.node)) {
-#if defined(__GNUC__) || defined(__clang__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wcast-align"
-#endif
-            struct nodeEntry *entry = caa_container_of(iter.node, struct nodeEntry, htn);
-#if defined(__GNUC__) || defined(__clang__)
-#pragma GCC diagnostic pop
-#endif
+            struct nodeEntry *entry = (struct nodeEntry*) ((uintptr_t)iter.node - offsetof(struct nodeEntry, htn)); 
             call_rcu(&entry->rcu_head, markDead);
         }
         cds_lfht_next(ht, &iter);
@@ -141,10 +117,10 @@ void UA_NodeStore_delete(UA_NodeStore *ns) {
     UA_free(ns);
 }
 
-UA_StatusCode UA_NodeStore_insert(UA_NodeStore *ns, const UA_Node **node, UA_Boolean getManaged) {
-    UA_UInt32 nodesize;
+UA_StatusCode UA_NodeStore_insert(UA_NodeStore *ns, UA_Node *node, const UA_Node **inserted) {
+    size_t nodesize;
     /* Copy the node into the entry. Then reset the original node. It shall no longer be used. */
-    switch((*node)->nodeClass) {
+    switch(node->nodeClass) {
     case UA_NODECLASS_OBJECT:
         nodesize = sizeof(UA_ObjectNode);
         break;
@@ -176,16 +152,16 @@ UA_StatusCode UA_NodeStore_insert(UA_NodeStore *ns, const UA_Node **node, UA_Boo
     struct nodeEntry *entry;
     if(!(entry = UA_malloc(sizeof(struct nodeEntry) - sizeof(UA_Node) + nodesize)))
         return UA_STATUSCODE_BADOUTOFMEMORY;
-    UA_memcpy((void*)&entry->node, *node, nodesize);
+    UA_memcpy((void*)&entry->node, node, nodesize);
 
     cds_lfht_node_init(&entry->htn);
     entry->refcount = ALIVE_BIT;
-    if(getManaged) // increase the counter before adding the node
+    if(inserted) // increase the counter before adding the node
         entry->refcount++;
 
     struct cds_lfht_node *result;
-    if(!UA_NodeId_isNull(&(*node)->nodeId)) {
-        hash_t h = hash(&(*node)->nodeId);
+    if(!UA_NodeId_isNull(&node->nodeId)) {
+        hash_t h = hash(&node->nodeId);
         rcu_read_lock();
         result = cds_lfht_add_unique(ns->ht, h, compare, &entry->node.nodeId, &entry->htn);
         rcu_read_unlock();
@@ -217,27 +193,17 @@ UA_StatusCode UA_NodeStore_insert(UA_NodeStore *ns, const UA_Node **node, UA_Boo
         rcu_read_unlock();
     }
 
-#if defined(__GNUC__) || defined(__clang__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wcast-qual"
-#endif
-    UA_free((UA_Node *)*node);     /* The old node is replaced by a managed node. */
-#if defined(__GNUC__) || defined(__clang__)
-#pragma GCC diagnostic pop
-#endif
-
-    if(getManaged)
-        *node = &entry->node;
-    else
-        *node = UA_NULL;
+    UA_free(node);
+    if(inserted)
+        *inserted = &entry->node;
     return UA_STATUSCODE_GOOD;
 }
 
-UA_StatusCode UA_NodeStore_replace(UA_NodeStore *ns, const UA_Node *oldNode,
-                                   const UA_Node **node, UA_Boolean getManaged) {
-    UA_UInt32 nodesize;
+UA_StatusCode UA_NodeStore_replace(UA_NodeStore *ns, const UA_Node *oldNode, UA_Node *node,
+                                   const UA_Node **inserted) {
+    size_t nodesize;
     /* Copy the node into the entry. Then reset the original node. It shall no longer be used. */
-    switch((*node)->nodeClass) {
+    switch(node->nodeClass) {
     case UA_NODECLASS_OBJECT:
         nodesize = sizeof(UA_ObjectNode);
         break;
@@ -269,18 +235,17 @@ UA_StatusCode UA_NodeStore_replace(UA_NodeStore *ns, const UA_Node *oldNode,
     struct nodeEntry *newEntry;
     if(!(newEntry = UA_malloc(sizeof(struct nodeEntry) - sizeof(UA_Node) + nodesize)))
         return UA_STATUSCODE_BADOUTOFMEMORY;
-    UA_memcpy((void*)&newEntry->node, *node, nodesize);
+    UA_memcpy((void*)&newEntry->node, node, nodesize);
 
     cds_lfht_node_init(&newEntry->htn);
     newEntry->refcount = ALIVE_BIT;
-    if(getManaged) // increase the counter before adding the node
+    if(inserted) // increase the counter before adding the node
         newEntry->refcount++;
 
-    hash_t h = hash(&(*node)->nodeId);
-
+    hash_t h = hash(&node->nodeId);
     struct cds_lfht_iter iter;
     rcu_read_lock();
-    cds_lfht_lookup(ns->ht, h, compare, &(*node)->nodeId, &iter);
+    cds_lfht_lookup(ns->ht, h, compare, &node->nodeId, &iter);
 
     /* No node found that can be replaced */
     if(!iter.node) {
@@ -289,14 +254,7 @@ UA_StatusCode UA_NodeStore_replace(UA_NodeStore *ns, const UA_Node *oldNode,
         return UA_STATUSCODE_BADNODEIDUNKNOWN;
     }
 
-#if defined(__GNUC__) || defined(__clang__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wcast-align"
-#endif
-    struct nodeEntry *oldEntry = caa_container_of(iter.node, struct nodeEntry, htn);
-#if defined(__GNUC__) || defined(__clang__)
-#pragma GCC diagnostic pop
-#endif
+    struct nodeEntry *oldEntry = (struct nodeEntry*) ((uintptr_t)iter.node - offsetof(struct nodeEntry, htn)); 
     /* The node we found is obsolete*/
     if(&oldEntry->node != oldNode) {
         rcu_read_unlock();
@@ -305,7 +263,7 @@ UA_StatusCode UA_NodeStore_replace(UA_NodeStore *ns, const UA_Node *oldNode,
     }
 
     /* The old node is replaced by a managed node. */
-    if(cds_lfht_replace(ns->ht, &iter, h, compare, &(*node)->nodeId, &newEntry->htn) != 0) {
+    if(cds_lfht_replace(ns->ht, &iter, h, compare, &node->nodeId, &newEntry->htn) != 0) {
         /* Replacing failed. Maybe the node got replaced just before this thread tried to.*/
         rcu_read_unlock();
         UA_free(newEntry);
@@ -315,21 +273,10 @@ UA_StatusCode UA_NodeStore_replace(UA_NodeStore *ns, const UA_Node *oldNode,
     /* If an entry got replaced, mark it as dead. */
     call_rcu(&oldEntry->rcu_head, markDead);
     rcu_read_unlock();
+    UA_free(node);
 
-#if defined(__GNUC__) || defined(__clang__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wcast-qual"
-#endif
-    UA_free((UA_Node *)*node); // was copied to newEntry and is obsolete
-#if defined(__GNUC__) || defined(__clang__)
-#pragma GCC diagnostic pop
-#endif
-
-    if(getManaged)
-        *node = &newEntry->node;
-    else
-        *node = UA_NULL;
-
+    if(inserted)
+        *inserted = &newEntry->node;
     return UA_STATUSCODE_GOOD;
 }
 
@@ -345,15 +292,7 @@ UA_StatusCode UA_NodeStore_remove(UA_NodeStore *ns, const UA_NodeId *nodeid) {
         return UA_STATUSCODE_BADNODEIDUNKNOWN;
     }
 
-#if defined(__GNUC__) || defined(__clang__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wcast-align"
-#endif
-    struct nodeEntry *entry = caa_container_of(iter.node, struct nodeEntry, htn);
-#if defined(__GNUC__) || defined(__clang__)
-#pragma GCC diagnostic pop
-#endif
-
+    struct nodeEntry *entry = (struct nodeEntry*) ((uintptr_t)iter.node - offsetof(struct nodeEntry, htn)); 
     call_rcu(&entry->rcu_head, markDead);
     rcu_read_unlock();
 

+ 32 - 32
src/server/ua_server.c

@@ -163,7 +163,7 @@ UA_Server * UA_Server_new(void) {
     references->isAbstract = UA_TRUE;
     references->symmetric  = UA_TRUE;
     // this node has no parent??
-    UA_NodeStore_insert(server->nodestore, (const UA_Node**)&references, UA_FALSE);
+    UA_NodeStore_insert(server->nodestore, (UA_Node*)references, UA_NULL);
 
     UA_ReferenceTypeNode *hassubtype = UA_ReferenceTypeNode_new();
     COPYNAMES(hassubtype, "HasSubtype");
@@ -172,7 +172,7 @@ UA_Server * UA_Server_new(void) {
     hassubtype->nodeClass  = UA_NODECLASS_REFERENCETYPE;
     hassubtype->isAbstract = UA_FALSE;
     hassubtype->symmetric  = UA_FALSE;
-    UA_NodeStore_insert(server->nodestore, (const UA_Node**)&hassubtype, UA_FALSE);
+    UA_NodeStore_insert(server->nodestore, (UA_Node*)hassubtype, UA_NULL);
 
     /* continue adding reference types with normal "addnode" */
     UA_ReferenceTypeNode *hierarchicalreferences = UA_ReferenceTypeNode_new();
@@ -181,7 +181,7 @@ UA_Server * UA_Server_new(void) {
     hierarchicalreferences->nodeClass  = UA_NODECLASS_REFERENCETYPE;
     hierarchicalreferences->isAbstract = UA_TRUE;
     hierarchicalreferences->symmetric  = UA_FALSE;
-    UA_Server_addNode(server, (const UA_Node**)&hierarchicalreferences,
+    UA_Server_addNode(server, (UA_Node*)hierarchicalreferences,
                       &UA_EXPANDEDNODEID_STATIC(UA_NS0ID_REFERENCES,0),
                       &UA_NODEID_STATIC(UA_NS0ID_HASSUBTYPE,0));
 
@@ -191,7 +191,7 @@ UA_Server * UA_Server_new(void) {
     nonhierarchicalreferences->nodeClass  = UA_NODECLASS_REFERENCETYPE;
     nonhierarchicalreferences->isAbstract = UA_TRUE;
     nonhierarchicalreferences->symmetric  = UA_FALSE;
-    UA_Server_addNode(server, (const UA_Node **)&nonhierarchicalreferences,
+    UA_Server_addNode(server, (UA_Node*)nonhierarchicalreferences,
                       &UA_EXPANDEDNODEID_STATIC(UA_NS0ID_REFERENCES,0),
                       &UA_NODEID_STATIC(UA_NS0ID_HASSUBTYPE,0));
 
@@ -201,7 +201,7 @@ UA_Server * UA_Server_new(void) {
     haschild->nodeClass  = UA_NODECLASS_REFERENCETYPE;
     haschild->isAbstract = UA_TRUE;
     haschild->symmetric  = UA_FALSE;
-    UA_Server_addNode(server, (const UA_Node **)&haschild,
+    UA_Server_addNode(server, (UA_Node*)haschild,
                       &UA_EXPANDEDNODEID_STATIC(UA_NS0ID_HIERARCHICALREFERENCES,0),
                       &UA_NODEID_STATIC(UA_NS0ID_HASSUBTYPE,0));
 
@@ -212,7 +212,7 @@ UA_Server * UA_Server_new(void) {
     organizes->nodeClass  = UA_NODECLASS_REFERENCETYPE;
     organizes->isAbstract = UA_FALSE;
     organizes->symmetric  = UA_FALSE;
-    UA_Server_addNode(server, (const UA_Node **)&organizes,
+    UA_Server_addNode(server, (UA_Node*)organizes,
                       &UA_EXPANDEDNODEID_STATIC(UA_NS0ID_HIERARCHICALREFERENCES,0),
                       &UA_NODEID_STATIC(UA_NS0ID_HASSUBTYPE,0));
 
@@ -223,7 +223,7 @@ UA_Server * UA_Server_new(void) {
     haseventsource->nodeClass  = UA_NODECLASS_REFERENCETYPE;
     haseventsource->isAbstract = UA_FALSE;
     haseventsource->symmetric  = UA_FALSE;
-    UA_Server_addNode(server, (const UA_Node **)&haseventsource,
+    UA_Server_addNode(server, (UA_Node*)haseventsource,
                       &UA_EXPANDEDNODEID_STATIC(UA_NS0ID_HIERARCHICALREFERENCES,0),
                       &UA_NODEID_STATIC(UA_NS0ID_HASSUBTYPE,0));
 
@@ -234,7 +234,7 @@ UA_Server * UA_Server_new(void) {
     hasmodellingrule->nodeClass  = UA_NODECLASS_REFERENCETYPE;
     hasmodellingrule->isAbstract = UA_FALSE;
     hasmodellingrule->symmetric  = UA_FALSE;
-    UA_Server_addNode(server, (const UA_Node **)&hasmodellingrule,
+    UA_Server_addNode(server, (UA_Node*)hasmodellingrule,
                       &UA_EXPANDEDNODEID_STATIC(UA_NS0ID_NONHIERARCHICALREFERENCES,0),
                       &UA_NODEID_STATIC(UA_NS0ID_HASSUBTYPE,0));
 
@@ -245,7 +245,7 @@ UA_Server * UA_Server_new(void) {
     hasencoding->nodeClass  = UA_NODECLASS_REFERENCETYPE;
     hasencoding->isAbstract = UA_FALSE;
     hasencoding->symmetric  = UA_FALSE;
-    UA_Server_addNode(server, (const UA_Node **)&hasencoding,
+    UA_Server_addNode(server, (UA_Node*)hasencoding,
                       &UA_EXPANDEDNODEID_STATIC(UA_NS0ID_NONHIERARCHICALREFERENCES,0),
                       &UA_NODEID_STATIC(UA_NS0ID_HASSUBTYPE,0));
 
@@ -256,7 +256,7 @@ UA_Server * UA_Server_new(void) {
     hasdescription->nodeClass  = UA_NODECLASS_REFERENCETYPE;
     hasdescription->isAbstract = UA_FALSE;
     hasdescription->symmetric  = UA_FALSE;
-    UA_Server_addNode(server, (const UA_Node **)&hasdescription,
+    UA_Server_addNode(server, (UA_Node*)hasdescription,
                       &UA_EXPANDEDNODEID_STATIC(UA_NS0ID_NONHIERARCHICALREFERENCES,0),
                       &UA_NODEID_STATIC(UA_NS0ID_HASSUBTYPE,0));
 
@@ -267,7 +267,7 @@ UA_Server * UA_Server_new(void) {
     hastypedefinition->nodeClass  = UA_NODECLASS_REFERENCETYPE;
     hastypedefinition->isAbstract = UA_FALSE;
     hastypedefinition->symmetric  = UA_FALSE;
-    UA_Server_addNode(server, (const UA_Node **)&hastypedefinition,
+    UA_Server_addNode(server, (UA_Node*)hastypedefinition,
                       &UA_EXPANDEDNODEID_STATIC(UA_NS0ID_NONHIERARCHICALREFERENCES,0),
                       &UA_NODEID_STATIC(UA_NS0ID_HASSUBTYPE,0));
 
@@ -278,7 +278,7 @@ UA_Server * UA_Server_new(void) {
     generatesevent->nodeClass  = UA_NODECLASS_REFERENCETYPE;
     generatesevent->isAbstract = UA_FALSE;
     generatesevent->symmetric  = UA_FALSE;
-    UA_Server_addNode(server, (const UA_Node **)&generatesevent,
+    UA_Server_addNode(server, (UA_Node*)generatesevent,
                       &UA_EXPANDEDNODEID_STATIC(UA_NS0ID_NONHIERARCHICALREFERENCES,0),
                       &UA_NODEID_STATIC(UA_NS0ID_HASSUBTYPE,0));
 
@@ -289,7 +289,7 @@ UA_Server * UA_Server_new(void) {
     aggregates->nodeClass  = UA_NODECLASS_REFERENCETYPE;
     aggregates->isAbstract = UA_TRUE;
     aggregates->symmetric  = UA_FALSE;
-    UA_Server_addNode(server, (const UA_Node **)&aggregates,
+    UA_Server_addNode(server, (UA_Node*)aggregates,
                       &UA_EXPANDEDNODEID_STATIC(UA_NS0ID_HASCHILD,0),
                       &UA_NODEID_STATIC(UA_NS0ID_HASSUBTYPE,0));
 
@@ -304,7 +304,7 @@ UA_Server * UA_Server_new(void) {
     hasproperty->nodeClass  = UA_NODECLASS_REFERENCETYPE;
     hasproperty->isAbstract = UA_FALSE;
     hasproperty->symmetric  = UA_FALSE;
-    UA_Server_addNode(server, (const UA_Node **)&hasproperty,
+    UA_Server_addNode(server, (UA_Node*)hasproperty,
                       &UA_EXPANDEDNODEID_STATIC(UA_NS0ID_AGGREGATES,0),
                       &UA_NODEID_STATIC(UA_NS0ID_HASSUBTYPE,0));
 
@@ -315,7 +315,7 @@ UA_Server * UA_Server_new(void) {
     hascomponent->nodeClass  = UA_NODECLASS_REFERENCETYPE;
     hascomponent->isAbstract = UA_FALSE;
     hascomponent->symmetric  = UA_FALSE;
-    UA_Server_addNode(server, (const UA_Node **)&hascomponent,
+    UA_Server_addNode(server, (UA_Node*)hascomponent,
                       &UA_EXPANDEDNODEID_STATIC(UA_NS0ID_AGGREGATES,0),
                       &UA_NODEID_STATIC(UA_NS0ID_HASSUBTYPE,0));
 
@@ -326,7 +326,7 @@ UA_Server * UA_Server_new(void) {
     hasnotifier->nodeClass  = UA_NODECLASS_REFERENCETYPE;
     hasnotifier->isAbstract = UA_FALSE;
     hasnotifier->symmetric  = UA_FALSE;
-    UA_Server_addNode(server, (const UA_Node **)&hasnotifier,
+    UA_Server_addNode(server, (UA_Node*)hasnotifier,
                       &UA_EXPANDEDNODEID_STATIC(UA_NS0ID_HASEVENTSOURCE,0),
                       &UA_NODEID_STATIC(UA_NS0ID_HASSUBTYPE,0));
 
@@ -337,7 +337,7 @@ UA_Server * UA_Server_new(void) {
     hasorderedcomponent->nodeClass  = UA_NODECLASS_REFERENCETYPE;
     hasorderedcomponent->isAbstract = UA_FALSE;
     hasorderedcomponent->symmetric  = UA_FALSE;
-    UA_Server_addNode(server, (const UA_Node **)&hasorderedcomponent,
+    UA_Server_addNode(server, (UA_Node*)hasorderedcomponent,
                       &UA_EXPANDEDNODEID_STATIC(UA_NS0ID_HASCOMPONENT,0),
                       &UA_NODEID_STATIC(UA_NS0ID_HASSUBTYPE,0));
 
@@ -348,7 +348,7 @@ UA_Server * UA_Server_new(void) {
     hasmodelparent->nodeClass  = UA_NODECLASS_REFERENCETYPE;
     hasmodelparent->isAbstract = UA_FALSE;
     hasmodelparent->symmetric  = UA_FALSE;
-    UA_Server_addNode(server, (const UA_Node **)&hasmodelparent,
+    UA_Server_addNode(server, (UA_Node*)hasmodelparent,
                       &UA_EXPANDEDNODEID_STATIC(UA_NS0ID_NONHIERARCHICALREFERENCES,0),
                       &UA_NODEID_STATIC(UA_NS0ID_HASSUBTYPE,0));
 
@@ -359,7 +359,7 @@ UA_Server * UA_Server_new(void) {
     fromstate->nodeClass  = UA_NODECLASS_REFERENCETYPE;
     fromstate->isAbstract = UA_FALSE;
     fromstate->symmetric  = UA_FALSE;
-    UA_Server_addNode(server, (const UA_Node **)&fromstate,
+    UA_Server_addNode(server, (UA_Node*)fromstate,
                       &UA_EXPANDEDNODEID_STATIC(UA_NS0ID_NONHIERARCHICALREFERENCES,0),
                       &UA_NODEID_STATIC(UA_NS0ID_HASSUBTYPE,0));
 
@@ -370,7 +370,7 @@ UA_Server * UA_Server_new(void) {
     tostate->nodeClass  = UA_NODECLASS_REFERENCETYPE;
     tostate->isAbstract = UA_FALSE;
     tostate->symmetric  = UA_FALSE;
-    UA_Server_addNode(server, (const UA_Node **)&tostate,
+    UA_Server_addNode(server, (UA_Node*)tostate,
                       &UA_EXPANDEDNODEID_STATIC(UA_NS0ID_NONHIERARCHICALREFERENCES,0),
                       &UA_NODEID_STATIC(UA_NS0ID_HASSUBTYPE,0));
 
@@ -381,7 +381,7 @@ UA_Server * UA_Server_new(void) {
     hascause->nodeClass  = UA_NODECLASS_REFERENCETYPE;
     hascause->isAbstract = UA_FALSE;
     hascause->symmetric  = UA_FALSE;
-    UA_Server_addNode(server, (const UA_Node **)&hascause,
+    UA_Server_addNode(server, (UA_Node*)hascause,
                       &UA_EXPANDEDNODEID_STATIC(UA_NS0ID_NONHIERARCHICALREFERENCES,0),
                       &UA_NODEID_STATIC(UA_NS0ID_HASSUBTYPE,0));
     
@@ -392,7 +392,7 @@ UA_Server * UA_Server_new(void) {
     haseffect->nodeClass  = UA_NODECLASS_REFERENCETYPE;
     haseffect->isAbstract = UA_FALSE;
     haseffect->symmetric  = UA_FALSE;
-    UA_Server_addNode(server, (const UA_Node **)&haseffect,
+    UA_Server_addNode(server, (UA_Node*)haseffect,
                       &UA_EXPANDEDNODEID_STATIC(UA_NS0ID_NONHIERARCHICALREFERENCES,0),
                       &UA_NODEID_STATIC(UA_NS0ID_HASSUBTYPE,0));
 
@@ -403,7 +403,7 @@ UA_Server * UA_Server_new(void) {
     hashistoricalconfiguration->nodeClass  = UA_NODECLASS_REFERENCETYPE;
     hashistoricalconfiguration->isAbstract = UA_FALSE;
     hashistoricalconfiguration->symmetric  = UA_FALSE;
-    UA_Server_addNode(server, (const UA_Node **)&hashistoricalconfiguration,
+    UA_Server_addNode(server, (UA_Node*)hashistoricalconfiguration,
                       &UA_EXPANDEDNODEID_STATIC(UA_NS0ID_AGGREGATES,0),
                       &UA_NODEID_STATIC(UA_NS0ID_HASSUBTYPE,0));
 
@@ -415,13 +415,13 @@ UA_Server * UA_Server_new(void) {
     folderType->nodeId.identifier.numeric = UA_NS0ID_FOLDERTYPE;
     folderType->nodeClass = UA_NODECLASS_OBJECTTYPE;
     COPYNAMES(folderType, "FolderType");
-    UA_NodeStore_insert(server->nodestore, (const UA_Node**)&folderType, UA_FALSE);
+    UA_NodeStore_insert(server->nodestore, (UA_Node*)folderType, UA_NULL);
 
     UA_ObjectNode *root = UA_ObjectNode_new();
     COPYNAMES(root, "Root");
     root->nodeId.identifier.numeric = UA_NS0ID_ROOTFOLDER;
     root->nodeClass = UA_NODECLASS_OBJECT;
-    UA_NodeStore_insert(server->nodestore, (const UA_Node**)&root, UA_FALSE);
+    UA_NodeStore_insert(server->nodestore, (UA_Node*)root, UA_NULL);
     ADDREFERENCE(UA_NODEID_STATIC(UA_NS0ID_ROOTFOLDER,0), UA_NODEID_STATIC(UA_NS0ID_HASTYPEDEFINITION,0),
                  UA_EXPANDEDNODEID_STATIC(UA_NS0ID_FOLDERTYPE,0));
     ADDREFERENCE(UA_NODEID_STATIC(UA_NS0ID_ROOTFOLDER,0), UA_NODEID_STATIC(UA_NS0ID_ORGANIZES,0),
@@ -435,7 +435,7 @@ UA_Server * UA_Server_new(void) {
     COPYNAMES(objects, "Objects");
     objects->nodeId.identifier.numeric = UA_NS0ID_OBJECTSFOLDER;
     objects->nodeClass = UA_NODECLASS_OBJECT;
-    UA_NodeStore_insert(server->nodestore, (const UA_Node**)&objects, UA_FALSE);
+    UA_NodeStore_insert(server->nodestore, (UA_Node*)objects, UA_NULL);
     ADDREFERENCE(UA_NODEID_STATIC(UA_NS0ID_OBJECTSFOLDER,0), UA_NODEID_STATIC(UA_NS0ID_HASTYPEDEFINITION,0),
                  UA_EXPANDEDNODEID_STATIC(UA_NS0ID_FOLDERTYPE,0));
     ADDREFERENCE(UA_NODEID_STATIC(UA_NS0ID_OBJECTSFOLDER,0), UA_NODEID_STATIC(UA_NS0ID_ORGANIZES,0),
@@ -445,7 +445,7 @@ UA_Server * UA_Server_new(void) {
     COPYNAMES(types, "Types");
     types->nodeId.identifier.numeric = UA_NS0ID_TYPESFOLDER;
     types->nodeClass = UA_NODECLASS_OBJECT;
-    UA_NodeStore_insert(server->nodestore, (const UA_Node**)&types, UA_FALSE);
+    UA_NodeStore_insert(server->nodestore, (UA_Node*)types, UA_NULL);
     ADDREFERENCE(UA_NODEID_STATIC(UA_NS0ID_TYPESFOLDER,0), UA_NODEID_STATIC(UA_NS0ID_HASTYPEDEFINITION,0),
                  UA_EXPANDEDNODEID_STATIC(UA_NS0ID_FOLDERTYPE,0));
 
@@ -453,7 +453,7 @@ UA_Server * UA_Server_new(void) {
     COPYNAMES(views, "Views");
     views->nodeId.identifier.numeric = UA_NS0ID_VIEWSFOLDER;
     views->nodeClass = UA_NODECLASS_OBJECT;
-    UA_NodeStore_insert(server->nodestore, (const UA_Node**)&views, UA_FALSE);
+    UA_NodeStore_insert(server->nodestore, (UA_Node*)views, UA_NULL);
     ADDREFERENCE(UA_NODEID_STATIC(UA_NS0ID_VIEWSFOLDER,0), UA_NODEID_STATIC(UA_NS0ID_HASTYPEDEFINITION,0),
                  UA_EXPANDEDNODEID_STATIC(UA_NS0ID_FOLDERTYPE,0));
 
@@ -461,7 +461,7 @@ UA_Server * UA_Server_new(void) {
     COPYNAMES(servernode, "Server");
     servernode->nodeId.identifier.numeric = UA_NS0ID_SERVER;
     servernode->nodeClass = UA_NODECLASS_OBJECT;
-    UA_NodeStore_insert(server->nodestore, (const UA_Node**)&servernode, UA_FALSE);
+    UA_NodeStore_insert(server->nodestore, (UA_Node*)servernode, UA_NULL);
     ADDREFERENCE(UA_NODEID_STATIC(UA_NS0ID_SERVER,0), UA_NODEID_STATIC(UA_NS0ID_HASCOMPONENT,0),
                  UA_EXPANDEDNODEID_STATIC(UA_NS0ID_SERVER_SERVERCAPABILITIES,0));
     ADDREFERENCE(UA_NODEID_STATIC(UA_NS0ID_SERVER,0), UA_NODEID_STATIC(UA_NS0ID_HASPROPERTY,0),
@@ -490,7 +490,7 @@ UA_Server * UA_Server_new(void) {
     namespaceArray->valueRank = 1;
     namespaceArray->minimumSamplingInterval = 1.0;
     namespaceArray->historizing = UA_FALSE;
-    UA_Server_addNode(server, (const UA_Node **)&namespaceArray,
+    UA_Server_addNode(server, (UA_Node*)namespaceArray,
                       &UA_EXPANDEDNODEID_STATIC(UA_NS0ID_SERVER,0),
                       &UA_NODEID_STATIC(UA_NS0ID_HASCOMPONENT,0));
 
@@ -514,7 +514,7 @@ UA_Server * UA_Server_new(void) {
     serverstatus->value.typeId.identifier.numeric = UA_TYPES_IDS[UA_TYPES_SERVERSTATUSDATATYPE];
     serverstatus->value.storage.data.arrayLength = 1;
     serverstatus->value.storage.data.dataPtr = status;
-    UA_Server_addNode(server, (const UA_Node **)&serverstatus,
+    UA_Server_addNode(server, (UA_Node*)serverstatus,
                       &UA_EXPANDEDNODEID_STATIC(UA_NS0ID_SERVER,0),
                       &UA_NODEID_STATIC(UA_NS0ID_HASPROPERTY,0));
 
@@ -530,6 +530,6 @@ UA_Server * UA_Server_new(void) {
     state->value.storage.data.arrayLength = 1;
     state->value.storage.data.dataPtr = stateEnum; // points into the other object.
     state->value.storageType = UA_VARIANT_DATA;
-    UA_NodeStore_insert(server->nodestore, (const UA_Node**)&state, UA_FALSE);
+    UA_NodeStore_insert(server->nodestore, (UA_Node*)state, UA_NULL);
     return server;
 }

+ 13 - 14
src/server/ua_server_addressspace.c

@@ -28,7 +28,7 @@ UA_StatusCode UA_Server_addScalarVariableNode(UA_Server *server, UA_QualifiedNam
         return UA_STATUSCODE_BADINTERNALERROR;
     }
     tmpNode->value.type = &UA_TYPES[i];
-    UA_Server_addNodeWithSession(server, &adminSession, (const UA_Node**)&tmpNode,
+    UA_Server_addNodeWithSession(server, &adminSession, (UA_Node*)tmpNode,
                                  parentNodeId, referenceTypeId);
     return UA_STATUSCODE_GOOD;
 }
@@ -118,8 +118,7 @@ static UA_StatusCode addOneWayReferenceWithSession(UA_Server *server, UA_Session
     UA_free(old_refs);
     newNode->references = new_refs;
     newNode->referencesSize = ++count;
-    const UA_Node *constNode = newNode;
-    retval = UA_NodeStore_replace(server->nodestore, node, (const UA_Node **)&constNode, UA_FALSE);
+    retval = UA_NodeStore_replace(server->nodestore, node, newNode, UA_NULL);
     UA_NodeStore_release(node);
     if(retval != UA_STATUSCODE_BADINTERNALERROR)
         return retval;
@@ -172,12 +171,12 @@ UA_StatusCode UA_Server_addReferenceWithSession(UA_Server *server, UA_Session *s
     return retval;
 } 
 
-UA_AddNodesResult UA_Server_addNode(UA_Server *server, const UA_Node **node,
-                                    const UA_ExpandedNodeId *parentNodeId, const UA_NodeId *referenceTypeId) {
+UA_AddNodesResult UA_Server_addNode(UA_Server *server, UA_Node *node, const UA_ExpandedNodeId *parentNodeId,
+                                    const UA_NodeId *referenceTypeId) {
     return UA_Server_addNodeWithSession(server, &adminSession, node, parentNodeId, referenceTypeId);
 }
 
-UA_AddNodesResult UA_Server_addNodeWithSession(UA_Server *server, UA_Session *session, const UA_Node **node,
+UA_AddNodesResult UA_Server_addNodeWithSession(UA_Server *server, UA_Session *session, UA_Node *node,
                                                const UA_ExpandedNodeId *parentNodeId,
                                                const UA_NodeId *referenceTypeId) {
     UA_AddNodesResult result;
@@ -207,19 +206,20 @@ UA_AddNodesResult UA_Server_addNodeWithSession(UA_Server *server, UA_Session *se
     }
 
     // todo: test if the referencetype is hierarchical
-    if(UA_NodeId_isNull(&(*node)->nodeId)) {
-        if(UA_NodeStore_insert(server->nodestore, node, UA_TRUE) != UA_STATUSCODE_GOOD) {
+    const UA_Node *managed = UA_NULL;
+    if(UA_NodeId_isNull(&node->nodeId)) {
+        if(UA_NodeStore_insert(server->nodestore, node, &managed) != UA_STATUSCODE_GOOD) {
             result.statusCode = UA_STATUSCODE_BADOUTOFMEMORY;
             goto ret2;
         }
-        result.addedNodeId = (*node)->nodeId; // cannot fail as unique nodeids are numeric
+        result.addedNodeId = managed->nodeId; // cannot fail as unique nodeids are numeric
     } else {
-        if(UA_NodeId_copy(&(*node)->nodeId, &result.addedNodeId) != UA_STATUSCODE_GOOD) {
+        if(UA_NodeId_copy(&node->nodeId, &result.addedNodeId) != UA_STATUSCODE_GOOD) {
             result.statusCode = UA_STATUSCODE_BADOUTOFMEMORY;
             goto ret2;
         }
 
-        if(UA_NodeStore_insert(server->nodestore, node, UA_TRUE) != UA_STATUSCODE_GOOD) {
+        if(UA_NodeStore_insert(server->nodestore, node, &managed) != UA_STATUSCODE_GOOD) {
             result.statusCode = UA_STATUSCODE_BADNODEIDEXISTS;  // todo: differentiate out of memory
             UA_NodeId_deleteMembers(&result.addedNodeId);
             goto ret2;
@@ -229,7 +229,7 @@ UA_AddNodesResult UA_Server_addNodeWithSession(UA_Server *server, UA_Session *se
     // reference back to the parent
     UA_AddReferencesItem item;
     UA_AddReferencesItem_init(&item);
-    item.sourceNodeId = (*node)->nodeId;
+    item.sourceNodeId = managed->nodeId;
     item.referenceTypeId = referenceType->nodeId;
     item.isForward = UA_FALSE;
     item.targetNodeId.nodeId = parent->nodeId;
@@ -237,8 +237,7 @@ UA_AddNodesResult UA_Server_addNodeWithSession(UA_Server *server, UA_Session *se
 
     // todo: error handling. remove new node from nodestore
 
-    UA_NodeStore_release(*node);
-    *node = UA_NULL;
+    UA_NodeStore_release(managed);
     
  ret2:
     UA_NodeStore_release((const UA_Node*)referenceType);

+ 5 - 4
src/server/ua_server_internal.h

@@ -64,11 +64,12 @@ struct UA_Server {
 
 void UA_Server_processBinaryMessage(UA_Server *server, UA_Connection *connection, const UA_ByteString *msg);
 
-UA_AddNodesResult UA_Server_addNodeWithSession(UA_Server *server, UA_Session *session, const UA_Node **node,
-                                               const UA_ExpandedNodeId *parentNodeId, const UA_NodeId *referenceTypeId);
+UA_AddNodesResult UA_Server_addNodeWithSession(UA_Server *server, UA_Session *session, UA_Node *node,
+                                               const UA_ExpandedNodeId *parentNodeId,
+                                               const UA_NodeId *referenceTypeId);
 
-UA_AddNodesResult UA_Server_addNode(UA_Server *server, const UA_Node **node,
-                                    const UA_ExpandedNodeId *parentNodeId, const UA_NodeId *referenceTypeId);
+UA_AddNodesResult UA_Server_addNode(UA_Server *server, UA_Node *node, const UA_ExpandedNodeId *parentNodeId,
+                                    const UA_NodeId *referenceTypeId);
 
 UA_StatusCode UA_Server_addReferenceWithSession(UA_Server *server, UA_Session *session, const UA_AddReferencesItem *item);
 

+ 1 - 2
src/server/ua_services_attribute.c

@@ -433,8 +433,7 @@ static UA_StatusCode writeValue(UA_Server *server, UA_WriteValue *aWriteValue) {
         if(retval != UA_STATUSCODE_GOOD)
             break;
 
-        const UA_Node *constPtr = newNode; // compilers complain if we directly cast
-        if(UA_NodeStore_replace(server->nodestore, node, &constPtr, UA_FALSE) == UA_STATUSCODE_GOOD) {
+        if(UA_NodeStore_replace(server->nodestore, node, newNode, UA_NULL) == UA_STATUSCODE_GOOD) {
             UA_NodeStore_release(node);
             break;
         }

+ 1 - 2
src/server/ua_services_nodemanagement.c

@@ -209,8 +209,7 @@ static void addNodeFromAttributes(UA_Server *server, UA_Session *session, UA_Add
         return;
 
     // add the node
-    const UA_Node *constNode = node; // compilers complain if we cast directly
-    *result = UA_Server_addNodeWithSession(server, session, &constNode, &item->parentNodeId,
+    *result = UA_Server_addNodeWithSession(server, session, node, &item->parentNodeId,
                                            &item->referenceTypeId);
     if(result->statusCode != UA_STATUSCODE_GOOD) {
         switch (node->nodeClass) {

+ 32 - 69
src/ua_types.c

@@ -178,33 +178,6 @@ UA_Boolean UA_String_equal(const UA_String *string1, const UA_String *string2) {
     return (is == 0) ? UA_TRUE : UA_FALSE;
 }
 
-void UA_String_printf(char const *label, const UA_String *string) {
-    printf("%s {Length=%d, Data=%.*s}\n", label, string->length,
-           string->length, (char *)string->data);
-}
-
-void UA_String_printx(char const *label, const UA_String *string) {
-    printf("%s {Length=%d, Data=", label, string->length);
-    if(string->length > 0) {
-        for(UA_Int32 i = 0;i < string->length;i++) {
-            printf("%c%d", i == 0 ? '{' : ',', (string->data)[i]);
-            // if (i > 0 && !(i%20)) { printf("\n\t"); }
-        }
-    } else
-        printf("{");
-    printf("}}\n");
-}
-
-void UA_String_printx_hex(char const *label, const UA_String *string) {
-    printf("%s {Length=%d, Data=", label, string->length);
-    if(string->length > 0) {
-        for(UA_Int32 i = 0;i < string->length;i++)
-            printf("%c%x", i == 0 ? '{' : ',', (string->data)[i]);
-    } else
-        printf("{");
-    printf("}}\n");
-}
-
 /* DateTime */
 #define UNIX_EPOCH_BIAS_SEC 11644473600LL // Number of seconds from 1 Jan. 1601 00:00 to 1 Jan 1970 00:00 UTC
 #define HUNDRED_NANOSEC_PER_USEC 10LL
@@ -314,18 +287,6 @@ UA_Boolean UA_ByteString_equal(const UA_ByteString *string1, const UA_ByteString
     return UA_String_equal((const UA_String *)string1, (const UA_String *)string2);
 }
 
-void UA_ByteString_printf(char *label, const UA_ByteString *string) {
-    UA_String_printf(label, (const UA_String *)string);
-}
-
-void UA_ByteString_printx(char *label, const UA_ByteString *string) {
-    UA_String_printx(label, (const UA_String *)string);
-}
-
-void UA_ByteString_printx_hex(char *label, const UA_ByteString *string) {
-    UA_String_printx_hex(label, (const UA_String *)string);
-}
-
 /** Creates a ByteString of the indicated length. The content is not set to zero. */
 UA_StatusCode UA_ByteString_newMembers(UA_ByteString *p, UA_Int32 length) {
     if(length > 0) {
@@ -755,15 +716,15 @@ UA_StatusCode UA_DiagnosticInfo_copy(UA_DiagnosticInfo const *src, UA_Diagnostic
 /*******************/
 
 void UA_init(void *p, const UA_DataType *dataType) {
-    UA_Byte *ptr = (UA_Byte *)p; // for pointer arithmetic
-
     /* Do not check if the index is a builtin-type here. Builtins will be called
        with their very own _init functions normally. In the off case, that the
        generic function is called with the index of a builtin, their layout
        contains a single member of the builtin type, that will be inited in the
        for loop. */
 
-    for(int i=0;i<dataType->membersSize; i++) {
+    uintptr_t ptr = (uintptr_t)p;
+    UA_Byte membersSize = dataType->membersSize;
+    for(size_t i=0;i<membersSize; i++) {
         const UA_DataTypeMember *member = &dataType->members[i];
         if(member->isArray) {
             /* Padding contains bit-magic to split into padding before and after
@@ -780,7 +741,7 @@ void UA_init(void *p, const UA_DataType *dataType) {
         if(!member->namespaceZero) {
             // pointer arithmetic
             const UA_DataType *memberType = dataType - dataType->typeIndex + member->memberTypeIndex;
-            UA_init(ptr, memberType);
+            UA_init((void*)ptr, memberType);
             ptr += memberType->memSize;
             continue;
         }
@@ -789,23 +750,23 @@ void UA_init(void *p, const UA_DataType *dataType) {
         case UA_TYPES_BOOLEAN:
         case UA_TYPES_SBYTE:
         case UA_TYPES_BYTE:
-            *ptr = 0;
+            *(UA_Byte*)ptr = 0;
             break;
         case UA_TYPES_INT16:
         case UA_TYPES_UINT16:
-            *((UA_Int16*)ptr) = 0;
+            *(UA_Int16*)ptr = 0;
             break;
         case UA_TYPES_INT32:
         case UA_TYPES_UINT32:
         case UA_TYPES_STATUSCODE:
         case UA_TYPES_FLOAT:
-            *((UA_Int32*)ptr) = 0;
+            *(UA_Int32*)ptr = 0;
             break;
         case UA_TYPES_INT64:
         case UA_TYPES_UINT64:
         case UA_TYPES_DOUBLE:
         case UA_TYPES_DATETIME:
-            *((UA_Int64*)ptr) = 0;
+            *(UA_Int64*)ptr = 0;
             break;
         case UA_TYPES_GUID:
             UA_Guid_init((UA_Guid*)ptr);
@@ -840,7 +801,7 @@ void UA_init(void *p, const UA_DataType *dataType) {
             UA_String_init((UA_String*)ptr);
             break;
         default:
-            UA_init(ptr, &UA_TYPES[member->memberTypeIndex]);
+            UA_init((void*)ptr, &UA_TYPES[member->memberTypeIndex]);
         }
         ptr += UA_TYPES[member->memberTypeIndex].memSize;
     }
@@ -848,7 +809,8 @@ void UA_init(void *p, const UA_DataType *dataType) {
 
 void * UA_new(const UA_DataType *dataType) {
     void *p = UA_malloc(dataType->memSize);
-    if(p) UA_init(p, dataType);
+    if(p)
+        UA_init(p, dataType);
     return p;
 }
 
@@ -859,9 +821,10 @@ UA_StatusCode UA_copy(const void *src, void *dst, const UA_DataType *dataType) {
     }
     UA_init(dst, dataType);
     UA_StatusCode retval = UA_STATUSCODE_GOOD;
-    const UA_Byte *ptrs = (const UA_Byte *)src;
-    UA_Byte *ptrd = (UA_Byte *)dst;
-    for(int i=0;i<dataType->membersSize; i++) {
+    uintptr_t ptrs = (uintptr_t)src;
+    uintptr_t ptrd = (uintptr_t)dst;
+    UA_Byte membersSize = dataType->membersSize;
+    for(size_t i=0;i<membersSize; i++) {
         const UA_DataTypeMember *member = &dataType->members[i];
         const UA_DataType *memberType;
         if(member->namespaceZero)
@@ -890,7 +853,7 @@ UA_StatusCode UA_copy(const void *src, void *dst, const UA_DataType *dataType) {
         ptrs += member->padding;
         ptrd += member->padding;
         if(!member->namespaceZero) {
-            retval = UA_copy(ptrs, ptrd, memberType);
+            retval = UA_copy((const void*)ptrs, (void*)ptrd, memberType);
             if(retval != UA_STATUSCODE_GOOD) {
                 UA_deleteMembers(dst, dataType);
                 return retval;
@@ -955,7 +918,7 @@ UA_StatusCode UA_copy(const void *src, void *dst, const UA_DataType *dataType) {
             retval |= UA_String_copy((const UA_String*)ptrs, (UA_String*)ptrd);
             break;
         default:
-            retval |= UA_copy(ptrs, ptrd, memberType);
+            retval |= UA_copy((const void *)ptrs, (void*)ptrd, memberType);
         }
         ptrs += memberType->memSize;
         ptrd += memberType->memSize;
@@ -966,11 +929,11 @@ UA_StatusCode UA_copy(const void *src, void *dst, const UA_DataType *dataType) {
 }
 
 void UA_deleteMembers(void *p, const UA_DataType *dataType) {
-    UA_Byte *ptr = (UA_Byte *)p; // for pointer arithmetic
+    uintptr_t ptr = (uintptr_t)p;
     if(dataType->fixedSize)
         return;
     UA_Byte membersSize = dataType->membersSize;
-    for(int i=0;i<membersSize; i++) {
+    for(size_t i=0;i<membersSize; i++) {
         const UA_DataTypeMember *member = &dataType->members[i];
         const UA_DataType *memberType;
         if(member->namespaceZero)
@@ -989,7 +952,7 @@ void UA_deleteMembers(void *p, const UA_DataType *dataType) {
 
         ptr += member->padding;
         if(!member->namespaceZero) {
-            UA_deleteMembers(ptr, memberType);
+            UA_deleteMembers((void*)ptr, memberType);
             ptr += memberType->memSize;
             continue;
         }
@@ -1028,7 +991,7 @@ void UA_deleteMembers(void *p, const UA_DataType *dataType) {
             UA_String_deleteMembers((UA_String*)ptr);
             break;
         default:
-            UA_deleteMembers(ptr, memberType);
+            UA_deleteMembers((void*)ptr, memberType);
         }
         ptr += memberType->memSize;
     }
@@ -1052,13 +1015,13 @@ UA_StatusCode UA_Array_new(void **p, UA_Int32 noElements, const UA_DataType *dat
     if(dataType->memSize * noElements < 0 || dataType->memSize * noElements > MAX_ARRAY_SIZE )
         return UA_STATUSCODE_BADOUTOFMEMORY;
 
-    *p = malloc(dataType->memSize * noElements);
+    *p = malloc(dataType->memSize * (size_t)noElements);
     if(!p)
         return UA_STATUSCODE_BADOUTOFMEMORY;
 
-    UA_Byte *ptr = *p;
-    for(UA_Int32 i = 0; i<noElements; i++) {
-        UA_init(ptr, dataType);
+    uintptr_t ptr = (uintptr_t)*p;
+    for(int i = 0; i<noElements; i++) {
+        UA_init((void*)ptr, dataType);
         ptr += dataType->memSize;
     }
     return UA_STATUSCODE_GOOD;
@@ -1070,19 +1033,19 @@ UA_StatusCode UA_Array_copy(const void *src, UA_Int32 noElements, void **dst, co
         return UA_STATUSCODE_GOOD;
     }
 
-    if(!(*dst = UA_malloc(noElements * dataType->memSize)))
+    if(!(*dst = UA_malloc((size_t)noElements * dataType->memSize)))
         return UA_STATUSCODE_BADOUTOFMEMORY;
 
     if(dataType->fixedSize) {
-        memcpy(*dst, src, dataType->memSize * noElements);
+        memcpy(*dst, src, dataType->memSize * (size_t)noElements);
         return UA_STATUSCODE_GOOD;
     }
 
-    const UA_Byte *ptrs = (const UA_Byte*)src;
-    UA_Byte *ptrd = (UA_Byte*)*dst;
+    uintptr_t ptrs = (uintptr_t)src;
+    uintptr_t ptrd = (uintptr_t)*dst;
     UA_StatusCode retval = UA_STATUSCODE_GOOD;
     for(int i=0;i<noElements; i++) {
-        retval = UA_copy(ptrs, ptrd, dataType);
+        retval = UA_copy((void*)ptrs, (void*)ptrd, dataType);
         ptrs += dataType->memSize;
         ptrd += dataType->memSize;
     }
@@ -1098,9 +1061,9 @@ void UA_Array_delete(void *p, UA_Int32 noElements, const UA_DataType *dataType)
         return;
 
     if(!dataType->fixedSize) {
-        UA_Byte *ptr = p; // for pointer arithemetic
+        uintptr_t ptr = (uintptr_t)p;
         for(UA_Int32 i = 0; i<noElements; i++) {
-            UA_deleteMembers(ptr, dataType);
+            UA_deleteMembers((void*)ptr, dataType);
             ptr += dataType->memSize;
         }
     }

+ 16 - 16
src/ua_types_encoding_binary.c

@@ -908,7 +908,7 @@ UA_StatusCode UA_DiagnosticInfo_decodeBinary(UA_ByteString const *src, size_t *o
 
 size_t UA_calcSizeBinary(const void *p, const UA_DataType *dataType) {
     size_t size = 0;
-    const UA_Byte *ptr = (const UA_Byte*)p;
+    uintptr_t ptr = (uintptr_t)p;
     UA_Byte membersSize = dataType->membersSize;
     for(size_t i=0;i<membersSize; i++) {
         const UA_DataTypeMember *member = &dataType->members[i];
@@ -929,7 +929,7 @@ size_t UA_calcSizeBinary(const void *p, const UA_DataType *dataType) {
 
         ptr += member->padding;
         if(!member->namespaceZero) {
-            size += UA_calcSizeBinary(ptr, memberType);
+            size += UA_calcSizeBinary((const void*)ptr, memberType);
             ptr += memberType->memSize;
             continue;
         }
@@ -989,7 +989,7 @@ size_t UA_calcSizeBinary(const void *p, const UA_DataType *dataType) {
             size += UA_String_calcSizeBinary((const UA_String*)ptr);
             break;
         default:
-            size += UA_calcSizeBinary(ptr, memberType);
+            size += UA_calcSizeBinary((const void*)ptr, memberType);
         }
         ptr += memberType->memSize;
     }
@@ -997,7 +997,7 @@ size_t UA_calcSizeBinary(const void *p, const UA_DataType *dataType) {
 }
 
 UA_StatusCode UA_encodeBinary(const void *src, const UA_DataType *dataType, UA_ByteString *dst, size_t *offset) {
-    const UA_Byte *ptr = (const UA_Byte*)src;
+    uintptr_t ptr = (uintptr_t)src;
     UA_StatusCode retval = UA_STATUSCODE_GOOD;
     UA_Byte membersSize = dataType->membersSize;
     for(size_t i=0;i<membersSize && retval == UA_STATUSCODE_GOOD; i++) {
@@ -1019,7 +1019,7 @@ UA_StatusCode UA_encodeBinary(const void *src, const UA_DataType *dataType, UA_B
 
         ptr += member->padding;
         if(!member->namespaceZero) {
-            UA_encodeBinary(ptr, memberType, dst, offset);
+            UA_encodeBinary((const void*)ptr, memberType, dst, offset);
             ptr += memberType->memSize;
             continue;
         }
@@ -1085,7 +1085,7 @@ UA_StatusCode UA_encodeBinary(const void *src, const UA_DataType *dataType, UA_B
             retval = UA_String_encodeBinary((const UA_String*)ptr, dst, offset);
             break;
         default:
-            retval = UA_encodeBinary(ptr, memberType, dst, offset);
+            retval = UA_encodeBinary((const void*)ptr, memberType, dst, offset);
         }
         ptr += memberType->memSize;
     }
@@ -1093,10 +1093,10 @@ UA_StatusCode UA_encodeBinary(const void *src, const UA_DataType *dataType, UA_B
 }
 
 UA_StatusCode UA_decodeBinary(const UA_ByteString *src, size_t *offset, void *dst, const UA_DataType *dataType) {
-    UA_Byte *ptr = (UA_Byte*)dst;
+    UA_init(dst, dataType);
+    uintptr_t ptr = (uintptr_t)dst;
     UA_StatusCode retval = UA_STATUSCODE_GOOD;
     UA_Byte membersSize = dataType->membersSize;
-    UA_init(dst, dataType);
     for(size_t i=0;i<membersSize && retval == UA_STATUSCODE_GOOD; i++) {
         const UA_DataTypeMember *member = &dataType->members[i];
         const UA_DataType *memberType;
@@ -1117,7 +1117,7 @@ UA_StatusCode UA_decodeBinary(const UA_ByteString *src, size_t *offset, void *ds
 
         ptr += member->padding;
         if(!member->namespaceZero) {
-            UA_decodeBinary(src, offset, ptr, memberType);
+            UA_decodeBinary(src, offset, (void*)ptr, memberType);
             ptr += memberType->memSize;
             continue;
         }
@@ -1181,7 +1181,7 @@ UA_StatusCode UA_decodeBinary(const UA_ByteString *src, size_t *offset, void *ds
             retval = UA_String_decodeBinary(src, offset, (UA_String*)ptr);
             break;
         default:
-            retval = UA_decodeBinary(src, offset, ptr, memberType);
+            retval = UA_decodeBinary(src, offset, (void*)ptr, memberType);
         }
         ptr += memberType->memSize;
     }
@@ -1202,9 +1202,9 @@ size_t UA_Array_calcSizeBinary(const void *p, UA_Int32 noElements, const UA_Data
         size += noElements * UA_calcSizeBinary(p, dataType);
         return size;
     }
-    const UA_Byte *ptr = (const UA_Byte*)p;
+    uintptr_t ptr = (uintptr_t)p;
     for(int i=0;i<noElements;i++) {
-        size += UA_calcSizeBinary(ptr, dataType);
+        size += UA_calcSizeBinary((void*)ptr, dataType);
         ptr += dataType->memSize;
     }
     return size;
@@ -1216,9 +1216,9 @@ UA_StatusCode UA_Array_encodeBinary(const void *src, UA_Int32 noElements, const
         noElements = -1;
     UA_Int32_encodeBinary(&noElements, dst, offset);
     UA_StatusCode retval = UA_STATUSCODE_GOOD;
-    const UA_Byte *ptr = (const UA_Byte*)src;
+    uintptr_t ptr = (uintptr_t)src;
     for(int i=0;i<noElements && retval == UA_STATUSCODE_GOOD;i++) {
-        retval = UA_encodeBinary(ptr, dataType, dst, offset);
+        retval = UA_encodeBinary((const void*)ptr, dataType, dst, offset);
         ptr += dataType->memSize;
     }
     return retval;
@@ -1242,11 +1242,11 @@ UA_StatusCode UA_Array_decodeBinary(const UA_ByteString *src, size_t *offset, UA
     if(!*dst)
         return UA_STATUSCODE_BADOUTOFMEMORY;
 
-    UA_Byte *ptr = (UA_Byte*)*dst;
+    uintptr_t ptr = (uintptr_t)*dst;
     UA_StatusCode retval = UA_STATUSCODE_GOOD;
     UA_Int32 i;
     for(i=0;i<noElements && retval == UA_STATUSCODE_GOOD;i++) {
-        retval = UA_decodeBinary(src, offset, ptr, dataType);
+        retval = UA_decodeBinary(src, offset, (void*)ptr, dataType);
         ptr += dataType->memSize;
     }
     if(retval != UA_STATUSCODE_GOOD)

+ 0 - 1
src/ua_types_encoding_binary.h

@@ -1,7 +1,6 @@
 #ifndef UA_TYPES_ENCODING_BINARY_H_
 #define UA_TYPES_ENCODING_BINARY_H_
 
-#include <stddef.h>
 #include "ua_types.h"
 
 /**

+ 102 - 112
tests/check_builtin.c

@@ -313,10 +313,10 @@ END_TEST
 
 START_TEST(UA_Byte_decodeShallCopyAndAdvancePosition) {
 	// given
-	UA_Byte       dst;
-	UA_Byte       data[] = { 0x08 };
-	UA_ByteString src    = { 1, data };
-	UA_UInt32     pos    = 0;
+	UA_Byte dst;
+	UA_Byte data[] = { 0x08 };
+	UA_ByteString src = { 1, data };
+	size_t pos = 0;
 
 	// when
 	UA_StatusCode retval = UA_Byte_decodeBinary(&src, &pos, &dst);
@@ -329,10 +329,10 @@ END_TEST
 
 START_TEST(UA_Byte_decodeShallModifyOnlyCurrentPosition) {
 	// given
-	UA_Byte       dst[]  = { 0xFF, 0xFF, 0xFF };
-	UA_Byte       data[] = { 0x08 };
-	UA_ByteString src    = { 1, data };
-	UA_UInt32     pos    = 0;
+	UA_Byte dst[]  = { 0xFF, 0xFF, 0xFF };
+	UA_Byte data[] = { 0x08 };
+	UA_ByteString src = { 1, data };
+	size_t pos = 0;
 	// when
 	UA_StatusCode retval = UA_Byte_decodeBinary(&src, &pos, &dst[1]);
 	// then
@@ -346,14 +346,14 @@ END_TEST
 
 START_TEST(UA_Int16_decodeShallAssumeLittleEndian) {
 	// given
-	UA_UInt32     pos    = 0;
-	UA_Byte       data[] = {
+	size_t pos = 0;
+	UA_Byte data[] = {
 			0x01, 0x00,     // 1
 			0x00, 0x01      // 256
 	};
 	UA_ByteString src = { 4, data };
 	// when
-	UA_Int16      val_01_00, val_00_01;
+	UA_Int16 val_01_00, val_00_01;
 	UA_StatusCode retval = UA_Int16_decodeBinary(&src, &pos, &val_01_00);
 	retval |= UA_Int16_decodeBinary(&src, &pos, &val_00_01);
 	// then
@@ -366,14 +366,14 @@ END_TEST
 
 START_TEST(UA_Int16_decodeShallRespectSign) {
 	// given
-	UA_UInt32     pos    = 0;
-	UA_Byte       data[] = {
+	size_t pos = 0;
+	UA_Byte data[] = {
 			0xFF, 0xFF,     // -1
 			0x00, 0x80      // -32768
 	};
 	UA_ByteString src = { 4, data };
 	// when
-	UA_Int16      val_ff_ff, val_00_80;
+	UA_Int16 val_ff_ff, val_00_80;
 	UA_StatusCode retval = UA_Int16_decodeBinary(&src, &pos, &val_ff_ff);
 	retval |= UA_Int16_decodeBinary(&src, &pos, &val_00_80);
 	// then
@@ -385,8 +385,8 @@ END_TEST
 
 START_TEST(UA_UInt16_decodeShallNotRespectSign) {
 	// given
-	UA_UInt32     pos    = 0;
-	UA_Byte       data[] = {
+	size_t pos = 0;
+	UA_Byte data[] = {
 			0xFF, 0xFF,     // (2^16)-1
 			0x00, 0x80      // (2^15)
 	};
@@ -405,8 +405,8 @@ END_TEST
 
 START_TEST(UA_Int32_decodeShallAssumeLittleEndian) {
 	// given
-	UA_UInt32     pos    = 0;
-	UA_Byte       data[] = {
+	size_t pos = 0;
+	UA_Byte data[] = {
 			0x01, 0x00, 0x00, 0x00,     // 1
 			0x00, 0x01, 0x00, 0x00      // 256
 	};
@@ -426,8 +426,8 @@ END_TEST
 
 START_TEST(UA_Int32_decodeShallRespectSign) {
 	// given
-	UA_UInt32     pos    = 0;
-	UA_Byte       data[] = {
+	size_t pos = 0;
+	UA_Byte data[] = {
 			0xFF, 0xFF, 0xFF, 0xFF,     // -1
 			0x00, 0x80, 0xFF, 0xFF      // -32768
 	};
@@ -446,8 +446,8 @@ END_TEST
 
 START_TEST(UA_UInt32_decodeShallNotRespectSign) {
 	// given
-	UA_UInt32     pos    = 0;
-	UA_Byte       data[] = {
+	size_t pos = 0;
+	UA_Byte data[] = {
 			0xFF, 0xFF, 0xFF, 0xFF,     // (2^32)-1
 			0x00, 0x00, 0x00, 0x80      // (2^31)
 	};
@@ -473,10 +473,10 @@ START_TEST(UA_UInt64_decodeShallNotRespectSign) {
 	UA_Byte mem[8] = { 00, 00, 00, 00, 0x00, 0x00, 0x00, 0xFF };
 	rawMessage.data   = mem;
 	rawMessage.length = 8;
-	UA_UInt32 p = 0;
+	size_t pos = 0;
 	UA_UInt64 val;
 	// when
-	UA_UInt64_decodeBinary(&rawMessage, &p, &val);
+	UA_UInt64_decodeBinary(&rawMessage, &pos, &val);
 	// then
 	ck_assert_uint_eq(val, expectedVal);
 }
@@ -491,10 +491,10 @@ START_TEST(UA_Int64_decodeShallRespectSign) {
 	rawMessage.data   = mem;
 	rawMessage.length = 8;
 
-	UA_UInt32 p = 0;
-	UA_Int64  val;
+	size_t pos = 0;
+	UA_Int64 val;
 	// when
-	UA_Int64_decodeBinary(&rawMessage, &p, &val);
+	UA_Int64_decodeBinary(&rawMessage, &pos, &val);
 	//then
 	ck_assert_uint_eq(val, expectedVal);
 }
@@ -502,10 +502,10 @@ END_TEST
 
 START_TEST(UA_Float_decodeShallWorkOnExample) {
 	// given
-	UA_UInt32     pos    = 0;
-	UA_Byte       data[] = { 0x00, 0x00, 0xD0, 0xC0 }; // -6.5
-	UA_ByteString src    = { 4, data };
-	UA_Float      dst;
+	size_t pos = 0;
+	UA_Byte data[] = { 0x00, 0x00, 0xD0, 0xC0 }; // -6.5
+	UA_ByteString src = { 4, data };
+	UA_Float dst;
 	// when
 	UA_StatusCode retval = UA_Float_decodeBinary(&src, &pos, &dst);
 	// then
@@ -518,10 +518,10 @@ END_TEST
 
 START_TEST(UA_Double_decodeShallGiveOne) {
 	// given
-	UA_UInt32     pos    = 0;
-	UA_Byte       data[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F }; // 1
-	UA_ByteString src    = { 8, data };                                        // 1
-	UA_Double     dst;
+	size_t pos = 0;
+	UA_Byte data[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F }; // 1
+	UA_ByteString src = { 8, data }; // 1
+	UA_Double dst;
 	// when
 	UA_StatusCode retval = UA_Double_decodeBinary(&src, &pos, &dst);
 	// then
@@ -534,10 +534,10 @@ END_TEST
 
 START_TEST(UA_Double_decodeShallGiveZero) {
 	// given
-	UA_UInt32     pos    = 0;
-	UA_Byte       data[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-	UA_ByteString src    = { 8, data }; // 1
-	UA_Double     dst;
+	size_t pos = 0;
+	UA_Byte data[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+	UA_ByteString src = { 8, data }; // 1
+	UA_Double dst;
 	// when
 	UA_StatusCode retval = UA_Double_decodeBinary(&src, &pos, &dst);
 	// then
@@ -550,11 +550,10 @@ END_TEST
 
 START_TEST(UA_Double_decodeShallGiveMinusTwo) {
 	// given
-	UA_UInt32     pos    = 0;
-	UA_Byte       data[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0 }; // -2
-	UA_ByteString src    = { 8, data };
-
-	UA_Double     dst;
+	size_t pos = 0;
+	UA_Byte data[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0 }; // -2
+	UA_ByteString src = { 8, data };
+	UA_Double dst;
 	// when
 	UA_StatusCode retval = UA_Double_decodeBinary(&src, &pos, &dst);
 	// then
@@ -567,11 +566,11 @@ END_TEST
 
 START_TEST(UA_String_decodeShallAllocateMemoryAndCopyString) {
 	// given
-	UA_UInt32     pos    = 0;
-	UA_Byte       data[] =
+	size_t pos = 0;
+	UA_Byte data[] =
 	{ 0x08, 0x00, 0x00, 0x00, 'A', 'C', 'P', 'L', 'T', ' ', 'U', 'A', 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
-	UA_ByteString src    = { 16, data };
-	UA_String     dst;
+	UA_ByteString src = { 16, data };
+	UA_String dst;
 	// when
 	UA_StatusCode retval = UA_String_decodeBinary(&src, &pos, &dst);
 	// then
@@ -585,12 +584,11 @@ END_TEST
 
 START_TEST(UA_String_decodeWithNegativeSizeShallNotAllocateMemoryAndNullPtr) {
 	// given
-	UA_UInt32     pos    = 0;
-	UA_Byte       data[] =
+	size_t pos = 0;
+	UA_Byte data[] =
 	{ 0xFF, 0xFF, 0xFF, 0xFF, 'A', 'C', 'P', 'L', 'T', ' ', 'U', 'A', 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
-	UA_ByteString src    = { 16, data };
-
-	UA_String     dst;
+	UA_ByteString src = { 16, data };
+	UA_String dst;
 	// when
 	UA_StatusCode retval = UA_String_decodeBinary(&src, &pos, &dst);
 	// then
@@ -602,28 +600,26 @@ END_TEST
 
 START_TEST(UA_String_decodeWithZeroSizeShallNotAllocateMemoryAndNullPtr) {
 	// given
-	UA_UInt32     pos    = 0;
-	UA_Byte       data[] =
+	size_t pos = 0;
+	UA_Byte data[] =
 	{ 0x00, 0x00, 0x00, 0x00, 'A', 'C', 'P', 'L', 'T', ' ', 'U', 'A', 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
-	UA_ByteString src    = { 16, data };
-
-	UA_String     dst    = { 2, (UA_Byte *)"XX" };
+	UA_ByteString src = { 17, data };
+	UA_String dst;
 	// when
 	UA_StatusCode retval = UA_String_decodeBinary(&src, &pos, &dst);
 	// then
 	ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
-	ck_assert_int_eq(dst.length, -1); // shall we keep zero?
+	ck_assert_int_eq(dst.length, 0);
 	ck_assert_ptr_eq(dst.data, UA_NULL);
 }
 END_TEST
 
 START_TEST(UA_NodeId_decodeTwoByteShallReadTwoBytesAndSetNamespaceToZero) {
 	// given
-	UA_UInt32     pos    = 0;
-	UA_Byte       data[] = { 0 /* UA_NODEIDTYPE_TWOBYTE */, 0x10 };
+	size_t pos = 0;
+	UA_Byte data[] = { 0 /* UA_NODEIDTYPE_TWOBYTE */, 0x10 };
 	UA_ByteString src    = { 2, data };
-
-	UA_NodeId     dst;
+	UA_NodeId dst;
 	// when
 	UA_StatusCode retval = UA_NodeId_decodeBinary(&src, &pos, &dst);
 	// then
@@ -637,11 +633,10 @@ END_TEST
 
 START_TEST(UA_NodeId_decodeFourByteShallReadFourBytesAndRespectNamespace) {
 	// given
-	UA_UInt32     pos    = 0;
-	UA_Byte       data[] = { 1 /* UA_NODEIDTYPE_FOURBYTE */, 0x01, 0x00, 0x01 };
-	UA_ByteString src    = { 4, data };
-
-	UA_NodeId     dst;
+	size_t pos = 0;
+	UA_Byte data[] = { 1 /* UA_NODEIDTYPE_FOURBYTE */, 0x01, 0x00, 0x01 };
+	UA_ByteString src = { 4, data };
+	UA_NodeId dst;
 	// when
 	UA_StatusCode retval = UA_NodeId_decodeBinary(&src, &pos, &dst);
 	// then
@@ -655,11 +650,10 @@ END_TEST
 
 START_TEST(UA_NodeId_decodeStringShallAllocateMemory) {
 	// given
-	UA_UInt32     pos    = 0;
-	UA_Byte       data[] = { UA_NODEIDTYPE_STRING, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 'P', 'L', 'T' };
-	UA_ByteString src    = { 10, data };
-
-	UA_NodeId     dst;
+	size_t pos = 0;
+	UA_Byte data[] = { UA_NODEIDTYPE_STRING, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 'P', 'L', 'T' };
+	UA_ByteString src = { 10, data };
+	UA_NodeId dst;
 	// when
 	UA_StatusCode retval = UA_NodeId_decodeBinary(&src, &pos, &dst);
 	// then
@@ -676,10 +670,10 @@ END_TEST
 
 START_TEST(UA_Variant_decodeWithOutArrayFlagSetShallSetVTAndAllocateMemoryForArray) {
 	// given
-	UA_UInt32     pos    = 0;
-	UA_Byte       data[] = { UA_TYPES_IDS[UA_TYPES_INT32], 0xFF, 0x00, 0x00, 0x00 };
-	UA_ByteString src    = { 5, data };
-	UA_Variant    dst;
+	size_t pos = 0;
+	UA_Byte data[] = { UA_TYPES_IDS[UA_TYPES_INT32], 0xFF, 0x00, 0x00, 0x00 };
+	UA_ByteString src = { 5, data };
+	UA_Variant dst;
 	// when
 	UA_StatusCode retval = UA_Variant_decodeBinary(&src, &pos, &dst);
 	// then
@@ -696,16 +690,14 @@ END_TEST
 
 START_TEST(UA_Variant_decodeWithArrayFlagSetShallSetVTAndAllocateMemoryForArray) {
 	// given
-	UA_UInt32     pos    = 0;
-	UA_Byte       data[] =
-	{ UA_TYPES_IDS[UA_TYPES_INT32] | UA_VARIANT_ENCODINGMASKTYPE_ARRAY, 0x02, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF,
-			0xFF,                                             0xFF };
+	size_t pos = 0;
+	UA_Byte data[] = { UA_TYPES_IDS[UA_TYPES_INT32] | UA_VARIANT_ENCODINGMASKTYPE_ARRAY,
+                       0x02, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+                       0xFF, 0xFF };
 	UA_ByteString src = { 13, data };
-	UA_Variant    dst;
-
+	UA_Variant dst;
 	// when
 	UA_StatusCode retval = UA_Variant_decodeBinary(&src, &pos, &dst);
-
 	// then
 	ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
 	ck_assert_int_eq(pos, 1+4+2*4);
@@ -721,12 +713,11 @@ END_TEST
 
 START_TEST(UA_Variant_decodeWithOutDeleteMembersShallFailInCheckMem) {
 	// given
-	UA_UInt32     pos    = 0;
-	UA_Byte       data[] =
-	{ UA_TYPES_IDS[UA_TYPES_INT32] | UA_VARIANT_ENCODINGMASKTYPE_ARRAY, 0x02, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF };
+	size_t pos = 0;
+	UA_Byte data[] = { UA_TYPES_IDS[UA_TYPES_INT32] | UA_VARIANT_ENCODINGMASKTYPE_ARRAY,
+                       0x02, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF };
 	UA_ByteString src = { 13, data };
-
-	UA_Variant    dst;
+	UA_Variant dst;
 	// when
 	UA_StatusCode retval = UA_Variant_decodeBinary(&src, &pos, &dst);
 	// then
@@ -738,12 +729,12 @@ END_TEST
 
 START_TEST(UA_Variant_decodeWithTooSmallSourceShallReturnWithError) {
 	// given
-	UA_UInt32     pos    = 0;
-	UA_Byte       data[] =
-	{ UA_TYPES_IDS[UA_TYPES_INT32] | UA_VARIANT_ENCODINGMASKTYPE_ARRAY, 0x02, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF };
+	size_t pos = 0;
+	UA_Byte data[] = { UA_TYPES_IDS[UA_TYPES_INT32] | UA_VARIANT_ENCODINGMASKTYPE_ARRAY,
+                       0x02, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF };
 	UA_ByteString src = { 4, data };
 
-	UA_Variant    dst;
+	UA_Variant dst;
 	// when
 	UA_StatusCode retval = UA_Variant_decodeBinary(&src, &pos, &dst);
 	// then
@@ -759,8 +750,8 @@ START_TEST(UA_Byte_encode_test) {
 	UA_Byte data[]    = { 0x00, 0xFF };
 	UA_ByteString dst = { 2, data };
 
-	UA_Int32  retval  = 0;
-	UA_UInt32 pos     = 0;
+	UA_Int32 retval = 0;
+	size_t pos = 0;
 
 	ck_assert_uint_eq(dst.data[1], 0xFF);
 
@@ -790,12 +781,11 @@ END_TEST
 START_TEST(UA_UInt16_encodeNegativeShallEncodeLittleEndian) {
 	// given
 	UA_UInt16     src;
-	UA_Byte       data[] = {  0x55, 0x55,
-			0x55,       0x55 };
+	UA_Byte       data[] = { 0x55, 0x55, 0x55, 0x55 };
 	UA_ByteString dst    = { 4, data };
 
 	UA_StatusCode retval = 0;
-	UA_UInt32     pos    = 0;
+	size_t pos = 0;
 
 	// when test 1
 	src    = -1;
@@ -825,7 +815,7 @@ START_TEST(UA_UInt16_encodeShallEncodeLittleEndian) {
 	UA_ByteString dst    = { 4, data };
 
 	UA_StatusCode retval = 0;
-	UA_UInt32     pos    = 0;
+	size_t pos = 0;
 
 	// when test 1
 	src    = 0;
@@ -854,7 +844,7 @@ START_TEST(UA_UInt32_encodeShallEncodeLittleEndian) {
 	UA_ByteString dst    = { 8, data };
 
 	UA_StatusCode retval = 0;
-	UA_UInt32     pos    = 0;
+	size_t pos = 0;
 
 	// when test 1
 	src    = -1;
@@ -886,8 +876,8 @@ START_TEST(UA_Int32_encodeShallEncodeLittleEndian) {
 	UA_Byte  data[]   = { 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55 };
 	UA_ByteString dst = { 8, data };
 
-	UA_Int32  retval  = 0;
-	UA_UInt32 pos     = 0;
+	UA_Int32 retval = 0;
+	size_t pos = 0;
 
 	// when test 1
 	src    = 1;
@@ -921,7 +911,7 @@ START_TEST(UA_Int32_encodeNegativeShallEncodeLittleEndian) {
 	UA_ByteString dst = { 8, data };
 
 	UA_Int32  retval  = 0;
-	UA_UInt32 pos     = 0;
+	size_t pos = 0;
 
 	// when test 1
 	src    = -1;
@@ -944,7 +934,7 @@ START_TEST(UA_UInt64_encodeShallWorkOnExample) {
 	UA_ByteString dst    = { 16, data };
 
 	UA_StatusCode retval = 0;
-	UA_UInt32     pos    = 0;
+	size_t pos    = 0;
 
 	// when test 1
 	src    = -1;
@@ -986,7 +976,7 @@ START_TEST(UA_Int64_encodeShallEncodeLittleEndian) {
 	UA_ByteString dst = { 16, data };
 
 	UA_Int32  retval  = 0;
-	UA_UInt32 pos     = 0;
+	size_t pos     = 0;
 
 	// when test 1
 	src    = 0x7F0033AA44EE6611;
@@ -1013,7 +1003,7 @@ START_TEST(UA_Int64_encodeNegativeShallEncodeLittleEndian) {
 	UA_ByteString dst = { 16, data };
 
 	UA_Int32  retval  = 0;
-	UA_UInt32 pos     = 0;
+	size_t pos     = 0;
 
 	// when test 1
 	src    = -1;
@@ -1040,7 +1030,7 @@ START_TEST(UA_Float_encodeShallWorkOnExample) {
 	UA_ByteString dst = { 16, data };
 
 	UA_Int32  retval  = 0;
-	UA_UInt32 pos     = 0;
+	size_t pos     = 0;
 
 	// when test 1
 	src    = -6.5;
@@ -1088,7 +1078,7 @@ START_TEST(UA_String_encodeShallWorkOnExample) {
 	UA_ByteString dst = { 24, data };
 
 	UA_Int32  retval  = 0;
-	UA_UInt32 pos     = 0;
+	size_t pos     = 0;
 
 	// when
 	retval = UA_String_encodeBinary(&src, &dst, &pos);
@@ -1118,7 +1108,7 @@ START_TEST(UA_DataValue_encodeShallWorkOnExampleWithoutVariant) {
 	UA_ByteString dst = { 24, data };
 
 	UA_Int32  retval  = 0;
-	UA_UInt32 pos     = 0;
+	size_t pos     = 0;
 
 	// when
 	retval = UA_DataValue_encodeBinary(&src, &dst, &pos);
@@ -1155,7 +1145,7 @@ START_TEST(UA_DataValue_encodeShallWorkOnExampleWithVariant) {
 	UA_ByteString dst = { 24, data };
 
 	UA_Int32  retval  = 0;
-	UA_UInt32 pos     = 0;
+	size_t pos     = 0;
 
 	// when
 	retval = UA_DataValue_encodeBinary(&src, &dst, &pos);
@@ -1632,7 +1622,7 @@ START_TEST(UA_ExtensionObject_encodeDecodeShallWorkOnExtensionObject) {
 	extensionObject.typeId.identifier.numeric = UA_TYPES_IDS[UA_TYPES_VARIABLEATTRIBUTES];
 	UA_Byte extensionData[50];
 	extensionObject.body = (UA_ByteString){.data = extensionData, .length=UA_VariableAttributes_calcSizeBinary(&varAttr)};
-	UA_UInt32 posEncode = 0;
+	size_t posEncode = 0;
 	UA_VariableAttributes_encodeBinary(&varAttr, &extensionObject.body, &posEncode);
 	extensionObject.encoding = UA_EXTENSIONOBJECT_ENCODINGMASK_BODYISBYTESTRING;
 	ck_assert_int_eq(posEncode, UA_VariableAttributes_calcSizeBinary(&varAttr));
@@ -1644,7 +1634,7 @@ START_TEST(UA_ExtensionObject_encodeDecodeShallWorkOnExtensionObject) {
 	UA_ExtensionObject_encodeBinary(&extensionObject, &dst, &posEncode);
 
 	UA_ExtensionObject extensionObjectDecoded;
-	UA_UInt32 posDecode = 0;
+	size_t posDecode = 0;
 	UA_ExtensionObject_decodeBinary(&dst, &posDecode, &extensionObjectDecoded);
 
 	ck_assert_int_eq(posEncode, posDecode);

+ 7 - 6
tests/check_memory.c

@@ -49,7 +49,7 @@ END_TEST
 START_TEST(encodeShallYieldDecode) {
 	// given
 	UA_ByteString msg1, msg2;
-	UA_UInt32     pos = 0;
+	size_t pos = 0;
 	void *obj1 = UA_new(&UA_TYPES[_i]);
 	UA_ByteString_newMembers(&msg1, UA_calcSizeBinary(obj1, &UA_TYPES[_i]));
     UA_StatusCode retval = UA_encodeBinary(obj1, &UA_TYPES[_i], &msg1, &pos);
@@ -82,14 +82,15 @@ END_TEST
 START_TEST(decodeShallFailWithTruncatedBufferButSurvive) {
 	// given
 	UA_ByteString msg1;
-	UA_UInt32 pos;
 	void *obj1 = UA_new(&UA_TYPES[_i]);
+	size_t pos = 0;
 	UA_ByteString_newMembers(&msg1, UA_calcSizeBinary(obj1, &UA_TYPES[_i]));
-    pos = 0;
     UA_StatusCode retval = UA_encodeBinary(obj1, &UA_TYPES[_i], &msg1, &pos);
 	UA_delete(obj1, &UA_TYPES[_i]);
-    if(retval != UA_STATUSCODE_GOOD)
+    if(retval != UA_STATUSCODE_GOOD) {
+        UA_ByteString_deleteMembers(&msg1);
         return; // e.g. variants cannot be encoded after an init without failing (no datatype set)
+    }
 	// when
 	void *obj2 = UA_new(&UA_TYPES[_i]);
 	pos = 0;
@@ -128,7 +129,7 @@ START_TEST(decodeScalarBasicTypeFromRandomBufferShallSucceed) {
 			msg1.data[i] = (UA_Byte)random();  // when
 #endif
 		}
-		UA_UInt32 pos = 0;
+		size_t pos = 0;
 		obj1 = UA_new(&UA_TYPES[_i]);
 		retval |= UA_decodeBinary(&msg1, &pos, obj1, &UA_TYPES[_i]);
 		//then
@@ -162,7 +163,7 @@ START_TEST(decodeComplexTypeFromRandomBufferShallSurvive) {
 			msg1.data[i] = (UA_Byte)random();  // when
 #endif
 		}
-		UA_UInt32 pos = 0;
+		size_t pos = 0;
 		void *obj1 = UA_new(&UA_TYPES[_i]);
 		retval |= UA_decodeBinary(&msg1, &pos, obj1, &UA_TYPES[_i]);
 		UA_delete(obj1, &UA_TYPES[_i]);

+ 63 - 60
tests/check_nodestore.c

@@ -34,11 +34,12 @@ static UA_Node* createNode(UA_Int16 nsid, UA_Int32 id) {
 
 START_TEST(replaceExistingNode) {
 	UA_NodeStore *ns = UA_NodeStore_new();
-	const UA_Node* n1 = createNode(0,2253);
-	UA_NodeStore_insert(ns, &n1, UA_TRUE);
-	const UA_Node* n2 = createNode(0,2253);
-    UA_StatusCode retval = UA_NodeStore_replace(ns, n1, &n2, UA_FALSE);
-    UA_NodeStore_release(n1);
+	UA_Node* n1 = createNode(0,2253);
+    const UA_Node *inserted;
+	UA_NodeStore_insert(ns, n1, &inserted);
+	UA_Node* n2 = createNode(0,2253);
+    UA_StatusCode retval = UA_NodeStore_replace(ns, inserted, n2, UA_NULL);
+    UA_NodeStore_release(inserted);
     
 	ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
     
@@ -48,13 +49,13 @@ END_TEST
 
 START_TEST(replaceNonExistingNode) {
 	UA_NodeStore *ns = UA_NodeStore_new();
-	const UA_Node* n1 = createNode(0,2253);
+	UA_Node* n1 = createNode(0,2253);
 	UA_Node* n2 = createNode(0,2253);
-    const UA_Node *dummy = n2;
-    UA_StatusCode retval = UA_NodeStore_replace(ns, n1, (const UA_Node **)&dummy, UA_FALSE);
+    UA_StatusCode retval = UA_NodeStore_replace(ns, n1, n2, UA_NULL);
     
 	ck_assert_int_ne(retval, UA_STATUSCODE_GOOD);
     
+    UA_VariableNode_delete((UA_VariableNode*)n1);
     UA_VariableNode_delete((UA_VariableNode*)n2);
 	UA_NodeStore_delete(ns);
 }
@@ -66,13 +67,14 @@ START_TEST(findNodeInUA_NodeStoreWithSingleEntry) {
 #endif
 	// given
 	UA_NodeStore *ns = UA_NodeStore_new();
-	const UA_Node* n1 = createNode(0,2253);
-	UA_NodeStore_insert(ns, &n1, UA_TRUE);
-	const UA_Node* nr = UA_NodeStore_get(ns,&n1->nodeId);
+    const UA_Node *inserted;
+	UA_Node* n1 = createNode(0,2253);
+	UA_NodeStore_insert(ns, n1, &inserted);
+	const UA_Node* nr = UA_NodeStore_get(ns,&inserted->nodeId);
 	// then
-	ck_assert_ptr_eq((const void*)nr, (const void*)n1);
+	ck_assert_int_eq((uintptr_t)inserted, (uintptr_t)nr);
 	// finally
-	UA_NodeStore_release(n1);
+	UA_NodeStore_release(inserted);
 	UA_NodeStore_release(nr);
 	UA_NodeStore_delete(ns);
 #ifdef UA_MULTITHREADING
@@ -88,14 +90,14 @@ START_TEST(failToFindNodeInOtherUA_NodeStore) {
 	// given
 	UA_NodeStore *ns = UA_NodeStore_new();
 
-	const UA_Node* n1 = createNode(0,2255);
-    UA_NodeStore_insert(ns, (const UA_Node **)&n1, UA_FALSE);
+	UA_Node* n1 = createNode(0,2255);
+    UA_NodeStore_insert(ns, n1, UA_NULL);
 
 	// when
 	UA_Node* n = createNode(1,2255);
 	const UA_Node* nr = UA_NodeStore_get(ns,&n->nodeId);
 	// then
-	ck_assert_ptr_eq((const void*)nr, UA_NULL);
+	ck_assert_int_eq((uintptr_t)nr, 0);
 	// finally
 	UA_VariableNode_delete((UA_VariableNode*)n);
 	UA_NodeStore_delete(ns);
@@ -111,25 +113,26 @@ START_TEST(findNodeInUA_NodeStoreWithSeveralEntries) {
 #endif
 	// given
 	UA_NodeStore *ns = UA_NodeStore_new();
-	const UA_Node* n1 = createNode(0,2253);
-    UA_NodeStore_insert(ns, &n1, UA_FALSE);
-	const UA_Node* n2 = createNode(0,2255);
-    UA_NodeStore_insert(ns, &n2, UA_FALSE);
-	const UA_Node* n3 = createNode(0,2257);
-    UA_NodeStore_insert(ns, &n3, UA_TRUE);
-	const UA_Node* n4 = createNode(0,2200);
-    UA_NodeStore_insert(ns, &n4, UA_FALSE);
-	const UA_Node* n5 = createNode(0,1);
-    UA_NodeStore_insert(ns, &n5, UA_FALSE);
-	const UA_Node* n6 = createNode(0,12);
-    UA_NodeStore_insert(ns, &n6, UA_FALSE);
+	UA_Node* n1 = createNode(0,2253);
+    UA_NodeStore_insert(ns, n1, UA_NULL);
+	UA_Node* n2 = createNode(0,2255);
+    UA_NodeStore_insert(ns, n2, UA_NULL);
+	UA_Node* n3 = createNode(0,2257);
+    const UA_Node *inserted;
+    UA_NodeStore_insert(ns, n3, &inserted);
+	UA_Node* n4 = createNode(0,2200);
+    UA_NodeStore_insert(ns, n4, UA_NULL);
+	UA_Node* n5 = createNode(0,1);
+    UA_NodeStore_insert(ns, n5, UA_NULL);
+	UA_Node* n6 = createNode(0,12);
+    UA_NodeStore_insert(ns, n6, UA_NULL);
 
 	// when
-	const UA_Node* nr = UA_NodeStore_get(ns,&(n3->nodeId));
+	const UA_Node* nr = UA_NodeStore_get(ns,&inserted->nodeId);
 	// then
-	ck_assert_ptr_eq((const void*)nr, (const void*)n3);
+	ck_assert_int_eq((uintptr_t)nr, (uintptr_t)inserted);
 	// finally
-	UA_NodeStore_release(n3);
+	UA_NodeStore_release(inserted);
 	UA_NodeStore_release(nr);
 	UA_NodeStore_delete(ns);
 #ifdef UA_MULTITHREADING
@@ -144,18 +147,18 @@ START_TEST(iterateOverUA_NodeStoreShallNotVisitEmptyNodes) {
 #endif
 	// given
 	UA_NodeStore *ns = UA_NodeStore_new();
-	const UA_Node* n1 = createNode(0,2253);
-    UA_NodeStore_insert(ns, &n1, 0);
-	const UA_Node* n2 = createNode(0,2255);
-    UA_NodeStore_insert(ns, &n2, 0);
-	const UA_Node* n3 = createNode(0,2257);
-    UA_NodeStore_insert(ns, &n3, 0);
-	const UA_Node* n4 = createNode(0,2200);
-    UA_NodeStore_insert(ns, &n4, 0);
-	const UA_Node* n5 = createNode(0,1);
-    UA_NodeStore_insert(ns, &n5, 0);
-	const UA_Node* n6 = createNode(0,12);
-    UA_NodeStore_insert(ns, &n6, 0);
+	UA_Node* n1 = createNode(0,2253);
+    UA_NodeStore_insert(ns, n1, UA_NULL);
+	UA_Node* n2 = createNode(0,2255);
+    UA_NodeStore_insert(ns, n2, UA_NULL);
+	UA_Node* n3 = createNode(0,2257);
+    UA_NodeStore_insert(ns, n3, UA_NULL);
+	UA_Node* n4 = createNode(0,2200);
+    UA_NodeStore_insert(ns, n4, UA_NULL);
+	UA_Node* n5 = createNode(0,1);
+    UA_NodeStore_insert(ns, n5, UA_NULL);
+	UA_Node* n6 = createNode(0,12);
+    UA_NodeStore_insert(ns, n6, UA_NULL);
 
 	// when
 	zeroCnt = 0;
@@ -178,11 +181,11 @@ START_TEST(findNodeInExpandedNamespace) {
 #endif
 	// given
 	UA_NodeStore *ns = UA_NodeStore_new();
-	const UA_Node* n;
+	UA_Node* n;
 	UA_Int32 i=0;
 	for (; i<200; i++) {
 		n = createNode(0,i);
-        UA_NodeStore_insert(ns, (const UA_Node **)&n, UA_FALSE);
+        UA_NodeStore_insert(ns, n, UA_NULL);
 	}
 	// when
 	UA_Node *n2 = createNode(0,25);
@@ -205,11 +208,11 @@ START_TEST(iterateOverExpandedNamespaceShallNotVisitEmptyNodes) {
 #endif
 	// given
 	UA_NodeStore *ns = UA_NodeStore_new();
-	const UA_Node* n;
+    UA_Node* n;
 	UA_Int32 i=0;
 	for (; i<200; i++) {
 		n = createNode(0,i);
-        UA_NodeStore_insert(ns, &n, UA_FALSE);
+        UA_NodeStore_insert(ns, n, UA_NULL);
 	}
 	// when
 	zeroCnt = 0;
@@ -232,22 +235,22 @@ START_TEST(failToFindNonExistantNodeInUA_NodeStoreWithSeveralEntries) {
 #endif
 	// given
 	UA_NodeStore *ns = UA_NodeStore_new();
-	const UA_Node* n1 = createNode(0,2253);
-    UA_NodeStore_insert(ns, &n1, UA_FALSE);
-	const UA_Node* n2 = createNode(0,2255);
-    UA_NodeStore_insert(ns, &n2, UA_FALSE);
-	const UA_Node* n3 = createNode(0,2257);
-    UA_NodeStore_insert(ns, &n3, UA_FALSE);
-	const UA_Node* n4 = createNode(0,2200);
-    UA_NodeStore_insert(ns, &n4, UA_FALSE);
-	const UA_Node* n5 = createNode(0,1);
-    UA_NodeStore_insert(ns, &n5, UA_FALSE);
+	UA_Node* n1 = createNode(0,2253);
+    UA_NodeStore_insert(ns, n1, UA_NULL);
+	UA_Node* n2 = createNode(0,2255);
+    UA_NodeStore_insert(ns, n2, UA_NULL);
+	UA_Node* n3 = createNode(0,2257);
+    UA_NodeStore_insert(ns, n3, UA_NULL);
+	UA_Node* n4 = createNode(0,2200);
+    UA_NodeStore_insert(ns, n4, UA_NULL);
+	UA_Node* n5 = createNode(0,1);
+    UA_NodeStore_insert(ns, n5, UA_NULL);
 	UA_Node* n6 = createNode(0,12); 
 
 	// when
 	const UA_Node* nr = UA_NodeStore_get(ns, &n6->nodeId);
 	// then
-	ck_assert_ptr_eq((const void*)nr, UA_NULL);
+	ck_assert_int_eq((uintptr_t)nr, 0);
 	// finally
 	UA_free((void *)n6);
 	UA_NodeStore_delete(ns);
@@ -297,10 +300,10 @@ START_TEST(profileGetDelete) {
 
 #define N 1000000
 	UA_NodeStore *ns = UA_NodeStore_new();
-	const UA_Node *n;
+	UA_Node *n;
 	for (int i=0; i<N; i++) {
 		n = createNode(0,i);
-        UA_NodeStore_insert(ns, (const UA_Node **)&n, UA_FALSE);
+        UA_NodeStore_insert(ns, n, UA_NULL);
 	}
 	clock_t begin, end;
 	begin = clock();