using System;
using System.Linq;
using System.Reflection;
using BinaryProtocol.Core.Attributes;
namespace BinaryProtocol.Core.Coder
{
public class BitDecoder<T>
{
private readonly byte[] _objBytes;
public BitDecoder(byte[] objBytes)
{
_objBytes = objBytes;
Decode();
}
public T Value { get; private set; }
private void Decode()
{
int index = 0;
T obj = Activator.CreateInstance<T>();
var type = typeof(T);
PropertyInfo[] properties;
if (!PropertyDictionary.ContainsKey(type.FullName))
{
properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly)
.Where(r => r.CustomAttributes.Select(t => t.AttributeType).Contains(typeof(FieldIndex)))
.OrderBy(r => ((FieldIndex)r.GetCustomAttributes(typeof(FieldIndex), false).FirstOrDefault()).Index).ToArray();
PropertyDictionary.Add(type.FullName, properties);
}
else
{
properties = PropertyDictionary.Cache[type.FullName];
}
foreach (var p in properties)
{
byte[] bytes;
byte[] bytes2;
switch (p.PropertyType.Name)
{
case "String":
bytes = new byte[2];
Buffer.BlockCopy(_objBytes, index, bytes, 0, 2);
bytes2 = bytes.Reverse().ToArray();
var strLen = BitConverter.ToUInt16(bytes2, 0);
index += 2;
var str = System.Text.Encoding.UTF8.GetString(_objBytes, index, strLen);
p.SetValue(obj, str);
index += strLen;
break;
case "DateTime":
var format = "yyyy-MM-dd HH:mm:ss fff";
var dateLen = System.Text.Encoding.UTF8.GetBytes(format).Length;
var dateStr = System.Text.Encoding.UTF8.GetString(_objBytes, index, dateLen);
DateTime date = GetDateTime(dateStr);
p.SetValue(obj, date);
index += dateLen;
break;
case "Boolean":
bytes = new byte[1];
Buffer.BlockCopy(_objBytes, index, bytes, 0, 1);
bytes2 = bytes.Reverse().ToArray();
p.SetValue(obj, BitConverter.ToBoolean(bytes2, 0));
index += 1;
break;
case "Char":
bytes = new byte[2];
Buffer.BlockCopy(_objBytes, index, bytes, 0, 2);
bytes2 = bytes.Reverse().ToArray();
p.SetValue(obj, BitConverter.ToChar(bytes2, 0));
index += 2;
break;
case "Byte":
bytes = new byte[2];
Buffer.BlockCopy(_objBytes, index, bytes, 0, 2);
bytes2 = bytes.Reverse().ToArray();
p.SetValue(obj, Convert.ToByte(BitConverter.ToInt16(bytes2, 0)));//这里可能有毛病
index += 2;
break;
case "Int16":
bytes = new byte[2];
Buffer.BlockCopy(_objBytes, index, bytes, 0, 2);
bytes2 = bytes.Reverse().ToArray();
p.SetValue(obj, BitConverter.ToInt16(bytes2, 0));
index += 2;
break;
case "Int32":
bytes = new byte[4];
Buffer.BlockCopy(_objBytes, index, bytes, 0, 4);
bytes2 = bytes.Reverse().ToArray();
p.SetValue(obj, BitConverter.ToInt32(bytes2, 0));
index += 4;
break;
case "Int64":
bytes = new byte[8];
Buffer.BlockCopy(_objBytes, index, bytes, 0, 8);
bytes2 = bytes.Reverse().ToArray();
p.SetValue(obj, BitConverter.ToInt64(bytes2, 0));
index += 8;
break;
case "Single":
bytes = new byte[4];
Buffer.BlockCopy(_objBytes, index, bytes, 0, 4);
bytes2 = bytes.Reverse().ToArray();
p.SetValue(obj, BitConverter.ToSingle(bytes2, 0));
index += 4;
break;
case "Double":
bytes = new byte[8];
Buffer.BlockCopy(_objBytes, index, bytes, 0, 8);
bytes2 = bytes.Reverse().ToArray();
p.SetValue(obj, BitConverter.ToDouble(bytes2, 0));
index += 8;
break;
case "SByte":
bytes = new byte[2];
Buffer.BlockCopy(_objBytes, index, bytes, 0, 2);
bytes2 = bytes.Reverse().ToArray();
p.SetValue(obj, Convert.ToSByte(BitConverter.ToUInt16(bytes2, 0)));//这里可能有毛病
index += 2;
break;
case "UInt16":
bytes = new byte[2];
Buffer.BlockCopy(_objBytes, index, bytes, 0, 2);
bytes2 = bytes.Reverse().ToArray();
p.SetValue(obj, BitConverter.ToUInt16(bytes2, 0));
index += 2;
break;
case "UInt32":
bytes = new byte[4];
Buffer.BlockCopy(_objBytes, index, bytes, 0, 4);
bytes2 = bytes.Reverse().ToArray();
p.SetValue(obj, BitConverter.ToUInt32(bytes2, 0));
index += 4;
break;
case "UInt64":
bytes = new byte[8];
Buffer.BlockCopy(_objBytes, index, bytes, 0, 8);
bytes2 = bytes.Reverse().ToArray();
p.SetValue(obj, BitConverter.ToUInt64(bytes2, 0));
index += 8;
break;
}
}
Value = obj;
}
/// <summary>
/// 带毫秒的字符转换成时间(DateTime)格式
/// 可处理格式:[2014-10-10 10:10:10,666 或 2014-10-10 10:10:10 666 或 2014-10-10 10:10:10.666]
/// </summary>
private DateTime GetDateTime(string dateTime)
{
string[] strArr = dateTime.Split('-', ' ', ':', ',', '.');
DateTime dt = new DateTime(int.Parse(strArr[0]),
int.Parse(strArr[1]),
int.Parse(strArr[2]),
int.Parse(strArr[3]),
int.Parse(strArr[4]),
int.Parse(strArr[5]),
int.Parse(strArr[6]));
return dt;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using BinaryProtocol.Core.Attributes;
namespace BinaryProtocol.Core.Coder
{
public class BitEncoder<T>
{
private readonly T _obj;
public BitEncoder(T obj)
{
_obj = obj;
Encode();
}
public byte[] Bytes { get; private set; }
private void Encode()
{
if (_obj == null)
{
Bytes = new byte[0];
}
List<byte> byteList = new List<byte>();
var type = _obj.GetType();
PropertyInfo[] properties;
if (!PropertyDictionary.ContainsKey(type.FullName))
{
properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly)
.Where(r => r.CustomAttributes.Select(t => t.AttributeType).Contains(typeof(FieldIndex)))
.OrderBy(r => ((FieldIndex)r.GetCustomAttributes(typeof(FieldIndex), false).FirstOrDefault()).Index).ToArray();
PropertyDictionary.Add(type.FullName, properties);
}
else
{
properties = PropertyDictionary.Cache[type.FullName];
}
foreach (var p in properties)
{
var value = p.GetValue(_obj);
switch (p.PropertyType.Name)
{
case "String":
var strBytes = System.Text.Encoding.UTF8.GetBytes(value.ToString());
Int16 len = (short)strBytes.Length;
var bytes = BitConverter.GetBytes(len).Reverse();
byteList.AddRange(bytes);
byteList.AddRange(strBytes);
break;
case "DateTime":
var format = "yyyy-MM-dd HH:mm:ss fff";
var dateStr = ((DateTime)value).ToString(format);
var dateBytes = System.Text.Encoding.UTF8.GetBytes(dateStr);
byteList.AddRange(dateBytes.ToList());
break;
case "Boolean":
byteList.AddRange(BitConverter.GetBytes((bool)value).Reverse().ToList());
break;
case "Char":
byteList.AddRange(BitConverter.GetBytes((char)value).Reverse().ToList());
break;
case "Byte":
byteList.AddRange(BitConverter.GetBytes((Byte)value).Reverse().ToList());
break;
case "Int16":
byteList.AddRange(BitConverter.GetBytes((Int16)value).Reverse().ToList());
break;
case "Int32":
byteList.AddRange(BitConverter.GetBytes((Int32)value).Reverse().ToList());
break;
case "Int64":
byteList.AddRange(BitConverter.GetBytes((Int64)value).Reverse().ToList());
break;
case "Single":
byteList.AddRange(BitConverter.GetBytes((float)value).Reverse().ToList());
break;
case "Double":
byteList.AddRange(BitConverter.GetBytes((Double)value).Reverse().ToList());
break;
case "SByte":
byteList.AddRange(BitConverter.GetBytes((SByte)value).Reverse().ToList());
break;
case "UInt16":
byteList.AddRange(BitConverter.GetBytes((UInt16)value).Reverse().ToList());
break;
case "UInt32":
byteList.AddRange(BitConverter.GetBytes((UInt32)value).Reverse().ToList());
break;
case "UInt64":
byteList.AddRange(BitConverter.GetBytes((UInt64)value).Reverse().ToList());
break;
}
}
Bytes = byteList.ToArray();
}
}
}