~ubuntu-branches/ubuntu/wily/psi/wily

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Jan Niehusmann
  • Date: 2009-09-25 17:49:51 UTC
  • mfrom: (6.1.3 sid)
  • Revision ID: james.westby@ubuntu.com-20090925174951-lvm7kdap82o8xhn3
Tags: 0.13-1
* Updated to upstream version 0.13
* Set Standards-Version to 3.8.3

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