backend_open62541_datatypes.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. from datatypes import *
  2. import datetime
  3. import re
  4. import logging
  5. logger = logging.getLogger(__name__)
  6. def generateBooleanCode(value):
  7. if value:
  8. return "true"
  9. return "false"
  10. def makeCLiteral(value):
  11. return value.replace('\\', r'\\\\').replace('\n', r'\\n').replace('\r', r'')
  12. def splitStringLiterals(value, splitLength=500, max_string_length=0):
  13. """
  14. Split a string literal longer than splitLength into smaller literals.
  15. E.g. "Some very long text" will be split into "Some ver" "y long te" "xt"
  16. On VS2008 there is a maximum allowed length of a single string literal.
  17. If maxLength is set and the string is longer than maxLength, then an
  18. empty string will be returned.
  19. """
  20. value = value.strip()
  21. if max_string_length > 0 and len(value) > max_string_length:
  22. logger.info("String is longer than {}. Returning empty string.".format(max_string_length))
  23. return "\"\""
  24. if len(value) < splitLength or splitLength == 0:
  25. return "\"" + value.replace('"', r'\"') + "\""
  26. ret = ""
  27. tmp = value
  28. while len(tmp) > splitLength:
  29. ret += "\"" + tmp[:splitLength].replace('"', r'\"') + "\" "
  30. tmp = tmp[splitLength:]
  31. ret += "\"" + tmp.replace('"', r'\"') + "\" "
  32. return ret
  33. def generateStringCode(value, alloc=False, max_string_length=0):
  34. value = makeCLiteral(value)
  35. return u"UA_STRING{}({})".format("_ALLOC" if alloc else "", splitStringLiterals(value, max_string_length=max_string_length))
  36. def generateXmlElementCode(value, alloc=False, max_string_length=0):
  37. value = makeCLiteral(value)
  38. return u"UA_XMLELEMENT{}({})".format("_ALLOC" if alloc else "", splitStringLiterals(value, max_string_length=max_string_length))
  39. def generateByteStringCode(value, alloc=False, max_string_length=0):
  40. value = makeCLiteral(value)
  41. return u"UA_BYTESTRING{}({})".format("_ALLOC" if alloc else "", splitStringLiterals(value, max_string_length=max_string_length))
  42. def generateLocalizedTextCode(value, alloc=False, max_string_length=0):
  43. vt = makeCLiteral(value.text)
  44. return u"UA_LOCALIZEDTEXT{}(\"{}\", {})".format("_ALLOC" if alloc else "", value.locale,
  45. splitStringLiterals(vt, max_string_length=max_string_length))
  46. def generateQualifiedNameCode(value, alloc=False, max_string_length=0):
  47. vn = makeCLiteral(value.name)
  48. return u"UA_QUALIFIEDNAME{}(ns[{}], {})".format("_ALLOC" if alloc else "",
  49. str(value.ns), splitStringLiterals(vn, max_string_length=max_string_length))
  50. def generateNodeIdCode(value):
  51. if not value:
  52. return "UA_NODEID_NUMERIC(0, 0)"
  53. if value.i != None:
  54. return "UA_NODEID_NUMERIC(ns[%s], %s)" % (value.ns, value.i)
  55. elif value.s != None:
  56. v = makeCLiteral(value.s)
  57. return u"UA_NODEID_STRING(ns[%s], \"%s\")" % (value.ns, v)
  58. raise Exception(str(value) + " no NodeID generation for bytestring and guid..")
  59. def generateExpandedNodeIdCode(value):
  60. if value.i != None:
  61. return "UA_EXPANDEDNODEID_NUMERIC(ns[%s], %s)" % (str(value.ns), str(value.i))
  62. elif value.s != None:
  63. vs = makeCLiteral(value.s)
  64. return u"UA_EXPANDEDNODEID_STRING(ns[%s], \"%s\")" % (str(value.ns), vs)
  65. raise Exception(str(value) + " no NodeID generation for bytestring and guid..")
  66. def generateDateTimeCode(value):
  67. epoch = datetime.datetime.utcfromtimestamp(0)
  68. mSecsSinceEpoch = int((value - epoch).total_seconds() * 1000.0)
  69. return "( (UA_DateTime)(" + str(mSecsSinceEpoch) + " * UA_DATETIME_MSEC) + UA_DATETIME_UNIX_EPOCH)"
  70. def generateNodeValueCode(node, instanceName, asIndirect=False, max_string_length=0):
  71. if type(node) in [Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Float, Double]:
  72. return "(UA_" + node.__class__.__name__ + ") " + str(node.value)
  73. elif type(node) == String:
  74. return generateStringCode(node.value, alloc=asIndirect, max_string_length=max_string_length)
  75. elif type(node) == XmlElement:
  76. return generateXmlElementCode(node.value, alloc=asIndirect, max_string_length=max_string_length)
  77. elif type(node) == ByteString:
  78. # replace whitespaces between tags and remove newlines
  79. return "UA_BYTESTRING_NULL" if not node.value else generateByteStringCode(re.sub(r">\s*<", "><", re.sub(r"[\r\n]+", "", node.value)), alloc=asIndirect, max_string_length=max_string_length)
  80. elif type(node) == LocalizedText:
  81. return generateLocalizedTextCode(node, alloc=asIndirect, max_string_length=max_string_length)
  82. elif type(node) == NodeId:
  83. return generateNodeIdCode(node)
  84. elif type(node) == ExpandedNodeId:
  85. return generateExpandedNodeIdCode(node)
  86. elif type(node) == DateTime:
  87. return generateDateTimeCode(node.value)
  88. elif type(node) == QualifiedName:
  89. return generateQualifiedNameCode(node.value, alloc=asIndirect, max_string_length=max_string_length)
  90. elif type(node) == StatusCode:
  91. raise Exception("generateNodeValueCode for type " + node.__class__.name + " not implemented")
  92. elif type(node) == DiagnosticInfo:
  93. raise Exception("generateNodeValueCode for type " + node.__class__.name + " not implemented")
  94. elif type(node) == Guid:
  95. raise Exception("generateNodeValueCode for type " + node.__class__.name + " not implemented")
  96. elif type(node) == ExtensionObject:
  97. if asIndirect == False:
  98. return "*" + str(instanceName)
  99. return str(instanceName)