I'm writing code to parse packets.
I want to change the reference address of the array, but I do not know how to change the reference address without using the pointer. If I copy a part of an array, I think it will slow down. If I use a pointer, it will be unsafe.
Below is the code I am writing.
public class Datagrams : LinkedList<DatagramPacket>
{
public Datagrams(byte[] RowData) : base()
{
AddLast(new DatagramPacket(RowData));
while(Last.Value.header.Length.LastIndicator)
{
///////////////////////////////////////////
//I want do that. But this is unsafe code//
///////////////////////////////////////////
AddLast(new DatagramPacket( RowData + sizeof[Last.Value] ));
}
}
}
public class DatagramPacket : Packet
{
public enum DatagramCmd : Byte
{
NOP = 0x0,
APRD = 0x1,
APWR = 0x2,
APRW = 0x3,
FPRD = 0x4,
FPWR = 0x5,
FPRW = 0x6,
BRD = 0x7,
BWR = 0x8,
BRW = 0x9,
LRD = 0xA,
LWR = 0xB,
LRW = 0xC,
ARMW = 0xD,
FRMW = 0xE
}
[StructLayout(LayoutKind.Explicit)]
public struct DatagramAddr
{
[MarshalAs(UnmanagedType.U4), FieldOffset(0)]
public UInt32 LogicalAddr;
[MarshalAs(UnmanagedType.U2), FieldOffset(0)]
public UInt16 SlaveAddr;
[MarshalAs(UnmanagedType.U2), FieldOffset(2)]
public UInt16 OffsetAddr;
}
public struct DatagramLength
{
[MarshalAs(UnmanagedType.U2)]
public UInt16 bits;
public int Length { get => bits & 0x07FF; }
public bool Valid { get => (bits & 0x0380) == 0; }
public bool RoundTrip { get => (bits & 0x4000) != 0; }
public bool LastIndicator { get => (bits & 0x8000) != 0; }
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct DatagramHeader
{
[MarshalAs(UnmanagedType.U1)]
public DatagramCmd Cmd;
[MarshalAs(UnmanagedType.U1)]
public Byte Index;
[MarshalAs(UnmanagedType.Struct)]
public DatagramAddr Addr;
[MarshalAs(UnmanagedType.Struct)]
public DatagramLength Length;
[MarshalAs(UnmanagedType.U2)]
public UInt16 Interrupt;
}
public DatagramHeader header;
public UInt16 wc; //Working Count
public DatagramPacket(byte[] RowData) : base(RowData)
{
header = new DatagramHeader();
GCHandle handle = GCHandle.Alloc(RowData, GCHandleType.Pinned);
try
{
header = (DatagramHeader)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(DatagramHeader));
}
finally
{
handle.Free();
}
body = new byte[header.Length.Length];
Buffer.BlockCopy(RowData, Marshal.SizeOf<DatagramHeader>(), body, 0, body.Length);
wc = BitConverter.ToUInt16(RowData, Marshal.SizeOf<DatagramHeader>() + body.Length);
}
public override Packet Parse()
{
throw new NotImplementedException();
}
}
Is there a way that change reference without using pointer?
I have already solved the problem by copying the array as shown below, but I think it will be slower than referring to it by any means. I tried to process packets in real time for showing graph, but should I give up real time processing as much as I use .net?
public class Datagrams : LinkedList<DatagramPacket>
{
public Datagrams(byte[] RowData) : base()
{
AddLast(new DatagramPacket(RowData));
while(Last.Value.header.Length.LastIndicator)
{
int index = Marshal.SizeOf<DatagramPacket.DatagramHeader>() + Last.Value.header.Length.Length + sizeof(UInt16);
byte[] temp = new byte[RowData.Length - index];
Buffer.BlockCopy(RowData, index, temp, 0, RowData.Length - index);
RowData = temp;
AddLast(new DatagramPacket(RowData));
}
}
}