Advertisement
Guest User

Untitled

a guest
May 27th, 2011
1,117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 3.17 KB | None | 0 0
  1. //  using System.Runtime.InteropServices;
  2. //  using System.Linq;
  3. //  using Microsoft.VisualStudio.TestTools.UnitTesting;
  4.  
  5. [TestClass]
  6. public class EndianStructExtensionTests
  7. {
  8.     [StructLayout(LayoutKind.Sequential, Pack = 1)]
  9.     public struct Foo
  10.     {
  11.         public byte b1;
  12.         public short s;
  13.         public ushort S;
  14.         public int i;
  15.         public uint I;
  16.         public long l;
  17.         public ulong L;
  18.         public float f;
  19.         public double d;
  20.         [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]
  21.         public string MyString;
  22.     }
  23.  
  24.     [StructLayout(LayoutKind.Sequential, Pack = 1)]
  25.     public struct FooReversed
  26.     {
  27.         [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]
  28.         public string MyString;
  29.         public double d;
  30.         public float f;
  31.         public ulong L;
  32.         public long l;
  33.         public uint I;
  34.         public int i;
  35.         public ushort S;
  36.         public short s;
  37.         public byte b1;
  38.     }
  39.  
  40.     byte[] _defaultBEBytes = new byte[] {
  41.         1,
  42.         0,1,
  43.         0,1,
  44.         0,0,0,1,
  45.         0,0,0,1,
  46.         0,0,0,0,0,0,0,1,
  47.         0,0,0,0,0,0,0,1,
  48.         0x3F,0X80,0,0, // float of 1 (see http://en.wikipedia.org/wiki/Endianness#Floating-point_and_endianness)
  49.         0x3F,0xF0,0,0,0,0,0,0, // double of 1
  50.         0,0,0,0x67,0x6E,0x69,0x74,0x73,0x65,0x54 // Testing\0\0\0
  51.     };
  52.  
  53.     private FooReversed GetDefaultStruct()
  54.     {
  55.         FooReversed f;
  56.         f.b1 = 1;
  57.         f.s = 1;
  58.         f.S = 1;
  59.         f.i = 1;
  60.         f.I = 1;
  61.         f.l = 1;
  62.         f.L = 1;
  63.         f.f = 1.0f;
  64.         f.d = 1.0;
  65.         f.MyString = "Testing";
  66.         return f;
  67.     }
  68.  
  69.     [TestMethod]
  70.     public void ToStructHostEndian_BEBytesOfValueOneForMostTypes_Matches()
  71.     {
  72.         byte[] bytes = _defaultBEBytes.Reverse().ToArray();
  73.         FooReversed expected = GetDefaultStruct();
  74.  
  75.         FooReversed actual = bytes.ToStructureHostEndian<FooReversed>();
  76.  
  77.         Assert.AreEqual(expected, actual);
  78.     }
  79.  
  80.     [TestMethod]
  81.     public void ToBytesHostEndian_DefaultStruct_BytesMatch()
  82.     {
  83.         byte[] expected = _defaultBEBytes.Reverse().ToArray();
  84.  
  85.         byte[] actual = GetDefaultStruct().ToBytesHostEndian();
  86.  
  87.         CollectionAssert.AreEqual(expected,actual);
  88.     }
  89. }
  90.  
  91. public static class EndianExtensions
  92. {  
  93.     /// <summary>
  94.     /// Convert the bytes to a structure in host-endian format (little-endian on PCs).
  95.     /// To use with big-endian data, reverse all of the data bytes and create a struct that is in the reverse order of the data.
  96.     /// </summary>
  97.     /// <typeparam name="T"></typeparam>
  98.     /// <param name="buffer">The buffer.</param>
  99.     /// <returns></returns>
  100.     public static T ToStructureHostEndian<T>(this byte[] buffer) where T : struct
  101.     {
  102.         GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
  103.         T stuff = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
  104.         handle.Free();
  105.         return stuff;
  106.     }
  107.    
  108.     /// <summary>
  109.     /// Converts the struct to a byte array in the endianness of this machine.
  110.     /// </summary>
  111.     /// <typeparam name="T"></typeparam>
  112.     /// <param name="structure">The structure.</param>
  113.     /// <returns></returns>
  114.     public static byte[] ToBytesHostEndian<T>(this T structure) where T : struct
  115.     {
  116.         int size = Marshal.SizeOf(structure);
  117.         var buffer = new byte[size];
  118.         GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
  119.         Marshal.StructureToPtr(structure, handle.AddrOfPinnedObject(), true);
  120.         handle.Free();
  121.         return buffer;
  122.     }
  123. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement