Browse Source

check_builtin runs cleanly, valgrind is happy

Julius Pfrommer 10 years ago
parent
commit
25802a6049
4 changed files with 67 additions and 78 deletions
  1. 5 8
      include/ua_types.h
  2. 25 27
      src/ua_types.c
  3. 20 17
      src/ua_types_encoding_binary.c
  4. 17 26
      tests/check_builtin.c

+ 5 - 8
include/ua_types.h

@@ -325,7 +325,7 @@ UA_TYPE_HANDLING_FUNCTIONS(UA_DiagnosticInfo)
 
 /* String */
 #define UA_STRING_NULL (UA_String) {-1, (UA_Byte*)0 }
-#define UA_STRING_STATIC(VARIABLE, STRING) do { \
+#define UA_STRING_ASSIGN(VARIABLE, STRING) do { \
         VARIABLE.length = sizeof(STRING)-1;     \
         VARIABLE.data   = (UA_Byte *)STRING; } while(0)
 
@@ -367,22 +367,19 @@ 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);
 UA_Boolean UA_EXPORT UA_NodeId_isNull(const UA_NodeId *p);
+#define UA_NODEID_ASSIGN(VARIABLE, NUMERICID, NAMESPACE) do { \
+    VARIABLE.namespaceIndex = NAMESPACE;                      \
+    VARIABLE.identifierType = UA_NODEIDTYPE_NUMERIC;          \
+    VARIABLE.identifier.numeric = NUMERICID; } while(0);
 
 /* ExpandedNodeId */
 UA_Boolean UA_EXPORT UA_ExpandedNodeId_isNull(const UA_ExpandedNodeId *p);
 
 /* QualifiedName */
-#define UA_QUALIFIEDNAME_STATIC(VARIABLE, STRING) do { \
-        VARIABLE.namespaceIndex = 0;                   \
-        UA_STRING_STATIC(VARIABLE.name, STRING); } while(0)
 UA_StatusCode UA_EXPORT UA_QualifiedName_copycstring(char const *src, UA_QualifiedName *dst);
 void UA_EXPORT UA_QualifiedName_printf(char const *label, const UA_QualifiedName *qn);
 
 /* LocalizedText */
-#define UA_LOCALIZEDTEXT_STATIC(VARIABLE, STRING) do { \
-        UA_STRING_STATIC(VARIABLE.locale, "en");       \
-        UA_STRING_STATIC(VARIABLE.text, STRING); } while(0)
-
 UA_StatusCode UA_EXPORT UA_LocalizedText_copycstring(char const *src, UA_LocalizedText *dst);
 
 /* Variant */

+ 25 - 27
src/ua_types.c

@@ -358,24 +358,20 @@ UA_StatusCode UA_NodeId_copy(UA_NodeId const *src, UA_NodeId *dst) {
     case UA_NODEIDTYPE_NUMERIC:
         *dst = *src;
         return UA_STATUSCODE_GOOD;
-        break;
-
     case UA_NODEIDTYPE_STRING: // Table 6, second entry
         retval |= UA_String_copy(&src->identifier.string, &dst->identifier.string);
         break;
-
     case UA_NODEIDTYPE_GUID: // Table 6, third entry
         retval |= UA_Guid_copy(&src->identifier.guid, &dst->identifier.guid);
         break;
-
     case UA_NODEIDTYPE_BYTESTRING: // Table 6, "OPAQUE"
         retval |= UA_ByteString_copy(&src->identifier.byteString, &dst->identifier.byteString);
         break;
-
     default:
         UA_NodeId_init(dst);
         return UA_STATUSCODE_BADINTERNALERROR;
     }
+    dst->namespaceIndex = src->namespaceIndex;
     dst->identifierType = src->identifierType;
     if(retval)
         UA_NodeId_deleteMembers(dst);
