]>
git.saurik.com Git - wxWidgets.git/blob - src/common/zstream.cpp
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 // normally, the compiler options should contain -I../zlib, but it is
31 // apparently not the case for all MSW makefiles and so, unless we use
32 // configure (which defines __WX_SETUP_H__) or it is explicitly overridden by
33 // the user (who can define wxUSE_ZLIB_H_IN_PATH), we hardcode the path here
34 #if defined(__WXMSW__) && !defined(__WX_SETUP_H__) && !defined(wxUSE_ZLIB_H_IN_PATH)
35 #include "../zlib/zlib.h"
36 #elif defined(__WXMAC__) && defined(__UNIX__)
42 #define ZSTREAM_BUFFER_SIZE 1024
44 //////////////////////
46 //////////////////////
48 wxZlibInputStream::wxZlibInputStream(wxInputStream
& stream
)
49 : wxFilterInputStream(stream
)
53 // I need a private stream buffer.
54 m_inflate
= new z_stream_s
;
56 m_inflate
->zalloc
= (alloc_func
)0;
57 m_inflate
->zfree
= (free_func
)0;
58 m_inflate
->opaque
= (voidpf
)0;
60 err
= inflateInit(m_inflate
);
62 inflateEnd(m_inflate
);
67 m_z_buffer
= new unsigned char[ZSTREAM_BUFFER_SIZE
];
68 m_z_size
= ZSTREAM_BUFFER_SIZE
;
70 m_inflate
->avail_in
= 0;
71 m_inflate
->next_in
= NULL
;
74 wxZlibInputStream::~wxZlibInputStream()
76 inflateEnd(m_inflate
);
80 size_t wxZlibInputStream::OnSysRead(void *buffer
, size_t size
)
84 m_inflate
->next_out
= (unsigned char *)buffer
;
85 m_inflate
->avail_out
= size
;
87 while (m_inflate
->avail_out
> 0) {
88 if (m_inflate
->avail_in
== 0) {
90 m_parent_i_stream
->Read(m_z_buffer
, wxMin(m_z_size
, size
));
91 m_inflate
->next_in
= m_z_buffer
;
92 m_inflate
->avail_in
= m_parent_i_stream
->LastRead();
94 if (m_parent_i_stream
->LastError() != wxStream_NOERROR
&&
95 m_parent_i_stream
->LastError() != wxStream_EOF
)
97 m_lasterror
= m_parent_i_stream
->LastError();
98 return 0; // failed to read anything
101 if ( m_inflate
->avail_in
== 0 )
104 m_lasterror
= wxStream_EOF
;
108 err
= inflate(m_inflate
, Z_FINISH
);
109 if (err
== Z_STREAM_END
)
110 return (size
- m_inflate
->avail_out
);
113 return size
-m_inflate
->avail_out
;
116 //////////////////////
117 // wxZlibOutputStream
118 //////////////////////
120 wxZlibOutputStream::wxZlibOutputStream(wxOutputStream
& stream
, int level
)
121 : wxFilterOutputStream(stream
)
125 m_deflate
= new z_stream_s
;
127 m_deflate
->zalloc
= (alloc_func
)0;
128 m_deflate
->zfree
= (free_func
)0;
129 m_deflate
->opaque
= (voidpf
)0;
131 if (level
== -1) level
= Z_DEFAULT_COMPRESSION
;
132 wxASSERT_MSG(level
>= 0 && level
<= 9, wxT("wxZlibOutputStream compression level must be between 0 and 9!"));
134 err
= deflateInit(m_deflate
, level
);
136 deflateEnd(m_deflate
);
140 m_z_buffer
= new unsigned char[ZSTREAM_BUFFER_SIZE
];
141 m_z_size
= ZSTREAM_BUFFER_SIZE
;
143 m_deflate
->avail_in
= 0;
144 m_deflate
->next_out
= m_z_buffer
;
145 m_deflate
->avail_out
= m_z_size
;
148 wxZlibOutputStream::~wxZlibOutputStream()
154 err
= deflate(m_deflate
, Z_FINISH
);
155 if (err
!= Z_STREAM_END
)
157 wxLogDebug( wxT("wxZlibOutputStream: an error occured while closing the stream.\n") );
161 deflateEnd(m_deflate
);
166 void wxZlibOutputStream::Sync()
170 m_parent_o_stream
->Write(m_z_buffer
, m_z_size
-m_deflate
->avail_out
);
171 m_deflate
->next_out
= m_z_buffer
;
172 m_deflate
->avail_out
= m_z_size
;
174 err
= deflate(m_deflate
, Z_FULL_FLUSH
);
179 // Fixed by "Stefan Csomor" <csomor@advancedconcepts.ch>
180 while( m_deflate
->avail_out
== 0 )
182 m_parent_o_stream
->Write(m_z_buffer
, m_z_size
);
183 m_deflate
->next_out
= m_z_buffer
;
184 m_deflate
->avail_out
= m_z_size
;
185 err
= deflate(m_deflate
, Z_FULL_FLUSH
);
192 m_parent_o_stream
->Write(m_z_buffer
, m_z_size
-m_deflate
->avail_out
);
193 m_deflate
->next_out
= m_z_buffer
;
194 m_deflate
->avail_out
= m_z_size
;
197 size_t wxZlibOutputStream::OnSysWrite(const void *buffer
, size_t size
)
201 m_deflate
->next_in
= (unsigned char *)buffer
;
202 m_deflate
->avail_in
= size
;
204 while (m_deflate
->avail_in
> 0) {
206 if (m_deflate
->avail_out
== 0) {
207 m_parent_o_stream
->Write(m_z_buffer
, m_z_size
);
208 if (m_parent_o_stream
->LastError() != wxStream_NOERROR
)
209 return (size
- m_deflate
->avail_in
);
211 m_deflate
->next_out
= m_z_buffer
;
212 m_deflate
->avail_out
= m_z_size
;
215 err
= deflate(m_deflate
, Z_NO_FLUSH
);
217 return (size
- m_deflate
->avail_in
);
223 // wxUSE_ZLIB && wxUSE_STREAMS