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 inflateEnd( &m_zinflate );
00055 deflateEnd( &m_zdeflate );
00056 }
00057
00058 void CompressionZlib::compress( const std::string& data )
00059 {
00060 if( !m_valid || !m_handler || data.empty() )
00061 return;
00062
00063 int CHUNK = data.length() + ( data.length() / 100 ) + 13;
00064 Bytef* out = new Bytef[CHUNK];
00065 char* in = const_cast<char*>( data.c_str() );
00066
00067 m_compressMutex.lock();
00068
00069 m_zdeflate.avail_in = data.length();
00070 m_zdeflate.next_in = (Bytef*)in;
00071
00072 int ret;
00073 std::string result;
00074 do {
00075 m_zdeflate.avail_out = CHUNK;
00076 m_zdeflate.next_out = (Bytef*)out;
00077
00078 ret = deflate( &m_zdeflate, Z_SYNC_FLUSH );
00079 result.append( (char*)out, CHUNK - m_zdeflate.avail_out );
00080 } while( m_zdeflate.avail_out == 0 );
00081
00082 m_compressMutex.unlock();
00083
00084 delete[] out;
00085
00086 m_handler->handleCompressedData( result );
00087 }
00088
00089 void CompressionZlib::decompress( const std::string& data )
00090 {
00091 if( !m_valid || !m_handler || data.empty() )
00092 return;
00093
00094 int CHUNK = 50;
00095 char* out = new char[CHUNK];
00096 char* in = const_cast<char*>( data.c_str() );
00097
00098 m_zinflate.avail_in = data.length();
00099 m_zinflate.next_in = (Bytef*)in;
00100
00101 int ret = Z_OK;
00102 std::string result;
00103 do
00104 {
00105 m_zinflate.avail_out = CHUNK;
00106 m_zinflate.next_out = (Bytef*)out;
00107
00108 ret = inflate( &m_zinflate, Z_SYNC_FLUSH );
00109 result.append( out, CHUNK - m_zinflate.avail_out );
00110 } while( m_zinflate.avail_out == 0 );
00111
00112 delete[] out;
00113
00114 m_handler->handleDecompressedData( result );
00115 }
00116
00117 }
00118
00119 #endif // HAVE_ZLIB