コード例 #1
0
ファイル: FieldCode.cs プロジェクト: enyim/ProtoBuf
 public static string GenerateFieldReader(Field f)
 {
     string code = "";
     if (f.Rule == FieldRule.Repeated) {
         if (f.OptionPacked == true) {
             code += "using(MemoryStream ms" + f.ID + " = new MemoryStream(ProtocolParser.ReadBytes(stream)))\n";
             code += "{\n";
             code += "	while(true)\n";
             code += "	{\n";
             code += "		if(ms" + f.ID + ".Position == ms" + f.ID + ".Length)\n";
             code += "			break;\n";
             code += "		instance." + f.Name + ".Add(" + GenerateFieldTypeReader (f, "ms" + f.ID, "br", null) + ");\n";
             code += "	}\n";
             code += "}\n";
         } else {
             code += "instance." + f.Name + ".Add(" + GenerateFieldTypeReader (f, "stream", "br", null) + ");\n";
         }
     } else {
         if (f.ProtoType == ProtoTypes.Message) {
             code += "if(instance." + f.Name + " == null)\n";
             code += "	instance." + f.Name + " = " + GenerateFieldTypeReader (f, "stream", "br", null) + ";\n";
             code += "else\n";
             code += "	instance." + f.Name + " = " + GenerateFieldTypeReader (f, "stream", "br", "instance." + f.Name) + ";";
         } else
             code += "instance." + f.Name + " = " + GenerateFieldTypeReader (f, "stream", "br", "instance." + f.Name) + ";";
     }
     return code;
 }
コード例 #2
0
ファイル: ProtoPrepare.cs プロジェクト: enyim/ProtoBuf
        /// <summary>
        /// Get the default value in c# form
        /// </summary>
        static string GetCSDefaultValue(Field f)
        {
            switch (f.ProtoType) {
            case ProtoTypes.Double:
            case ProtoTypes.Float:
            case ProtoTypes.Fixed32:
            case ProtoTypes.Fixed64:
            case ProtoTypes.Sfixed32:
            case ProtoTypes.Sfixed64:
            case ProtoTypes.Int32:
            case ProtoTypes.Int64:
            case ProtoTypes.Uint32:
            case ProtoTypes.Uint64:
            case ProtoTypes.Sint32:
            case ProtoTypes.Sint64:
            case ProtoTypes.Bool:
                return f.OptionDefault;

            case ProtoTypes.String:
                return f.OptionDefault;

            case ProtoTypes.Bytes:
                throw new NotImplementedException ();

            case ProtoTypes.Enum:
                return f.OptionDefault;

            case ProtoTypes.Message:
                throw new InvalidDataException ("Don't think there can be a default for messages");

            default:
                throw new NotImplementedException ();
            }
        }
