1 #include "zip/ZipInflateStream.h"
2 #include <stdexcept>
3 #include <algorithm>
4 #include <string.h>
5 #include <assert.h>
6 
7 using namespace Framework;
8 
CZipInflateStream(CStream & baseStream,unsigned int compressedLength)9 CZipInflateStream::CZipInflateStream(CStream& baseStream, unsigned int compressedLength) :
10 m_baseStream(baseStream),
11 m_compressedLength(compressedLength)
12 {
13     m_zStream.zalloc = Z_NULL;
14     m_zStream.zfree = Z_NULL;
15     m_zStream.opaque = Z_NULL;
16     m_zStream.avail_in = 0;
17     m_zStream.next_in = Z_NULL;
18     if(inflateInit2(&m_zStream, -MAX_WBITS) != Z_OK)
19     {
20 		throw std::runtime_error("zlib stream initialization error.");
21     }
22 }
23 
~CZipInflateStream()24 CZipInflateStream::~CZipInflateStream()
25 {
26     inflateEnd(&m_zStream);
27 }
28 
Seek(int64,STREAM_SEEK_DIRECTION)29 void CZipInflateStream::Seek(int64, STREAM_SEEK_DIRECTION)
30 {
31 	throw std::runtime_error("Unsupported operation.");
32 }
33 
Tell()34 uint64 CZipInflateStream::Tell()
35 {
36     throw std::runtime_error("Unsupported operation.");
37 }
38 
Read(void * buffer,uint64 length)39 uint64 CZipInflateStream::Read(void* buffer, uint64 length)
40 {
41     Bytef outBuffer[BUFFERSIZE];
42     uint8* destBuffer = reinterpret_cast<uint8*>(buffer);
43     uint64 sizeCounter = length;
44     do
45     {
46         if(m_zStream.avail_in == 0)
47         {
48             if(m_compressedLength == 0)
49             {
50                 //EOF
51                 break;
52             }
53             FeedBuffer();
54         }
55 
56 		int bufferSize = std::min<int>(BUFFERSIZE, static_cast<int>(sizeCounter));
57         m_zStream.avail_out = bufferSize;
58         m_zStream.next_out = outBuffer;
59 
60         int ret = inflate(&m_zStream, Z_NO_FLUSH);
61         switch (ret) {
62         case Z_NEED_DICT:
63         case Z_DATA_ERROR:
64         case Z_MEM_ERROR:
65 			throw std::runtime_error("Error occured while inflating.");
66             break;
67         }
68 
69         int have = bufferSize - m_zStream.avail_out;
70         memcpy(destBuffer, outBuffer, have);
71         destBuffer += have;
72         sizeCounter -= have;
73         if(ret == Z_STREAM_END)
74         {
75             assert(IsEOF());
76             break;
77         }
78     }
79     while (sizeCounter != 0);
80     return length - sizeCounter;
81 }
82 
Write(const void * buffer,uint64 size)83 uint64 CZipInflateStream::Write(const void* buffer, uint64 size)
84 {
85     throw std::runtime_error("Unsupported operation.");
86 }
87 
IsEOF()88 bool CZipInflateStream::IsEOF()
89 {
90     return (m_compressedLength == 0) && (m_zStream.avail_in == 0);
91 }
92 
FeedBuffer()93 void CZipInflateStream::FeedBuffer()
94 {
95     assert(m_zStream.avail_in == 0);
96 	unsigned int toRead = std::min<unsigned int>(BUFFERSIZE, m_compressedLength);
97     m_zStream.avail_in = static_cast<uInt>(m_baseStream.Read(m_inputBuffer, toRead));
98     m_zStream.next_in = m_inputBuffer;
99     m_compressedLength -= m_zStream.avail_in;
100 }
101