From 301deecc27a700e5432f8923be63ec71a79b8a52 Mon Sep 17 00:00:00 2001 From: Ryan Norton Date: Sun, 21 Dec 2003 04:28:45 +0000 Subject: [PATCH] Committed Mike's Update Patch 862130 wxZlibInput/OutputStream gzip support git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@24952 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/latex/wx/strmzlib.tex | 44 ++++++++++++++++++++++---------------- include/wx/zstream.h | 8 ++++--- src/common/zstream.cpp | 28 ++++++++++++++++++++---- 3 files changed, 55 insertions(+), 25 deletions(-) diff --git a/docs/latex/wx/strmzlib.tex b/docs/latex/wx/strmzlib.tex index a16745b8fb..d563a50640 100644 --- a/docs/latex/wx/strmzlib.tex +++ b/docs/latex/wx/strmzlib.tex @@ -3,8 +3,8 @@ % ----------------------------------------------------------------------------- \section{\class{wxZlibInputStream}}\label{wxzlibinputstream} -This stream uncompresses all data read from it. It uses the "filtered" -stream to get new compressed data. +This filter stream decompresses a stream that is in zlib or gzip format. +Note that reading the gzip format requires zlib version 1.2.0 greater. The stream is not seekable, \helpref{SeekI()}{wxinputstreamseeki} returns {\it wxInvalidOffset}. Also \helpref{GetSize()}{wxstreambasegetsize} is @@ -27,19 +27,23 @@ not supported, it always returns $0$. \membersection{wxZlibInputStream::wxZlibInputStream} -\func{}{wxZlibInputStream}{\param{wxInputStream\&}{ stream}, \param{int}{ flags = 0}} +\func{}{wxZlibInputStream}{\param{wxInputStream\&}{ stream}, \param{int}{ flags = wxZLIB\_ZLIB | wxZLIB\_GZIP}} -{\it flags} should be omitted for normal usage. The flag {\it wxZLIB\_NO_HEADER} - is needed when wxZlibInputStream is used as an 'inflate' decompressor for gzip -or zip files. +The {\it flags} wxZLIB\_ZLIB and wxZLIB\_GZIP specify whether the input data +is in zlib or gzip format. If both are used, bitwise ored, then zlib will +autodetect the stream type, this is the default. +If {\it flags} is zero, then the data is assumed to be a raw deflate stream +without either zlib or gzip headers. -{\it wxZLIB\_NO_HEADER} is currently the only flag: +The following symbols can be use for the flags: \begin{verbatim} // Flags enum { - wxZLIB_NO_HEADER = 1 // required for use in Gzip and Zip files -} + wxZLIB_NO_HEADER = 0, // raw deflate stream, no header or checksum + wxZLIB_ZLIB = 1, // zlib header and checksum + wxZLIB_GZIP = 2 // gzip header and checksum, requires zlib 1.2+ +}; \end{verbatim} @@ -48,8 +52,9 @@ enum { % ----------------------------------------------------------------------------- \section{\class{wxZlibOutputStream}}\label{wxzliboutputstream} -This stream compresses all data written to it, and passes the compressed data -to the "filtered" stream. +This stream compresses all data written to it. The compressed output can be +in zlib or gzip format. +Note that writing the gzip format requires zlib version 1.2.0 greater. The stream is not seekable, \helpref{SeekO()}{wxoutputstreamseeko} returns {\it wxInvalidOffset}. @@ -72,16 +77,17 @@ The stream is not seekable, \helpref{SeekO()}{wxoutputstreamseeko} returns \membersection{wxZlibOutputStream::wxZlibOutputStream} -\func{}{wxZlibOutputStream}{\param{wxOutputStream\&}{ stream}, \param{int}{ level = -1}, \param{int}{ flags = 0}} +\func{}{wxZlibOutputStream}{\param{wxOutputStream\&}{ stream}, \param{int}{ level = -1}, \param{int}{ flags = wxZLIB\_ZLIB}} Creates a new write-only compressed stream. {\it level} means level of compression. It is number between 0 and 9 (including these values) where 0 means no compression and 9 best but slowest compression. -1 is default value (currently equivalent to 6). -{\it flags} should be omitted for normal usage. The flag {\it wxZLIB\_NO_HEADER} - suppresses the generation of the zlib header and checksum, and is required -when wxZlibOutputStream is used as a 'deflate' compressor for gzip or zip files. +The {\it flags} wxZLIB\_ZLIB and wxZLIB\_GZIP specify whether the output data +will be in zlib or gzip format. wxZLIB\_ZLIB is the default. +If {\it flags} is zero, then a raw deflate stream is output without either +zlib or gzip headers. The following symbols can be use for the compression level and flags: @@ -92,11 +98,13 @@ enum { wxZ_NO_COMPRESSION = 0, wxZ_BEST_SPEED = 1, wxZ_BEST_COMPRESSION = 9 -} +}; // Flags enum { - wxZLIB_NO_HEADER = 1 // required for use in Gzip and Zip files -} + wxZLIB_NO_HEADER = 0, // raw deflate stream, no header or checksum + wxZLIB_ZLIB = 1, // zlib header and checksum + wxZLIB_GZIP = 2 // gzip header and checksum, requires zlib 1.2+ +}; \end{verbatim} diff --git a/include/wx/zstream.h b/include/wx/zstream.h index 66be16c5df..20def98569 100644 --- a/include/wx/zstream.h +++ b/include/wx/zstream.h @@ -31,12 +31,14 @@ enum { // Flags enum { - wxZLIB_NO_HEADER = 1 // required for use in Gzip and Zip files + wxZLIB_NO_HEADER = 1, // raw deflate stream, no header or checksum + wxZLIB_ZLIB = 2, // zlib header and checksum + wxZLIB_GZIP = 3 // gzip header and checksum, requires zlib 1.2+ }; class WXDLLIMPEXP_BASE wxZlibInputStream: public wxFilterInputStream { public: - wxZlibInputStream(wxInputStream& stream, int flags = 0); + wxZlibInputStream(wxInputStream& stream, int flags = wxZLIB_ZLIB | wxZLIB_GZIP); virtual ~wxZlibInputStream(); char Peek() { return wxInputStream::Peek(); } @@ -57,7 +59,7 @@ class WXDLLIMPEXP_BASE wxZlibInputStream: public wxFilterInputStream { class WXDLLIMPEXP_BASE wxZlibOutputStream: public wxFilterOutputStream { public: - wxZlibOutputStream(wxOutputStream& stream, int level = -1, int flags = 0); + wxZlibOutputStream(wxOutputStream& stream, int level = -1, int flags = wxZLIB_ZLIB); virtual ~wxZlibOutputStream(); void Sync() { DoFlush(false); } diff --git a/src/common/zstream.cpp b/src/common/zstream.cpp index c9d2b701c5..678b0d7485 100644 --- a/src/common/zstream.cpp +++ b/src/common/zstream.cpp @@ -68,7 +68,17 @@ wxZlibInputStream::wxZlibInputStream(wxInputStream& stream, int flags) m_inflate->next_in = NULL; m_inflate->next_out = NULL; - int bits = (flags & wxZLIB_NO_HEADER) ? -MAX_WBITS : MAX_WBITS; + wxASSERT((flags & ~(wxZLIB_ZLIB | wxZLIB_GZIP)) == 0); + + // when autodetecting between gzip & zlib, silently drop gzip flag + // if the version of zlib doesn't support it + if (flags == (wxZLIB_ZLIB | wxZLIB_GZIP) + && strcmp(zlib_version, "1.2.") < 0) + flags &= ~wxZLIB_GZIP; + + int bits = flags ? MAX_WBITS : -MAX_WBITS; + if (flags & wxZLIB_GZIP) + bits |= (flags & wxZLIB_ZLIB) ? 0x20 : 0x10; if (inflateInit2(m_inflate, bits) == Z_OK) return; @@ -126,7 +136,10 @@ size_t wxZlibInputStream::OnSysRead(void *buffer, size_t size) } m_lasterror = wxSTREAM_EOF; } else if (err != Z_OK) { - wxLogError(_("Can't read from inflate stream (zlib error %d)."), err); + wxString msg(m_inflate->msg, *wxConvCurrent); + if (!msg) + msg.Format(_("zlib error %d"), err); + wxLogError(_("Can't read from inflate stream: %s\n"), msg.c_str()); m_lasterror = wxSTREAM_READ_ERROR; } @@ -169,7 +182,11 @@ wxZlibOutputStream::wxZlibOutputStream(wxOutputStream& stream, m_deflate->next_out = m_z_buffer; m_deflate->avail_out = m_z_size; - int bits = (flags & wxZLIB_NO_HEADER) ? -MAX_WBITS : MAX_WBITS; + wxASSERT(flags == 0 || flags == wxZLIB_ZLIB || flags == wxZLIB_GZIP); + + int bits = flags ? MAX_WBITS : -MAX_WBITS; + if (flags & wxZLIB_GZIP) + bits |= 0x10; if (deflateInit2(m_deflate, level, Z_DEFLATED, bits, 8, Z_DEFAULT_STRATEGY) == Z_OK) @@ -253,7 +270,10 @@ size_t wxZlibOutputStream::OnSysWrite(const void *buffer, size_t size) if (err != Z_OK) { m_lasterror = wxSTREAM_WRITE_ERROR; - wxLogError(_("Can't write to deflate stream (zlib error %d)."), err); + wxString msg(m_deflate->msg, *wxConvCurrent); + if (!msg) + msg.Format(_("zlib error %d"), err); + wxLogError(_("Can't write to deflate stream: %s\n"), msg.c_str()); } size -= m_deflate->avail_in; -- 2.45.2