Explorar el Código

restore variants copySetValue and borrowSetValue

If a value is borrowed, it is not freed when the variant is deleted.
Julius Pfrommer hace 10 años
padre
commit
adc25007eb
Se han modificado 4 ficheros con 127 adiciones y 118 borrados
  1. 21 22
      src/ua_services_attribute.c
  2. 32 30
      src/ua_types.c
  3. 4 5
      src/ua_types.h
  4. 70 61
      tools/generate_namespace.py

+ 21 - 22
src/ua_services_attribute.c

@@ -65,19 +65,19 @@ static UA_DataValue service_read_node(Application * app, const UA_ReadValueId *
 	switch (id->attributeId) {
 	switch (id->attributeId) {
 	case UA_ATTRIBUTEID_NODEID:
 	case UA_ATTRIBUTEID_NODEID:
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, UA_NODEID, &node->nodeId);
+		retval |= UA_Variant_copySetValue(&v.value, &UA_.types[UA_NODEID], &node->nodeId);
 		break;
 		break;
 	case UA_ATTRIBUTEID_NODECLASS:
 	case UA_ATTRIBUTEID_NODECLASS:
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, UA_UINT32, &node->nodeClass);
+		retval |= UA_Variant_copySetValue(&v.value, &UA_.types[UA_UINT32], &node->nodeClass);
 		break;
 		break;
 	case UA_ATTRIBUTEID_BROWSENAME:
 	case UA_ATTRIBUTEID_BROWSENAME:
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, UA_QUALIFIEDNAME, &node->browseName);
+		retval |= UA_Variant_copySetValue(&v.value, &UA_.types[UA_QUALIFIEDNAME], &node->browseName);
 		break;
 		break;
 	case UA_ATTRIBUTEID_DISPLAYNAME:
 	case UA_ATTRIBUTEID_DISPLAYNAME:
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, UA_LOCALIZEDTEXT, &node->displayName);
+		retval |= UA_Variant_copySetValue(&v.value, &UA_.types[UA_LOCALIZEDTEXT], &node->displayName);
 		break;
 		break;
 	case UA_ATTRIBUTEID_DESCRIPTION:
 	case UA_ATTRIBUTEID_DESCRIPTION:
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
@@ -85,88 +85,87 @@ static UA_DataValue service_read_node(Application * app, const UA_ReadValueId *
 		break;
 		break;
 	case UA_ATTRIBUTEID_WRITEMASK:
 	case UA_ATTRIBUTEID_WRITEMASK:
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, UA_UINT32, &node->writeMask);
+		retval |= UA_Variant_copySetValue(&v.value, &UA_.types[UA_UINT32], &node->writeMask);
 		break;
 		break;
 	case UA_ATTRIBUTEID_USERWRITEMASK:
 	case UA_ATTRIBUTEID_USERWRITEMASK:
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, UA_UINT32, &node->userWriteMask);
+		retval |= UA_Variant_copySetValue(&v.value, &UA_.types[UA_UINT32], &node->userWriteMask);
 		break;
 		break;
 	case UA_ATTRIBUTEID_ISABSTRACT:
 	case UA_ATTRIBUTEID_ISABSTRACT:
 		CHECK_NODECLASS(UA_NODECLASS_REFERENCETYPE);
 		CHECK_NODECLASS(UA_NODECLASS_REFERENCETYPE);
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, UA_BOOLEAN, &((UA_ReferenceTypeNode *) node)->isAbstract);
+		retval |= UA_Variant_copySetValue(&v.value, &UA_.types[UA_BOOLEAN], &((UA_ReferenceTypeNode *) node)->isAbstract);
 		break;
 		break;
 	case UA_ATTRIBUTEID_SYMMETRIC:
 	case UA_ATTRIBUTEID_SYMMETRIC:
 		CHECK_NODECLASS(UA_NODECLASS_REFERENCETYPE);
 		CHECK_NODECLASS(UA_NODECLASS_REFERENCETYPE);
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, UA_BOOLEAN, &((UA_ReferenceTypeNode *) node)->symmetric);
+		retval |= UA_Variant_copySetValue(&v.value, &UA_.types[UA_BOOLEAN], &((UA_ReferenceTypeNode *) node)->symmetric);
 		break;
 		break;
 	case UA_ATTRIBUTEID_INVERSENAME:
 	case UA_ATTRIBUTEID_INVERSENAME:
 		CHECK_NODECLASS(UA_NODECLASS_REFERENCETYPE);
 		CHECK_NODECLASS(UA_NODECLASS_REFERENCETYPE);
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, UA_LOCALIZEDTEXT, &((UA_ReferenceTypeNode *) node)->inverseName);
+		retval |= UA_Variant_copySetValue(&v.value, &UA_.types[UA_LOCALIZEDTEXT], &((UA_ReferenceTypeNode *) node)->inverseName);
 		break;
 		break;
 	case UA_ATTRIBUTEID_CONTAINSNOLOOPS:
 	case UA_ATTRIBUTEID_CONTAINSNOLOOPS:
 		CHECK_NODECLASS(UA_NODECLASS_VIEW);
 		CHECK_NODECLASS(UA_NODECLASS_VIEW);
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, UA_BOOLEAN, &((UA_ViewNode *) node)->containsNoLoops);
+		retval |= UA_Variant_copySetValue(&v.value, &UA_.types[UA_BOOLEAN], &((UA_ViewNode *) node)->containsNoLoops);
 		break;
 		break;
 	case UA_ATTRIBUTEID_EVENTNOTIFIER:
 	case UA_ATTRIBUTEID_EVENTNOTIFIER:
 		CHECK_NODECLASS(UA_NODECLASS_VIEW);
 		CHECK_NODECLASS(UA_NODECLASS_VIEW);
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, UA_BYTE, &((UA_ViewNode *) node)->eventNotifier);
+		retval |= UA_Variant_copySetValue(&v.value, &UA_.types[UA_BYTE], &((UA_ViewNode *) node)->eventNotifier);
 		break;
 		break;
 	case UA_ATTRIBUTEID_VALUE:
 	case UA_ATTRIBUTEID_VALUE:
 		CHECK_NODECLASS(UA_NODECLASS_VARIABLE);
 		CHECK_NODECLASS(UA_NODECLASS_VARIABLE);
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
 		// TODO: Ensure that the borrowed value is not freed prematurely (multithreading)
 		// TODO: Ensure that the borrowed value is not freed prematurely (multithreading)
