MemoryReader.cs 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. using System.IO;
  2. using System.Runtime.InteropServices;
  3. namespace FF8
  4. {
  5. class MemoryReader : BinaryReader
  6. {
  7. public long Length => BaseStream.Length;
  8. public long Position => BaseStream.Position;
  9. public MemoryReader(byte[] buffer) : base(new MemoryStream(buffer)) { }
  10. public void Seek(long offset, SeekOrigin origin)
  11. {
  12. BaseStream.Seek(offset, origin);
  13. }
  14. /// <summary>
  15. /// Allows C/C++ classes and structs to be read directly from a stream <see cref="https://docs.microsoft.com/en-us/dotnet/framework/interop/marshaling-classes-structures-and-unions"/>
  16. /// </summary>
  17. /// <typeparam name="T"></typeparam>
  18. /// <returns></returns>
  19. public T Read<T>()
  20. {
  21. var buffer = ReadBytes(Marshal.SizeOf<T>());
  22. var handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
  23. var result = Marshal.PtrToStructure<T>(handle.AddrOfPinnedObject());
  24. handle.Free();
  25. return result;
  26. }
  27. /// <summary>
  28. /// Allows an array of C/C++ classes and structs to be read directly from a stream <see cref="https://docs.microsoft.com/en-us/dotnet/framework/interop/marshaling-classes-structures-and-unions"/>
  29. /// </summary>
  30. /// <typeparam name="T"></typeparam>
  31. /// <returns></returns>
  32. public T[] Read<T>(int count)
  33. {
  34. T[] array = new T[count];
  35. var size = Marshal.SizeOf<T>();
  36. for (var i = 0; i < count; i++)
  37. {
  38. var buffer = ReadBytes(size);
  39. var handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
  40. array[i] = Marshal.PtrToStructure<T>(handle.AddrOfPinnedObject());
  41. handle.Free();
  42. }
  43. return array;
  44. }
  45. }
  46. }