コード例 #3
0
ファイル: FieldCode.cs プロジェクト: enyim/ProtoBuf
        public static string GenerateFieldTypeWriter(Field f, string stream, string binaryWriter, string instance)
        {
            if (f.OptionCodeType != null) {
                switch (f.OptionCodeType) {
                case "DateTime":
                case "TimeSpan":
                    return "ProtocolParser.WriteUInt64 (" + stream + ", (ulong)" + instance + ".Ticks);\n";
                default: //enum
                    break;
                }
            }

            switch (f.ProtoType) {
            case ProtoTypes.Double:
            case ProtoTypes.Float:
            case ProtoTypes.Fixed32:
            case ProtoTypes.Fixed64:
            case ProtoTypes.Sfixed32:
            case ProtoTypes.Sfixed64:
                return binaryWriter + ".Write(" + instance + ");\n";
            case ProtoTypes.Int32:
                return "ProtocolParser.WriteUInt32(" + stream + ", (uint)" + instance + ");\n";
            case ProtoTypes.Int64:
                return "ProtocolParser.WriteUInt64(" + stream + ", (ulong)" + instance + ");\n";
            case ProtoTypes.Uint32:
                return "ProtocolParser.WriteUInt32(" + stream + ", " + instance + ");\n";
            case ProtoTypes.Uint64:
                return "ProtocolParser.WriteUInt64(" + stream + ", " + instance + ");\n";
            case ProtoTypes.Sint32:
                return "ProtocolParser.WriteSInt32(" + stream + ", " + instance + ");\n";
            case ProtoTypes.Sint64:
                return "ProtocolParser.WriteSInt64(" + stream + ", " + instance + ");\n";
            case ProtoTypes.Bool:
                return "ProtocolParser.WriteBool(" + stream + ", " + instance + ");\n";
            case ProtoTypes.String:
                return "ProtocolParser.WriteString(" + stream + ", " + instance + ");\n";
            case ProtoTypes.Bytes:
                return "ProtocolParser.WriteBytes(" + stream + ", " + instance + ");\n";
            case ProtoTypes.Enum:
                return "ProtocolParser.WriteUInt32(" + stream + ", (uint)" + instance + ");\n";
            case ProtoTypes.Message:
                string code = "";
                code += "using(MemoryStream ms" + f.ID + " = new MemoryStream())\n";
                code += "{\n";
                code += "	" + f.FullPath + ".Serialize(ms" + f.ID + ", " + instance + ");\n";
                code += "	ProtocolParser.WriteBytes(" + stream + ", ms" + f.ID + ".ToArray());\n";
                code += "}\n";
                return code;
            default:
                throw new NotImplementedException ();
            }
        }
コード例 #4
0
ファイル: MessageCode.cs プロジェクト: enyim/ProtoBuf
 protected virtual string GenerateProperty(Field f)
 {
     return f.OptionAccess + " " + f.PropertyType + " " + f.Name + " { get; set; }";
 }
コード例 #5
0
ファイル: ProtoPrepare.cs プロジェクト: enyim/ProtoBuf
        /// <summary>
        /// Prepare: ProtoType, WireType and CSType
        /// </summary>
        static void PrepareProtoType(Message m, Field f)
        {
            //Change property name to C# style, CamelCase.
            f.Name = GetCSPropertyName (m, f.Name);

            f.ProtoType = GetScalarProtoType (f.ProtoTypeName);

            //Wire, and set type
            switch (f.ProtoType) {
            case ProtoTypes.Double:
            case ProtoTypes.Fixed64:
            case ProtoTypes.Sfixed64:
                f.WireType = Wire.Fixed64;
                break;
            case ProtoTypes.Float:
            case ProtoTypes.Fixed32:
            case ProtoTypes.Sfixed32:
                f.WireType = Wire.Fixed32;
                break;
            case ProtoTypes.Int32:
            case ProtoTypes.Int64:
            case ProtoTypes.Uint32:
            case ProtoTypes.Uint64:
            case ProtoTypes.Sint32:
            case ProtoTypes.Sint64:
            case ProtoTypes.Bool:
                f.WireType = Wire.Varint;
                break;
            case ProtoTypes.String:
            case ProtoTypes.Bytes:
                f.WireType = Wire.LengthDelimited;
                break;
            default:
                MessageEnumBase pt = GetProtoType (m, f.ProtoTypeName);

                if (pt == null) {
                    //Assumed to be a message defined elsewhere
                    f.ProtoType = ProtoTypes.Message;
                    f.WireType = Wire.LengthDelimited;
                    f.ProtoTypeMessage = new MessageName (m, f.ProtoTypeName);
                }
                if (pt is MessageEnum) {
                    f.ProtoType = ProtoTypes.Enum;
                    f.WireType = Wire.Varint;
                    f.ProtoTypeEnum = (MessageEnum)pt;
                }
                if (pt is Message) {
                    f.ProtoType = ProtoTypes.Message;
                    f.WireType = Wire.LengthDelimited;
                    f.ProtoTypeMessage = (Message)pt;
                }

                string[] parts = f.ProtoTypeName.Split ('.');
                string cc = GetCamelCase (parts [parts.Length - 1]);
                if (pt is Message) {
                    f.CSClass = cc;
            #if GENERATE_INTERFACE
                    f.CSType += "I" + cc;
            #else
                    f.CSType += cc;
            #endif
                    break;
                } else
                    f.CSType = cc;

                break;
            }

            if (f.OptionPacked) {
                if (f.WireType == Wire.LengthDelimited)
                    throw new InvalidDataException ("Packed field not allowed for length delimited types");
                f.WireType = Wire.LengthDelimited;
            }

            if (f.OptionCodeType != null) {
                f.CSClass = f.OptionCodeType;
                f.CSType = f.OptionCodeType;
            }

            if (f.CSType == null) {
                f.CSType = GetCSType (f.ProtoType);
                f.CSClass = f.CSType;
            }
        }
