123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- using System;
- using System.Runtime.InteropServices;
- namespace DiskAccessLibrary.Mod
- {
- public class UnmanagedGigabyteBlockSeparatedRamDisk : Disk, ILoadableRamDisk
- {
- private const int SectorSize = 512;
- private const int BlockSize = Consts.Gigabyte;
- private IntPtr[] _blocks;
- public UnmanagedGigabyteBlockSeparatedRamDisk(int sizeInGigabyte)
- {
- _blocks = new IntPtr[sizeInGigabyte];
- Size = (long)sizeInGigabyte * Consts.Gigabyte;
- }
- public void Allocate()
- {
- for (var i = 0; i < _blocks.Length; i++)
- {
- _blocks[i] = Marshal.AllocHGlobal(BlockSize);
- }
- }
- public void Free()
- {
- foreach (var block in _blocks)
- {
- if (block != IntPtr.Zero) Marshal.FreeHGlobal(block);
- }
- _blocks = null;
- GC.Collect();
- GC.WaitForPendingFinalizers();
- }
- private void ReadBlock(byte[] buffer, int offset, int count, int blockIndex, int blockOffset)
- {
- Marshal.Copy(_blocks[blockIndex] + blockOffset, buffer, offset, count);
- }
- private void WriteBlock(byte[] buffer, int offset, int count, int blockIndex, int blockOffset)
- {
- Marshal.Copy(buffer, offset, _blocks[blockIndex] + blockOffset, count);
- }
- public void WriteData(long rawOffset, byte[] data)
- {
- for (var i = 0; i < data.Length;)
- {
- var blockIndex = (int)(rawOffset / BlockSize);
- var blockOffset = (int)(rawOffset % BlockSize);
- var bytesToWrite = BlockSize - blockOffset;
- if (i + bytesToWrite > data.Length)
- {
- bytesToWrite = data.Length - i;
- }
- WriteBlock(data, i, bytesToWrite, blockIndex, blockOffset);
- i += bytesToWrite;
- rawOffset += bytesToWrite;
- }
- }
- public override byte[] ReadSectors(long sectorIndex, int sectorCount)
- {
- var rawOffset = sectorIndex * SectorSize;
- var rawSize = sectorCount * SectorSize;
- var buffer = new byte[rawSize];
- for (var i = 0; i < rawSize;)
- {
- var blockIndex = (int)(rawOffset / BlockSize);
- var blockOffset = (int)(rawOffset % BlockSize);
- var bytesToRead = BlockSize - blockOffset;
- if (i + bytesToRead > rawSize)
- {
- bytesToRead = rawSize - i;
- }
- ReadBlock(buffer, i, bytesToRead, blockIndex, blockOffset);
- i += bytesToRead;
- rawOffset += bytesToRead;
- }
- return buffer;
- }
- public override void WriteSectors(long sectorIndex, byte[] data)
- {
- var rawOffset = sectorIndex * SectorSize;
- WriteData(rawOffset, data);
- }
- public override int BytesPerSector => SectorSize;
- public override long Size { get; }
- }
- }
|