Browse Source

Set nodeset max binary encoding size

Stefan Profanter 6 years ago
parent
commit
d8d36f2902

+ 5 - 0
CMakeLists.txt

@@ -644,6 +644,10 @@ if(MSVC)
     set(NODESET_MAX_STR_LEN 65535)
 endif()
 
+if(NOT UA_NODESET_ENCODE_BINARY_SIZE)
+    set(UA_NODESET_ENCODE_BINARY_SIZE 32000)
+endif()
+
 # generated namespace 0
 add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/src_generated/ua_namespace0.c
                           ${PROJECT_BINARY_DIR}/src_generated/ua_namespace0.h
@@ -652,6 +656,7 @@ add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/src_generated/ua_namespace0.c
                            --generate-ns0
                            --internal-headers
                            --max-string-length=${NODESET_MAX_STR_LEN}
+                           --encode-binary-size=${UA_NODESET_ENCODE_BINARY_SIZE}
                            --ignore ${PROJECT_SOURCE_DIR}/tools/nodeset_compiler/NodeID_NS0_Base.txt
                            --xml ${UA_FILE_NS0}
                            ${PROJECT_BINARY_DIR}/src_generated/ua_namespace0

+ 2 - 2
tools/nodeset_compiler/backend_open62541.py

@@ -131,7 +131,7 @@ def sortNodes(nodeset):
 # Generate C Code #
 ###################
 
-def generateOpen62541Code(nodeset, outfilename, generate_ns0=False, internal_headers=False, typesArray=[], max_string_length=0):
+def generateOpen62541Code(nodeset, outfilename, generate_ns0=False, internal_headers=False, typesArray=[], max_string_length=0, encode_binary_size=32000):
     outfilebase = basename(outfilename)
     # Printing functions
     outfileh = codecs.open(outfilename + ".h", r"w+", encoding='utf-8')
@@ -235,7 +235,7 @@ extern UA_StatusCode %s(UA_Server *server);
         parentref = node.popParentRef(parentreftypes)
         if not node.hidden:
             writec("\n/* " + str(node.displayName) + " - " + str(node.id) + " */")
-            code = generateNodeCode_begin(node, nodeset, max_string_length, generate_ns0, parentref)
+            code = generateNodeCode_begin(node, nodeset, max_string_length, generate_ns0, parentref, encode_binary_size)
             if code is None:
                 writec("/* Ignored. No parent */")
                 nodeset.hide_node(node.id)

+ 15 - 13
tools/nodeset_compiler/backend_open62541_nodes.py

@@ -72,7 +72,7 @@ def generateObjectNodeCode(node):
         code.append("attr.eventNotifier = true;")
     return code
 
-def generateVariableNodeCode(node, nodeset, max_string_length):
+def generateVariableNodeCode(node, nodeset, max_string_length, encode_binary_size):
     code = []
     codeCleanup = []
     code.append("UA_VariableAttributes attr = UA_VariableAttributes_default;")
@@ -107,14 +107,14 @@ def generateVariableNodeCode(node, nodeset, max_string_length):
 
             if dataTypeNode.isEncodable():
                 if node.value is not None:
-                    [code1, codeCleanup1] = generateValueCode(node.value, nodeset.nodes[node.id], nodeset, max_string_length=max_string_length)
+                    [code1, codeCleanup1] = generateValueCode(node.value, nodeset.nodes[node.id], nodeset, max_string_length=max_string_length, encode_binary_size=encode_binary_size)
                     code += code1
                     codeCleanup += codeCleanup1
                 else:
                     code += generateValueCodeDummy(dataTypeNode, nodeset.nodes[node.id], nodeset)
     return [code, codeCleanup]
 
-def generateVariableTypeNodeCode(node, nodeset, max_string_length):
+def generateVariableTypeNodeCode(node, nodeset, max_string_length, encode_binary_size):
     code = []
     codeCleanup = []
     code.append("UA_VariableTypeAttributes attr = UA_VariableTypeAttributes_default;")
@@ -133,14 +133,14 @@ def generateVariableTypeNodeCode(node, nodeset, max_string_length):
             code.append("attr.dataType = %s;" % generateNodeIdCode(dataTypeNode.id))
             if dataTypeNode.isEncodable():
                 if node.value is not None:
-                    [code1, codeCleanup1] = generateValueCode(node.value, nodeset.nodes[node.id], nodeset, max_string_length)
+                    [code1, codeCleanup1] = generateValueCode(node.value, nodeset.nodes[node.id], nodeset, max_string_length, encode_binary_size)
                     code += code1
                     codeCleanup += codeCleanup1
                 else:
                     code += generateValueCodeDummy(dataTypeNode, nodeset.nodes[node.id], nodeset)
     return [code, codeCleanup]
 
-def generateExtensionObjectSubtypeCode(node, parent, nodeset, recursionDepth=0, arrayIndex=0, max_string_length=0):
+def generateExtensionObjectSubtypeCode(node, parent, nodeset, recursionDepth=0, arrayIndex=0, max_string_length=0, encode_binary_size=32000):
     code = [""]
     codeCleanup = [""]
 
@@ -216,11 +216,11 @@ def generateExtensionObjectSubtypeCode(node, parent, nodeset, recursionDepth=0,
         instanceName + "->content.encoded.typeId = UA_NODEID_NUMERIC(" + str(binaryEncodingId.ns) + ", " +
         str(binaryEncodingId.i) + ");")
     code.append(
-        "UA_ByteString_allocBuffer(&" + instanceName + "->content.encoded.body, 65000);")
+        "UA_ByteString_allocBuffer(&" + instanceName + "->content.encoded.body, " + str(encode_binary_size) + ");")
 
     # Encode each value as a bytestring separately.
     code.append("UA_Byte *pos" + instanceName + " = " + instanceName + "->content.encoded.body.data;")
