2 Generate address space c++ code from xml file specification 7 import xml.etree.ElementTree
as ET
9 from IPython
import embed
14 NotRequest = [
"MonitoredItemCreateRequest",
"MonitoredItemModifyRequest",
"CallMethodRequest"]
20 InheritExtensionObjects = [
"UserIdentityToken",
"NodeAttributes"]
52 raise Exception(
"field not found: " + name)
76 if self.
uatype in (
"Char",
"SByte",
"Int8",
"Int16",
"Int32",
"Int64",
"UInt8",
"UInt16",
"UInt32",
"UInt64",
"Boolean",
"Double",
"Float",
"Byte",
"String",
"CharArray",
"ByteString",
"DateTime"):
81 if self.
uatype ==
"String":
83 elif self.
uatype ==
"CharArray":
85 elif self.
uatype ==
"Char":
87 elif self.
uatype ==
"SByte":
89 elif self.
uatype ==
"Int8":
91 elif self.
uatype ==
"Int16":
93 elif self.
uatype ==
"Int32":
95 elif self.
uatype ==
"Int64":
97 elif self.
uatype ==
"UInt8":
99 elif self.
uatype ==
"UInt16":
101 elif self.
uatype ==
"UInt32":
103 elif self.
uatype ==
"UInt64":
105 elif self.
uatype ==
"DateTime":
106 ty =
"OpcUa::DateTime" 107 elif self.
uatype ==
"Boolean":
109 elif self.
uatype ==
"Double":
111 elif self.
uatype ==
"Float":
113 elif self.
uatype ==
"ByteString":
114 ty =
"OpcUa::ByteString" 115 elif self.
uatype ==
"Byte":
118 ty =
"OpcUa::" + self.
uatype 120 ty =
"std::vector<{}>".
format(ty)
131 return "{}_t".
format(self.uatype.lower())
148 if name == struct.name:
150 raise Exception(
"No struct named: " + str(name))
156 raise Exception(
"No enum named: " + str(name))
160 for struct
in model.structs:
163 for field
in struct.fields:
164 if field.name
not in names:
165 names.append(field.name)
167 struct.fields = fields
171 for struct
in model.structs:
175 for field
in struct.fields:
176 if field.uatype
in (
"UInt6",
"NodeIdType"):
177 container = field.name
181 b.container = container
184 struct.bits[b.name] = b
186 if field.uatype ==
"Bit":
187 if not container
or idx > 7:
188 container =
"Encoding" 191 f.sourcetype = field.sourcetype
199 b.container = container
200 b.length = field.bitlength
201 idx += field.bitlength
202 struct.bits[b.name] = b
204 newfields.append(field)
205 struct.fields = newfields
208 for struct
in model.structs:
210 for field
in struct.fields:
211 if not field.name.startswith(
"NoOf"):
216 for struct
in model.structs:
218 for field
in struct.fields:
219 if not field.name ==
"BodyLength":
230 for struct
in model.structs:
232 if struct.name.endswith(
"Request")
and not struct.name
in NotRequest:
233 structtype =
"Request" 234 elif struct.name.endswith(
"Response")
or struct.name ==
"ServiceFault":
235 structtype =
"Response" 245 struct.isrequest =
True 246 struct.needconstructor =
True 248 field.name =
"TypeId" 249 field.uatype =
"NodeId" 250 struct.fields.insert(0, field)
252 if structtype
and not struct.name
in NoSplitStruct:
254 if structtype ==
"Request":
255 basename = struct.name.replace(
"Request",
"") +
"Parameters" 256 paramstruct.name = basename
258 basename = struct.name.replace(
"Response",
"") +
"Result" 259 paramstruct.name = basename
260 paramstruct.fields = struct.fields[2:]
261 paramstruct.bits = struct.bits
263 struct.fields = struct.fields[:2]
265 structs.append(paramstruct)
268 typeid.name =
"Parameters" 269 typeid.uatype = paramstruct.name
270 struct.fields.append(typeid)
271 structs.append(struct)
272 model.structs = structs
273 model.struct_list = [s.name
for s
in model.structs]
284 tree = ET.parse(self.
path)
285 root = tree.getroot()
289 if tag ==
"StructuredType":
291 if struct.name !=
"ExtensionObject":
292 self.model.structs.append(struct)
293 self.model.struct_list.append(struct.name)
294 elif tag ==
"EnumeratedType":
296 self.model.enums.append(enum)
297 self.model.enum_list.append(enum.name)
304 obj.name =
"ExtensionObject" 310 f.name =
"BinaryBody" 319 f.uatype =
"ByteString" 320 f.switchfield =
"BinaryBody" 322 self.model.struct_list.append(obj.name)
324 self.model.structs.append(obj)
329 for key, val
in child.attrib.items():
332 elif key ==
"BaseType":
334 prefix, val = val.split(
":")
335 struct.basetype = val
338 struct.parents.append(tmp.basetype)
339 tmp = self.model.get_struct(tmp.basetype)
341 print(
"Error unknown key: ", key)
346 for key, val
in el.attrib.items():
349 elif key ==
"TypeName":
350 field.uatype = val.split(
":")[1]
351 elif key ==
"LengthField":
353 elif key ==
"SourceType":
354 field.sourcetype = val
355 elif key ==
"SwitchField":
356 field.switchfield = val
357 elif key ==
"SwitchValue":
358 field.switchvalue = val
359 elif key ==
"Length":
360 field.bitlength = int(val)
362 print(
"Uknown field item: ", struct.name, key)
364 struct.fields.append(field)
365 elif tag ==
"Documentation":
368 print(
"Uknown tag: ", tag)
375 for k, v
in child.items():
378 elif k ==
"LengthInBits":
379 enum.uatype =
"UInt" + v
381 print(
"Unknown attr for enum: ", k)
384 if tag ==
"EnumeratedValue":
386 for k, v
in el.attrib.items():
392 print(
"Uknown field attrib: ", k)
393 enum.values.append(ev)
394 elif tag ==
"Documentation":
397 print(
"Unknown enum tag: ", tag)
409 for struct
in model.structs:
410 if not struct.basetype:
413 if len(struct.fields) == 0:
415 if not emptystruct
and struct.basetype
in (
"ExtensionObject")
and not struct.name
in InheritExtensionObjects:
417 struct.parents.remove(struct.basetype)
418 struct.basetype =
None 420 base = model.get_struct(struct.basetype)
431 for name, bit
in base.bits.items():
432 struct.bits[name] = bit
433 for idx, field
in enumerate(base.fields):
435 if field.name ==
"Body" and not emptystruct:
437 struct.extensionobject =
True 438 field.name =
"BodyLength" 439 field.uatype =
"Int32" 441 field.switchfield =
None 453 if not field.sourcetype:
454 field.sourcetype = base.name
455 struct.fields.insert(idx, field)
def parse_enum(self, child)
def remove_duplicates(model)
FMT_API void print(std::FILE *f, CStringRef format_str, ArgList args)
def add_basetype_members(model)
std::string format(CStringRef format_str, ArgList args)
def get_struct(self, name)
def remove_body_length(model)
def add_encoding_field(model)
def remove_vector_length(model)
def split_requests(model, NoSplitStruct)
def parse_struct(self, child)
def add_extension_object(self)
def get_field(self, name)