Browse Source

reduce use if C99 idioms

Julius Pfrommer 10 years ago
parent
commit
556c2e85e3
5 changed files with 59 additions and 63 deletions
  1. 1 1
      CMakeLists.txt
  2. 5 6
      include/ua_types.h
  3. 26 23
      src/ua_types.c
  4. 19 25
      src/ua_types_encoding_binary.c
  5. 8 8
      tools/generate_datatypes.py

+ 1 - 1
CMakeLists.txt

@@ -45,7 +45,7 @@ set(lib_sources
 
 # compiler flags
 if(CMAKE_COMPILER_IS_GNUCC OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang")
-add_definitions(-pipe -Wall -Wextra -Werror -Wformat
+add_definitions(-std=c99 -pedantic -pipe -Wall -Wextra -Werror -Wformat
                 -Wno-unused-parameter -Wno-unused-function -Wno-unused-label -Wpointer-arith -Wreturn-type -Wsign-compare -Wmultichar
                 -Wshadow -Wcast-qual -Wmissing-prototypes -Wstrict-prototypes # -Wconversion
                 -Winit-self -Wuninitialized -Wno-deprecated -Wformat-security -ffunction-sections -fdata-sections)

+ 5 - 6
include/ua_types.h

@@ -213,15 +213,13 @@ typedef struct {
 
 struct UA_DataType;
 typedef struct UA_DataType UA_DataType; 
-struct UA_DataTypeTable;
-typedef struct UA_DataTypeTable UA_DataTypeTable; 
 
 /** @brief Variants store (arrays of) any data type. Either they provide a pointer to the data in
     memory, or functions from which the data can be accessed. Variants are replaced together with
     the data they store (exception: use a data source).*/
 typedef struct {
-    UA_UInt16 typeIndex;
-    const UA_DataTypeTable *typeTable;
+    const UA_DataType *dataType;
+    UA_NodeId dataTypeId;
     enum {
         UA_VARIANT_DATA, ///< The data is "owned" by this variant (copied and deleted together)
         UA_VARIANT_DATA_NODELETE, /**< The data is "borrowed" by the variant and shall not be
@@ -430,7 +428,7 @@ struct UA_DataType {
     UA_DataTypeMember members[UA_MAX_TYPE_MEMBERS];
 };
 
-struct UA_DataTypeTable {
+struct UA_DataTypeDescription {
     UA_DataType *types;
     UA_UInt32 *numericNodeIds;
     UA_UInt16 namespaceIndex;
@@ -439,7 +437,8 @@ struct UA_DataTypeTable {
 
 /** The structured types defined in the standard are stored in this array. Generally access looks
     like UA_TYPES_NS0[UA_INT32], where the name of the type in uppercase gives the types index. */
-extern const UA_DataTypeTable UA_EXPORT UA_TYPES;
+extern const UA_DataType UA_EXPORT *UA_TYPES;
+extern const UA_UInt32 UA_EXPORT *UA_TYPES_IDS;
 
 void UA_EXPORT * UA_new(const UA_DataType *dataType);
 void UA_EXPORT UA_init(void *p, const UA_DataType *dataType);

+ 26 - 23
src/ua_types.c

@@ -2,7 +2,7 @@
 #include <time.h>
 #include <stdio.h> // printf
 #include <string.h> // strlen
-//#define __USE_POSIX
+#define __USE_POSIX
 #include <stdlib.h> // malloc, free, rand
 
 #ifdef _WIN32
@@ -601,19 +601,17 @@ void UA_Variant_init(UA_Variant *p) {
     p->storage.data.dataPtr        = UA_NULL;
     p->storage.data.arrayDimensions       = UA_NULL;
     p->storage.data.arrayDimensionsLength = -1;
-    p->typeIndex = 0;
-    p->typeTable = &UA_TYPES;
+    UA_NodeId_init(&p->dataTypeId);
+    p->dataType = UA_NULL;
 }
 
 UA_TYPE_DELETE_DEFAULT(UA_Variant)
 void UA_Variant_deleteMembers(UA_Variant *p) {
     if(p->storageType == UA_VARIANT_DATA) {
         if(p->storage.data.dataPtr) {
-            if(p->storage.data.arrayLength == 1)
-                UA_delete(p->storage.data.dataPtr, &p->typeTable->types[p->typeIndex]);
-            else
-                UA_Array_delete(p->storage.data.dataPtr, p->storage.data.arrayLength, &p->typeTable->types[p->typeIndex]);
+            UA_Array_delete(p->storage.data.dataPtr, p->storage.data.arrayLength, p->dataType);
             p->storage.data.dataPtr = UA_NULL;
+            p->storage.data.arrayLength = 0;
         }
 
         if(p->storage.data.arrayDimensions) {
@@ -623,6 +621,8 @@ void UA_Variant_deleteMembers(UA_Variant *p) {
         return;
     }
 
+    UA_NodeId_deleteMembers(&p->dataTypeId);
+
     if(p->storageType == UA_VARIANT_DATASOURCE) {
         p->storage.datasource.delete(p->storage.datasource.handle);
     }
@@ -646,16 +646,15 @@ UA_StatusCode UA_Variant_copy(UA_Variant const *src, UA_Variant *dst) {
     }
 
     /* 2) Copy the data to the destination */
-    retval |= UA_Array_copy(srcdata->dataPtr, srcdata->arrayLength, &dstdata->dataPtr,
-                            &src->typeTable->types[src->typeIndex]);
+    retval |= UA_Array_copy(srcdata->dataPtr, srcdata->arrayLength, &dstdata->dataPtr, src->dataType);
     if(retval == UA_STATUSCODE_GOOD) {
         dst->storageType = UA_VARIANT_DATA;
-        dst->typeIndex = src->typeIndex;
-        dst->typeTable = src->typeTable;
+        dst->dataType= src->dataType;
+        UA_NodeId_copy(&src->dataTypeId, &dst->dataTypeId);
         dstdata->arrayLength = srcdata->arrayLength;
         if(srcdata->arrayDimensions) {
             retval |= UA_Array_copy(srcdata->arrayDimensions, srcdata->arrayDimensionsLength,
-                                    (void **)&dstdata->arrayDimensions, &UA_TYPES.types[UA_INT32]);
+                                    (void **)&dstdata->arrayDimensions, &UA_TYPES[UA_INT32]);
             if(retval == UA_STATUSCODE_GOOD)
                 dstdata->arrayDimensionsLength = srcdata->arrayDimensionsLength;
             else {
@@ -675,12 +674,14 @@ UA_StatusCode UA_Variant_copy(UA_Variant const *src, UA_Variant *dst) {
 /** Copies data into a variant. The target variant has always a storagetype UA_VARIANT_DATA */
 UA_StatusCode UA_Variant_copySetValue(UA_Variant *v, const void *p, UA_UInt16 typeIndex) {
     UA_Variant_init(v);
-    v->typeIndex = typeIndex;
-    v->typeTable = &UA_TYPES;
+    v->dataType = &UA_TYPES[typeIndex];
+    v->dataTypeId = (UA_NodeId){.namespaceIndex = 0,
+                                .identifierType = UA_NODEIDTYPE_NUMERIC,
+                                .identifier.numeric = UA_TYPES_IDS[typeIndex]};
     v->storage.data.arrayLength = 1; // no array but a single entry
     UA_StatusCode retval = UA_STATUSCODE_GOOD;
-    if((v->storage.data.dataPtr = UA_new(&UA_TYPES.types[typeIndex])))
-       retval = UA_copy(p, v->storage.data.dataPtr, &UA_TYPES.types[typeIndex]);
+    if((v->storage.data.dataPtr = UA_new(&UA_TYPES[typeIndex])))
+       retval = UA_copy(p, v->storage.data.dataPtr, &UA_TYPES[typeIndex]);
     else
         retval = UA_STATUSCODE_BADOUTOFMEMORY;
     if(retval) {
@@ -692,10 +693,12 @@ UA_StatusCode UA_Variant_copySetValue(UA_Variant *v, const void *p, UA_UInt16 ty
 
 UA_StatusCode UA_Variant_copySetArray(UA_Variant *v, const void *array, UA_Int32 noElements, UA_UInt16 typeIndex) {
     UA_Variant_init(v);
-    v->typeIndex = typeIndex;
-    v->typeTable = &UA_TYPES;
+    v->dataType = &UA_TYPES[typeIndex];
+    v->dataTypeId = (UA_NodeId){.namespaceIndex = 0,
+                                .identifierType = UA_NODEIDTYPE_NUMERIC,
+                                .identifier.numeric = UA_TYPES_IDS[typeIndex]};
     v->storage.data.arrayLength = noElements;
-    UA_StatusCode retval = UA_Array_copy(array, noElements, &v->storage.data.dataPtr, &UA_TYPES.types[typeIndex]);
+    UA_StatusCode retval = UA_Array_copy(array, noElements, &v->storage.data.dataPtr, &UA_TYPES[typeIndex]);
     if(retval) {
         UA_Variant_deleteMembers(v);
         UA_Variant_init(v);
@@ -837,9 +840,9 @@ void UA_init(void *p, const UA_DataType *dataType) {
             UA_String_init((UA_String*)ptr);
             break;
         default:
-            UA_init(ptr, &UA_TYPES.types[member->memberTypeIndex]);
+            UA_init(ptr, &UA_TYPES[member->memberTypeIndex]);
         }
-        ptr += UA_TYPES.types[member->memberTypeIndex].memSize;
+        ptr += UA_TYPES[member->memberTypeIndex].memSize;
     }
 }
 
@@ -860,7 +863,7 @@ UA_StatusCode UA_copy(const void *src, void *dst, const UA_DataType *dataType) {
         const UA_DataTypeMember *member = &dataType->members[i];
         const UA_DataType *memberType;
         if(member->namespaceZero)
-            memberType = &UA_TYPES.types[member->memberTypeIndex];
+            memberType = &UA_TYPES[member->memberTypeIndex];
         else
             memberType = dataType - dataType->typeIndex + member->memberTypeIndex;
 
@@ -903,7 +906,7 @@ void UA_deleteMembers(void *p, const UA_DataType *dataType) {
         const UA_DataTypeMember *member = &dataType->members[i];
         const UA_DataType *memberType;
         if(member->namespaceZero)
-            memberType = &UA_TYPES.types[member->memberTypeIndex];
+            memberType = &UA_TYPES[member->memberTypeIndex];
         else
             memberType = dataType - dataType->typeIndex + member->memberTypeIndex;
 

+ 19 - 25
src/ua_types_encoding_binary.c

@@ -754,8 +754,6 @@ UA_UInt32 UA_Variant_calcSizeBinary(UA_Variant const *p) {
             return 0;
     }
 
-    const UA_DataType *dataType = &p->typeTable->types[p->typeIndex];
-        
     arrayLength = data->arrayLength;
     if(data->dataPtr == UA_NULL)
         arrayLength = -1;
@@ -764,14 +762,14 @@ UA_UInt32 UA_Variant_calcSizeBinary(UA_Variant const *p) {
     if(arrayLength < 1) {
         length += 4; // length
     } else {
-        length += UA_Array_calcSizeBinary(data->dataPtr, arrayLength, dataType);
+        length += UA_Array_calcSizeBinary(data->dataPtr, arrayLength, p->dataType);
         // if the type is not builtin, we encode it as an extensionobject
-        if(p->typeTable != &UA_TYPES || p->typeIndex > 24)
+        if(!p->dataType->namespaceZero || p->dataType->typeIndex > 24)
             length += 9 * arrayLength;  // overhead for extensionobjects: 4 byte nodeid + 1 byte encoding + 4 byte bytestring length
     }
 
     if(arrayLength != 1 && data->arrayDimensions != UA_NULL)
-        length += UA_Array_calcSizeBinary(data->arrayDimensions, data->arrayDimensionsLength, &UA_TYPES.types[UA_INT32]);
+        length += UA_Array_calcSizeBinary(data->arrayDimensions, data->arrayDimensionsLength, &UA_TYPES[UA_INT32]);
     
     if(p->storageType == UA_VARIANT_DATASOURCE)
         p->storage.datasource.release(p->storage.datasource.handle, data);
@@ -791,8 +789,7 @@ UA_StatusCode UA_Variant_encodeBinary(UA_Variant const *src, UA_ByteString *dst,
     UA_Byte encodingByte = 0;
     UA_Boolean isArray = data->arrayLength != 1;  // a single element is not an array
     UA_Boolean hasDimensions = isArray && data->arrayDimensions != UA_NULL;
-    const UA_DataType *dataType = &src->typeTable->types[src->typeIndex];
-    UA_Boolean isBuiltin = (dataType->namespaceZero && src->typeIndex <= 24);
+    UA_Boolean isBuiltin = (src->dataType->namespaceZero && src->dataType->typeIndex <= 24);
 
     if(isArray) {
         encodingByte |= UA_VARIANT_ENCODINGMASKTYPE_ARRAY;
@@ -801,33 +798,30 @@ UA_StatusCode UA_Variant_encodeBinary(UA_Variant const *src, UA_ByteString *dst,
     }
 
     if(isBuiltin)
-        encodingByte |= UA_VARIANT_ENCODINGMASKTYPE_TYPEID_MASK & (UA_Byte)UA_TYPES.numericNodeIds[src->typeIndex];
+        encodingByte |= UA_VARIANT_ENCODINGMASKTYPE_TYPEID_MASK & (UA_Byte)UA_TYPES_IDS[src->dataType->typeIndex];
     else
         encodingByte |= UA_VARIANT_ENCODINGMASKTYPE_TYPEID_MASK & (UA_Byte)22;  // ExtensionObject
 
     UA_StatusCode retval = UA_Byte_encodeBinary(&encodingByte, dst, offset);
 
     if(isArray)
-        retval |= UA_Array_encodeBinary(data->dataPtr, data->arrayLength, dataType, dst, offset);
+        retval |= UA_Array_encodeBinary(data->dataPtr, data->arrayLength, src->dataType, dst, offset);
     else if(!data->dataPtr)
         retval = UA_STATUSCODE_BADENCODINGERROR; // an array can be empty. a single element must be present.
     else {
         if(!isBuiltin) {
             // print the extensionobject header
-            UA_NodeId typeNodeId = (UA_NodeId){.namespaceIndex = src->typeTable->namespaceIndex,
-                                               .identifierType = UA_NODEIDTYPE_NUMERIC,
-                                               .identifier.numeric = src->typeTable->numericNodeIds[dataType->typeIndex]};
-            UA_NodeId_encodeBinary(&typeNodeId, dst, offset);
+            UA_NodeId_encodeBinary(&src->dataTypeId, dst, offset);
             UA_Byte eoEncoding = UA_EXTENSIONOBJECT_ENCODINGMASK_BODYISBYTESTRING;
             UA_Byte_encodeBinary(&eoEncoding, dst, offset);
-            UA_Int32 eoEncodingLength = UA_calcSizeBinary(data->dataPtr, dataType);
+            UA_Int32 eoEncodingLength = UA_calcSizeBinary(data->dataPtr, src->dataType);
             UA_Int32_encodeBinary(&eoEncodingLength, dst, offset);
         }
-        retval |= UA_encodeBinary(data->dataPtr, dataType, dst, offset);
+        retval |= UA_encodeBinary(data->dataPtr, src->dataType, dst, offset);
     }
 
     if(hasDimensions)
-        retval |= UA_Array_encodeBinary(data->arrayDimensions, data->arrayDimensionsLength, &UA_TYPES.types[UA_INT32], dst, offset);
+        retval |= UA_Array_encodeBinary(data->arrayDimensions, data->arrayDimensionsLength, &UA_TYPES[UA_INT32], dst, offset);
 
     if(src->storageType == UA_VARIANT_DATASOURCE)
         src->storage.datasource.release(src->storage.datasource.handle, data);
@@ -850,11 +844,11 @@ UA_StatusCode UA_Variant_decodeBinary(UA_ByteString const *src, UA_UInt32 *offse
                          .identifier.numeric = encodingByte & UA_VARIANT_ENCODINGMASKTYPE_TYPEID_MASK };
 
     UA_UInt16 typeIndex;
-    for(typeIndex = 0; typeIndex < UA_TYPES.tableSize; typeIndex++) {
-        if(UA_TYPES.numericNodeIds[typeIndex] == typeid.identifier.numeric)
+    for(typeIndex = 0; typeIndex < UA_TYPES_COUNT; typeIndex++) {
+        if(UA_TYPES_IDS[typeIndex] == typeid.identifier.numeric)
             break;
     }
-    const UA_DataType *dataType = &UA_TYPES.types[typeIndex];
+    const UA_DataType *dataType = &UA_TYPES[typeIndex];
 
     if(!isArray) {
         if(!(data->dataPtr = UA_malloc(dataType->memSize)))
@@ -876,13 +870,13 @@ UA_StatusCode UA_Variant_decodeBinary(UA_ByteString const *src, UA_UInt32 *offse
     if(hasDimensions && retval == UA_STATUSCODE_GOOD) {
         retval |= UA_Int32_decodeBinary(src, offset, &data->arrayDimensionsLength);
         if(retval == UA_STATUSCODE_GOOD)
-            retval |= UA_Array_decodeBinary(src, offset, data->arrayDimensionsLength, &data->dataPtr, &UA_TYPES.types[UA_INT32]);
+            retval |= UA_Array_decodeBinary(src, offset, data->arrayDimensionsLength, &data->dataPtr, &UA_TYPES[UA_INT32]);
         if(retval)
             data->arrayLength = -1; // for deleteMembers
     }
 
-    dst->typeTable = &UA_TYPES;
-    dst->typeIndex = typeIndex;
+    dst->dataType = dataType;
+    dst->dataTypeId = typeid;
 
     if(retval)
         UA_Variant_deleteMembers(dst);
@@ -978,7 +972,7 @@ UA_UInt32 UA_calcSizeBinary(const void *p, const UA_DataType *dataType) {
         const UA_DataTypeMember *member = &dataType->members[i];
         const UA_DataType *memberType;
         if(member->namespaceZero)
-            memberType = &UA_TYPES.types[member->memberTypeIndex];
+            memberType = &UA_TYPES[member->memberTypeIndex];
         else
             memberType = dataType - dataType->typeIndex + member->memberTypeIndex;
 
@@ -1066,7 +1060,7 @@ UA_StatusCode UA_encodeBinary(const void *src, const UA_DataType *dataType, UA_B
         const UA_DataTypeMember *member = &dataType->members[i];
         const UA_DataType *memberType;
         if(member->namespaceZero)
-            memberType = &UA_TYPES.types[member->memberTypeIndex];
+            memberType = &UA_TYPES[member->memberTypeIndex];
         else
             memberType = dataType - dataType->typeIndex + member->memberTypeIndex;
 
@@ -1162,7 +1156,7 @@ UA_StatusCode UA_decodeBinary(const UA_ByteString *src, UA_UInt32 *offset, void
         const UA_DataTypeMember *member = &dataType->members[i];
         const UA_DataType *memberType;
         if(member->namespaceZero)
-            memberType = &UA_TYPES.types[member->memberTypeIndex];
+            memberType = &UA_TYPES[member->memberTypeIndex];
         else
             memberType = dataType - dataType->typeIndex + member->memberTypeIndex;
 

+ 8 - 8
tools/generate_datatypes.py

@@ -247,7 +247,7 @@ class StructType(object):
 #define %s_calcSizeBinary(p) UA_calcSizeBinary(p, %s)
 #define %s_encodeBinary(src, dst, offset) UA_encodeBinary(src, %s, dst, offset)
 #define %s_decodeBinary(src, offset, dst) UA_decodeBinary(src, offset, dst, %s)''' % \
-    tuple(itertools.chain(*itertools.repeat([self.name, "&"+typeTableName+".types["+self.name.upper()+"]"], 8)))
+    tuple(itertools.chain(*itertools.repeat([self.name, "&"+typeTableName+"["+self.name.upper()+"]"], 8)))
 
 def parseTypeDefinitions(xmlDescription, existing_types = OrderedDict()):
     '''Returns an ordered dict that maps names to types. The order is such that
@@ -415,7 +415,8 @@ extern "C" {
 */
 ''')
 if outname != "ua_types":
-    printh("extern const UA_DataTypeTable " + outname.upper() + ";\n")
+    printh("extern const UA_DataType *" + outname.upper() + ";\n")
+    printh("extern const UA_UInt32 *" + outname.upper() + "_IDS;\n")
 
 i = 0
 for t in types.itervalues():
@@ -429,6 +430,7 @@ for t in types.itervalues():
         printh(t.functions_c(outname.upper()))
     i += 1
 
+printh("#define " + outname.upper() + "_COUNT %s\n" % (str(len(types))))
 printh('''
 /// @} /* end of group */\n
 #ifdef __cplusplus
@@ -447,19 +449,17 @@ printc('''/**
 #include "stddef.h"
 #include "ua_types.h"
 #include "''' + outname + '''_generated.h"\n
-const UA_DataTypeTable ''' + outname.upper() + ''' = (UA_DataTypeTable){
-.types = (UA_DataType[]){''')
+const UA_DataType *''' + outname.upper() + ''' = (UA_DataType[]){''')
 for t in types.itervalues():
     printc("")
     printc("/* " + t.name + " */")
     printc(t.typelayout_c(args.namespace_id == 0) + ",")
-printc("},\n")
+printc("};\n")
 if args.typedescriptions:
-    printc(".numericNodeIds = (UA_UInt32[]){")
+    printc('const UA_UInt32 *' + outname.upper() + '_ID = (UA_UInt32[]){')
     for t in types.itervalues():
         print(str(typedescriptions[t.name].nodeid) + ", ", end='', file=fc)
-    printc("},\n")
-printc(".namespaceIndex = %s, .tableSize = %s};" % (str(args.namespace_id), str(len(types))))
+    printc("};")
 
 fh.close()
 fc.close()