@@ -474,9 +470,8 @@ void UA_ExpandedNodeId_init(UA_ExpandedNodeId *p) {
 
 UA_TYPE_NEW_DEFAULT(UA_ExpandedNodeId)
 UA_StatusCode UA_ExpandedNodeId_copy(UA_ExpandedNodeId const *src, UA_ExpandedNodeId *dst) {
-    UA_StatusCode retval = UA_STATUSCODE_GOOD;
+    UA_StatusCode retval = UA_NodeId_copy(&src->nodeId, &dst->nodeId);
     retval |= UA_String_copy(&src->namespaceUri, &dst->namespaceUri);
-    retval |= UA_NodeId_copy(&src->nodeId, &dst->nodeId);
     dst->serverIndex = src->serverIndex;
     if(retval)
         UA_ExpandedNodeId_deleteMembers(dst);
@@ -587,6 +582,7 @@ void UA_DataValue_init(UA_DataValue *p) {
 
 UA_TYPE_NEW_DEFAULT(UA_DataValue)
 UA_StatusCode UA_DataValue_copy(UA_DataValue const *src, UA_DataValue *dst) {
+    UA_DataValue_init(dst);
     *((UA_Byte*)dst) = *((const UA_Byte*)src); // the bitfield
     UA_StatusCode retval = UA_DateTime_copy(&src->serverTimestamp, &dst->serverTimestamp);
     retval |= UA_DateTime_copy(&src->sourceTimestamp, &dst->sourceTimestamp);
@@ -774,7 +770,7 @@ void UA_init(void *p, const UA_DataType *dataType) {
                the length integer */
             ptr += (member->padding >> 3);
             *((UA_Int32*)ptr) = -1;
-            ptr += sizeof(UA_Int32) + (member->padding & 0x000fff);
+            ptr += sizeof(UA_Int32) + (member->padding & 0x07);
             *((void**)ptr) = UA_NULL;
             ptr += sizeof(void*);
             continue;
@@ -861,6 +857,8 @@ UA_StatusCode UA_copy(const void *src, void *dst, const UA_DataType *dataType) {
         memcpy(dst, src, dataType->memSize);
         return UA_STATUSCODE_GOOD;
     }
+    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++) {
@@ -876,9 +874,9 @@ UA_StatusCode UA_copy(const void *src, void *dst, const UA_DataType *dataType) {
             ptrd += (member->padding >> 3);
             UA_Int32 *dstNoElements = (UA_Int32*)ptrd;
             const UA_Int32 noElements = *((const UA_Int32*)ptrs);
-            ptrs += sizeof(UA_Int32) + (member->padding & 0x000fff);
-            ptrd += sizeof(UA_Int32) + (member->padding & 0x000fff);
-            UA_StatusCode retval = UA_Array_copy(ptrs, noElements, (void**)&ptrd, memberType);
+            ptrs += sizeof(UA_Int32) + (member->padding & 0x07);
+            ptrd += sizeof(UA_Int32) + (member->padding & 0x07);
+            retval = UA_Array_copy(*(void* const*)ptrs, noElements, (void**)ptrd, memberType);
             if(retval != UA_STATUSCODE_GOOD) {
                 UA_deleteMembers(dst, dataType);
                 return retval;
@@ -891,9 +889,8 @@ UA_StatusCode UA_copy(const void *src, void *dst, const UA_DataType *dataType) {
 
         ptrs += member->padding;
         ptrd += member->padding;
-
         if(!member->namespaceZero) {
-            UA_StatusCode retval = UA_copy(ptrs, ptrd, memberType);
+            retval = UA_copy(ptrs, ptrd, memberType);
             if(retval != UA_STATUSCODE_GOOD) {
                 UA_deleteMembers(dst, dataType);
                 return retval;
@@ -929,41 +926,43 @@ UA_StatusCode UA_copy(const void *src, void *dst, const UA_DataType *dataType) {
             *((UA_Guid*)ptrd) = *((const UA_Guid*)ptrs);
             break;
         case UA_TYPES_NODEID:
-            UA_NodeId_copy((const UA_NodeId*)ptrs, (UA_NodeId*)ptrd);
+            retval |= UA_NodeId_copy((const UA_NodeId*)ptrs, (UA_NodeId*)ptrd);
             break;
         case UA_TYPES_EXPANDEDNODEID:
-            UA_ExpandedNodeId_copy((const UA_ExpandedNodeId*)ptrs, (UA_ExpandedNodeId*)ptrd);
+            retval |= UA_ExpandedNodeId_copy((const UA_ExpandedNodeId*)ptrs, (UA_ExpandedNodeId*)ptrd);
             break;
         case UA_TYPES_QUALIFIEDNAME:
-            UA_QualifiedName_copy((const UA_QualifiedName*)ptrs, (UA_QualifiedName*)ptrd);
+            retval |= UA_QualifiedName_copy((const UA_QualifiedName*)ptrs, (UA_QualifiedName*)ptrd);
             break;
         case UA_TYPES_LOCALIZEDTEXT:
-            UA_LocalizedText_copy((const UA_LocalizedText*)ptrs, (UA_LocalizedText*)ptrd);
+            retval |= UA_LocalizedText_copy((const UA_LocalizedText*)ptrs, (UA_LocalizedText*)ptrd);
             break;
         case UA_TYPES_EXTENSIONOBJECT:
-            UA_ExtensionObject_copy((const UA_ExtensionObject*)ptrs, (UA_ExtensionObject*)ptrd);
+            retval |= UA_ExtensionObject_copy((const UA_ExtensionObject*)ptrs, (UA_ExtensionObject*)ptrd);
             break;
         case UA_TYPES_DATAVALUE:
-            UA_DataValue_copy((const UA_DataValue*)ptrs, (UA_DataValue*)ptrd);
+            retval |= UA_DataValue_copy((const UA_DataValue*)ptrs, (UA_DataValue*)ptrd);
             break;
         case UA_TYPES_VARIANT:
-            UA_Variant_copy((const UA_Variant*)ptrs, (UA_Variant*)ptrd);
+            retval |= UA_Variant_copy((const UA_Variant*)ptrs, (UA_Variant*)ptrd);
             break;
         case UA_TYPES_DIAGNOSTICINFO:
-            UA_DiagnosticInfo_copy((const UA_DiagnosticInfo*)ptrs, (UA_DiagnosticInfo*)ptrd);
+            retval |= UA_DiagnosticInfo_copy((const UA_DiagnosticInfo*)ptrs, (UA_DiagnosticInfo*)ptrd);
             break;
         case UA_TYPES_STRING:
         case UA_TYPES_BYTESTRING:
         case UA_TYPES_XMLELEMENT:
-            UA_String_copy((const UA_String*)ptrs, (UA_String*)ptrd);
+            retval |= UA_String_copy((const UA_String*)ptrs, (UA_String*)ptrd);
             break;
         default:
-            UA_copy(ptrs, ptrd, &UA_TYPES[member->memberTypeIndex]);
+            retval |= UA_copy(ptrs, ptrd, &UA_TYPES[member->memberTypeIndex]);
         }
         ptrs += memberType->memSize;
         ptrd += memberType->memSize;
     }
-    return UA_STATUSCODE_GOOD;
+    if(retval != UA_STATUSCODE_GOOD)
+        UA_deleteMembers(dst, dataType);
+    return retval;
 }
 
 void UA_deleteMembers(void *p, const UA_DataType *dataType) {
@@ -982,14 +981,13 @@ void UA_deleteMembers(void *p, const UA_DataType *dataType) {
         if(member->isArray) {
             ptr += (member->padding >> 3);
             UA_Int32 noElements = *((UA_Int32*)ptr);
-            ptr += sizeof(UA_Int32) + (member->padding & 0x000fff);
-            UA_Array_delete(ptr, noElements, memberType);
+            ptr += sizeof(UA_Int32) + (member->padding & 0x07);
+            UA_Array_delete(*(void**)ptr, noElements, memberType);
             ptr += sizeof(void*);
             continue;
         }
 
         ptr += member->padding;
-            
         if(!member->namespaceZero) {
             UA_deleteMembers(ptr, memberType);
             ptr += memberType->memSize;

+ 20 - 17
src/ua_types_encoding_binary.c

@@ -602,31 +602,29 @@ UA_UInt32 UA_ExtensionObject_calcSizeBinary(UA_ExtensionObject const *p) {
     UA_Int32 length = UA_NodeId_calcSizeBinary(&p->typeId);
     length += 1; // encoding
     switch(p->encoding) {
+    case UA_EXTENSIONOBJECT_ENCODINGMASK_NOBODYISENCODED:
+        break;
     case UA_EXTENSIONOBJECT_ENCODINGMASK_BODYISBYTESTRING:
         length += UA_ByteString_calcSizeBinary(&p->body);
         break;
-
     case UA_EXTENSIONOBJECT_ENCODINGMASK_BODYISXML:
         length += UA_XmlElement_calcSizeBinary((const UA_XmlElement *)&p->body);
         break;
-
     default:
-        break;
+        UA_assert(UA_FALSE);
     }
     return length;
 }
 
 UA_StatusCode UA_ExtensionObject_encodeBinary(UA_ExtensionObject const *src, UA_ByteString * dst, UA_UInt32 *offset) {
-    UA_Byte encoding = src->encoding;
     UA_StatusCode retval = UA_NodeId_encodeBinary(&src->typeId, dst, offset);
-    retval |= UA_Byte_encodeBinary(&encoding, dst, offset);
+    retval |= UA_Byte_encodeBinary((const UA_Byte*)&src->encoding, dst, offset);
     switch(src->encoding) {
     case UA_EXTENSIONOBJECT_ENCODINGMASK_NOBODYISENCODED:
         break;
     case UA_EXTENSIONOBJECT_ENCODINGMASK_BODYISBYTESTRING:
-        // FIXME: This code is valid for numeric nodeIds in ns0 only!
-        //retval |= UA_TYPES[UA_ns0ToVTableIndex(&src->typeId)].encodings[UA_ENCODING_BINARY].encode(src->body.data, dst, offset);
-        //break;
+        retval |= UA_ByteString_encodeBinary(&src->body, dst, offset);
+        break;
     case UA_EXTENSIONOBJECT_ENCODINGMASK_BODYISXML:
         retval |= UA_ByteString_encodeBinary(&src->body, dst, offset);
         break;
@@ -764,7 +762,10 @@ UA_UInt32 UA_Variant_calcSizeBinary(UA_Variant const *p) {
     if(arrayLength < 1) {
         length += 4; // length
     } else {
-        length += UA_Array_calcSizeBinary(data->dataPtr, arrayLength, p->type);
+        if(arrayLength > 1)
+            length += UA_Array_calcSizeBinary(data->dataPtr, arrayLength, p->type);
+        else
+            length += UA_calcSizeBinary(data->dataPtr, p->type);
         // if the type is not builtin, we encode it as an extensionobject
         if(!p->type->namespaceZero || p->type->typeIndex > 24)
             length += 9 * arrayLength;  // overhead for extensionobjects: 4 byte nodeid + 1 byte encoding + 4 byte bytestring length
@@ -977,17 +978,19 @@ UA_UInt32 UA_calcSizeBinary(const void *p, const UA_DataType *dataType) {
         if(member->isArray) {
             ptr += (member->padding >> 3);
             const UA_Int32 noElements = *((const UA_Int32*)ptr);
-            ptr += sizeof(UA_Int32) + (member->padding & 0x000fff);
-            size += UA_Array_calcSizeBinary(ptr, noElements, memberType);
+            ptr += sizeof(UA_Int32) + (member->padding & 0x07);
+            size += UA_Array_calcSizeBinary(*(void * const *)ptr, noElements, memberType);
             ptr += sizeof(void*);
             continue;
         }
+
         ptr += member->padding;
         if(!member->namespaceZero) {
             size += UA_calcSizeBinary(ptr, memberType);
             ptr += memberType->memSize;
             continue;
         }
+
         switch(member->memberTypeIndex) {
         case UA_TYPES_BOOLEAN:
         case UA_TYPES_SBYTE:
@@ -1065,8 +1068,8 @@ UA_StatusCode UA_encodeBinary(const void *src, const UA_DataType *dataType, UA_B
         if(member->isArray) {
             ptr += (member->padding >> 3);
             const UA_Int32 noElements = *((const UA_Int32*)ptr);
-            ptr += sizeof(UA_Int32) + (member->padding & 0x000fff);
-            retval = UA_Array_encodeBinary(ptr, noElements, memberType, dst, offset);
+            ptr += sizeof(UA_Int32) + (member->padding & 0x07);
+            retval = UA_Array_encodeBinary(*(void * const *)ptr, noElements, memberType, dst, offset);
             ptr += sizeof(void*);
             continue;
         }
@@ -1161,19 +1164,19 @@ UA_StatusCode UA_decodeBinary(const UA_ByteString *src, UA_UInt32 *offset, void
         if(member->isArray) {
             ptr += (member->padding >> 3);
             UA_Int32 noElements = *((UA_Int32*)ptr);
-            ptr += sizeof(UA_Int32) + (member->padding & 0x000fff);
-            void **array = (void**)&ptr;
-            retval = UA_Array_decodeBinary(src, offset, noElements, array, memberType);
+            ptr += sizeof(UA_Int32) + (member->padding & 0x07);
+            retval = UA_Array_decodeBinary(src, offset, noElements, (void**)ptr, memberType);
             ptr += sizeof(void*);
             continue;
         }
+
         ptr += member->padding;
         if(!member->namespaceZero) {
             UA_decodeBinary(src, offset, ptr, memberType);
             ptr += memberType->memSize;
             continue;
         }
-        ptr += member->padding;
+
         switch(member->memberTypeIndex) {
         case UA_TYPES_BOOLEAN:
         case UA_TYPES_SBYTE:

+ 17 - 26
tests/check_builtin.c

@@ -41,6 +41,7 @@ END_TEST
 START_TEST(UA_DataValue_calcSizeShallWorkOnExample) {
 	// given
 	UA_DataValue dataValue;
+    UA_DataValue_init(&dataValue);
 	dataValue.status       = 12;
     dataValue.hasStatus = UA_TRUE;
 	dataValue.sourceTimestamp = 80;
@@ -59,6 +60,7 @@ END_TEST
 START_TEST(UA_DiagnosticInfo_calcSizeShallWorkOnExample) {
 	// given
 	UA_DiagnosticInfo diagnosticInfo;
+    UA_DiagnosticInfo_init(&diagnosticInfo);
 	diagnosticInfo.symbolicId    = 30;
     diagnosticInfo.hasSymbolicId = UA_TRUE;
 	diagnosticInfo.namespaceUri  = 25;
@@ -1104,6 +1106,7 @@ END_TEST
 START_TEST(UA_DataValue_encodeShallWorkOnExampleWithoutVariant) {
 	// given
 	UA_DataValue src;
+    UA_DataValue_init(&src);
 	src.serverTimestamp = 80;
     src.hasServerTimestamp = UA_TRUE;
 
@@ -1135,10 +1138,10 @@ END_TEST
 START_TEST(UA_DataValue_encodeShallWorkOnExampleWithVariant) {
 	// given
 	UA_DataValue src;
+    UA_DataValue_init(&src);
 	src.serverTimestamp    = 80;
     src.hasVariant = UA_TRUE;
     src.hasServerTimestamp = UA_TRUE;
-	UA_Variant_init(&src.value);
 	src.value.type = &UA_TYPES[UA_TYPES_INT32];
 	src.value.storage.data.arrayLength  = 1; // one element (encoded as not an array)
 	UA_Int32  vdata  = 45;
@@ -1607,35 +1610,20 @@ START_TEST(UA_Variant_copyShallWorkOn2DArrayExample) {
 END_TEST
 
 START_TEST(UA_ExtensionObject_encodeDecodeShallWorkOnExtensionObject) {
-	/* take an int */
 	UA_Int32 val = 42;
-
-	/* wrap it into a variant */
-	UA_Variant varVal;
-	UA_Variant_init(&varVal);
-	varVal.type = &UA_TYPES[UA_TYPES_INT32];
-	varVal.storage.data.dataPtr = &val;
-	varVal.storage.data.arrayDimensionsLength = -1;
-	varVal.storage.data.arrayDimensions = UA_NULL;
-	varVal.storageType = UA_VARIANT_DATA_NODELETE;
-	varVal.storage.data.arrayLength = 1;
-	varVal.storage.data.dataPtr = &val;
-
-	/* wrap it into a variable attributes */
 	UA_VariableAttributes varAttr;
 	UA_VariableAttributes_init(&varAttr);
+    varAttr.dataType.identifierType = UA_NODEIDTYPE_NUMERIC;
 	varAttr.dataType.identifier.numeric = UA_TYPES_IDS[UA_TYPES_INT32];
-	UA_Variant_copy(&varVal,&varAttr.value);
+	UA_Variant_init(&varAttr.value);
+	varAttr.value.type = &UA_TYPES[UA_TYPES_INT32];
+    UA_NODEID_ASSIGN(varAttr.value.typeId, UA_TYPES_IDS[UA_TYPES_INT32], 0);
+	varAttr.value.storage.data.dataPtr = &val;
+	varAttr.value.storage.data.arrayLength = 1;
 	varAttr.userWriteMask = 41;
-	varAttr.specifiedAttributes |= UA_NODEATTRIBUTESMASK_VALUERANK;
-	varAttr.arrayDimensions = UA_NULL;
-	varAttr.arrayDimensionsSize = -1;
-	varAttr.specifiedAttributes |= UA_NODEATTRIBUTESMASK_BROWSENAME;
-	varAttr.specifiedAttributes |= UA_NODEATTRIBUTESMASK_DISPLAYNAME;
-	varAttr.specifiedAttributes |= UA_NODEATTRIBUTESMASK_DESCRIPTION;
-	varAttr.specifiedAttributes |= UA_NODEATTRIBUTESMASK_VALUE;
 	varAttr.specifiedAttributes |= UA_NODEATTRIBUTESMASK_DATATYPE;
-	varAttr.specifiedAttributes |= UA_NODEATTRIBUTESMASK_ARRAYDIMENSIONS;
+	varAttr.specifiedAttributes |= UA_NODEATTRIBUTESMASK_VALUE;
+	varAttr.specifiedAttributes |= UA_NODEATTRIBUTESMASK_USERWRITEMASK;
 	/* wrap it into a extension object attributes */
 	UA_ExtensionObject extensionObject;
 	UA_ExtensionObject_init(&extensionObject);
@@ -1665,8 +1653,11 @@ START_TEST(UA_ExtensionObject_encodeDecodeShallWorkOnExtensionObject) {
 	posDecode = 0;
 	UA_VariableAttributes_decodeBinary(&extensionObjectDecoded.body, &posDecode, &varAttrDecoded);
 	ck_assert_uint_eq(41, varAttrDecoded.userWriteMask);
-	UA_Variant* varValDecoded = &(varAttrDecoded.value);
-	ck_assert_int_eq(1, varValDecoded->storage.data.arrayLength);
+	ck_assert_int_eq(1, varAttrDecoded.value.storage.data.arrayLength);
+
+    // finally
+    UA_ExtensionObject_deleteMembers(&extensionObjectDecoded);
+    UA_Variant_deleteMembers(&varAttrDecoded.value);
 
 }
 END_TEST