コード例 #6
0
ファイル: ProtoParser.cs プロジェクト: enyim/ProtoBuf
        static void ParseFieldOption(string key, string val, Field f)
        {
            switch (key) {
            case "default":
                f.OptionDefault = val;
                break;
            case "packed":
                f.OptionPacked = Boolean.Parse (val);
                break;
            case "deprecated":
                f.OptionDeprecated = Boolean.Parse (val);
                break;

            //Local options:

            case "access":
                f.OptionAccess = val;
                break;
            case "codetype":
                if (val == "DateTime" || val == "TimeSpan") {
                    if (f.ProtoTypeName != "int64")
                        throw new ProtoFormatException ("DateTime and TimeSpan must be stored in int64. was " + f.ProtoTypeName);
                }
                f.OptionCodeType = val;
                break;
            case "generate":
                f.OptionGenerate = Boolean.Parse (val);
                break;
            default:
                Console.WriteLine ("Warning: Unknown field option: " + key);
                break;
            }
        }
コード例 #7
0
ファイル: ProtoParser.cs プロジェクト: enyim/ProtoBuf
        static bool ParseField(TokenReader tr, Message m)
        {
            string rule = tr.ReadNext ();
            while (true) {
                if (ParseComment (rule) == false)
                    break;
                rule = tr.ReadNext ();
            }

            if (rule == "}")
                return false;

            if (rule == "enum") {
                MessageEnum me = ParseEnum (tr, m);
                m.Enums.Add (me);
                return true;
            }

            Field f = new Field ();
            f.Comments = lastComment;
            lastComment = null;

            //Rule
            switch (rule) {
            case "required":
                f.Rule = FieldRule.Required;
                break;
            case "optional":
                f.Rule = FieldRule.Optional;
                break;
            case "repeated":
                f.Rule = FieldRule.Repeated;
                break;
            case "option":
                //Save options
                ParseOption (tr, m);
                return true;
            case "message":
                m.Messages.Add (ParseMessage (tr, m));
                return true;
            default:
                throw new ProtoFormatException ("unknown rule: " + rule);
            }

            //Type
            f.ProtoTypeName = tr.ReadNext ();

            //Name
            f.Name = tr.ReadNext ();

            //ID
            tr.ReadNextOrThrow ("=");
            f.ID = int.Parse (tr.ReadNext ());
            if (19000 <= f.ID && f.ID <= 19999)
                throw new ProtoFormatException ("Can't use reserved field ID 19000-19999");
            if (f.ID > (1 << 29) - 1)
                throw new ProtoFormatException ("Maximum field id is 2^29 - 1");

            //Add Field to message
            m.Fields.Add (f.ID, f);

            //Determine if extra options
            string extra = tr.ReadNext ();
            if (extra == ";")
                return true;

            //Field options
            if (extra != "[")
                throw new ProtoFormatException ("Expected: [ got " + extra);

            while (true) {
                string key = tr.ReadNext ();
                tr.ReadNextOrThrow ("=");
                string val = tr.ReadNext ();

                ParseFieldOption (key, val, f);
                string optionSep = tr.ReadNext ();
                if (optionSep == "]")
                    break;
                if (optionSep == ",")
                    continue;
                throw new ProtoFormatException (@"Expected "","" or ""]"" got " + tr.Next);
            }
            tr.ReadNextOrThrow (";");

            return true;
        }
