* New wxStreams (to be documented), new classes: wxBufferedStreams,
[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_inflate = new z_stream_s;
48
49 m_inflate->zalloc = (alloc_func)0;
50 m_inflate->zfree = (free_func)0;
51 m_inflate->opaque = (voidpf)0;
52
53 err = inflateInit(m_inflate);
54 if (err != Z_OK) {
55 inflateEnd(m_inflate);
56 delete m_inflate;
57 return;
58 }
59
60 m_z_buffer = new unsigned char[ZSTREAM_BUFFER_SIZE];
61 m_z_size = ZSTREAM_BUFFER_SIZE;
62
63 m_inflate->avail_in = 0;
64 m_inflate->next_in = NULL;
65 }
66
67 wxZlibInputStream::~wxZlibInputStream()
68 {
69 inflateEnd(m_inflate);
70 delete m_inflate;
71 }
72
73 size_t wxZlibInputStream::OnSysRead(void *buffer, size_t size)
74 {
75 int err;
76
77 m_inflate->next_out = (unsigned char *)buffer;
78 m_inflate->avail_out = size;
79
80 while (m_inflate->avail_out > 0) {
81 if (m_inflate->avail_in == 0) {
82
83 m_parent_i_stream->Read(m_z_buffer, m_z_size);
84 m_inflate->next_in = m_z_buffer;
85 m_inflate->avail_in = m_parent_i_stream->LastRead();
86
87 if (m_parent_i_stream->LastError() != wxStream_NOERROR)
88 return (size - m_inflate->avail_in);
89 }
90 err = inflate(m_inflate, Z_FINISH);
91 if (err == Z_STREAM_END)
92 return (size - m_inflate->avail_in);
93 }
94
95 return size-m_inflate->avail_in;
96 }
97
98 //////////////////////
99 // wxZlibOutputStream
100 //////////////////////
101
102 wxZlibOutputStream::wxZlibOutputStream(wxOutputStream& stream)
103 : wxFilterOutputStream(stream)
104 {
105 int err;
106
107 m_deflate = new z_stream_s;
108
109 m_deflate->zalloc = (alloc_func)0;
110 m_deflate->zfree = (free_func)0;
111 m_deflate->opaque = (voidpf)0;
112
113 err = deflateInit(m_deflate, Z_DEFAULT_COMPRESSION);
114 if (err != Z_OK) {
115 deflateEnd(m_deflate);
116 return;
117 }
118
119 m_z_buffer = new unsigned char[ZSTREAM_BUFFER_SIZE];
120 m_z_size = ZSTREAM_BUFFER_SIZE;
121
122 m_deflate->avail_in = 0;
123 m_deflate->next_out = m_z_buffer;
124 m_deflate->avail_out = m_z_size;
125 }
126
127 wxZlibOutputStream::~wxZlibOutputStream()
128 {
129 int err;
130
131 Sync();
132
133 err = deflate(m_deflate, Z_FINISH);
134 if (err != Z_STREAM_END)
135 {
136 wxLogDebug( _T("wxZlibOutputStream: an error occured while closing the stream.\n") );
137 return;
138 }
139
140 deflateEnd(m_deflate);
141
142 delete[] m_z_buffer;
143 }
144
145 void wxZlibOutputStream::Sync()
146 {
147 int err;
148
149 m_parent_o_stream->Write(m_z_buffer, m_z_size-m_deflate->avail_out);
150 m_deflate->next_out = m_z_buffer;
151 m_deflate->avail_out = m_z_size;
152
153 err = deflate(m_deflate, Z_FULL_FLUSH);
154 if (err != Z_OK) {
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::OnSysWrite(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->LastError() != wxStream_NOERROR)
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 #endif
189 // wxUSE_ZLIB && wxUSE_STREAMS
190