using System; using System.Collections.Generic; using System.IO; using System.Linq; namespace ProtoCSStruct { public class CSharpStructWriter { //所有fixed 长度大小的string类,int表示长度,为了减少类型数量,长度必须是8的倍数 private HashSet AllFixStringClass; //所有repeated struct 的类型 private HashSet AllRepeatedStructSet; //需要按申明顺序保存 private List AllRepeatedStructList; public CSharpStructWriter() { AllFixStringClass = new HashSet(); AllRepeatedStructSet = new HashSet(); AllRepeatedStructList = new List(); } public void WriteCSStructFile() { //固定长度的string类型 FixedRepeatedStruct WriteAllFixRepeatedClass(); //协议文件 WriteAllProtoFile(); } private void WriteAllFixRepeatedClass() { string outfile = ProtoDescriptorAll.Instance.AllProtoDescriptor[0].OutPutPath + "/FixedRepeatedStruct.cs"; string nameSpace = ProtoDescriptorAll.Instance.AllProtoDescriptor[0].NameSpace; FileWriter fw = new FileWriter(outfile); fw.Write(Define.FileHeader); fw.Write( "", "using System;", "using System.Text;", "", "namespace " + nameSpace, "{", "" ); fw.Indent(); WriteFixStringClass(fw); WriteRepeatedStructClass(fw); fw.Outdent(); fw.Write("}");//namespace fw.WriteToFile(); Console.WriteLine("generator {0} success", outfile); } private void WriteFixStringClass(FileWriter fw) { GetAllFixedString(); foreach (var length in AllFixStringClass) { FixedStringWriter fsw = new FixedStringWriter(); fsw.Write(length, fw); } } private void WriteRepeatedStructClass(FileWriter fw) { GetAllRepeatedStructClass(); foreach (var repeatedstruct in AllRepeatedStructList) { RepeatedStructWriter rsw = new RepeatedStructWriter(); rsw.Write(repeatedstruct,fw); } } private void GetAllFixedString() { foreach (var pd in ProtoDescriptorAll.Instance.AllProtoDescriptor) { foreach (var message in pd.Messages) { foreach (var field in message.Fields) { if (field.FieldType == FieldType.String) { if (AllFixStringClass.Contains(field.StringLength) == false) { AllFixStringClass.Add(field.StringLength); } } } } } //AllFixStringClass = AllFixStringClass.OrderBy(o => o).to } private void GetAllRepeatedStructClass() { foreach (var pd in ProtoDescriptorAll.Instance.AllProtoDescriptor) { foreach (var message in pd.Messages) { foreach (var field in message.Fields) { if (field.IsRepeated == false && field.FieldType != FieldType.Bytes) { continue; } //生成的repeated class 名字, 类似 string repeatedclassname = field.GetRepeatedFiledTypeNameInCSharp(); if (repeatedclassname != null) { if (AllRepeatedStructSet.Contains(repeatedclassname) == false) { AllRepeatedStructSet.Add(repeatedclassname); AllRepeatedStructList.Add(field); } } } } } } private void WriteAllProtoFile() { foreach (var pd in ProtoDescriptorAll.Instance.AllProtoDescriptor) { WriteProtoFile(pd); } } private void WriteProtoFile(ProtoDescriptor pd) { string outfile = pd.OutPutFile; string nameSpace = pd.NameSpace; FileWriter fw = new FileWriter(outfile); fw.Write(Define.FileHeader); fw.Write( "using System;", "", "namespace " + nameSpace, "{", "" ); fw.Indent(); WriteAllMessage(pd, fw); fw.Outdent(); fw.Write("}");//namespace fw.WriteToFile(); Console.WriteLine("generator csharp file {0} success", outfile); //枚举单独写一个文件,方便共享 WriteAllEnums(pd); //需要生成class描述的message单独生成一个文件 WriteMessageClassDesc(pd); } private void WriteAllEnums(ProtoDescriptor pd) { FileWriter fw = new FileWriter(pd.EnumOutPutFile); fw.Write(Define.FileHeader); fw.Write( "using System;", "", "namespace " + pd.NameSpace, "{", "" ); fw.Indent(); fw.Write("//"); fw.Write("//enum"); fw.Write("//"); fw.Write("#region Enums"); fw.Write(""); EnumWriter ew = new EnumWriter(); foreach (var oneEnum in pd.Enums) { ew.Write(oneEnum, fw); } fw.Write(""); fw.Write("#endregion"); fw.Outdent(); fw.Write("}");//namespace fw.WriteToFile(); Console.WriteLine("generator csharp file {0} success", pd.EnumOutPutFile); } private void WriteAllMessage(ProtoDescriptor pd, FileWriter fw) { MessageWriter mw = new MessageWriter(); fw.Write("//"); fw.Write("//message"); fw.Write("//"); fw.Write("#region Messages"); fw.Write(""); foreach (var message in pd.Messages) { mw.Write(message, fw); } fw.Write(""); fw.Write("#endregion"); } private void WriteMessageClassDesc(ProtoDescriptor pd) { if (pd.MessagesNeedClassDesc.Count == 0) { return; } MessageWriter mw = new MessageWriter(); FileWriter fw = new FileWriter(pd.ClassOutPutFile); fw.Write(Define.FileHeader); fw.Write( //"#if ILRUNTIME_MODE", //"", "using System;", "using System.Collections.Generic;", "using BinarySerialize;", "using System.IO;", "", "namespace " + pd.NameSpace, "{", "" ); fw.Indent(); fw.Write("//"); fw.Write("//class desc"); fw.Write("//"); fw.Write("#region ClassDesc"); fw.Write(""); foreach (var message in pd.MessagesNeedClassDesc) { mw.WriteClassDesc(message, fw); } fw.Write(""); fw.Write("#endregion"); fw.Outdent(); fw.Write("}");//namespace //fw.Write(""); //fw.Write("#endif"); fw.WriteToFile(); Console.WriteLine("generator csharp file {0} success", pd.ClassOutPutFile); } } }