using System.Runtime.InteropServices;

namespace FastArena.Network.Packets
{
    public static class StructBinaryConverter
    {
        public static byte[] GetBytes<T>(T s) where T : struct
        {
            return GetBytes(ref s);
        }
        
        public static byte[] GetBytes<T>(ref T s) where T : struct
        {
            int size = Marshal.SizeOf<T>();
            // TODO: implement array pool
            byte[] buffer = new byte[size];
            // tel GC to not move the buffer in memory
            var handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
            try
            {
                Marshal.StructureToPtr(s, handle.AddrOfPinnedObject(), false);
            }
            finally
            {
                handle.Free();
            }
            return buffer;
        }

        public static T ReadStruct<T>(byte[] buffer) where T : struct
        {
            T s;
            // tel GC to not move the buffer in memory
            var handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
            try
            {
                s = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
            }
            finally
            {
                handle.Free();
            }
            return s;
        }
    }
}