Browse Source

move datatype nodeid to the typedescription -> single source of truth

Julius Pfrommer 10 years ago
parent
commit
c877fcaa9d

+ 1 - 1
include/ua_types.h

@@ -219,7 +219,6 @@ typedef struct UA_DataType UA_DataType;
     the data they store (exception: use a data source).*/
 typedef struct {
     const UA_DataType *type;
-    UA_NodeId typeId;
     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
@@ -491,6 +490,7 @@ typedef struct {
 } UA_DataTypeMember;
     
 struct UA_DataType {
+    UA_NodeId typeId; ///< The nodeid of the type
     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.

+ 0 - 2
src/server/ua_server.c

@@ -600,7 +600,6 @@ UA_Server * UA_Server_new(void) {
     namespaceArray->value.storage.data.dataPtr = UA_Array_new(&UA_TYPES[UA_TYPES_STRING], 2);
     namespaceArray->value.storage.data.arrayLength = 2;
     namespaceArray->value.type = &UA_TYPES[UA_TYPES_STRING];
-    namespaceArray->value.typeId.identifier.numeric = UA_TYPES_IDS[UA_TYPES_STRING];
     // Fixme: Insert the external namespaces
     UA_String_copycstring("http://opcfoundation.org/UA/",
                           &((UA_String *)(namespaceArray->value.storage.data.dataPtr))[0]);
@@ -639,7 +638,6 @@ UA_Server * UA_Server_new(void) {
     COPYNAMES(state, "State");
     state->nodeId.identifier.numeric = UA_NS0ID_SERVER_SERVERSTATUS_STATE;
     state->value.type = &UA_TYPES[UA_TYPES_SERVERSTATE];
-    state->value.typeId.identifier.numeric = UA_TYPES_IDS[UA_TYPES_SERVERSTATE];
     state->value.storage.data.arrayLength = 1;
     state->value.storage.data.dataPtr = stateEnum; // points into the other object.
     state->value.storageType = UA_VARIANT_DATA;

+ 2 - 2
src/server/ua_services_attribute.c

@@ -114,7 +114,7 @@ static void readValue(UA_Server *server, const UA_ReadValueId *id, UA_DataValue
     case UA_ATTRIBUTEID_DATATYPE:
         CHECK_NODECLASS(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE);
         v->hasVariant = UA_TRUE;
-        retval |= UA_Variant_copySetValue(&v->value, &((const UA_VariableTypeNode *)node)->value.typeId,
+        retval |= UA_Variant_copySetValue(&v->value, &((const UA_VariableTypeNode *)node)->value.type->typeId,
                                           UA_TYPES_NODEID);
         break;
 
@@ -367,7 +367,7 @@ static UA_StatusCode writeValue(UA_Server *server, UA_WriteValue *wvalue) {
             const UA_VariableNode *vn = (const UA_VariableNode*)node;
             // has the wvalue a variant of the right type?
             // array sizes are not checked yet..
-            if(!wvalue->value.hasVariant || !UA_NodeId_equal(&vn->value.typeId, &wvalue->value.value.typeId)) {
+            if(!wvalue->value.hasVariant || !UA_NodeId_equal(&vn->value.type->typeId,  &wvalue->value.value.type->typeId)) {
                 retval = UA_STATUSCODE_BADWRITENOTSUPPORTED;
                 break;
             }

+ 2 - 2
src/server/ua_services_nodemanagement.c

@@ -22,7 +22,7 @@
 
 static UA_StatusCode parseVariableNode(UA_ExtensionObject *attributes, UA_Node **new_node) {
     if(attributes->typeId.identifier.numeric !=
-       UA_TYPES_IDS[UA_TYPES_VARIABLEATTRIBUTES] + UA_ENCODINGOFFSET_BINARY)
+       UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES].typeId.identifier.numeric + UA_ENCODINGOFFSET_BINARY)
         return UA_STATUSCODE_BADNODEATTRIBUTESINVALID;
 
     UA_VariableAttributes attr;
@@ -83,7 +83,7 @@ static UA_StatusCode parseVariableNode(UA_ExtensionObject *attributes, UA_Node *
 
 static UA_StatusCode parseObjectNode(UA_ExtensionObject *attributes, UA_Node **new_node) {
     if(attributes->typeId.identifier.numeric !=
-       UA_TYPES_IDS[UA_TYPES_OBJECTATTRIBUTES] + UA_ENCODINGOFFSET_BINARY)  // VariableAttributes_Encoding_DefaultBinary
+       UA_TYPES[UA_TYPES_OBJECTATTRIBUTES].typeId.identifier.numeric + UA_ENCODINGOFFSET_BINARY)  // VariableAttributes_Encoding_DefaultBinary
         return UA_STATUSCODE_BADNODEATTRIBUTESINVALID;
     UA_ObjectAttributes attr;
     size_t pos = 0;

+ 1 - 7
src/ua_types.c

@@ -576,13 +576,11 @@ void UA_Variant_init(UA_Variant *p) {
     p->storage.data.dataPtr = UA_NULL;
     p->storage.data.arrayDimensions = UA_NULL;
     p->storage.data.arrayDimensionsSize = -1;
-    UA_NodeId_init(&p->typeId);
     p->type = UA_NULL;
 }
 
 UA_TYPE_DELETE_DEFAULT(UA_Variant)
 void UA_Variant_deleteMembers(UA_Variant *p) {
-    UA_NodeId_deleteMembers(&p->typeId);
     if(p->storageType == UA_VARIANT_DATA) {
         if(p->storage.data.dataPtr) {
             UA_Array_delete(p->storage.data.dataPtr, p->type, p->storage.data.arrayLength);
@@ -598,9 +596,6 @@ void UA_Variant_deleteMembers(UA_Variant *p) {
 
 UA_StatusCode UA_Variant_copy(UA_Variant const *src, UA_Variant *dst) {
     UA_Variant_init(dst);
-    UA_StatusCode retval = UA_NodeId_copy(&src->typeId, &dst->typeId);
-    if(retval != UA_STATUSCODE_GOOD)
-        return retval;
     dst->type = src->type;
     if(src->storageType == UA_VARIANT_DATASOURCE) {
         dst->storageType = UA_VARIANT_DATASOURCE;
@@ -611,7 +606,7 @@ UA_StatusCode UA_Variant_copy(UA_Variant const *src, UA_Variant *dst) {
     UA_VariantData *dstdata = &dst->storage.data;
     const UA_VariantData *srcdata = &src->storage.data;
     dst->storageType = UA_VARIANT_DATA;
-    retval |= UA_Array_copy(srcdata->dataPtr, &dstdata->dataPtr, src->type, srcdata->arrayLength);
+    UA_StatusCode retval = UA_Array_copy(srcdata->dataPtr, &dstdata->dataPtr, src->type, srcdata->arrayLength);
     if(retval != UA_STATUSCODE_GOOD) {
         UA_Variant_deleteMembers(dst);
         UA_Variant_init(dst);
@@ -655,7 +650,6 @@ UA_StatusCode UA_Variant_setArray(UA_Variant *v, void *array, UA_Int32 noElement
         return UA_STATUSCODE_BADINTERNALERROR;
 
     v->type = &UA_TYPES[typeIndex];
-    v->typeId = UA_NODEID_STATIC(0, UA_TYPES_IDS[typeIndex]);
     v->storage.data.arrayLength = noElements;
     v->storage.data.dataPtr = array;
     return UA_STATUSCODE_GOOD;

+ 6 - 7
src/ua_types_encoding_binary.c

@@ -743,7 +743,7 @@ UA_StatusCode UA_Variant_encodeBinary(UA_Variant const *src, UA_ByteString *dst,
     }
 
     if(isBuiltin)
-        encodingByte |= UA_VARIANT_ENCODINGMASKTYPE_TYPEID_MASK & (UA_Byte)UA_TYPES_IDS[src->type->typeIndex];
+        encodingByte |= UA_VARIANT_ENCODINGMASKTYPE_TYPEID_MASK & (UA_Byte)src->type->typeId.identifier.numeric;
     else
         encodingByte |= UA_VARIANT_ENCODINGMASKTYPE_TYPEID_MASK & (UA_Byte)22;  // ExtensionObject
 
@@ -756,13 +756,13 @@ UA_StatusCode UA_Variant_encodeBinary(UA_Variant const *src, UA_ByteString *dst,
     else {
         if(!isBuiltin) {
             // print the extensionobject header
-        	if(src->typeId.identifier.numeric==862){ //fixme: CAUTION, THIS IS  A DIRTY WORKAROUND FOR #182, needs to be fixed
+        	if(src->type->typeId.identifier.numeric==862){ //fixme: CAUTION, THIS IS  A DIRTY WORKAROUND FOR #182, needs to be fixed
         		UA_NodeId copy;
-        		UA_NodeId_copy(&src->typeId, &copy);
+        		UA_NodeId_copy(&src->type->typeId, &copy);
         		copy.identifier.numeric=copy.identifier.numeric+2;
         		UA_NodeId_encodeBinary(&copy, dst, offset);
-        	}else{
-        		UA_NodeId_encodeBinary(&src->typeId, dst, offset);
+        	} else {
+        		UA_NodeId_encodeBinary(&src->type->typeId, dst, offset);
         	}
             UA_Byte eoEncoding = UA_EXTENSIONOBJECT_ENCODINGMASK_BODYISBYTESTRING;
             UA_Byte_encodeBinary(&eoEncoding, dst, offset);
@@ -798,7 +798,7 @@ UA_StatusCode UA_Variant_decodeBinary(UA_ByteString const *src, size_t *offset,
 
     UA_UInt16 typeIndex;
     for(typeIndex = 0; typeIndex < UA_TYPES_COUNT; typeIndex++) {
-        if(UA_TYPES_IDS[typeIndex] == typeid.identifier.numeric)
+        if(UA_TYPES[typeIndex].typeId.identifier.numeric == typeid.identifier.numeric)
             break;
     }
 
@@ -834,7 +834,6 @@ UA_StatusCode UA_Variant_decodeBinary(UA_ByteString const *src, size_t *offset,
     }
 
     dst->type = dataType;
-    dst->typeId = typeid;
 
     if(retval)
         UA_Variant_deleteMembers(dst);

+ 38 - 15
tools/generate_datatypes.py

@@ -77,8 +77,13 @@ class BuiltinType(object):
     def typedef_c(self):
         pass
 
-    def typelayout_c(self, namespace_0, outname):
-        return "{.memSize = sizeof(" + self.name + "), " + \
+    def typelayout_c(self, namespace_0, description, outname):
+        if description == None:
+            typeid = "{.namespaceIndex = 0, .identifierType = UA_NODEIDTYPE_NUMERIC, .identifier.numeric = 0}, "
+        else:
+            typeid = "{.namespaceIndex = %s, .identifierType = UA_NODEIDTYPE_NUMERIC, .identifier.numeric = %s}, " % (description.namespaceid, description.nodeid)
+        return "{.typeId = " + typeid + \
+            ".memSize = sizeof(" + self.name + "), " + \
             ".namespaceZero = UA_TRUE, " + \
             ".fixedSize = " + ("UA_TRUE" if self.fixed_size() else "UA_FALSE") + \
             ", .zeroCopyable = " + ("UA_TRUE" if self.zero_copy() else "UA_FALSE") + \
@@ -109,8 +114,13 @@ class EnumerationType(object):
             ",\n    ".join(map(lambda (key,value) : key.upper() + " = " + value,self.elements.iteritems())) + \
             "\n} " + self.name + ";"
 
-    def typelayout_c(self, namespace_0, outname):
-        return "{.memSize = sizeof(" + self.name + "), " +\
+    def typelayout_c(self, namespace_0, description, outname):
+        if description == None:
+            typeid = "{.namespaceIndex = 0, .identifierType = UA_NODEIDTYPE_NUMERIC, .identifier.numeric = 0}, "
+        else:
+            typeid = "{.namespaceIndex = %s, .identifierType = UA_NODEIDTYPE_NUMERIC, .identifier.numeric = %s}, " % (description.namespaceid, description.nodeid)
+        return "{.typeId = " + typeid + \
+            ".memSize = sizeof(" + self.name + "), " +\
             ".namespaceZero = " + ("UA_TRUE" if namespace_0 else "UA_FALSE") + \
             ", .fixedSize = UA_TRUE, .zeroCopyable = UA_TRUE, " + \
             ".membersSize = 1,\n\t.members = {{.memberTypeIndex = UA_TYPES_INT32," + \
@@ -140,8 +150,13 @@ class OpaqueType(object):
     def typedef_c(self):
         return "typedef UA_ByteString " + self.name + ";"
 
-    def typelayout_c(self, namespace_0, outname):
-        return "{.memSize = sizeof(" + self.name + "), .fixedSize = UA_FALSE, .zeroCopyable = UA_FALSE, " + \
+    def typelayout_c(self, namespace_0, description, outname):
+        if description == None:
+            typeid = "{.namespaceIndex = 0, .identifierType = UA_NODEIDTYPE_NUMERIC, .identifier.numeric = 0}, "
+        else:
+            typeid = "{.namespaceIndex = %s, .identifierType = UA_NODEIDTYPE_NUMERIC, .identifier.numeric = %s}, " % (description.namespaceid, description.nodeid)
+        return "{.typeId = " + typeid + \
+            ".memSize = sizeof(" + self.name + "), .fixedSize = UA_FALSE, .zeroCopyable = UA_FALSE, " + \
             ".namespaceZero = " + ("UA_TRUE" if namespace_0 else "UA_FALSE") + \
             ", .membersSize = 1,\n\t.members = {{.memberTypeIndex = UA_TYPES_BYTESTRING," + \
             ".namespaceZero = UA_TRUE, .padding = 0, .isArray = UA_FALSE }}, .typeIndex = %s }" % (outname.upper() + "_" + self.name[3:].upper())
@@ -201,8 +216,13 @@ class StructType(object):
                 returnstr += "    " + member.memberType.name + " " +name + ";\n"
         return returnstr + "} " + self.name + ";"
 
-    def typelayout_c(self, namespace_0, outname):
-        layout = "{.memSize = sizeof(" + self.name + "), "+ \
+    def typelayout_c(self, namespace_0, description, outname):
+        if description == None:
+            typeid = "{.namespaceIndex = 0, .identifierType = UA_NODEIDTYPE_NUMERIC, .identifier.numeric = 0}, "
+        else:
+            typeid = "{.namespaceIndex = %s, .identifierType = UA_NODEIDTYPE_NUMERIC, .identifier.numeric = %s}, " % (description.namespaceid, description.nodeid)
+        layout = "{.typeId = "+ typeid + \
+                 ".memSize = sizeof(" + self.name + "), "+ \
                  ".namespaceZero = " + ("UA_TRUE" if namespace_0 else "UA_FALSE") + \
                  ", .fixedSize = " + ("UA_TRUE" if self.fixed_size() else "UA_FALSE") + \
                  ", .zeroCopyable = " + ("sizeof(" + self.name + ") == " + str(self.mem_size()) if self.zero_copy() \
@@ -419,7 +439,6 @@ extern "C" {
 ''')
 printh("#define " + outname.upper() + "_COUNT %s\n" % (str(len(types))))
 printh("extern UA_EXPORT const UA_DataType *" + outname.upper() + ";\n")
-printh("extern UA_EXPORT const UA_UInt32 *" + outname.upper() + "_IDS;\n")
 
 i = 0
 for t in types.itervalues():
@@ -455,13 +474,17 @@ const UA_DataType *''' + outname.upper() + ''' = (UA_DataType[]){''')
 for t in types.itervalues():
     printc("")
     printc("/* " + t.name + " */")
-    printc(t.typelayout_c(args.namespace_id == 0, outname) + ",")
+    if args.typedescriptions:
+        td = typedescriptions[t.name]
+    else:
+        td = None
+    printc(t.typelayout_c(args.namespace_id == 0, td, outname) + ",")
 printc("};\n")
-if args.typedescriptions:
-    printc('const UA_UInt32 *' + outname.upper() + '_IDS = (UA_UInt32[]){')
-    for t in types.itervalues():
-        print(str(typedescriptions[t.name].nodeid) + ", ", end='', file=fc)
-    printc("};")
+# if args.typedescriptions:
+#     printc('const UA_UInt32 *' + outname.upper() + '_IDS = (UA_UInt32[]){')
+#     for t in types.itervalues():
+#         print(str(typedescriptions[t.name].nodeid) + ", ", end='', file=fc)
+#     printc("};")
 
 fh.close()
 fc.close()