generate_protocol.py
Go to the documentation of this file.
00001 """
00002 Generate address space c++ code from xml file specification
00003 """
00004 import sys
00005 from copy import copy
00006 
00007 import xml.etree.ElementTree as ET
00008 
00009 from IPython import embed
00010 
00011 import generate_model as gm
00012 
00013 
00014 #declare default constructor in header, then constructor must be implemented
00015 NeedConstructor = ["RelativePathElement", "OpenSecureChannelParameters", "UserIdentityToken", "RequestHeader", "ResponseHeader", "ReadParameters", "UserIdentityToken", "BrowseDescription", "ReferenceDescription", "CreateSubscriptionParameters", "SubscriptionData", "NotificationMessage", "PublishResult", "PublishResult", "NotificationMessage", "SetPublishingModeParameters"]
00016 IgnoredEnums = ["IdType", "NodeIdType"]
00017 #by default we split requests and respons in header and parameters, but some are so simple we do not split them
00018 NoSplitStruct = ["GetEndpointsResponse", "CloseSessionRequest", "AddNodesResponse", "BrowseResponse", "HistoryReadResponse", "HistoryUpdateResponse", "RegisterServerResponse", "CloseSecureChannelRequest", "CloseSecureChannelResponse", "CloseSessionRequest", "CloseSessionResponse", "UnregisterNodesResponse", "MonitoredItemModifyRequest", "MonitoredItemsCreateRequest", "ReadResponse", "WriteResponse", "TranslateBrowsePathsToNodeIdsResponse", "DeleteSubscriptionsResponse", "DeleteMonitoredItemsResponse", "PublishRequest", "CreateMonitoredItemsResponse", "DeleteMonitoredItemsResponse", "ServiceFault", "AddReferencesRequest", "AddReferencesResponse", "ModifyMonitoredItemsResponse", "CallRequest", "CallResponse", "RepublishResponse", "DeleteSubscriptionsRequest", "DeleteSubscriptionsResponse", "DeleteNodesRequest", "DeleteNodesResponse"]
00019 OverrideTypes = {"AttributeId": "AttributeId",  "ResultMask": "BrowseResultMask", "NodeClassMask": "NodeClass", "AccessLevel": "VariableAccessLevel", "UserAccessLevel": "VariableAccessLevel", "NotificationData": "NotificationData"}
00020 OverrideStructTypeName = {"CreateSubscriptionResult": "SubscriptionData", "SetPublishingModeParameters": "PublishingModeParameters", "SetPublishingModeResult": "PublishingModeResult", "CreateMonitoredItemsParameters": "MonitoredItemsParameters"}
00021 OverrideNameInStruct = {"CreateSubscriptionResponse": {"Parameters": "Data"}, "SetPublishingModeResponse": {"Parameters": "Result"}}
00022 OverrideTypeInStruct = {"ActivateSessionParameters": {"UserIdentityToken": "UserIdentifyToken"}, "MonitoringParameters": {"Filter": "MonitoringFilter"}, "MonitoredItemCreateResult": {"FilterResult": "MonitoringFilter"}}
00023 OverrideNames = {"RequestHeader": "Header", "ResponseHeader": "Header", "StatusCode": "Status", "NodesToRead": "AttributesToRead"} # "MonitoringMode": "Mode",, "NotificationMessage": "Notification", "NodeIdType": "Type"}
00024 
00025 #list of UA structure we want to enable, some structures may
00026 #need to be added by hand (those generated from splitted request and response structs)
00027 EnabledStructs = [\
00028     #we want to implement som struct by hand, to make better interface or simply because they are too complicated
00029     #'NodeId',
00030     #'TwoByteNodeId',
00031     #'FourByteNodeId',
00032     #'NumericNodeId',
00033     #'StringNodeId',
00034     #'GuidNodeId',
00035     #'ByteStringNodeId',
00036     #'ExpandedNodeId',
00037     #'QualifiedName',
00038     #'LocalizedText',
00039     #'DataValue',
00040     #'Variant',
00041     #'DiagnosticInfo',
00042     #
00043     #
00044     #structs we should enable or that we haven't checked yet
00045     #
00046     'ExtensionObject',
00047     'XmlElement',
00048     #'Node',
00049     #'InstanceNode',
00050     #'TypeNode',
00051     #'ObjectNode',
00052     #'ObjectTypeNode',
00053     #'VariableNode',
00054     #'VariableTypeNode',
00055     #'ReferenceTypeNode',
00056     #'MethodNode',
00057     #'ViewNode',
00058     #'DataTypeNode',
00059     #'ReferenceNode',
00060     #'Argument',
00061     #'EnumValueType',
00062     #'TimeZoneDataType',
00063     'ApplicationDescription',
00064     #'RequestHeader',
00065     #'ResponseHeader',
00066     #'ServiceFault',
00067     #'FindServersRequest',
00068     #'FindServersResponse',
00069     'UserTokenPolicy',
00070     'EndpointDescription',
00071     'GetEndpointsRequest',
00072     'GetEndpointsParameters',
00073     'GetEndpointsResponse',
00074     #'RegisteredServer',
00075     #'RegisterServerRequest',
00076     #'RegisterServerResponse',
00077     #'ChannelSecurityToken',
00078     #'OpenSecureChannelRequest',
00079     #'OpenSecureChannelResponse',
00080     #'CloseSecureChannelRequest',
00081     #'CloseSecureChannelResponse',
00082     'SignedSoftwareCertificate',
00083     'SignatureData',
00084     'CreateSessionRequest',
00085     'CreateSessionParameters',
00086     'CreateSessionResponse',
00087     'CreateSessionResult',
00088     #'UserIdentityToken',
00089     #'AnonymousIdentityToken',
00090     #'UserNameIdentityToken',
00091     #'X509IdentityToken',
00092     #'IssuedIdentityToken',
00093     'ActivateSessionRequest',
00094     'ActivateSessionParameters',
00095     'ActivateSessionResponse',
00096     'ActivateSessionResult',
00097     #'CloseSessionRequest',
00098     #'CloseSessionResponse',
00099     #'CancelRequest',
00100     #'CancelResponse',
00101     #'NodeAttributes',
00102     #'ObjectAttributes',
00103     #'VariableAttributes',
00104     #'MethodAttributes',
00105     #'ObjectTypeAttributes',
00106     #'VariableTypeAttributes',
00107     #'ReferenceTypeAttributes',
00108     #'DataTypeAttributes',
00109     #'ViewAttributes',
00110     #'AddNodesItem',
00111     #'AddNodesResult',
00112     #'AddNodesRequest',
00113     #'AddNodesResponse',
00114     #'AddReferencesItem',
00115     #'AddReferencesRequest',
00116     #'AddReferencesResponse',
00117     'DeleteNodesItem',
00118     'DeleteNodesRequest',
00119     'DeleteNodesResponse',
00120     #'DeleteReferencesItem',
00121     #'DeleteReferencesRequest',
00122     #'DeleteReferencesResponse',
00123     #'ViewDescription',
00124     #'BrowseDescription',
00125     #'ReferenceDescription',
00126     #'BrowseResult',
00127     #'BrowseRequest',
00128     #'BrowseResponse',
00129     #'BrowseNextRequest',
00130     #'BrowseNextResponse',
00131     #'RelativePathElement',
00132     #'RelativePath',
00133     #'BrowsePath',
00134     #'BrowsePathTarget',
00135     #'BrowsePathResult',
00136     #'TranslateBrowsePathsToNodeIdsRequest',
00137     #'TranslateBrowsePathsToNodeIdsResponse',
00138     #'RegisterNodesRequest',
00139     #'RegisterNodesResponse',
00140     #'UnregisterNodesRequest',
00141     #'UnregisterNodesResponse',
00142     #'EndpointConfiguration',
00143     #'SupportedProfile',
00144     #'SoftwareCertificate',
00145     #'QueryDataDescription',
00146     #'NodeTypeDescription',
00147     #'QueryDataSet',
00148     #'NodeReference',
00149     #'ContentFilterElement',
00150     #'ContentFilter',
00151     #'FilterOperand',
00152     #'ElementOperand',
00153     #'LiteralOperand',
00154     #'AttributeOperand',
00155     #'SimpleAttributeOperand',
00156     #'ContentFilterElementResult',
00157     #'ContentFilterResult',
00158     #'ParsingResult',
00159     #'QueryFirstRequest',
00160     #'QueryFirstResponse',
00161     #'QueryNextRequest',
00162     #'QueryNextResponse',
00163     'ReadValueId',
00164     'ReadRequest',
00165     'ReadParameters',
00166     'ReadResult',
00167     'ReadResponse',
00168     #'HistoryReadValueId',
00169     #'HistoryReadResult',
00170     #'HistoryReadDetails',
00171     #'ReadEventDetails',
00172     #'ReadRawModifiedDetails',
00173     #'ReadProcessedDetails',
00174     #'ReadAtTimeDetails',
00175     #'HistoryData',
00176     #'ModificationInfo',
00177     #'HistoryModifiedData',
00178     #'HistoryEvent',
00179     #'HistoryReadRequest',
00180     #'HistoryReadResponse',
00181     'WriteValue',
00182     'WriteParameters',
00183     'WriteRequest',
00184     'WriteResponse',
00185     'WriteResult',
00186     #'HistoryUpdateDetails',
00187     #'UpdateDataDetails',
00188     #'UpdateStructureDataDetails',
00189     #'UpdateEventDetails',
00190     #'DeleteRawModifiedDetails',
00191     #'DeleteAtTimeDetails',
00192     #'DeleteEventDetails',
00193     #'HistoryUpdateResult',
00194     #'HistoryUpdateEventResult',
00195     #'HistoryUpdateRequest',
00196     #'HistoryUpdateResponse',
00197     'CallMethodRequest',
00198     'CallMethodResult',
00199     'CallRequest',
00200     'CallResponse',
00201     #'MonitoringFilter',
00202     #'DataChangeFilter',
00203     #'EventFilter',
00204     #'AggregateConfiguration',
00205     #'AggregateFilter',
00206     #'MonitoringFilterResult',
00207     #'EventFilterResult',
00208     #'AggregateFilterResult',
00209     'MonitoringParameters',
00210     'MonitoredItemCreateRequest',
00211     'MonitoredItemCreateResult',
00212     'MonitoredItemsParameters',
00213     'CreateMonitoredItemsRequest',
00214     'CreateMonitoredItemsResponse',
00215     #'MonitoredItemModifyRequest',
00216     #'MonitoredItemModifyResult',
00217     #'ModifyMonitoredItemsRequest',
00218     #'ModifyMonitoredItemsResponse',
00219     #'SetMonitoringModeRequest',
00220     #'SetMonitoringModeResponse',
00221     #'SetTriggeringRequest',
00222     #'SetTriggeringResponse',
00223     'DeleteMonitoredItemsParameters',
00224     'DeleteMonitoredItemsRequest',
00225     'DeleteMonitoredItemsResponse',
00226     'CreateSubscriptionRequest',
00227     'CreateSubscriptionParameters',
00228     'SubscriptionData',
00229     'CreateSubscriptionResponse',
00230     #'ModifySubscriptionRequest',
00231     #'ModifySubscriptionResponse',
00232     'SetPublishingModeRequest',
00233     'PublishingModeParameters',
00234     'SetPublishingModeResponse',
00235     'PublishingModeResult',
00236     'NotificationMessage',
00237     #'NotificationData',
00238     #'DataChangeNotification',
00239     #'MonitoredItemNotification',
00240     #'EventNotificationList',
00241     #'EventFieldList',
00242     #'HistoryEventFieldList',
00243     #'StatusChangeNotification',
00244     'SubscriptionAcknowledgement',
00245     'PublishRequest',
00246     'PublishResult',
00247     'PublishResponse',
00248     'RepublishParameters',
00249     'RepublishRequest',
00250     'RepublishResponse',
00251     #'TransferResult',
00252     #'TransferSubscriptionsRequest',
00253     #'TransferSubscriptionsResponse',
00254     'DeleteSubscriptionsRequest',
00255     'DeleteSubscriptionsResponse',
00256     #'ScalarTestType',
00257     #'ArrayTestType',
00258     #'CompositeTestType',
00259     #'TestStackRequest',
00260     #'TestStackResponse',
00261     #'TestStackExRequest',
00262     #'TestStackExResponse',
00263     #'BuildInfo',
00264     #'RedundantServerDataType',
00265     #'EndpointUrlListDataType',
00266     #'NetworkGroupDataType',
00267     #'SamplingIntervalDiagnosticsDataType',
00268     #'ServerDiagnosticsSummaryDataType',
00269     #'ServerStatusDataType',
00270     #'SessionDiagnosticsDataType',
00271     #'SessionSecurityDiagnosticsDataType',
00272     #'ServiceCounterDataType',
00273     #'StatusResult',
00274     #'SubscriptionDiagnosticsDataType',
00275     #'ModelChangeStructureDataType',
00276     #'SemanticChangeStructureDataType',
00277     #'Range',
00278     #'EUInformation',
00279     #'ComplexNumberType',
00280     #'DoubleComplexNumberType',
00281     #'AxisInformation',
00282     #'XVType',
00283     #'ProgramDiagnosticDataType',
00284     'Annotation']
00285 
00286 
00287 def reorder_structs(model):
00288     types = IgnoredEnums + ["Bit", "Char", "CharArray", "Guid", "SByte", "Int8", "Int16", "Int32", "Int64", "UInt8", "UInt16", "UInt32", "UInt64", "DateTime", "Boolean", "Double", "Float", "ByteString", "Byte", "StatusCode", "DiagnosticInfo", "String", "AttributeId"] + [enum.name for enum in model.enums] + ["VariableAccessLevel"]
00289     waiting = {}
00290     newstructs = []
00291     for s in model.structs:
00292         types.append(s.name)
00293         s.waitingfor = []
00294         ok = True
00295         for f in s.fields:
00296             if f.uatype not in types:
00297                 if f.uatype in waiting.keys():
00298                     waiting[f.uatype].append(s)
00299                     s.waitingfor.append(f.uatype)
00300                 else:
00301                     waiting[f.uatype] = [s]
00302                     s.waitingfor.append(f.uatype)
00303                 ok = False
00304         if ok:
00305             newstructs.append(s)
00306             waitings = waiting.pop(s.name, None)
00307             if waitings:
00308                 for s2 in waitings:
00309                     s2.waitingfor.remove(s.name)
00310                     if not s2.waitingfor:
00311                         newstructs.append(s2)
00312     if len(model.structs) != len(newstructs):
00313         print("Error while reordering structs, some structs could not be reinserted, had {} structs, we now have {} structs".format(len(model.structs), len(newstructs)))
00314         s1 = set(model.structs)
00315         s2 = set(newstructs)
00316         rest = s1 -s2
00317         print("Variant" in types)
00318         for s in s1-s2:
00319             print("{} is waiting for: {}".format(s, s.waitingfor))
00320         #print(s1 -s2)
00321         #print(waiting)
00322     model.structs = newstructs
00323 
00324 
00325 def override_types(model):
00326     for struct in model.structs:
00327         for field in struct.fields:
00328             if field.name in OverrideTypes.keys():
00329                 field.uatype = OverrideTypes[field.name]
00330 
00331             if struct.name in OverrideNameInStruct.keys():
00332                 if field.name in OverrideNameInStruct[struct.name].keys():
00333                     field.name = OverrideNameInStruct[struct.name][field.name]
00334 
00335             if struct.name in OverrideTypeInStruct.keys():
00336                 if field.name in OverrideTypeInStruct[struct.name].keys():
00337                     field.uatype = OverrideTypeInStruct[struct.name][field.name]
00338 
00339             if field.uatype in OverrideStructTypeName.keys():
00340                 field.uatype = OverrideStructTypeName[field.uatype]
00341 
00342         if struct.name in OverrideStructTypeName.keys():
00343             struct.name = OverrideStructTypeName[struct.name]
00344 
00345 
00346 class CodeGenerator(object):
00347     def __init__(self, model, h_path, enum_path, size_path, ser_path, deser_path, const_path):
00348         self.model = model
00349         self.h_path = h_path
00350         self.enum_path = enum_path
00351         self.rawsize_path = size_path
00352         self.serialize_path = ser_path
00353         self.deserialize_path = deser_path
00354         self.constructors_path = const_path
00355         self.h_file = None
00356         self.cpp_file = None
00357         self.structs = []
00358 
00359     def run(self):
00360         #sys.stderr.write("Generating header file {} and C++ files for XML file {}".format(self.h_path, self.input_path) + "\n")
00361         print("Generating: ", self.h_path)
00362         self.h_file = open(self.h_path, "w")
00363         print("Generating: ", self.enum_path)
00364         self.enum_file = open(self.enum_path, "w")
00365         print("Generating: ", self.rawsize_path)
00366         self.rawsize_file = open(self.rawsize_path, "w")
00367         print("Generating: ", self.serialize_path)
00368         self.serialize_file = open(self.serialize_path, "w")
00369         print("Generating: ", self.deserialize_path)
00370         self.deserialize_file = open(self.deserialize_path, "w")
00371         print("Generating: ", self.constructors_path)
00372         self.constructors_file = open(self.constructors_path, "w")
00373 
00374         self.make_header_h()
00375         self.make_header_enum()
00376         self.make_header_rawsize()
00377         self.make_header_serialize()
00378         self.make_header_deserialize()
00379         self.make_header_constructors()
00380 
00381         for enum in self.model.enums:
00382             if not enum.name in IgnoredEnums:
00383                 self.make_enum_h(enum)
00384                 self.make_struct_ser(enum)
00385         for struct in self.model.structs:
00386             self.rename_fields(struct)
00387             if struct.name in NeedConstructor:
00388                 struct.needconstructor = True
00389             #if not struct.name.endswith("Node") and not struct.name.endswith("NodeId"):
00390             if not struct.name in EnabledStructs:
00391                 self.write_h("\n/* DISABLED")
00392                 self.write_size("\n/* DISABLED")
00393                 self.write_ser("\n/*  DISABLED")
00394                 self.write_deser("\n/*  DISABLED")
00395                 if struct.needconstructor:
00396                     self.write_const("\n/*  DISABLED")
00397             self.make_struct_h(struct)
00398             self.make_struct_ser(struct)
00399             if struct.isrequest:
00400                 self.make_request_constructors(struct)
00401             if not struct.name in EnabledStructs:
00402                 self.write_h("*/")
00403                 self.write_size("*/")
00404                 self.write_ser("*/")
00405                 self.write_deser("*/")
00406                 if struct.needconstructor:
00407                     self.write_const("*/")
00408 
00409         self.make_footer_h()
00410         self.make_footer_enum()
00411         self.make_footer_rawsize()
00412         self.make_footer_serialize()
00413         self.make_footer_deserialize()
00414         self.make_footer_constructors()
00415 
00416     def rename_fields(self, struct):
00417         ##gcc does not want member with same name as a type
00418         for field in struct.fields:
00419             if field.name in OverrideNames:
00420                 field.name = OverrideNames[field.name]
00421             #else:
00422                 #print("Error name same as type: ", field.name, field.get_ctype(), field.uatype)
00423 
00424     def make_struct_h(self, struct):
00425         self.write_h("")
00426         if struct.doc: self.write_h("    //", struct.doc)
00427         name = struct.name
00428         base = ""
00429         #if struct.basetype:
00430             #base = " : public " + struct.basetype
00431         self.write_h("    struct %s %s\n    {""" % (name, base))
00432         for field in struct.fields:
00433             #if field.sourcetype:
00434                 #continue
00435 
00436             if field.get_ctype() == "OpcUa::" + struct.name:
00437                 #we have a problem selv referensing struct
00438                 self.write_h("         std::shared_ptr<{}> {};".format(field.get_ctype(), field.name))
00439             else:
00440                 self.write_h("        " , field.get_ctype(), field.name + ";")
00441         if struct.needconstructor:
00442             self.write_h("\n        ", struct.name + "();")
00443 
00444         self.write_h("    };")
00445 
00446     def make_raw_size(self, struct):
00447         self.write_size("")
00448         self.write_size("    template<>")
00449         self.write_size("    std::size_t RawSize<{}>(const {}& data)".format(struct.name, struct.name))
00450         self.write_size("    {")
00451 
00452         if type(struct) == gm.Enum:
00453             self.write_size("        return sizeof({});".format(struct.get_ctype()))
00454         else:
00455             self.write_size("        size_t size = 0;")
00456             for field in struct.fields:
00457                 switch = ""
00458                 if field.switchfield:
00459                     if field.switchvalue:
00460                         switch = "if ((data.{}) & (1<<({}))) ".format(field.switchfield, field.switchvalue)
00461                     else:
00462                         container = struct.bits[field.switchfield].container
00463                         idx = struct.bits[field.switchfield].idx
00464                         switch = "if ((data.{}) & (1<<({}))) ".format(container, idx)
00465                 prefix = ""
00466                 if field.get_ctype() == struct.name:
00467                     prefix = "*"
00468                 if field.length:
00469                     self.write_size("        {}size += RawSizeContainer({}data.{});".format(switch, prefix, field.name))
00470                 else:
00471                     self.write_size("        {}size += RawSize({}data.{});".format(switch, prefix, field.name))
00472             self.write_size("        return size;")
00473         self.write_size("    }")
00474         self.write_size("")
00475 
00476     def make_serialize(self, struct):
00477         self.write_ser("")
00478         self.write_ser("    template<>")
00479         self.write_ser("    void DataSerializer::Serialize<{}>(const {}& data)".format(struct.name, struct.name))
00480         self.write_ser("    {")
00481         if type(struct) == gm.Enum:
00482             self.write_ser("        *this << static_cast<{}>(data);".format(struct.get_ctype()))
00483         else:
00484             for idx, field in enumerate(struct.fields):
00485                 if field.name == "Body" and idx != (len(struct.fields) - 1):
00486                     self.write_ser("        int32_t bodylength = RawSize(data) - RawSize(data.Encoding);")
00487                     self.write_ser("        if ((data.Encoding) & (1<<(0))) bodylength -= RawSize(data.TypeId);")
00488                     self.write_ser("        *this << bodylength;")
00489                     continue
00490 
00491                 switch = ""
00492                 if field.switchfield:
00493                     if field.switchvalue:
00494                         switch = "if ((data.{}) & (1<<({}))) ".format(field.switchfield, field.switchvalue)
00495                     else:
00496                         container = struct.bits[field.switchfield].container
00497                         idx = struct.bits[field.switchfield].idx
00498                         switch = "if ((data.{}) & (1<<({}))) ".format(container, idx)
00499                 prefix = ""
00500                 if field.get_ctype() == struct.name:
00501                     prefix = "*"
00502                 if field.length:
00503                     self.write_ser("        {}SerializeContainer(*this, {}data.{});".format(switch, prefix, field.name))
00504                 else:
00505                     self.write_ser("        {}*this << {}data.{};".format(switch, prefix, field.name))
00506         self.write_ser("    }")
00507         self.write_ser("")
00508 
00509     def make_deserialize(self, struct):
00510         self.write_deser("")
00511         self.write_deser("    template<>")
00512         self.write_deser("    void DataDeserializer::Deserialize<{}>({}& data)".format(struct.name, struct.name))
00513         self.write_deser("    {")
00514         if type(struct) == gm.Enum:
00515             self.write_deser("        {} tmp;".format(struct.get_ctype()))
00516             self.write_deser("        *this >> tmp;")
00517             #self.write_deser("        data = static_cast<{}>(tmp);".format(struct.get_ctype()))
00518             self.write_deser("        data = static_cast<{}>(tmp);".format(struct.name))
00519         else:
00520             for idx, field in enumerate(struct.fields):
00521                 if field.name == "Body" and idx != (len(struct.fields) - 1):
00522                     self.write_deser("        int32_t tmp; //Not used")
00523                     self.write_deser("        *this >> tmp;")
00524                     continue
00525                 switch = ""
00526                 if field.switchfield:
00527                     if field.switchvalue:
00528                         switch = "if ((data.{}) & (1>>({}))) ".format(field.switchfield, field.switchvalue)
00529                     else:
00530                         container = struct.bits[field.switchfield].container
00531                         idx = struct.bits[field.switchfield].idx
00532                         switch = "if ((data.{}) & (1>>({}))) ".format(container, idx)
00533                 if field.length:
00534                     self.write_deser("        {}DeserializeContainer(*this, data.{});".format(switch, field.name))
00535                 else:
00536                     self.write_deser("        {}*this >> data.{};".format(switch, field.name))
00537         self.write_deser("    }")
00538         self.write_deser("")
00539 
00540     def make_request_constructors(self, struct):
00541         if not struct.needconstructor:
00542             return
00543         self.write_const("")
00544         self.write_const("    ", struct.name + "::" + struct.name + "()")
00545         #self.write_const("        : TypeId(ObjectId::" + struct.name +"_Encoding_DefaultBinary)")
00546         self.write_const("        : TypeId(FourByteNodeId((uint16_t)ObjectId::" + struct.name +"_Encoding_DefaultBinary))")
00547         self.write_const("    {")
00548         self.write_const("    }")
00549 
00550     def make_struct_ser(self, struct):
00551         self.make_raw_size(struct)
00552         self.make_serialize(struct)
00553         self.make_deserialize(struct)
00554 
00555     def make_enum_h(self, enum):
00556         self.write_enum("\n")
00557         if enum.doc: self.write_enum("    //", enum.doc)
00558         self.write_enum("    enum class %s : %s\n    {" % (enum.name, self.to_enum_type(enum.uatype)))
00559         for val in enum.values:
00560             self.write_enum("        ", val.name, "=", val.value + ",")
00561         self.write_enum("    };")
00562         #if enum.name.endswith("Mask"):
00563         self.write_enum("""    inline {name} operator|({name} a, {name} b) {{ return static_cast<{name}>(static_cast<{type}>(a) | static_cast<{type}>(b)); }}""".format(name=enum.name, type=self.to_enum_type(enum.uatype)))
00564         self.write_enum("""    inline {name} operator&({name} a, {name} b) {{ return static_cast<{name}>(static_cast<{type}>(a) & static_cast<{type}>(b)); }}""".format(name=enum.name, type=self.to_enum_type(enum.uatype)))
00565 
00566 
00567     def to_enum_type(self, val):
00568         #if val == "6":
00569             #val = "8"
00570         return "{}_t".format(val.lower())
00571 
00572     def write_h(self, *args):
00573         self.h_file.write(" ".join(args) + "\n")
00574 
00575     def write_enum(self, *args):
00576         self.enum_file.write(" ".join(args) + "\n")
00577 
00578     def write_ser(self, *args):
00579         self.serialize_file.write(" ".join(args) + "\n")
00580 
00581     def write_size(self, *args):
00582         self.rawsize_file.write(" ".join(args) + "\n")
00583 
00584     def write_deser(self, *args):
00585         self.deserialize_file.write(" ".join(args) + "\n")
00586 
00587     def write_const(self, *args):
00588         self.constructors_file.write(" ".join(args) + "\n")
00589 
00590     def make_header_h(self, ):
00591         self.write_h('''// DO NOT EDIT THIS FILE!
00592 // It is automatically generated from opcfoundation.org schemas.
00593 //
00594 
00595 /// @brief Opc Ua Binary.
00596 /// @license GNU LGPL
00597 ///
00598 /// Distributed under the GNU LGPL License
00599 /// (See accompanying file LICENSE or copy at
00600 /// http://www.gnu.org/licenses/lgpl.html)
00601 ///
00602 
00603 #pragma once
00604 
00605 #include <opc/ua/protocol/enums.h>
00606 #include <opc/ua/protocol/variable_access_level.h>
00607 #include <opc/ua/protocol/attribute_ids.h>
00608 #include <opc/ua/protocol/nodeid.h>
00609 #include <opc/ua/protocol/types.h>
00610 #include <opc/ua/protocol/types_manual.h>
00611 #include <opc/ua/protocol/variant.h>
00612 #include <opc/ua/protocol/data_value.h>
00613 
00614 namespace OpcUa
00615 {''')
00616 
00617     def make_footer_h(self):
00618         self.write_h('''
00619 } // namespace
00620     ''')
00621 
00622     def make_header_enum(self, ):
00623         self.write_enum('''// DO NOT EDIT THIS FILE!
00624 // It is automatically generated from opcfoundation.org schemas.
00625 //
00626 
00627 /// @brief Opc Ua Binary.
00628 /// @license GNU LGPL
00629 ///
00630 /// Distributed under the GNU LGPL License
00631 /// (See accompanying file LICENSE or copy at
00632 /// http://www.gnu.org/licenses/lgpl.html)
00633 ///
00634 
00635 #pragma once
00636 
00637 #include <cstdint>
00638 #include <vector>
00639 #include <string>
00640 
00641 #include <opc/ua/protocol/status_codes.h>
00642 
00643 namespace OpcUa
00644 {
00645   struct DiagnosticInfo;
00646 ''')
00647 
00648     def make_footer_enum(self):
00649         self.write_enum('''
00650 } // namespace
00651     ''')
00652 
00653     def make_header_rawsize(self, ):
00654         self.write_size('''// DO NOT EDIT THIS FILE!
00655 // It is automatically generated from opcfoundation.org schemas.
00656 //
00657 
00658 /// @author Olivier Roulet-Dubonnet
00659 /// @email olivier@sintef.no
00660 /// @brief Opc Ua Binary.
00661 /// @license GNU LGPL
00662 ///
00663 /// Distributed under the GNU LGPL License
00664 /// (See accompanying file LICENSE or copy at
00665 /// http://www.gnu.org/licenses/lgpl.html)
00666 ///
00667 
00668 #include "binary_serialization.h"
00669 #include <opc/ua/protocol/protocol.h>
00670 
00671 #include <opc/ua/protocol/binary/stream.h>
00672 
00673 namespace OpcUa
00674 {
00675     namespace Binary
00676     {''')
00677 
00678     def make_footer_rawsize(self):
00679         self.write_size('''
00680    }
00681 
00682 } // namespace
00683     ''')
00684 
00685 
00686 
00687     def make_header_serialize(self, ):
00688         self.write_ser('''// DO NOT EDIT THIS FILE!
00689 // It is automatically generated from opcfoundation.org schemas.
00690 //
00691 
00692 /// @author Olivier Roulet-Dubonnet
00693 /// @email olivier@sintef.no
00694 /// @brief Opc Ua Binary.
00695 /// @license GNU LGPL
00696 ///
00697 /// Distributed under the GNU LGPL License
00698 /// (See accompanying file LICENSE or copy at
00699 /// http://www.gnu.org/licenses/lgpl.html)
00700 ///
00701 
00702 #include "binary_serialization.h"
00703 #include <opc/ua/protocol/protocol.h>
00704 
00705 #include <opc/ua/protocol/binary/stream.h>
00706 
00707 namespace OpcUa
00708 {
00709     namespace Binary
00710     {''')
00711 
00712     def make_footer_serialize(self):
00713         self.write_ser('''
00714    }
00715 
00716 } // namespace
00717     ''')
00718 
00719     def make_header_deserialize(self, ):
00720         self.write_deser('''// DO NOT EDIT THIS FILE!
00721 // It is automatically generated from opcfoundation.org schemas.
00722 //
00723 
00724 /// @author Olivier Roulet-Dubonnet
00725 /// @email olivier@sintef.no
00726 /// @brief Opc Ua Binary.
00727 /// @license GNU LGPL
00728 ///
00729 /// Distributed under the GNU LGPL License
00730 /// (See accompanying file LICENSE or copy at
00731 /// http://www.gnu.org/licenses/lgpl.html)
00732 ///
00733 
00734 #include "binary_serialization.h"
00735 #include <opc/ua/protocol/protocol.h>
00736 
00737 #include <opc/ua/protocol/binary/stream.h>
00738 
00739 namespace OpcUa
00740 {
00741     namespace Binary
00742     {''')
00743 
00744     def make_footer_deserialize(self):
00745         self.write_deser('''
00746    }
00747 
00748 } // namespace
00749     ''')
00750 
00751 
00752     def make_header_constructors(self, ):
00753         self.write_const('''// DO NOT EDIT THIS FILE!
00754 // It is automatically generated from opcfoundation.org schemas.
00755 //
00756 
00757 /// @author Olivier Roulet-Dubonnet
00758 /// @email olivier@sintef.no
00759 /// @brief Opc Ua Binary.
00760 /// @license GNU LGPL
00761 ///
00762 /// Distributed under the GNU LGPL License
00763 /// (See accompanying file LICENSE or copy at
00764 /// http://www.gnu.org/licenses/lgpl.html)
00765 ///
00766 
00767 #include <opc/ua/protocol/protocol_auto.h>
00768 #include <opc/ua/protocol/object_ids.h>
00769 
00770 namespace OpcUa
00771 {   ''')
00772 
00773     def make_footer_constructors(self):
00774         self.write_const('''
00775 } // namespace
00776     ''')
00777 
00778 
00779 
00780 
00781 if __name__ == "__main__":
00782     xmlpath = "Opc.Ua.Types.bsd"
00783     hpath = "../include/opc/ua/protocol/protocol_auto.h"
00784     enumpath = "../include/opc/ua/protocol/enums.h"
00785     serializerpath = "../src/protocol/serialize_auto.cpp"
00786     rawsizepath = "../src/protocol/rawsize_auto.cpp"
00787     deserializerpath = "../src/protocol/deserialize_auto.cpp"
00788     constructorspath = "../src/protocol/constructors_auto.cpp"
00789 
00790     p = gm.Parser(xmlpath)
00791     model = p.parse()
00792     gm.add_basetype_members(model)
00793     gm.add_encoding_field(model)
00794     gm.remove_duplicates(model)
00795     gm.remove_vector_length(model)
00796     gm.split_requests(model, NoSplitStruct)
00797 
00798     #p = Parser(xmlpath)
00799     #model = p.parse()
00800     #Changes specific to our C++ implementation
00801     #reorder_extobjects(model)
00802     #add_basetype_members(model)
00803     #add_encoding_field(model)
00804     #remove_vector_length(model)
00805     #remove_body_length(model)
00806     #remove_duplicates(model)
00807     #split_requests(model)
00808     reorder_structs(model)
00809     override_types(model)
00810 
00811     f = open("struct_list.txt", "w")
00812     f.write("enabled_structs = [\\")
00813     for name in model.struct_list:
00814         f.write("\n    #'" + name + "',")
00815     f.write("]")
00816 
00817 
00818     c = CodeGenerator(model, hpath, enumpath, rawsizepath, serializerpath, deserializerpath, constructorspath)
00819     c.run()
00820 
00821 


ros_opcua_impl_freeopcua
Author(s): Denis Štogl
autogenerated on Sat Jun 8 2019 18:24:40