public void Commit(FPut put, bool phase2) { if (!_isDirty) { return; } if (phase2 && ReadUInt32(0) != CalcCrc32()) { throw new InvalidDataException(); } else { MakeValid(); } long phaseShift = phase2 ? (SectionSize - BlockSize) : 0; put(_sectionPosition + phaseShift, _blockData, 0, BlockSize); if (phase2) { _isDirty = false; } }
public void SetHandle(FPut fcommit, int index, uint blockId) { if (index <= 0 || index >= BlocksPerSection - 1) { throw new InvalidDataException(); } WriteUInt32(index, blockId); _isDirty = true; if (fcommit != null) { Commit(fcommit, false); Commit(fcommit, true); } }
/// <summary> /// Creates or opens a TransactedCompoundFile using the filename specified. /// </summary> public TransactedCompoundFile(Options options) { _options = options.Clone(); _sync = new object(); BlockSize = _options.BlockSize; BlocksPerSection = BlockSize >> 2; SectionSize = BlockSize * BlocksPerSection; _freeHandles = new OrdinalList(); _freeBlocks = new OrdinalList(); _reservedBlocks = new OrdinalList(); _stream = new FileStream( _options.FilePath, _options.CreateNew ? FileMode.Create : FileMode.Open, _options.ReadOnly ? FileAccess.Read : FileAccess.ReadWrite, _options.ReadOnly ? FileShare.ReadWrite : FileShare.Read, 8, _options.FileOptions ); _fcommit = _fput = fput; _fget = ReadBytes; try { LoadSections(_stream); if (_sections.Length == 0) { AddSection(); } } catch { _stream.Dispose(); throw; } if (!_options.CommitOnWrite) { _fcommit = null; } _readers = new StreamCache( new FileStreamFactory(_options.FilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, 8, FileOptions.None), 4); }
public void Write(BlockRef block, FPut fput, byte[] bytes, int offset, int length) { byte[] blockdata = new byte[BlockSize * block.ActualBlocks]; PutUInt32(blockdata, OffsetOfLength, (uint)length); blockdata[OffsetOfHeaderSize] = BlockHeaderSize; Crc32 crc = new Crc32(); crc.Add(bytes, offset, length); PutUInt32(blockdata, OffsetOfCrc32, (uint)crc.Value); PutUInt32(blockdata, OffsetOfBlockCount, (uint)block.ActualBlocks); PutUInt32(blockdata, OffsetOfBlockId, block.Identity); Buffer.BlockCopy(bytes, offset, blockdata, BlockHeaderSize, length); long position = _sectionPosition + (BlockSize * block.Offset); fput(position, blockdata, 0, blockdata.Length); }