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