You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1006 lines
33 KiB
1006 lines
33 KiB
using System;
|
|
using System.Collections.Generic;
|
|
|
|
namespace ProtoCSStruct
|
|
{
|
|
public class MessageWriter
|
|
{
|
|
public void Write(ProtoMessage message, FileWriter fw)
|
|
{
|
|
string unsafestr = "";
|
|
if(message.Unsafe)
|
|
{
|
|
unsafestr = "unsafe ";
|
|
}
|
|
|
|
fw.Write(unsafestr + "public struct " + message.Name + " : IStructMessage<" + message.Name + ">");
|
|
fw.Write("{");
|
|
fw.Write(" public static StructMessageParser<" + message.Name + "> Parser = new StructMessageParser<" + message.Name + ">();");
|
|
fw.Write(" public const int SizeOf = " + message.GetMessageSize() + ";");
|
|
fw.Indent();
|
|
|
|
foreach (var field in message.Fields)
|
|
{
|
|
if(field.IsRepeated || field.FieldType == FieldType.Bytes)
|
|
{
|
|
WriteRepeatedFiled(field, fw);
|
|
}
|
|
else
|
|
{
|
|
WriteFiled(field, fw);
|
|
}
|
|
}
|
|
|
|
//结构体内存占用大小,就是SizeOf
|
|
WriteFun_StructSizeof(message, fw);
|
|
//结构体名字
|
|
WriteFun_GetName(message, fw);
|
|
//结构体实际打包后的大小,字节
|
|
WriteFun_CalculateSize(message, fw);
|
|
//是否为空的意思是所有字段都是缺省值,int等是0,bool是false,enum是0,string是""
|
|
//WriteFun_IsEmpty(message, fw);
|
|
//清空所有字段
|
|
WriteFun_Clear(message, fw);
|
|
//从另一个结构体复制数据,提供这个提高copy效率,直接用结构体复制就是memcpy,对大结构体来说效率不高,repeated字段满的情况毕竟少见
|
|
WriteFun_CopyFrom(message, fw);
|
|
//序列化
|
|
WriteFun_WriteTo(message, fw);
|
|
//反序列化
|
|
WriteFun_ReadFrom(message, fw);
|
|
//打印消息,类json(不完全是)格式
|
|
WriteFun_ToString(message, fw);
|
|
|
|
|
|
fw.Outdent();
|
|
fw.Write("}"); //struct
|
|
fw.Write("");
|
|
}
|
|
|
|
private void WriteFiled(ProtoMessageField field , FileWriter fw)
|
|
{
|
|
string cstypename = field.GetFiledTypeNameInCSharp();
|
|
|
|
string fielddef = string.Format("public {0} {1};", cstypename, field.Name);
|
|
|
|
fw.Write(fielddef);
|
|
|
|
}
|
|
|
|
private void WriteRepeatedFiled(ProtoMessageField field, FileWriter fw)
|
|
{
|
|
string cstypename = field.RepeatedFiledTypeNameInCSharp;
|
|
|
|
string fielddef = string.Format("public {0} {1};", cstypename, field.Name);
|
|
|
|
fw.Write(fielddef);
|
|
|
|
|
|
}
|
|
# region WriteFun Struct
|
|
private void WriteFun_StructSizeof(ProtoMessage message, FileWriter fw)
|
|
{
|
|
fw.Write("");
|
|
fw.Write(
|
|
"public int StructSizeof()",
|
|
"{",
|
|
" return SizeOf;",
|
|
"}"
|
|
);
|
|
|
|
fw.Write("");
|
|
}
|
|
|
|
private void WriteFun_GetName(ProtoMessage message, FileWriter fw)
|
|
{
|
|
fw.Write("");
|
|
fw.Write(
|
|
"public string GetName()",
|
|
"{",
|
|
" return \"" + message.Name + "\";",
|
|
"}"
|
|
);
|
|
|
|
fw.Write("");
|
|
}
|
|
|
|
private void WriteFun_CalculateSize(ProtoMessage message, FileWriter fw)
|
|
{
|
|
fw.Write(
|
|
"public int CalculateSize()",
|
|
"{",
|
|
" int size = 0;"
|
|
);
|
|
|
|
fw.Indent();
|
|
|
|
foreach (var field in message.Fields)
|
|
{
|
|
if (field.IsRepeated || field.FieldType == FieldType.Bytes)
|
|
{
|
|
WriteFun_CalculateSize_RepeatedFiled(message, field, fw);
|
|
}
|
|
else
|
|
{
|
|
WriteFun_CalculateSize_Filed(message, field, fw);
|
|
}
|
|
}
|
|
fw.Write("return size;");
|
|
fw.Outdent();
|
|
fw.Write("}");
|
|
fw.Write("");
|
|
}
|
|
|
|
private void WriteFun_CalculateSize_Filed(ProtoMessage message, ProtoMessageField field, FileWriter fw)
|
|
{
|
|
string checkfieldempty = "if (" + field.Name;
|
|
string computesizefield = "";
|
|
if (field.FieldType == FieldType.Int32)
|
|
{
|
|
checkfieldempty += " != 0)";
|
|
computesizefield = "WireFormat.ComputeInt32Size(" + field.Name + ");";
|
|
}
|
|
|
|
if (field.FieldType == FieldType.UInt32)
|
|
{
|
|
checkfieldempty += " != 0)";
|
|
computesizefield = "WireFormat.ComputeUInt32Size(" + field.Name + ");";
|
|
}
|
|
|
|
if (field.FieldType == FieldType.Int64)
|
|
{
|
|
checkfieldempty += " != 0)";
|
|
computesizefield = "WireFormat.ComputeInt64Size(" + field.Name + ");";
|
|
}
|
|
|
|
if (field.FieldType == FieldType.UInt64)
|
|
{
|
|
checkfieldempty += " != 0)";
|
|
computesizefield = "WireFormat.ComputeUInt64Size(" + field.Name + ");";
|
|
}
|
|
|
|
if (field.FieldType == FieldType.Bool)
|
|
{
|
|
checkfieldempty += " != false)";
|
|
computesizefield = "WireFormat.ComputeBoolSize(" + field.Name + ");";
|
|
}
|
|
|
|
if (field.FieldType == FieldType.Enum)
|
|
{
|
|
checkfieldempty += " != 0)";
|
|
computesizefield = "WireFormat.ComputeEnumSize((int)" + field.Name + ");";
|
|
}
|
|
|
|
uint tag = WireFormat.MakeTag(field.Number, field.FieldType);
|
|
uint tagsize = (uint)WireFormat.ComputeTagSize(tag);
|
|
|
|
|
|
if (field.FieldType == FieldType.String)
|
|
{
|
|
checkfieldempty += ".Length != 0)";
|
|
fw.Write(
|
|
checkfieldempty,
|
|
"{",
|
|
" int length = " + field.Name + ".CalculateSize();",
|
|
" size += " + tagsize + " + length + WireFormat.ComputeLengthSize(length);",
|
|
"}"
|
|
);
|
|
}
|
|
else if (field.FieldType == FieldType.Message)
|
|
{
|
|
checkfieldempty += ".CalculateSize() != 0)";
|
|
fw.Write(
|
|
checkfieldempty,
|
|
"{",
|
|
" int length = " + field.Name + ".CalculateSize();",
|
|
" size += " + tagsize + " + length + WireFormat.ComputeLengthSize(length);",
|
|
"}"
|
|
);
|
|
}
|
|
else
|
|
{
|
|
fw.Write(
|
|
checkfieldempty,
|
|
"{",
|
|
" size += " + tagsize + " + " + computesizefield,
|
|
"}"
|
|
);
|
|
}
|
|
|
|
|
|
}
|
|
|
|
private void WriteFun_CalculateSize_RepeatedFiled(ProtoMessage message, ProtoMessageField field, FileWriter fw)
|
|
{
|
|
uint tag = WireFormat.MakeTag(field.Number, WireFormat.WireType.LengthDelimited);
|
|
|
|
string checkfieldempty = "if (" + field.Name;
|
|
string computesizefield = "";
|
|
|
|
checkfieldempty += ".GetCount() != 0)";
|
|
computesizefield = field.Name + ".CalculateSize(" + tag + ");";
|
|
|
|
fw.Write(
|
|
checkfieldempty,
|
|
"{",
|
|
" size += " + computesizefield,
|
|
"}"
|
|
);
|
|
}
|
|
|
|
private void WriteFun_IsEmpty(ProtoMessage message, FileWriter fw)
|
|
{
|
|
fw.Write(
|
|
"public bool IsEmpty()",
|
|
"{",
|
|
" return CalculateSize() == 0;",
|
|
"}"
|
|
);
|
|
|
|
fw.Write("");
|
|
}
|
|
|
|
private void WriteFun_Clear(ProtoMessage message, FileWriter fw)
|
|
{
|
|
fw.Write(
|
|
"public void Clear()",
|
|
"{"
|
|
);
|
|
|
|
fw.Indent();
|
|
|
|
foreach (var field in message.Fields)
|
|
{
|
|
if (field.IsRepeated || field.FieldType == FieldType.Bytes)
|
|
{
|
|
WriteFun_Clear_RepeatedFiled(message, field, fw);
|
|
}
|
|
else
|
|
{
|
|
WriteFun_Clear_Filed(message, field, fw);
|
|
}
|
|
}
|
|
fw.Write("");
|
|
fw.Outdent();
|
|
fw.Write("}");
|
|
fw.Write("");
|
|
}
|
|
|
|
private void WriteFun_Clear_Filed(ProtoMessage message, ProtoMessageField field, FileWriter fw)
|
|
{
|
|
string checkfieldempty = "if (" + field.Name;
|
|
string clearfield = "";
|
|
if (field.FieldType == FieldType.Int32)
|
|
{
|
|
checkfieldempty += " != 0)";
|
|
clearfield = field.Name + " = 0;";
|
|
}
|
|
|
|
if (field.FieldType == FieldType.UInt32)
|
|
{
|
|
checkfieldempty += " != 0)";
|
|
clearfield = field.Name + " = 0;";
|
|
}
|
|
|
|
if (field.FieldType == FieldType.Int64)
|
|
{
|
|
checkfieldempty += " != 0)";
|
|
clearfield = field.Name + " = 0;";
|
|
}
|
|
|
|
if (field.FieldType == FieldType.UInt64)
|
|
{
|
|
checkfieldempty += " != 0)";
|
|
clearfield = field.Name + " = 0;";
|
|
}
|
|
|
|
if (field.FieldType == FieldType.Bool)
|
|
{
|
|
checkfieldempty += " != false)";
|
|
clearfield = field.Name + " = false;";
|
|
}
|
|
|
|
if (field.FieldType == FieldType.Enum)
|
|
{
|
|
checkfieldempty += " != 0)";
|
|
clearfield = field.Name + " = 0;";
|
|
}
|
|
|
|
if (field.FieldType == FieldType.Message
|
|
|| field.FieldType == FieldType.String)
|
|
{
|
|
clearfield = field.Name + ".Clear();";
|
|
|
|
fw.Write(
|
|
clearfield
|
|
);
|
|
}
|
|
else
|
|
{
|
|
fw.Write(
|
|
checkfieldempty,
|
|
"{",
|
|
" " + clearfield,
|
|
"}"
|
|
);
|
|
}
|
|
}
|
|
|
|
private void WriteFun_Clear_RepeatedFiled(ProtoMessage message, ProtoMessageField field, FileWriter fw)
|
|
{
|
|
fw.Write(
|
|
field.Name + ".Clear();"
|
|
);
|
|
}
|
|
|
|
private void WriteFun_CopyFrom(ProtoMessage message, FileWriter fw)
|
|
{
|
|
fw.Write(
|
|
"public void CopyFrom(ref " + message.Name + " other)",
|
|
"{"
|
|
);
|
|
|
|
fw.Indent();
|
|
|
|
foreach (var field in message.Fields)
|
|
{
|
|
if (field.IsRepeated || field.FieldType == FieldType.Bytes)
|
|
{
|
|
WriteFun_CopyFrom_RepeatedFiled(message, field, fw);
|
|
}
|
|
else
|
|
{
|
|
WriteFun_CopyFrom_Filed(message, field, fw);
|
|
}
|
|
}
|
|
fw.Write("");
|
|
fw.Outdent();
|
|
fw.Write("}");
|
|
fw.Write("");
|
|
}
|
|
|
|
private void WriteFun_CopyFrom_Filed(ProtoMessage message, ProtoMessageField field, FileWriter fw)
|
|
{
|
|
if (field.FieldType == FieldType.Int32
|
|
|| field.FieldType == FieldType.UInt32
|
|
|| field.FieldType == FieldType.Int64
|
|
|| field.FieldType == FieldType.UInt64
|
|
|| field.FieldType == FieldType.Bool
|
|
|| field.FieldType == FieldType.Enum)
|
|
{
|
|
fw.Write(
|
|
field.Name + " = other." + field.Name + ";"
|
|
);
|
|
}
|
|
|
|
if(field.FieldType == FieldType.String
|
|
|| field.FieldType == FieldType.Message)
|
|
{
|
|
fw.Write(
|
|
field.Name + ".CopyFrom(ref other." + field.Name + ");"
|
|
);
|
|
}
|
|
}
|
|
|
|
private void WriteFun_CopyFrom_RepeatedFiled(ProtoMessage message, ProtoMessageField field, FileWriter fw)
|
|
{
|
|
fw.Write(
|
|
field.Name + ".CopyFrom(ref other." + field.Name + ");"
|
|
);
|
|
}
|
|
|
|
private void WriteFun_WriteTo(ProtoMessage message, FileWriter fw)
|
|
{
|
|
fw.Write(
|
|
"public void WriteTo(CodedOutputStream output)",
|
|
"{"
|
|
);
|
|
|
|
fw.Indent();
|
|
|
|
foreach (var field in message.Fields)
|
|
{
|
|
if(field.IsRepeated || field.FieldType == FieldType.Bytes)
|
|
{
|
|
WriteFun_WriteTo_RepeatedFiled(message, field, fw);
|
|
}
|
|
else
|
|
{
|
|
WriteFun_WriteTo_Filed(message, field, fw);
|
|
}
|
|
}
|
|
|
|
fw.Outdent();
|
|
fw.Write("}");
|
|
fw.Write("");
|
|
}
|
|
|
|
private void WriteFun_WriteTo_Filed(ProtoMessage message, ProtoMessageField field, FileWriter fw)
|
|
{
|
|
string checkfieldempty = "if (" + field.Name;
|
|
string writefield = "";
|
|
if (field.FieldType == FieldType.Int32)
|
|
{
|
|
checkfieldempty += " != 0)";
|
|
writefield = "output.WriteInt32(" + field.Name + ");";
|
|
}
|
|
|
|
if (field.FieldType == FieldType.UInt32)
|
|
{
|
|
checkfieldempty += " != 0)";
|
|
writefield = "output.WriteUInt32(" + field.Name + ");";
|
|
}
|
|
|
|
if (field.FieldType == FieldType.Int64)
|
|
{
|
|
checkfieldempty += " != 0)";
|
|
writefield = "output.WriteInt64(" + field.Name + ");";
|
|
}
|
|
|
|
if (field.FieldType == FieldType.UInt64)
|
|
{
|
|
checkfieldempty += " != 0)";
|
|
writefield = "output.WriteUInt64(" + field.Name + ");";
|
|
}
|
|
|
|
if (field.FieldType == FieldType.Bool)
|
|
{
|
|
checkfieldempty += " != false)";
|
|
writefield = "output.WriteBool(" + field.Name + ");";
|
|
}
|
|
|
|
if (field.FieldType == FieldType.Enum)
|
|
{
|
|
checkfieldempty += " != 0)";
|
|
writefield = "output.WriteEnum((int)" + field.Name + ");";
|
|
}
|
|
|
|
if (field.FieldType == FieldType.String)
|
|
{
|
|
checkfieldempty += ".Length != 0)";
|
|
writefield = field.Name + ".WriteTo(output);";
|
|
}
|
|
|
|
uint tag = WireFormat.MakeTag(field.Number, field.FieldType);
|
|
|
|
if(field.FieldType == FieldType.Message)
|
|
{
|
|
checkfieldempty += ".CalculateSize() != 0)";
|
|
writefield = field.Name + ".WriteTo(output);";
|
|
|
|
fw.Write(
|
|
checkfieldempty,
|
|
"{",
|
|
" output.WriteTag(" + tag + ");",
|
|
" int length = " + field.Name + ".CalculateSize();",
|
|
" output.WriteLength(length);",
|
|
" " + writefield,
|
|
"}"
|
|
);
|
|
}
|
|
else
|
|
{
|
|
fw.Write(
|
|
checkfieldempty,
|
|
"{",
|
|
" output.WriteTag(" + tag + ");",
|
|
" " + writefield,
|
|
"}"
|
|
);
|
|
}
|
|
}
|
|
|
|
private void WriteFun_WriteTo_RepeatedFiled(ProtoMessage message, ProtoMessageField field, FileWriter fw)
|
|
{
|
|
//所有repeated类型的tag都带长度信息
|
|
uint tag = WireFormat.MakeTag(field.Number, WireFormat.WireType.LengthDelimited);
|
|
|
|
string checkfieldempty = "if (" + field.Name;
|
|
string writefield = "";
|
|
|
|
checkfieldempty += ".GetCount() != 0)";
|
|
writefield = field.Name + ".WriteTo(output," + tag + ");";
|
|
|
|
fw.Write(
|
|
checkfieldempty,
|
|
"{",
|
|
" " + writefield,
|
|
"}"
|
|
);
|
|
}
|
|
|
|
private void WriteFun_ReadFrom(ProtoMessage message, FileWriter fw)
|
|
{
|
|
fw.Write(
|
|
"public void ReadFrom(CodedInputStream input)",
|
|
"{",
|
|
" uint tag;",
|
|
" while ((tag = input.ReadTag()) != 0)",
|
|
" {",
|
|
" switch(tag)",
|
|
" {",
|
|
" default:",
|
|
" input.SkipLastField();",
|
|
" break;"
|
|
);
|
|
|
|
fw.Indent();//while
|
|
fw.Indent();//switch
|
|
fw.Indent();
|
|
|
|
foreach (var field in message.Fields)
|
|
{
|
|
if (field.IsRepeated || field.FieldType == FieldType.Bytes)
|
|
{
|
|
WriteFun_ReadFrom_RepeatedFiled(message, field, fw);
|
|
}
|
|
else
|
|
{
|
|
WriteFun_ReadFrom_Filed(message, field, fw);
|
|
}
|
|
}
|
|
|
|
fw.Outdent();
|
|
fw.Write("}");//switch
|
|
fw.Outdent();
|
|
fw.Write("}");//while
|
|
fw.Outdent();
|
|
fw.Write("}");//fun
|
|
fw.Write("");
|
|
}
|
|
|
|
private void WriteFun_ReadFrom_Filed(ProtoMessage message, ProtoMessageField field, FileWriter fw)
|
|
{
|
|
string readfield = "";
|
|
if (field.FieldType == FieldType.Int32)
|
|
{
|
|
readfield = field.Name + " = input.ReadInt32();";
|
|
}
|
|
|
|
if (field.FieldType == FieldType.UInt32)
|
|
{
|
|
readfield = field.Name + " = input.ReadUInt32();";
|
|
}
|
|
|
|
if (field.FieldType == FieldType.Int64)
|
|
{
|
|
readfield = field.Name + " = input.ReadInt64();";
|
|
}
|
|
|
|
if (field.FieldType == FieldType.UInt64)
|
|
{
|
|
readfield = field.Name + " = input.ReadUInt64();";
|
|
}
|
|
|
|
if (field.FieldType == FieldType.Bool)
|
|
{
|
|
readfield = field.Name + " = input.ReadBool();";
|
|
}
|
|
|
|
if (field.FieldType == FieldType.Enum)
|
|
{
|
|
readfield = field.Name + " = (" + field.TypeName + ")input.ReadEnum();";
|
|
}
|
|
|
|
if (field.FieldType == FieldType.String
|
|
|| field.FieldType == FieldType.Bytes)
|
|
{
|
|
readfield = field.Name + ".ReadFrom(input);";
|
|
}
|
|
|
|
uint tag = WireFormat.MakeTag(field.Number, field.FieldType);
|
|
|
|
if (field.FieldType == FieldType.Message)
|
|
{
|
|
fw.Write(
|
|
"case " + tag + ":",
|
|
"{",
|
|
" int length = input.ReadLength();",
|
|
" int oldLimit = input.PushLimit(length);",
|
|
" " + field.Name + ".ReadFrom(input); ",
|
|
" input.CheckReadEndOfStreamTag();",
|
|
" if (!input.ReachedLimit)",
|
|
" {",
|
|
" throw InvalidProtocolBufferException.TruncatedMessage();",
|
|
" }",
|
|
" input.PopLimit(oldLimit);",
|
|
" break;",
|
|
"}"
|
|
);
|
|
}
|
|
else if(field.FieldType == FieldType.String)//字符串容易溢出,特殊处理下
|
|
{
|
|
fw.Write(
|
|
"case " + tag + ":",
|
|
"{",
|
|
" try",
|
|
" {",
|
|
" " + readfield,
|
|
" }",
|
|
" catch(Exception e)",
|
|
" {",
|
|
" string message = \"proto message string field [" + message.Name + "." + field.Name + "] parse error, \" + e.Message;",
|
|
" throw new InvalidProtocolBufferException(message);",
|
|
" }",
|
|
" break;",
|
|
"}"
|
|
);
|
|
}
|
|
else
|
|
{
|
|
fw.Write(
|
|
"case " + tag + ":",
|
|
"{",
|
|
" " + readfield,
|
|
" break;",
|
|
"}"
|
|
);
|
|
}
|
|
|
|
|
|
}
|
|
|
|
private void WriteFun_ReadFrom_RepeatedFiled(ProtoMessage message, ProtoMessageField field, FileWriter fw)
|
|
{
|
|
uint tag = WireFormat.MakeTag(field.Number, WireFormat.WireType.LengthDelimited);
|
|
|
|
string readfield = field.Name + ".ReadFrom(input, " + tag + ");";
|
|
|
|
if (field.FieldType == FieldType.String)//字符串容易溢出,特殊处理下
|
|
{
|
|
fw.Write(
|
|
"case " + tag + ":",
|
|
"{",
|
|
" try",
|
|
" {",
|
|
" " + readfield,
|
|
" }",
|
|
" catch(Exception e)",
|
|
" {",
|
|
" string message = \"proto message string field [" + message.Name + "." + field.Name + "] parse error, \" + e.Message;",
|
|
" throw new InvalidProtocolBufferException(message);",
|
|
" }",
|
|
" break;",
|
|
"}"
|
|
);
|
|
}
|
|
else
|
|
{
|
|
fw.Write(
|
|
"case " + tag + ":",
|
|
"{",
|
|
" " + readfield,
|
|
" break;",
|
|
"}"
|
|
);
|
|
}
|
|
}
|
|
|
|
private void WriteFun_ToString(ProtoMessage message, FileWriter fw)
|
|
{
|
|
//空结构体,特殊处理
|
|
if (message.Fields.Count == 0)
|
|
{
|
|
fw.Write(
|
|
"public override string ToString()",
|
|
"{",
|
|
" MessageFormat format = new MessageFormat();",
|
|
" format.WriteLine(\"{ }\");",
|
|
" return format.ToString();",
|
|
"}"
|
|
);
|
|
fw.Write("");
|
|
}
|
|
else
|
|
{
|
|
fw.Write(
|
|
"public override string ToString()",
|
|
"{",
|
|
" MessageFormat format = new MessageFormat();",
|
|
" format.WriteLine(\"{\");",
|
|
" format.Indent();"
|
|
);
|
|
|
|
fw.Indent();
|
|
|
|
for (int i = 0; i < message.Fields.Count; i++)
|
|
{
|
|
var field = message.Fields[i];
|
|
bool islastField = (i == (message.Fields.Count - 1));
|
|
|
|
if (field.IsRepeated || field.FieldType == FieldType.Bytes)
|
|
{
|
|
WriteFun_ToString_RepeatedFiled(message, field, fw, islastField);
|
|
}
|
|
else
|
|
{
|
|
WriteFun_ToString_Filed(message, field, fw, islastField);
|
|
}
|
|
}
|
|
|
|
fw.Write("format.Outdent();");
|
|
fw.Write("return format.ToString();");
|
|
fw.Outdent();
|
|
fw.Write("}");
|
|
fw.Write("");
|
|
}
|
|
}
|
|
|
|
private void WriteFun_ToString_Filed(ProtoMessage message, ProtoMessageField field, FileWriter fw, bool islastField)
|
|
{
|
|
|
|
if (field.FieldType == FieldType.Int32
|
|
|| field.FieldType == FieldType.UInt32
|
|
|| field.FieldType == FieldType.Int64
|
|
|| field.FieldType == FieldType.UInt64
|
|
|| field.FieldType == FieldType.Bool)
|
|
{
|
|
string laststr = ",";
|
|
if (islastField)
|
|
{
|
|
laststr = " }";
|
|
}
|
|
|
|
//format.WriteLine("Id : " + Id.ToString() + ",");
|
|
fw.Write(
|
|
"format.WriteLine(\"" + field.Name + " : \" + " + field.Name + ".ToString() + \"" + laststr + "\");"
|
|
);
|
|
}
|
|
else if(field.FieldType == FieldType.Enum)
|
|
{
|
|
string laststr = ",";
|
|
if (islastField)
|
|
{
|
|
laststr = " }";
|
|
}
|
|
|
|
//format.WriteLine("MsgId : " + MsgId.ToString() + "(" + ((int)MsgId).ToString() + "),");
|
|
fw.Write(
|
|
"format.WriteLine(\"" + field.Name + " : \" + " + field.Name + ".ToString() + \"(\"" + "+((int)" + field.Name + ").ToString() + \")" + laststr + "\");"
|
|
);
|
|
}
|
|
else if (field.FieldType == FieldType.String)//
|
|
{
|
|
string laststr = ",";
|
|
if (islastField)
|
|
{
|
|
laststr = " }";
|
|
}
|
|
//format.WriteLine("Message : \"" + Message.ToString() + "\",");
|
|
fw.Write(
|
|
"format.WriteLine(\"" + field.Name + " : \\\"\" + " + field.Name + ".ToString() + \"\\\"" + laststr + "\");"
|
|
);
|
|
}
|
|
else if (field.FieldType == FieldType.Message)//
|
|
{
|
|
string laststr = "";
|
|
fw.Write(
|
|
"format.WriteLine(\"" + field.Name + " : \" + " + field.Name + ".ToString() + \"" + laststr + "\");"
|
|
);
|
|
}
|
|
|
|
}
|
|
|
|
private void WriteFun_ToString_RepeatedFiled(ProtoMessage message, ProtoMessageField field, FileWriter fw, bool islastField)
|
|
{
|
|
string laststr = ",";
|
|
if (islastField)
|
|
{
|
|
laststr = " }";
|
|
}
|
|
|
|
fw.Write(
|
|
"format.WriteLine(\"" + field.Name + " : \" + " + field.Name + ".ToString() + \"" + laststr + "\");"
|
|
);
|
|
}
|
|
|
|
#endregion
|
|
|
|
public void WriteClassDesc(ProtoMessage message, FileWriter fw)
|
|
{
|
|
fw.Write("public class " + message.Name + " : " + "ClassMessage");
|
|
fw.Write("{");
|
|
fw.Indent();
|
|
|
|
foreach (var field in message.Fields)
|
|
{
|
|
string cstypename = field.FieldType == FieldType.String ? "string" : field.GetFiledTypeNameInCSharp();
|
|
if (InputParams.ClassNeedAttribute)
|
|
{
|
|
fw.Write("[BinarySerialize.BinSerializeMember(" + field.Number + ")]");
|
|
}
|
|
if(field.IsRepeated)
|
|
{
|
|
string str = string.Format("public List<{0}> {1} = new List<{0}>();", cstypename, field.Name);
|
|
fw.Write(str);
|
|
}
|
|
else if (field.FieldType == FieldType.Message)
|
|
{
|
|
string str = string.Format("public {0} {1} = new {0}();", cstypename, field.Name);
|
|
fw.Write(str);
|
|
}
|
|
else
|
|
{
|
|
string str = string.Format("public {0} {1};", cstypename, field.Name);
|
|
fw.Write(str);
|
|
}
|
|
}
|
|
|
|
//序列化
|
|
WriteClassFun_WriteTo(message, fw);
|
|
//反序列化
|
|
WriteClassFun_ReadFrom(message, fw);
|
|
fw.Outdent();
|
|
fw.Write("}"); //class
|
|
fw.Write("");
|
|
}
|
|
|
|
private void WriteClassFun_WriteTo(ProtoMessage message, FileWriter fw)
|
|
{
|
|
fw.Write(
|
|
"public override void WriteTo(MemoryStream output)",
|
|
"{"
|
|
);
|
|
|
|
fw.Indent();
|
|
|
|
foreach (var field in message.Fields)
|
|
{
|
|
if(field.IsRepeated || field.FieldType == FieldType.Bytes)
|
|
{
|
|
// WriteFun_WriteTo_RepeatedFiled(message, field, fw);
|
|
WriteClassFun_WriteTo_RepeatedFiled(message, field, fw);
|
|
}
|
|
else
|
|
{
|
|
// WriteFun_WriteTo_Filed(message, field, fw);
|
|
WriteClassFun_WriteTo_Filed(message, field, fw);
|
|
}
|
|
}
|
|
|
|
fw.Outdent();
|
|
fw.Write("}");
|
|
fw.Write("");
|
|
}
|
|
|
|
private void WriteClassFun_WriteTo_RepeatedFiled(ProtoMessage message, ProtoMessageField field, FileWriter fw)
|
|
{
|
|
// //所有repeated类型的tag都带长度信息
|
|
uint tag = WireFormat.MakeTag(field.Number, WireFormat.WireType.LengthDelimited);
|
|
|
|
string writeTag = $"WriteTo_UInt32(output, {tag});";
|
|
fw.Write("\n");
|
|
if (field.FieldType == FieldType.Message)
|
|
{
|
|
fw.Write($"//List<{field.Message.Name}> Begin");
|
|
fw.Write($"foreach (var item in {field.Name})");
|
|
fw.Write("{");
|
|
fw.Indent();
|
|
fw.Write(
|
|
writeTag,
|
|
"WriteTo_Message(output, item);"
|
|
);
|
|
fw.Outdent();
|
|
fw.Write("}");
|
|
fw.Write($"//List<{field.Message.Name}> End");
|
|
}
|
|
else
|
|
{
|
|
fw.Write($"//List<{field.GetFiledTypeNameInCSharp()}> Begin");
|
|
fw.Write(writeTag);
|
|
|
|
string msField = "msField" + field.Number;
|
|
fw.Write($"var {msField} = Helper.GetMemoryStream();");
|
|
fw.Write($"{msField}.SetLength(0);");
|
|
fw.Write($"foreach (var item in {field.Name})");
|
|
fw.Write("{");
|
|
fw.Indent();
|
|
string line = WriteTo_Filed(field, msField);
|
|
line = line.Replace(field.Name, "item");
|
|
fw.Write(line);
|
|
fw.Outdent();
|
|
fw.Write("}");
|
|
string length = "length" + field.Number;
|
|
fw.Write($"uint {length} = (uint){msField}.Length;");
|
|
fw.Write($"ProtocolParser.WriteUInt32(output, {length});");
|
|
fw.Write($"{msField}.WriteTo(output);");
|
|
fw.Write($"Helper.RecycleMemoryStream(ref {msField});");
|
|
fw.Write($"//List<{field.GetFiledTypeNameInCSharp()}> End");
|
|
}
|
|
}
|
|
|
|
private void WriteClassFun_WriteTo_Filed(ProtoMessage message, ProtoMessageField field, FileWriter fw)
|
|
{
|
|
uint tag = WireFormat.MakeTag(field.Number, field.FieldType);
|
|
string writeTag = $"WriteTo_UInt32(output, {tag});";
|
|
if (field.FieldType == FieldType.String) // 为了和原来的协议长度对上,要不没法做检测工具
|
|
{
|
|
fw.Write($"if({field.Name} != null)");
|
|
fw.Write("{");
|
|
fw.Indent();
|
|
|
|
fw.Write(
|
|
writeTag,
|
|
WriteTo_Filed(field)
|
|
);
|
|
|
|
fw.Outdent();
|
|
fw.Write("}");
|
|
}
|
|
else
|
|
{
|
|
fw.Write("\n");
|
|
// uint tag = WireFormat.MakeTag(field.Number, field.FieldType);
|
|
fw.Write(
|
|
writeTag,
|
|
WriteTo_Filed(field)
|
|
);
|
|
}
|
|
}
|
|
|
|
private string WriteTo_Filed(ProtoMessageField field, string streamOutput = "output")
|
|
{
|
|
string writefield = "";
|
|
|
|
if (field.FieldType == FieldType.Int32)
|
|
{
|
|
// writefield = "output.WriteInt32(" + field.Name + ");";
|
|
writefield = $"WriteTo_Int32({streamOutput}, {field.Name});";
|
|
}
|
|
|
|
if (field.FieldType == FieldType.UInt32)
|
|
{
|
|
// writefield = "output.WriteUInt32(" + field.Name + ");";
|
|
writefield = $"WriteTo_UInt32({streamOutput}, {field.Name});";
|
|
}
|
|
|
|
if (field.FieldType == FieldType.Int64)
|
|
{
|
|
// writefield = "output.WriteInt64(" + field.Name + ");";
|
|
writefield = $"WriteTo_Int64({streamOutput}, {field.Name});";
|
|
}
|
|
|
|
if (field.FieldType == FieldType.UInt64)
|
|
{
|
|
// writefield = "output.WriteUInt64(" + field.Name + ");";
|
|
writefield = $"WriteTo_UInt64({streamOutput}, {field.Name});";
|
|
}
|
|
|
|
if (field.FieldType == FieldType.Bool)
|
|
{
|
|
// writefield = "output.WriteBool(" + field.Name + ");";
|
|
writefield = $"WriteTo_Bool({streamOutput}, {field.Name});";
|
|
}
|
|
|
|
if (field.FieldType == FieldType.Enum)
|
|
{
|
|
// writefield = "output.WriteEnum((int)" + field.Name + ");";
|
|
writefield = $"WriteTo_Enum({streamOutput}, (int){field.Name});";
|
|
}
|
|
|
|
if (field.FieldType == FieldType.String)
|
|
{
|
|
// writefield = field.Name + ".WriteTo(output);";
|
|
writefield = $"WriteTo_String({streamOutput}, {field.Name});";
|
|
}
|
|
|
|
if(field.FieldType == FieldType.Message)
|
|
{
|
|
writefield = $"WriteTo_Message({streamOutput}, {field.Name});";
|
|
}
|
|
|
|
return writefield;
|
|
}
|
|
|
|
|
|
private void WriteClassFun_ReadFrom(ProtoMessage message, FileWriter fw)
|
|
{
|
|
fw.Write(
|
|
"public override void ReadFrom(MemoryStream stream)",
|
|
"{",
|
|
" //TODO",
|
|
"}"
|
|
);
|
|
}
|
|
|
|
}
|
|
}
|
|
|