File Stream C#

/****************************************************************************************************************
*                                                                                                               *
* Copyright (C) 2011 5173.com                                                                                   *
* This project may be copied only under the terms of the Apache License 2.0.                                    *
* Please visit the project Home Page http://bqqapicsharp.codeplex.com/ for more detail.                         *
*                                                                                                               *
****************************************************************************************************************/
namespace BQQAPIClient.Core.Utility
{
    using System;
    using System.Linq;
    using System.Reflection;
    using System.Runtime.InteropServices;
    internal static class Protocol
    {
        internal static byte[] GetBigEndianBytes(this ushort v)
        {
            return BitConverter.GetBytes(v.SwapEndian());
        }
        internal static byte[] GetBigEndianBytes(this uint v)
        {
            return BitConverter.GetBytes(v.SwapEndian());
        }
        internal static byte[] GetBigEndianBytes(this ulong v)
        {
            return BitConverter.GetBytes(v.SwapEndian());
        }
        internal static ushort GetLittleEndianUInt16(this byte[] data)
        {
            return data.GetLittleEndianUInt16(0);
        }
        internal static uint GetLittleEndianUInt32(this byte[] data)
        {
            return data.GetLittleEndianUInt32(0);
        }
        internal static ulong GetLittleEndianUInt64(this byte[] data)
        {
            return data.GetLittleEndianUInt64(0);
        }
        internal static ushort GetLittleEndianUInt16(this byte[] data, int index)
        {
            return BitConverter.ToUInt16(data, index).SwapEndian();
        }
        internal static uint GetLittleEndianUInt32(this byte[] data, int index)
        {
            return BitConverter.ToUInt32(data, index).SwapEndian();
        }
        internal static ulong GetLittleEndianUInt64(this byte[] data, int index)
        {
            return BitConverter.ToUInt64(data, index).SwapEndian();
        }
        internal static T BytesToStruct(this byte[] rawData) where T : IToBytes
        {
            T result = default(T);
            RespectEndianness(typeof(T), rawData);
            GCHandle handle = GCHandle.Alloc(rawData, GCHandleType.Pinned);
            try
            {
                IntPtr rawDataPtr = handle.AddrOfPinnedObject();
                result = (T)Marshal.PtrToStructure(rawDataPtr, typeof(T));
            }
            finally
            {
                handle.Free();
            }
            return result;
        }
        internal static byte[] StructToBytes(this T data) where T : IToBytes
        {
            byte[] rawData = new byte[Marshal.SizeOf(data)];
            GCHandle handle = GCHandle.Alloc(rawData, GCHandleType.Pinned);
            try
            {
                IntPtr rawDataPtr = handle.AddrOfPinnedObject();
                Marshal.StructureToPtr(data, rawDataPtr, false);
            }
            finally
            {
                handle.Free();
            }
            RespectEndianness(typeof(T), rawData);
            return rawData;
        }
        private static void RespectEndianness(Type type, byte[] data)
        {
            var fields = type.GetFields(BindingFlags.NonPublic | BindingFlags.Instance).Select(field => new
            {
                Field = field,
                Offset = Marshal.OffsetOf(type, field.Name).ToInt32()
            }).ToList();
            fields.ForEach(item => Array.Reverse(data, item.Offset, Marshal.SizeOf(item.Field.FieldType)));
        }
        private static ushort SwapEndian(this ushort v)
        {
            return (ushort)(((v & 0xff) << 8) | ((v >> 8) & 0xff));
        }
        private static uint SwapEndian(this uint v)
        {
            return (uint)(((SwapEndian((ushort)v) & 0xffff) << 0x10) |
                           (SwapEndian((ushort)(v >> 0x10)) & 0xffff));
        }
        internal static ulong SwapEndian(this ulong v)
        {
            return (ulong)(((SwapEndian((uint)v) & 0xffffffffL) << 0x20) |
                            (SwapEndian((uint)(v >> 0x20)) & 0xffffffffL));
        }
    }
}