コード例 #8
0
ファイル: FieldCode.cs プロジェクト: enyim/ProtoBuf
        /// <summary>
        /// Generates code for writing one field
        /// </summary>
        public static string GenerateFieldWriter(Message m, Field f)
        {
            string code = "";
            if (f.Rule == FieldRule.Repeated) {
                if (f.OptionPacked == true) {

                    string binaryWriter = "";
                    switch (f.ProtoType) {
                    case ProtoTypes.Double:
                    case ProtoTypes.Float:
                    case ProtoTypes.Fixed32:
                    case ProtoTypes.Fixed64:
                    case ProtoTypes.Sfixed32:
                    case ProtoTypes.Sfixed64:
                        binaryWriter = "\nBinaryWriter bw" + f.ID + " = new BinaryWriter(ms" + f.ID + ");";
                        break;
                    }

                    code += "if(instance." + f.Name + " != null)\n";
                    code += "{\n";
                    code += "	ProtocolParser.WriteKey(stream, new ProtocolBuffers.Key(" + f.ID + ", Wire." + f.WireType + "));\n";
                    code += "	using(MemoryStream ms" + f.ID + " = new MemoryStream())\n";
                    code += "	{	" + binaryWriter + "\n";
                    code += "		foreach(" + f.PropertyItemType + " i" + f.ID + " in instance." + f.Name + ")\n";
                    code += "		{\n";
                    code += Code.Indent (3, GenerateFieldTypeWriter (f, "ms" + f.ID, "bw" + f.ID, "i" + f.ID)) + "\n";
                    code += "		}\n";
                    code += "		ProtocolParser.WriteBytes(stream, ms" + f.ID + ".ToArray());\n";
                    code += "	}\n";
                    code += "}\n";
                    return code;
                } else {
                    code += "if(instance." + f.Name + " != null)\n";
                    code += "{\n";
                    code += "	foreach(" + f.PropertyItemType + " i" + f.ID + " in instance." + f.Name + ")\n";
                    code += "	{\n";
                    code += "		ProtocolParser.WriteKey(stream, new ProtocolBuffers.Key(" + f.ID + ", Wire." + f.WireType + "));\n";
                    code += Code.Indent (2, GenerateFieldTypeWriter (f, "stream", "bw", "i" + f.ID)) + "\n";
                    code += "	}\n";
                    code += "}\n";
                    return code;
                }
            } else if (f.Rule == FieldRule.Optional) {
                switch (f.ProtoType) {
                case ProtoTypes.String:
                case ProtoTypes.Message:
                case ProtoTypes.Bytes:
                    code += "if(instance." + f.Name + " != null)\n";
                    code += "{\n";
                    code += "	ProtocolParser.WriteKey(stream, new ProtocolBuffers.Key(" + f.ID + ", Wire." + f.WireType + "));\n";
                    code += Code.Indent (GenerateFieldTypeWriter (f, "stream", "bw", "instance." + f.Name));
                    code += "}\n";
                    return code;
                case ProtoTypes.Enum:
                    code += "if(instance." + f.Name + " != " + f.PropertyItemType + "." + f.OptionDefault + ")\n";
                    code += "{\n";
                    code += "	ProtocolParser.WriteKey(stream, new ProtocolBuffers.Key(" + f.ID + ", Wire." + f.WireType + "));\n";
                    code += Code.Indent (GenerateFieldTypeWriter (f, "stream", "bw", "instance." + f.Name));
                    code += "}\n";
                    return code;
                default:
                    code += "ProtocolParser.WriteKey(stream, new ProtocolBuffers.Key(" + f.ID + ", Wire." + f.WireType + "));\n";
                    code += GenerateFieldTypeWriter (f, "stream", "bw", "instance." + f.Name);
                    return code;
                }
            } else if (f.Rule == FieldRule.Required) {
                switch (f.ProtoType) {
                case ProtoTypes.String:
                case ProtoTypes.Message:
                case ProtoTypes.Bytes:
                    code += "if(instance." + f.Name + " == null)\n";
                    code += "	throw new ArgumentNullException(\"" + f.Name + "\", \"Required by proto specification.\");\n";
                    break;
                }
                code += "ProtocolParser.WriteKey(stream, new ProtocolBuffers.Key(" + f.ID + ", Wire." + f.WireType + "));\n";
                code += GenerateFieldTypeWriter (f, "stream", "bw", "instance." + f.Name);
                return code;
            }
            throw new NotImplementedException ("Unknown rule: " + f.Rule);
        }
