diff --git a/BigEndianStructure.cs b/BigEndianStructure.cs new file mode 100644 index 0000000..c15ca8d --- /dev/null +++ b/BigEndianStructure.cs @@ -0,0 +1,118 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : EndianSwapStructure.cs +// Author(s) : Natalia Portillo +// +// Component : Component +// +// --[ Description ] ---------------------------------------------------------- +// +// Description +// +// --[ License ] -------------------------------------------------------------- +// +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 2.1 of the +// License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, see . +// +// ---------------------------------------------------------------------------- +// Copyright © 2011-2016 Natalia Portillo +// ****************************************************************************/ +using System; +using System.Linq; +using System.Reflection; +using System.Runtime.InteropServices; + +namespace DiscImageChef.Helpers +{ + public static class BigEndianStructure + { + // TODO: Check this works + /// + /// Marshals a big-endian byte array to a C# structure. Dunno if it works with nested structures. + /// + /// The big endian byte array. + /// Byte array. + /// C# structure type. + public static T ByteArrayToStructureBigEndian(byte[] bytes) where T : struct + { + GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned); + T stuff = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T)); + handle.Free(); + Type t = stuff.GetType(); + FieldInfo[] fieldInfo = t.GetFields(); + foreach(FieldInfo fi in fieldInfo) + { + if(fi.FieldType == typeof(short)) + { + short i16 = (short)fi.GetValue(stuff); + byte[] b16 = BitConverter.GetBytes(i16); + byte[] b16r = b16.Reverse().ToArray(); + fi.SetValueDirect(__makeref(stuff), BitConverter.ToInt16(b16r, 0)); + } + else if(fi.FieldType == typeof(int)) + { + int i32 = (int)fi.GetValue(stuff); + byte[] b32 = BitConverter.GetBytes(i32); + byte[] b32r = b32.Reverse().ToArray(); + fi.SetValueDirect(__makeref(stuff), BitConverter.ToInt32(b32r, 0)); + } + else if(fi.FieldType == typeof(long)) + { + long i64 = (long)fi.GetValue(stuff); + byte[] b64 = BitConverter.GetBytes(i64); + byte[] b64r = b64.Reverse().ToArray(); + fi.SetValueDirect(__makeref(stuff), BitConverter.ToInt64(b64r, 0)); + } + else if(fi.FieldType == typeof(ushort)) + { + ushort i16 = (ushort)fi.GetValue(stuff); + byte[] b16 = BitConverter.GetBytes(i16); + byte[] b16r = b16.Reverse().ToArray(); + fi.SetValueDirect(__makeref(stuff), BitConverter.ToUInt16(b16r, 0)); + } + else if(fi.FieldType == typeof(uint)) + { + uint i32 = (uint)fi.GetValue(stuff); + byte[] b32 = BitConverter.GetBytes(i32); + byte[] b32r = b32.Reverse().ToArray(); + fi.SetValueDirect(__makeref(stuff), BitConverter.ToUInt32(b32r, 0)); + } + else if(fi.FieldType == typeof(ulong)) + { + ulong i64 = (ulong)fi.GetValue(stuff); + byte[] b64 = BitConverter.GetBytes(i64); + byte[] b64r = b64.Reverse().ToArray(); + fi.SetValueDirect(__makeref(stuff), BitConverter.ToUInt64(b64r, 0)); + } + else if(fi.FieldType == typeof(float)) + { + float iflt = (float)fi.GetValue(stuff); + byte[] bflt = BitConverter.GetBytes(iflt); + byte[] bfltr = bflt.Reverse().ToArray(); + fi.SetValueDirect(__makeref(stuff), BitConverter.ToSingle(bfltr, 0)); + } + else if(fi.FieldType == typeof(double)) + { + double idbl = (double)fi.GetValue(stuff); + byte[] bdbl = BitConverter.GetBytes(idbl); + byte[] bdblr = bdbl.Reverse().ToArray(); + fi.SetValueDirect(__makeref(stuff), BitConverter.ToDouble(bdblr, 0)); + } + } + return stuff; + } + } +} + diff --git a/ChangeLog b/ChangeLog index 3b9f5c6..486a931 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2016-08-21 Natalia Portillo + + * BigEndianStructure.cs: + * DiscImageChef.Helpers.csproj: Added code that directly + marshals from a big-endian byte array. But untested with + nested structures. + 2016-08-09 Natalia Portillo * DiscImageChef.Helpers.csproj: Bumped version to 3.2.99.2. diff --git a/DiscImageChef.Helpers.csproj b/DiscImageChef.Helpers.csproj index bad2344..f1d6aea 100644 --- a/DiscImageChef.Helpers.csproj +++ b/DiscImageChef.Helpers.csproj @@ -42,6 +42,7 @@ +