File indexing completed on 2024-04-28 15:23:40

0001 /*
0002    This file is part of the KDE libraries
0003    Copyright (c) 2002 Waldo Bastian <bastian@kde.org>
0004    Copyright 2009 David Faure <faure@kde.org>
0005 
0006    This library is free software; you can redistribute it and/or
0007    modify it under the terms of the GNU Library General Public
0008    License version 2 as published by the Free Software Foundation.
0009 
0010    This library is distributed in the hope that it will be useful,
0011    but WITHOUT ANY WARRANTY; without even the implied warranty of
0012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0013    Library General Public License for more details.
0014 
0015    You should have received a copy of the GNU Library General Public License
0016    along with this library; see the file COPYING.LIB.  If not, write to
0017    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0018    Boston, MA 02110-1301, USA.
0019 */
0020 
0021 #include "httpfiltergzip_p.h"
0022 #include <kcompressiondevice.h>
0023 #include <kfilterbase.h>
0024 #include <KLocalizedString>
0025 #include "kmultipart_debug.h"
0026 
0027 HTTPFilterGZip::HTTPFilterGZip()
0028     : m_firstData(true),
0029       m_finished(false)
0030 {
0031     // We can't use KFilterDev because it assumes it can read as much data as necessary
0032     // from the underlying device. It's a pull strategy, while we have to do
0033     // a push strategy.
0034     m_gzipFilter = KCompressionDevice::filterForCompressionType(KCompressionDevice::GZip);
0035 }
0036 
0037 HTTPFilterGZip::~HTTPFilterGZip()
0038 {
0039     m_gzipFilter->terminate();
0040     delete m_gzipFilter;
0041 
0042 }
0043 
0044 /*
0045   The data format used by the zlib library is described by RFCs (Request for
0046   Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt
0047   (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
0048 
0049   Use /usr/include/zlib.h as the primary source of documentation though.
0050 */
0051 
0052 void
0053 HTTPFilterGZip::slotInput(const QByteArray &d)
0054 {
0055     if (d.isEmpty()) {
0056         return;
0057     }
0058 
0059     //qCDebug(KHTML_LOG) << "Got" << d.size() << "bytes as input";
0060     if (m_firstData) {
0061         m_gzipFilter->setFilterFlags(KFilterBase::WithHeaders);
0062         m_gzipFilter->init(QIODevice::ReadOnly);
0063         m_firstData = false;
0064     }
0065 
0066     m_gzipFilter->setInBuffer(d.constData(), d.size());
0067 
0068     while (!m_gzipFilter->inBufferEmpty() && !m_finished) {
0069         char buf[8192];
0070         m_gzipFilter->setOutBuffer(buf, sizeof(buf));
0071         KFilterBase::Result result = m_gzipFilter->uncompress();
0072         //qCDebug(KMULTIPART_LOG) << "uncompress returned" << result;
0073         switch (result) {
0074         case KFilterBase::Ok:
0075         case KFilterBase::End: {
0076             const int bytesOut = sizeof(buf) - m_gzipFilter->outBufferAvailable();
0077             if (bytesOut) {
0078                 emit output(QByteArray(buf, bytesOut));
0079             }
0080             if (result == KFilterBase::End) {
0081                 //qCDebug(KMULTIPART_LOG) << "done, bHasFinished=true";
0082                 emit output(QByteArray());
0083                 m_finished = true;
0084             }
0085             break;
0086         }
0087         case KFilterBase::Error:
0088             qCDebug(KMULTIPART_LOG) << "Error from KGZipFilter";
0089             emit error(i18n("Receiving corrupt data."));
0090             m_finished = true; // exit this while loop
0091             break;
0092         }
0093     }
0094 }
0095 
0096 #include "moc_httpfiltergzip_p.cpp"