45 lines
1.8 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|