File indexing completed on 2025-02-16 13:00:36
0001 /* This file is part of the KDE libraries 0002 SPDX-FileCopyrightText: 2000-2005 David Faure <faure@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "kbzip2filter.h" 0008 #include "loggingcategory.h" 0009 0010 #if HAVE_BZIP2_SUPPORT 0011 0012 // we don't need that 0013 #define BZ_NO_STDIO 0014 extern "C" { 0015 #include <bzlib.h> 0016 } 0017 0018 #if NEED_BZ2_PREFIX 0019 #define bzDecompressInit(x, y, z) BZ2_bzDecompressInit(x, y, z) 0020 #define bzDecompressEnd(x) BZ2_bzDecompressEnd(x) 0021 #define bzCompressEnd(x) BZ2_bzCompressEnd(x) 0022 #define bzDecompress(x) BZ2_bzDecompress(x) 0023 #define bzCompress(x, y) BZ2_bzCompress(x, y) 0024 #define bzCompressInit(x, y, z, a) BZ2_bzCompressInit(x, y, z, a); 0025 #endif 0026 0027 #include <QDebug> 0028 0029 #include <QIODevice> 0030 0031 // For docu on this, see /usr/doc/bzip2-0.9.5d/bzip2-0.9.5d/manual_3.html 0032 0033 class Q_DECL_HIDDEN KBzip2Filter::Private 0034 { 0035 public: 0036 Private() 0037 : isInitialized(false) 0038 { 0039 memset(&zStream, 0, sizeof(zStream)); 0040 mode = 0; 0041 } 0042 0043 bz_stream zStream; 0044 int mode; 0045 bool isInitialized; 0046 }; 0047 0048 KBzip2Filter::KBzip2Filter() 0049 : d(new Private) 0050 { 0051 } 0052 0053 KBzip2Filter::~KBzip2Filter() 0054 { 0055 delete d; 0056 } 0057 0058 bool KBzip2Filter::init(int mode) 0059 { 0060 if (d->isInitialized) { 0061 terminate(); 0062 } 0063 0064 d->zStream.next_in = nullptr; 0065 d->zStream.avail_in = 0; 0066 if (mode == QIODevice::ReadOnly) { 0067 const int result = bzDecompressInit(&d->zStream, 0, 0); 0068 if (result != BZ_OK) { 0069 // qCDebug(KArchiveLog) << "bzDecompressInit returned " << result; 0070 return false; 0071 } 0072 } else if (mode == QIODevice::WriteOnly) { 0073 const int result = bzCompressInit(&d->zStream, 5, 0, 0); 0074 if (result != BZ_OK) { 0075 // qCDebug(KArchiveLog) << "bzDecompressInit returned " << result; 0076 return false; 0077 } 0078 } else { 0079 // qCWarning(KArchiveLog) << "Unsupported mode " << mode << ". Only QIODevice::ReadOnly and QIODevice::WriteOnly supported"; 0080 return false; 0081 } 0082 d->mode = mode; 0083 d->isInitialized = true; 0084 return true; 0085 } 0086 0087 int KBzip2Filter::mode() const 0088 { 0089 return d->mode; 0090 } 0091 0092 bool KBzip2Filter::terminate() 0093 { 0094 if (d->mode == QIODevice::ReadOnly) { 0095 const int result = bzDecompressEnd(&d->zStream); 0096 if (result != BZ_OK) { 0097 // qCDebug(KArchiveLog) << "bzDecompressEnd returned " << result; 0098 return false; 0099 } 0100 } else if (d->mode == QIODevice::WriteOnly) { 0101 const int result = bzCompressEnd(&d->zStream); 0102 if (result != BZ_OK) { 0103 // qCDebug(KArchiveLog) << "bzCompressEnd returned " << result; 0104 return false; 0105 } 0106 } else { 0107 // qCWarning(KArchiveLog) << "Unsupported mode " << d->mode << ". Only QIODevice::ReadOnly and QIODevice::WriteOnly supported"; 0108 return false; 0109 } 0110 d->isInitialized = false; 0111 return true; 0112 } 0113 0114 void KBzip2Filter::reset() 0115 { 0116 // bzip2 doesn't seem to have a reset call... 0117 terminate(); 0118 init(d->mode); 0119 } 0120 0121 void KBzip2Filter::setOutBuffer(char *data, uint maxlen) 0122 { 0123 d->zStream.avail_out = maxlen; 0124 d->zStream.next_out = data; 0125 } 0126 0127 void KBzip2Filter::setInBuffer(const char *data, unsigned int size) 0128 { 0129 d->zStream.avail_in = size; 0130 d->zStream.next_in = const_cast<char *>(data); 0131 } 0132 0133 int KBzip2Filter::inBufferAvailable() const 0134 { 0135 return d->zStream.avail_in; 0136 } 0137 0138 int KBzip2Filter::outBufferAvailable() const 0139 { 0140 return d->zStream.avail_out; 0141 } 0142 0143 KBzip2Filter::Result KBzip2Filter::uncompress() 0144 { 0145 // qCDebug(KArchiveLog) << "Calling bzDecompress with avail_in=" << inBufferAvailable() << " avail_out=" << outBufferAvailable(); 0146 int result = bzDecompress(&d->zStream); 0147 if (result < BZ_OK) { 0148 qCWarning(KArchiveLog) << "bzDecompress returned" << result; 0149 } 0150 0151 switch (result) { 0152 case BZ_OK: 0153 return KFilterBase::Ok; 0154 case BZ_STREAM_END: 0155 return KFilterBase::End; 0156 default: 0157 return KFilterBase::Error; 0158 } 0159 } 0160 0161 KBzip2Filter::Result KBzip2Filter::compress(bool finish) 0162 { 0163 // qCDebug(KArchiveLog) << "Calling bzCompress with avail_in=" << inBufferAvailable() << " avail_out=" << outBufferAvailable(); 0164 int result = bzCompress(&d->zStream, finish ? BZ_FINISH : BZ_RUN); 0165 0166 switch (result) { 0167 case BZ_OK: 0168 case BZ_FLUSH_OK: 0169 case BZ_RUN_OK: 0170 case BZ_FINISH_OK: 0171 return KFilterBase::Ok; 0172 break; 0173 case BZ_STREAM_END: 0174 // qCDebug(KArchiveLog) << " bzCompress returned " << result; 0175 return KFilterBase::End; 0176 break; 0177 default: 0178 // qCDebug(KArchiveLog) << " bzCompress returned " << result; 0179 return KFilterBase::Error; 0180 break; 0181 } 0182 } 0183 0184 #endif /* HAVE_BZIP2_SUPPORT */