private void Read(uint physicalBlockIndex, uint blockIndex) { if (m_currentPhysicalBlock == physicalBlockIndex) { return; } Flush(); if (blockIndex >= m_subFile.DataBlockCount) { uint additionalBlocks = blockIndex - m_subFile.DataBlockCount + 1; Memory.Clear(m_memory.Address, m_blockSize); m_header.AllocateFreeBlocks(additionalBlocks); m_subFile.DataBlockCount += additionalBlocks; } else { ReadBlockCount++; m_stream.Position = physicalBlockIndex * m_blockSize; int bytesRead = m_stream.Read(m_buffer, 0, m_blockSize); if (bytesRead < m_buffer.Length) { Array.Clear(m_buffer, bytesRead, m_buffer.Length - bytesRead); } Marshal.Copy(m_buffer, 0, m_memory.Address, m_buffer.Length); } //I don't need to verify any of the footer data since I've written it all correctly. m_currentPhysicalBlock = physicalBlockIndex; m_currentBlockIndex = blockIndex; }
/// <summary> /// Makes a shadow copy of the indirect index passed to this function. If the block does not exists, it creates it. /// </summary> /// <param name="sourceBlockAddress">The block to be copied</param> /// <param name="indexValue">the index value that goes in the footer of the file.</param> /// <param name="blockType">Gets the expected block type</param> /// <param name="remoteAddressOffset">the offset of the remote address that needs to be updated.</param> /// <param name="remoteBlockAddress">the value of the remote address.</param> /// <returns>Returns true if the block had to be shadowed, false if it did not change</returns> private bool ShadowCopyIndexIndirect(ref uint sourceBlockAddress, uint indexValue, BlockType blockType, int remoteAddressOffset, uint remoteBlockAddress) { uint indexIndirectBlock; //Make a copy of the index block referenced //if the block does not exist, create it. if (sourceBlockAddress == 0) { DiskIoSession buffer = m_ioSessions.SourceIndex; indexIndirectBlock = m_fileHeaderBlock.AllocateFreeBlocks(1); m_subFileHeader.TotalBlockCount++; buffer.WriteToNewBlock(indexIndirectBlock, blockType, indexValue); Memory.Clear(buffer.Pointer, buffer.Length); WriteIndexIndirectBlock(buffer.Pointer, remoteAddressOffset, remoteBlockAddress); sourceBlockAddress = indexIndirectBlock; return(true); } //if the data page is an old page, allocate space to create a new copy else if (sourceBlockAddress <= m_lastReadOnlyBlock) { indexIndirectBlock = m_fileHeaderBlock.AllocateFreeBlocks(1); m_subFileHeader.TotalBlockCount++; ReadThenWriteIndexIndirectBlock(sourceBlockAddress, indexIndirectBlock, indexValue, blockType, remoteAddressOffset, remoteBlockAddress); sourceBlockAddress = indexIndirectBlock; return(true); } //The page has already been copied, use the existing address. else { ReadThenWriteIndexIndirectBlock(sourceBlockAddress, sourceBlockAddress, indexValue, blockType, remoteAddressOffset, remoteBlockAddress); return(false); } }