-		retval |= UA_Variant_borrowSetValue(&v.value, UA_VARIANT, &((UA_VariableNode *) node)->value);
+		retval |= UA_Variant_borrowSetValue(&v.value, &UA_.types[UA_VARIANT], &((UA_VariableNode *) node)->value);
 		break;
 		break;
 	case UA_ATTRIBUTEID_DATATYPE:
 	case UA_ATTRIBUTEID_DATATYPE:
 		CHECK_NODECLASS(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE);
 		CHECK_NODECLASS(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE);
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, UA_NODEID, &((UA_VariableTypeNode *) node)->dataType);
+		retval |= UA_Variant_copySetValue(&v.value, &UA_.types[UA_NODEID], &((UA_VariableTypeNode *) node)->dataType);
 		break;
 		break;
 	case UA_ATTRIBUTEID_VALUERANK:
 	case UA_ATTRIBUTEID_VALUERANK:
 		CHECK_NODECLASS(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE);
 		CHECK_NODECLASS(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE);
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, UA_INT32, &((UA_VariableTypeNode *) node)->valueRank);
+		retval |= UA_Variant_copySetValue(&v.value, &UA_.types[UA_INT32], &((UA_VariableTypeNode *) node)->valueRank);
 		break;
 		break;
 	case UA_ATTRIBUTEID_ARRAYDIMENSIONS:
 	case UA_ATTRIBUTEID_ARRAYDIMENSIONS:
 		CHECK_NODECLASS(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE);
 		CHECK_NODECLASS(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE);
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		UA_Variant_copySetArray(&v.value, UA_UINT32, ((UA_VariableTypeNode *) node)->arrayDimensionsSize, sizeof(UA_UInt32),
-								&((UA_VariableTypeNode *) node)->arrayDimensions);
+		UA_Variant_copySetArray(&v.value, &UA_.types[UA_UINT32], ((UA_VariableTypeNode *) node)->arrayDimensionsSize, &((UA_VariableTypeNode *) node)->arrayDimensions);
 		break;
 		break;
 	case UA_ATTRIBUTEID_ACCESSLEVEL:
 	case UA_ATTRIBUTEID_ACCESSLEVEL:
 		CHECK_NODECLASS(UA_NODECLASS_VARIABLE);
 		CHECK_NODECLASS(UA_NODECLASS_VARIABLE);
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, UA_BYTE, &((UA_VariableNode *) node)->accessLevel);
+		retval |= UA_Variant_copySetValue(&v.value, &UA_.types[UA_BYTE], &((UA_VariableNode *) node)->accessLevel);
 		break;
 		break;
 	case UA_ATTRIBUTEID_USERACCESSLEVEL:
 	case UA_ATTRIBUTEID_USERACCESSLEVEL:
 		CHECK_NODECLASS(UA_NODECLASS_VARIABLE);
 		CHECK_NODECLASS(UA_NODECLASS_VARIABLE);
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, UA_BYTE, &((UA_VariableNode *) node)->userAccessLevel);
+		retval |= UA_Variant_copySetValue(&v.value, &UA_.types[UA_BYTE], &((UA_VariableNode *) node)->userAccessLevel);
 		break;
 		break;
 	case UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL:
 	case UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL:
 		CHECK_NODECLASS(UA_NODECLASS_VARIABLE);
 		CHECK_NODECLASS(UA_NODECLASS_VARIABLE);
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, UA_DOUBLE, &((UA_VariableNode *) node)->minimumSamplingInterval);
+		retval |= UA_Variant_copySetValue(&v.value, &UA_.types[UA_DOUBLE], &((UA_VariableNode *) node)->minimumSamplingInterval);
 		break;
 		break;
 	case UA_ATTRIBUTEID_HISTORIZING:
 	case UA_ATTRIBUTEID_HISTORIZING:
 		CHECK_NODECLASS(UA_NODECLASS_VARIABLE);
 		CHECK_NODECLASS(UA_NODECLASS_VARIABLE);
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, UA_BOOLEAN, &((UA_VariableNode *) node)->historizing);
+		retval |= UA_Variant_copySetValue(&v.value, &UA_.types[UA_BOOLEAN], &((UA_VariableNode *) node)->historizing);
 		break;
 		break;
 	case UA_ATTRIBUTEID_EXECUTABLE:
 	case UA_ATTRIBUTEID_EXECUTABLE:
 		CHECK_NODECLASS(UA_NODECLASS_METHOD);
 		CHECK_NODECLASS(UA_NODECLASS_METHOD);
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, UA_BOOLEAN, &((UA_MethodNode *) node)->executable);
+		retval |= UA_Variant_copySetValue(&v.value, &UA_.types[UA_BOOLEAN], &((UA_MethodNode *) node)->executable);
 		break;
 		break;
 	case UA_ATTRIBUTEID_USEREXECUTABLE:
 	case UA_ATTRIBUTEID_USEREXECUTABLE:
 		CHECK_NODECLASS(UA_NODECLASS_METHOD);
 		CHECK_NODECLASS(UA_NODECLASS_METHOD);
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, UA_BOOLEAN, &((UA_MethodNode *) node)->userExecutable);
+		retval |= UA_Variant_copySetValue(&v.value, &UA_.types[UA_BOOLEAN], &((UA_MethodNode *) node)->userExecutable);
 		break;
 		break;
 	default:
 	default:
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;

