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