From 51acf83bd6029aeb8fbd8af9c316c03565c715d2 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 6 Mar 2009 16:26:15 +0000 Subject: [PATCH] added wxZlibStream::SetDictionary() (closes #10551) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@59370 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/changes.txt | 5 +++-- include/wx/zstream.h | 6 ++++++ interface/wx/zstream.h | 26 ++++++++++++++++++++++++++ src/common/zstream.cpp | 20 ++++++++++++++++++++ tests/streams/zlibstream.cpp | 27 ++++++++++++++++++++++++--- 5 files changed, 79 insertions(+), 5 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index 8c980baf73..3ca763a24b 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -313,9 +313,9 @@ All: - Added (experimental) IPv6 support to wxSocket (Arcen). - Cleaned up wxURI and made it Unicode-friendly. -- Add support for wxExecute(wxEXEC_ASYNC) in wxBase (Lukasz Michalski) +- Add support for wxExecute(wxEXEC_ASYNC) in wxBase (Lukasz Michalski). - Added wxXLocale class and xlocale-like functions using it. -- Allow loading message catalogs from wxFileSystem (Axel Gembe) +- Allow loading message catalogs from wxFileSystem (Axel Gembe). - Added wxMessageQueue class for inter-thread communications - Use UTF-8 for Unicode data in wxIPC classes (Anders Larsen) - Added support for user-defined types to wxConfig (Marcin Wojdyr). @@ -327,6 +327,7 @@ All: - Implemented wxMemoryInputStream::CanRead(). - Implemented wxMemoryFSHandler::FindFirst/Next(). - Added wxEventLoop::DispatchTimeout(). +- Added wxZlibStream::SetDictionary() (Axel Gembe). - Added wxEXEC_BLOCK flag (Hank Schultz). - Add support for wxStream-derived classes to wxRTTI (Stas Sergeev). - Added wxStreamBuffer::Truncate() (Stas Sergeev). diff --git a/include/wx/zstream.h b/include/wx/zstream.h index ae7e4124fa..5a895ab5a8 100644 --- a/include/wx/zstream.h +++ b/include/wx/zstream.h @@ -44,6 +44,9 @@ class WXDLLIMPEXP_BASE wxZlibInputStream: public wxFilterInputStream { static bool CanHandleGZip(); + bool SetDictionary(const char *data, const size_t datalen); + bool SetDictionary(const wxMemoryBuffer &buf); + protected: size_t OnSysRead(void *buffer, size_t size); wxFileOffset OnSysTell() const { return m_pos; } @@ -72,6 +75,9 @@ class WXDLLIMPEXP_BASE wxZlibOutputStream: public wxFilterOutputStream { static bool CanHandleGZip(); + bool SetDictionary(const char *data, const size_t datalen); + bool SetDictionary(const wxMemoryBuffer &buf); + protected: size_t OnSysWrite(const void *buffer, size_t size); wxFileOffset OnSysTell() const { return m_pos; } diff --git a/interface/wx/zstream.h b/interface/wx/zstream.h index b28ca95dd2..d5e5977a51 100644 --- a/interface/wx/zstream.h +++ b/interface/wx/zstream.h @@ -76,6 +76,19 @@ public: Returns @true if zlib library in use can handle gzip compressed data. */ static bool CanHandleGZip(); + + //@{ + /** + Sets the dictionary to the specified chunk of data. This can improve + compression rate but note that the dictionary has to be the same when + you deflate the data as when you inflate the data, otherwise you + will inflate corrupted data. + + Returns @true if the dictionary was successfully set. + */ + bool SetDictionary(const char *data, const size_t datalen); + bool SetDictionary(const wxMemoryBuffer &buf); + //@} }; @@ -122,5 +135,18 @@ public: Returns @true if zlib library in use can handle gzip compressed data. */ static bool CanHandleGZip(); + + //@{ + /** + Sets the dictionary to the specified chunk of data. This can improve + compression rate but note that the dictionary has to be the same when + you deflate the data as when you inflate the data, otherwise you + will inflate corrupted data. + + Returns @true if the dictionary was successfully set. + */ + bool SetDictionary(const char *data, const size_t datalen); + bool SetDictionary(const wxMemoryBuffer &buf); + //@} }; diff --git a/src/common/zstream.cpp b/src/common/zstream.cpp index 44c26f2703..57bed6a6a3 100644 --- a/src/common/zstream.cpp +++ b/src/common/zstream.cpp @@ -248,6 +248,16 @@ size_t wxZlibInputStream::OnSysRead(void *buffer, size_t size) return major > 1 || (major == 1 && minor >= 2); } +bool wxZlibInputStream::SetDictionary(const char *data, const size_t datalen) +{ + return (inflateSetDictionary(m_inflate, (Bytef*)data, datalen) == Z_OK); +} + +bool wxZlibInputStream::SetDictionary(const wxMemoryBuffer &buf) +{ + return SetDictionary((char*)buf.GetData(), buf.GetDataLen()); +} + ////////////////////// // wxZlibOutputStream @@ -412,5 +422,15 @@ size_t wxZlibOutputStream::OnSysWrite(const void *buffer, size_t size) return wxZlibInputStream::CanHandleGZip(); } +bool wxZlibOutputStream::SetDictionary(const char *data, const size_t datalen) +{ + return (deflateSetDictionary(m_deflate, (Bytef*)data, datalen) == Z_OK); +} + +bool wxZlibOutputStream::SetDictionary(const wxMemoryBuffer &buf) +{ + return SetDictionary((char*)buf.GetData(), buf.GetDataLen()); +} + #endif // wxUSE_ZLIB && wxUSE_STREAMS diff --git a/tests/streams/zlibstream.cpp b/tests/streams/zlibstream.cpp index 423d549159..58b3c3b34e 100644 --- a/tests/streams/zlibstream.cpp +++ b/tests/streams/zlibstream.cpp @@ -23,8 +23,8 @@ #include "wx/zstream.h" #include "wx/wfstream.h" #include "wx/mstream.h" - #include "wx/txtstrm.h" +#include "wx/buffer.h" #include "bstream.h" @@ -72,6 +72,7 @@ public: CPPUNIT_TEST(TestStream_NoHeader_NoComp); CPPUNIT_TEST(TestStream_NoHeader_SpeedComp); CPPUNIT_TEST(TestStream_NoHeader_BestComp); + CPPUNIT_TEST(TestStream_NoHeader_Dictionary); CPPUNIT_TEST(TestStream_ZLib_Default); CPPUNIT_TEST(TestStream_ZLib_NoComp); CPPUNIT_TEST(TestStream_ZLib_SpeedComp); @@ -80,6 +81,7 @@ public: WXTEST_WITH_GZIP_CONDITION(TestStream_GZip_NoComp); WXTEST_WITH_GZIP_CONDITION(TestStream_GZip_SpeedComp); WXTEST_WITH_GZIP_CONDITION(TestStream_GZip_BestComp); + WXTEST_WITH_GZIP_CONDITION(TestStream_GZip_Dictionary); WXTEST_WITH_GZIP_CONDITION(TestStream_ZLibGZip); CPPUNIT_TEST(Decompress_BadData); CPPUNIT_TEST(Decompress_wx251_zlib114_Data_NoHeader); @@ -93,6 +95,7 @@ protected: void TestStream_NoHeader_NoComp(); void TestStream_NoHeader_SpeedComp(); void TestStream_NoHeader_BestComp(); + void TestStream_NoHeader_Dictionary(); void TestStream_ZLib_Default(); void TestStream_ZLib_NoComp(); void TestStream_ZLib_SpeedComp(); @@ -101,6 +104,7 @@ protected: void TestStream_GZip_NoComp(); void TestStream_GZip_SpeedComp(); void TestStream_GZip_BestComp(); + void TestStream_GZip_Dictionary(); void TestStream_ZLibGZip(); // Try to decompress bad data. void Decompress_BadData(); @@ -114,7 +118,7 @@ protected: private: const char *GetDataBuffer(); const unsigned char *GetCompressedData(); - void doTestStreamData(int input_flag, int output_flag, int compress_level); + void doTestStreamData(int input_flag, int output_flag, int compress_level, const wxMemoryBuffer *buf = NULL); void doDecompress_ExternalData(const unsigned char *data, const char *value, size_t data_size, size_t value_size, int flag = wxZLIB_AUTO); private: @@ -132,6 +136,7 @@ private: char m_DataBuffer[DATABUFFER_SIZE]; size_t m_SizeCompressedData; unsigned char *m_pCompressedData; + wxMemoryBuffer m_Dictionary; // Used by the base Creat[In|Out]Stream and Delete[In|Out]Stream. wxMemoryInputStream *m_pTmpMemInStream; @@ -148,6 +153,8 @@ zlibStream::zlibStream() for (size_t i = 0; i < DATABUFFER_SIZE; i++) m_DataBuffer[i] = (i % 0xFF); + m_Dictionary.AppendData(m_DataBuffer, sizeof(m_DataBuffer) / 2); + // Set extra base config settings. m_bSimpleTellITest = true; m_bSimpleTellOTest = true; @@ -187,6 +194,10 @@ void zlibStream::TestStream_NoHeader_BestComp() { doTestStreamData(wxZLIB_NO_HEADER, wxZLIB_NO_HEADER, wxZ_BEST_COMPRESSION); } +void zlibStream::TestStream_NoHeader_Dictionary() +{ + doTestStreamData(wxZLIB_NO_HEADER, wxZLIB_NO_HEADER, wxZ_DEFAULT_COMPRESSION, &m_Dictionary); +} void zlibStream::TestStream_ZLib_Default() { @@ -221,6 +232,10 @@ void zlibStream::TestStream_GZip_BestComp() { doTestStreamData(wxZLIB_GZIP, wxZLIB_GZIP, wxZ_BEST_COMPRESSION); } +void zlibStream::TestStream_GZip_Dictionary() +{ + doTestStreamData(wxZLIB_GZIP, wxZLIB_GZIP, wxZ_DEFAULT_COMPRESSION, &m_Dictionary); +} void zlibStream::TestStream_ZLibGZip() { @@ -307,7 +322,7 @@ const unsigned char *zlibStream::GetCompressedData() return m_pCompressedData; } -void zlibStream::doTestStreamData(int input_flag, int output_flag, int compress_level) +void zlibStream::doTestStreamData(int input_flag, int output_flag, int compress_level, const wxMemoryBuffer *buf) { size_t fail_pos; char last_value = 0; @@ -320,6 +335,9 @@ void zlibStream::doTestStreamData(int input_flag, int output_flag, int compress_ wxZlibOutputStream zstream_out(fstream_out, compress_level, output_flag); CPPUNIT_ASSERT_MESSAGE("Could not create the output stream", zstream_out.IsOk()); + if (buf) + zstream_out.SetDictionary(*buf); + // Next: Compress some data so the file is containing something. zstream_out.Write(GetDataBuffer(), DATABUFFER_SIZE); } @@ -336,6 +354,9 @@ void zlibStream::doTestStreamData(int input_flag, int output_flag, int compress_ wxZlibInputStream zstream_in(fstream_in, input_flag); CPPUNIT_ASSERT_MESSAGE("Could not create the input stream", zstream_in.IsOk()); + if (buf) + zstream_in.SetDictionary(*buf); + // Next: Check char per char if the returned data is valid. const char *pbuf = GetDataBuffer(); for (fail_pos = 0; !zstream_in.Eof(); fail_pos++) -- 2.45.2