-    code.append("const UA_Byte *end" + instanceName + " = &" + instanceName + "->content.encoded.body.data[65000];")
+    code.append("const UA_Byte *end" + instanceName + " = &" + instanceName + "->content.encoded.body.data[" + str(encode_binary_size) + "];")
     encFieldIdx = 0
     code.append("{")
     for subv in node.value:
@@ -288,7 +288,7 @@ def getTypesArrayForValue(nodeset, value):
     return "&" + typesArray + "[" + typesArray + "_" + \
                     value.__class__.__name__.upper() + "]"
 
-def generateValueCode(node, parentNode, nodeset, bootstrapping=True, max_string_length=0):
+def generateValueCode(node, parentNode, nodeset, bootstrapping=True, max_string_length=0, encode_binary_size=32000):
     code = []
     codeCleanup = []
     valueName = generateNodeIdPrintable(parentNode) + "_variant_DataContents"
@@ -323,7 +323,8 @@ def generateValueCode(node, parentNode, nodeset, bootstrapping=True, max_string_
             if node.value[0].numericRepresentation == BUILTINTYPE_TYPEID_EXTENSIONOBJECT:
                 for idx, v in enumerate(node.value):
                     logger.debug("Building extObj array index " + str(idx))
-                    [code1, codeCleanup1] = generateExtensionObjectSubtypeCode(v, parent=parentNode, nodeset=nodeset, arrayIndex=idx, max_string_length=max_string_length)
+                    [code1, codeCleanup1] = generateExtensionObjectSubtypeCode(v, parent=parentNode, nodeset=nodeset, arrayIndex=idx, max_string_length=max_string_length,
+                                                                               encode_binary_size=encode_binary_size)
                     code = code + code1
                     codeCleanup = codeCleanup + codeCleanup1
             code.append("UA_" + node.value[0].__class__.__name__ + " " + valueName + "[" + str(len(node.value)) + "];")
@@ -354,7 +355,8 @@ def generateValueCode(node, parentNode, nodeset, bootstrapping=True, max_string_
         else:
             # The following strategy applies to all other types, in particular strings and numerics.
             if node.value[0].numericRepresentation == BUILTINTYPE_TYPEID_EXTENSIONOBJECT:
-                [code1, codeCleanup1] = generateExtensionObjectSubtypeCode(node.value[0], parent=parentNode, nodeset=nodeset, max_string_length=max_string_length)
+                [code1, codeCleanup1] = generateExtensionObjectSubtypeCode(node.value[0], parent=parentNode, nodeset=nodeset, max_string_length=max_string_length,
+                                                                           encode_binary_size=encode_binary_size)
                 code = code + code1
                 codeCleanup = codeCleanup + codeCleanup1
             instanceName = generateNodeValueInstanceName(node.value[0], parentNode, 0, 0)
@@ -423,7 +425,7 @@ def generateSubtypeOfDefinitionCode(node):
             return generateNodeIdCode(ref.target)
     return "UA_NODEID_NULL"
 
-def generateNodeCode_begin(node, nodeset, max_string_length, generate_ns0, parentref):
+def generateNodeCode_begin(node, nodeset, max_string_length, generate_ns0, parentref, encode_binary_size):
     code = []
     codeCleanup = []
     code.append("UA_StatusCode retVal = UA_STATUSCODE_GOOD;")
@@ -434,11 +436,11 @@ def generateNodeCode_begin(node, nodeset, max_string_length, generate_ns0, paren
     elif isinstance(node, ObjectNode):
         code.extend(generateObjectNodeCode(node))
     elif isinstance(node, VariableNode) and not isinstance(node, VariableTypeNode):
-        [code1, codeCleanup1] = generateVariableNodeCode(node, nodeset, max_string_length)
+        [code1, codeCleanup1] = generateVariableNodeCode(node, nodeset, max_string_length, encode_binary_size)
         code.extend(code1)
         codeCleanup.extend(codeCleanup1)
     elif isinstance(node, VariableTypeNode):
-        [code1, codeCleanup1] = generateVariableTypeNodeCode(node, nodeset, max_string_length)
+        [code1, codeCleanup1] = generateVariableTypeNodeCode(node, nodeset, max_string_length, encode_binary_size)
         code.extend(code1)
         codeCleanup.extend(codeCleanup1)
     elif isinstance(node, MethodNode):

+ 7 - 1
tools/nodeset_compiler/nodeset_compiler.py

@@ -88,6 +88,12 @@ parser.add_argument('--max-string-length',
                     default=0,
                     help='Maximum allowed length of a string literal. If longer, it will be set to an empty string')
 
+parser.add_argument('--encode-binary-size',
+                    type=int,
+                    dest="encode_binary_size",
+                    default=32000,
+                    help='Size of the temporary array used to encode custom datatypes. If you don\'t know what it is, do not use this option')
+
 parser.add_argument('-v', '--verbose', action='count',
                     default=1,
                     help='Make the script more verbose. Can be applied up to 4 times')
@@ -182,5 +188,5 @@ ns.allocateVariables()
 
 # Create the C code with the open62541 backend of the compiler
 logger.info("Generating Code")
-generateOpen62541Code(ns, args.outputFile, args.generate_ns0, args.internal_headers, args.typesArray, args.max_string_length)
+generateOpen62541Code(ns, args.outputFile, args.generate_ns0, args.internal_headers, args.typesArray, args.max_string_length, args.encode_binary_size)
 logger.info("NodeSet generation code successfully printed")