private void EmitClassIdentity(ClassNode cnode, StringBuilder sb, int level) { string padding = new String('\t', level); if (cnode.Ident != null) { if (cnode.Name.Contains("MsgGC")) { sb.AppendLine(padding + "- (EGCMsg) eMsg"); sb.AppendLine(padding + "{"); sb.AppendLine(padding + "\treturn " + EmitType(cnode.Ident) + ";"); sb.AppendLine(padding + "}"); sb.AppendLine(); } else { sb.AppendLine(padding + "- (EMsg) eMsg"); sb.AppendLine(padding + "{"); sb.AppendLine(padding + "\treturn " + EmitType(cnode.Ident) + ";"); sb.AppendLine(padding + "}"); sb.AppendLine(); } } else if (cnode.Name.Contains("Hdr")) { if (cnode.Name.Contains("MsgGC")) { if (cnode.childNodes.Find(node => node.Name == "msg") != null) { sb.AppendLine(padding + "- (void) setEMsg:(EGCMsg)_msg"); sb.AppendLine(padding + "{"); sb.AppendLine(padding + "\tself.msg = _msg;"); sb.AppendLine(padding + "}"); sb.AppendLine(); } else { // this is required for a gc header which doesn't have an emsg sb.AppendLine(padding + "- (void) setEMsg:(EGCMsg)msg { }"); sb.AppendLine(); } } else { sb.AppendLine(padding + "- (void) setEMsg:(EMsg)_msg"); sb.AppendLine(padding + "{"); sb.AppendLine(padding + "\tself.msg = _msg;"); sb.AppendLine(padding + "}"); sb.AppendLine(); } } }
protected override void EmitClassNode(ClassNode cnode, StringBuilder sb, int level) { EmitClassDef(cnode, sb, level, false); EmitClassIdentity(cnode, sb, level + 1); int baseSize = EmitClassProperties(cnode, sb, level + 1); EmitClassConstructor(cnode, sb, level + 1); EmitClassDestructor(cnode, sb, level + 1); EmitClassSerializer(cnode, sb, level + 1, baseSize); EmitClassDeserializer(cnode, sb, level + 1, baseSize); EmitClassDef(cnode, sb, level, true); }
private void EmitClassDef(ClassNode cnode, StringBuilder sb, int level, bool end) { string padding = new String('\t', level); if (end) { sb.AppendLine(padding + "@end"); sb.AppendLine(); return; } if (cnode.Name.Contains("Hdr")) { sb.AppendLine(padding + "//[StructLayout( LayoutKind.Sequential )]"); } sb.AppendLine(padding + "@implementation _SK" + cnode.Name); sb.AppendLine(); }
private void EmitClassDef(ClassNode cnode, StringBuilder sb, int level, bool end) { string padding = new String(' ', level * 2); if (end) { sb.AppendLine(padding + "};"); sb.AppendLine(); sb.AppendLine("Steam.Internal." + cnode.Name + " = " + cnode.Name + ";"); return; } sb.AppendLine(); sb.AppendLine(); sb.AppendLine(padding + "var " + cnode.Name + " = {"); }
private void EmitClassSerializer(ClassNode cnode, StringBuilder sb, int level, int baseSize) { string padding = new String('\t', level); sb.AppendLine(); sb.AppendLine(padding + "public void Serialize(Stream stream)"); sb.AppendLine(padding + "{"); // first emit variable length members List<String> varLengthProps = new List<String>(); List<String> openedStreams = new List<String>(); varLengthProps.Add(baseSize.ToString()); if (cnode.Parent != null) { sb.AppendLine(padding + "\tHeader.Serialize(stream);"); varLengthProps.Add("(int)msHeader.Length"); openedStreams.Add("msHeader"); sb.AppendLine(); } foreach (PropNode prop in cnode.childNodes) { string typestr = EmitType(prop.Type); int size = CodeGenerator.GetTypeSize(prop); if (size == 0) { if (prop.Flags != null && prop.Flags == "proto") { if (baseSize == 0) { // early exit sb.AppendLine(padding + "\tProtoBuf.Serializer.Serialize<" + typestr + ">(stream, " + GetUpperName(prop.Name) + ");"); sb.AppendLine(padding + "}"); return; } sb.AppendLine(padding + "\tMemoryStream ms" + GetUpperName(prop.Name) + " = new MemoryStream();"); sb.AppendLine(padding + "\tProtoBuf.Serializer.Serialize<" + typestr + ">(ms" + GetUpperName(prop.Name) + ", " + GetUpperName(prop.Name) + ");"); if (prop.FlagsOpt != null) { sb.AppendLine(padding + "\t" + GetUpperName(prop.FlagsOpt) + " = (int)ms" + GetUpperName(prop.Name) + ".Length;"); } //sb.AppendLine(padding + "\tms" + GetUpperName(prop.Name) + ".Seek( 0, SeekOrigin.Begin );"); } else { sb.AppendLine(padding + "\tMemoryStream ms" + GetUpperName(prop.Name) + " = " + GetUpperName(prop.Name) + ".serialize();"); } varLengthProps.Add( "(int)ms" + GetUpperName(prop.Name) + ".Length" ); openedStreams.Add( "ms" + GetUpperName(prop.Name) ); } } //sb.AppendLine(padding + "\tBinaryWriterEx bw = new BinaryWriterEx( stream );"); //sb.AppendLine(); sb.AppendLine(padding + "\tBinaryWriter bw = new BinaryWriter( stream );"); sb.AppendLine(); if (cnode.Parent != null) { sb.AppendLine(padding + "\tmsHeader.CopyTo( msBuffer );"); } // next emit writers foreach (PropNode prop in cnode.childNodes) { string typecast = ""; string propName = GetUpperName(prop.Name); if (prop.Type is StrongSymbol && ((StrongSymbol)prop.Type).Class is EnumNode) { EnumNode enode = ((StrongSymbol)prop.Type).Class as EnumNode; if (enode.Type is WeakSymbol) typecast = "(" + ((WeakSymbol)enode.Type).Identifier + ")"; else typecast = "(int)"; } if (prop.Flags != null) { if ( prop.Flags == "steamidmarshal" || prop.Flags == "gameidmarshal" || prop.Flags == "boolmarshal" ) { propName = prop.Name; } else if ( prop.Flags == "proto" ) { sb.AppendLine( padding + "\tbw.Write( ms" + propName + ".ToArray() );" ); continue; } else if ( prop.Flags == "const" ) { continue; } } if (prop.Flags == "protomask") { if ( prop.Default is StrongSymbol && ( prop.Default as StrongSymbol ).Class.Name == "EGCMsg" ) propName = "MsgUtil.MakeGCMsg( " + propName + ", true )"; else propName = "MsgUtil.MakeMsg( " + propName + ", true )"; } sb.AppendLine(padding + "\tbw.Write( " + typecast + propName + " );"); } sb.AppendLine(); foreach (String stream in openedStreams) { sb.AppendLine(padding + "\t" + stream + ".Close();"); } //sb.AppendLine(); //sb.AppendLine(padding + "\tmsBuffer.Seek( 0, SeekOrigin.Begin );"); sb.AppendLine(padding + "}"); }
private void EmitClassDeserializer(ClassNode cnode, StringBuilder sb, int level, int baseSize) { string padding = new String('\t', level); sb.AppendLine(); sb.AppendLine(padding + "public void Deserialize( Stream stream )"); sb.AppendLine(padding + "{"); if (baseSize > 0) { sb.AppendLine(padding + "\tBinaryReader br = new BinaryReader( stream );"); sb.AppendLine(); } if (cnode.Parent != null) { sb.AppendLine(padding + "\tHeader.Deserialize( stream );"); } foreach (PropNode prop in cnode.childNodes) { string typestr = EmitType(prop.Type); int size = CodeGenerator.GetTypeSize(prop); string defflags = prop.Flags; string symname = GetUpperName(prop.Name); if ( defflags != null && ( defflags == "steamidmarshal" || defflags == "gameidmarshal" || defflags == "boolmarshal" ) ) { symname = prop.Name; } else if ( defflags != null && defflags == "const" ) { continue; } if (size == 0) { if (prop.Flags != null && prop.Flags == "proto") { if (prop.FlagsOpt != null) { sb.AppendLine(padding + "\tusing( MemoryStream ms" + GetUpperName(prop.Name) + " = new MemoryStream( br.ReadBytes( " + GetUpperName(prop.FlagsOpt) + " ) ) )"); sb.AppendLine(padding + "\t\t" + GetUpperName(prop.Name) + " = ProtoBuf.Serializer.Deserialize<" + typestr + ">( ms" + GetUpperName(prop.Name) + " );"); } else { sb.AppendLine(padding + "\t" + GetUpperName(prop.Name) + " = ProtoBuf.Serializer.Deserialize<" + typestr + ">( stream );"); } } else { sb.AppendLine(padding + "\t" + GetUpperName(prop.Name) + ".Deserialize( stream );"); } } else { string typecast = ""; if (!readerTypeMap.ContainsKey(typestr)) { typecast = "(" + typestr + ")"; typestr = CodeGenerator.GetTypeOfSize(size, SupportsUnsignedTypes()); } string call = "br.Read" + readerTypeMap[typestr] + "()"; if (!String.IsNullOrEmpty(prop.FlagsOpt)) { call = "br.Read" + readerTypeMap[typestr] + "s( " + prop.FlagsOpt + " )"; } if (prop.Flags == "protomask") { if ( prop.Default is StrongSymbol && ( prop.Default as StrongSymbol ).Class.Name == "EGCMsg" ) call = "MsgUtil.GetGCMsg( (uint)" + call + " )"; else call = "MsgUtil.GetMsg( (uint)" + call + " )"; } sb.AppendLine(padding + "\t" + symname + " = " + typecast + call + ";"); } } sb.AppendLine(padding + "}"); }
private void EmitClassDef(ClassNode cnode, StringBuilder sb, int level, bool end) { string padding = new String('\t', level); if (end) { sb.AppendLine(padding + "}"); sb.AppendLine(); return; } string parent = "ISteamSerializable"; if (cnode.Ident != null) { if ( cnode.Name.Contains( "MsgGC" ) ) { parent = "IGCSerializableMessage"; } else { parent = "ISteamSerializableMessage"; } } else if (cnode.Name.Contains("Hdr")) { if ( cnode.Name.Contains( "MsgGC" ) ) parent = "IGCSerializableHeader"; else parent = "ISteamSerializableHeader"; } if ( cnode.Name.Contains( "Hdr" ) ) { sb.AppendLine( padding + "[StructLayout( LayoutKind.Sequential )]" ); } sb.AppendLine(padding + "public class " + cnode.Name + " : " + parent); sb.AppendLine(padding + "{"); }
private int EmitClassProperties(ClassNode cnode, StringBuilder sb, int level) { string padding = new String('\t', level); int baseClassSize = 0; if (cnode.Parent != null) { sb.AppendLine(padding + "public " + EmitType(cnode.Parent) + " Header { get; set; }"); } foreach (PropNode prop in cnode.childNodes) { string typestr = EmitType(prop.Type); string propName = GetUpperName(prop.Name); if (prop.Flags != null && prop.Flags == "const") { sb.AppendLine(padding + "public static readonly " + typestr + " " + propName + " = " + EmitType(prop.Default) + ";"); continue; } int size = CodeGenerator.GetTypeSize(prop); baseClassSize += size; sb.AppendLine( padding + "// Static size: " + size); if (prop.Flags != null && prop.Flags == "steamidmarshal" && typestr == "ulong") { sb.AppendLine( padding + string.Format( "private {0} {1};", typestr, prop.Name ) ); sb.AppendLine( padding + "public SteamID " + propName + " { get { return new SteamID( " + prop.Name + " ); } set { " + prop.Name + " = value.ConvertToUInt64(); } }"); } else if ( prop.Flags != null && prop.Flags == "boolmarshal" && typestr == "byte" ) { sb.AppendLine( padding + string.Format( "private {0} {1};", typestr, prop.Name ) ); sb.AppendLine( padding + "public bool " + propName + " { get { return ( " + prop.Name + " == 1 ); } set { " + prop.Name + " = ( byte )( value ? 1 : 0 ); } }" ); } else if ( prop.Flags != null && prop.Flags == "gameidmarshal" && typestr == "ulong" ) { sb.AppendLine( padding + string.Format( "private {0} {1};", typestr, prop.Name ) ); sb.AppendLine( padding + "public GameID " + propName + " { get { return new GameID( " + prop.Name + " ); } set { " + prop.Name + " = value.ToUInt64(); } }" ); } else { int temp; if ( !String.IsNullOrEmpty( prop.FlagsOpt ) && Int32.TryParse( prop.FlagsOpt, out temp ) ) { typestr += "[]"; } sb.AppendLine( padding + "public " + typestr + " " + propName + " { get; set; }" ); } } sb.AppendLine(); return baseClassSize; }
private void EmitClassEMsg(ClassNode cnode, StringBuilder sb) { if (cnode.Ident == null) return; string ident = EmitSymbol(cnode.Ident); if (!ident.Contains("EMsg_")) return; sb.AppendLine("func (d *" + cnode.Name + ") GetEMsg() EMsg {"); sb.AppendLine(" return " + ident); sb.AppendLine("}"); sb.AppendLine(); }
private void EmitClassSerializer(ClassNode cnode, StringBuilder sb) { var nodeToBuf = new Dictionary<PropNode, string>(); int tempNum = 0; sb.AppendLine("func (d *" + cnode.Name + ") Serialize(w io.Writer) error {"); sb.AppendLine(" var err error"); foreach (PropNode node in cnode.childNodes) { if (node.Flags == "proto") { sb.AppendLine(" buf" + tempNum + ", err := proto.Marshal(d." + GetUpperName(node.Name) + ")"); sb.AppendLine(" if err != nil { return err }"); if (node.FlagsOpt != null) { sb.AppendLine(" d." + GetUpperName(node.FlagsOpt) + " = int32(len(buf" + tempNum + "))"); } nodeToBuf[node] = "buf" + tempNum; tempNum++; } } foreach (PropNode node in cnode.childNodes) { if (node.Flags == "const") { continue; } else if (node.Flags == "boolmarshal") { sb.AppendLine(" err = rwu.WriteBool(w, d." + GetUpperName(node.Name) + ")"); } else if (node.Flags == "steamidmarshal") { sb.AppendLine(" err = binary.Write(w, binary.LittleEndian, d." + GetUpperName(node.Name) + ")"); } else if (node.Flags == "protomask") { sb.AppendLine(" err = binary.Write(w, binary.LittleEndian, EMsg(uint32(d." + GetUpperName(node.Name) + ") | ProtoMask))"); } else if (node.Flags == "protomaskgc") { sb.AppendLine(" err = binary.Write(w, binary.LittleEndian, EMsg(uint32(d." + GetUpperName(node.Name) + ") | ProtoMask))"); } else if (node.Flags == "proto") { sb.AppendLine(" _, err = w.Write(" + nodeToBuf[node] + ")"); } else { sb.AppendLine(" err = binary.Write(w, binary.LittleEndian, d." + GetUpperName(node.Name) + ")"); } if (node != cnode.childNodes[cnode.childNodes.Count - 1]) sb.AppendLine(" if err != nil { return err }"); } sb.AppendLine(" return err"); sb.AppendLine("}"); sb.AppendLine(); }
private void EmitClassSerializer(ClassNode cnode, StringBuilder sb, int level, int baseSize) { string padding = new String(' ', level * 2); //sb.AppendLine(); sb.AppendLine(padding + "serialize: function(object) {"); // first emit variable length members List<String> varLengthProps = new List<String>(); varLengthProps.Add(baseSize.ToString()); //if (cnode.Parent != null) //{ // sb.AppendLine(padding + "\tHeader.Serialize(stream);"); // varLengthProps.Add("(int)msHeader.Length"); // openedStreams.Add("msHeader"); // sb.AppendLine(); //} foreach (PropNode prop in cnode.childNodes) { string typestr = EmitType(prop.Type); int size = CodeGenerator.GetTypeSize(prop); if (size == 0) { if (prop.Flags != null && prop.Flags == "proto") { if (baseSize == 0) { // early exit sb.AppendLine(padding + " return " + typestr + ".serialize(object." + prop.Name + " || {});"); sb.AppendLine(padding + "},"); return; } sb.AppendLine(padding + " var buf" + GetUpperName(prop.Name) + " = " + typestr + ".serialize(object." + prop.Name + " || {});"); if (prop.FlagsOpt != null) { sb.AppendLine(padding + " object." + prop.FlagsOpt + " = buf" + GetUpperName(prop.Name) + ".length;"); } } else { //sb.AppendLine(padding + "\tMemoryStream ms" + GetUpperName(prop.Name) + " = " + GetUpperName(prop.Name) + ".serialize();"); } varLengthProps.Add("buf" + GetUpperName(prop.Name) + ".length"); } } sb.AppendLine(padding + " var buffer = new Buffer(" + String.Join(" + ", varLengthProps.ToArray()) + ");"); sb.AppendLine(); if (cnode.Parent != null) { //sb.AppendLine(padding + "\tmsHeader.CopyTo( msBuffer );"); } // next emit writers var offset = 0; foreach (PropNode prop in cnode.childNodes) { string typestr = EmitType(prop.Type); int size = CodeGenerator.GetTypeSize(prop); string propName = "object." + prop.Name; if (prop.Flags != null) { if (prop.Flags == "proto") { sb.AppendLine(padding + " buf" + GetUpperName(prop.Name) + ".copy(buffer, " + offset + ");"); continue; } else if (prop.Flags == "const") { continue; } } if (prop.Flags == "protomask" || prop.Flags == "protomaskgc") { propName = propName + " | protoMask"; } if (!readerTypeMap.ContainsKey(typestr)) { typestr = CodeGenerator.GetTypeOfSize(size, SupportsUnsignedTypes()); } Symbol defsym = prop.Default; string ctor = EmitType(defsym); if (defsym == null) { ctor = "0"; } string call = "buffer.write" + readerTypeMap[typestr] + "(" + propName + " || " + ctor + ", " + offset + ");"; if (!String.IsNullOrEmpty(prop.FlagsOpt)) { call = propName + " && " + propName + ".copy(buffer, " + offset + ");"; } sb.AppendLine(padding + " " + call); offset += size; } sb.AppendLine(); sb.AppendLine(padding + " return buffer;"); sb.AppendLine(padding + "},"); }
private void EmitClassDef(ClassNode cnode, StringBuilder sb) { sb.AppendLine("type " + cnode.Name + " struct {"); foreach (PropNode node in cnode.childNodes) { if (node.Flags == "const") { continue; } else if (node.Flags == "boolmarshal" && EmitSymbol(node.Type) == "byte") { sb.AppendLine(" " + GetUpperName(node.Name) + " bool"); } else if (node.Flags == "steamidmarshal" && EmitSymbol(node.Type) == "ulong") { sb.AppendLine(" " + GetUpperName(node.Name) + " steamid.SteamId"); } else if (node.Flags == "proto") { sb.AppendLine(" " + GetUpperName(node.Name) + " *" + EmitType(node.Type)); } else { int arraySize; string typestr = EmitType(node.Type); if (!String.IsNullOrEmpty(node.FlagsOpt) && Int32.TryParse(node.FlagsOpt, out arraySize)) { // TODO: use arrays instead of slices? typestr = "[]" + typestr; } sb.AppendLine(" " + GetUpperName(node.Name) + " " + typestr); } } sb.AppendLine("}"); sb.AppendLine(); }
protected virtual void EmitClassNode(ClassNode n, StringBuilder sb, int level) { }
public static Node Analyze(Queue <Token> tokens) { Node root = new Node(); while (tokens.Count > 0) { Token cur = tokens.Dequeue(); switch (cur.Name) { case "EOF": break; case "preprocess": Token text = Expect(tokens, "string"); if (cur.Value == "import") { Queue <Token> parentTokens = LanguageParser.TokenizeString(File.ReadAllText(text.Value), text.Value); Node newRoot = Analyze(parentTokens); foreach (Node child in newRoot.childNodes) { root.childNodes.Add(child); } } break; case "identifier": switch (cur.Value) { case "class": { Token name = Expect(tokens, "identifier"); Token ident = null, parent = null; Token op1 = Optional(tokens, "operator", "<"); if (op1 != null) { ident = Expect(tokens, "identifier"); Token op2 = Expect(tokens, "operator", ">"); } Token expect = Optional(tokens, "identifier", "expects"); if (expect != null) { parent = Expect(tokens, "identifier"); } Token removed = Optional(tokens, "identifier", "removed"); ClassNode cnode = new ClassNode(); cnode.Name = name.Value; if (ident != null) { cnode.Ident = SymbolLocator.LookupSymbol(root, ident.Value, false); } if (parent != null) { //cnode.Parent = SymbolLocator.LookupSymbol(root, parent.Value, true); } if (removed != null) { cnode.Emit = false; } else { cnode.Emit = true; } root.childNodes.Add(cnode); ParseInnerScope(tokens, cnode, root); } break; case "enum": { Token name = Expect(tokens, "identifier"); Token datatype = null; Token op1 = Optional(tokens, "operator", "<"); if (op1 != null) { datatype = Expect(tokens, "identifier"); Token op2 = Expect(tokens, "operator", ">"); } Token flag = Optional(tokens, "identifier", "flags"); EnumNode enode = new EnumNode(); enode.Name = name.Value; if (flag != null) { enode.Flags = flag.Value; } if (datatype != null) { enode.Type = SymbolLocator.LookupSymbol(root, datatype.Value, false); } root.childNodes.Add(enode); ParseInnerScope(tokens, enode, root); } break; } break; } } return(root); }
private void EmitClassSize(ClassNode cnode, StringBuilder sb, int level) { }
private void EmitClassConstructor(ClassNode cnode, StringBuilder sb, int level) { string padding = new String('\t', level); sb.AppendLine(padding + "- (id) init;"); }
private int EmitClassProperties(ClassNode cnode, StringBuilder sb, int level) { string padding = new String('\t', level); int baseClassSize = 0; if (cnode.Parent != null) { sb.AppendLine(padding + "@property (nonatomic, readwrite) " + EmitType(cnode.Parent) + " header;"); } foreach (PropNode prop in cnode.childNodes) { string typestr = EmitType(prop.Type); string propName = GetPropertyName(prop.Name); if (prop.Flags != null && prop.Flags == "const") { sb.AppendLine(padding + "+ (" + typestr + ") " + GetUpperName(prop.Name) + ";"); continue; } int size = CodeGenerator.GetTypeSize(prop); baseClassSize += size; sb.AppendLine(padding + "// Static size: " + size); if (prop.Flags != null && prop.Flags == "steamidmarshal" && typestr == "ulong") { sb.AppendLine(padding + "@property (nonatomic, readwrite) SKSteamID * " + propName + ";"); } else if (prop.Flags != null && prop.Flags == "boolmarshal" && typestr == "byte") { sb.AppendLine(padding + "@property (nonatomic, readwrite) bool " + propName + ";"); } else if (prop.Flags != null && prop.Flags == "gameidmarshal" && typestr == "ulong") { sb.AppendLine(padding + "@property (nonatomic, readwrite) SKGameID * " + propName + ";"); } else if (prop.Flags != null && prop.Flags == "proto") { sb.AppendLine(padding + "@property (nonatomic, strong, readwrite) " + GetLastPartNameFromDottedType(typestr) + " * " + propName + ";"); } else { int temp; if (!String.IsNullOrEmpty(prop.FlagsOpt) && Int32.TryParse(prop.FlagsOpt, out temp)) { typestr = "NSData *"; } if (typestr.StartsWith("NS")) { sb.AppendLine(padding + "@property (nonatomic, strong, readwrite) " + typestr + " " + propName + ";"); } else { sb.AppendLine(padding + "@property (nonatomic, readwrite) " + typestr + " " + propName + ";"); } } } sb.AppendLine(); return(baseClassSize); }
private void EmitClassParser(ClassNode cnode, StringBuilder sb, int level, int baseSize) { string padding = new String(' ', level * 2); sb.AppendLine(); sb.AppendLine(padding + "parse: function(buffer) {"); sb.AppendLine(padding + " var object = {};"); sb.AppendLine(); if (cnode.Parent != null) { //sb.AppendLine(padding + "\tHeader.Deserialize( stream );"); } var offset = 0; foreach (PropNode prop in cnode.childNodes) { string typestr = EmitType(prop.Type); int size = CodeGenerator.GetTypeSize(prop); string defflags = prop.Flags; string symname = "object." + prop.Name; if (defflags != null && defflags == "const") { continue; } if (size == 0) { if (prop.Flags != null && prop.Flags == "proto") { if (prop.FlagsOpt != null) { sb.AppendLine(padding + " object." + prop.Name + " = " + typestr + ".parse(buffer.slice(" + offset + ", " + offset + " + object." + prop.FlagsOpt + "));"); } else { //sb.AppendLine(padding + "\t" + GetUpperName(prop.Name) + " = ProtoBuf.Serializer.Deserialize<" + typestr + ">( stream );"); } } else { //sb.AppendLine(padding + "\t" + GetUpperName(prop.Name) + ".Deserialize( stream );"); } } else { if (!readerTypeMap.ContainsKey(typestr)) { typestr = CodeGenerator.GetTypeOfSize(size, SupportsUnsignedTypes()); } string call = "buffer.read" + readerTypeMap[typestr] + "(" + offset + ")"; if (!String.IsNullOrEmpty(prop.FlagsOpt)) { call = "buffer.slice(" + offset + ", " + offset + " + " + prop.FlagsOpt + ")"; } if (prop.Flags == "protomask" || prop.Flags == "protomaskgc") { call = call + " & ~protoMask"; } sb.AppendLine(padding + " " + symname + " = " + call + ";"); } offset += size; } sb.AppendLine(); sb.AppendLine(padding + " return object;"); sb.AppendLine(padding + "}"); }
private void EmitClassIdentity(ClassNode cnode, StringBuilder sb, int level) { string padding = new String('\t', level); if (cnode.Ident != null) { var cnodeIdentAsStrongSymbol = cnode.Ident as StrongSymbol; var supressObsoletionWarning = false; if (cnodeIdentAsStrongSymbol != null) { var propNode = cnodeIdentAsStrongSymbol.Prop as PropNode; if (propNode != null && propNode.Obsolete != null) { supressObsoletionWarning = true; } } if (supressObsoletionWarning) { sb.AppendLine( padding + "#pragma warning disable 0612" ); } if ( cnode.Name.Contains( "MsgGC" ) ) { sb.AppendLine( padding + "public uint GetEMsg() { return " + EmitType( cnode.Ident ) + "; }" ); } else { sb.AppendLine( padding + "public EMsg GetEMsg() { return " + EmitType( cnode.Ident ) + "; }" ); } if (supressObsoletionWarning) { sb.AppendLine(padding + "#pragma warning restore 0612"); } sb.AppendLine(); } else if (cnode.Name.Contains("Hdr")) { if ( cnode.Name.Contains( "MsgGC" ) ) { if ( cnode.childNodes.Find( node => node.Name == "msg" ) != null ) { sb.AppendLine( padding + "public void SetEMsg( uint msg ) { this.Msg = msg; }" ); sb.AppendLine(); } else { // this is required for a gc header which doesn't have an emsg sb.AppendLine( padding + "public void SetEMsg( uint msg ) { }" ); sb.AppendLine(); } } else { sb.AppendLine( padding + "public void SetEMsg( EMsg msg ) { this.Msg = msg; }" ); sb.AppendLine(); } } }
private void EmitClassDeserializer(ClassNode cnode, StringBuilder sb) { int tempNum = 0; sb.AppendLine("func (d *" + cnode.Name + ") Deserialize(r io.Reader) error {"); sb.AppendLine(" var err error"); foreach (PropNode node in cnode.childNodes) { if (node.Flags == "const") { continue; } else if (node.Flags == "boolmarshal") { sb.AppendLine(" d." + GetUpperName(node.Name) + ", err = rwu.ReadBool(r)"); } else if (node.Flags == "steamidmarshal") { sb.AppendLine(" t" + tempNum + ", err := rwu.ReadUint64(r)"); sb.AppendLine(" if err != nil { return err }"); sb.AppendLine(" d." + GetUpperName(node.Name) + " = steamid.SteamId(t" + tempNum + ")"); tempNum++; continue; } else if (node.Flags == "protomask") { string type = EmitType(node.Type); if (enumTypes.ContainsKey(type)) type = enumTypes[type]; sb.AppendLine(" t" + tempNum + ", err := rwu.Read" + GetUpperName(type) + "(r)"); sb.AppendLine(" if err != nil { return err }"); sb.AppendLine(" d." + GetUpperName(node.Name) + " = EMsg(uint32(t" + tempNum + ") & EMsgMask)"); tempNum++; continue; } else if (node.Flags == "protomaskgc") { sb.AppendLine(" t" + tempNum + ", err := rwu.Read" + GetUpperName(EmitType(node.Type)) + "(r)"); sb.AppendLine(" if err != nil { return err }"); sb.AppendLine(" d." + GetUpperName(node.Name) + " = uint32(t" + tempNum + ") & EMsgMask"); tempNum++; continue; } else if (node.Flags == "proto") { sb.AppendLine(" buf" + tempNum + " := make([]byte, d." + GetUpperName(node.FlagsOpt) + ", d." + GetUpperName(node.FlagsOpt) + ")"); sb.AppendLine(" _, err = io.ReadFull(r, buf" + tempNum + ")"); sb.AppendLine(" if err != nil { return err }"); sb.AppendLine(" err = proto.Unmarshal(buf" + tempNum + ", d." + GetUpperName(node.Name) + ")"); tempNum++; } else { string type = EmitType(node.Type); if (!String.IsNullOrEmpty(node.FlagsOpt)) { sb.AppendLine(" err = binary.Read(r, binary.LittleEndian, d." + GetUpperName(node.Name) + ")"); } else if (!enumTypes.ContainsKey(type)) { sb.AppendLine(" d." + GetUpperName(node.Name) + ", err = rwu.Read" + GetUpperName(type) + "(r)"); } else { sb.AppendLine(" t" + tempNum + ", err := rwu.Read" + GetUpperName(enumTypes[type]) + "(r)"); if (node != cnode.childNodes[cnode.childNodes.Count - 1]) sb.AppendLine(" if err != nil { return err }"); sb.AppendLine(" d." + GetUpperName(node.Name) + " = " + type + "(t" + tempNum + ")"); tempNum++; continue; } } if (node != cnode.childNodes[cnode.childNodes.Count - 1]) sb.AppendLine(" if err != nil { return err }"); } sb.AppendLine(" return err"); sb.AppendLine("}"); sb.AppendLine(); }
private void EmitClassDef(ClassNode cnode, StringBuilder sb, int level, bool end) { string padding = new String('\t', level); if (end) { sb.AppendLine(padding + "@end"); sb.AppendLine(); return; } string parent = "_SKSteamSerializable"; if (cnode.Ident != null) { if (cnode.Name.Contains("MsgGC")) { parent = "_SKGCSerializableMessage"; } else { parent = "_SKSteamSerializableMessage"; } } else if (cnode.Name.Contains("Hdr")) { if (cnode.Name.Contains("MsgGC")) parent = "_SKGCSerializableHeader"; else parent = "_SKSteamSerializableHeader"; } if (cnode.Name.Contains("Hdr")) { sb.AppendLine(padding + "//[StructLayout( LayoutKind.Sequential )]"); } sb.AppendLine(padding + "@interface _SK" + cnode.Name + " : NSObject <" + parent + ">"); sb.AppendLine(); }
private void EmitClassNode(ClassNode cnode, StringBuilder sb) { EmitClassConstants(cnode, sb); EmitClassDef(cnode, sb); EmitClassConstructor(cnode, sb); EmitClassEMsg(cnode, sb); EmitClassSerializer(cnode, sb); EmitClassDeserializer(cnode, sb); }
private void EmitClassIdentity(ClassNode cnode, StringBuilder sb, int level) { string padding = new String('\t', level); if (cnode.Ident != null) { if (cnode.Name.Contains("MsgGC")) { sb.AppendLine(padding + "- (EGCMsg) eMsg;"); sb.AppendLine(); } else { sb.AppendLine(padding + "- (EMsg) eMsg;"); sb.AppendLine(); } } else if (cnode.Name.Contains("Hdr")) { if (cnode.Name.Contains("MsgGC")) { sb.AppendLine(padding + "- (void) setEMsg:(EGCMsg)msg;"); sb.AppendLine(); } else { sb.AppendLine(padding + "- (void) setEMsg:(EMsg)msg;"); sb.AppendLine(); } } }
public static Node Analyze( Queue<Token> tokens ) { Node root = new Node(); while (tokens.Count > 0) { Token cur = tokens.Dequeue(); switch (cur.Name) { case "EOF": break; case "preprocess": Token text = Expect(tokens, "string"); if (cur.Value == "import") { Queue<Token> parentTokens = LanguageParser.TokenizeString( File.ReadAllText( text.Value ) ); Node newRoot = Analyze( parentTokens ); foreach (Node child in newRoot.childNodes) { root.childNodes.Add(child); } } break; case "identifier": switch (cur.Value) { case "class": { Token name = Expect(tokens, "identifier"); Token ident = null, parent = null; Token op1 = Optional(tokens, "operator", "<"); if (op1 != null) { ident = Expect(tokens, "identifier"); Token op2 = Expect(tokens, "operator", ">"); } Token expect = Optional(tokens, "identifier", "expects"); if (expect != null) { parent = Expect(tokens, "identifier"); } ClassNode cnode = new ClassNode(); cnode.Name = name.Value; if (ident != null) { cnode.Ident = SymbolLocator.LookupSymbol(root, ident.Value, false); } if (parent != null) { //cnode.Parent = SymbolLocator.LookupSymbol(root, parent.Value, true); } root.childNodes.Add(cnode); ParseInnerScope(tokens, cnode, root); } break; case "enum": { Token name = Expect(tokens, "identifier"); Token datatype = null; Token op1 = Optional(tokens, "operator", "<"); if (op1 != null) { datatype = Expect(tokens, "identifier"); Token op2 = Expect(tokens, "operator", ">"); } Token flag = Optional( tokens, "identifier", "flags" ); EnumNode enode = new EnumNode(); enode.Name = name.Value; if ( flag != null ) { enode.Flags = flag.Value; } if (datatype != null) { enode.Type = SymbolLocator.LookupSymbol(root, datatype.Value, false); } root.childNodes.Add(enode); ParseInnerScope(tokens, enode, root); } break; } break; } } return root; }
private int EmitClassProperties(ClassNode cnode, StringBuilder sb, int level) { string padding = new String('\t', level); int baseClassSize = 0; if (cnode.Parent != null) { sb.AppendLine(padding + "@property (nonatomic, readwrite) " + EmitType(cnode.Parent) + " header;"); } foreach (PropNode prop in cnode.childNodes) { string typestr = EmitType(prop.Type); string propName = GetPropertyName(prop.Name); if (prop.Flags != null && prop.Flags == "const") { sb.AppendLine(padding + "+ (" + typestr + ") " + GetUpperName(prop.Name) + ";"); continue; } int size = CodeGenerator.GetTypeSize(prop); baseClassSize += size; sb.AppendLine(padding + "// Static size: " + size); if (prop.Flags != null && prop.Flags == "steamidmarshal" && typestr == "ulong") { sb.AppendLine(padding + "@property (nonatomic, readwrite) SKSteamID * " + propName + ";"); } else if (prop.Flags != null && prop.Flags == "boolmarshal" && typestr == "byte") { sb.AppendLine(padding + "@property (nonatomic, readwrite) bool " + propName + ";"); } else if (prop.Flags != null && prop.Flags == "gameidmarshal" && typestr == "ulong") { sb.AppendLine(padding + "@property (nonatomic, readwrite) SKGameID * " + propName + ";"); } else if (prop.Flags != null && prop.Flags == "proto") { sb.AppendLine(padding + "@property (nonatomic, strong, readwrite) " + GetLastPartNameFromDottedType(typestr) + " * " + propName + ";"); } else { int temp; if (!String.IsNullOrEmpty(prop.FlagsOpt) && Int32.TryParse(prop.FlagsOpt, out temp)) { typestr = "NSData *"; } if (typestr.StartsWith("NS")) { sb.AppendLine(padding + "@property (nonatomic, strong, readwrite) " + typestr + " " + propName + ";"); } else { sb.AppendLine(padding + "@property (nonatomic, readwrite) " + typestr + " " + propName + ";"); } } } sb.AppendLine(); return baseClassSize; }
private void EmitClassIdentity(ClassNode cnode, StringBuilder sb, int level) { string padding = new String('\t', level); if (cnode.Ident != null) { if ( cnode.Name.Contains( "MsgGC" ) ) { sb.AppendLine( padding + "public EGCMsg GetEMsg() { return " + EmitType( cnode.Ident ) + "; }" ); sb.AppendLine(); } else { sb.AppendLine( padding + "public EMsg GetEMsg() { return " + EmitType( cnode.Ident ) + "; }" ); sb.AppendLine(); } } else if (cnode.Name.Contains("Hdr")) { if ( cnode.Name.Contains( "MsgGC" ) ) { if ( cnode.childNodes.Find( node => node.Name == "msg" ) != null ) { sb.AppendLine( padding + "public void SetEMsg( EGCMsg msg ) { this.Msg = msg; }" ); sb.AppendLine(); } else { // this is required for a gc header which doesn't have an emsg sb.AppendLine( padding + "public void SetEMsg( EGCMsg msg ) { }" ); sb.AppendLine(); } } else { sb.AppendLine( padding + "public void SetEMsg( EMsg msg ) { this.Msg = msg; }" ); sb.AppendLine(); } } }
private void EmitClassConstructor(ClassNode cnode, StringBuilder sb, int level) { string padding = new String('\t', level); sb.AppendLine(padding + "- (id) init;"); }
private void EmitClassConstructor(ClassNode cnode, StringBuilder sb, int level) { string padding = new String('\t', level); sb.AppendLine(padding + "public " + cnode.Name + "()"); sb.AppendLine(padding + "{"); if (cnode.Parent != null) { sb.AppendLine(padding + "\tHeader = new " + EmitType(cnode.Parent) + "();"); sb.AppendLine(padding + "\tHeader.Msg = GetEMsg();"); } foreach (PropNode prop in cnode.childNodes) { Symbol defsym = prop.Default; string defflags = prop.Flags; string symname = GetUpperName(prop.Name); string ctor = EmitType(defsym); if (defflags != null && defflags == "proto") { ctor = "new " + EmitType(prop.Type) + "()"; } else if (defsym == null) { if ( !String.IsNullOrEmpty( prop.FlagsOpt ) ) { ctor = "new " + EmitType( prop.Type ) + "[" + CodeGenerator.GetTypeSize( prop ) + "]"; } else { ctor = "0"; } } if (defflags != null && ( defflags == "steamidmarshal" || defflags == "gameidmarshal" || defflags == "boolmarshal" )) { symname = prop.Name; } else if ( defflags != null && defflags == "const" ) { continue; } sb.AppendLine(padding + "\t" + symname + " = " + ctor + ";"); } sb.AppendLine(padding + "}"); }
private void EmitClassSerializer(ClassNode cnode, StringBuilder sb, int level, int baseSize) { string padding = new String('\t', level); sb.AppendLine(); sb.AppendLine(padding + "- (void) serialize:(NSMutableData *)data;"); }
private void EmitClassSize( ClassNode cnode, StringBuilder sb, int level ) { }
private void EmitClassDeserializer(ClassNode cnode, StringBuilder sb, int level, int baseSize) { string padding = new String('\t', level); sb.AppendLine(); sb.AppendLine(padding + "- (void) deserializeWithReader:(CRDataReader *)reader;"); }
private void EmitClassNode(ClassNode cnode, StringBuilder sb, int level) { EmitClassDef(cnode, sb, level, false); int baseSize = EmitClassProperties(cnode, sb, level + 1); EmitClassSerializer(cnode, sb, level + 1, baseSize); EmitClassParser(cnode, sb, level + 1, baseSize); EmitClassDef(cnode, sb, level, true); }
private void EmitClassConstants(ClassNode cnode, StringBuilder sb) { Func<PropNode, string> emitElement = node => cnode.Name + "_" + node.Name + " " + EmitType(node.Type) + " = " + EmitType(node.Default.FirstOrDefault()); var statics = cnode.childNodes.Where(node => node is PropNode && (node as PropNode).Flags == "const"); if (statics.Count() == 1) { sb.AppendLine("const " + emitElement(cnode.childNodes[0] as PropNode)); sb.AppendLine(); return; } bool first = true; foreach (PropNode node in statics) { if (first) { sb.AppendLine("const ("); first = false; } sb.AppendLine(" " + emitElement(node)); } if (!first) { sb.AppendLine(")"); sb.AppendLine(); } }
private int EmitClassProperties(ClassNode cnode, StringBuilder sb, int level) { string padding = new String(' ', level * 2); int baseClassSize = 0; //if (cnode.Parent != null) //{ // sb.AppendLine(padding + "public " + EmitType(cnode.Parent) + " Header { get; set; }"); //} foreach (PropNode prop in cnode.childNodes) { string propName = prop.Name; if (prop.Flags != null && prop.Flags == "const") { sb.AppendLine(padding + propName + ": " + EmitType(prop.Default) + ","); sb.AppendLine(); continue; } int size = CodeGenerator.GetTypeSize(prop); baseClassSize += size; } sb.AppendLine(padding + "baseSize: " + baseClassSize + ","); sb.AppendLine(); return baseClassSize; }
private void EmitClassConstructor(ClassNode cnode, StringBuilder sb) { sb.AppendLine("func New" + cnode.Name + "() *" + cnode.Name + " {"); sb.AppendLine(" return &" + cnode.Name + "{"); foreach (PropNode node in cnode.childNodes) { string ctor = null; Symbol firstDefault = node.Default.FirstOrDefault(); if (node.Flags == "const") { continue; } else if (node.Flags == "proto") { ctor = "new(" + GetUpperName(EmitType(node.Type)) + ")"; } else if (firstDefault == null) { // only arrays/slices need explicit initialization if (String.IsNullOrEmpty(node.FlagsOpt)) continue; ctor = "make([]" + EmitType(node.Type) + ", " + node.FlagsOpt + ", " + node.FlagsOpt + ")"; } else { ctor = EmitSymbol(firstDefault); } sb.AppendLine(" " + GetUpperName(node.Name) + ": " + ctor + ","); } sb.AppendLine(" }"); sb.AppendLine("}"); sb.AppendLine(); }
private void EmitClassParser(ClassNode cnode, StringBuilder sb, int level, int baseSize) { string padding = new String(' ', level * 2); sb.AppendLine(); sb.AppendLine(padding + "parse: function(buffer) {"); sb.AppendLine(padding + " var object = {};"); sb.AppendLine(); if (cnode.Parent != null) { //sb.AppendLine(padding + "\tHeader.Deserialize( stream );"); } var offset = 0; foreach (PropNode prop in cnode.childNodes) { string typestr = EmitType(prop.Type); int size = CodeGenerator.GetTypeSize(prop); string defflags = prop.Flags; string symname = "object." + prop.Name; if (defflags != null && defflags == "const") { continue; } if (size == 0) { if (prop.Flags != null && prop.Flags == "proto") { if (prop.FlagsOpt != null) { sb.AppendLine(padding + " object." + prop.Name + " = " + typestr + ".parse(buffer.slice(" + offset + ", " + offset + " + object." + prop.FlagsOpt + "));"); } else { //sb.AppendLine(padding + "\t" + GetUpperName(prop.Name) + " = ProtoBuf.Serializer.Deserialize<" + typestr + ">( stream );"); } } else { //sb.AppendLine(padding + "\t" + GetUpperName(prop.Name) + ".Deserialize( stream );"); } } else { if (!readerTypeMap.ContainsKey(typestr)) { typestr = CodeGenerator.GetTypeOfSize(size, SupportsUnsignedTypes()); } string call = "buffer.read" + readerTypeMap[typestr] + "(" + offset +")"; if (!String.IsNullOrEmpty(prop.FlagsOpt)) { call = "buffer.slice(" + offset + ", " + offset + " + " + prop.FlagsOpt + ")"; } if (prop.Flags == "protomask" || prop.Flags == "protomaskgc") { call = call + " & ~protoMask"; } sb.AppendLine(padding + " " + symname + " = " + call + ";"); } offset += size; } sb.AppendLine(); sb.AppendLine(padding + " return object;"); sb.AppendLine(padding + "}"); }
private void EmitClassSerializer(ClassNode cnode, StringBuilder sb, int level, int baseSize) { string padding = new String(' ', level * 2); //sb.AppendLine(); sb.AppendLine(padding + "serialize: function(object) {"); // first emit variable length members List <String> varLengthProps = new List <String>(); varLengthProps.Add(baseSize.ToString()); //if (cnode.Parent != null) //{ // sb.AppendLine(padding + "\tHeader.Serialize(stream);"); // varLengthProps.Add("(int)msHeader.Length"); // openedStreams.Add("msHeader"); // sb.AppendLine(); //} foreach (PropNode prop in cnode.childNodes) { string typestr = EmitType(prop.Type); int size = CodeGenerator.GetTypeSize(prop); if (size == 0) { if (prop.Flags != null && prop.Flags == "proto") { if (baseSize == 0) { // early exit sb.AppendLine(padding + " return " + typestr + ".serialize(object." + prop.Name + " || {});"); sb.AppendLine(padding + "},"); return; } sb.AppendLine(padding + " var buf" + GetUpperName(prop.Name) + " = " + typestr + ".serialize(object." + prop.Name + " || {});"); if (prop.FlagsOpt != null) { sb.AppendLine(padding + " object." + prop.FlagsOpt + " = buf" + GetUpperName(prop.Name) + ".length;"); } } else { //sb.AppendLine(padding + "\tMemoryStream ms" + GetUpperName(prop.Name) + " = " + GetUpperName(prop.Name) + ".serialize();"); } varLengthProps.Add("buf" + GetUpperName(prop.Name) + ".length"); } } sb.AppendLine(padding + " var buffer = new Buffer(" + String.Join(" + ", varLengthProps.ToArray()) + ");"); sb.AppendLine(); if (cnode.Parent != null) { //sb.AppendLine(padding + "\tmsHeader.CopyTo( msBuffer );"); } // next emit writers var offset = 0; foreach (PropNode prop in cnode.childNodes) { string typestr = EmitType(prop.Type); int size = CodeGenerator.GetTypeSize(prop); string propName = "object." + prop.Name; if (prop.Flags != null) { if (prop.Flags == "proto") { sb.AppendLine(padding + " buf" + GetUpperName(prop.Name) + ".copy(buffer, " + offset + ");"); continue; } else if (prop.Flags == "const") { continue; } } if (prop.Flags == "protomask" || prop.Flags == "protomaskgc") { propName = propName + " | protoMask"; } if (!readerTypeMap.ContainsKey(typestr)) { typestr = CodeGenerator.GetTypeOfSize(size, SupportsUnsignedTypes()); } Symbol defsym = prop.Default; string ctor = EmitType(defsym); if (defsym == null) { ctor = "0"; } string call = "buffer.write" + readerTypeMap[typestr] + "(" + propName + " || " + ctor + ", " + offset + ");"; if (!String.IsNullOrEmpty(prop.FlagsOpt)) { call = propName + " && " + propName + ".copy(buffer, " + offset + ");"; } sb.AppendLine(padding + " " + call); offset += size; } sb.AppendLine(); sb.AppendLine(padding + " return buffer;"); sb.AppendLine(padding + "},"); }