+ 32 - 30
src/ua_types.c

@@ -670,43 +670,45 @@ UA_Int32 UA_Variant_copy(UA_Variant const *src, UA_Variant *dst) {
 	return retval;
 	return retval;
 }
 }
 
 
-// FIXME! ns0type vs typeid
-UA_Int32 UA_Variant_borrowSetValue(UA_Variant *v, UA_Int32 ns0type_id, const void *value) {
-	/* v->encodingMask = type_id & UA_VARIANT_ENCODINGMASKTYPE_TYPEID_MASK; */
-	/* if(UA_VTable_isValidType(type_id) != UA_SUCCESS) return UA_INVALIDTYPE; */
-	/* v->vt = &UA_borrowed_.types[type_id]; */
-	/* v->data   = (void *)value; */
-	return UA_SUCCESS;
+UA_Int32 UA_Variant_copySetValue(UA_Variant *v, UA_VTable_Entry *vt, const void *value) {
+	if(v == UA_NULL || vt == UA_NULL || value == UA_NULL)
+		return UA_ERROR;
+	UA_Variant_init(v);
+	v->vt = vt;
+	v->arrayLength = 1; // no array but a single entry
+	UA_Int32 retval = UA_SUCCESS;
+	retval |= vt->new(&v->data);
+	if(retval == UA_SUCCESS)
+		retval |= vt->copy(value, v->data);
+	return retval;
 }
 }
 
 
-UA_Int32 UA_Variant_copySetValue(UA_Variant *v, UA_Int32 ns0type_id, const void *value) {
-	/* v->encodingMask = type_id & UA_VARIANT_ENCODINGMASKTYPE_TYPEID_MASK; */
-	/* if(UA_VTable_isValidType(type_id) != UA_SUCCESS) return UA_INVALIDTYPE; */
-	/* v->vt = &UA_.types[type_id]; */
-	return v->vt->copy(value, v->data);
+UA_Int32 UA_Variant_copySetArray(UA_Variant *v, UA_VTable_Entry *vt, UA_Int32 arrayLength, const void *array) {
+	if(v == UA_NULL || vt == UA_NULL || array == UA_NULL)
+		return UA_ERROR;
+	UA_Variant_init(v);
+	v->vt = vt;
+	v->arrayLength = arrayLength;
+	return UA_Array_copy(array, arrayLength, vt, &v->data);
 }
 }
 
 