コード例 #9
0
ファイル: FieldCode.cs プロジェクト: enyim/ProtoBuf
 static string GenerateFieldTypeReaderPrimitive(Field f, string stream, string instance)
 {
     switch (f.ProtoType) {
     case ProtoTypes.Double:
         return "br.ReadDouble ()";
     case ProtoTypes.Float:
         return "br.ReadSingle ()";
     case ProtoTypes.Fixed32:
         return "br.ReadUInt32 ()";
     case ProtoTypes.Fixed64:
         return "br.ReadUInt64 ()";
     case ProtoTypes.Sfixed32:
         return "br.ReadInt32 ()";
     case ProtoTypes.Sfixed64:
         return "br.ReadInt64 ()";
     case ProtoTypes.Int32:
         return "(int)ProtocolParser.ReadUInt32(" + stream + ")";
     case ProtoTypes.Int64:
         return "(long)ProtocolParser.ReadUInt64(" + stream + ")";
     case ProtoTypes.Uint32:
         return "ProtocolParser.ReadUInt32(" + stream + ")";
     case ProtoTypes.Uint64:
         return "ProtocolParser.ReadUInt64(" + stream + ");";
     case ProtoTypes.Sint32:
         return "ProtocolParser.ReadSInt32(" + stream + ");";
     case ProtoTypes.Sint64:
         return "ProtocolParser.ReadSInt64(" + stream + ");";
     case ProtoTypes.Bool:
         return "ProtocolParser.ReadBool(" + stream + ")";
     case ProtoTypes.String:
         return "ProtocolParser.ReadString(" + stream + ")";
     case ProtoTypes.Bytes:
         return "ProtocolParser.ReadBytes(" + stream + ")";
     case ProtoTypes.Enum:
         return "(" + f.PropertyItemType + ")ProtocolParser.ReadUInt32(" + stream + ")";
     case ProtoTypes.Message:
         if (f.Rule == FieldRule.Repeated)
             return f.FullPath + ".Deserialize(ProtocolParser.ReadBytes(" + stream + "))";
         else {
             if (instance == null)
                 return f.FullPath + ".Deserialize(ProtocolParser.ReadBytes(" + stream + "))";
             else
                 return f.FullPath + ".Deserialize(ProtocolParser.ReadBytes(" + stream + "), " + instance + ")";
         }
     default:
         throw new NotImplementedException ();
     }
 }
コード例 #10
0
ファイル: FieldCode.cs プロジェクト: enyim/ProtoBuf
        static string GenerateFieldTypeReader(Field f, string stream, string binaryReader, string instance)
        {
            if (f.OptionCodeType != null) {
                switch (f.OptionCodeType) {
                case "DateTime":
                    return "new DateTime((long)ProtocolParser.ReadUInt64 (" + stream + "))";
                case "TimeSpan":
                    return "new TimeSpan((long)ProtocolParser.ReadUInt64 (" + stream + "))";
                default:
                    //Assume enum
                    return "(" + f.OptionCodeType + ")" + GenerateFieldTypeReaderPrimitive (f, stream, instance);
                }
            }

            return GenerateFieldTypeReaderPrimitive (f, stream, instance);
        }