Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // using System.Runtime.InteropServices;
- // using System.Linq;
- // using Microsoft.VisualStudio.TestTools.UnitTesting;
- [TestClass]
- public class EndianStructExtensionTests
- {
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
- public struct Foo
- {
- public byte b1;
- public short s;
- public ushort S;
- public int i;
- public uint I;
- public long l;
- public ulong L;
- public float f;
- public double d;
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]
- public string MyString;
- }
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
- public struct FooReversed
- {
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]
- public string MyString;
- public double d;
- public float f;
- public ulong L;
- public long l;
- public uint I;
- public int i;
- public ushort S;
- public short s;
- public byte b1;
- }
- byte[] _defaultBEBytes = new byte[] {
- 1,
- 0,1,
- 0,1,
- 0,0,0,1,
- 0,0,0,1,
- 0,0,0,0,0,0,0,1,
- 0,0,0,0,0,0,0,1,
- 0x3F,0X80,0,0, // float of 1 (see http://en.wikipedia.org/wiki/Endianness#Floating-point_and_endianness)
- 0x3F,0xF0,0,0,0,0,0,0, // double of 1
- 0,0,0,0x67,0x6E,0x69,0x74,0x73,0x65,0x54 // Testing\0\0\0
- };
- private FooReversed GetDefaultStruct()
- {
- FooReversed f;
- f.b1 = 1;
- f.s = 1;
- f.S = 1;
- f.i = 1;
- f.I = 1;
- f.l = 1;
- f.L = 1;
- f.f = 1.0f;
- f.d = 1.0;
- f.MyString = "Testing";
- return f;
- }
- [TestMethod]
- public void ToStructHostEndian_BEBytesOfValueOneForMostTypes_Matches()
- {
- byte[] bytes = _defaultBEBytes.Reverse().ToArray();
- FooReversed expected = GetDefaultStruct();
- FooReversed actual = bytes.ToStructureHostEndian<FooReversed>();
- Assert.AreEqual(expected, actual);
- }
- [TestMethod]
- public void ToBytesHostEndian_DefaultStruct_BytesMatch()
- {
- byte[] expected = _defaultBEBytes.Reverse().ToArray();
- byte[] actual = GetDefaultStruct().ToBytesHostEndian();
- CollectionAssert.AreEqual(expected,actual);
- }
- }
- public static class EndianExtensions
- {
- /// <summary>
- /// Convert the bytes to a structure in host-endian format (little-endian on PCs).
- /// 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.
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="buffer">The buffer.</param>
- /// <returns></returns>
- public static T ToStructureHostEndian<T>(this byte[] buffer) where T : struct
- {
- GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
- T stuff = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
- handle.Free();
- return stuff;
- }
- /// <summary>
- /// Converts the struct to a byte array in the endianness of this machine.
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="structure">The structure.</param>
- /// <returns></returns>
- public static byte[] ToBytesHostEndian<T>(this T structure) where T : struct
- {
- int size = Marshal.SizeOf(structure);
- var buffer = new byte[size];
- GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
- Marshal.StructureToPtr(structure, handle.AddrOfPinnedObject(), true);
- handle.Free();
- return buffer;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement