Tuesday 13 September 2011

Struct serialize and deserialize


A while ago i had to make some structures in C# that you can easy serialize/deserialize.  The constraint was to have the structure and the fields mirror the serialization (eg : for a struct 3 bytes struct we have a 3 bytes serialization stream).

First find out : for c# and c++ structs the memory allocation is 'optimized' and the fields may not be sequential or may not occupy the expected size in bytes.

Solution(C#) : use [StructLayout(LayoutKind.Sequential, Pack = 1)] attribute

The serialize and deserialize functions try to save/load the pointed memory :

        //serialize any object by geting the unmanaged byte stream
        internal static byte[] rawSerialize(object anything)
        {
            int rawSize = Marshal.SizeOf(anything);
            IntPtr buffer = Marshal.AllocHGlobal(rawSize);
            Marshal.StructureToPtr(anything, buffer, false);
            byte[] rawDatas = new byte[rawSize];
            Marshal.Copy(buffer, rawDatas, 0, rawSize);
            Marshal.FreeHGlobal(buffer);
            return rawDatas;
        }

        //deserialize byte stream
        internal static object rawDeserialize(byte[] rawData, ref ulong position, Type anyType)
        {
            object retVal = null;

            if (rawData != null && rawData.Length > 0)
            {
                int rawsize = Marshal.SizeOf(anyType);
                if (rawsize > rawData.LongLength)
                    return null;
                IntPtr buffer = Marshal.AllocHGlobal(rawsize);
                Marshal.Copy(rawData, (int)position, buffer, rawsize);
                retVal = Marshal.PtrToStructure(buffer, anyType);
                Marshal.FreeHGlobal(buffer);
                position += (ulong)rawsize;
            }

            return retVal;
        }
Hope it was helpful  : D

1 comment:

  1. Thanks, nice feedback !
    The goal is to make it useful

    ReplyDelete