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; } }