Remove unused header include
[xapian.git] / xapian-core / common / compression_stream.cc
blob4da863da99ef3484e4d1409201cbf43722e2fc66
1 /** @file compression_stream.cc
2 * @brief class wrapper around zlib
3 */
4 /* Copyright (C) 2007,2009,2012,2013,2014,2016 Olly Betts
5 * Copyright (C) 2009 Richard Boulton
6 * Copyright (C) 2012 Dan Colish
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 #include <config.h>
24 #include "compression_stream.h"
26 #include "omassert.h"
27 #include "str.h"
28 #include "stringutils.h"
30 #include "xapian/error.h"
32 using namespace std;
34 CompressionStream::~CompressionStream() {
35 if (deflate_zstream) {
36 // Errors which we care about have already been handled, so just ignore
37 // any which get returned here.
38 (void) deflateEnd(deflate_zstream);
39 delete deflate_zstream;
42 if (inflate_zstream) {
43 // Errors which we care about have already been handled, so just ignore
44 // any which get returned here.
45 (void) inflateEnd(inflate_zstream);
46 delete inflate_zstream;
49 delete [] out;
52 const char*
53 CompressionStream::compress(const char* buf, size_t* p_size) {
54 lazy_alloc_deflate_zstream();
55 size_t size = *p_size;
56 if (!out || out_len < size - 1) {
57 delete [] out;
58 out = NULL;
59 out_len = size - 1;
60 out = new char[out_len];
62 deflate_zstream->avail_in = (uInt)size;
63 deflate_zstream->next_in = (Bytef*)const_cast<char*>(buf);
64 deflate_zstream->next_out = (Bytef*)out;
65 deflate_zstream->avail_out = (uInt)(size - 1);
66 int zerr = deflate(deflate_zstream, Z_FINISH);
67 if (zerr != Z_STREAM_END) {
68 // Deflate failed - presumably the data wasn't compressible.
69 return NULL;
72 // If deflate succeeded, then the output was at least one byte smaller than
73 // the input.
75 *p_size = deflate_zstream->total_out;
76 return out;
79 bool
80 CompressionStream::decompress_chunk(const char* p, int len, string & buf)
82 Bytef blk[8192];
84 inflate_zstream->next_in = (Bytef*)const_cast<char*>(p);
85 inflate_zstream->avail_in = (uInt)len;
87 while (true) {
88 inflate_zstream->next_out = blk;
89 inflate_zstream->avail_out = (uInt)sizeof(blk);
90 int err = inflate(inflate_zstream, Z_SYNC_FLUSH);
91 if (err != Z_OK && err != Z_STREAM_END) {
92 if (err == Z_MEM_ERROR) throw std::bad_alloc();
93 string msg = "inflate failed";
94 if (inflate_zstream->msg) {
95 msg += " (";
96 msg += inflate_zstream->msg;
97 msg += ')';
99 throw Xapian::DatabaseError(msg);
102 buf.append(reinterpret_cast<const char *>(blk),
103 inflate_zstream->next_out - blk);
104 if (err == Z_STREAM_END) return true;
105 if (inflate_zstream->avail_in == 0) return false;
109 void
110 CompressionStream::lazy_alloc_deflate_zstream() {
111 if (usual(deflate_zstream)) {
112 if (usual(deflateReset(deflate_zstream) == Z_OK)) return;
113 // Try to recover by deleting the stream and starting from scratch.
114 delete deflate_zstream;
117 deflate_zstream = new z_stream;
119 deflate_zstream->zalloc = reinterpret_cast<alloc_func>(0);
120 deflate_zstream->zfree = reinterpret_cast<free_func>(0);
121 deflate_zstream->opaque = (voidpf)0;
123 // -15 means raw deflate with 32K LZ77 window (largest)
124 // memLevel 9 is the highest (8 is default)
125 int err = deflateInit2(deflate_zstream, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
126 -15, 9, compress_strategy);
127 if (rare(err != Z_OK)) {
128 if (err == Z_MEM_ERROR) {
129 delete deflate_zstream;
130 deflate_zstream = 0;
131 throw std::bad_alloc();
133 string msg = "deflateInit2 failed (";
134 if (deflate_zstream->msg) {
135 msg += deflate_zstream->msg;
136 } else {
137 msg += str(err);
139 msg += ')';
140 delete deflate_zstream;
141 deflate_zstream = 0;
142 throw Xapian::DatabaseError(msg);
146 void
147 CompressionStream::lazy_alloc_inflate_zstream() {
148 if (usual(inflate_zstream)) {
149 if (usual(inflateReset(inflate_zstream) == Z_OK)) return;
150 // Try to recover by deleting the stream and starting from scratch.
151 delete inflate_zstream;
154 inflate_zstream = new z_stream;
156 inflate_zstream->zalloc = reinterpret_cast<alloc_func>(0);
157 inflate_zstream->zfree = reinterpret_cast<free_func>(0);
159 inflate_zstream->next_in = Z_NULL;
160 inflate_zstream->avail_in = 0;
162 int err = inflateInit2(inflate_zstream, -15);
163 if (rare(err != Z_OK)) {
164 if (err == Z_MEM_ERROR) {
165 delete inflate_zstream;
166 inflate_zstream = 0;
167 throw std::bad_alloc();
169 string msg = "inflateInit2 failed (";
170 if (inflate_zstream->msg) {
171 msg += inflate_zstream->msg;
172 } else {
173 msg += str(err);
175 msg += ')';
176 delete inflate_zstream;
177 inflate_zstream = 0;
178 throw Xapian::DatabaseError(msg);