协议解析

zw
smartwyy 7 months ago
parent 6f0ab1b44e
commit 9d3ac3270c

@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\HybirdFrameworkCore\HybirdFrameworkCore.csproj" />
<ProjectReference Include="..\HybirdFrameworkEntity\HybirdFrameworkEntity.csproj" />
</ItemGroup>
</Project>

@ -0,0 +1,44 @@
// See https://aka.ms/new-console-template for more information
using System.Reflection;
using System.Text;
using ConsoleStarter;
using HybirdFrameworkCore.Utils;
internal class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Hello, World!");
Type type = typeof(TestPerson);
var o = Activator.CreateInstance(type);
if (o != null)
{
TestPerson person = (TestPerson) o;
foreach (PropertyInfo property in person.GetType().GetProperties())
{
Console.WriteLine(property.PropertyType);
}
UInt16 ui = 12;
Console.WriteLine(Convert.ToInt16(ui));
Console.WriteLine(BitConverter.IsLittleEndian);
string str = "€";
//1252 windows-1252 ANSI Latin 1; Western European (Windows)
var array = Encoding.Unicode.GetBytes(str);
foreach (byte b in array)
{
Console.WriteLine(b);
}
Console.WriteLine(BitUtls.BytesToHexStr(array));
var array2 = Encoding.BigEndianUnicode.GetBytes(str);
Console.WriteLine(BitUtls.BytesToHexStr(array2));
}
}
}

@ -0,0 +1,37 @@
namespace ConsoleStarter;
public class TestPerson
{
public int Id { get; set; }
public int? Idn { get; set; }
public uint uit { get; set; }
public byte b { get; set; }
public sbyte sb { get; set; }
public byte[] bs { get; set; }
public string s { get; set; }
public string[] ss { get; set; }
public short st { get; set; }
public ushort ust { get; set; }
public Int16 I16 { get; set; }
public UInt16 UI16 { get; set; }
public Int32 I32 { get; set; }
public UInt32 UI32 { get; set; }
public Int64 I64 { get; set; }
public UInt64 UI64 { get; set; }
public long lg { get; set; }
public ulong ulg { get; set; }
public float ft { get; set; }
public double de { get; set; }
public bool bl { get; set; }
public bool[] bls { get; set; }
}

