/***************************************************************************
- * Copyright (C) 2005-2018 by the Quassel Project *
+ * Copyright (C) 2005-2020 by the Quassel Project *
* devel@quassel-irc.org *
* *
* This program is free software; you can redistribute it and/or modify *
#include <QTcpSocket>
#include <QTimer>
-const int maxBufferSize = 64 * 1024 * 1024; // protect us from zip bombs
-const int ioBufferSize = 64 * 1024; // chunk size for inflate/deflate; should not be too large as we preallocate that space!
+const int maxBufferSize = 64 * 1024 * 1024; // protect us from zip bombs
+const int ioBufferSize = 64 * 1024; // chunk size for inflate/deflate; should not be too large as we preallocate that space!
-Compressor::Compressor(QTcpSocket *socket, Compressor::CompressionLevel level, QObject *parent)
- : QObject(parent),
- _socket(socket),
- _level(level),
- _inflater(nullptr),
- _deflater(nullptr)
+Compressor::Compressor(QTcpSocket* socket, Compressor::CompressionLevel level, QObject* parent)
+ : QObject(parent)
+ , _socket(socket)
+ , _level(level)
+ , _inflater(nullptr)
+ , _deflater(nullptr)
{
connect(socket, &QIODevice::readyRead, this, &Compressor::readData);
QTimer::singleShot(0, this, &Compressor::readData);
}
-
Compressor::~Compressor()
{
// release resources allocated by zlib
}
}
-
bool Compressor::initStreams()
{
int zlevel;
- switch(compressionLevel()) {
- case BestCompression:
- zlevel = 9;
- break;
- case BestSpeed:
- zlevel = 1;
- break;
- default:
- zlevel = Z_DEFAULT_COMPRESSION;
+ switch (compressionLevel()) {
+ case BestCompression:
+ zlevel = 9;
+ break;
+ case BestSpeed:
+ zlevel = 1;
+ break;
+ default:
+ zlevel = Z_DEFAULT_COMPRESSION;
}
_inflater = new z_stream;
return false;
}
- _inputBuffer.reserve(ioBufferSize); // pre-allocate space
- _outputBuffer.resize(ioBufferSize); // not a typo; we never change the size of this buffer anyway (we *do* for _inputBuffer!)
+ _inputBuffer.reserve(ioBufferSize); // pre-allocate space
+ _outputBuffer.resize(ioBufferSize); // not a typo; we never change the size of this buffer anyway (we *do* for _inputBuffer!)
qDebug() << "Enabling compression...";
return true;
}
-
-
qint64 Compressor::bytesAvailable() const
{
return _readBuffer.size();
}
-
-qint64 Compressor::read(char *data, qint64 maxSize)
+qint64 Compressor::read(char* data, qint64 maxSize)
{
if (maxSize <= 0)
maxSize = _readBuffer.size();
return n;
}
-
// The usual usage pattern is to write a blocksize first, followed by the actual data.
// By setting NoFlush, one can indicate that the write buffer should not immediately be
// written, which should make things a bit more efficient.
-qint64 Compressor::write(const char *data, qint64 count, WriteBufferHint flush)
+qint64 Compressor::write(const char* data, qint64 count, WriteBufferHint flush)
{
int pos = _writeBuffer.size();
_writeBuffer.resize(pos + count);
return count;
}
-
void Compressor::readData()
{
// don't try to read more data if we're already closing
- if (_socket->state() != QAbstractSocket::ConnectedState)
+ if (_socket->state() != QAbstractSocket::ConnectedState)
return;
if (!_socket->bytesAvailable() || _readBuffer.size() >= maxBufferSize)
_readBuffer.resize(_readBuffer.size() + ioBufferSize);
_inputBuffer.append(_socket->read(ioBufferSize - _inputBuffer.size()));
- _inflater->next_in = reinterpret_cast<unsigned char *>(_inputBuffer.data());
+ _inflater->next_in = reinterpret_cast<unsigned char*>(_inputBuffer.data());
_inflater->avail_in = _inputBuffer.size();
- _inflater->next_out = reinterpret_cast<unsigned char *>(_readBuffer.data() + _readBuffer.size() - ioBufferSize);
+ _inflater->next_out = reinterpret_cast<unsigned char*>(_readBuffer.data() + _readBuffer.size() - ioBufferSize);
_inflater->avail_out = ioBufferSize;
- const unsigned char *orig_out = _inflater->next_out; // so we see if we have actually produced any output
+ const unsigned char* orig_out = _inflater->next_out; // so we see if we have actually produced any output
- int status = inflate(_inflater, Z_SYNC_FLUSH); // get as much data as possible
+ int status = inflate(_inflater, Z_SYNC_FLUSH); // get as much data as possible
// adjust input and output buffers
- _readBuffer.resize(_inflater->next_out - reinterpret_cast<unsigned char *>(_readBuffer.data()));
+ _readBuffer.resize(_inflater->next_out - reinterpret_cast<unsigned char*>(_readBuffer.data()));
if (_inflater->avail_in > 0)
memmove(_inputBuffer.data(), _inflater->next_in, _inflater->avail_in);
_inputBuffer.resize(_inflater->avail_in);
if (_inflater->next_out != orig_out)
emit readyRead();
- switch(status) {
- case Z_NEED_DICT:
- case Z_DATA_ERROR:
- case Z_MEM_ERROR:
- case Z_STREAM_ERROR:
- qWarning() << "Error while decompressing stream:" << status;
- emit error(StreamError);
- return;
- case Z_BUF_ERROR:
- // means that we need more input to continue, so this is not an actual error
- return;
- case Z_STREAM_END:
- qWarning() << "Reached end of zlib stream!"; // this should really never happen
- return;
- default:
- // just try to get more out of the stream
- break;
+ switch (status) {
+ case Z_NEED_DICT:
+ case Z_DATA_ERROR:
+ case Z_MEM_ERROR:
+ case Z_STREAM_ERROR:
+ qWarning() << "Error while decompressing stream:" << status;
+ emit error(StreamError);
+ return;
+ case Z_BUF_ERROR:
+ // means that we need more input to continue, so this is not an actual error
+ return;
+ case Z_STREAM_END:
+ qWarning() << "Reached end of zlib stream!"; // this should really never happen
+ return;
+ default:
+ // just try to get more out of the stream
+ break;
}
}
- //qDebug() << "inflate in:" << _inflater->total_in << "out:" << _inflater->total_out << "ratio:" << (double)_inflater->total_in/_inflater->total_out;
+ // qDebug() << "inflate in:" << _inflater->total_in << "out:" << _inflater->total_out << "ratio:" << (double)_inflater->total_in/_inflater->total_out;
}
-
void Compressor::writeData()
{
if (compressionLevel() == NoCompression) {
return;
}
- _deflater->next_in = reinterpret_cast<unsigned char *>(_writeBuffer.data());
+ _deflater->next_in = reinterpret_cast<unsigned char*>(_writeBuffer.data());
_deflater->avail_in = _writeBuffer.size();
int status;
do {
- _deflater->next_out = reinterpret_cast<unsigned char *>(_outputBuffer.data());
+ _deflater->next_out = reinterpret_cast<unsigned char*>(_outputBuffer.data());
_deflater->avail_out = ioBufferSize;
status = deflate(_deflater, Z_PARTIAL_FLUSH);
if (status != Z_OK && status != Z_BUF_ERROR) {
}
if (_deflater->avail_out == static_cast<unsigned int>(ioBufferSize))
- continue; // nothing to write here
+ continue; // nothing to write here
if (!_socket->write(_outputBuffer.constData(), ioBufferSize - _deflater->avail_out)) {
qWarning() << "Error while writing to socket:" << _socket->errorString();
emit error(DeviceError);
return;
}
- } while (_deflater->avail_out == 0); // the output buffer being full is the only reason we should have to loop here!
+ } while (_deflater->avail_out == 0); // the output buffer being full is the only reason we should have to loop here!
if (_deflater->avail_in > 0) {
qWarning() << "Oops, something weird happened: data still remaining in write buffer!";
_writeBuffer.resize(0);
- //qDebug() << "deflate in:" << _deflater->total_in << "out:" << _deflater->total_out << "ratio:" << (double)_deflater->total_out/_deflater->total_in;
+ // qDebug() << "deflate in:" << _deflater->total_in << "out:" << _deflater->total_out << "ratio:" << (double)_deflater->total_out/_deflater->total_in;
}
-
void Compressor::flush()
{
if (compressionLevel() == NoCompression && _socket->state() == QAbstractSocket::ConnectedState)