-UA_Int32 UA_Variant_borrowSetArray(UA_Variant *v, UA_Int32 type_id, UA_Int32 arrayLength, const void *array) {
-	/* v->encodingMask = (type_id & UA_VARIANT_ENCODINGMASKTYPE_TYPEID_MASK) | UA_VARIANT_ENCODINGMASKTYPE_ARRAY; */
-	/* if(UA_VTable_isValidType(type_id) != UA_SUCCESS) return UA_INVALIDTYPE; */
-	/* v->vt = &UA_borrowed_.types[type_id]; */
-	/* v->arrayLength  = arrayLength; */
-	/* v->data         = (void *)array; */
+UA_Int32 UA_Variant_borrowSetValue(UA_Variant *v, UA_VTable_Entry *vt, const void *value) {
+	if(v == UA_NULL || vt == UA_NULL || value == UA_NULL)
+		return UA_ERROR;
+	UA_Variant_init(v);
+	v->vt = &UA_borrowed_.types[UA_ns0ToVTableIndex(&vt->typeId)];
+	v->arrayLength = 1; // no array but a single entry
+	v->data = (void *)value;
 	return UA_SUCCESS;
 	return UA_SUCCESS;
 }
 }
 
 
-UA_Int32 UA_Variant_copySetArray(UA_Variant *v, UA_Int32 type_id, UA_Int32 arrayLength, UA_UInt32 elementSize,
-                                 const void *array) {
-	/* v->encodingMask = (type_id & UA_VARIANT_ENCODINGMASKTYPE_TYPEID_MASK) | UA_VARIANT_ENCODINGMASKTYPE_ARRAY; */
-	/* if(UA_VTable_isValidType(type_id) != UA_SUCCESS) return UA_INVALIDTYPE; */
-	/* v->vt = &UA_.types[type_id]; */
-	/* v->arrayLength  = arrayLength; */
-	/* void    *new_arr; */
-	/* UA_Int32 retval = UA_SUCCESS; */
-	/* retval |= UA_alloc(&new_arr, arrayLength * elementSize); */
-	/* retval |= UA_memcpy(new_arr, array, arrayLength * elementSize); */
-	/* v->data = new_arr; */
-	return UA_SUCCESS;
+UA_Int32 UA_Variant_borrowSetArray(UA_Variant *v, UA_VTable_Entry *vt, UA_Int32 arrayLength, const void *array) {
+	if(v == UA_NULL || vt == UA_NULL || array == UA_NULL)
+		return UA_ERROR;
+	UA_Variant_init(v);
+	v->vt = &UA_borrowed_.types[UA_ns0ToVTableIndex(&vt->typeId)];
+	v->arrayLength = arrayLength;
+	return UA_Array_copy(array, arrayLength, v->vt, &v->data);
 }
 }
 
 
 /* DiagnosticInfo */
 /* DiagnosticInfo */

+ 4 - 5
src/ua_types.h

@@ -322,16 +322,15 @@ void UA_QualifiedName_printf(char const *label, const UA_QualifiedName *qn);
 UA_Int32 UA_LocalizedText_copycstring(char const *src, UA_LocalizedText *dst);
 UA_Int32 UA_LocalizedText_copycstring(char const *src, UA_LocalizedText *dst);
 
 
 /* Variant */
 /* Variant */
-UA_Int32 UA_Variant_copySetValue(UA_Variant *v, UA_Int32 type, const void *data);
-UA_Int32 UA_Variant_copySetArray(UA_Variant *v, UA_Int32 type_id, UA_Int32 arrayLength, UA_UInt32 elementSize,
-                                 const void *array);
+UA_Int32 UA_Variant_copySetValue(UA_Variant *v, UA_VTable_Entry *vt, const void *value);
+UA_Int32 UA_Variant_copySetArray(UA_Variant *v, UA_VTable_Entry *vt, UA_Int32 arrayLength, const void *array);
 
 
 /** @brief Functions UA_Variant_borrowSetValue and ..Array allow to define
 /** @brief Functions UA_Variant_borrowSetValue and ..Array allow to define
    variants whose payload will not be deleted. This is achieved by a second
    variants whose payload will not be deleted. This is achieved by a second
    vtable. The functionality can be used e.g. when UA_VariableNodes point into a
    vtable. The functionality can be used e.g. when UA_VariableNodes point into a
    "father" structured object that is stored in an UA_VariableNode itself. */
    "father" structured object that is stored in an UA_VariableNode itself. */
