def generateReferenceCode(reference): code = [] forwardFlag = "true" if reference.isForward else "false" code.append("retVal |= UA_Server_addReference(server, %s, %s, %s, %s);" % (generateNodeIdCode(reference.source), generateNodeIdCode(reference.referenceType), generateExpandedNodeIdCode(reference.target), forwardFlag)) code.append("if (retVal != UA_STATUSCODE_GOOD) return retVal;") return "\n".join(code)
def generateNodeCode_begin(node, nodeset, code_global): code = [] codeCleanup = [] code.append("UA_StatusCode retVal = UA_STATUSCODE_GOOD;") # Attributes if isinstance(node, ReferenceTypeNode): code.extend(generateReferenceTypeNodeCode(node)) elif isinstance(node, ObjectNode): code.extend(generateObjectNodeCode(node)) elif isinstance(node, VariableNode) and not isinstance(node, VariableTypeNode): [code1, codeCleanup1, codeGlobal1] = generateVariableNodeCode(node, nodeset) code.extend(code1) codeCleanup.extend(codeCleanup1) code_global.extend(codeGlobal1) elif isinstance(node, VariableTypeNode): [code1, codeCleanup1, codeGlobal1] = generateVariableTypeNodeCode(node, nodeset) code.extend(code1) codeCleanup.extend(codeCleanup1) code_global.extend(codeGlobal1) elif isinstance(node, MethodNode): code.extend(generateMethodNodeCode(node)) elif isinstance(node, ObjectTypeNode): code.extend(generateObjectTypeNodeCode(node)) elif isinstance(node, DataTypeNode): code.extend(generateDataTypeNodeCode(node)) elif isinstance(node, ViewNode): code.extend(generateViewNodeCode(node)) if node.displayName is not None: code.append("attr.displayName = " + generateLocalizedTextCode(node.displayName, alloc=False) + ";") if node.description is not None: code.append("#ifdef UA_ENABLE_NODESET_COMPILER_DESCRIPTIONS") code.append("attr.description = " + generateLocalizedTextCode(node.description, alloc=False) + ";") code.append("#endif") if node.writeMask is not None: code.append("attr.writeMask = %d;" % node.writeMask) if node.userWriteMask is not None: code.append("attr.userWriteMask = %d;" % node.userWriteMask) # AddNodes call code.append("retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_{},". format(makeCIdentifier(node.__class__.__name__.upper().replace("NODE" ,"")))) code.append(generateNodeIdCode(node.id) + ",") code.append(generateNodeIdCode(node.parent.id if node.parent else NodeId()) + ",") code.append(generateNodeIdCode(node.parentReference.id if node.parent else NodeId()) + ",") code.append(generateQualifiedNameCode(node.browseName) + ",") if isinstance(node, VariableNode) or isinstance(node, ObjectNode): typeDefRef = node.popTypeDef() code.append(generateNodeIdCode(typeDefRef.target) + ",") else: code.append(" UA_NODEID_NULL,") code.append("(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_{}ATTRIBUTES],NULL, NULL);". format(makeCIdentifier(node.__class__.__name__.upper().replace("NODE" ,"")))) code.extend(codeCleanup) return "\n".join(code)
def generateReferenceCode(reference): if reference.isForward: return "retVal |= UA_Server_addReference(server, %s, %s, %s, true);" % \ (generateNodeIdCode(reference.source), generateNodeIdCode(reference.referenceType), generateExpandedNodeIdCode(reference.target)) else: return "retVal |= UA_Server_addReference(server, %s, %s, %s, false);" % \ (generateNodeIdCode(reference.source), generateNodeIdCode(reference.referenceType), generateExpandedNodeIdCode(reference.target))
def generateNodeCode_finish(node): code = [] if isinstance(node, MethodNode): code.append("UA_Server_addMethodNode_finish(server, ") else: code.append("UA_Server_addNode_finish(server, ") code.append(generateNodeIdCode(node.id)) if isinstance(node, MethodNode): code.append(", NULL, 0, NULL, 0, NULL);") else: code.append(");") return "\n".join(code)
def generateSubtypeOfDefinitionCode(node): for ref in node.inverseReferences: # 45 = HasSubtype if ref.referenceType.i == 45: return generateNodeIdCode(ref.target) return "UA_NODEID_NULL"
def generateCommonVariableCode(node, nodeset): code = [] codeCleanup = [] codeGlobal = [] if node.valueRank is None: # Set the constrained value rank from the type/parent node setNodeValueRankRecursive(node, nodeset) code.append("/* Value rank inherited */") code.append("attr.valueRank = %d;" % node.valueRank) if node.valueRank > 0: code.append("attr.arrayDimensionsSize = %d;" % node.valueRank) code.append("UA_UInt32 arrayDimensions[{}];".format(node.valueRank)) if len(node.arrayDimensions) == node.valueRank: for idx, v in enumerate(node.arrayDimensions): code.append("arrayDimensions[{}] = {};".format( idx, int(str(v)))) else: for dim in range(0, node.valueRank): code.append("arrayDimensions[{}] = 0;".format(dim)) code.append("attr.arrayDimensions = &arrayDimensions[0];") if node.dataType is None: # Inherit the datatype from the HasTypeDefinition reference, as stated in the OPC UA Spec: # 6.4.2 # "Instances inherit the initial values for the Attributes that they have in common with the # TypeDefinitionNode from which they are instantiated, with the exceptions of the NodeClass and # NodeId." setNodeDatatypeRecursive(node, nodeset) code.append("/* DataType inherited */") dataTypeNode = nodeset.getBaseDataType( nodeset.getDataTypeNode(node.dataType)) if dataTypeNode is None: raise RuntimeError("Cannot get BaseDataType for dataType : " + str(node.dataType) + " of node " + node.browseName.name + " " + str(node.id)) code.append("attr.dataType = %s;" % generateNodeIdCode(node.dataType)) if dataTypeNode.isEncodable(): if node.value is not None: [code1, codeCleanup1, codeGlobal1] = generateValueCode(node.value, nodeset.nodes[node.id], nodeset) code += code1 codeCleanup += codeCleanup1 codeGlobal += codeGlobal1 # #1978 Variant arrayDimensions are only required to properly decode multidimensional arrays # (valueRank > 1) from data stored as one-dimensional array of arrayLength elements. # One-dimensional arrays are already completely defined by arraylength attribute so setting # also arrayDimensions, even if not explicitly forbidden, can confuse clients if node.valueRank is not None and node.valueRank > 1 and len( node.arrayDimensions) == node.valueRank and len( node.value.value) > 0: numElements = 1 hasZero = False for v in node.arrayDimensions: dim = int(unicode(v)) if dim > 0: numElements = numElements * dim else: hasZero = True if hasZero == False and len(node.value.value) == numElements: code.append( "attr.value.arrayDimensionsSize = attr.arrayDimensionsSize;" ) code.append( "attr.value.arrayDimensions = attr.arrayDimensions;") elif node.value is not None: code.append("/* Cannot encode the value */") logger.warn("Cannot encode dataTypeNode: " + dataTypeNode.browseName.name + " for value of node " + node.browseName.name + " " + str(node.id)) return [code, codeCleanup, codeGlobal]