diff --git a/CMakeLists.txt b/CMakeLists.txt index ccb8fb709..499b18cc7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -90,6 +90,7 @@ option( WITH_CONSOLEKIT "Enable ConsoleKit support" ${WITH_ALL_OPTIONS} ) OPTION( WITH_NETWORK_MANAGER_BACKEND "Enable network-manager support" OFF ) OPTION( WITH_SUDO_TDESU_BACKEND "Use sudo as backend for tdesu (default is su)" OFF ) OPTION( WITH_OLD_XDG_STD "Use the pre R14.0.0 XDG standard where both TDE and KDE are recognized in desktop files" OFF ) +OPTION( WITH_LZMA "Enable support for LZMA/XZ" ${WITH_ALL_OPTIONS} ) OPTION( WITH_ASPELL "Enable aspell support" ${WITH_ALL_OPTIONS} ) OPTION( WITH_HSPELL "Enable hspell support" ${WITH_ALL_OPTIONS} ) @@ -493,6 +494,17 @@ if( BZIP2_NEED_PREFIX ) endif( BZIP2_NEED_PREFIX ) +##### check for lzma/xz ######################### + +if( WITH_LZMA ) + pkg_search_module( LZMA liblzma ) + if( NOT LZMA_FOUND ) + tde_message_fatal( "LZMA are requested, but not found on your system" ) + endif( NOT LZMA_FOUND ) + set( HAVE_XZ_SUPPORT 1 ) +endif( WITH_LZMA ) + + ##### check for jpeg ############################ find_package( JPEG ) diff --git a/config.h.cmake b/config.h.cmake index 1e7dcff74..471a83974 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -62,6 +62,9 @@ /* Defines if bzip2 is compiled */ #cmakedefine HAVE_BZIP2_SUPPORT 1 +/* Defines if lzma/xz is compiled */ +#cmakedefine HAVE_XZ_SUPPORT 1 + /* Define to 1 if you have the header file. */ #cmakedefine HAVE_CARBON_CARBON_H 1 diff --git a/tdecore/kdebug.areas b/tdecore/kdebug.areas index 5653a9a03..2221c5d80 100644 --- a/tdecore/kdebug.areas +++ b/tdecore/kdebug.areas @@ -289,6 +289,7 @@ 7126 tdeio_devices 7127 tdeio_fish 7128 tdeio_svn +7131 tdeio_xz # tdesdk 8100 kompare diff --git a/tdecore/kurl.cpp b/tdecore/kurl.cpp index 7d9c3f5a6..0b5f88c3d 100644 --- a/tdecore/kurl.cpp +++ b/tdecore/kurl.cpp @@ -1482,6 +1482,10 @@ bool KURL::hasSubURL() const return true; if (m_strRef_encoded.startsWith("zip:")) return true; + if (m_strRef_encoded.startsWith("lzma:")) + return true; + if (m_strRef_encoded.startsWith("xz:")) + return true; if ( m_strProtocol == "error" ) // anything that starts with error: has suburls return true; return false; diff --git a/tdeio/magic b/tdeio/magic index c12cec4ba..6356a04c1 100644 --- a/tdeio/magic +++ b/tdeio/magic @@ -484,6 +484,9 @@ # ACE archive 7 string **ACE** application/x-ace +# XZ +0 string \0fd\037\07a\058\05a\000 application/x-xz + #------------------------------------------------------------------------------ # frame: file(1) magic for FrameMaker files diff --git a/tdeio/tests/kfiltertest.cpp b/tdeio/tests/kfiltertest.cpp index 1922e207e..f16b957ab 100644 --- a/tdeio/tests/kfiltertest.cpp +++ b/tdeio/tests/kfiltertest.cpp @@ -94,11 +94,14 @@ int main() getcwd( currentdir, PATH_MAX ); TQString pathgz = TQFile::decodeName(currentdir) + "/test.gz"; TQString pathbz2 = TQFile::decodeName(currentdir) + "/test.bz2"; + TQString pathxz = TQFile::decodeName(currentdir) + "/test.xz"; kdDebug() << " -- test_block_write gzip -- " << endl; test_block_write(pathgz); kdDebug() << " -- test_block_write bzip2 -- " << endl; test_block_write(pathbz2); + kdDebug() << " -- test_block_write xz -- " << endl; + test_block_write(pathxz); kdDebug() << " -- test_block gzip -- " << endl; test_block(pathgz); @@ -114,5 +117,12 @@ int main() kdDebug() << " -- test_textstream bzip2 -- " << endl; test_textstream(pathbz2); + kdDebug() << " -- test_block xz -- " << endl; + test_block(pathxz); + kdDebug() << " -- test_getch xz -- " << endl; + test_getch(pathxz); + kdDebug() << " -- test_textstream xz -- " << endl; + test_textstream(pathxz); + return 0; } diff --git a/tdeioslave/CMakeLists.txt b/tdeioslave/CMakeLists.txt index 4c7bfe1c4..36c54239c 100644 --- a/tdeioslave/CMakeLists.txt +++ b/tdeioslave/CMakeLists.txt @@ -14,5 +14,6 @@ add_subdirectory( http ) add_subdirectory( ftp ) add_subdirectory( gzip ) add_subdirectory( bzip2 ) +tde_conditional_add_subdirectory( WITH_LZMA xz ) add_subdirectory( metainfo ) add_subdirectory( iso ) diff --git a/tdeioslave/xz/CMakeLists.txt b/tdeioslave/xz/CMakeLists.txt new file mode 100644 index 000000000..17677593f --- /dev/null +++ b/tdeioslave/xz/CMakeLists.txt @@ -0,0 +1,42 @@ +################################################# +# +# (C) 2010 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +include_directories( + ${TQT_INCLUDE_DIRS} + ${CMAKE_BINARY_DIR} + ${CMAKE_BINARY_DIR}/tdecore + ${CMAKE_SOURCE_DIR}/tdecore + ${CMAKE_SOURCE_DIR}/tdeio/tdeio +) + +link_directories( + ${TQT_LIBRARY_DIRS} +) + + +##### other data ################################ + +install( FILES kxzfilter.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) + + +##### kxzfilter ############################### + +set( target kxzfilter ) + +set( ${target}_SRCS + kxzfilter.cpp +) + +tde_add_kpart( ${target} AUTOMOC + SOURCES ${${target}_SRCS} + LINK tdeio-shared ${LZMA_LIBRARIES} + DESTINATION ${PLUGIN_INSTALL_DIR} +) diff --git a/tdeioslave/xz/kxzfilter.cpp b/tdeioslave/xz/kxzfilter.cpp new file mode 100644 index 000000000..2172ce2c8 --- /dev/null +++ b/tdeioslave/xz/kxzfilter.cpp @@ -0,0 +1,189 @@ +/* This file is part of the KDE libraries + Copyright (C) 2007-2008 Per Øyvind Karlsen + + Based on kbzip2filter: + Copyright (C) 2000-2005 David Faure + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "kxzfilter.h" +#include + +#include +#if HAVE_XZ_SUPPORT +extern "C" { + #include +} + +#include + +#include + +// #define DEBUG_XZ + +class KXzFilterFactory : public KLibFactory +{ +public: + KXzFilterFactory() : KLibFactory() {} + virtual ~KXzFilterFactory(){} + TQObject *createObject( TQObject *, const char *, const char*, const TQStringList & ) + { + return new KXzFilter; + } +}; + +K_EXPORT_COMPONENT_FACTORY( kxzfilter, KXzFilterFactory ) + + +class KXzFilter::Private +{ +public: + Private() + : isInitialized(false) + { + memset(&zStream, 0, sizeof(zStream)); + mode = 0; + } + + lzma_stream zStream; + int mode; + bool isInitialized; +}; + +KXzFilter::KXzFilter() + :d(new Private) +{ +} + + +KXzFilter::~KXzFilter() +{ + delete d; +} + +void KXzFilter::init( int mode ) +{ + if (d->isInitialized) { + terminate(); + } + + lzma_ret result; + d->zStream.next_in = 0; + d->zStream.avail_in = 0; + if ( mode == IO_ReadOnly ) + { + /* We set the memlimit for decompression to 100MiB which should be + * more than enough to be sufficient for level 9 which requires 65 MiB. + */ + result = lzma_auto_decoder(&d->zStream, 100<<20, 0); + //kdDebug(7131) << "lzma_auto_decoder returned " << result; + } else if ( mode == IO_WriteOnly ) { + result = lzma_easy_encoder(&d->zStream, LZMA_PRESET_DEFAULT, LZMA_CHECK_CRC32); + //kdDebug(7131) << "lzma_easy_encoder returned " << result; + } else + kdWarning(7131) << "Unsupported mode " << mode << ". Only IO_ReadOnly and IO_WriteOnly supported"; + d->mode = mode; + d->isInitialized = true; +} + +int KXzFilter::mode() const +{ + return d->mode; +} + +void KXzFilter::terminate() +{ + if (d->mode == IO_ReadOnly || d->mode == IO_WriteOnly) { + lzma_end(&d->zStream); + } else { + kdWarning(7131) << "Unsupported mode " << d->mode << ". Only IO_ReadOnly and IO_WriteOnly supported"; + } + d->isInitialized = false; +} + + +void KXzFilter::reset() +{ + //kdDebug(7131) << "KXzFilter::reset"; + // liblzma doesn't have a reset call... + terminate(); + init( d->mode ); +} + +void KXzFilter::setOutBuffer( char * data, uint maxlen ) +{ + d->zStream.avail_out = maxlen; + d->zStream.next_out = (uint8_t *)data; +} + +void KXzFilter::setInBuffer( const char *data, unsigned int size ) +{ + d->zStream.avail_in = size; + d->zStream.next_in = (uint8_t *)const_cast(data); +} + +int KXzFilter::inBufferAvailable() const +{ + return d->zStream.avail_in; +} + +int KXzFilter::outBufferAvailable() const +{ + return d->zStream.avail_out; +} + +KXzFilter::Result KXzFilter::uncompress() +{ + //kdDebug(7131) << "Calling lzma_code with avail_in=" << inBufferAvailable() << " avail_out =" << outBufferAvailable(); + lzma_ret result = lzma_code(&d->zStream, LZMA_RUN); + if ( result != LZMA_OK ) + { + kdDebug(7131) << "lzma_code returned " << result; + kdDebug(7131) << "KXzFilter::uncompress " << ( result == LZMA_STREAM_END ? END : ERROR ); + } + + switch (result) { + case LZMA_OK: + return OK; + case LZMA_STREAM_END: + return END; + default: + return ERROR; + } +} + +KXzFilter::Result KXzFilter::compress( bool finish ) +{ + //kdDebug(7131) << "Calling lzma_code with avail_in=" << inBufferAvailable() << " avail_out=" << outBufferAvailable(); + lzma_ret result = lzma_code(&d->zStream, finish ? LZMA_FINISH : LZMA_RUN ); + + switch (result) { + case LZMA_OK: + return OK; + break; + case LZMA_STREAM_END: + kdDebug(7131) << " lzma_code returned " << result; + return END; + break; + default: + kdDebug(7131) << " lzma_code returned " << result; + return ERROR; + break; + } +} + +#endif /* HAVE_XZ_SUPPORT */ diff --git a/tdeioslave/xz/kxzfilter.desktop b/tdeioslave/xz/kxzfilter.desktop new file mode 100644 index 000000000..7d6f4a649 --- /dev/null +++ b/tdeioslave/xz/kxzfilter.desktop @@ -0,0 +1,86 @@ +[Desktop Entry] +Type=Service +Name=XZ Filter +Name[af]=XZ Filter +Name[ar]=فلتر XZ +Name[az]=XZ Filtri +Name[be]=Фільтр XZ +Name[bg]=Филтър XZ +Name[bn]=জি-জিপ (XZ) ফিল্টার +Name[br]=Sil XZ +Name[ca]=Filtre XZ +Name[cs]=Filtr XZ +Name[csb]=Filter XZ +Name[cy]=Hidl XZ +Name[da]=XZ-filter +Name[de]=XZ-Filter +Name[el]=Φίλτρο XZ +Name[eo]=XZ-filtrilo +Name[es]=Filtro XZ +Name[et]=XZ filter +Name[eu]=XZ iragazkia +Name[fa]=پالایۀ XZ +Name[fi]=XZ-suodin +Name[fr]=Filtre XZ +Name[fy]=XZ-filter +Name[ga]=Scagaire XZ +Name[gl]=Filtro XZ +Name[he]=מסנן XZ +Name[hi]=XZ फ़िल्टर +Name[hr]=XZ filtar +Name[hu]=XZ szűrő +Name[id]=Filter XZ +Name[is]=XZ sía +Name[it]=Filtro XZ +Name[ja]=XZ フィルタ +Name[ka]=XZ ფილტრი +Name[kk]=XZ сүзгісі +Name[km]=តម្រង XZ +Name[ko]=XZ 거르개 +Name[lb]=XZ-Filter +Name[lt]=XZ filtras +Name[lv]=XZ Filtrs +Name[mk]=XZ филтер +Name[mn]=XZ-Filter +Name[ms]=Penapis XZ +Name[mt]=Filtru XZ +Name[nb]=XZ-filter +Name[nds]=XZ-Filter +Name[ne]=XZ फिल्टर +Name[nl]=XZ-filter +Name[nn]=XZ-filter +Name[nso]=Sesekodi sa XZ +Name[pa]=XZ ਫਿਲਟਰ +Name[pl]=Filtr XZ +Name[pt]=Filtro XZ +Name[pt_BR]=Filtro XZ +Name[ro]=Filtru XZ +Name[ru]=Фильтр XZ +Name[rw]=Muyunguruzi XZ +Name[se]=XZ-filter +Name[sk]=XZ filter +Name[sl]=Filter za XZ +Name[sq]=Filteri XZ +Name[sr]=XZ филтер +Name[sr@Latn]=XZ filter +Name[ss]=Sisefo se XZ +Name[sv]=XZ-filter +Name[ta]=XZ வடிகட்டி +Name[te]=జిజిప్ గలని +Name[tg]=Таровиши XZ +Name[th]=ตัวกรอง XZ +Name[tr]=XZ Filtresi +Name[tt]=XZ Sözgeçe +Name[uk]=Фільтр XZ +Name[uz]=XZ-filter +Name[uz@cyrillic]=XZ-филтер +Name[ven]=Filithara ya XZ +Name[vi]=Bộ lọc XZ +Name[wa]=Passete XZ +Name[xh]=Isihluzi se XZ +Name[zh_CN]=XZ 过滤程序 +Name[zh_HK]=XZ 過濾器 +Name[zh_TW]=XZ 過濾器 +Name[zu]=Ihluzo le-XZ +X-TDE-Library=kxzfilter +ServiceTypes=TDECompressionFilter,application/x-xz,application/x-txz,application/x-lzma diff --git a/tdeioslave/xz/kxzfilter.h b/tdeioslave/xz/kxzfilter.h new file mode 100644 index 000000000..b2ef164ae --- /dev/null +++ b/tdeioslave/xz/kxzfilter.h @@ -0,0 +1,60 @@ +/* This file is part of the KDE libraries + Copyright (C) 2007-2008 Per Øyvind Karlsen + + Based on kbzip2filter: + Copyright (C) 2000 David Faure + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KXZFILTER_H +#define KXZFILTER_H + +#include +#if HAVE_XZ_SUPPORT + +#include "kfilterbase.h" + +/** + * Internal class used by KFilterDev + * @internal + */ +class KXzFilter : public KFilterBase +{ +public: + KXzFilter(); + virtual ~KXzFilter(); + + virtual void init( int ); + virtual int mode() const; + virtual void terminate(); + virtual void reset(); + virtual bool readHeader() { return true; } // lzma handles it by itself ! Cool ! + virtual bool writeHeader( const TQCString & ) { return true; } + virtual void setOutBuffer( char * data, uint maxlen ); + virtual void setInBuffer( const char * data, uint size ); + virtual int inBufferAvailable() const; + virtual int outBufferAvailable() const; + virtual Result uncompress(); + virtual Result compress( bool finish ); +private: + class Private; + Private* const d; +}; + +#endif + +#endif // KXZFILTER_H