-UA_Int32 UA_Variant_borrowSetValue(UA_Variant *v, UA_Int32 type, const void *data);
-UA_Int32 UA_Variant_borrowSetArray(UA_Variant *v, UA_Int32 type, UA_Int32 arrayLength, const void *data);
+UA_Int32 UA_Variant_borrowSetValue(UA_Variant *v, UA_VTable_Entry *vt, const void *value);
+UA_Int32 UA_Variant_borrowSetArray(UA_Variant *v, UA_VTable_Entry *vt, UA_Int32 arrayLength, const void *array);
 
 
 /* Array operations */
 /* Array operations */
 UA_Int32 UA_Array_new(void **p, UA_Int32 noElements, UA_VTable_Entry *vt);
 UA_Int32 UA_Array_new(void **p, UA_Int32 noElements, UA_VTable_Entry *vt);

+ 70 - 61
tools/generate_namespace.py

@@ -6,44 +6,51 @@ import getpass
 import time
 import time
 
 
 if len(sys.argv) != 3:
 if len(sys.argv) != 3:
-	print("Usage: python generate_namespace.py <path/to/NodeIds.csv> <outfile w/o extension>", file=sys.stdout)
-	exit(0)
+    print("Usage: python generate_namespace.py <path/to/NodeIds.csv> <outfile w/o extension>",
+          file=sys.stdout)
+    exit(0)
 
 
 # types that are to be excluded
 # types that are to be excluded
 exclude_kinds = set(["Object","ObjectType","Variable","Method","ReferenceType"])
 exclude_kinds = set(["Object","ObjectType","Variable","Method","ReferenceType"])
