File indexing completed on 2024-06-23 04:03:44

0001 #include "xmpp/zlib/zlibcompressor.h"
0002 
0003 #include <QtDebug>
0004 #include <QIODevice>
0005 #include <zlib.h>
0006 
0007 #include "common.h"
0008 
0009 ZLibCompressor::ZLibCompressor(QIODevice* device, int compression) : device_(device)
0010 {
0011     zlib_stream_ = (z_stream*) malloc(sizeof(z_stream));
0012     initZStream(zlib_stream_);
0013     int result = deflateInit(zlib_stream_, compression);
0014     Q_ASSERT(result == Z_OK);
0015     Q_UNUSED(result);
0016     connect(device, &QIODevice::aboutToClose, this, &ZLibCompressor::flush);
0017     flushed_ = false;
0018 }
0019 
0020 ZLibCompressor::~ZLibCompressor()
0021 {
0022     flush();
0023     free(zlib_stream_);
0024 }
0025 
0026 void ZLibCompressor::flush()
0027 {
0028     if (flushed_)
0029         return;
0030     
0031     // Flush
0032     write(QByteArray(),true);
0033     int result = deflateEnd(zlib_stream_);
0034     if (result != Z_OK) 
0035         qWarning("compressor.c: deflateEnd failed (%d)", result);
0036     
0037     flushed_ = true;
0038 }
0039 
0040 int ZLibCompressor::write(const QByteArray& input)
0041 {
0042     return write(input,false);
0043 }
0044 
0045 int ZLibCompressor::write(const QByteArray& input, bool flush)
0046 {
0047     int result;
0048     zlib_stream_->avail_in = input.size();
0049     zlib_stream_->next_in = (Bytef*) input.data();
0050     QByteArray output;
0051 
0052     // Write the data
0053     int output_position = 0;
0054     do {
0055         output.resize(output_position + CHUNK_SIZE);
0056         zlib_stream_->avail_out = CHUNK_SIZE;
0057         zlib_stream_->next_out = (Bytef*) (output.data() + output_position);
0058         result = deflate(zlib_stream_,(flush ? Z_FINISH : Z_NO_FLUSH));
0059         if (result == Z_STREAM_ERROR) {
0060             qWarning("compressor.cpp: Error ('%s')", zlib_stream_->msg);
0061             return result;
0062         }
0063         output_position += CHUNK_SIZE;
0064     }
0065     while (zlib_stream_->avail_out == 0);
0066     if (zlib_stream_->avail_in != 0) {
0067         qWarning("ZLibCompressor: avail_in != 0");
0068     }
0069     output_position -= zlib_stream_->avail_out;
0070 
0071     // Flush the data
0072     if (!flush) {
0073         do {
0074             output.resize(output_position + CHUNK_SIZE);
0075             zlib_stream_->avail_out = CHUNK_SIZE;
0076             zlib_stream_->next_out = (Bytef*) (output.data() + output_position);
0077             result = deflate(zlib_stream_,Z_SYNC_FLUSH);
0078             if (result == Z_STREAM_ERROR) {
0079                 qWarning("compressor.cpp: Error ('%s')", zlib_stream_->msg);
0080                 return result;
0081             }
0082             output_position += CHUNK_SIZE;
0083         }
0084         while (zlib_stream_->avail_out == 0);
0085         output_position -= zlib_stream_->avail_out;
0086     }
0087     output.resize(output_position);
0088 
0089     // Write the compressed data
0090     device_->write(output);
0091     return 0;
0092 }