/// <summary> /// See <see cref="IByteProvider.ApplyChanges" /> for more information. /// </summary> public void ApplyChanges() { if (_readOnly) { throw new OperationCanceledException("File is in read-only mode"); } // This method is implemented to efficiently save the changes to the same file stream opened for reading. // Saving to a separate file would be a much simpler implementation. // Firstly, extend the file length (if necessary) to ensure that there is enough disk space. if (_totalLength > _stream.Length) { _stream.SetLength(_totalLength); } // Secondly, shift around any file sections that have moved. 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; } // Next, write in-memory changes. 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; } // Finally, if the file has shortened, truncate the stream. _stream.SetLength(_totalLength); ReInitialize(); }
// Token: 0x0600036A RID: 874 RVA: 0x00012454 File Offset: 0x00010654 public void InsertBytes(long index, byte[] bs) { try { long num; DataBlock dataBlock = this.GetDataBlock(index, out num); MemoryDataBlock memoryDataBlock = dataBlock as MemoryDataBlock; if (memoryDataBlock != null) { memoryDataBlock.InsertBytes(index - num, bs); } else { FileDataBlock fileDataBlock = (FileDataBlock)dataBlock; if (num == index && dataBlock.PreviousBlock != null) { MemoryDataBlock memoryDataBlock2 = dataBlock.PreviousBlock as MemoryDataBlock; if (memoryDataBlock2 != null) { memoryDataBlock2.InsertBytes(memoryDataBlock2.Length, bs); return; } } FileDataBlock fileDataBlock2 = null; if (index > num) { fileDataBlock2 = new FileDataBlock(fileDataBlock.FileOffset, index - num); } FileDataBlock fileDataBlock3 = null; if (index < num + fileDataBlock.Length) { fileDataBlock3 = new FileDataBlock(fileDataBlock.FileOffset + index - num, fileDataBlock.Length - (index - num)); } dataBlock = this._dataMap.Replace(dataBlock, new MemoryDataBlock(bs)); if (fileDataBlock2 != null) { this._dataMap.AddBefore(dataBlock, fileDataBlock2); } if (fileDataBlock3 != null) { this._dataMap.AddAfter(dataBlock, fileDataBlock3); } } } finally { this._totalLength += (long)bs.Length; this.OnLengthChanged(EventArgs.Empty); this.OnChanged(EventArgs.Empty); } }
// Token: 0x06000368 RID: 872 RVA: 0x00012290 File Offset: 0x00010490 public byte ReadByte(long index) { long num; DataBlock dataBlock = this.GetDataBlock(index, out num); FileDataBlock fileDataBlock = dataBlock as FileDataBlock; if (fileDataBlock != null) { return(this.ReadByteFromFile(fileDataBlock.FileOffset + index - num)); } MemoryDataBlock memoryDataBlock = (MemoryDataBlock)dataBlock; return(memoryDataBlock.Data[(int)(checked ((IntPtr)(unchecked (index - num))))]); }
/// <summary> /// See <see cref="IByteProvider.ReadByte" /> for more information. /// </summary> public byte ReadByte(long index) { DataBlock block = GetDataBlock(index, out long 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]); } }
// Token: 0x0600036E RID: 878 RVA: 0x000126C8 File Offset: 0x000108C8 public void ApplyChanges() { if (this._readOnly) { throw new OperationCanceledException("File is in read-only mode"); } if (this._totalLength > this._stream.Length) { this._stream.SetLength(this._totalLength); } long num = 0L; for (DataBlock dataBlock = this._dataMap.FirstBlock; dataBlock != null; dataBlock = dataBlock.NextBlock) { FileDataBlock fileDataBlock = dataBlock as FileDataBlock; if (fileDataBlock != null && fileDataBlock.FileOffset != num) { this.MoveFileBlock(fileDataBlock, num); } num += dataBlock.Length; } num = 0L; for (DataBlock dataBlock2 = this._dataMap.FirstBlock; dataBlock2 != null; dataBlock2 = dataBlock2.NextBlock) { MemoryDataBlock memoryDataBlock = dataBlock2 as MemoryDataBlock; if (memoryDataBlock != null) { this._stream.Position = num; int num2 = 0; while ((long)num2 < memoryDataBlock.Length) { this._stream.Write(memoryDataBlock.Data, num2, (int)Math.Min(4096L, memoryDataBlock.Length - (long)num2)); num2 += 4096; } } num += dataBlock2.Length; } this._stream.SetLength(this._totalLength); this.ReInitialize(); }
/// <summary> /// See <see cref="IByteProvider.InsertBytes" /> for more information. /// </summary> public void InsertBytes(long index, byte[] bs) { try { // Find the block affected. long blockOffset; DataBlock block = GetDataBlock(index, out blockOffset); // If the insertion point is in a memory block, just insert it. MemoryDataBlock memoryBlock = block as MemoryDataBlock; if (memoryBlock != null) { memoryBlock.InsertBytes(index - blockOffset, bs); return; } FileDataBlock fileBlock = (FileDataBlock)block; // If the insertion point is at the start of a file block, and the previous block is a memory block, append it to that block. if (blockOffset == index && block.PreviousBlock != null) { MemoryDataBlock previousMemoryBlock = block.PreviousBlock as MemoryDataBlock; if (previousMemoryBlock != null) { previousMemoryBlock.InsertBytes(previousMemoryBlock.Length, bs); return; } } // Split the block into a prefix and a suffix and place a memory block in-between. 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); } }
/// <summary> /// See <see cref="IByteProvider.WriteByte" /> for more information. /// </summary> public void WriteByte(long index, byte value) { try { // Find the block affected. long blockOffset; DataBlock block = GetDataBlock(index, out blockOffset); // If the byte is already in a memory block, modify it. MemoryDataBlock memoryBlock = block as MemoryDataBlock; if (memoryBlock != null) { memoryBlock.Data[index - blockOffset] = value; return; } FileDataBlock fileBlock = (FileDataBlock)block; // If the byte changing is the first byte in the block and the previous block is a memory block, extend that. 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 the byte changing is the last byte in the block and the next block is a memory block, extend that. 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; } } // Split the block into a prefix and a suffix and place a memory block in-between. 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); } }
// Token: 0x06000369 RID: 873 RVA: 0x000122D4 File Offset: 0x000104D4 public void WriteByte(long index, byte value) { try { long num; DataBlock dataBlock = this.GetDataBlock(index, out num); MemoryDataBlock memoryDataBlock = dataBlock as MemoryDataBlock; if (memoryDataBlock != null) { memoryDataBlock.Data[(int)(checked ((IntPtr)(unchecked (index - num))))] = value; } else { FileDataBlock fileDataBlock = (FileDataBlock)dataBlock; if (num == index && dataBlock.PreviousBlock != null) { MemoryDataBlock memoryDataBlock2 = dataBlock.PreviousBlock as MemoryDataBlock; if (memoryDataBlock2 != null) { memoryDataBlock2.AddByteToEnd(value); fileDataBlock.RemoveBytesFromStart(1L); if (fileDataBlock.Length == 0L) { this._dataMap.Remove(fileDataBlock); } return; } } if (num + fileDataBlock.Length - 1L == index && dataBlock.NextBlock != null) { MemoryDataBlock memoryDataBlock3 = dataBlock.NextBlock as MemoryDataBlock; if (memoryDataBlock3 != null) { memoryDataBlock3.AddByteToStart(value); fileDataBlock.RemoveBytesFromEnd(1L); if (fileDataBlock.Length == 0L) { this._dataMap.Remove(fileDataBlock); } return; } } FileDataBlock fileDataBlock2 = null; if (index > num) { fileDataBlock2 = new FileDataBlock(fileDataBlock.FileOffset, index - num); } FileDataBlock fileDataBlock3 = null; if (index < num + fileDataBlock.Length - 1L) { fileDataBlock3 = new FileDataBlock(fileDataBlock.FileOffset + index - num + 1L, fileDataBlock.Length - (index - num + 1L)); } dataBlock = this._dataMap.Replace(dataBlock, new MemoryDataBlock(value)); if (fileDataBlock2 != null) { this._dataMap.AddBefore(dataBlock, fileDataBlock2); } if (fileDataBlock3 != null) { this._dataMap.AddAfter(dataBlock, fileDataBlock3); } } } finally { this.OnChanged(EventArgs.Empty); } }