magellan/Lucidiot.Raima/Helpers.cs

45 lines
1.8 KiB
C#

using System.IO;
using System.Runtime.InteropServices;
using System;
namespace Lucidiot.Raima {
internal static class Helpers {
internal class ParsingException : Exception {
public readonly byte[] ErroneousBytes;
public readonly Type DestinationType;
public ParsingException(byte[] bytes, Type type)
: this(bytes, type, String.Format("An error occurred while parsing binary data into a {0} type.", type.AssemblyQualifiedName)) { }
public ParsingException(byte[] bytes, Type type, string message)
: base(message) {
this.ErroneousBytes = bytes;
this.DestinationType = type;
}
public ParsingException(byte[] bytes, Type type, Exception innerException)
: this(bytes, type, String.Format("An error occurred while parsing binary data into a {0} type.", type.AssemblyQualifiedName), innerException) { }
public ParsingException(byte[] bytes, Type type, string message, Exception innerException)
: base(message, innerException) {
this.ErroneousBytes = bytes;
this.DestinationType = type;
}
}
internal static T ReadStruct<T>(BinaryReader reader) where T : struct {
byte[] bytes = reader.ReadBytes(Marshal.SizeOf(typeof(T)));
GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
T parsedStruct;
try {
parsedStruct = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
} catch (TypeLoadException e) {
throw new ParsingException(bytes, typeof(T), e);
} finally {
handle.Free();
}
return parsedStruct;
}
}
}