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.
 
 
 
 
 
 

124 lines
3.0 KiB

using System.IO;
namespace ProtoCSStruct
{
/// <summary>
/// 定义接口,方便代码使用
/// </summary>
public interface IStructMessage
{
void ReadFrom(CodedInputStream input);
void WriteTo(CodedOutputStream output);
int CalculateSize();//打包后的大小
void Clear();
string GetName();
string ToString();
int StructSizeof(); //结构体内存大小(估算,不完全正确)
}
public interface IStructMessage<T> : IStructMessage where T : struct, IStructMessage<T>
{
}
public interface IStructMessageParser
{
void ParseFrom(byte[] data, int length);
string GetMessageString();
string GetMessageName();
IStructMessageParser Clone();
int GetStructSizeof();
}
public class StructMessageParser<T> : IStructMessageParser where T : struct, IStructMessage<T>
{
/// <summary>
/// 线程不安全,请逻辑层自己注意!!!
/// </summary>
T structData;
CodedInputStream input;
public void ParseFrom(byte[] data, int length)
{
if(input != null)
{
input.Init(data, 0, length);
}
else
{
input = new CodedInputStream(data, 0, length);
}
structData.Clear();
structData.ReadFrom(input);
return;
}
public string GetMessageString()
{
return structData.ToString();
}
public string GetMessageName()
{
return structData.GetName();
}
public ref T GetMessage()
{
return ref structData;
}
public ref T GetMessageClear()
{
structData.Clear();
return ref structData;
}
public IStructMessageParser Clone()
{
var cloneParser = new StructMessageParser<T>();
cloneParser.structData = this.structData;
return cloneParser;
}
public int GetStructSizeof()
{
return structData.StructSizeof();
}
}
/// <summary>
/// parse 整个buffer
/// </summary>
public static class StructMessageParseUtils
{
public static void ParseFrom<T>(ref T message, byte[] buffer )
where T : struct, IStructMessage<T>
{
CodedInputStream input = new CodedInputStream(buffer);
message.ReadFrom(input);
}
public static byte[] ToByteArray<T>(ref T message)
where T : struct, IStructMessage<T>
{
int size = message.CalculateSize();
if (size == 0) return new byte[0];
byte[] buffer = new byte[size];
CodedOutputStream output = new CodedOutputStream(buffer);
message.WriteTo(output);
//return buffer.Skip(0).Take(size).ToArray();
return buffer;
}
}
}