Thursday, July 2, 2009

Quick and Dirty Way of Buffer Serialization in C#

This article will tell you to get raw buffer from the c# structure. Basically C# is a TypeSafe language, it never lets you to access byte-stream of any managed object. But You can still make a raw buffer using Marshal.StructureToPtr Method . Today, In this article I will introduce you to new serialization format called QP-Encoding(Quoted-Printable Encoding). QP-Encoding is old encoding style, but known to very little people. Its very simple to understand.
Its a string formed from Raw buffer, whose every byte is represented by '=XX' way. In QP every byte is represented by =and followed by the 2 character of Hex which tells you the value of that byte. BUT if byte is printable it will be printed as it is.

For Example: a buffer whose byte sequence is 41,4A,4F,08 Then QP could be =41=4A=4F=08 but since 41 4A and 4F is printable character you can also write as ")JO=08" (as a better QP)

Using marshalling technique here you can transform any(almost any) c# managed object into QP string using following function
static public string SerializeBuffer(object obj, ref int size)
{
size = Marshal.SizeOf(obj.GetType());
IntPtr ptr = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(obj, ptr, true);
byte[] byteArray = new byte[size];
string encode_qp = "";
for (int i = 0; i < size; ++i)
{
byte b = (byte)Marshal.ReadByte(ptr, i);
encode_qp += "=" + b.ToString("X2");
}
Marshal.FreeHGlobal(ptr);
return encode_qp;
}
This is How you can DeSerialize
static public void GetDeSerializedBuffer(ref object Obj, ref string QPData)
{
int size = Marshal.SizeOf(Obj.GetType());
IntPtr ptr = Marshal.AllocHGlobal(size);
for (int i = 0; i < size; i++)
{
Marshal.WriteByte(ptr, i, ReadByteFromQPString(ref QPData));
}
Obj = Marshal.PtrToStructure(ptr, Obj.GetType());
Marshal.FreeHGlobal(ptr);
}

No comments:

Post a Comment