File indexing completed on 2024-06-16 05:01:51
0001 /**************************************************************************** 0002 ** 0003 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). 0004 ** All rights reserved. 0005 ** Contact: Nokia Corporation (qt-info@nokia.com) 0006 ** 0007 ** This file is part of the Qt Messaging Framework. 0008 ** 0009 ** $QT_BEGIN_LICENSE:LGPL$ 0010 ** GNU Lesser General Public License Usage 0011 ** This file may be used under the terms of the GNU Lesser General Public 0012 ** License version 2.1 as published by the Free Software Foundation and 0013 ** appearing in the file LICENSE.LGPL included in the packaging of this 0014 ** file. Please review the following information to ensure the GNU Lesser 0015 ** General Public License version 2.1 requirements will be met: 0016 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 0017 ** 0018 ** In addition, as a special exception, Nokia gives you certain additional 0019 ** rights. These rights are described in the Nokia Qt LGPL Exception 0020 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 0021 ** 0022 ** GNU General Public License Usage 0023 ** Alternatively, this file may be used under the terms of the GNU General 0024 ** Public License version 3.0 as published by the Free Software Foundation 0025 ** and appearing in the file LICENSE.GPL included in the packaging of this 0026 ** file. Please review the following information to ensure the GNU General 0027 ** Public License version 3.0 requirements will be met: 0028 ** http://www.gnu.org/copyleft/gpl.html. 0029 ** 0030 ** Other Usage 0031 ** Alternatively, this file may be used in accordance with the terms and 0032 ** conditions contained in a signed written agreement between you and Nokia. 0033 ** 0034 ** 0035 ** 0036 ** 0037 ** 0038 ** $QT_END_LICENSE$ 0039 0040 This file contains modifications by Jan Kundrát <jkt@flaska.net> for use in Trojitá. 0041 These modifications are released into public domain. 0042 0043 ** 0044 ****************************************************************************/ 0045 0046 #include "rfc1951.h" 0047 0048 namespace Streams { 0049 0050 Rfc1951Compressor::Rfc1951Compressor(int chunkSize) 0051 { 0052 _chunkSize = chunkSize; 0053 _buffer = new char[chunkSize]; 0054 0055 /* allocate deflate state */ 0056 _zStream.zalloc = Z_NULL; 0057 _zStream.zfree = Z_NULL; 0058 _zStream.opaque = Z_NULL; 0059 0060 bool ok(deflateInit2(&_zStream, 0061 Z_DEFAULT_COMPRESSION, 0062 Z_DEFLATED, 0063 -(MAX_WBITS-2), // 32KB // MAX_WBITS == 15 (zconf.h) MEM128KB 0064 MAX_MEM_LEVEL-2 , // 64KB // MAX_MEM_LEVEL = 9 (zconf.h) MEM256KB 0065 Z_DEFAULT_STRATEGY) == Z_OK); 0066 Q_ASSERT(ok); Q_UNUSED(ok); 0067 } 0068 0069 Rfc1951Compressor::~Rfc1951Compressor() 0070 { 0071 delete[] _buffer; 0072 deflateEnd(&_zStream); 0073 } 0074 0075 bool Rfc1951Compressor::write(QIODevice *out, QByteArray *in) 0076 { 0077 _zStream.next_in = reinterpret_cast<Bytef*>(in->data()); 0078 _zStream.avail_in = in->size(); 0079 0080 do { 0081 _zStream.next_out = reinterpret_cast<Bytef*>(_buffer); 0082 _zStream.avail_out = _chunkSize; 0083 int result = deflate(&_zStream, Z_SYNC_FLUSH); 0084 if (result != Z_OK && 0085 result != Z_STREAM_END && 0086 result != Z_BUF_ERROR) { 0087 return false; 0088 } 0089 out->write(_buffer, _chunkSize - _zStream.avail_out); 0090 } while (!_zStream.avail_out); 0091 return true; 0092 } 0093 0094 0095 Rfc1951Decompressor::Rfc1951Decompressor(int chunkSize) 0096 { 0097 _chunkSize = chunkSize; 0098 _stagingBuffer = new char[_chunkSize]; 0099 0100 /* allocate inflate state */ 0101 _zStream.zalloc = Z_NULL; 0102 _zStream.zfree = Z_NULL; 0103 _zStream.opaque = Z_NULL; 0104 _zStream.avail_in = 0; 0105 _zStream.next_in = Z_NULL; 0106 bool ok(inflateInit2(&_zStream, -MAX_WBITS) == Z_OK); 0107 Q_ASSERT(ok); Q_UNUSED(ok); 0108 } 0109 0110 Rfc1951Decompressor::~Rfc1951Decompressor() 0111 { 0112 inflateEnd(&_zStream); 0113 delete[] _stagingBuffer; 0114 } 0115 0116 bool Rfc1951Decompressor::consume(QIODevice *in) 0117 { 0118 while (in->bytesAvailable()) { 0119 _inBuffer = in->read(_chunkSize); 0120 _zStream.next_in = reinterpret_cast<Bytef*>(_inBuffer.data()); 0121 _zStream.avail_in = _inBuffer.size(); 0122 do { 0123 _zStream.next_out = reinterpret_cast<Bytef *>(_stagingBuffer); 0124 _zStream.avail_out = _chunkSize; 0125 int result = inflate(&_zStream, Z_SYNC_FLUSH); 0126 if (result != Z_OK && 0127 result != Z_STREAM_END && 0128 result != Z_BUF_ERROR) { 0129 return false; 0130 } 0131 _output.append(_stagingBuffer, _chunkSize - _zStream.avail_out); 0132 } while (_zStream.avail_out == 0); 0133 } 0134 return true; 0135 } 0136 0137 bool Rfc1951Decompressor::canReadLine() const 0138 { 0139 return _output.contains('\n'); 0140 } 0141 0142 QByteArray Rfc1951Decompressor::readLine() 0143 { 0144 int eolPos = _output.indexOf('\n'); 0145 if (eolPos == -1) { 0146 return QByteArray(); 0147 } 0148 0149 QByteArray result = _output.left(eolPos + 1); 0150 _output = _output.mid(eolPos + 1); 0151 return result; 0152 } 0153 0154 QByteArray Rfc1951Decompressor::read(qint64 maxSize) 0155 { 0156 QByteArray res = _output.left(maxSize); 0157 _output = _output.mid(maxSize); 0158 return res; 0159 } 0160 0161 }