1 #include "zip/ZipDeflateStream.h"
2 #include <stdexcept>
3 #include <assert.h>
4 
5 using namespace Framework;
6 
CZipDeflateStream(CStream & baseStream)7 CZipDeflateStream::CZipDeflateStream(CStream& baseStream) :
8 m_baseStream(baseStream),
9 m_crc(0),
10 m_uncompressedLength(0),
11 m_compressedLength(0)
12 {
13     m_zStream.zalloc = Z_NULL;
14     m_zStream.zfree = Z_NULL;
15     m_zStream.opaque = Z_NULL;
16     if(deflateInit2(&m_zStream, Z_DEFAULT_COMPRESSION,
17         Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY) != Z_OK)
18     {
19 		throw std::runtime_error("Error initializing deflate stream.");
20     }
21 }
22 
~CZipDeflateStream()23 CZipDeflateStream::~CZipDeflateStream()
24 {
25     deflateEnd(&m_zStream);
26 }
27 
GetCrc() const28 uint32 CZipDeflateStream::GetCrc() const
29 {
30     return m_crc;
31 }
32 
GetCompressedLength() const33 uint64 CZipDeflateStream::GetCompressedLength() const
34 {
35     return m_compressedLength;
36 }
37 
GetUncompressedLength() const38 uint64 CZipDeflateStream::GetUncompressedLength() const
39 {
40     return m_uncompressedLength;
41 }
42 
Seek(int64,STREAM_SEEK_DIRECTION)43 void CZipDeflateStream::Seek(int64, STREAM_SEEK_DIRECTION)
44 {
45     throw std::runtime_error("Unsupported operation.");
46 }
47 
Tell()48 uint64 CZipDeflateStream::Tell()
49 {
50     return m_baseStream.Tell();
51 }
52 
Read(void *,uint64)53 uint64 CZipDeflateStream::Read(void*, uint64)
54 {
55     throw std::runtime_error("Unsupported operation.");
56 }
57 
Write(const void * buffer,uint64 size)58 uint64 CZipDeflateStream::Write(const void* buffer, uint64 size)
59 {
60     m_uncompressedLength += size;
61     m_crc = crc32(m_crc, reinterpret_cast<const Bytef*>(buffer), static_cast<uInt>(size));
62 
63     m_zStream.avail_in = static_cast<uInt>(size);
64     m_zStream.next_in = const_cast<Bytef*>(reinterpret_cast<const Bytef*>(buffer));
65 
66     do
67     {
68         Bytef outBuffer[BUFFERSIZE];
69         m_zStream.avail_out = BUFFERSIZE;
70         m_zStream.next_out = outBuffer;
71 
72         int ret = deflate(&m_zStream, Z_NO_FLUSH);
73         assert(ret != Z_STREAM_ERROR);
74 
75         uint64 have = BUFFERSIZE - m_zStream.avail_out;
76         m_compressedLength += have;
77         m_baseStream.Write(outBuffer, have);
78     }
79     while(m_zStream.avail_out == 0);
80     assert(m_zStream.avail_in == 0);
81 
82     return size;
83 }
84 
IsEOF()85 bool CZipDeflateStream::IsEOF()
86 {
87     return m_baseStream.IsEOF();
88 }
89 
Flush()90 void CZipDeflateStream::Flush()
91 {
92     do
93     {
94         Bytef outBuffer[BUFFERSIZE];
95         m_zStream.avail_out = BUFFERSIZE;
96         m_zStream.next_out = outBuffer;
97 
98         int ret = deflate(&m_zStream, Z_FINISH);
99         assert(ret != Z_STREAM_ERROR);
100 
101         uint64 have = BUFFERSIZE - m_zStream.avail_out;
102         m_compressedLength += have;
103         m_baseStream.Write(outBuffer, have);
104     }
105     while(m_zStream.avail_out == 0);
106     assert(m_zStream.avail_in == 0);     /* all input will be used */
107 }
108