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));
            }