]> git.saurik.com Git - wxWidgets.git/blob - src/common/zstream.cpp
* Bug fix in wxFilter*Stream
[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 <wx/intl.h>
21 #include "../zlib/zlib.h" // don't change this, Robert
22
23 #ifdef __BORLANDC__
24 #pragma hdrstop
25 #endif
26
27 #define ZSTREAM_BUFFER_SIZE 1024
28
29 //////////////////////
30 // wxZlibInputStream
31 //////////////////////
32
33 wxZlibInputStream::wxZlibInputStream(wxInputStream& stream)
34 : wxFilterInputStream(stream)
35 {
36 int err;
37
38 // I need a private stream buffer.
39 m_i_streambuf = new wxStreamBuffer(*this);
40 m_i_destroybuf = TRUE;
41
42 m_inflate.zalloc = (alloc_func)0;
43 m_inflate.zfree = (free_func)0;
44 m_inflate.opaque = (voidpf)0;
45
46 err = inflateInit(&m_inflate);
47 if (err != Z_OK) {
48 inflateEnd(&m_inflate);
49 return;
50 }
51
52 m_z_buffer = new unsigned char[ZSTREAM_BUFFER_SIZE];
53 m_z_size = ZSTREAM_BUFFER_SIZE;
54
55 m_inflate.avail_in = 0;
56 m_inflate.next_in = NULL;
57 }
58
59 wxZlibInputStream::~wxZlibInputStream()
60 {
61 inflateEnd(&m_inflate);
62 }
63
64 size_t wxZlibInputStream::DoRead(void *buffer, size_t size)
65 {
66 int err;
67
68 m_inflate.next_out = (unsigned char *)buffer;
69 m_inflate.avail_out = size;
70
71 while (m_inflate.avail_out > 0) {
72 if (m_inflate.avail_in == 0) {
73
74 m_parent_i_stream->Read(m_z_buffer, m_z_size);
75 m_inflate.next_in = m_z_buffer;
76 m_inflate.avail_in = m_parent_i_stream->LastRead();
77
78 if (m_parent_i_stream->Eof())
79 return (size - m_inflate.avail_in);
80 }
81 err = inflate(&m_inflate, Z_FINISH);
82 if (err == Z_STREAM_END)
83 return (size - m_inflate.avail_in);
84 }
85
86 return size-m_inflate.avail_in;
87 }
88
89 bool wxZlibInputStream::Eof() const
90 {
91 if (!m_eof)
92 return m_parent_i_stream->Eof();
93 return m_eof;
94 }
95
96 //////////////////////
97 // wxZlibOutputStream
98 //////////////////////
99
100 wxZlibOutputStream::wxZlibOutputStream(wxOutputStream& stream)
101 : wxFilterOutputStream(stream)
102 {
103 int err;
104
105 m_o_streambuf = new wxStreamBuffer(*this);
106 m_o_destroybuf = TRUE;
107
108 m_deflate.zalloc = (alloc_func)0;
109 m_deflate.zfree = (free_func)0;
110 m_deflate.opaque = (voidpf)0;
111
112 err = deflateInit(&m_deflate, Z_DEFAULT_COMPRESSION);
113 if (err != Z_OK) {
114 deflateEnd(&m_deflate);
115 return;
116 }
117
118 m_z_buffer = new unsigned char[ZSTREAM_BUFFER_SIZE];
119 m_z_size = ZSTREAM_BUFFER_SIZE;
120
121 m_deflate.avail_in = 0;
122 m_deflate.next_out = m_z_buffer;
123 m_deflate.avail_out = m_z_size;
124 }
125
126 wxZlibOutputStream::~wxZlibOutputStream()
127 {
128 int err;
129
130 Sync();
131
132 err = deflate(&m_deflate, Z_FINISH);
133 if (err != Z_STREAM_END) {
134 wxDebugMsg(_("wxZlibOutputStream: an error occured while we was closing "
135 "the stream.\n"));
136 return;
137 }
138
139 deflateEnd(&m_deflate);
140
141 delete[] m_z_buffer;
142 }
143
144 void wxZlibOutputStream::Sync()
145 {
146 int err;
147
148 m_parent_o_stream->Write(m_z_buffer, m_z_size-m_deflate.avail_out);
149 m_deflate.next_out = m_z_buffer;
150 m_deflate.avail_out = m_z_size;
151
152 err = deflate(&m_deflate, Z_FULL_FLUSH);
153 if (err != Z_OK) {
154 m_bad = TRUE;
155 return;
156 }
157
158 m_parent_o_stream->Write(m_z_buffer, m_z_size-m_deflate.avail_out);
159 m_deflate.next_out = m_z_buffer;
160 m_deflate.avail_out = m_z_size;
161 }
162
163 size_t wxZlibOutputStream::DoWrite(const void *buffer, size_t size)
164 {
165 int err;
166
167 m_deflate.next_in = (unsigned char *)buffer;
168 m_deflate.avail_in = size;
169
170 while (m_deflate.avail_in > 0) {
171
172 if (m_deflate.avail_out == 0) {
173 m_parent_o_stream->Write(m_z_buffer, m_z_size);
174 if (m_parent_o_stream->Bad())
175 return (size - m_deflate.avail_in);
176
177 m_deflate.next_out = m_z_buffer;
178 m_deflate.avail_out = m_z_size;
179 }
180
181 err = deflate(&m_deflate, Z_NO_FLUSH);
182 if (err != Z_OK)
183 return (size - m_deflate.avail_in);
184 }
185 return size;
186 }
187
188 bool wxZlibOutputStream::Bad() const
189 {
190 if (!m_bad)
191 return m_parent_o_stream->Bad();
192 return m_bad;
193 }