public override void Write(byte[] buffer, int offset, int count) { _checksum.Add(buffer, offset, count); while (count > 0) { PrepareWrite(); int amt = Math.Min(count, FileBlockDataSize - _current.Length); Array.Copy(buffer, offset, _current.BlockData, _current.Length + _current.DataOffset, amt); _current.Length += amt; offset += amt; count -= amt; } }
private uint CalcCrc32() { Crc32 crc = new Crc32(); crc.Add(_blockData, 4, BlockSize - 8); return(unchecked ((uint)crc.Value)); }
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); }
public BlockStreamReader(FragmentedFile file, long ordinal, BlockFlags typeExpected, bool validated) { _file = file; _blockPos = 0; _validated = validated; _block = new FileBlock(file._blockSize, file._useAlignedIo); _file.ReadBlock(ordinal, _block, file._blockSize, typeExpected, _validated); if (_validated) { _expectedSum = _block.CheckSum; _checksum = new Crc32(); _checksum.Add(_block.BlockData, _block.DataOffset, _block.Length); if (_block.NextBlockId == 0 && _checksum != _expectedSum) { throw new InvalidDataException(); } } }
private bool PrepareRead() { int remains = _block.Length - _blockPos; if (remains <= 0 && _block.NextBlockId != 0) { _file.ReadBlock(_block.NextBlockId, _block, _file._blockSize, _validated ? BlockFlags.InternalBlock : 0, _validated); remains = _block.Length; _blockPos = 0; if (_validated) { _checksum.Add(_block.BlockData, _block.DataOffset, _block.Length); if (_block.NextBlockId == 0 && _checksum != _expectedSum) { throw new InvalidDataException(); } } } return(remains > 0); }
public Stream Read(ref BlockRef block, bool headerOnly, FGet fget) { bool retry; byte[] bytes; int readBytes, headerSize, length; do { retry = false; long position = _sectionPosition + (BlockSize * block.Offset); bytes = new byte[headerOnly ? BlockHeaderSize : block.ActualBlocks * BlockSize]; readBytes = fget(position, bytes, 0, bytes.Length); if (readBytes < BlockHeaderSize) { throw new InvalidDataException(); } headerSize = bytes[OffsetOfHeaderSize]; length = (int)GetUInt32(bytes, OffsetOfLength) & 0x00FFFFFF; block.ActualBlocks = (int)GetUInt32(bytes, OffsetOfBlockCount); uint blockId = GetUInt32(bytes, OffsetOfBlockId); if (headerSize < BlockHeaderSize || blockId != block.Identity || ((block.Count < 16 && block.ActualBlocks != block.Count) || (block.Count == 16 && block.ActualBlocks < 16))) { throw new InvalidDataException(); } if (block.ActualBlocks != Math.Max(1, (length + headerSize + BlockSize - 1) / BlockSize)) { throw new InvalidDataException(); } if (headerOnly) { return(null); } if (readBytes < length + headerSize) { retry = bytes.Length != block.ActualBlocks * BlockSize; } } while (retry); if (readBytes < length + headerSize) { throw new InvalidDataException(); } Crc32 crc = new Crc32(); crc.Add(bytes, headerSize, length); if ((uint)crc.Value != GetUInt32(bytes, OffsetOfCrc32)) { throw new InvalidDataException(); } return(new MemoryStream(bytes, headerSize, length, false, false)); }