-exclude_types = set(["Number", "Integer", "UInteger", "Enumeration",
-	"Image", "ImageBMP", "ImageGIF", "ImageJPG", "ImagePNG",
-	"References", "BaseVariableType", "BaseDataVariableType", 
-	"PropertyType", "DataTypeDescriptionType", "DataTypeDictionaryType", "NamingRuleType",
-	"IntegerId","Counter","Duration","NumericRange","Time","Date",
-	"UtcTime", "LocaleId","UserTokenType",
-	"ApplicationType","ApplicationInstanceCertificate",
-	"ServerVendorCapabilityType","ServerStatusType","ServerDiagnosticsSummaryType",
-	"SamplingIntervalDiagnosticsArrayType", "SamplingIntervalDiagnosticsType", 
-	"SubscriptionDiagnosticsArrayType", "SubscriptionDiagnosticsType",
-	"SessionDiagnosticsArrayType", "SessionDiagnosticsVariableType", 
-	"SessionSecurityDiagnosticsArrayType", "SessionSecurityDiagnosticsType", 
-	"DataItemType", "AnalogItemType", "DiscreteItemType", "TwoStateDiscreteType",
-	"MultiStateDiscreteType", "ProgramDiagnosticType", "StateVariableType", "FiniteStateVariableType",
-	"TransitionVariableType", "FiniteTransitionVariableType", "BuildInfoType", "TwoStateVariableType",
-	"ConditionVariableType", "MultiStateValueDiscreteType", "OptionSetType", "ArrayItemType",
-	"YArrayItemType", "XYArrayItemType", "ImageItemType", "CubeItemType", "NDimensionArrayItemType"])
+exclude_types = set(["Number", "Integer", "UInteger", "Enumeration", "Image", "ImageBMP",
+                     "ImageGIF", "ImageJPG", "ImagePNG", "References", "BaseVariableType",
+                     "BaseDataVariableType", "PropertyType", "DataTypeDescriptionType",
+                     "DataTypeDictionaryType", "NamingRuleType", "IntegerId", "Counter",
+                     "Duration", "NumericRange", "Time", "Date", "UtcTime", "LocaleId",
+                     "UserTokenType", "ApplicationType", "ApplicationInstanceCertificate",
+                     "ServerVendorCapabilityType", "ServerStatusType",
+                     "ServerDiagnosticsSummaryType", "SamplingIntervalDiagnosticsArrayType",
+                     "SamplingIntervalDiagnosticsType", "SubscriptionDiagnosticsArrayType",
+                     "SubscriptionDiagnosticsType", "SessionDiagnosticsArrayType",
+                     "SessionDiagnosticsVariableType", "SessionSecurityDiagnosticsArrayType",
+                     "SessionSecurityDiagnosticsType", "DataItemType", "AnalogItemType",
+                     "DiscreteItemType", "TwoStateDiscreteType", "MultiStateDiscreteType",
+                     "ProgramDiagnosticType", "StateVariableType", "FiniteStateVariableType",
+                     "TransitionVariableType", "FiniteTransitionVariableType", "BuildInfoType",
+                     "TwoStateVariableType", "ConditionVariableType",
+                     "MultiStateValueDiscreteType", "OptionSetType", "ArrayItemType",
+                     "YArrayItemType", "XYArrayItemType", "ImageItemType", "CubeItemType",
+                     "NDimensionArrayItemType"])
 
 
 fixed_size = ['UA_DeadbandType', 'UA_DataChangeTrigger', 'UA_Guid', 'UA_ApplicationType',
 fixed_size = ['UA_DeadbandType', 'UA_DataChangeTrigger', 'UA_Guid', 'UA_ApplicationType',
               'UA_ComplexNumberType', 'UA_EnumeratedTestType', 'UA_BrowseResultMask',
               'UA_ComplexNumberType', 'UA_EnumeratedTestType', 'UA_BrowseResultMask',
               'UA_TimeZoneDataType', 'UA_NodeClass', 'UA_IdType', 'UA_ServiceCounterDataType',
               'UA_TimeZoneDataType', 'UA_NodeClass', 'UA_IdType', 'UA_ServiceCounterDataType',
               'UA_Float', 'UA_ModelChangeStructureVerbMask', 'UA_EndpointConfiguration',
               'UA_Float', 'UA_ModelChangeStructureVerbMask', 'UA_EndpointConfiguration',
-              'UA_NodeAttributesMask', 'UA_DataChangeFilter', 'UA_StatusCode', 'UA_MonitoringFilterResult',
-              'UA_OpenFileMode', 'UA_SecurityTokenRequestType', 'UA_ServerDiagnosticsSummaryDataType',
-              'UA_ElementOperand', 'UA_AggregateConfiguration', 'UA_UInt64', 'UA_FilterOperator',
-              'UA_ReadRawModifiedDetails', 'UA_ServerState', 'UA_FilterOperand', 'UA_SubscriptionAcknowledgement',
-              'UA_AttributeWriteMask', 'UA_SByte', 'UA_Int32', 'UA_Range', 'UA_Byte', 'UA_TimestampsToReturn',
-              'UA_UserTokenType', 'UA_Int16', 'UA_XVType', 'UA_AggregateFilterResult', 'UA_Boolean',
-              'UA_MessageSecurityMode', 'UA_AxisScaleEnumeration', 'UA_PerformUpdateType', 'UA_UInt16',
-              'UA_NotificationData', 'UA_DoubleComplexNumberType', 'UA_HistoryUpdateType', 'UA_MonitoringFilter',
-              'UA_NodeIdType', 'UA_BrowseDirection', 'UA_SamplingIntervalDiagnosticsDataType', 'UA_UInt32',
-              'UA_ChannelSecurityToken', 'UA_RedundancySupport', 'UA_MonitoringMode', 'UA_HistoryReadDetails',
-              'UA_ExceptionDeviationFormat', 'UA_ComplianceLevel', 'UA_DateTime', 'UA_Int64', 'UA_Double']
+              'UA_NodeAttributesMask', 'UA_DataChangeFilter', 'UA_StatusCode',
+              'UA_MonitoringFilterResult', 'UA_OpenFileMode', 'UA_SecurityTokenRequestType',
+              'UA_ServerDiagnosticsSummaryDataType', 'UA_ElementOperand',
+              'UA_AggregateConfiguration', 'UA_UInt64', 'UA_FilterOperator',
+              'UA_ReadRawModifiedDetails', 'UA_ServerState', 'UA_FilterOperand',
+              'UA_SubscriptionAcknowledgement', 'UA_AttributeWriteMask', 'UA_SByte', 'UA_Int32',
+              'UA_Range', 'UA_Byte', 'UA_TimestampsToReturn', 'UA_UserTokenType', 'UA_Int16',
+              'UA_XVType', 'UA_AggregateFilterResult', 'UA_Boolean', 'UA_MessageSecurityMode',
+              'UA_AxisScaleEnumeration', 'UA_PerformUpdateType', 'UA_UInt16',
+              'UA_NotificationData', 'UA_DoubleComplexNumberType', 'UA_HistoryUpdateType',
+              'UA_MonitoringFilter', 'UA_NodeIdType', 'UA_BrowseDirection',
+              'UA_SamplingIntervalDiagnosticsDataType', 'UA_UInt32', 'UA_ChannelSecurityToken',
+              'UA_RedundancySupport', 'UA_MonitoringMode', 'UA_HistoryReadDetails',
+              'UA_ExceptionDeviationFormat', 'UA_ComplianceLevel', 'UA_DateTime', 'UA_Int64',
+              'UA_Double']
 
 
 f = open(sys.argv[1])
 f = open(sys.argv[1])
 input_str = f.read() + "\nInvalidType,0,DataType"
 input_str = f.read() + "\nInvalidType,0,DataType"
