Exemple #1
0
            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;
                }
            }
Exemple #2
0
            private uint CalcCrc32()
            {
                Crc32 crc = new Crc32();

                crc.Add(_blockData, 4, BlockSize - 8);
                return(unchecked ((uint)crc.Value));
            }
Exemple #3
0
            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);
            }
Exemple #4
0
            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();
                    }
                }
            }
Exemple #5
0
            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);
            }
Exemple #6
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));
            }