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