using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using System.Text; using WCS.Core.DataTrans; using WCS.Entity; namespace WCS.Core { public static class Extentions { //public static PlcDB Regist(this IPlcConn plc, ushort dbNo, ushort length) //{ // var plc= new PlcDB(plc, dbNo, length); //} #region GetData public static byte[] GetData(this bool value) { return BitConverter.GetBytes(value); } public static byte[] GetData(this byte value) { return new byte[] { value }; } public static byte[] GetData(this char value) { return BitConverter.GetBytes(value); } public static byte[] GetData(this short value) { return BitConverter.GetBytes(value); } public static byte[] GetData(this ushort value) { return BitConverter.GetBytes(value); } public static byte[] GetData(this int value) { return BitConverter.GetBytes(value); } public static byte[] GetData(this uint value) { return BitConverter.GetBytes(value); } public static byte[] GetData(this long value) { return BitConverter.GetBytes(value); } public static byte[] GetData(this ulong value) { return BitConverter.GetBytes(value); } internal static Encoding enCoding = Encoding.GetEncoding("gb2312"); private static Dictionary ToBytesMethods = new Dictionary(); private static byte[] GetPrimitiveData(object obj) { try { var t = obj.GetType(); if (t == typeof(byte)) return new byte[] { (byte)obj }; MethodInfo mi; lock (ToBytesMethods) { if (!ToBytesMethods.TryGetValue(t, out mi)) { var ms = typeof(BitConverter).GetMethods(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static); ms = ms.Where(v => v.Name == "GetBytes").ToArray(); mi = ms.FirstOrDefault(v => v.GetParameters()[0].ParameterType == t); ToBytesMethods.Add(t, mi); } } var res = mi.Invoke(null, new object[] { obj }) as byte[]; //if (!BitConverter.IsLittleEndian) { res = res.Reverse().ToArray(); } return res; } catch (Exception) { throw; } } public static byte[] GetData(this object obj, byte dataSize = 0) { var type = obj.GetType(); System.IO.MemoryStream st = new System.IO.MemoryStream(); if (type.IsArray) { foreach (var o in obj as Array) { var data = GetData(o); st.Write(data, 0, data.Length); } } else { if (type == typeof(string)) { var data = enCoding.GetBytes(obj.ToString()); st.WriteByte(dataSize); st.WriteByte((byte)data.Length); st.Write(data, 0, data.Length); } else { var data = GetPrimitiveData(obj); st.Write(data, 0, data.Length); } } return st.ToArray(); } #endregion GetData /// /// 转换基元类型或者String /// /// /// 类型为基元类型或者String /// public static object GetObj(this byte[] data, Type type) { if (type == typeof(string)) { var len = data.Skip(1).First(); var bytes = data.Skip(2).Take(len).ToArray(); return Configs.StringEncoding.GetString(bytes); } else { if (type.IsEnum) type = type.GetEnumUnderlyingType(); data = data.Reverse().ToArray(); if (type == typeof(bool)) { return BitConverter.ToBoolean(data, 0); } else if (type == typeof(char)) { return BitConverter.ToChar(data, 0); } else if (type == typeof(byte)) { return data.First(); } else if (type == typeof(short)) { return BitConverter.ToInt16(data, 0); } else if (type == typeof(ushort)) { return BitConverter.ToUInt16(data, 0); } else if (type == typeof(int)) { return BitConverter.ToInt32(data, 0); } else if (type == typeof(uint)) { return BitConverter.ToUInt32(data, 0); } else if (type == typeof(long)) { return BitConverter.ToInt64(data, 0); } else if (type == typeof(ulong)) { return BitConverter.ToUInt64(data, 0); } else { throw new Exception("类型不支持"); } } } /// /// 转换基元类型或者String /// /// /// /// public static T GetObj(this byte[] data) { return (T)data.GetObj(typeof(T)); } /// /// 转换基元类型或者String,或数组 /// /// /// /// String长度 /// public static object GetObj(this byte[] data, Type type, byte datasize) { if (type.IsArray) { var t = type.GetElementType(); var lsttype = typeof(List<>).MakeGenericType(t); var lst = Activator.CreateInstance(lsttype) as System.Collections.IList; var i = 0; if (t == typeof(bool)) datasize = 1; else datasize = (byte)Marshal.SizeOf(t); while (i < data.Length) { var obj = GetObj(data.Skip(i).Take(datasize).ToArray(), t, datasize); lst.Add(obj); i += datasize; } var array = Array.CreateInstance(t, lst.Count) as Array; lst.CopyTo(array, 0); return array; } else return data.GetObj(type); } /// /// 转换基元类型或者String,或数组 /// /// /// /// String长度 /// public static T GetObj(this byte[] data, byte datasize = 0) { return (T)data.GetObj(typeof(T), datasize); } } public static class BitExtension { #region ushort /// /// 设置指定位置的位值的值 /// /// ushort对象 /// 指定位置 /// 值 /// public static ushort SetBit(this ushort value, int position, bool flag) { return SetBits(value, position, 1, flag ? (byte)1 : (byte)0); } /// /// 批量设置指定位置的位值的值 /// /// ushort对象 /// 开始位置 /// 长度 /// 值 /// public static ushort SetBits(this ushort value, int position, int length, ushort bits) { if (length <= 0 || position >= 16) return value; var mask = (2 << (length - 1)) - 1; value &= (ushort)~(mask << position); value |= (ushort)((bits & mask) << position); return value; } /// /// 获取指定位置的值 /// /// ushort对象 /// 指定位置 /// public static bool GetBit(this ushort value, int position) { return GetBits(value, position, 1) == 1; } /// /// 批量获取指定位置的值 /// /// ushort对象 /// 开始位值 /// 长度 /// public static ushort GetBits(this ushort value, int position, int length) { if (length <= 0 || position >= 16) return 0; var mask = (2 << (length - 1)) - 1; return (ushort)((value >> position) & mask); } #endregion ushort #region byte /// /// 设置指定位置的值 /// /// byte对象 /// 指定位置 /// 设置值 /// public static byte SetBit(this byte value, int position, bool flag) { if (position >= 8) return value; var mask = (2 << (1 - 1)) - 1; value &= (byte)~(mask << position); value |= (byte)(((flag ? 1 : 0) & mask) << position); return value; } /// /// 获取指定位置的值 /// /// byte对象 /// 指定位置 /// public static bool GetBit(this byte value, int position) { if (position >= 8) return false; var mask = (2 << (1 - 1)) - 1; return (byte)((value >> position) & mask) == 1; } #endregion byte #region uint /// /// 设置指定位置的位值的值 /// /// uint对象 /// 指定位置 /// 值 /// public static uint SetBit(this uint value, int position, bool flag) { return SetBits(value, position, 1, flag ? (byte)1 : (byte)0); } /// /// 批量设置指定位置的位值的值 /// /// uint对象 /// 开始位置 /// 长度 /// 值 /// public static uint SetBits(this uint value, int position, int length, uint bits) { if (length <= 0 || position >= 32) return value; var mask = (2 << (length - 1)) - 1; value &= (uint)~(mask << position); value |= (uint)((bits & mask) << position); return value; } /// /// 获取指定位置的值 /// /// uint对象 /// 指定位置 /// public static bool GetBit(this uint value, int position) { return GetBits(value, position, 1) == 1; } /// /// 批量获取指定位置的值 /// /// uint对象 /// 开始位值 /// 长度 /// public static uint GetBits(this uint value, int position, int length) { if (length <= 0 || position >= 32) return 0; var mask = (2 << (length - 1)) - 1; return (uint)((value >> position) & mask); } #endregion uint #region ulong /// /// 设置指定位置的位值的值 /// /// ulong对象 /// 指定位置 /// 值 /// public static ulong SetBit(this ulong value, int position, bool flag) { return SetBits(value, position, 1, flag ? (byte)1 : (byte)0); } /// /// 批量设置指定位置的位值的值 /// /// ulong对象 /// 开始位置 /// 长度 /// 值 /// public static ulong SetBits(this ulong value, int position, int length, ulong bits) { if (length <= 0 || position >= 64) return value; var mask = (ulong)(2 << (length - 1)) - 1; value &= ~(mask << position); value |= (bits & mask) << position; return value; } /// /// 获取指定位置的值 /// /// ulong对象 /// 指定位置 /// public static bool GetBit(this ulong value, int position) { return GetBits(value, position, 1) == 1; } /// /// 批量获取指定位置的值 /// /// ulong对象 /// 开始位值 /// 长度 /// public static ulong GetBits(this ulong value, int position, int length) { if (length <= 0 || position >= 64) return 0; var mask = (ulong)(2 << (length - 1)) - 1; return (value >> position) & mask; } #endregion ulong } public static class Extensions { private static ConcurrentDictionary Datas = new ConcurrentDictionary(); private static ConcurrentDictionary ExObjs = new ConcurrentDictionary(); public static T Data(this WCS_DEVICEPROTOCOL obj) { return (T)Data(obj); } public static object Data(this WCS_DEVICEPROTOCOL obj) { if (!Datas.ContainsKey(obj)) { var type = typeof(Generator<,>); type = type.MakeGenericType(obj.DB.GetProtocolType(), Configs.ProtocolProxyBaseType); var m = type.GetMethod("Create", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static); Datas[obj] = m.Invoke(null, new object[] { new object[] { obj.DEVICE.CODE.ToString(), obj.DB, (ushort)obj.POSITION, obj } }); } return Datas[obj]; } //public static WCS_DEVICE Device(this IDATA obj) //{ // return (obj as PLCData).Device; //} public static T GetEx(object entity) { if (!ExObjs.ContainsKey(entity)) { var obj = Activator.CreateInstance(typeof(T), entity); ExObjs[entity] = obj; } return (T)ExObjs[entity]; } public static DataBlock Ex(this WCS_DATABLOCK source) { return GetEx(source); } public static PlcAccessor Ex(this WCS_PLC source) { return GetEx(source); } public static WCS_DEVICEPROTOCOL PROTOCOL(this IProtocol obj) { return (obj as ProtocolProxyBase).Protocol; } public static T Create(this WCS_DEVICE source) { return (T)Activator.CreateInstance(typeof(T), source); } public static Device Device(this WCS_DEVICE source) where T : IProtocol { var res = (Device)Activator.CreateInstance(typeof(Device), source); return res; } public static Device Device(this WCS_DEVICE source) where T : IProtocol where T2 : IProtocol { return (Device)Activator.CreateInstance(typeof(Device), source); } public static Device Device(this WCS_DEVICE source) where T : IProtocol where T2 : IProtocol where T3 : IProtocol { return (Device)Activator.CreateInstance(typeof(Device), source); } public static DeviceGroup DeviceGroup(this WCS_DEVICE source) where T : IProtocol { return (DeviceGroup)Activator.CreateInstance(typeof(DeviceGroup), source); } public static DeviceGroup DeviceGroup(this WCS_DEVICE source) where T : IProtocol where T2 : IProtocol { return (DeviceGroup)Activator.CreateInstance(typeof(DeviceGroup), source); } public static DeviceGroup DeviceGroup(this WCS_DEVICE source) where T : IProtocol where T2 : IProtocol where T3 : IProtocol { return (DeviceGroup)Activator.CreateInstance(typeof(DeviceGroup), source); } public static DateTime GetUpdateTime(this IProtocol source) { dynamic obj = source; return obj.UpdateTime; } } }