[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[certi-cvs] certi/scripts GenerateMessages.py GenMsgJava.py...
From: |
certi-cvs |
Subject: |
[certi-cvs] certi/scripts GenerateMessages.py GenMsgJava.py... |
Date: |
Thu, 04 Mar 2010 09:28:30 +0000 |
CVSROOT: /sources/certi
Module name: certi
Changes by: Eric NOULARD <erk> 10/03/04 09:28:30
Modified files:
scripts : GenerateMessages.py
Added files:
scripts : GenMsgJava.py GenMsgBase.py GenMsgPython.py
GenMsgCXX.py
Log message:
Begin Message Generator modularization
Now one can write/maintain generator backend
in an independant manner
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/certi/scripts/GenerateMessages.py?cvsroot=certi&r1=1.30&r2=1.31
http://cvs.savannah.gnu.org/viewcvs/certi/scripts/GenMsgJava.py?cvsroot=certi&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/certi/scripts/GenMsgBase.py?cvsroot=certi&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/certi/scripts/GenMsgPython.py?cvsroot=certi&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/certi/scripts/GenMsgCXX.py?cvsroot=certi&rev=1.1
Patches:
Index: GenerateMessages.py
===================================================================
RCS file: /sources/certi/certi/scripts/GenerateMessages.py,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -b -r1.30 -r1.31
--- GenerateMessages.py 27 Feb 2010 16:45:19 -0000 1.30
+++ GenerateMessages.py 4 Mar 2010 09:28:30 -0000 1.31
@@ -19,7 +19,7 @@
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
## USA
##
-## $Id: GenerateMessages.py,v 1.30 2010/02/27 16:45:19 erk Exp $
+## $Id: GenerateMessages.py,v 1.31 2010/03/04 09:28:30 erk Exp $
## ----------------------------------------------------------------------------
"""
@@ -69,8 +69,24 @@
mainlogger.setLevel(logging.ERROR)
mainlogger.addHandler(stdoutHandler)
+# FIXME TODO: implement automatic loading of additionnal
+# languages
+import GenMsgBase
+import GenMsgCXX
+import GenMsgPython
+import GenMsgJava
+
+generatorBackends = dict()
+generatorBackends[GenMsgBase.MsgSpecGenerator.generatorName().lower()] =
GenMsgBase.MsgSpecGenerator
+generatorBackends[GenMsgCXX.CXXGenerator.generatorName().lower()] =
GenMsgCXX.CXXGenerator
+generatorBackends[GenMsgPython.PythonGenerator.generatorName().lower()] =
GenMsgPython.PythonGenerator
+generatorBackends[GenMsgJava.JavaGenerator.generatorName().lower()] =
GenMsgJava.JavaGenerator
+
def usage():
- print "Usage:\n %s --input=<message> [--language=C++|Java|Python|MsgSpec]
[--type=header|body] [--factory-only] [--output=<filename>] [--verbose]
[--help]" % os.path.basename(sys.argv[0])
+ print "Usage:\n%s --input=<message> [--language=<lang>]
[--type=header|body] [--factory-only] [--output=<filename>] [--verbose]
[--help]" % os.path.basename(sys.argv[0])
+ print " Supported target languages are:"
+ for gene in generatorBackends.values():
+ print " - " + gene.generatorName()
try:
opts, args = getopt.getopt(sys.argv[1:], "i:l:t:o:vh",
["input=","language=","type=","factory-only","output=","verbose","help"])
@@ -964,1082 +980,6 @@
AST.checked = True
-class CodeGenerator(object):
- """
- This is a base class generator for C{MessageAST}.
-
- This is not a working generator it should be subclassed.
- """
- def __init__(self,MessageAST,commentLineBeginWith):
- self.AST = MessageAST
- self.commentLineBeginWith = commentLineBeginWith
- self.logger = logging.Logger("CodeGenerator")
- self.logger.setLevel(logging.ERROR)
- self.logger.addHandler(stdoutHandler)
- self.__indentString = " "
- self.__indentLevel = 0
- self.builtinTypeMap = {'onoff' : 'onoff',
- 'bool' : 'bool',
- 'string' : 'string',
- 'byte' : 'byte',
- 'int8' : 'int8',
- 'uint8' : 'uint8',
- 'int16' : 'int16',
- 'uint16' : 'uint16',
- 'int32' : 'int32',
- 'uint32' : 'uint32',
- 'int64' : 'int64',
- 'uint64' : 'uint64',
- 'float' : 'float',
- 'double' : 'double',}
-
- def setIndentString(self,indentString):
- self.__indentString = indentString
-
- def indent(self):
- self.__indentLevel += 1
-
- def unIndent(self):
- if self.__indentLevel>0:
- self.__indentLevel -= 1
- else:
- self.logger.error("Trying to unIndent lower than 0!??!")
-
- def getIndent(self):
- res=""
- i = self.__indentLevel
- while i>0:
- res = res + self.__indentString
- i -= 1
- return res
-
- def getTargetTypeName(self,name):
- if name in self.builtinTypeMap.keys():
- return self.builtinTypeMap[name]
- else:
- return name
-
- def lowerFirst(self,str):
- res = str[0].lower()+str[1:]
- return res
-
- def upperFirst(self,str):
- res = str[0].upper()+str[1:]
- return res
-
- def writeComment(self,stream,ASTElement):
- """
- Write a comment block to the stream.
-
- This function may be generic if the target
- language has whole line comment support
- with some beginning characters.
- """
- if ASTElement.hasComment():
- for line in ASTElement.comment.lines:
- # we should not indent optional comment
- # since they come at the end of a line
- if not ASTElement.comment.isAtEOL:
- stream.write(self.getIndent())
- stream.write(self.commentLineBeginWith)
- stream.write(str(line))
- stream.write("\n")
- else:
- stream.write("\n")
-
- def generateHeader(self,stream,factoryOnly=False):
- """
- Generate the header.
- """
- self.logger.error("generateHeader not IMPLEMENTED")
-
- def generateBody(self,stream,factoryOnly=False):
- """
- Generate the body.
- """
- self.logger.error("generateBody not IMPLEMENTED")
-
- def generate(self,stream,what,factoryOnly=False):
- stream.write(self.commentLineBeginWith)
- stream.write(" Generated on %s by the CERTI message
generator\n"%datetime.datetime.now().strftime("%Y %B %a, %d at %H:%M:%S"))
- if what.lower() == "header":
- self.generateHeader(stream,factoryOnly)
- elif what.lower() == "body":
- self.generateBody(stream,factoryOnly)
- else:
- self.logger.error("What <%s> unknown type??"%what)
-
-class MsgSpecGenerator(CodeGenerator):
- """
- This is a text generator for C{MessageAST}.
-
- This generator should produce almost the same output
- as the input message specification file.
- """
- def __init__(self,MessageAST):
- super(MsgSpecGenerator,self).__init__(MessageAST,"//")
- self.logger = logging.Logger("MsgSpecGenerator")
- self.logger.setLevel(logging.ERROR)
- self.logger.addHandler(stdoutHandler)
-
- def generate(self,stream,what,factoryOnly=False):
- """
- Redefine super.generate.
-
- what is not important in this case.
- """
- # Generate package
- if self.AST.hasPackage():
- self.writeComment(stream, self.AST.package)
- stream.write("package %s\n\n" % self.AST.package.name)
-
- if not factoryOnly:
- # Generate native type
- for native in self.AST.natives:
- self.writeComment(stream, native)
- stream.write("native %s\n\n" % native.name)
-
- # Generate enum
- for enum in self.AST.enums:
- self.writeComment(stream, enum)
- stream.write("enum %s {\n" % enum.name)
- first = True
- self.indent()
- for enumval in enum.values:
- if first:
- stream.write(self.getIndent()+"%s = %d, " %
(enumval.name,enumval.value))
- first=False
- else:
- stream.write(self.getIndent()+"%s, " % enumval.name)
- self.writeComment(stream, enumval)
- self.unIndent()
- stream.write("}\n\n")
-
- # Generate message type
- for msg in self.AST.messages:
- self.writeComment(stream, msg)
- stream.write("message %s"%msg.name)
- if msg.hasMerge():
- stream.write(" : merge %s {\n" % msg.merge.name)
- else:
- stream.write(" {\n")
-
- for field in msg.fields:
- stream.write(" %s %s %s " %
(field.qualifier,field.typeid.name,field.name))
- if field.hasDefaultValue():
- stream.write("[default=%s] " % field.defaultValue)
- self.writeComment(stream, field)
- stream.write("}\n\n")
-
- # Generate Factory
- if self.AST.hasFactory():
- self.writeComment(stream, self.AST.factory)
- stream.write("factory %s {\n" % self.AST.factory.name)
- self.indent()
- stream.write(self.getIndent()+"factoryCreator %s %s(%s)\n"%
self.AST.factory.creator)
- stream.write(self.getIndent()+"factoryReceiver %s %s(%s)\n"%
self.AST.factory.receiver)
- self.unIndent()
- stream.write("}\n\n")
-
-class CXXGenerator(CodeGenerator):
- """
- This is a C++ generator for C{MessageAST}.
-
- """
- def __init__(self,MessageAST):
- super(CXXGenerator,self).__init__(MessageAST,"//")
- self.logger = logging.Logger("CXXGenerator")
- self.logger.setLevel(logging.ERROR)
- self.logger.addHandler(stdoutHandler)
- self.included = dict()
- self.typedefed = dict()
- self.builtinTypeMap = {'onoff' : 'bool',
- 'bool' : 'bool',
- 'string' : 'std::string',
- 'byte' : 'byte',
- 'int8' : 'int8_t',
- 'uint8' : 'uint8_t',
- 'int16' : 'int16_t',
- 'uint16' : 'uint16_t',
- 'int32' : 'int32_t',
- 'uint32' : 'uint32_t',
- 'int64' : 'int64_t',
- 'uint64' : 'uint64_t',
- 'float' : 'float_t',
- 'double' : 'double_t',}
- self.serializeTypeMap = {'onoff' : 'write_bool',
- 'bool' : 'write_bool',
- 'string' : 'write_string',
- 'byte' : 'write_byte',
- 'int8' : 'write_int8',
- 'uint8' : 'write_uint8',
- 'int16' : 'write_int16',
- 'uint16' : 'write_uint16',
- 'int32' : 'write_int32',
- 'uint32' : 'write_uint32',
- 'int64' : 'write_int64',
- 'uint64' : 'write_uint64',
- 'float' : 'write_float',
- 'double' : 'write_double',}
- self.deserializeTypeMap = {'onoff' : 'read_bool',
- 'bool' : 'read_bool',
- 'string' : 'read_string',
- 'byte' : 'read_byte',
- 'int8' : 'read_int8',
- 'uint8' : 'read_uint8',
- 'int16' : 'read_int16',
- 'uint16' : 'read_uint16',
- 'int32' : 'read_int32',
- 'uint32' : 'read_uint32',
- 'int64' : 'read_int64',
- 'uint64' : 'read_uint64',
- 'float' : 'read_float',
- 'double' : 'read_double',}
-
- def getRepresentationFor(self,name):
- for native in self.AST.natives:
- if name == native.name:
- representation = native.getRepresentation()
- if representation:
- return representation
- return None
-
- def getSerializeMethodName(self,name):
- if name in self.serializeTypeMap.keys():
- return self.serializeTypeMap[name]
- else:
- representation = self.getRepresentationFor(name)
- if representation:
- return self.getSerializeMethodName(representation)
- return None
-
- def getDeSerializeMethodName(self,name):
- if name in self.deserializeTypeMap.keys():
- return self.deserializeTypeMap[name]
- else:
- representation = self.getRepresentationFor(name)
- if representation:
- return self.getDeSerializeMethodName(representation)
- return None
-
- def openNamespaces(self,stream):
- if self.AST.hasPackage():
- self.writeComment(stream, self.AST.package)
- # we may have nested namespace
- nameSpaceList = self.AST.package.name.split(".")
- for ns in nameSpaceList:
- stream.write(self.getIndent()+"namespace %s {\n\n" % ns)
- self.indent()
-
- def closeNamespaces(self, stream):
- if self.AST.hasPackage():
- # we may have nested namespace
- nameSpaceList = self.AST.package.name.split(".")
- nameSpaceList.reverse()
- for ns in nameSpaceList:
- self.unIndent()
- stream.write(self.getIndent()+"} "+self.commentLineBeginWith+"
end of namespace %s \n" % ns)
-
- def writeOneGetterSetter(self,stream,field):
-
- targetTypeName = self.getTargetTypeName(field.typeid.name)
-
- if field.typeid.name == "onoff":
- if field.qualifier == "repeated":
- stream.write(self.getIndent())
- stream.write("uint32_t
get"+self.upperFirst(field.name)+"Size() const")
- stream.write(" {return "+field.name+".size();}\n")
-
- stream.write(self.getIndent())
- stream.write("void
set"+self.upperFirst(field.name)+"Size(uint32_t num)")
- stream.write(" {"+field.name+".resize(num);}\n")
-
- stream.write(self.getIndent())
- stream.write("const std::vector<"+targetTypeName+">&
get"+self.upperFirst(field.name)+"() const")
- stream.write(" {return "+field.name+";}\n")
-
- stream.write(self.getIndent())
- stream.write("void "+field.name+"On(uint32_t rank)")
- stream.write(" {"+field.name+"[rank] = true;}\n")
-
- stream.write(self.getIndent())
- stream.write("void "+field.name+"Off(uint32_t rank)")
- stream.write(" {"+field.name+"[rank] = false;}\n")
-
- stream.write(self.getIndent())
- stream.write(targetTypeName+ "
is"+self.upperFirst(field.name)+"On(uint32_t rank) const")
- stream.write(" {return "+field.name+"[rank];}\n")
- else:
- stream.write(self.getIndent())
- stream.write("void "+field.name+"On()")
- stream.write(" {"+field.name+" = true;}\n")
-
- stream.write(self.getIndent())
- stream.write("void "+field.name+"Off()")
- stream.write(" {"+field.name+" = false;}\n")
-
- stream.write(self.getIndent())
- stream.write(targetTypeName+ "
is"+self.upperFirst(field.name)+"On() const")
- stream.write(" {return "+field.name+";}\n")
- else:
- if field.qualifier == "repeated":
- stream.write(self.getIndent())
- stream.write("uint32_t
get"+self.upperFirst(field.name)+"Size() const")
- stream.write(" {return "+field.name+".size();}\n")
-
- stream.write(self.getIndent())
- stream.write("void
set"+self.upperFirst(field.name)+"Size(uint32_t num)")
- stream.write(" {"+field.name+".resize(num);}\n")
-
- stream.write(self.getIndent())
- stream.write("const std::vector<"+targetTypeName+">&
get"+self.upperFirst(field.name)+"() const")
- stream.write(" {return "+field.name+";}\n")
-
- stream.write(self.getIndent())
- stream.write("const "+targetTypeName+"&
get"+self.upperFirst(field.name)+"(uint32_t rank) const")
- stream.write(" {return "+field.name+"[rank];}\n")
-
- stream.write(self.getIndent())
- stream.write(targetTypeName+"&
get"+self.upperFirst(field.name)+"(uint32_t rank)")
- stream.write(" {return "+field.name+"[rank];}\n")
-
- stream.write(self.getIndent())
- stream.write("void set"+self.upperFirst(field.name)+"(const ")
- stream.write(targetTypeName+"&
new"+self.upperFirst(field.name)+", uint32_t rank)")
- stream.write("
{"+field.name+"[rank]=new"+self.upperFirst(field.name)+";}\n")
- else:
- stream.write(self.getIndent())
- stream.write("const "+targetTypeName+"&
get"+self.upperFirst(field.name)+"() const")
- stream.write(" {return "+field.name+";}\n")
-
- stream.write(self.getIndent())
- stream.write("void set"+self.upperFirst(field.name)+"(const ")
- stream.write(targetTypeName+"&
new"+self.upperFirst(field.name)+") {")
- if field.qualifier == "optional":
- stream.write("\n")
- self.indent();
-
stream.write(self.getIndent()+"has%s=true;\n"%self.upperFirst(field.name))
-
stream.write(self.getIndent()+field.name+"=new"+self.upperFirst(field.name)+";\n")
- self.unIndent()
- stream.write(self.getIndent())
- else:
-
stream.write(field.name+"=new"+self.upperFirst(field.name)+";")
- stream.write("}\n")
-
- def writeDeclarationFieldStatement(self,stream,field):
- stream.write(self.getIndent())
- if field.qualifier == "repeated":
- stream.write("std::vector<%s> %s;" %
(self.getTargetTypeName(field.typeid.name),field.name))
- else:
- stream.write("%s %s;" %
(self.getTargetTypeName(field.typeid.name),field.name))
- self.writeComment(stream, field)
- # optional field generate another boolean field
- # used to detect whether if the optional field has
- # been given or not.
- if field.qualifier == "optional":
- stream.write(self.getIndent()+"bool has%s;\n" %
self.upperFirst(field.name))
-
- def generateHeader(self,stream,factoryOnly=False):
- # write the usual header protecting MACRO
- supposedHeaderName=stream.name
- if supposedHeaderName != "<stdout>":
- supposedHeaderName=os.path.basename(supposedHeaderName)
- supposedHeaderName=os.path.splitext(supposedHeaderName)[0]
- headerProtectMacroName = supposedHeaderName
- else:
- (headerProtectMacroName,ext) = os.path.splitext(self.AST.name)
- headerProtectMacroName = "%s_HH" % headerProtectMacroName.upper()
- stream.write("#ifndef %s\n"%headerProtectMacroName)
- stream.write("#define %s\n"%headerProtectMacroName)
- # add necessary standard and global includes
- stream.write(self.commentLineBeginWith+" ****-**** Global System
includes ****-****\n")
- stream.write("#include <vector>\n")
- self.included["#include <vector>"]=1
- stream.write("#include <string>\n")
- self.included["#include <string>"]=1
- # add include coming from native type specification
- stream.write(self.commentLineBeginWith+" ****-**** Includes coming
from native types ****-****\n")
- for native in self.AST.natives:
- line = native.getLanguage("CXX").statement
- # we are only interested in native "include" statement
- if line.find("#include")>=0 and (not line in self.included.keys()):
- self.writeComment(stream, native)
- stream.write(line+"\n")
- self.included[line]=1
- # Generate namespace for specified package package
- # we may have nested namespace
- self.openNamespaces(stream)
-
- if not factoryOnly:
- # Native type should be defined in included header
- stream.write(self.getIndent()+self.commentLineBeginWith)
- stream.write(" Native types has been defined:\n");
- stream.write(self.getIndent()+self.commentLineBeginWith)
- stream.write(" - by included headers (see above)\n")
- stream.write(self.getIndent()+self.commentLineBeginWith)
- stream.write(" - with typedef (see below [if any])\n")
- for native in self.AST.natives:
- line = native.getLanguage("CXX").statement
- # we are only interested in native statement
- # which are not #include
- if line.find("typedef")>=0 and (not line in
self.typedefed.keys()):
- self.writeComment(stream, native)
- stream.write(self.getIndent()+line+"\n")
- self.typedefed[line]=1
-
- # Generate enum
- for enum in self.AST.enums:
- self.writeComment(stream, enum)
- stream.write(self.getIndent())
- stream.write("typedef enum %s {\n" % enum.name)
- self.indent()
- first = True
- lastname = (enum.values[len(enum.values)-1]).name
- for enumval in enum.values:
- if first:
- stream.write(self.getIndent())
- stream.write("%s = %d, " %
(enumval.name,enumval.value))
- first=False
- else:
- stream.write(self.getIndent())
- if (enumval.name==lastname):
- stream.write("%s " % enumval.name)
- else:
- stream.write("%s, " % enumval.name)
- self.writeComment(stream, enumval)
- self.unIndent()
- stream.write(self.getIndent())
- stream.write("} %s_t; " % enum.name)
- stream.write(self.commentLineBeginWith + "end of enum %s \n" %
enum.name)
-
- # Generate message type
- for msg in self.AST.messages:
- self.writeComment(stream, msg)
- stream.write(self.getIndent())
- stream.write("class CERTI_EXPORT %s" % msg.name)
- if msg.hasMerge():
- stream.write(" : public %s {\n" % msg.merge.name)
- virtual = "virtual "
- else:
- stream.write(" {\n")
- virtual = ""
-
- self.indent()
-
- # begin public
- stream.write(self.getIndent()+"public:\n")
- self.indent()
- if msg.hasMerge():
- stream.write(self.getIndent()+"typedef %s
Super;\n"%msg.merge.name)
- # now write constructor/destructor
- stream.write(self.getIndent()+msg.name+"();\n")
- stream.write(self.getIndent()+virtual+"~"+msg.name+"();\n")
-
- # write virtual serialize and deserialize
- # if we have some specific field
- if len(msg.fields)>0:
- # serialize/deserialize
- stream.write(self.getIndent()+virtual+"void
serialize(MessageBuffer& msgBuffer);\n")
- stream.write(self.getIndent()+virtual+"void
deserialize(MessageBuffer& msgBuffer);\n")
- # specific getter/setter
- stream.write(self.getIndent()+self.commentLineBeginWith+"
specific Getter(s)/Setter(s)\n")
- for field in msg.fields:
- self.writeOneGetterSetter(stream,field)
- # the show method
- stream.write(self.getIndent()+self.commentLineBeginWith+"
the show method\n")
- stream.write(self.getIndent()+virtual+"void
show(std::ostream& out);\n")
-
- self.unIndent()
- # end public:
-
- # begin protected
- stream.write(self.getIndent()+"protected:\n")
- self.indent()
- for field in msg.fields:
- self.writeDeclarationFieldStatement(stream,field)
- self.unIndent()
- # end protected
-
- # begin private
- stream.write(self.getIndent()+"private:\n")
- self.indent()
- self.unIndent()
- # end private
-
- self.unIndent()
- stream.write(self.getIndent() + "};\n")
-
- # Generate Factory (if any)
- # @todo
- if self.AST.hasFactory():
- self.writeComment(stream, self.AST.factory)
- stream.write(self.getIndent() + "class CERTI_EXPORT %s {\n" %
self.AST.factory.name)
- self.indent()
- # begin public
- stream.write(self.getIndent()+"public:\n")
- self.indent()
- stream.write(self.getIndent()+"static %s* %s(%s type) throw
(RTIinternalError);\n"% self.AST.factory.creator)
- stream.write(self.getIndent()+"static %s* %s(%s stream) throw
(RTIinternalError);\n"% self.AST.factory.receiver)
- self.unIndent()
- #end public
- #begin protected
- stream.write(self.getIndent()+"protected:\n")
- self.indent()
- self.unIndent()
- #end protected
- #begin private
- stream.write(self.getIndent()+"private:\n")
- self.indent()
- self.unIndent()
- #end private
- self.unIndent()
- stream.write(self.getIndent()+"};\n\n")
-
- # may close any open namespaces
- self.closeNamespaces(stream)
- # close usual HEADER protecting MACRO
- stream.write(self.commentLineBeginWith+" %s\n"%headerProtectMacroName)
- stream.write("#endif\n")
-
- def writeInitFieldStatement(self,stream,field):
- if field.hasDefaultValue():
- stream.write(self.getIndent())
- stream.write(field.name+"="+str(field.defaultValue)+";\n")
- else:
- stream.write(self.getIndent())
- stream.write(self.commentLineBeginWith)
- stream.write(field.name+"= <no default value in message spec using
builtin>\n")
- # FIXME find a default value for every type beside natives
-
- def writeSerializeFieldStatement(self,stream,field):
- indexField = ''
- if field.qualifier == "optional":
- stream.write(self.getIndent())
- stream.write("msgBuffer.write_bool(has%s);\n" %
self.upperFirst(field.name))
- stream.write(self.getIndent())
- stream.write("if (has%s) {\n" % self.upperFirst(field.name))
- self.indent()
- elif field.qualifier == "repeated":
- indexField = '[i]'
- stream.write(self.getIndent())
- stream.write("uint32_t "+field.name+"Size =
"+field.name+".size();\n")
- stream.write(self.getIndent())
- stream.write("msgBuffer.write_uint32("+field.name+"Size);\n")
- stream.write(self.getIndent())
- stream.write("for (uint32_t i = 0; i < "+field.name+"Size; ++i)
{\n")
- self.indent()
-
- stream.write(self.getIndent())
- methodName = self.getSerializeMethodName(field.typeid.name)
- if None == methodName:
- if field.typeid.name in [m.name for m in self.AST.messages]:
- stream.write(field.name+indexField+".serialize(msgBuffer);\n")
- else:
- stream.write(self.commentLineBeginWith+" FIXME FIXME FIXME\n")
- stream.write(self.getIndent()+self.commentLineBeginWith+"
don't know how to serialize native field <%s> of type
<%s>\n"%(field.name,field.typeid.name))
- else:
- stream.write("msgBuffer."+methodName)
- stream.write("("+field.name+indexField+");\n")
-
- if field.qualifier == "optional":
- self.unIndent()
- stream.write(self.getIndent()+"}\n")
- elif field.qualifier == "repeated":
- self.unIndent()
- stream.write(self.getIndent()+"}\n")
-
- def writeShowFieldStatement(self,stream,field):
- indexField = ''
- if field.qualifier == "optional":
- stream.write(self.getIndent())
- stream.write("out << \"(opt) %s =\" " % field.name)
- elif field.qualifier == "repeated":
- indexField = '[i]'
- stream.write(self.getIndent())
- stream.write("out << \" %s [] =\" << std::endl;\n" % field.name
)
- stream.write(self.getIndent())
- stream.write("for (uint32_t i = 0; i <
get"+self.upperFirst(field.name)+"Size(); ++i) {\n")
- self.indent()
- stream.write(self.getIndent()+"out ")
- else:
- stream.write(self.getIndent())
- stream.write("out << \" %s = \" " % field.name)
-
- methodName = self.getSerializeMethodName(field.typeid.name)
- if None == methodName:
- if field.typeid.name in [m.name for m in self.AST.messages]:
- stream.write("<< \"FIXME inherited \";\n ")
- stream.write(self.commentLineBeginWith+" FIXME FIXME FIXME
inherited message\n")
- else:
- stream.write("<< \"")
- stream.write(self.getIndent()+self.commentLineBeginWith+"FIXME
FIXME don't know how to serialize native field <%s> of type
<%s>"%(field.name,field.typeid.name))
- stream.write("\"")
-
- else:
- stream.write("<< %s << \" \" " % (field.name+indexField))
-
- if field.qualifier == "optional":
- stream.write(self.getIndent()+"<< std::endl;\n")
- elif field.qualifier == "repeated":
- stream.write(";\n")
- self.unIndent()
- stream.write(self.getIndent()+"}\n")
- stream.write(self.getIndent()+"out << std::endl;\n")
- else:
- stream.write(self.getIndent()+"<< std::endl;\n")
-
-
- def writeDeSerializeFieldStatement(self,stream,field):
- indexField = ''
- if field.qualifier == "optional":
- stream.write(self.getIndent())
- stream.write("has%s = msgBuffer.read_bool();\n" %
self.upperFirst(field.name))
- stream.write(self.getIndent())
- stream.write("if (has%s) {\n" % self.upperFirst(field.name))
- self.indent()
- elif field.qualifier == "repeated":
- indexField = '[i]'
- stream.write(self.getIndent())
- stream.write("uint32_t "+field.name+"Size =
msgBuffer.read_uint32();\n")
- stream.write(self.getIndent())
- stream.write(field.name+".resize("+field.name+"Size);\n")
- stream.write(self.getIndent())
- stream.write("for (uint32_t i = 0; i < "+field.name+"Size; ++i)
{\n")
- self.indent()
-
- stream.write(self.getIndent())
- methodName = self.getDeSerializeMethodName(field.typeid.name)
- if None == methodName:
- if field.typeid.name in [m.name for m in self.AST.messages]:
-
stream.write(field.name+indexField+".deserialize(msgBuffer);\n")
- else:
- stream.write(self.commentLineBeginWith+" FIXME FIXME FIXME\n")
- stream.write(self.getIndent()+self.commentLineBeginWith+"
don't know how to deserialize native field <%s> of type
<%s>\n"%(field.name,field.typeid.name))
- else:
- if methodName == 'read_string':
-
stream.write("msgBuffer."+methodName+"("+field.name+indexField+");\n")
- else:
- # We may have to vast in order to enforce conversion
- if isinstance(field.typeid,NativeType):
- stream.write(field.name+indexField+" =
static_cast<"+field.typeid.name+">(msgBuffer."+methodName+"());\n")
- else:
- stream.write(field.name+indexField+" =
msgBuffer."+methodName+"();\n")
-
- if field.qualifier == "optional":
- self.unIndent()
- stream.write(self.getIndent()+"}\n")
- elif field.qualifier == "repeated":
- self.unIndent()
- stream.write(self.getIndent()+"}\n")
-
- def writeFactoryCreator(self,stream):
- creator =
(self.AST.factory.creator[0],self.AST.factory.name)+self.AST.factory.creator[1:]
- stream.write(self.getIndent()+"%s* %s::%s(%s type) throw
(RTIinternalError) {\n"% creator)
- self.indent()
- stream.write(self.getIndent()+"%s* msg;\n\n" % creator[0])
- stream.write(self.getIndent() + "switch (type) {\n")
- self.indent()
- for e in self.AST.eMessageType.values:
- #stream.write(self.getIndent()+"case %s::%s:\n" %
(creator[0],e.name))
- stream.write(self.getIndent()+"case %s::%s:\n" %
(creator[0],e.name.replace("M_","",1)))
- self.indent()
- if None==e.type:
- stream.write(self.getIndent()+"throw RTIinternalError(\"%s
message type should not be used!!\");\n"%e.name)
- else:
- stream.write(self.getIndent()+"msg = new %s();\n" % e.type)
- stream.write(self.getIndent()+"break;\n")
- self.unIndent()
- self.unIndent()
- stream.write(self.getIndent()+ "} "+self.commentLineBeginWith+" end if
switch (type)\n")
- stream.write(self.getIndent()+ "return msg;\n")
- self.unIndent()
- stream.write(self.getIndent()+("} /* end of %s::%s */\n\n" %
(creator[1],creator[2])))
-
- def writeFactoryReceiver(self,stream):
- receiver =
(self.AST.factory.receiver[0],self.AST.factory.name)+self.AST.factory.receiver[1:]
- stream.write(self.getIndent()+"%s* %s::%s(%s stream) throw
(RTIinternalError) {\n"% receiver)
- self.indent()
- stream.write(self.getIndent()+self.commentLineBeginWith+" FIXME This
is not thread safe\n")
- stream.write(self.getIndent()+"static MessageBuffer msgBuffer;\n")
- stream.write(self.getIndent()+"%s msgGen;\n" % receiver[0])
- stream.write(self.getIndent()+"%s* msg;\n\n" % receiver[0])
- stream.write(self.getIndent()+self.commentLineBeginWith+" receive
generic message \n")
- stream.write(self.getIndent()+"msgGen.receive(stream,msgBuffer);\n")
- stream.write(self.getIndent()+self.commentLineBeginWith+" create
specific message from type \n")
-
- stream.write(self.getIndent()+"msg = ");
-
stream.write(self.AST.factory.name+"::"+self.AST.factory.creator[1]+"(msgGen.getType());\n")
-
-
stream.write(self.getIndent()+"msgBuffer.assumeSizeFromReservedBytes();\n")
- stream.write(self.getIndent()+"msg->deserialize(msgBuffer);\n")
- stream.write(self.getIndent()+"return msg;\n")
- self.unIndent()
- stream.write(self.getIndent()+("} /* end of %s::%s */ \n\n" %
(receiver[1],receiver[2])))
-
-
- def generateBody(self,stream,factoryOnly=False):
- """
- Generate the body.
- """
- # add necessary standard includes
- stream.write("#include <vector>\n")
- stream.write("#include <string>\n")
-
- # [Try to] add corresponding header include
- supposedHeaderName=stream.name
- if supposedHeaderName != "<stdout>":
- supposedHeaderName=os.path.basename(supposedHeaderName)
- supposedHeaderName=os.path.splitext(supposedHeaderName)[0]
- stream.write("#include \""+supposedHeaderName+".hh\"\n")
- # Generate namespace for specified package package
- # we may have nested namespace
- self.openNamespaces(stream)
- if not factoryOnly:
- # Generate message type
- for msg in self.AST.messages:
- # Generate Constructor
- stream.write(self.getIndent()+"%s::%s() {\n" %
(msg.name,msg.name))
- self.indent()
- # Assign my name.
- stream.write(self.getIndent()+"this->messageName =
\""+msg.name+"\";\n")
- #stream.write(self.getIndent()+"this->type =
"+msg.name.upper().replace("NM_","NetworkMessage::")+";\n")
- stream.write(self.getIndent()+"this->type =
"+msg.name.upper().replace("M_","Message::",1)+";\n")
- # Write init value if any was provided
- if len(msg.fields)>0:
- for field in msg.fields:
- self.writeInitFieldStatement(stream,field)
- self.unIndent()
- stream.write(self.getIndent()+"}\n\n")
- # Generate Destructor
- stream.write(self.getIndent()+"%s::~%s() {\n" %
(msg.name,msg.name))
- self.indent()
- self.unIndent()
- stream.write(self.getIndent()+"}\n\n")
-
- # write virtual serialize and deserialize
- # if we have some specific field
- if len(msg.fields)>0:
- # begin serialize method
- stream.write(self.getIndent()+"void
%s::serialize(MessageBuffer& msgBuffer) {\n" % msg.name)
- self.indent()
- if msg.hasMerge():
-
stream.write(self.getIndent()+self.commentLineBeginWith)
- stream.write("Call mother class\n")
-
stream.write(self.getIndent()+"Super::serialize(msgBuffer);\n")
- stream.write(self.getIndent()+self.commentLineBeginWith)
- stream.write("Specific serialization code\n")
- for field in msg.fields:
- self.writeSerializeFieldStatement(stream,field)
- self.unIndent()
- stream.write(self.getIndent()+"}\n\n")
- # end serialize method
-
- # begin deserialize method
- stream.write(self.getIndent()+"void
%s::deserialize(MessageBuffer& msgBuffer) {\n" % msg.name)
- self.indent()
- if msg.hasMerge():
-
stream.write(self.getIndent()+self.commentLineBeginWith)
- stream.write("Call mother class\n")
-
stream.write(self.getIndent()+"Super::deserialize(msgBuffer);\n")
- stream.write(self.getIndent()+self.commentLineBeginWith)
- stream.write("Specific deserialization code\n")
- for field in msg.fields:
- self.writeDeSerializeFieldStatement(stream,field)
- self.unIndent()
- stream.write(self.getIndent()+"}\n\n")
- # end deserialize method
- # begin show method
- stream.write(self.getIndent()+"void %s::show(std::ostream&
out) {\n" % msg.name)
- self.indent()
- stream.write(self.getIndent()+"out << \"[%s -Begin]\" <<
std::endl;" % msg.name)
- if msg.hasMerge():
-
stream.write(self.getIndent()+self.commentLineBeginWith)
- stream.write("Call mother class\n")
- stream.write(self.getIndent()+"Super::show(out);\n")
- stream.write(self.getIndent()+self.commentLineBeginWith)
- stream.write("Specific show code\n")
- for field in msg.fields:
- self.writeShowFieldStatement(stream,field)
- stream.write(self.getIndent()+"out << \"[%s -End]\" <<
std::endl;" % msg.name)
- self.unIndent()
- stream.write(self.getIndent()+"}\n\n")
- # end show method
-
- # Generate Factory (if any)
- # @todo
- if self.AST.hasFactory():
- # begin creator
- self.writeFactoryCreator(stream)
- # begin receiver
- self.writeFactoryReceiver(stream)
-
- self.closeNamespaces(stream)
-
-class JavaGenerator(CodeGenerator):
- """
- This is a Java generator for C{MessageAST}.
- """
- def __init__(self, MessageAST):
- super(JavaGenerator, self).__init__(MessageAST, "//")
- self.logger = logging.Logger("JavaGenerator")
- self.logger.setLevel(logging.ERROR)
- self.logger.addHandler(stdoutHandler)
- # Message builtin type to Java type
- # Note that java integer type are ALL signed:
- #
http://java.sun.com/docs/books/tutorial/java/nutsandbolts/datatypes.html
- self.builtinTypeMap = {'onoff': 'boolean',
- 'bool': 'boolean',
- 'string': 'String',
- 'byte': 'byte',
- 'int8': 'byte',
- 'uint8': 'byte',
- 'int16': 'short',
- 'uint16': 'short',
- 'int32': 'int',
- 'uint32': 'int',
- 'int64': 'long',
- 'uint64': 'long',
- 'float': 'float',
- 'double': 'double',
- 'Tag': 'byte[]',
- 'Extents': 'List<CertiExtent>',
- 'SuppliedParameters': 'SuppliedParameters',
- #'FederateHandleSet': 'FederateHandleSet',
- 'Regions': 'List<Long>'}
- self.serializeTypeMap = {'onoff': 'messageBuffer.write(%s);',
- 'bool': 'messageBuffer.write(%s);',
- 'string': 'messageBuffer.write(%s);',
- 'byte': 'messageBuffer.write(%s);',
- 'int8': 'messageBuffer.write(%s);',
- 'uint8': 'messageBuffer.write(%s);',
- 'int16': ' messageBuffer.write(%s);',
- 'uint16': 'messageBuffer.write(%s);',
- 'int32': 'messageBuffer.write(%s);',
- 'uint32': 'messageBuffer.write(%s);',
- 'int64': 'messageBuffer.write(%s);',
- 'uint64': 'messageBuffer.write(%s);',
- 'float': 'messageBuffer.write(%s);',
- 'double': 'messageBuffer.write(%s);',
- 'Tag': 'messageBuffer.writeBytesWithSize(%s);',
- 'AttributeHandleSet': 'messageBuffer.write(%s);',
- 'SuppliedAttributes': 'messageBuffer.write(%s);',
- 'SuppliedParameters': 'messageBuffer.write(%s);',
- 'FederateHandleSet': 'messageBuffer.write(%s);',
- 'LogicalTimeInterval':'messageBuffer.write(%s);',
- 'Extents': 'messageBuffer.write(%s);',
- 'Regions': 'messageBuffer.writeRegions(%s);'}
- self.deserializeTypeMap = {'onoff': '%s =
messageBuffer.readBoolean();',
- 'bool': '%s = messageBuffer.readBoolean();',
- 'string': '%s = messageBuffer.readString();',
- 'byte': '%s = messageBuffer.readByte();',
- 'int8': '%s = messageBuffer.read_int8();',
- 'uint8': '%s = messageBuffer.read_uint8();',
- 'int16': '%s = messageBuffer.readShort();',
- 'uint16': '%s = messageBuffer.readShort();',
- 'int32': '%s = messageBuffer.readInt();',
- 'uint32': '%s = messageBuffer.readInt();',
- 'int64': '%s = messageBuffer.readLong();',
- 'uint64': '%s = messageBuffer.readLong();',
- 'float': '%s = messageBuffer.readFloat();',
- 'double': '%s = messageBuffer.readDouble();',
- 'Tag': '%s = messageBuffer.readBytesWithSize();',
- 'AttributeHandleSet': '%s =
messageBuffer.readAttributeHandleSet();',
- 'SuppliedAttributes': '%s =
messageBuffer.readSuppliedAttributes();',
- 'SuppliedParameters': '%s =
messageBuffer.readSuppliedParameters();',
- 'FederateHandleSet': '%s = messageBuffer.readFederateHandleSet();',
- 'LogicalTimeInterval':'%s =
messageBuffer.readLogicalTimeInterval();',
- 'Extents': '%s = messageBuffer.readExtents();',
- 'Regions': '%s = messageBuffer.readRegions();'}
-
- def writeFieldStatement(self, stream, field):
- if field.hasDefaultValue():
- stream.write(self.getTargetTypeName(field.typeid.name) + " " +
field.name + "=" + str(field.defaultValue) + ";\n")
- else:
- stream.write(self.getTargetTypeName(field.typeid.name) + " " +
field.name + ";\n")
-
- def generateIncludes(self, stream):
- stream.write("""import certi.communication.CertiException;
-import certi.communication.MessageBuffer;
-import certi.communication.CertiMessageType;
-import certi.communication.CertiMessage;
-import certi.rti.impl.CertiAttributeHandleSet;
-import certi.rti.impl.CertiSuppliedAttributes;
-import hla.rti.AttributeHandleSet;
-import hla.rti.SuppliedAttributes;
-import certi.rti.impl.CertiExtent;
-import java.util.List;
-import hla.rti.Region;
-import hla.rti.FederateHandleSet;
-import hla.rti.SuppliedParameters;
-import certi.rti.impl.CertiLogicalTime;
-import certi.rti.impl.CertiLogicalTimeInterval;
-import hla.rti.LogicalTime;
-import hla.rti.LogicalTimeInterval;\n\n""")
-
- def generateHeader(self, stream, factoryOnly=False):
- for native in self.AST.natives:
- line = native.getLanguage("Java").statement
- # we are only interested in native "include" statement
- stream.write("Hohohoo maaary christmass" + line + "\n")
-
- def prepareName(self, name):
- upperAfterScore = lambda x:__import__('re').sub(r'_(.)', lambda
y:y.group(0).upper(), x)
- return upperAfterScore(name.lower()).replace("_", "")[1:]
-
- def getSerializeMethodName(self, name):
- if name in self.serializeTypeMap.keys():
- return self.serializeTypeMap[name]
- else:
- representation = self.getRepresentationFor(name)
- if representation:
- return self.getSerializeMethodName(representation)
- return None
-
- def getDeSerializeMethodName(self, name):
- if name in self.deserializeTypeMap.keys():
- return self.deserializeTypeMap[name]
- else:
- representation = self.getRepresentationFor(name)
- if representation:
- return self.getDeSerializeMethodName(representation)
- return None
-
- def getRepresentationFor(self, name):
- for native in self.AST.natives:
- if name == native.name:
- representation = native.getRepresentation()
- if representation:
- return representation
- return None
-
- def generateBody(self, stream, factoryOnly=False):
- """
- Generate the body.
- """
-
- for msg in self.AST.messages:
- file = open("messages/" + self.prepareName(msg.name) + ".java",
"w")
-
- file.write("""//
----------------------------------------------------------------------------
-// CERTI - HLA Run Time Infrastructure
-// Copyright (C) 2010 Andrej Pancik
-//
-// This program is free software ; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public License
-// as published by the Free Software Foundation ; either version 2 of
-// the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY ; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this program ; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// ----------------------------------------------------------------------------
-""")
-
- if self.AST.hasPackage():
- file.write("package " + self.AST.package.name + ";\n\n")
- self.generateIncludes(file);
- file.write(self.getIndent() + "public class " +
self.prepareName(msg.name) + " extends CertiMessage {\n")
- self.indent()
-
- if len(msg.fields) > 0:
- for field in msg.fields:
- file.write(self.getIndent() + "private ");
- self.writeFieldStatement(file, field)
-
- file.write("\n")
- #constructor
- file.write(self.getIndent() + "public " +
self.prepareName(msg.name) + "() {\n")
- self.indent()
- file.write(self.getIndent() + "super(CertiMessageType." +
msg.name.upper()[2:] + ");\n")
- self.unIndent()
- file.write(self.getIndent() + "}\n\n");
-
- file.write(self.getIndent() + "public " +
self.prepareName(msg.name) + "(CertiLogicalTime federationTime) {\n")
- self.indent()
- file.write(self.getIndent() + "super(CertiMessageType." +
msg.name.upper()[2:] + ", federationTime);\n")
- self.unIndent()
- file.write(self.getIndent() + "}\n\n");
-
-
- #file.write(self.getIndent() + "public " +
self.prepareName(msg.name) + "(double federationTime, attributes) {\n")
- #TODO attributes in constructor
- #self.indent()
- #file.write(self.getIndent() + "super(CertiMessageType." +
msg.name.upper()[2:] + ", federationTime);\n")
-
- #TODO initialize local attributes
- #self.unIndent()
- #file.write(self.getIndent() + "}\n\n");
-
- if len(msg.fields) > 0:
- file.write(self.getIndent() + "@Override\n")
- file.write(self.getIndent() + "public void
writeMessage(MessageBuffer messageBuffer) {\n")
- self.indent()
- file.write(self.getIndent() +
"super.writeMessage(messageBuffer); //Header\n\n");
-
- for field in msg.fields:
- file.write(self.getIndent() +
self.getSerializeMethodName(field.typeid.name) % field.name + "\n")
-
- self.unIndent()
- file.write(self.getIndent() + "}\n\n");
-
- file.write(self.getIndent() + "@Override\n")
- file.write(self.getIndent() + "public void
readMessage(MessageBuffer messageBuffer) throws CertiException {\n")
- self.indent()
- file.write(self.getIndent() +
"super.readMessage(messageBuffer); //Header \n\n");
-
- for field in msg.fields:
- file.write(self.getIndent() +
self.getDeSerializeMethodName(field.typeid.name) % field.name + "\n")
-
- self.unIndent()
- file.write(self.getIndent() + "}\n\n");
-
- file.write(self.getIndent() + "@Override\n")
- file.write(self.getIndent() + "public String toString() {\n")
- self.indent()
- file.write(self.getIndent() + "return (super.toString()");
- for field in msg.fields:
- file.write(" + \", " + field.name + ": \" + " + field.name)
- file.write(");\n")
- self.unIndent()
- file.write(self.getIndent() + "}\n\n");
-
- #GETTERS
- for field in msg.fields:
- file.write(self.getIndent() + "public " +
self.getTargetTypeName(field.typeid.name) + " get" + field.name[0].capitalize()
+ field.name[1:] + "() {\n");
- self.indent()
- file.write(self.getIndent() + "return " + field.name +
";\n")
- self.unIndent()
- file.write(self.getIndent() + "}\n\n")
-
- #SETTERS
- for field in msg.fields:
- file.write(self.getIndent() + "public void set" +
field.name[0].capitalize() + field.name[1:] + "(" +
self.getTargetTypeName(field.typeid.name) + " new" + field.name[0].capitalize()
+ field.name[1:] + ") {\n");
- self.indent()
- file.write(self.getIndent() + "this." + field.name + " =
new" + field.name[0].capitalize() + field.name[1:] + ";\n")
- self.unIndent()
- file.write(self.getIndent() + "}\n\n")
-
- file.write("}\n\n")
- self.unIndent()
-
-
-class PythonGenerator(CodeGenerator):
- """
- This is a Python generator for C{MessageAST}.
- """
- def __init__(self,MessageAST):
- super(PythonGenerator,self).__init__(MessageAST,"##")
- self.logger = logging.Logger("PythonGenerator")
- self.logger.setLevel(logging.ERROR)
- self.logger.addHandler(stdoutHandler)
- # Message builtin type to Java type
-
# Build the PLY parser
parserlogger = logging.Logger("MessageParser")
parserlogger.setLevel(logging.ERROR)
@@ -2075,14 +1015,8 @@
mainlogger.info("Generate %s from AST,..."%language)
generator = None
-if language.lower()=="msgspec":
- generator = MsgSpecGenerator(parser.AST)
-elif language.lower()=="c++":
- generator = CXXGenerator(parser.AST)
-elif language.lower()=="java":
- generator = JavaGenerator(parser.AST)
-elif language.lower()=="python":
- generator= PythonGenerator(parser.AST)
+if language.lower() in generatorBackends.keys():
+ generator = generatorBackends[language.lower()](parser.AST)
elif language.lower()=="none":
mainlogger.info("Nothing to generate for <%s>." % language)
else:
@@ -2091,5 +1025,4 @@
if generator != None:
generator.generate(output,gentype,factoryOnly)
mainlogger.info("Generate %s from AST, Done." % language)
-
msgFile.close()
Index: GenMsgJava.py
===================================================================
RCS file: GenMsgJava.py
diff -N GenMsgJava.py
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ GenMsgJava.py 4 Mar 2010 09:28:30 -0000 1.1
@@ -0,0 +1,289 @@
+#!/usr/bin/env python
+
+## ----------------------------------------------------------------------------
+## CERTI - HLA RunTime Infrastructure
+## Copyright (C) 2002-2005 ONERA
+##
+## This program is free software ; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public License
+## as published by the Free Software Foundation ; either version 2 of
+## the License, or (at your option) Any later version.
+##
+## This program is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY ; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this program ; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+## USA
+##
+## $Id: GenMsgJava.py,v 1.1 2010/03/04 09:28:30 erk Exp $
+## ----------------------------------------------------------------------------
+
+"""
+The CERTI Message Generator.
+Java Backend Generator
+"""
+import logging
+import GenMsgBase
+import sys
+
+class JavaGenerator(GenMsgBase.CodeGenerator):
+ """
+ This is a Java generator for C{MessageAST}.
+ """
+
+ def generatorName(cls):
+ return "Java"
+ generatorName = classmethod(generatorName)
+
+ def __init__(self, MessageAST):
+ super(JavaGenerator, self).__init__(MessageAST, "//")
+ self.logger = logging.Logger("JavaGenerator")
+ self.logger.setLevel(logging.ERROR)
+ self.logger.addHandler(logging.StreamHandler(sys.stdout))
+ # Message builtin type to Java type
+ # Note that java integer type are ALL signed:
+ #
http://java.sun.com/docs/books/tutorial/java/nutsandbolts/datatypes.html
+ self.builtinTypeMap = {'onoff': 'boolean',
+ 'bool': 'boolean',
+ 'string': 'String',
+ 'byte': 'byte',
+ 'int8': 'byte',
+ 'uint8': 'byte',
+ 'int16': 'short',
+ 'uint16': 'short',
+ 'int32': 'int',
+ 'uint32': 'int',
+ 'int64': 'long',
+ 'uint64': 'long',
+ 'float': 'float',
+ 'double': 'double',
+ 'Tag': 'byte[]',
+ 'Extents': 'List<CertiExtent>',
+ 'SuppliedParameters': 'SuppliedParameters',
+ #'FederateHandleSet': 'FederateHandleSet',
+ 'Regions': 'List<Long>'}
+ self.serializeTypeMap = {'onoff': 'messageBuffer.write(%s);',
+ 'bool': 'messageBuffer.write(%s);',
+ 'string': 'messageBuffer.write(%s);',
+ 'byte': 'messageBuffer.write(%s);',
+ 'int8': 'messageBuffer.write(%s);',
+ 'uint8': 'messageBuffer.write(%s);',
+ 'int16': ' messageBuffer.write(%s);',
+ 'uint16': 'messageBuffer.write(%s);',
+ 'int32': 'messageBuffer.write(%s);',
+ 'uint32': 'messageBuffer.write(%s);',
+ 'int64': 'messageBuffer.write(%s);',
+ 'uint64': 'messageBuffer.write(%s);',
+ 'float': 'messageBuffer.write(%s);',
+ 'double': 'messageBuffer.write(%s);',
+ 'Tag': 'messageBuffer.writeBytesWithSize(%s);',
+ 'AttributeHandleSet': 'messageBuffer.write(%s);',
+ 'SuppliedAttributes': 'messageBuffer.write(%s);',
+ 'SuppliedParameters': 'messageBuffer.write(%s);',
+ 'FederateHandleSet': 'messageBuffer.write(%s);',
+ 'LogicalTimeInterval':'messageBuffer.write(%s);',
+ 'Extents': 'messageBuffer.write(%s);',
+ 'Regions': 'messageBuffer.writeRegions(%s);'}
+ self.deserializeTypeMap = {'onoff': '%s =
messageBuffer.readBoolean();',
+ 'bool': '%s = messageBuffer.readBoolean();',
+ 'string': '%s = messageBuffer.readString();',
+ 'byte': '%s = messageBuffer.readByte();',
+ 'int8': '%s = messageBuffer.read_int8();',
+ 'uint8': '%s = messageBuffer.read_uint8();',
+ 'int16': '%s = messageBuffer.readShort();',
+ 'uint16': '%s = messageBuffer.readShort();',
+ 'int32': '%s = messageBuffer.readInt();',
+ 'uint32': '%s = messageBuffer.readInt();',
+ 'int64': '%s = messageBuffer.readLong();',
+ 'uint64': '%s = messageBuffer.readLong();',
+ 'float': '%s = messageBuffer.readFloat();',
+ 'double': '%s = messageBuffer.readDouble();',
+ 'Tag': '%s = messageBuffer.readBytesWithSize();',
+ 'AttributeHandleSet': '%s =
messageBuffer.readAttributeHandleSet();',
+ 'SuppliedAttributes': '%s =
messageBuffer.readSuppliedAttributes();',
+ 'SuppliedParameters': '%s =
messageBuffer.readSuppliedParameters();',
+ 'FederateHandleSet': '%s = messageBuffer.readFederateHandleSet();',
+ 'LogicalTimeInterval':'%s =
messageBuffer.readLogicalTimeInterval();',
+ 'Extents': '%s = messageBuffer.readExtents();',
+ 'Regions': '%s = messageBuffer.readRegions();'}
+
+ def writeFieldStatement(self, stream, field):
+ if field.hasDefaultValue():
+ stream.write(self.getTargetTypeName(field.typeid.name) + " " +
field.name + "=" + str(field.defaultValue) + ";\n")
+ else:
+ stream.write(self.getTargetTypeName(field.typeid.name) + " " +
field.name + ";\n")
+
+ def generateIncludes(self, stream):
+ stream.write("""import certi.communication.CertiException;
+import certi.communication.MessageBuffer;
+import certi.communication.CertiMessageType;
+import certi.communication.CertiMessage;
+import certi.rti.impl.CertiAttributeHandleSet;
+import certi.rti.impl.CertiSuppliedAttributes;
+import hla.rti.AttributeHandleSet;
+import hla.rti.SuppliedAttributes;
+import certi.rti.impl.CertiExtent;
+import java.util.List;
+import hla.rti.Region;
+import hla.rti.FederateHandleSet;
+import hla.rti.SuppliedParameters;
+import certi.rti.impl.CertiLogicalTime;
+import certi.rti.impl.CertiLogicalTimeInterval;
+import hla.rti.LogicalTime;
+import hla.rti.LogicalTimeInterval;\n\n""")
+
+ def generateHeader(self, stream, factoryOnly=False):
+ for native in self.AST.natives:
+ line = native.getLanguage("Java").statement
+ # we are only interested in native "include" statement
+ stream.write("Hohohoo maaary christmass" + line + "\n")
+
+ def prepareName(self, name):
+ upperAfterScore = lambda x:__import__('re').sub(r'_(.)', lambda
y:y.group(0).upper(), x)
+ return upperAfterScore(name.lower()).replace("_", "")[1:]
+
+ def getSerializeMethodName(self, name):
+ if name in self.serializeTypeMap.keys():
+ return self.serializeTypeMap[name]
+ else:
+ representation = self.getRepresentationFor(name)
+ if representation:
+ return self.getSerializeMethodName(representation)
+ return None
+
+ def getDeSerializeMethodName(self, name):
+ if name in self.deserializeTypeMap.keys():
+ return self.deserializeTypeMap[name]
+ else:
+ representation = self.getRepresentationFor(name)
+ if representation:
+ return self.getDeSerializeMethodName(representation)
+ return None
+
+ def getRepresentationFor(self, name):
+ for native in self.AST.natives:
+ if name == native.name:
+ representation = native.getRepresentation()
+ if representation:
+ return representation
+ return None
+
+ def generateBody(self, stream, factoryOnly=False):
+ """
+ Generate the body.
+ """
+
+ for msg in self.AST.messages:
+ file = open("messages/" + self.prepareName(msg.name) + ".java",
"w")
+
+ file.write("""//
----------------------------------------------------------------------------
+// CERTI - HLA Run Time Infrastructure
+// Copyright (C) 2010 Andrej Pancik
+//
+// This program is free software ; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public License
+// as published by the Free Software Foundation ; either version 2 of
+// the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY ; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this program ; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// ----------------------------------------------------------------------------
+""")
+
+ if self.AST.hasPackage():
+ file.write("package " + self.AST.package.name + ";\n\n")
+ self.generateIncludes(file);
+ file.write(self.getIndent() + "public class " +
self.prepareName(msg.name) + " extends CertiMessage {\n")
+ self.indent()
+
+ if len(msg.fields) > 0:
+ for field in msg.fields:
+ file.write(self.getIndent() + "private ");
+ self.writeFieldStatement(file, field)
+
+ file.write("\n")
+ #constructor
+ file.write(self.getIndent() + "public " +
self.prepareName(msg.name) + "() {\n")
+ self.indent()
+ file.write(self.getIndent() + "super(CertiMessageType." +
msg.name.upper()[2:] + ");\n")
+ self.unIndent()
+ file.write(self.getIndent() + "}\n\n");
+
+ file.write(self.getIndent() + "public " +
self.prepareName(msg.name) + "(CertiLogicalTime federationTime) {\n")
+ self.indent()
+ file.write(self.getIndent() + "super(CertiMessageType." +
msg.name.upper()[2:] + ", federationTime);\n")
+ self.unIndent()
+ file.write(self.getIndent() + "}\n\n");
+
+
+ #file.write(self.getIndent() + "public " +
self.prepareName(msg.name) + "(double federationTime, attributes) {\n")
+ #TODO attributes in constructor
+ #self.indent()
+ #file.write(self.getIndent() + "super(CertiMessageType." +
msg.name.upper()[2:] + ", federationTime);\n")
+
+ #TODO initialize local attributes
+ #self.unIndent()
+ #file.write(self.getIndent() + "}\n\n");
+
+ if len(msg.fields) > 0:
+ file.write(self.getIndent() + "@Override\n")
+ file.write(self.getIndent() + "public void
writeMessage(MessageBuffer messageBuffer) {\n")
+ self.indent()
+ file.write(self.getIndent() +
"super.writeMessage(messageBuffer); //Header\n\n");
+
+ for field in msg.fields:
+ file.write(self.getIndent() +
self.getSerializeMethodName(field.typeid.name) % field.name + "\n")
+
+ self.unIndent()
+ file.write(self.getIndent() + "}\n\n");
+
+ file.write(self.getIndent() + "@Override\n")
+ file.write(self.getIndent() + "public void
readMessage(MessageBuffer messageBuffer) throws CertiException {\n")
+ self.indent()
+ file.write(self.getIndent() +
"super.readMessage(messageBuffer); //Header \n\n");
+
+ for field in msg.fields:
+ file.write(self.getIndent() +
self.getDeSerializeMethodName(field.typeid.name) % field.name + "\n")
+
+ self.unIndent()
+ file.write(self.getIndent() + "}\n\n");
+
+ file.write(self.getIndent() + "@Override\n")
+ file.write(self.getIndent() + "public String toString() {\n")
+ self.indent()
+ file.write(self.getIndent() + "return (super.toString()");
+ for field in msg.fields:
+ file.write(" + \", " + field.name + ": \" + " + field.name)
+ file.write(");\n")
+ self.unIndent()
+ file.write(self.getIndent() + "}\n\n");
+
+ #GETTERS
+ for field in msg.fields:
+ file.write(self.getIndent() + "public " +
self.getTargetTypeName(field.typeid.name) + " get" + field.name[0].capitalize()
+ field.name[1:] + "() {\n");
+ self.indent()
+ file.write(self.getIndent() + "return " + field.name +
";\n")
+ self.unIndent()
+ file.write(self.getIndent() + "}\n\n")
+
+ #SETTERS
+ for field in msg.fields:
+ file.write(self.getIndent() + "public void set" +
field.name[0].capitalize() + field.name[1:] + "(" +
self.getTargetTypeName(field.typeid.name) + " new" + field.name[0].capitalize()
+ field.name[1:] + ") {\n");
+ self.indent()
+ file.write(self.getIndent() + "this." + field.name + " =
new" + field.name[0].capitalize() + field.name[1:] + ";\n")
+ self.unIndent()
+ file.write(self.getIndent() + "}\n\n")
+
+ file.write("}\n\n")
+ self.unIndent()
Index: GenMsgBase.py
===================================================================
RCS file: GenMsgBase.py
diff -N GenMsgBase.py
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ GenMsgBase.py 4 Mar 2010 09:28:30 -0000 1.1
@@ -0,0 +1,223 @@
+#!/usr/bin/env python
+
+## ----------------------------------------------------------------------------
+## CERTI - HLA RunTime Infrastructure
+## Copyright (C) 2002-2005 ONERA
+##
+## This program is free software ; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public License
+## as published by the Free Software Foundation ; either version 2 of
+## the License, or (at your option) Any later version.
+##
+## This program is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY ; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this program ; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+## USA
+##
+## $Id: GenMsgBase.py,v 1.1 2010/03/04 09:28:30 erk Exp $
+## ----------------------------------------------------------------------------
+
+"""
+The CERTI Message Generator.
+Generator Base class
+"""
+
+# We use logging for ... logging :-)
+# see http://docs.python.org/library/logging.html
+import logging
+import sys
+import datetime
+
+class CodeGenerator(object):
+ """
+ This is a base class generator for C{MessageAST}.
+
+ This is not a working generator it should be subclassed.
+ """
+
+ def generatorName(cls):
+ raise Exception("This class method should be overloaded by daughter
class <"+cls.__name__+">")
+ generatorName = classmethod(generatorName)
+
+ def __init__(self,MessageAST,commentLineBeginWith):
+ self.AST = MessageAST
+ self.commentLineBeginWith = commentLineBeginWith
+ self.logger = logging.Logger("CodeGenerator")
+ self.logger.setLevel(logging.ERROR)
+ self.logger.addHandler(logging.StreamHandler(sys.stdout))
+ self.__indentString = " "
+ self.__indentLevel = 0
+ self.builtinTypeMap = {'onoff' : 'onoff',
+ 'bool' : 'bool',
+ 'string' : 'string',
+ 'byte' : 'byte',
+ 'int8' : 'int8',
+ 'uint8' : 'uint8',
+ 'int16' : 'int16',
+ 'uint16' : 'uint16',
+ 'int32' : 'int32',
+ 'uint32' : 'uint32',
+ 'int64' : 'int64',
+ 'uint64' : 'uint64',
+ 'float' : 'float',
+ 'double' : 'double',}
+
+ def setIndentString(self,indentString):
+ self.__indentString = indentString
+
+ def indent(self):
+ self.__indentLevel += 1
+
+ def unIndent(self):
+ if self.__indentLevel>0:
+ self.__indentLevel -= 1
+ else:
+ self.logger.error("Trying to unIndent lower than 0!??!")
+
+ def getIndent(self):
+ res=""
+ i = self.__indentLevel
+ while i>0:
+ res = res + self.__indentString
+ i -= 1
+ return res
+
+ def getTargetTypeName(self,name):
+ if name in self.builtinTypeMap.keys():
+ return self.builtinTypeMap[name]
+ else:
+ return name
+
+ def lowerFirst(self,str):
+ res = str[0].lower()+str[1:]
+ return res
+
+ def upperFirst(self,str):
+ res = str[0].upper()+str[1:]
+ return res
+
+ def writeComment(self,stream,ASTElement):
+ """
+ Write a comment block to the stream.
+
+ This function may be generic if the target
+ language has whole line comment support
+ with some beginning characters.
+ """
+ if ASTElement.hasComment():
+ for line in ASTElement.comment.lines:
+ # we should not indent optional comment
+ # since they come at the end of a line
+ if not ASTElement.comment.isAtEOL:
+ stream.write(self.getIndent())
+ stream.write(self.commentLineBeginWith)
+ stream.write(str(line))
+ stream.write("\n")
+ else:
+ stream.write("\n")
+
+ def generateHeader(self,stream,factoryOnly=False):
+ """
+ Generate the header.
+ """
+ self.logger.error("generateHeader not IMPLEMENTED")
+
+ def generateBody(self,stream,factoryOnly=False):
+ """
+ Generate the body.
+ """
+ self.logger.error("generateBody not IMPLEMENTED")
+
+ def generate(self,stream,what,factoryOnly=False):
+ stream.write(self.commentLineBeginWith)
+ stream.write(" Generated on %s by the CERTI message
generator\n"%datetime.datetime.now().strftime("%Y %B %a, %d at %H:%M:%S"))
+ if what.lower() == "header":
+ self.generateHeader(stream,factoryOnly)
+ elif what.lower() == "body":
+ self.generateBody(stream,factoryOnly)
+ else:
+ self.logger.error("What <%s> unknown type??"%what)
+
+class MsgSpecGenerator(CodeGenerator):
+ """
+ This is a text generator for C{MessageAST}.
+
+ This generator should produce almost the same output
+ as the input message specification file.
+ """
+
+ def generatorName(cls):
+ return "MsgSpec"
+ generatorName = classmethod(generatorName)
+
+ def __init__(self,MessageAST):
+ super(MsgSpecGenerator,self).__init__(MessageAST,"//")
+ self.logger = logging.Logger("MsgSpecGenerator")
+ self.logger.setLevel(logging.ERROR)
+ self.logger.addHandler(logging.StreamHandler(sys.stdout))
+ self.__languageName = "MsgSpec"
+
+ def generate(self,stream,what,factoryOnly=False):
+ """
+ Redefine super.generate.
+
+ what is not important in this case.
+ """
+ # Generate package
+ if self.AST.hasPackage():
+ self.writeComment(stream, self.AST.package)
+ stream.write("package %s\n\n" % self.AST.package.name)
+
+ if not factoryOnly:
+ # Generate native type
+ for native in self.AST.natives:
+ self.writeComment(stream, native)
+ stream.write("native %s\n\n" % native.name)
+
+ # Generate enum
+ for enum in self.AST.enums:
+ self.writeComment(stream, enum)
+ stream.write("enum %s {\n" % enum.name)
+ first = True
+ self.indent()
+ for enumval in enum.values:
+ if first:
+ stream.write(self.getIndent()+"%s = %d, " %
(enumval.name,enumval.value))
+ first=False
+ else:
+ stream.write(self.getIndent()+"%s, " % enumval.name)
+ self.writeComment(stream, enumval)
+ self.unIndent()
+ stream.write("}\n\n")
+
+ # Generate message type
+ for msg in self.AST.messages:
+ self.writeComment(stream, msg)
+ stream.write("message %s"%msg.name)
+ if msg.hasMerge():
+ stream.write(" : merge %s {\n" % msg.merge.name)
+ else:
+ stream.write(" {\n")
+
+ for field in msg.fields:
+ stream.write(" %s %s %s " %
(field.qualifier,field.typeid.name,field.name))
+ if field.hasDefaultValue():
+ stream.write("[default=%s] " % field.defaultValue)
+ self.writeComment(stream, field)
+ stream.write("}\n\n")
+
+ # Generate Factory
+ if self.AST.hasFactory():
+ self.writeComment(stream, self.AST.factory)
+ stream.write("factory %s {\n" % self.AST.factory.name)
+ self.indent()
+ stream.write(self.getIndent()+"factoryCreator %s %s(%s)\n"%
self.AST.factory.creator)
+ stream.write(self.getIndent()+"factoryReceiver %s %s(%s)\n"%
self.AST.factory.receiver)
+ self.unIndent()
+ stream.write("}\n\n")
+
\ No newline at end of file
Index: GenMsgPython.py
===================================================================
RCS file: GenMsgPython.py
diff -N GenMsgPython.py
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ GenMsgPython.py 4 Mar 2010 09:28:30 -0000 1.1
@@ -0,0 +1,48 @@
+#!/usr/bin/env python
+
+## ----------------------------------------------------------------------------
+## CERTI - HLA RunTime Infrastructure
+## Copyright (C) 2002-2005 ONERA
+##
+## This program is free software ; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public License
+## as published by the Free Software Foundation ; either version 2 of
+## the License, or (at your option) Any later version.
+##
+## This program is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY ; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this program ; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+## USA
+##
+## $Id: GenMsgPython.py,v 1.1 2010/03/04 09:28:30 erk Exp $
+## ----------------------------------------------------------------------------
+
+"""
+The CERTI Message Generator.
+Python Backend Generator
+"""
+import logging
+import GenMsgBase
+
+class PythonGenerator(GenMsgBase.CodeGenerator):
+ """
+ This is a Python generator for C{MessageAST}.
+ """
+
+ def generatorName(cls):
+ return "Python"
+ generatorName = classmethod(generatorName)
+
+
+ def __init__(self,MessageAST):
+ super(PythonGenerator,self).__init__(MessageAST,"##")
+ self.logger = logging.Logger("PythonGenerator")
+ self.logger.setLevel(logging.ERROR)
+ self.logger.addHandler(logging.StreamHandler(sys.stdout))
+ # Message builtin type to Python type
+
\ No newline at end of file
Index: GenMsgCXX.py
===================================================================
RCS file: GenMsgCXX.py
diff -N GenMsgCXX.py
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ GenMsgCXX.py 4 Mar 2010 09:28:30 -0000 1.1
@@ -0,0 +1,673 @@
+#!/usr/bin/env python
+
+## ----------------------------------------------------------------------------
+## CERTI - HLA RunTime Infrastructure
+## Copyright (C) 2002-2005 ONERA
+##
+## This program is free software ; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public License
+## as published by the Free Software Foundation ; either version 2 of
+## the License, or (at your option) Any later version.
+##
+## This program is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY ; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this program ; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+## USA
+##
+## $Id: GenMsgCXX.py,v 1.1 2010/03/04 09:28:30 erk Exp $
+## ----------------------------------------------------------------------------
+
+"""
+The CERTI Message Generator.
+C++ Backend Generator
+"""
+import logging
+import GenMsgBase
+import sys
+import os
+
+class CXXGenerator(GenMsgBase.CodeGenerator):
+ """
+ This is a C++ generator for C{MessageAST}.
+
+ """
+
+ def generatorName(cls):
+ return "C++"
+ generatorName = classmethod(generatorName)
+
+
+ def __init__(self,MessageAST):
+ super(CXXGenerator,self).__init__(MessageAST,"//")
+ self.logger = logging.Logger("CXXGenerator")
+ self.logger.setLevel(logging.ERROR)
+ self.logger.addHandler(logging.StreamHandler(sys.stdout))
+ self.included = dict()
+ self.typedefed = dict()
+ self.builtinTypeMap = {'onoff' : 'bool',
+ 'bool' : 'bool',
+ 'string' : 'std::string',
+ 'byte' : 'byte',
+ 'int8' : 'int8_t',
+ 'uint8' : 'uint8_t',
+ 'int16' : 'int16_t',
+ 'uint16' : 'uint16_t',
+ 'int32' : 'int32_t',
+ 'uint32' : 'uint32_t',
+ 'int64' : 'int64_t',
+ 'uint64' : 'uint64_t',
+ 'float' : 'float_t',
+ 'double' : 'double_t',}
+ self.serializeTypeMap = {'onoff' : 'write_bool',
+ 'bool' : 'write_bool',
+ 'string' : 'write_string',
+ 'byte' : 'write_byte',
+ 'int8' : 'write_int8',
+ 'uint8' : 'write_uint8',
+ 'int16' : 'write_int16',
+ 'uint16' : 'write_uint16',
+ 'int32' : 'write_int32',
+ 'uint32' : 'write_uint32',
+ 'int64' : 'write_int64',
+ 'uint64' : 'write_uint64',
+ 'float' : 'write_float',
+ 'double' : 'write_double',}
+ self.deserializeTypeMap = {'onoff' : 'read_bool',
+ 'bool' : 'read_bool',
+ 'string' : 'read_string',
+ 'byte' : 'read_byte',
+ 'int8' : 'read_int8',
+ 'uint8' : 'read_uint8',
+ 'int16' : 'read_int16',
+ 'uint16' : 'read_uint16',
+ 'int32' : 'read_int32',
+ 'uint32' : 'read_uint32',
+ 'int64' : 'read_int64',
+ 'uint64' : 'read_uint64',
+ 'float' : 'read_float',
+ 'double' : 'read_double',}
+ self.__languageName="C++"
+
+ def getRepresentationFor(self,name):
+ for native in self.AST.natives:
+ if name == native.name:
+ representation = native.getRepresentation()
+ if representation:
+ return representation
+ return None
+
+ def getSerializeMethodName(self,name):
+ if name in self.serializeTypeMap.keys():
+ return self.serializeTypeMap[name]
+ else:
+ representation = self.getRepresentationFor(name)
+ if representation:
+ return self.getSerializeMethodName(representation)
+ return None
+
+ def getDeSerializeMethodName(self,name):
+ if name in self.deserializeTypeMap.keys():
+ return self.deserializeTypeMap[name]
+ else:
+ representation = self.getRepresentationFor(name)
+ if representation:
+ return self.getDeSerializeMethodName(representation)
+ return None
+
+ def openNamespaces(self,stream):
+ if self.AST.hasPackage():
+ self.writeComment(stream, self.AST.package)
+ # we may have nested namespace
+ nameSpaceList = self.AST.package.name.split(".")
+ for ns in nameSpaceList:
+ stream.write(self.getIndent()+"namespace %s {\n\n" % ns)
+ self.indent()
+
+ def closeNamespaces(self, stream):
+ if self.AST.hasPackage():
+ # we may have nested namespace
+ nameSpaceList = self.AST.package.name.split(".")
+ nameSpaceList.reverse()
+ for ns in nameSpaceList:
+ self.unIndent()
+ stream.write(self.getIndent()+"} "+self.commentLineBeginWith+"
end of namespace %s \n" % ns)
+
+ def writeOneGetterSetter(self,stream,field):
+
+ targetTypeName = self.getTargetTypeName(field.typeid.name)
+
+ if field.typeid.name == "onoff":
+ if field.qualifier == "repeated":
+ stream.write(self.getIndent())
+ stream.write("uint32_t
get"+self.upperFirst(field.name)+"Size() const")
+ stream.write(" {return "+field.name+".size();}\n")
+
+ stream.write(self.getIndent())
+ stream.write("void
set"+self.upperFirst(field.name)+"Size(uint32_t num)")
+ stream.write(" {"+field.name+".resize(num);}\n")
+
+ stream.write(self.getIndent())
+ stream.write("const std::vector<"+targetTypeName+">&
get"+self.upperFirst(field.name)+"() const")
+ stream.write(" {return "+field.name+";}\n")
+
+ stream.write(self.getIndent())
+ stream.write("void "+field.name+"On(uint32_t rank)")
+ stream.write(" {"+field.name+"[rank] = true;}\n")
+
+ stream.write(self.getIndent())
+ stream.write("void "+field.name+"Off(uint32_t rank)")
+ stream.write(" {"+field.name+"[rank] = false;}\n")
+
+ stream.write(self.getIndent())
+ stream.write(targetTypeName+ "
is"+self.upperFirst(field.name)+"On(uint32_t rank) const")
+ stream.write(" {return "+field.name+"[rank];}\n")
+ else:
+ stream.write(self.getIndent())
+ stream.write("void "+field.name+"On()")
+ stream.write(" {"+field.name+" = true;}\n")
+
+ stream.write(self.getIndent())
+ stream.write("void "+field.name+"Off()")
+ stream.write(" {"+field.name+" = false;}\n")
+
+ stream.write(self.getIndent())
+ stream.write(targetTypeName+ "
is"+self.upperFirst(field.name)+"On() const")
+ stream.write(" {return "+field.name+";}\n")
+ else:
+ if field.qualifier == "repeated":
+ stream.write(self.getIndent())
+ stream.write("uint32_t
get"+self.upperFirst(field.name)+"Size() const")
+ stream.write(" {return "+field.name+".size();}\n")
+
+ stream.write(self.getIndent())
+ stream.write("void
set"+self.upperFirst(field.name)+"Size(uint32_t num)")
+ stream.write(" {"+field.name+".resize(num);}\n")
+
+ stream.write(self.getIndent())
+ stream.write("const std::vector<"+targetTypeName+">&
get"+self.upperFirst(field.name)+"() const")
+ stream.write(" {return "+field.name+";}\n")
+
+ stream.write(self.getIndent())
+ stream.write("const "+targetTypeName+"&
get"+self.upperFirst(field.name)+"(uint32_t rank) const")
+ stream.write(" {return "+field.name+"[rank];}\n")
+
+ stream.write(self.getIndent())
+ stream.write(targetTypeName+"&
get"+self.upperFirst(field.name)+"(uint32_t rank)")
+ stream.write(" {return "+field.name+"[rank];}\n")
+
+ stream.write(self.getIndent())
+ stream.write("void set"+self.upperFirst(field.name)+"(const ")
+ stream.write(targetTypeName+"&
new"+self.upperFirst(field.name)+", uint32_t rank)")
+ stream.write("
{"+field.name+"[rank]=new"+self.upperFirst(field.name)+";}\n")
+ else:
+ stream.write(self.getIndent())
+ stream.write("const "+targetTypeName+"&
get"+self.upperFirst(field.name)+"() const")
+ stream.write(" {return "+field.name+";}\n")
+
+ stream.write(self.getIndent())
+ stream.write("void set"+self.upperFirst(field.name)+"(const ")
+ stream.write(targetTypeName+"&
new"+self.upperFirst(field.name)+") {")
+ if field.qualifier == "optional":
+ stream.write("\n")
+ self.indent();
+
stream.write(self.getIndent()+"has%s=true;\n"%self.upperFirst(field.name))
+
stream.write(self.getIndent()+field.name+"=new"+self.upperFirst(field.name)+";\n")
+ self.unIndent()
+ stream.write(self.getIndent())
+ else:
+
stream.write(field.name+"=new"+self.upperFirst(field.name)+";")
+ stream.write("}\n")
+
+ def writeDeclarationFieldStatement(self,stream,field):
+ stream.write(self.getIndent())
+ if field.qualifier == "repeated":
+ stream.write("std::vector<%s> %s;" %
(self.getTargetTypeName(field.typeid.name),field.name))
+ else:
+ stream.write("%s %s;" %
(self.getTargetTypeName(field.typeid.name),field.name))
+ self.writeComment(stream, field)
+ # optional field generate another boolean field
+ # used to detect whether if the optional field has
+ # been given or not.
+ if field.qualifier == "optional":
+ stream.write(self.getIndent()+"bool has%s;\n" %
self.upperFirst(field.name))
+
+ def generateHeader(self,stream,factoryOnly=False):
+ # write the usual header protecting MACRO
+ supposedHeaderName=stream.name
+ if supposedHeaderName != "<stdout>":
+ supposedHeaderName=os.path.basename(supposedHeaderName)
+ supposedHeaderName=os.path.splitext(supposedHeaderName)[0]
+ headerProtectMacroName = supposedHeaderName
+ else:
+ (headerProtectMacroName,ext) = os.path.splitext(self.AST.name)
+ headerProtectMacroName = "%s_HH" % headerProtectMacroName.upper()
+ stream.write("#ifndef %s\n"%headerProtectMacroName)
+ stream.write("#define %s\n"%headerProtectMacroName)
+ # add necessary standard and global includes
+ stream.write(self.commentLineBeginWith+" ****-**** Global System
includes ****-****\n")
+ stream.write("#include <vector>\n")
+ self.included["#include <vector>"]=1
+ stream.write("#include <string>\n")
+ self.included["#include <string>"]=1
+ # add include coming from native type specification
+ stream.write(self.commentLineBeginWith+" ****-**** Includes coming
from native types ****-****\n")
+ for native in self.AST.natives:
+ line = native.getLanguage("CXX").statement
+ # we are only interested in native "include" statement
+ if line.find("#include")>=0 and (not line in self.included.keys()):
+ self.writeComment(stream, native)
+ stream.write(line+"\n")
+ self.included[line]=1
+ # Generate namespace for specified package package
+ # we may have nested namespace
+ self.openNamespaces(stream)
+
+ if not factoryOnly:
+ # Native type should be defined in included header
+ stream.write(self.getIndent()+self.commentLineBeginWith)
+ stream.write(" Native types has been defined:\n");
+ stream.write(self.getIndent()+self.commentLineBeginWith)
+ stream.write(" - by included headers (see above)\n")
+ stream.write(self.getIndent()+self.commentLineBeginWith)
+ stream.write(" - with typedef (see below [if any])\n")
+ for native in self.AST.natives:
+ line = native.getLanguage("CXX").statement
+ # we are only interested in native statement
+ # which are not #include
+ if line.find("typedef")>=0 and (not line in
self.typedefed.keys()):
+ self.writeComment(stream, native)
+ stream.write(self.getIndent()+line+"\n")
+ self.typedefed[line]=1
+
+ # Generate enum
+ for enum in self.AST.enums:
+ self.writeComment(stream, enum)
+ stream.write(self.getIndent())
+ stream.write("typedef enum %s {\n" % enum.name)
+ self.indent()
+ first = True
+ lastname = (enum.values[len(enum.values)-1]).name
+ for enumval in enum.values:
+ if first:
+ stream.write(self.getIndent())
+ stream.write("%s = %d, " %
(enumval.name,enumval.value))
+ first=False
+ else:
+ stream.write(self.getIndent())
+ if (enumval.name==lastname):
+ stream.write("%s " % enumval.name)
+ else:
+ stream.write("%s, " % enumval.name)
+ self.writeComment(stream, enumval)
+ self.unIndent()
+ stream.write(self.getIndent())
+ stream.write("} %s_t; " % enum.name)
+ stream.write(self.commentLineBeginWith + "end of enum %s \n" %
enum.name)
+
+ # Generate message type
+ for msg in self.AST.messages:
+ self.writeComment(stream, msg)
+ stream.write(self.getIndent())
+ stream.write("class CERTI_EXPORT %s" % msg.name)
+ if msg.hasMerge():
+ stream.write(" : public %s {\n" % msg.merge.name)
+ virtual = "virtual "
+ else:
+ stream.write(" {\n")
+ virtual = ""
+
+ self.indent()
+
+ # begin public
+ stream.write(self.getIndent()+"public:\n")
+ self.indent()
+ if msg.hasMerge():
+ stream.write(self.getIndent()+"typedef %s
Super;\n"%msg.merge.name)
+ # now write constructor/destructor
+ stream.write(self.getIndent()+msg.name+"();\n")
+ stream.write(self.getIndent()+virtual+"~"+msg.name+"();\n")
+
+ # write virtual serialize and deserialize
+ # if we have some specific field
+ if len(msg.fields)>0:
+ # serialize/deserialize
+ stream.write(self.getIndent()+virtual+"void
serialize(MessageBuffer& msgBuffer);\n")
+ stream.write(self.getIndent()+virtual+"void
deserialize(MessageBuffer& msgBuffer);\n")
+ # specific getter/setter
+ stream.write(self.getIndent()+self.commentLineBeginWith+"
specific Getter(s)/Setter(s)\n")
+ for field in msg.fields:
+ self.writeOneGetterSetter(stream,field)
+ # the show method
+ stream.write(self.getIndent()+self.commentLineBeginWith+"
the show method\n")
+ stream.write(self.getIndent()+virtual+"void
show(std::ostream& out);\n")
+
+ self.unIndent()
+ # end public:
+
+ # begin protected
+ stream.write(self.getIndent()+"protected:\n")
+ self.indent()
+ for field in msg.fields:
+ self.writeDeclarationFieldStatement(stream,field)
+ self.unIndent()
+ # end protected
+
+ # begin private
+ stream.write(self.getIndent()+"private:\n")
+ self.indent()
+ self.unIndent()
+ # end private
+
+ self.unIndent()
+ stream.write(self.getIndent() + "};\n")
+
+ # Generate Factory (if any)
+ # @todo
+ if self.AST.hasFactory():
+ self.writeComment(stream, self.AST.factory)
+ stream.write(self.getIndent() + "class CERTI_EXPORT %s {\n" %
self.AST.factory.name)
+ self.indent()
+ # begin public
+ stream.write(self.getIndent()+"public:\n")
+ self.indent()
+ stream.write(self.getIndent()+"static %s* %s(%s type) throw
(RTIinternalError);\n"% self.AST.factory.creator)
+ stream.write(self.getIndent()+"static %s* %s(%s stream) throw
(RTIinternalError);\n"% self.AST.factory.receiver)
+ self.unIndent()
+ #end public
+ #begin protected
+ stream.write(self.getIndent()+"protected:\n")
+ self.indent()
+ self.unIndent()
+ #end protected
+ #begin private
+ stream.write(self.getIndent()+"private:\n")
+ self.indent()
+ self.unIndent()
+ #end private
+ self.unIndent()
+ stream.write(self.getIndent()+"};\n\n")
+
+ # may close any open namespaces
+ self.closeNamespaces(stream)
+ # close usual HEADER protecting MACRO
+ stream.write(self.commentLineBeginWith+" %s\n"%headerProtectMacroName)
+ stream.write("#endif\n")
+
+ def writeInitFieldStatement(self,stream,field):
+ if field.hasDefaultValue():
+ stream.write(self.getIndent())
+ stream.write(field.name+"="+str(field.defaultValue)+";\n")
+ else:
+ stream.write(self.getIndent())
+ stream.write(self.commentLineBeginWith)
+ stream.write(field.name+"= <no default value in message spec using
builtin>\n")
+ # FIXME find a default value for every type beside natives
+
+ def writeSerializeFieldStatement(self,stream,field):
+ indexField = ''
+ if field.qualifier == "optional":
+ stream.write(self.getIndent())
+ stream.write("msgBuffer.write_bool(has%s);\n" %
self.upperFirst(field.name))
+ stream.write(self.getIndent())
+ stream.write("if (has%s) {\n" % self.upperFirst(field.name))
+ self.indent()
+ elif field.qualifier == "repeated":
+ indexField = '[i]'
+ stream.write(self.getIndent())
+ stream.write("uint32_t "+field.name+"Size =
"+field.name+".size();\n")
+ stream.write(self.getIndent())
+ stream.write("msgBuffer.write_uint32("+field.name+"Size);\n")
+ stream.write(self.getIndent())
+ stream.write("for (uint32_t i = 0; i < "+field.name+"Size; ++i)
{\n")
+ self.indent()
+
+ stream.write(self.getIndent())
+ methodName = self.getSerializeMethodName(field.typeid.name)
+ if None == methodName:
+ if field.typeid.name in [m.name for m in self.AST.messages]:
+ stream.write(field.name+indexField+".serialize(msgBuffer);\n")
+ else:
+ stream.write(self.commentLineBeginWith+" FIXME FIXME FIXME\n")
+ stream.write(self.getIndent()+self.commentLineBeginWith+"
don't know how to serialize native field <%s> of type
<%s>\n"%(field.name,field.typeid.name))
+ else:
+ stream.write("msgBuffer."+methodName)
+ stream.write("("+field.name+indexField+");\n")
+
+ if field.qualifier == "optional":
+ self.unIndent()
+ stream.write(self.getIndent()+"}\n")
+ elif field.qualifier == "repeated":
+ self.unIndent()
+ stream.write(self.getIndent()+"}\n")
+
+ def writeShowFieldStatement(self,stream,field):
+ indexField = ''
+ if field.qualifier == "optional":
+ stream.write(self.getIndent())
+ stream.write("out << \"(opt) %s =\" " % field.name)
+ elif field.qualifier == "repeated":
+ indexField = '[i]'
+ stream.write(self.getIndent())
+ stream.write("out << \" %s [] =\" << std::endl;\n" % field.name
)
+ stream.write(self.getIndent())
+ stream.write("for (uint32_t i = 0; i <
get"+self.upperFirst(field.name)+"Size(); ++i) {\n")
+ self.indent()
+ stream.write(self.getIndent()+"out ")
+ else:
+ stream.write(self.getIndent())
+ stream.write("out << \" %s = \" " % field.name)
+
+ methodName = self.getSerializeMethodName(field.typeid.name)
+ if None == methodName:
+ if field.typeid.name in [m.name for m in self.AST.messages]:
+ stream.write("<< \"FIXME inherited \";\n ")
+ stream.write(self.commentLineBeginWith+" FIXME FIXME FIXME
inherited message\n")
+ else:
+ stream.write("<< \"")
+ stream.write(self.getIndent()+self.commentLineBeginWith+"FIXME
FIXME don't know how to serialize native field <%s> of type
<%s>"%(field.name,field.typeid.name))
+ stream.write("\"")
+
+ else:
+ stream.write("<< %s << \" \" " % (field.name+indexField))
+
+ if field.qualifier == "optional":
+ stream.write(self.getIndent()+"<< std::endl;\n")
+ elif field.qualifier == "repeated":
+ stream.write(";\n")
+ self.unIndent()
+ stream.write(self.getIndent()+"}\n")
+ stream.write(self.getIndent()+"out << std::endl;\n")
+ else:
+ stream.write(self.getIndent()+"<< std::endl;\n")
+
+
+ def writeDeSerializeFieldStatement(self,stream,field):
+ indexField = ''
+ if field.qualifier == "optional":
+ stream.write(self.getIndent())
+ stream.write("has%s = msgBuffer.read_bool();\n" %
self.upperFirst(field.name))
+ stream.write(self.getIndent())
+ stream.write("if (has%s) {\n" % self.upperFirst(field.name))
+ self.indent()
+ elif field.qualifier == "repeated":
+ indexField = '[i]'
+ stream.write(self.getIndent())
+ stream.write("uint32_t "+field.name+"Size =
msgBuffer.read_uint32();\n")
+ stream.write(self.getIndent())
+ stream.write(field.name+".resize("+field.name+"Size);\n")
+ stream.write(self.getIndent())
+ stream.write("for (uint32_t i = 0; i < "+field.name+"Size; ++i)
{\n")
+ self.indent()
+
+ stream.write(self.getIndent())
+ methodName = self.getDeSerializeMethodName(field.typeid.name)
+ if None == methodName:
+ if field.typeid.name in [m.name for m in self.AST.messages]:
+
stream.write(field.name+indexField+".deserialize(msgBuffer);\n")
+ else:
+ stream.write(self.commentLineBeginWith+" FIXME FIXME FIXME\n")
+ stream.write(self.getIndent()+self.commentLineBeginWith+"
don't know how to deserialize native field <%s> of type
<%s>\n"%(field.name,field.typeid.name))
+ else:
+ if methodName == 'read_string':
+
stream.write("msgBuffer."+methodName+"("+field.name+indexField+");\n")
+ else:
+ # We may have to vast in order to enforce conversion
+ if isinstance(field.typeid,NativeType):
+ stream.write(field.name+indexField+" =
static_cast<"+field.typeid.name+">(msgBuffer."+methodName+"());\n")
+ else:
+ stream.write(field.name+indexField+" =
msgBuffer."+methodName+"();\n")
+
+ if field.qualifier == "optional":
+ self.unIndent()
+ stream.write(self.getIndent()+"}\n")
+ elif field.qualifier == "repeated":
+ self.unIndent()
+ stream.write(self.getIndent()+"}\n")
+
+ def writeFactoryCreator(self,stream):
+ creator =
(self.AST.factory.creator[0],self.AST.factory.name)+self.AST.factory.creator[1:]
+ stream.write(self.getIndent()+"%s* %s::%s(%s type) throw
(RTIinternalError) {\n"% creator)
+ self.indent()
+ stream.write(self.getIndent()+"%s* msg;\n\n" % creator[0])
+ stream.write(self.getIndent() + "switch (type) {\n")
+ self.indent()
+ for e in self.AST.eMessageType.values:
+ #stream.write(self.getIndent()+"case %s::%s:\n" %
(creator[0],e.name))
+ stream.write(self.getIndent()+"case %s::%s:\n" %
(creator[0],e.name.replace("M_","",1)))
+ self.indent()
+ if None==e.type:
+ stream.write(self.getIndent()+"throw RTIinternalError(\"%s
message type should not be used!!\");\n"%e.name)
+ else:
+ stream.write(self.getIndent()+"msg = new %s();\n" % e.type)
+ stream.write(self.getIndent()+"break;\n")
+ self.unIndent()
+ self.unIndent()
+ stream.write(self.getIndent()+ "} "+self.commentLineBeginWith+" end if
switch (type)\n")
+ stream.write(self.getIndent()+ "return msg;\n")
+ self.unIndent()
+ stream.write(self.getIndent()+("} /* end of %s::%s */\n\n" %
(creator[1],creator[2])))
+
+ def writeFactoryReceiver(self,stream):
+ receiver =
(self.AST.factory.receiver[0],self.AST.factory.name)+self.AST.factory.receiver[1:]
+ stream.write(self.getIndent()+"%s* %s::%s(%s stream) throw
(RTIinternalError) {\n"% receiver)
+ self.indent()
+ stream.write(self.getIndent()+self.commentLineBeginWith+" FIXME This
is not thread safe\n")
+ stream.write(self.getIndent()+"static MessageBuffer msgBuffer;\n")
+ stream.write(self.getIndent()+"%s msgGen;\n" % receiver[0])
+ stream.write(self.getIndent()+"%s* msg;\n\n" % receiver[0])
+ stream.write(self.getIndent()+self.commentLineBeginWith+" receive
generic message \n")
+ stream.write(self.getIndent()+"msgGen.receive(stream,msgBuffer);\n")
+ stream.write(self.getIndent()+self.commentLineBeginWith+" create
specific message from type \n")
+
+ stream.write(self.getIndent()+"msg = ");
+
stream.write(self.AST.factory.name+"::"+self.AST.factory.creator[1]+"(msgGen.getType());\n")
+
+
stream.write(self.getIndent()+"msgBuffer.assumeSizeFromReservedBytes();\n")
+ stream.write(self.getIndent()+"msg->deserialize(msgBuffer);\n")
+ stream.write(self.getIndent()+"return msg;\n")
+ self.unIndent()
+ stream.write(self.getIndent()+("} /* end of %s::%s */ \n\n" %
(receiver[1],receiver[2])))
+
+
+ def generateBody(self,stream,factoryOnly=False):
+ """
+ Generate the body.
+ """
+ # add necessary standard includes
+ stream.write("#include <vector>\n")
+ stream.write("#include <string>\n")
+
+ # [Try to] add corresponding header include
+ supposedHeaderName=stream.name
+ if supposedHeaderName != "<stdout>":
+ supposedHeaderName=os.path.basename(supposedHeaderName)
+ supposedHeaderName=os.path.splitext(supposedHeaderName)[0]
+ stream.write("#include \""+supposedHeaderName+".hh\"\n")
+ # Generate namespace for specified package package
+ # we may have nested namespace
+ self.openNamespaces(stream)
+ if not factoryOnly:
+ # Generate message type
+ for msg in self.AST.messages:
+ # Generate Constructor
+ stream.write(self.getIndent()+"%s::%s() {\n" %
(msg.name,msg.name))
+ self.indent()
+ # Assign my name.
+ stream.write(self.getIndent()+"this->messageName =
\""+msg.name+"\";\n")
+ #stream.write(self.getIndent()+"this->type =
"+msg.name.upper().replace("NM_","NetworkMessage::")+";\n")
+ stream.write(self.getIndent()+"this->type =
"+msg.name.upper().replace("M_","Message::",1)+";\n")
+ # Write init value if any was provided
+ if len(msg.fields)>0:
+ for field in msg.fields:
+ self.writeInitFieldStatement(stream,field)
+ self.unIndent()
+ stream.write(self.getIndent()+"}\n\n")
+ # Generate Destructor
+ stream.write(self.getIndent()+"%s::~%s() {\n" %
(msg.name,msg.name))
+ self.indent()
+ self.unIndent()
+ stream.write(self.getIndent()+"}\n\n")
+
+ # write virtual serialize and deserialize
+ # if we have some specific field
+ if len(msg.fields)>0:
+ # begin serialize method
+ stream.write(self.getIndent()+"void
%s::serialize(MessageBuffer& msgBuffer) {\n" % msg.name)
+ self.indent()
+ if msg.hasMerge():
+
stream.write(self.getIndent()+self.commentLineBeginWith)
+ stream.write("Call mother class\n")
+
stream.write(self.getIndent()+"Super::serialize(msgBuffer);\n")
+ stream.write(self.getIndent()+self.commentLineBeginWith)
+ stream.write("Specific serialization code\n")
+ for field in msg.fields:
+ self.writeSerializeFieldStatement(stream,field)
+ self.unIndent()
+ stream.write(self.getIndent()+"}\n\n")
+ # end serialize method
+
+ # begin deserialize method
+ stream.write(self.getIndent()+"void
%s::deserialize(MessageBuffer& msgBuffer) {\n" % msg.name)
+ self.indent()
+ if msg.hasMerge():
+
stream.write(self.getIndent()+self.commentLineBeginWith)
+ stream.write("Call mother class\n")
+
stream.write(self.getIndent()+"Super::deserialize(msgBuffer);\n")
+ stream.write(self.getIndent()+self.commentLineBeginWith)
+ stream.write("Specific deserialization code\n")
+ for field in msg.fields:
+ self.writeDeSerializeFieldStatement(stream,field)
+ self.unIndent()
+ stream.write(self.getIndent()+"}\n\n")
+ # end deserialize method
+ # begin show method
+ stream.write(self.getIndent()+"void %s::show(std::ostream&
out) {\n" % msg.name)
+ self.indent()
+ stream.write(self.getIndent()+"out << \"[%s -Begin]\" <<
std::endl;" % msg.name)
+ if msg.hasMerge():
+
stream.write(self.getIndent()+self.commentLineBeginWith)
+ stream.write("Call mother class\n")
+ stream.write(self.getIndent()+"Super::show(out);\n")
+ stream.write(self.getIndent()+self.commentLineBeginWith)
+ stream.write("Specific show code\n")
+ for field in msg.fields:
+ self.writeShowFieldStatement(stream,field)
+ stream.write(self.getIndent()+"out << \"[%s -End]\" <<
std::endl;" % msg.name)
+ self.unIndent()
+ stream.write(self.getIndent()+"}\n\n")
+ # end show method
+
+ # Generate Factory (if any)
+ # @todo
+ if self.AST.hasFactory():
+ # begin creator
+ self.writeFactoryCreator(stream)
+ # begin receiver
+ self.writeFactoryReceiver(stream)
+
+ self.closeNamespaces(stream)
- [certi-cvs] certi/scripts GenerateMessages.py GenMsgJava.py...,
certi-cvs <=