public StreamReadDecompress(Stream p_StreamDataForReading)
 {
     _StreamDataForReading   = p_StreamDataForReading;
     _StreamCompressedData   = new MemoryStream();
     _BufferCompressedData   = new byte[0];
     _BufferDecompressedData = new byte[0];
     _StreamReadModules      = new StreamReadModules();
 }
        public StreamReadPredecompressedChunks(Stream p_StreamDataForReading, int p_PreparedChunks = 1)
        {
            _StreamDataForReading = p_StreamDataForReading;
            _StreamReadModules    = new StreamReadModules();

            _Chunks = new List <ChunkDecompress>(p_PreparedChunks);
            for (var i = 0; i < p_PreparedChunks; i++)
            {
                var chunk = new ChunkDecompress(new byte[0], new byte[0], new MemoryStream());
                chunk.ReadDataAndStartDecompressingInTask(_StreamDataForReading, _StreamReadModules, 80 * 1024);
                _Chunks.Add(chunk);
            }
        }
        public void ReadDataAndStartDecompressingInTask(Stream p_StreamDataForReading, StreamReadModules p_StreamReadModules, int p_Count)
        {
            _ManualResetEvent.Set();
            //Read new compressed chunk
            //Read first 4 bytes - may be known headerIdentification - it means that stream is compressed
            byte[] intBytes             = new byte[4];
            var    headerIdentification = p_StreamDataForReading.Read(intBytes, 0, intBytes.Length);

            if (headerIdentification == 0)
            {
                _BufferDecompressedDataLength = 0;
                return;
            }
            var module = p_StreamReadModules.FindByHeaderIdentification(intBytes);

            if (module == null)
            {
                //not compressed by known headerIdentification - only copy to output
                if (_BufferDecompressedData.Length < p_Count)
                {
                    Array.Resize(ref _BufferDecompressedData, p_Count);
                }
                Array.Copy(intBytes, _BufferDecompressedData, intBytes.Length);

                int readedOriginal = p_StreamDataForReading.ReadMaybeMoreTimes(_BufferDecompressedData, intBytes.Length, p_Count);
                _BufferDecompressedDataLength   = readedOriginal;
                _BufferDecompressedDataPosition = 0;
                return;
            }

            // Chunk header - Uncompressed and Compressed size
            var readedUncompressedChunkSize = p_StreamDataForReading.Read(intBytes, 0, intBytes.Length);

            if (readedUncompressedChunkSize == 0)
            {
                _BufferDecompressedDataLength = 0;
                return;
            }
            var uncompressedChunkSize = BitConverter.ToInt32(intBytes, 0);

            var readedCompressedChunkSize = p_StreamDataForReading.Read(intBytes, 0, intBytes.Length);

            if (readedCompressedChunkSize == 0)
            {
                _BufferDecompressedDataLength = 0;
                return;
            }
            var compressedChunkSize = BitConverter.ToInt32(intBytes, 0);

            //Read Chunk data to _BufferCompressedData
            if (_BufferCompressedData.Length < compressedChunkSize)
            {
                Array.Resize(ref _BufferCompressedData, compressedChunkSize);
            }

            int readed = p_StreamDataForReading.ReadMaybeMoreTimes(_BufferCompressedData, 0, compressedChunkSize);

            if (readed == 0)
            {
                _BufferDecompressedDataLength = 0;
                return;
            }

            _ManualResetEvent.Reset();
            Task.Factory.StartNew(() => DecompressData(readed, module, uncompressedChunkSize));
        }