Esempio n. 1
0
        protected override int ReadGrain(byte[] buffer, int bufferOffset, long grainStart, int grainOffset, int numToRead)
        {
            if ((_hostedHeader.Flags & HostedSparseExtentFlags.CompressedGrains) != 0)
            {
                _fileStream.Position = grainStart;

                byte[] readBuffer         = Utilities.ReadFully(_fileStream, CompressedGrainHeader.Size);
                CompressedGrainHeader hdr = new CompressedGrainHeader();
                hdr.Read(readBuffer, 0);

                readBuffer = Utilities.ReadFully(_fileStream, hdr.DataSize);

                // This is really a zlib stream, so has header and footer.  We ignore this right now, but we sanity
                // check against expected header values...
                ushort header = Utilities.ToUInt16BigEndian(readBuffer, 0);

                if ((header % 31) != 0)
                {
                    throw new IOException("Invalid ZLib header found");
                }

                if ((header & 0x0F00) != (8 << 8))
                {
                    throw new NotSupportedException("ZLib compression not using DEFLATE algorithm");
                }

                if ((header & 0x0020) != 0)
                {
                    throw new NotSupportedException("ZLib compression using preset dictionary");
                }

                Stream        readStream    = new MemoryStream(readBuffer, 2, hdr.DataSize - 2, false);
                DeflateStream deflateStream = new DeflateStream(readStream, CompressionMode.Decompress);

                // Need to skip some bytes, but DefaultStream doesn't support seeking...
                Utilities.ReadFully(deflateStream, grainOffset);

                return(deflateStream.Read(buffer, bufferOffset, numToRead));
            }
            else
            {
                return(base.ReadGrain(buffer, bufferOffset, grainStart, grainOffset, numToRead));
            }
        }