public void InsertBytes(long index, byte[] bs) { try { long blockOffset; DataBlock block = GetDataBlock(index, out blockOffset); MemoryDataBlock memoryBlock = block as MemoryDataBlock; if (memoryBlock != null) { memoryBlock.InsertBytes(index - blockOffset, bs); return; } FileDataBlock fileBlock = (FileDataBlock)block; if (blockOffset == index && block.PreviousBlock != null) { MemoryDataBlock previousMemoryBlock = block.PreviousBlock as MemoryDataBlock; if (previousMemoryBlock != null) { previousMemoryBlock.InsertBytes(previousMemoryBlock.Length, bs); return; } } FileDataBlock prefixBlock = null; if (index > blockOffset) { prefixBlock = new FileDataBlock(fileBlock.FileOffset, index - blockOffset); } FileDataBlock suffixBlock = null; if (index < blockOffset + fileBlock.Length) { suffixBlock = new FileDataBlock( fileBlock.FileOffset + index - blockOffset, fileBlock.Length - (index - blockOffset)); } block = _dataMap.Replace(block, new MemoryDataBlock(bs)); if (prefixBlock != null) { _dataMap.AddBefore(block, prefixBlock); } if (suffixBlock != null) { _dataMap.AddAfter(block, suffixBlock); } } finally { _totalLength += bs.Length; OnLengthChanged(EventArgs.Empty); OnChanged(EventArgs.Empty); } }
public byte ReadByte(long index) { long blockOffset; DataBlock block = GetDataBlock(index, out blockOffset); FileDataBlock fileBlock = block as FileDataBlock; if (fileBlock != null) { return(ReadByteFromFile(fileBlock.FileOffset + index - blockOffset)); } else { MemoryDataBlock memoryBlock = (MemoryDataBlock)block; return(memoryBlock.Data[index - blockOffset]); } }
public void ApplyChanges() { if (_readOnly) { throw new OperationCanceledException("File is in read-only mode"); } if (_totalLength > _stream.Length) { _stream.SetLength(_totalLength); } long dataOffset = 0; for (DataBlock block = _dataMap.FirstBlock; block != null; block = block.NextBlock) { FileDataBlock fileBlock = block as FileDataBlock; if (fileBlock != null && fileBlock.FileOffset != dataOffset) { MoveFileBlock(fileBlock, dataOffset); } dataOffset += block.Length; } dataOffset = 0; for (DataBlock block = _dataMap.FirstBlock; block != null; block = block.NextBlock) { MemoryDataBlock memoryBlock = block as MemoryDataBlock; if (memoryBlock != null) { _stream.Position = dataOffset; for (int memoryOffset = 0; memoryOffset < memoryBlock.Length; memoryOffset += COPY_BLOCK_SIZE) { _stream.Write(memoryBlock.Data, memoryOffset, (int)Math.Min(COPY_BLOCK_SIZE, memoryBlock.Length - memoryOffset)); } } dataOffset += block.Length; } _stream.SetLength(_totalLength); ReInitialize(); }
public void WriteByte(long index, byte value) { try { long blockOffset; DataBlock block = GetDataBlock(index, out blockOffset); MemoryDataBlock memoryBlock = block as MemoryDataBlock; if (memoryBlock != null) { memoryBlock.Data[index - blockOffset] = value; return; } FileDataBlock fileBlock = (FileDataBlock)block; if (blockOffset == index && block.PreviousBlock != null) { MemoryDataBlock previousMemoryBlock = block.PreviousBlock as MemoryDataBlock; if (previousMemoryBlock != null) { previousMemoryBlock.AddByteToEnd(value); fileBlock.RemoveBytesFromStart(1); if (fileBlock.Length == 0) { _dataMap.Remove(fileBlock); } return; } } if (blockOffset + fileBlock.Length - 1 == index && block.NextBlock != null) { MemoryDataBlock nextMemoryBlock = block.NextBlock as MemoryDataBlock; if (nextMemoryBlock != null) { nextMemoryBlock.AddByteToStart(value); fileBlock.RemoveBytesFromEnd(1); if (fileBlock.Length == 0) { _dataMap.Remove(fileBlock); } return; } } FileDataBlock prefixBlock = null; if (index > blockOffset) { prefixBlock = new FileDataBlock(fileBlock.FileOffset, index - blockOffset); } FileDataBlock suffixBlock = null; if (index < blockOffset + fileBlock.Length - 1) { suffixBlock = new FileDataBlock( fileBlock.FileOffset + index - blockOffset + 1, fileBlock.Length - (index - blockOffset + 1)); } block = _dataMap.Replace(block, new MemoryDataBlock(value)); if (prefixBlock != null) { _dataMap.AddBefore(block, prefixBlock); } if (suffixBlock != null) { _dataMap.AddAfter(block, suffixBlock); } } finally { OnChanged(EventArgs.Empty); } }