KDECore
kxzfilter.cpp
Go to the documentation of this file.
00001 /* This file is part of the KDE libraries 00002 Copyright (C) 2007-2008 Per Øyvind Karlsen <peroyvind@mandriva.org> 00003 00004 Based on kbzip2filter: 00005 Copyright (C) 2000-2005 David Faure <faure@kde.org> 00006 00007 This library is free software; you can redistribute it and/or 00008 modify it under the terms of the GNU Library General Public 00009 License as published by the Free Software Foundation; either 00010 version 2 of the License, or (at your option) any later version. 00011 00012 This library is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 Library General Public License for more details. 00016 00017 You should have received a copy of the GNU Library General Public License 00018 along with this library; see the file COPYING.LIB. If not, write to 00019 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00020 Boston, MA 02110-1301, USA. 00021 */ 00022 00023 #include "kxzfilter.h" 00024 00025 #include <config.h> 00026 00027 #if defined( HAVE_XZ_SUPPORT ) 00028 extern "C" { 00029 #include <lzma.h> 00030 } 00031 00032 #include <kdebug.h> 00033 00034 #include <qiodevice.h> 00035 00036 00037 class KXzFilter::Private 00038 { 00039 public: 00040 Private() 00041 : isInitialized(false) 00042 { 00043 memset(&zStream, 0, sizeof(zStream)); 00044 mode = 0; 00045 } 00046 00047 lzma_stream zStream; 00048 int mode; 00049 bool isInitialized; 00050 }; 00051 00052 KXzFilter::KXzFilter() 00053 :d(new Private) 00054 { 00055 } 00056 00057 00058 KXzFilter::~KXzFilter() 00059 { 00060 delete d; 00061 } 00062 00063 void KXzFilter::init( int mode ) 00064 { 00065 if (d->isInitialized) { 00066 terminate(); 00067 } 00068 00069 lzma_ret result; 00070 d->zStream.next_in = 0; 00071 d->zStream.avail_in = 0; 00072 if ( mode == QIODevice::ReadOnly ) 00073 { 00074 /* We set the memlimit for decompression to 100MiB which should be 00075 * more than enough to be sufficient for level 9 which requires 65 MiB. 00076 */ 00077 result = lzma_auto_decoder(&d->zStream, 100<<20, 0); 00078 //kDebug(7131) << "lzma_auto_decoder returned " << result; 00079 } else if ( mode == QIODevice::WriteOnly ) { 00080 result = lzma_easy_encoder(&d->zStream, LZMA_PRESET_DEFAULT, LZMA_CHECK_CRC32); 00081 //kDebug(7131) << "lzma_easy_encoder returned " << result; 00082 } else 00083 kWarning(7131) << "Unsupported mode " << mode << ". Only QIODevice::ReadOnly and QIODevice::WriteOnly supported"; 00084 d->mode = mode; 00085 d->isInitialized = true; 00086 } 00087 00088 int KXzFilter::mode() const 00089 { 00090 return d->mode; 00091 } 00092 00093 void KXzFilter::terminate() 00094 { 00095 if (d->mode == QIODevice::ReadOnly || d->mode == QIODevice::WriteOnly) { 00096 lzma_end(&d->zStream); 00097 } else { 00098 kWarning(7131) << "Unsupported mode " << d->mode << ". Only QIODevice::ReadOnly and QIODevice::WriteOnly supported"; 00099 } 00100 d->isInitialized = false; 00101 } 00102 00103 00104 void KXzFilter::reset() 00105 { 00106 kDebug(7131) << "KXzFilter::reset"; 00107 // liblzma doesn't have a reset call... 00108 terminate(); 00109 init( d->mode ); 00110 } 00111 00112 void KXzFilter::setOutBuffer( char * data, uint maxlen ) 00113 { 00114 d->zStream.avail_out = maxlen; 00115 d->zStream.next_out = (uint8_t *)data; 00116 } 00117 00118 void KXzFilter::setInBuffer( const char *data, unsigned int size ) 00119 { 00120 d->zStream.avail_in = size; 00121 d->zStream.next_in = (uint8_t *)const_cast<char *>(data); 00122 } 00123 00124 int KXzFilter::inBufferAvailable() const 00125 { 00126 return d->zStream.avail_in; 00127 } 00128 00129 int KXzFilter::outBufferAvailable() const 00130 { 00131 return d->zStream.avail_out; 00132 } 00133 00134 KXzFilter::Result KXzFilter::uncompress() 00135 { 00136 //kDebug(7131) << "Calling lzma_code with avail_in=" << inBufferAvailable() << " avail_out =" << outBufferAvailable(); 00137 lzma_ret result = lzma_code(&d->zStream, LZMA_RUN); 00138 if ( result != LZMA_OK ) 00139 { 00140 kDebug(7131) << "lzma_code returned " << result; 00141 kDebug(7131) << "KXzFilter::uncompress " << ( result == LZMA_STREAM_END ? KFilterBase::End : KFilterBase::Error ); 00142 } 00143 00144 switch (result) { 00145 case LZMA_OK: 00146 return KFilterBase::Ok; 00147 case LZMA_STREAM_END: 00148 return KFilterBase::End; 00149 default: 00150 return KFilterBase::Error; 00151 } 00152 } 00153 00154 KXzFilter::Result KXzFilter::compress( bool finish ) 00155 { 00156 //kDebug(7131) << "Calling lzma_code with avail_in=" << inBufferAvailable() << " avail_out=" << outBufferAvailable(); 00157 lzma_ret result = lzma_code(&d->zStream, finish ? LZMA_FINISH : LZMA_RUN ); 00158 00159 switch (result) { 00160 case LZMA_OK: 00161 return KFilterBase::Ok; 00162 break; 00163 case LZMA_STREAM_END: 00164 kDebug(7131) << " lzma_code returned " << result; 00165 return KFilterBase::End; 00166 break; 00167 default: 00168 kDebug(7131) << " lzma_code returned " << result; 00169 return KFilterBase::Error; 00170 break; 00171 } 00172 } 00173 00174 #endif /* HAVE_XZ_SUPPORT */
KDE 4.6 API Reference