@ -4,7 +4,7 @@ public class OrderAttribute : System.Attribute
{
public readonly int Order;
public OrderAttribute(int order)
public OrderAttribute(int order = 0)
{
this.Order = order;
}

@ -0,0 +1,26 @@
namespace HybirdFrameworkCore.Autofac.Attribute;
public class PropertyAttribute : System.Attribute
{
public readonly int Start;
public readonly int Length;
public readonly PropertyReadConstant Type;
public readonly double Scale;
public readonly double Offset;
public PropertyAttribute(int start, int length, PropertyReadConstant type = PropertyReadConstant.Bit,
double scale = 1, double offset = 0)
{
this.Start = start;
this.Length = length;
this.Type = type;
this.Scale = scale;
this.Offset = offset;
}
}
public enum PropertyReadConstant
{
Bit,
Byte
}

@ -0,0 +1,198 @@
using System.Text;
namespace HybirdFrameworkCore.Utils;
public static class BitUtls
{
public static string Bytes2BinaryString(byte[] bytes)
{
return string.Join(" ", bytes.Select(b => Convert.ToString(b, 2).PadLeft(8, '0')));
}
/// <summary>
/// 字节数组转16进制字符串空格分隔
/// </summary>
/// <param name="byteDatas"></param>
/// <returns></returns>
public static string BytesToHexStr(byte[] byteDatas)
{
StringBuilder builder = new StringBuilder();
for (int i = 0; i < byteDatas.Length; i++)
{
builder.Append($"{byteDatas[i]:X2} ");
}
return builder.ToString().Trim();
}
public static byte[] HexStrToBytes(string hexStr)
{
//以 ' ' 分割字符串,并去掉空字符
string[] chars = hexStr.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
byte[] returnBytes = new byte[chars.Length];
//逐个字符变为16进制字节数据
for (int i = 0; i < chars.Length; i++)
{
returnBytes[i] = Convert.ToByte(chars[i], 16);
}
return returnBytes;
}
public static byte Byte2Bit(byte[] bytes, int startBit, int length)
{
if (length > 8)
{
throw new ArgumentException("length can not be greater then 8!");
}
/*
byte result = 0;
int index = startBit / 8;
byte b = bytes[index];
int suffix = startBit % 8;
if (suffix == 0)
{
byte mask = (byte)(255 >> (8 - length));
result = (byte)(b & mask);
}
else
{
if ((8 - suffix) >= length)
{
byte mask = (byte)(255 >> (8 - length));
result = (byte)(b & mask);
}
else
{
byte pre = (byte)(b >> suffix);
int remain = length - (8 - suffix);
byte nextByte = bytes[index + 1];
nextByte = (byte)(nextByte << (8 - remain));
nextByte = (byte)(nextByte >> (8 - remain));
nextByte = (byte)(nextByte << (8 - suffix));
result = (byte)(pre | nextByte);
}
}
return result;*/
byte[] sub = Sub(bytes, startBit, length);
return sub[0];
}
public static string BytesToHexStr(byte[] bytes, int startBit, int length)
{
byte[] sub = Sub(bytes, startBit, length);
return BytesToHexStr(sub);
}
/// <summary>
/// 00 00 01000000
/// 00000000 01010000
/// </summary>
/// <param name="bytes"></param>
/// <param name="startBit"></param>
/// <param name="length"></param>
/// <returns></returns>
public static byte[] Sub(byte[] bytes, int startBit, int length)
{
var skip = startBit % 8;
var index = startBit / 8;
byte bStart = (byte)(bytes[index] >> skip);
var needed = length - (8 - skip);
if (needed <= 0)
{
bStart = (byte)(bStart << (-needed + skip));
bStart = (byte)(bStart >> (-needed + skip));
return new[] { bStart };
}
var needRemain = needed % 8;
var needCount = needRemain == 0 ? needed / 8 : needed / 8 + 1;
List<byte> list = new List<byte>(needCount);
for (int i = 1; i <= needCount; i++)
{
byte b = bytes[index + i];
list.Add((byte)(((b & ((1 << needRemain) - 1)) << (8 - skip)) | bStart));
bStart = (byte)(b >> skip);
}
list.Add(bStart);
return list.ToArray();
}
public static float Byte2Float(byte[] bytes, int startBit, int length, double factor)
{
uint d = Byte2UInt16(bytes, startBit, length);
return (float)(d * factor);
}
public static double Byte2Double(byte[] bytes, int startBit, int length, double factor)
{
uint d = Byte2UInt32(bytes, startBit, length);
return (float)(d * factor);
}
public static UInt16 Byte2UInt16(byte[] bytes, int startBit, int length)
{
if (length < 9 || length > 16)
{
throw new ArgumentException("length should be less then 17 and greater then 8");
}
byte[] sub = Sub(bytes, startBit, length);
return BitConverter.ToUInt16(sub, 0);
}
public static Int16 Byte2Int16(byte[] bytes, int startBit, int length)
{
if (length < 9 || length > 16)
{
throw new ArgumentException("length should be less then 17 and greater then 8");
}
byte[] sub = Sub(bytes, startBit, length);
return BitConverter.ToInt16(sub, 0);
}
public static UInt32 Byte2UInt32(byte[] bytes, int startBit, int length)
{
if (length < 17 || length > 32)
{
throw new ArgumentException("length should be less then 32 and greater then 17");
}
byte[] sub = Sub(bytes, startBit, length);
if (sub.Length < 4)
{
sub = new[] { sub[0], sub[1], sub[2], (byte)0 };
}
return BitConverter.ToUInt32(sub, 0);
}
public static Int32 Byte2Int32(byte[] bytes, int startBit, int length)
{
if (length < 17 || length > 32)
{
throw new ArgumentException("length should be less then 32 and greater then 17");
}
byte[] sub = Sub(bytes, startBit, length);
if (sub.Length < 4)
{
sub = new[] { sub[0], sub[1], sub[2], (byte)0 };
}
return BitConverter.ToInt32(sub, 0);
}
}

@ -0,0 +1,120 @@
using System.Reflection;
using HybirdFrameworkCore.Autofac.Attribute;
namespace HybirdFrameworkCore.Utils;
public static class ModelConvert
{
private static readonly Type BOOLEAN = typeof(bool);
private static readonly Type BYTE = typeof(byte);
private static readonly Type SBYTE = typeof(sbyte);
private static readonly Type SHORT = typeof(short);
private static readonly Type USHORT = typeof(ushort);
private static readonly Type INT = typeof(int);
private static readonly Type UINT = typeof(uint);
private static readonly Type LONG = typeof(long);
private static readonly Type ULONG = typeof(ulong);
private static readonly Type FLOAT = typeof(float);
private static readonly Type DOUBLE = typeof(double);
private static readonly Type STRING = typeof(string);
public static T Decode<T>(byte[] bytes) where T : class, new()
{
T t = new T();
Type type = t.GetType();
PropertyInfo[] fields = type.GetProperties();
foreach (var field in fields)
{
SetPropertyValue(t, field, bytes);
}
return t;
}
private static void SetPropertyValue<T>(T t, PropertyInfo field, byte[] bytes)
{
PropertyAttribute? attribute = field.GetCustomAttribute<PropertyAttribute>();
if (attribute != null)
{
double scale = attribute.Scale;
int length = PropertyReadConstant.Byte == attribute.Type ? attribute.Length * 8 : attribute.Length;
int start = attribute.Start;
double offset = attribute.Offset;
Type propertyType = field.PropertyType;
if (propertyType == BOOLEAN)
{
field.SetValue(t,
Convert.ChangeType(BitUtls.Byte2Bit(bytes, start, length) == 1, propertyType), null);
}
else if (propertyType == BYTE || propertyType == SBYTE)
{
field.SetValue(t,
Convert.ChangeType(BitUtls.Byte2Bit(bytes, start, length) * scale - offset, propertyType), null);
}
else if (propertyType == USHORT)
{
field.SetValue(t,
Convert.ChangeType(BitUtls.Byte2UInt16(bytes, start, length) * scale - offset, propertyType), null);
}
else if (propertyType == SHORT)
{
field.SetValue(t,
Convert.ChangeType(BitUtls.Byte2Int16(bytes, start, length) * scale - offset, propertyType), null);
}
else if (propertyType == INT)
{
field.SetValue(t,
Convert.ChangeType(BitUtls.Byte2Int32(bytes, start, length) * scale - offset, propertyType), null);
}
else if (propertyType == UINT)
{
field.SetValue(t,
Convert.ChangeType(BitUtls.Byte2UInt32(bytes, start, length) * scale - offset, propertyType), null);
}
else if (propertyType == FLOAT)
{
field.SetValue(t,
Convert.ChangeType(BitUtls.Byte2Float(bytes, start, length, scale) - offset, propertyType), null);
}
else if (propertyType == DOUBLE)
{
field.SetValue(t,
Convert.ChangeType(BitUtls.Byte2Double(bytes, start, length, scale) - offset, propertyType), null);
}
else if (propertyType == STRING)
{
field.SetValue(t, Convert.ChangeType(BitUtls.BytesToHexStr(bytes, start, length), propertyType), null);
}
}
}
public static byte[] Encode<T>(T t) where T : class, new()
{
List<byte> list = new List<byte>();
Type type = t.GetType();
PropertyInfo[] fields = type.GetProperties();
Dictionary<PropertyAttribute, PropertyInfo> dictionary = new Dictionary<PropertyAttribute, PropertyInfo>();
foreach (var field in fields)
{
PropertyAttribute? attribute = field.GetCustomAttribute<PropertyAttribute>();
if (attribute != null)
{
dictionary.Add(attribute, field);
}
}
PropertyAttribute[] attributes = dictionary.Keys.ToArray();
Array.Sort(attributes, (a, b) => a.Start.CompareTo(b.Start));
return list.ToArray();
}
private static byte[] GetPropertyValue()
{
return new byte[]{0};
}
}

@ -31,6 +31,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "HybirdFramework.Driver", "H
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HybirdFrameworkDriver", "HybirdFrameworkDriver\HybirdFrameworkDriver.csproj", "{6ACFA707-E72E-4BA1-8262-9F2E5B758D46}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleStarter", "ConsoleStarter\ConsoleStarter.csproj", "{8EAFC092-1C8A-4CF7-B283-FFCB02D58ED8}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Starter", "Starter", "{E0B949DC-17FE-414D-8898-937A317BB853}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -65,6 +69,10 @@ Global
{6ACFA707-E72E-4BA1-8262-9F2E5B758D46}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6ACFA707-E72E-4BA1-8262-9F2E5B758D46}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6ACFA707-E72E-4BA1-8262-9F2E5B758D46}.Release|Any CPU.Build.0 = Release|Any CPU
{8EAFC092-1C8A-4CF7-B283-FFCB02D58ED8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8EAFC092-1C8A-4CF7-B283-FFCB02D58ED8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8EAFC092-1C8A-4CF7-B283-FFCB02D58ED8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8EAFC092-1C8A-4CF7-B283-FFCB02D58ED8}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -77,6 +85,7 @@ Global
{A6757DAD-EF5A-41FD-9323-F3FCF05ED777} = {A0BA21DB-6630-41AB-A0FD-594DBB197E0E}
{C2380814-15D4-491D-ADF2-ADC68617C3FA} = {6203689E-8261-4814-BFC2-013188AED6A1}
{6ACFA707-E72E-4BA1-8262-9F2E5B758D46} = {EF6B2DEC-ADAA-4A6D-AE93-0F98A555B265}
{8EAFC092-1C8A-4CF7-B283-FFCB02D58ED8} = {E0B949DC-17FE-414D-8898-937A317BB853}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {3E10BF3D-9914-44B1-A6AA-FCF013C3F155}

Loading…
Cancel
Save