]> git.saurik.com Git - wxWidgets.git/blob - src/common/zstream.cpp
de38cad39c295f4b418c447d19a0a17fc0a63dd2
[wxWidgets.git] / src / common / zstream.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: zstream.cpp
3 // Purpose: Compressed stream classes
4 // Author: Guilhem Lavaux
5 // Modified by:
6 // Created: 11/07/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Guilhem Lavaux
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11 #ifdef __GNUG__
12 #pragma implementation "zstream.h"
13 #endif
14
15 // For compilers that support precompilation, includes "wx.h".
16 #include "wx/wxprec.h"
17 #include <wx/stream.h>
18 #include <wx/zstream.h>
19 #include <wx/utils.h>
20 #include "zlib.h"
21
22 #ifdef __BORLANDC__
23 #pragma hdrstop
24 #endif
25
26 #if !USE_SHARED_LIBRARY
27 IMPLEMENT_CLASS(wxZlibInputStream, wxFilterInputStream)
28 IMPLEMENT_CLASS(wxZlibOutputStream, wxFilterOutputStream)
29 #endif
30
31 //////////////////////
32 // wxZlibInputStream
33 //////////////////////
34
35 wxZlibInputStream::wxZlibInputStream(wxInputStream& stream)
36 : wxFilterInputStream(stream)
37 {
38 int err;
39
40 m_inflate.zalloc = (alloc_func)0;
41 m_inflate.zfree = (free_func)0;
42 m_inflate.opaque = (voidpf)0;
43
44 err = inflateInit(&m_inflate);
45 if (err != Z_OK) {
46 inflateEnd(&m_inflate);
47 return;
48 }
49
50 m_inflate.avail_in = 0;
51 }
52
53 wxZlibInputStream::~wxZlibInputStream()
54 {
55 inflateEnd(&m_inflate);
56 }
57
58 wxInputStream& wxZlibInputStream::Read(void *buffer, size_t size)
59 {
60 int err;
61
62 m_inflate.next_out = (unsigned char *)buffer;
63 m_inflate.avail_out = size;
64 m_eof = FALSE;
65
66 while (m_inflate.avail_out > 0) {
67 if (m_inflate.avail_in == 0) {
68 wxFilterInputStream::Read(m_z_buffer, m_z_size);
69 m_inflate.next_in = m_z_buffer;
70 m_inflate.avail_in = wxFilterInputStream::LastRead();
71 if (wxFilterInputStream::Eof()) {
72 m_lastread = size - m_inflate.avail_out;
73 return *this;
74 }
75 }
76 err = inflate(&m_inflate, Z_FINISH);
77 if (err == Z_STREAM_END) {
78 m_lastread = size - m_inflate.avail_out;
79 m_eof = TRUE;
80 return *this;
81 }
82 }
83
84 m_lastread = size;
85 return *this;
86 }
87
88 off_t wxZlibInputStream::SeekI(off_t WXUNUSED(pos), wxSeekMode WXUNUSED(mode))
89 {
90 return 0;
91 }
92
93 off_t wxZlibInputStream::TellI() const
94 {
95 return 0;
96 }
97
98 bool wxZlibInputStream::Eof() const
99 {
100 if (!m_eof)
101 return wxFilterInputStream::Eof();
102 return m_eof;
103 }
104
105 //////////////////////
106 // wxZlibOutputStream
107 //////////////////////
108
109 wxZlibOutputStream::wxZlibOutputStream(wxOutputStream& stream)
110 : wxFilterOutputStream(stream)
111 {
112 int err;
113
114 m_deflate.zalloc = (alloc_func)0;
115 m_deflate.zfree = (free_func)0;
116 m_deflate.opaque = (voidpf)0;
117
118 err = deflateInit(&m_deflate, Z_DEFAULT_COMPRESSION);
119 if (err != Z_OK) {
120 deflateEnd(&m_deflate);
121 return;
122 }
123 m_deflate.avail_in = 0;
124 m_deflate.next_out = m_z_buffer;
125 m_deflate.avail_out = m_z_size;
126 }
127
128 wxZlibOutputStream::~wxZlibOutputStream()
129 {
130 int err;
131
132 while (1) {
133 err = deflate(&m_deflate, Z_FINISH);
134 if (err == Z_STREAM_END)
135 break;
136 if (err < 0) {
137 wxDebugMsg("wxZlibOutputStream: error during final deflate");
138 break;
139 }
140 if (m_deflate.avail_out == 0) {
141 wxFilterOutputStream::Write(m_z_buffer, m_z_size);
142 if (wxFilterOutputStream::Bad()) {
143 wxDebugMsg("wxZlibOutputStream: error during final write");
144 break;
145 }
146 m_deflate.next_out = m_z_buffer;
147 m_deflate.avail_out = m_z_size;
148 }
149 }
150 wxFilterOutputStream::Write(m_z_buffer, m_z_size-m_deflate.avail_out);
151
152 deflateEnd(&m_deflate);
153 }
154
155 wxOutputStream& wxZlibOutputStream::Write(const void *buffer, size_t size)
156 {
157 int err;
158
159 m_deflate.next_in = (unsigned char *)buffer;
160 m_deflate.avail_in = size;
161
162 m_bad = FALSE;
163 while (m_deflate.avail_in > 0) {
164 if (m_deflate.avail_out == 0) {
165 wxFilterOutputStream::Write(m_z_buffer, m_z_size);
166 if (wxFilterOutputStream::Bad()) {
167 m_lastwrite = size - m_deflate.avail_in;
168 return *this;
169 }
170
171 m_deflate.next_out = m_z_buffer;
172 m_deflate.avail_out = m_z_size;
173 }
174 err = deflate(&m_deflate, Z_NO_FLUSH);
175 if (err < 0) {
176 m_bad = TRUE;
177 m_lastwrite = size - m_deflate.avail_in;
178 return *this;
179 }
180 }
181 m_lastwrite = size;
182 return *this;
183 }
184
185 off_t wxZlibOutputStream::SeekO(off_t WXUNUSED(pos), wxSeekMode WXUNUSED(mode))
186 {
187 return 0;
188 }
189
190 off_t wxZlibOutputStream::TellO() const
191 {
192 return 0;
193 }
194
195 bool wxZlibOutputStream::Bad() const
196 {
197 if (!m_bad)
198 return wxFilterOutputStream::Bad();
199 return m_bad;
200 }