From 9d3ac3270c4941989e13125218cc3e4cc9acda93 Mon Sep 17 00:00:00 2001 From: smartwyy <645583145@qq.com> Date: Sat, 13 Apr 2024 17:29:58 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8D=8F=E8=AE=AE=E8=A7=A3=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ConsoleStarter/ConsoleStarter.csproj | 15 ++ ConsoleStarter/Program.cs | 44 ++++ ConsoleStarter/TestPerson.cs | 37 ++++ .../Autofac/Attribute/OrderAttribute.cs | 2 +- .../Autofac/Attribute/PropertyAttribute.cs | 26 +++ HybirdFrameworkCore/Utils/BitUtls.cs | 198 ++++++++++++++++++ HybirdFrameworkCore/Utils/ModelConvert.cs | 120 +++++++++++ hybirdMyFrame.sln | 9 + 8 files changed, 450 insertions(+), 1 deletion(-) create mode 100644 ConsoleStarter/ConsoleStarter.csproj create mode 100644 ConsoleStarter/Program.cs create mode 100644 ConsoleStarter/TestPerson.cs create mode 100644 HybirdFrameworkCore/Autofac/Attribute/PropertyAttribute.cs create mode 100644 HybirdFrameworkCore/Utils/BitUtls.cs create mode 100644 HybirdFrameworkCore/Utils/ModelConvert.cs diff --git a/ConsoleStarter/ConsoleStarter.csproj b/ConsoleStarter/ConsoleStarter.csproj new file mode 100644 index 0000000..c645c7c --- /dev/null +++ b/ConsoleStarter/ConsoleStarter.csproj @@ -0,0 +1,15 @@ + + + + Exe + net6.0 + enable + enable + + + + + + + + diff --git a/ConsoleStarter/Program.cs b/ConsoleStarter/Program.cs new file mode 100644 index 0000000..9ef218c --- /dev/null +++ b/ConsoleStarter/Program.cs @@ -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)); + } + } +} + \ No newline at end of file diff --git a/ConsoleStarter/TestPerson.cs b/ConsoleStarter/TestPerson.cs new file mode 100644 index 0000000..9bb8d03 --- /dev/null +++ b/ConsoleStarter/TestPerson.cs @@ -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; } +} \ No newline at end of file diff --git a/HybirdFrameworkCore/Autofac/Attribute/OrderAttribute.cs b/HybirdFrameworkCore/Autofac/Attribute/OrderAttribute.cs index c21b862..e742330 100644 --- a/HybirdFrameworkCore/Autofac/Attribute/OrderAttribute.cs +++ b/HybirdFrameworkCore/Autofac/Attribute/OrderAttribute.cs @@ -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; } diff --git a/HybirdFrameworkCore/Autofac/Attribute/PropertyAttribute.cs b/HybirdFrameworkCore/Autofac/Attribute/PropertyAttribute.cs new file mode 100644 index 0000000..6080643 --- /dev/null +++ b/HybirdFrameworkCore/Autofac/Attribute/PropertyAttribute.cs @@ -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 +} \ No newline at end of file diff --git a/HybirdFrameworkCore/Utils/BitUtls.cs b/HybirdFrameworkCore/Utils/BitUtls.cs new file mode 100644 index 0000000..49611a0 --- /dev/null +++ b/HybirdFrameworkCore/Utils/BitUtls.cs @@ -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'))); + } + + /// + /// 字节数组转16进制字符串:空格分隔 + /// + /// + /// + 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); + } + + /// + /// 00 00 01000000 + /// 00000000 01010000 + /// + /// + /// + /// + /// + 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 list = new List(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); + } +} \ No newline at end of file diff --git a/HybirdFrameworkCore/Utils/ModelConvert.cs b/HybirdFrameworkCore/Utils/ModelConvert.cs new file mode 100644 index 0000000..7121747 --- /dev/null +++ b/HybirdFrameworkCore/Utils/ModelConvert.cs @@ -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(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, PropertyInfo field, byte[] bytes) + { + PropertyAttribute? attribute = field.GetCustomAttribute(); + 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) where T : class, new() + { + List list = new List(); + Type type = t.GetType(); + PropertyInfo[] fields = type.GetProperties(); + Dictionary dictionary = new Dictionary(); + foreach (var field in fields) + { + PropertyAttribute? attribute = field.GetCustomAttribute(); + 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}; + } +} \ No newline at end of file diff --git a/hybirdMyFrame.sln b/hybirdMyFrame.sln index a047ffb..4d13104 100644 --- a/hybirdMyFrame.sln +++ b/hybirdMyFrame.sln @@ -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}