~ubuntu-branches/ubuntu/jaunty/psi/jaunty

« back to all changes in this revision

Viewing changes to iris/xmpp-core/compress.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jan Niehusmann
  • Date: 2008-04-14 18:57:30 UTC
  • mfrom: (2.1.9 hardy)
  • Revision ID: james.westby@ubuntu.com-20080414185730-528re3zp0m2hdlhi
Tags: 0.11-8
* added CONFIG -= link_prl to .pro files and removed dependencies
  which are made unnecessary by this change
* Fix segfault when closing last chat tab with qt4.4
  (This is from upstream svn, rev. 1101) (Closes: Bug#476122)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <QtCore> // for qWarning()
 
2
#include <QObject>
 
3
#include <QIODevice>
 
4
#include <zlib.h>
 
5
 
 
6
#include "compress.h"
 
7
 
 
8
#define CHUNK_SIZE 1024
 
9
 
 
10
Compressor::Compressor(QIODevice* device, int compression) : device_(device)
 
11
{
 
12
        zlib_stream_ = (z_stream*) malloc(sizeof(z_stream));
 
13
        zlib_stream_->zalloc = Z_NULL;
 
14
        zlib_stream_->zfree = Z_NULL;
 
15
        zlib_stream_->opaque = Z_NULL;
 
16
        int result = deflateInit(zlib_stream_, compression);
 
17
        Q_ASSERT(result == Z_OK);
 
18
        Q_UNUSED(result);
 
19
        connect(device, SIGNAL(aboutToClose()), this, SLOT(flush()));
 
20
        flushed_ = false;
 
21
}
 
22
 
 
23
Compressor::~Compressor()
 
24
{
 
25
        flush();
 
26
}
 
27
 
 
28
void Compressor::flush()
 
29
{
 
30
        if (flushed_)
 
31
                return;
 
32
        
 
33
        // Flush
 
34
        write(QByteArray(),true);
 
35
        int result = deflateEnd(zlib_stream_);
 
36
        if (result != Z_OK) 
 
37
                qWarning(QString("compressor.c: deflateEnd failed (%1)").arg(result).toAscii());
 
38
        
 
39
        flushed_ = true;
 
40
}
 
41
 
 
42
int Compressor::write(const QByteArray& input)
 
43
{
 
44
        return write(input,false);
 
45
}
 
46
 
 
47
int Compressor::write(const QByteArray& input, bool flush)
 
48
{
 
49
        int result;
 
50
        zlib_stream_->avail_in = input.size();
 
51
        zlib_stream_->next_in = (Bytef*) input.data();
 
52
        QByteArray output;
 
53
 
 
54
        // Write the data
 
55
        int output_position = 0;
 
56
        do {
 
57
                output.resize(output_position + CHUNK_SIZE);
 
58
                zlib_stream_->avail_out = CHUNK_SIZE;
 
59
                zlib_stream_->next_out = (Bytef*) (output.data() + output_position);
 
60
                result = deflate(zlib_stream_,(flush ? Z_FINISH : Z_NO_FLUSH));
 
61
                if (result == Z_STREAM_ERROR) {
 
62
                        qWarning(QString("compressor.cpp: Error ('%1')").arg(zlib_stream_->msg).toAscii());
 
63
                        return result;
 
64
                }
 
65
                output_position += CHUNK_SIZE;
 
66
        }
 
67
        while (zlib_stream_->avail_out == 0);
 
68
        if (zlib_stream_->avail_in != 0) {
 
69
                qWarning("Compressor: avail_in != 0");
 
70
        }
 
71
        output_position -= zlib_stream_->avail_out;
 
72
 
 
73
        // Flush the data
 
74
        if (!flush) {
 
75
                do {
 
76
                        output.resize(output_position + CHUNK_SIZE);
 
77
                        zlib_stream_->avail_out = CHUNK_SIZE;
 
78
                        zlib_stream_->next_out = (Bytef*) (output.data() + output_position);
 
79
                        result = deflate(zlib_stream_,Z_SYNC_FLUSH);
 
80
                        if (result == Z_STREAM_ERROR) {
 
81
                                qWarning(QString("compressor.cpp: Error ('%1')").arg(zlib_stream_->msg).toAscii());
 
82
                                return result;
 
83
                        }
 
84
                        output_position += CHUNK_SIZE;
 
85
                }
 
86
                while (zlib_stream_->avail_out == 0);
 
87
                output_position -= zlib_stream_->avail_out;
 
88
        }
 
89
        output.resize(output_position);
 
90
 
 
91
        // Write the compressed data
 
92
        device_->write(output);
 
93
        return 0;
 
94
}
 
95
 
 
96
// -----------------------------------------------------------------------------
 
97
 
 
98
Decompressor::Decompressor(QIODevice* device) : device_(device)
 
99
{
 
100
        zlib_stream_ = (z_stream*) malloc(sizeof(z_stream));
 
101
        zlib_stream_->zalloc = Z_NULL;
 
102
        zlib_stream_->zfree = Z_NULL;
 
103
        zlib_stream_->opaque = Z_NULL;
 
104
        int result = inflateInit(zlib_stream_);
 
105
        Q_ASSERT(result == Z_OK);
 
106
        Q_UNUSED(result);
 
107
        connect(device, SIGNAL(aboutToClose()), this, SLOT(flush()));
 
108
        flushed_ = false;
 
109
}
 
110
 
 
111
Decompressor::~Decompressor()
 
112
{
 
113
        flush();
 
114
}
 
115
 
 
116
void Decompressor::flush()
 
117
{
 
118
        if (flushed_)
 
119
                return;
 
120
        
 
121
        // Flush
 
122
        write(QByteArray(),true);
 
123
        int result = inflateEnd(zlib_stream_);
 
124
        if (result != Z_OK) 
 
125
                qWarning(QString("compressor.c: inflateEnd failed (%1)").arg(result).toAscii());
 
126
        
 
127
        flushed_ = true;
 
128
}
 
129
 
 
130
int Decompressor::write(const QByteArray& input)
 
131
{
 
132
        return write(input,false);
 
133
}
 
134
 
 
135
int Decompressor::write(const QByteArray& input, bool flush)
 
136
{
 
137
        int result;
 
138
        zlib_stream_->avail_in = input.size();
 
139
        zlib_stream_->next_in = (Bytef*) input.data();
 
140
        QByteArray output;
 
141
 
 
142
        // Write the data
 
143
        int output_position = 0;
 
144
        do {
 
145
                output.resize(output_position + CHUNK_SIZE);
 
146
                zlib_stream_->avail_out = CHUNK_SIZE;
 
147
                zlib_stream_->next_out = (Bytef*) (output.data() + output_position);
 
148
                result = inflate(zlib_stream_,(flush ? Z_FINISH : Z_NO_FLUSH));
 
149
                if (result == Z_STREAM_ERROR) {
 
150
                        qWarning(QString("compressor.cpp: Error ('%1')").arg(zlib_stream_->msg).toAscii());
 
151
                        return result;
 
152
                }
 
153
                output_position += CHUNK_SIZE;
 
154
        }
 
155
        while (zlib_stream_->avail_out == 0);
 
156
        //Q_ASSERT(zlib_stream_->avail_in == 0);
 
157
        if (zlib_stream_->avail_in != 0) {
 
158
                qWarning() << "Decompressor: Unexpected state: avail_in=" << zlib_stream_->avail_in << ",avail_out=" << zlib_stream_->avail_out << ",result=" << result;
 
159
                return Z_STREAM_ERROR; // FIXME: Should probably return 'result'
 
160
        }
 
161
        output_position -= zlib_stream_->avail_out;
 
162
 
 
163
        // Flush the data
 
164
        if (!flush) {
 
165
                do {
 
166
                        output.resize(output_position + CHUNK_SIZE);
 
167
                        zlib_stream_->avail_out = CHUNK_SIZE;
 
168
                        zlib_stream_->next_out = (Bytef*) (output.data() + output_position);
 
169
                        result = inflate(zlib_stream_,Z_SYNC_FLUSH);
 
170
                        if (result == Z_STREAM_ERROR) {
 
171
                                qWarning(QString("compressor.cpp: Error ('%1')").arg(zlib_stream_->msg).toAscii());
 
172
                                return result;
 
173
                        }
 
174
                        output_position += CHUNK_SIZE;
 
175
                }
 
176
                while (zlib_stream_->avail_out == 0);
 
177
                output_position -= zlib_stream_->avail_out;
 
178
        }
 
179
        output.resize(output_position);
 
180
 
 
181
        // Write the compressed data
 
182
        device_->write(output);
 
183
        return 0;
 
184
}