1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Compressed stream classes
4 // Author: Guilhem Lavaux
8 // Copyright: (c) Guilhem Lavaux
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "zstream.h"
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
23 #if wxUSE_ZLIB && wxUSE_STREAMS
25 #include "wx/zstream.h"
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 // If we are building with configure (defines __WX_SETUP_H__),
33 // we trust the zlib path is given as a -I option.
34 #if defined(__WXMSW__) && !defined(__WX_SETUP_H__)
35 #include "../zlib/zlib.h"
40 #define ZSTREAM_BUFFER_SIZE 1024
42 //////////////////////
44 //////////////////////
46 wxZlibInputStream::wxZlibInputStream(wxInputStream
& stream
)
47 : wxFilterInputStream(stream
)
51 // I need a private stream buffer.
52 m_inflate
= new z_stream_s
;
54 m_inflate
->zalloc
= (alloc_func
)0;
55 m_inflate
->zfree
= (free_func
)0;
56 m_inflate
->opaque
= (voidpf
)0;
58 err
= inflateInit(m_inflate
);
60 inflateEnd(m_inflate
);
65 m_z_buffer
= new unsigned char[ZSTREAM_BUFFER_SIZE
];
66 m_z_size
= ZSTREAM_BUFFER_SIZE
;
68 m_inflate
->avail_in
= 0;
69 m_inflate
->next_in
= NULL
;
72 wxZlibInputStream::~wxZlibInputStream()
74 inflateEnd(m_inflate
);
78 size_t wxZlibInputStream::OnSysRead(void *buffer
, size_t size
)
82 m_inflate
->next_out
= (unsigned char *)buffer
;
83 m_inflate
->avail_out
= size
;
85 while (m_inflate
->avail_out
> 0) {
86 if (m_inflate
->avail_in
== 0) {
88 m_parent_i_stream
->Read(m_z_buffer
, m_z_size
);
89 m_inflate
->next_in
= m_z_buffer
;
90 m_inflate
->avail_in
= m_parent_i_stream
->LastRead();
92 if (m_parent_i_stream
->LastError() != wxStream_NOERROR
&&
93 m_parent_i_stream
->LastError() != wxStream_EOF
)
95 m_lasterror
= m_parent_i_stream
->LastError();
96 return 0; // failed to read anything
99 err
= inflate(m_inflate
, Z_FINISH
);
100 if (err
== Z_STREAM_END
)
101 return (size
- m_inflate
->avail_out
);
104 return size
-m_inflate
->avail_out
;
107 //////////////////////
108 // wxZlibOutputStream
109 //////////////////////
111 wxZlibOutputStream::wxZlibOutputStream(wxOutputStream
& stream
, int level
)
112 : wxFilterOutputStream(stream
)
116 m_deflate
= new z_stream_s
;
118 m_deflate
->zalloc
= (alloc_func
)0;
119 m_deflate
->zfree
= (free_func
)0;
120 m_deflate
->opaque
= (voidpf
)0;
122 if (level
== -1) level
= Z_DEFAULT_COMPRESSION
;
123 wxASSERT_MSG(level
>= 0 && level
<= 9, wxT("wxZlibOutputStream compression level must be between 0 and 9!"));
125 err
= deflateInit(m_deflate
, level
);
127 deflateEnd(m_deflate
);
131 m_z_buffer
= new unsigned char[ZSTREAM_BUFFER_SIZE
];
132 m_z_size
= ZSTREAM_BUFFER_SIZE
;
134 m_deflate
->avail_in
= 0;
135 m_deflate
->next_out
= m_z_buffer
;
136 m_deflate
->avail_out
= m_z_size
;
139 wxZlibOutputStream::~wxZlibOutputStream()
145 err
= deflate(m_deflate
, Z_FINISH
);
146 if (err
!= Z_STREAM_END
)
148 wxLogDebug( wxT("wxZlibOutputStream: an error occured while closing the stream.\n") );
152 deflateEnd(m_deflate
);
157 void wxZlibOutputStream::Sync()
161 m_parent_o_stream
->Write(m_z_buffer
, m_z_size
-m_deflate
->avail_out
);
162 m_deflate
->next_out
= m_z_buffer
;
163 m_deflate
->avail_out
= m_z_size
;
165 err
= deflate(m_deflate
, Z_FULL_FLUSH
);
170 // Fixed by "Stefan Csomor" <csomor@advancedconcepts.ch>
171 while( m_deflate
->avail_out
== 0 )
173 m_parent_o_stream
->Write(m_z_buffer
, m_z_size
);
174 m_deflate
->next_out
= m_z_buffer
;
175 m_deflate
->avail_out
= m_z_size
;
176 err
= deflate(m_deflate
, Z_FULL_FLUSH
);
183 m_parent_o_stream
->Write(m_z_buffer
, m_z_size
-m_deflate
->avail_out
);
184 m_deflate
->next_out
= m_z_buffer
;
185 m_deflate
->avail_out
= m_z_size
;
188 size_t wxZlibOutputStream::OnSysWrite(const void *buffer
, size_t size
)
192 m_deflate
->next_in
= (unsigned char *)buffer
;
193 m_deflate
->avail_in
= size
;
195 while (m_deflate
->avail_in
> 0) {
197 if (m_deflate
->avail_out
== 0) {
198 m_parent_o_stream
->Write(m_z_buffer
, m_z_size
);
199 if (m_parent_o_stream
->LastError() != wxStream_NOERROR
)
200 return (size
- m_deflate
->avail_in
);
202 m_deflate
->next_out
= m_z_buffer
;
203 m_deflate
->avail_out
= m_z_size
;
206 err
= deflate(m_deflate
, Z_NO_FLUSH
);
208 return (size
- m_deflate
->avail_in
);
214 // wxUSE_ZLIB && wxUSE_STREAMS