]> git.saurik.com Git - wxWidgets.git/blob - src/common/zstream.cpp
* wxDataStreams use wxUint now.
[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
12 #ifdef __GNUG__
13 #pragma implementation "zstream.h"
14 #endif
15
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #ifndef WX_PRECOMP
24 #include "wx/defs.h"
25 #endif
26
27 #if wxUSE_ZLIB && wxUSE_STREAMS
28
29 #include "wx/zstream.h"
30 #include "wx/utils.h"
31 #include "wx/intl.h"
32 #include "wx/log.h"
33 #include "zlib.h"
34
35 #define ZSTREAM_BUFFER_SIZE 1024
36
37 //////////////////////
38 // wxZlibInputStream
39 //////////////////////
40
41 wxZlibInputStream::wxZlibInputStream(wxInputStream& stream)
42 : wxFilterInputStream(stream)
43 {
44 int err;
45
46 // I need a private stream buffer.
47 m_i_streambuf = new wxStreamBuffer(*this, wxStreamBuffer::read);
48 m_i_destroybuf = TRUE;
49 m_inflate = new z_stream_s;
50
51 m_inflate->zalloc = (alloc_func)0;
52 m_inflate->zfree = (free_func)0;
53 m_inflate->opaque = (voidpf)0;
54
55 err = inflateInit(m_inflate);
56 if (err != Z_OK) {
57 inflateEnd(m_inflate);
58 delete m_inflate;
59 return;
60 }
61
62 m_z_buffer = new unsigned char[ZSTREAM_BUFFER_SIZE];
63 m_z_size = ZSTREAM_BUFFER_SIZE;
64
65 m_inflate->avail_in = 0;
66 m_inflate->next_in = NULL;
67 }
68
69 wxZlibInputStream::~wxZlibInputStream()
70 {
71 inflateEnd(m_inflate);
72 delete m_inflate;
73 }
74
75 size_t wxZlibInputStream::OnSysRead(void *buffer, size_t size)
76 {
77 int err;
78
79 m_inflate->next_out = (unsigned char *)buffer;
80 m_inflate->avail_out = size;
81
82 while (m_inflate->avail_out > 0) {
83 if (m_inflate->avail_in == 0) {
84
85 m_parent_i_stream->Read(m_z_buffer, m_z_size);
86 m_inflate->next_in = m_z_buffer;
87 m_inflate->avail_in = m_parent_i_stream->LastRead();
88
89 if (m_parent_i_stream->LastError() != wxStream_NOERROR)
90 return (size - m_inflate->avail_in);
91 }
92 err = inflate(m_inflate, Z_FINISH);
93 if (err == Z_STREAM_END)
94 return (size - m_inflate->avail_in);
95 }
96
97 return size-m_inflate->avail_in;
98 }
99
100 //////////////////////
101 // wxZlibOutputStream
102 //////////////////////
103
104 wxZlibOutputStream::wxZlibOutputStream(wxOutputStream& stream)
105 : wxFilterOutputStream(stream)
106 {
107 int err;
108
109 m_o_streambuf = new wxStreamBuffer(*this, wxStreamBuffer::write);
110 m_o_destroybuf = TRUE;
111 m_deflate = new z_stream_s;
112
113 m_deflate->zalloc = (alloc_func)0;
114 m_deflate->zfree = (free_func)0;
115 m_deflate->opaque = (voidpf)0;
116
117 err = deflateInit(m_deflate, Z_DEFAULT_COMPRESSION);
118 if (err != Z_OK) {
119 deflateEnd(m_deflate);
120 return;
121 }
122
123 m_z_buffer = new unsigned char[ZSTREAM_BUFFER_SIZE];
124 m_z_size = ZSTREAM_BUFFER_SIZE;
125
126 m_deflate->avail_in = 0;
127 m_deflate->next_out = m_z_buffer;
128 m_deflate->avail_out = m_z_size;
129 }
130
131 wxZlibOutputStream::~wxZlibOutputStream()
132 {
133 int err;
134
135 Sync();
136
137 err = deflate(m_deflate, Z_FINISH);
138 if (err != Z_STREAM_END)
139 {
140 wxLogDebug( _T("wxZlibOutputStream: an error occured while closing the stream.\n") );
141 return;
142 }
143
144 deflateEnd(m_deflate);
145
146 delete[] m_z_buffer;
147 }
148
149 void wxZlibOutputStream::Sync()
150 {
151 int err;
152
153 m_parent_o_stream->Write(m_z_buffer, m_z_size-m_deflate->avail_out);
154 m_deflate->next_out = m_z_buffer;
155 m_deflate->avail_out = m_z_size;
156
157 err = deflate(m_deflate, Z_FULL_FLUSH);
158 if (err != Z_OK) {
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::OnSysWrite(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->LastError() != wxStream_NOERROR)
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 #endif
193 // wxUSE_ZLIB && wxUSE_STREAMS
194