gloox 1.0
compressionzlib.cpp
00001 /*
00002   Copyright (c) 2005-2009 by Jakob Schroeter <js@camaya.net>
00003   This file is part of the gloox library. http://camaya.net/gloox
00004 
00005   This software is distributed under a license. The full license
00006   agreement can be found in the file LICENSE in this distribution.
00007   This software may not be copied, modified, sold or distributed
00008   other than expressed in the named license agreement.
00009 
00010   This software is distributed without any warranty.
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/*Z_DEFAULT_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