]> git.saurik.com Git - wxWidgets.git/blob - src/common/zstream.cpp
* wxMemoryStreams updates
[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 #if wxUSE_ZLIB && wxUSE_STREAMS
24
25 #include "wx/zstream.h"
26 #include "wx/utils.h"
27 #include "wx/intl.h"
28 #include "wx/log.h"
29
30 // When using configure, the path must be "zlib.h" I don't know
31 // what other ports (wxMac, wxMotif without configure) need here.
32
33 #ifdef __WXMSW__
34 #include "..\zlib\zlib.h"
35 #else
36 #include "zlib.h"
37 #endif
38
39 #define ZSTREAM_BUFFER_SIZE 1024
40
41 //////////////////////
42 // wxZlibInputStream
43 //////////////////////
44
45 wxZlibInputStream::wxZlibInputStream(wxInputStream& stream)
46 : wxFilterInputStream(stream)
47 {
48 int err;
49
50 // I need a private stream buffer.
51 m_inflate = new z_stream_s;
52
53 m_inflate->zalloc = (alloc_func)0;
54 m_inflate->zfree = (free_func)0;
55 m_inflate->opaque = (voidpf)0;
56
57 err = inflateInit(m_inflate);
58 if (err != Z_OK) {
59 inflateEnd(m_inflate);
60 delete m_inflate;
61 return;
62 }
63
64 m_z_buffer = new unsigned char[ZSTREAM_BUFFER_SIZE];
65 m_z_size = ZSTREAM_BUFFER_SIZE;
66
67 m_inflate->avail_in = 0;
68 m_inflate->next_in = NULL;
69 }
70
71 wxZlibInputStream::~wxZlibInputStream()
72 {
73 inflateEnd(m_inflate);
74 delete m_inflate;
75 }
76
77 size_t wxZlibInputStream::OnSysRead(void *buffer, size_t size)
78 {
79 int err;
80
81 m_inflate->next_out = (unsigned char *)buffer;
82 m_inflate->avail_out = size;
83
84 while (m_inflate->avail_out > 0) {
85 if (m_inflate->avail_in == 0) {
86
87 m_parent_i_stream->Read(m_z_buffer, m_z_size);
88 m_inflate->next_in = m_z_buffer;
89 m_inflate->avail_in = m_parent_i_stream->LastRead();
90
91 if (m_parent_i_stream->LastError() != wxStream_NOERROR)
92 return (size - m_inflate->avail_in);
93 }
94 err = inflate(m_inflate, Z_FINISH);
95 if (err == Z_STREAM_END)
96 return (size - m_inflate->avail_in);
97 }
98
99 return size-m_inflate->avail_in;
100 }
101
102 //////////////////////
103 // wxZlibOutputStream
104 //////////////////////
105
106 wxZlibOutputStream::wxZlibOutputStream(wxOutputStream& stream)
107 : wxFilterOutputStream(stream)
108 {
109 int err;
110
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