public override void GetBlock(BlockArguments args)
{
int blockDataLength = m_blockDataLength;
long pos = args.Position;
if (IsDisposed || m_ioSessions.IsDisposed)
{
throw new ObjectDisposedException(GetType().FullName);
}
if (pos < 0)
{
throw new ArgumentOutOfRangeException("position", "cannot be negative");
}
if (pos >= (long)blockDataLength * (uint.MaxValue - 1))
{
throw new ArgumentOutOfRangeException("position", "position reaches past the end of the file.");
}
uint physicalBlockIndex;
uint indexPosition;
if (pos <= uint.MaxValue) //64-bit divide is 2 times slower
{
indexPosition = ((uint)pos / (uint)blockDataLength);
}
else
{
indexPosition = (uint)((ulong)pos / (ulong)blockDataLength); //64-bit signed divide is twice as slow as 64-bit unsigned.
}
args.FirstPosition = (long)indexPosition * blockDataLength;
args.Length = blockDataLength;
if (args.IsWriting)
{
//Writing
if (m_isReadOnly)
{
throw new Exception("File is read only");
}
bool wasShadowPaged;
physicalBlockIndex = m_pager.VirtualToShadowPagePhysical(indexPosition, out wasShadowPaged);
if (wasShadowPaged)
{
m_stream.ClearIndexNodeCache(this, m_parser);
}
if (physicalBlockIndex == 0)
{
throw new Exception("Failure to shadow copy the page.");
}
DataIoSession.WriteToExistingBlock(physicalBlockIndex, BlockType.DataBlock, indexPosition);
args.FirstPointer = (IntPtr)DataIoSession.Pointer;
args.SupportsWriting = true;
}
else
{
//Reading
physicalBlockIndex = m_parser.VirtualToPhysical(indexPosition);
if (physicalBlockIndex <= 0)
{
throw new Exception("Page does not exist");
}
DataIoSession.Read(physicalBlockIndex, BlockType.DataBlock, indexPosition);
args.FirstPointer = (IntPtr)DataIoSession.Pointer;
args.SupportsWriting = !m_isReadOnly && physicalBlockIndex > m_lastEditedBlock;
}
}