compressionzlib.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "compressionzlib.h"
00016
00017 #ifdef HAVE_ZLIB
00018
00019 namespace gloox
00020 {
00021
00022 CompressionZlib::CompressionZlib( CompressionDataHandler* cdh )
00023 : CompressionBase( cdh )
00024 {
00025 }
00026
00027 bool CompressionZlib::init()
00028 {
00029 int ret = Z_OK;
00030 m_zinflate.zalloc = Z_NULL;
00031 m_zinflate.zfree = Z_NULL;
00032 m_zinflate.opaque = Z_NULL;
00033 m_zinflate.avail_in = 0;
00034 m_zinflate.next_in = Z_NULL;
00035 ret = inflateInit( &m_zinflate );
00036 if( ret != Z_OK )
00037 return false;
00038
00039 m_zdeflate.zalloc = Z_NULL;
00040 m_zdeflate.zfree = Z_NULL;
00041 m_zdeflate.opaque = Z_NULL;
00042 m_zinflate.avail_in = 0;
00043 m_zinflate.next_in = Z_NULL;
00044 ret = deflateInit( &m_zdeflate, Z_BEST_COMPRESSION );
00045 if( ret != Z_OK )
00046 return false;
00047
00048 m_valid = true;
00049 return true;
00050 }
00051
00052 CompressionZlib::~CompressionZlib()
00053 {
00054 cleanup();
00055 }
00056
00057 void CompressionZlib::compress( const std::string& data )
00058 {
00059 if( !m_valid )
00060 init();
00061
00062 if( !m_valid || !m_handler || data.empty() )
00063 return;
00064
00065 long unsigned int CHUNK = data.length() + ( data.length() / 100 ) + 13;
00066 Bytef* out = new Bytef[CHUNK];
00067 char* in = const_cast<char*>( data.c_str() );
00068
00069 m_compressMutex.lock();
00070
00071 m_zdeflate.avail_in = static_cast<uInt>( data.length() );
00072 m_zdeflate.next_in = (Bytef*)in;
00073
00074 int ret;
00075 std::string result;
00076 do {
00077 m_zdeflate.avail_out = static_cast<uInt>( CHUNK );
00078 m_zdeflate.next_out = (Bytef*)out;
00079
00080 ret = deflate( &m_zdeflate, Z_SYNC_FLUSH );
00081 result.append( (char*)out, CHUNK - m_zdeflate.avail_out );
00082 } while( m_zdeflate.avail_out == 0 );
00083
00084 m_compressMutex.unlock();
00085
00086 delete[] out;
00087
00088 m_handler->handleCompressedData( result );
00089 }
00090
00091 void CompressionZlib::decompress( const std::string& data )
00092 {
00093 if( !m_valid )
00094 init();
00095
00096 if( !m_valid || !m_handler || data.empty() )
00097 return;
00098
00099 int CHUNK = 50;
00100 char* out = new char[CHUNK];
00101 char* in = const_cast<char*>( data.c_str() );
00102
00103 m_zinflate.avail_in = static_cast<uInt>( data.length() );
00104 m_zinflate.next_in = (Bytef*)in;
00105
00106 int ret = Z_OK;
00107 std::string result;
00108 do
00109 {
00110 m_zinflate.avail_out = CHUNK;
00111 m_zinflate.next_out = (Bytef*)out;
00112
00113 ret = inflate( &m_zinflate, Z_SYNC_FLUSH );
00114 result.append( out, CHUNK - m_zinflate.avail_out );
00115 } while( m_zinflate.avail_out == 0 );
00116
00117 delete[] out;
00118
00119 m_handler->handleDecompressedData( result );
00120 }
00121
00122 void CompressionZlib::cleanup()
00123 {
00124 if( !m_valid )
00125 return;
00126
00127 inflateEnd( &m_zinflate );
00128 deflateEnd( &m_zdeflate );
00129
00130 m_valid = false;
00131 }
00132
00133 }
00134
00135 #endif // HAVE_ZLIB