@@ -63,7 +70,8 @@ printh('''/**********************************************************
  * '''+sys.argv[2]+'''.hgen -- do not modify
  * '''+sys.argv[2]+'''.hgen -- do not modify
  **********************************************************
  **********************************************************
  * Generated from '''+sys.argv[1]+''' with script '''+sys.argv[0]+'''
  * Generated from '''+sys.argv[1]+''' with script '''+sys.argv[0]+'''
- * on host '''+platform.uname()[1]+''' by user '''+getpass.getuser()+''' at '''+ time.strftime("%Y-%m-%d %I:%M:%S")+'''
+ * on host '''+platform.uname()[1]+''' by user '''+getpass.getuser()+''' at '''+
+       time.strftime("%Y-%m-%d %I:%M:%S")+'''
  **********************************************************/\n 
  **********************************************************/\n 
 #ifndef ''' + sys.argv[2].upper() + '''_H_
 #ifndef ''' + sys.argv[2].upper() + '''_H_
 #define ''' + sys.argv[2].upper() + '''_H_\n
 #define ''' + sys.argv[2].upper() + '''_H_\n
@@ -93,7 +101,8 @@ printc('''/**********************************************************
  * '''+sys.argv[2]+'''.cgen -- do not modify
  * '''+sys.argv[2]+'''.cgen -- do not modify
  **********************************************************
  **********************************************************
  * Generated from '''+sys.argv[1]+''' with script '''+sys.argv[0]+'''
  * Generated from '''+sys.argv[1]+''' with script '''+sys.argv[0]+'''
- * on host '''+platform.uname()[1]+''' by user '''+getpass.getuser()+''' at '''+ time.strftime("%Y-%m-%d %I:%M:%S")+'''
+ * on host '''+platform.uname()[1]+''' by user '''+getpass.getuser() +
+       ''' at '''+ time.strftime("%Y-%m-%d %I:%M:%S")+'''
  **********************************************************/\n
  **********************************************************/\n
 #include "''' + sys.argv[2] + '''.h"\n
 #include "''' + sys.argv[2] + '''.h"\n
 UA_Int32 UA_ns0ToVTableIndex(const UA_NodeId *id) {
 UA_Int32 UA_ns0ToVTableIndex(const UA_NodeId *id) {
@@ -134,26 +143,26 @@ for row in rows:
 
 
     printh('#define '+name.upper()+'_NS0 '+row[1])
     printh('#define '+name.upper()+'_NS0 '+row[1])
 
 
-    printc("\t{.typeId={UA_NODEIDTYPE_FOURBYTE,0,.identifier.numeric=" + row[1] +"}"+ 
-          ",.name=(UA_Byte*)&\""+name+"\""+
-          ",.new=(UA_Int32(*)(void **))"+name+"_new"+
-          ",.init=(UA_Int32(*)(void *))"+name+"_init"+
-          ",.copy=(UA_Int32(*)(void const * ,void*))"+name+"_copy"+
-          ",.delete=(UA_Int32(*)(void *))"+name+"_delete"+
-          ",.deleteMembers=(UA_Int32(*)(void *))"+name+"_deleteMembers"+
-          ",.memSize=" + ("sizeof("+name+")" if (name != "UA_InvalidType") else "0") +
+    printc("\t{.typeId={UA_NODEIDTYPE_FOURBYTE,0,.identifier.numeric=" + row[1] + "}" + 
+          ",.name=(UA_Byte*)&\"%(name)s\"" +
+          ",.new=(UA_Int32(*)(void **))%(name)s_new" +
+          ",.init=(UA_Int32(*)(void *))%(name)s_init"+
+          ",.copy=(UA_Int32(*)(void const * ,void*))%(name)s_copy" +
+          ",.delete=(UA_Int32(*)(void *))%(name)s_delete" +
+          ",.deleteMembers=(UA_Int32(*)(void *))%(name)s_deleteMembers" +
+          ",.memSize=" + ("sizeof(%(name)s)" if (name != "UA_InvalidType") else "0") +
           ",.dynMembers=" + ("UA_FALSE" if (name in fixed_size) else "UA_TRUE") +
           ",.dynMembers=" + ("UA_FALSE" if (name in fixed_size) else "UA_TRUE") +
-          ",.encodings={{.calcSize=(UA_calcSize)"+ name +"_calcSizeBinary" +
-          ",.encode=(UA_encode)"+name+ "_encodeBinary" +
-          ",.decode=(UA_decode)"+name+"_decodeBinary}"+
-          ",{.calcSize=(UA_calcSize)"+ name +"_calcSizeXml" +
-          ",.encode=(UA_encode)"+name+ "_encodeXml" +
-          ",.decode=(UA_decode)"+name+"_decodeXml}"+
+          ",.encodings={{.calcSize=(UA_calcSize)%(name)s_calcSizeBinary" +
+          ",.encode=(UA_encode)%(name)s_encodeBinary" +
+          ",.decode=(UA_decode)%(name)s_decodeBinary}" +
+          ",{.calcSize=(UA_calcSize)%(name)s_calcSizeXml" +
+          ",.encode=(UA_encode)%(name)s_encodeXml" +
+          ",.decode=(UA_decode)%(name)s_decodeXml}" +
           "}},")
           "}},")
 
 
 printc('''}};
 printc('''}};
 
 
-const UA_VTable UA_noDelete_ = {
+const UA_VTable UA_borrowed_ = {
 \t.getTypeIndex=UA_ns0ToVTableIndex,
 \t.getTypeIndex=UA_ns0ToVTableIndex,
 \t.types = (UA_VTable_Entry[]){''')
 \t.types = (UA_VTable_Entry[]){''')
 
 
@@ -167,21 +176,21 @@ for row in rows:
     else:	
     else:	
 	name = "UA_" + row[0]
 	name = "UA_" + row[0]
 
 
-    printc("\t{.typeId={UA_NODEIDTYPE_FOURBYTE,0,.identifier.numeric=" + row[1] +"}"+ 
-          ",.name=(UA_Byte*)&\""+name+"\""+
-          ",.new=(UA_Int32(*)(void **))"+name+"_new"+
-          ",.init=(UA_Int32(*)(void *))"+name+"_init"+
-          ",.copy=(UA_Int32(*)(void const * ,void*))"+name+"_copy"+
-          ",.delete=(UA_Int32(*)(void *))phantom_delete"+
-          ",.deleteMembers=(UA_Int32(*)(void *))phantom_delete"+
-          ",.memSize=" + ("sizeof("+name+")" if (name != "UA_InvalidType") else "0") +
+    printc("\t{.typeId={UA_NODEIDTYPE_FOURBYTE,0,.identifier.numeric=" + row[1] + "}" + 
+          ",.name=(UA_Byte*)&\"%(name)s\"" +
+          ",.new=(UA_Int32(*)(void **))%(name)s_new" +
+          ",.init=(UA_Int32(*)(void *))%(name)s_init" +
+          ",.copy=(UA_Int32(*)(void const * ,void*))%(name)s_copy" +
+          ",.delete=(UA_Int32(*)(void *))phantom_delete" +
+          ",.deleteMembers=(UA_Int32(*)(void *))phantom_delete" +
+          ",.memSize=" + ("sizeof(%(name)s)" if (name != "UA_InvalidType") else "0") +
           ",.dynMembers=" + ("UA_FALSE" if (name in fixed_size) else "UA_TRUE") +
           ",.dynMembers=" + ("UA_FALSE" if (name in fixed_size) else "UA_TRUE") +
-          ",.encodings={{.calcSize=(UA_calcSize)"+ name +"_calcSizeBinary" +
-          ",.encode=(UA_encode)"+name+ "_encodeBinary" +
-          ",.decode=(UA_decode)"+name+"_decodeBinary}"+
-          ",{.calcSize=(UA_calcSize)"+ name +"_calcSizeXml" +
-          ",.encode=(UA_encode)"+name+ "_encodeXml" +
-          ",.decode=(UA_decode)"+name+"_decodeXml}"+
+          ",.encodings={{.calcSize=(UA_calcSize)" + name +"_calcSizeBinary" +
+          ",.encode=(UA_encode)%(name)s_encodeBinary" +
+          ",.decode=(UA_decode)%(name)s_decodeBinary}" +
+          ",{.calcSize=(UA_calcSize)%(name)s_calcSizeXml" +
+          ",.encode=(UA_encode)%(name)s_encodeXml" +
+          ",.decode=(UA_decode)%(name)s_decodeXml}" +
           "}},")
           "}},")
 
 
 printc("}};")
 printc("}};")