using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.EndPoints.CytEndPoints { public class ByteStructConverter { public static T ToStruct(byte[] by) where T : struct { int objectSize = Marshal.SizeOf(typeof(T)); if (objectSize > by.Length) return default(T); // Allocate some unmanaged memory. IntPtr buffer = Marshal.AllocHGlobal(objectSize); // Copy the read byte array (byte[]) into the unmanaged memory block. Marshal.Copy(by, 0, buffer, objectSize); // Push the memory into a new struct of type (T). T returnStruct = (T)Marshal.PtrToStructure(buffer, typeof(T)); // Free the unmanaged memory block. Marshal.FreeHGlobal(buffer); return returnStruct; } public static object ToStruct(byte[] buffer, Type t) { int objectSize = Marshal.SizeOf(t); if (objectSize > buffer.Length) return null; // Allocate some unmanaged memory. IntPtr buf = Marshal.AllocHGlobal(objectSize); // Copy the read byte array (byte[]) into the unmanaged memory block. Marshal.Copy(buffer, 0, buf, objectSize); // Push the memory into a new struct of type (T). object result = Marshal.PtrToStructure(buf, t); // Free the unmanaged memory block. Marshal.FreeHGlobal(buf); return result; } public static byte[] Struct2Bytes(object o) { // create a new byte buffer the size of your struct byte[] buffer = new byte[Marshal.SizeOf(o)]; // pin the buffer so we can copy data into it w/o GC collecting it GCHandle bufferHandle = GCHandle.Alloc(buffer, GCHandleType.Pinned); // copy the struct data into the buffer Marshal.StructureToPtr(o, bufferHandle.AddrOfPinnedObject(), false); // free the GC handle bufferHandle.Free(); return buffer; } } public class ByteReader { private byte[] buffer; private int idx; private int length; public int Length => length; public ByteReader(byte[] data, int len) { buffer = new byte[len]; System.Buffer.BlockCopy(data, 0, buffer, 0, len); length = len; idx = 0; } public void Append(byte[] data, int len) { var buf = new byte[Length + len]; System.Buffer.BlockCopy(buffer, 0, buf, 0, Length); System.Buffer.BlockCopy(data, 0, buf, Length, len); buffer = buf; length += len; } public bool Reset(int curIdx = 0) { if (curIdx < length) idx = curIdx; return idx == curIdx; } public bool ReadBytes(byte[] buf, int len) { if (idx + len <= length) { System.Buffer.BlockCopy(buffer, (int)idx, buf, 0, (int)len); idx += len; return true; } return false; } public bool ReadInt(out int data) { data = 0; if (idx + 4 <= length) { data = BitConverter.ToInt32(buffer, (int)idx); idx += 4; return true; } return false; } public bool ReadUInt16(out UInt16 data) { data = 0; if (idx + 2 <= length) { data = BitConverter.ToUInt16(buffer, (int)idx); idx += 2; return true; } return false; } public bool ReadInt64(out Int64 data) { data = 0; if (idx + 8 <= length) { data = BitConverter.ToInt64(buffer, (int)idx); idx += 8; return true; } return false; } } }