tdf#130857 qt weld: Implement QtInstanceWidget::get_text_height
[LibreOffice.git] / hwpfilter / source / hgzip.cxx
blobb1e96f9ba807bcb08f43cbf9332f453664021903
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "precompile.h"
22 #include <sal/types.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <stdlib.h>
26 #include <errno.h>
27 #include "hgzip.h"
28 #include "hstream.hxx"
30 #define Z_BUFSIZE (1024 * 4)
32 #define ALLOC(size) malloc(size)
33 #define TRYFREE(p) {if (p) free(p);}
35 static unsigned char get_byte(gz_stream * s);
36 static int destroy(gz_stream * s);
37 static bool getLongEquals(gz_stream* s, uLong value);
39 /* ===========================================================================
40 Opens a gzip (.gz) file for reading or writing. The mode parameter
41 is as in fopen ("rb" or "wb"). The file is given either by file descriptor
42 or path name (if fd == -1).
43 gz_open return NULL if the file could not be opened or if there was
44 insufficient memory to allocate the (de)compression state; errno
45 can be checked to distinguish the two cases (if errno is zero, the
46 zlib error is Z_MEM_ERROR).
48 gz_stream *gz_open(HStream & _stream)
50 int err;
51 //int level = Z_DEFAULT_COMPRESSION; /* compression level */
53 // char *p = (char*)mode;
54 //char fmode[80]; /* copy of mode, without the compression level */
55 //char *m = fmode;
56 gz_stream *s;
58 s = static_cast<gz_stream *>(ALLOC(sizeof(gz_stream)));
59 if (!s)
60 return Z_NULL;
61 s->stream.zalloc = nullptr;
62 s->stream.zfree = nullptr;
63 s->stream.opaque = nullptr;
64 s->stream.next_in = s->inbuf = Z_NULL;
65 s->stream.next_out = Z_NULL;
66 s->stream.avail_in = s->stream.avail_out = 0;
67 //s->_inputstream = NULL;
68 s->z_err = Z_OK;
69 s->z_eof = 0;
70 s->crc = crc32(0, Z_NULL, 0);
71 s->msg = nullptr;
73 s->mode = 'r';
75 //realking
76 err = inflateInit2(&(s->stream), -MAX_WBITS);
77 s->stream.next_in = s->inbuf = static_cast<Byte *>(ALLOC(Z_BUFSIZE));
79 if (err != Z_OK || s->inbuf == Z_NULL)
81 destroy(s);
82 return Z_NULL;
85 s->stream.avail_out = Z_BUFSIZE;
87 errno = 0;
88 s->_inputstream = &_stream;
90 return s;
94 /* ===========================================================================
95 Read a byte from a gz_stream; update next_in and avail_in. EOF is flagged
96 by setting z_eof.
97 IN assertion: the stream s has been successfully opened for reading.
99 static unsigned char get_byte(gz_stream * s)
101 if (s->z_eof)
102 return 0xFF;
103 if (s->stream.avail_in == 0)
105 errno = 0;
107 s->stream.avail_in = s->_inputstream->readBytes(s->inbuf, Z_BUFSIZE);
108 if (s->stream.avail_in == 0)
110 s->z_eof = 1;
111 return 0xFF;
113 s->stream.next_in = s->inbuf;
115 s->stream.avail_in--;
116 return *(s->stream.next_in)++;
120 /* ===========================================================================
121 * Cleanup then free the given gz_stream. Return a zlib error code.
122 * Try freeing in the reverse order of allocations.
124 static int destroy(gz_stream * s)
126 int err = Z_OK;
128 if (!s)
129 return Z_STREAM_ERROR;
131 TRYFREE(s->msg);
133 if (s->stream.state != nullptr)
135 err = inflateEnd(&(s->stream));
137 if (s->z_err < 0)
138 err = s->z_err;
140 TRYFREE(s->inbuf);
141 TRYFREE(s);
142 return err;
146 // typedef unsigned char Byte
147 // typedef Byte Bytef;
148 /* ===========================================================================
149 Reads the given number of uncompressed bytes from the compressed file.
150 gz_read returns the number of bytes actually read (0 for end of file).
152 size_t gz_read(gz_stream * file, voidp buf, unsigned len)
154 //printf("@@ gz_read : len : %d\t",len);
155 gz_stream *s = file;
156 Bytef *start = static_cast<Bytef *>(buf); /* starting point for crc computation */
157 if (s == nullptr)
158 return 0;
160 if (s->z_eof)
161 return 0;
163 if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO)
164 return 0;
165 if (s->z_err == Z_STREAM_END)
166 return 0; /* EOF */
168 s->stream.next_out = static_cast<Bytef *>(buf);
169 s->stream.avail_out = len;
171 while (s->stream.avail_out != 0)
173 if (s->stream.avail_in == 0 && !s->z_eof)
176 errno = 0;
177 s->stream.avail_in = s->_inputstream->readBytes(s->inbuf, Z_BUFSIZE);
178 if (s->stream.avail_in == 0)
180 s->z_eof = 1;
181 break;
183 s->stream.next_in = s->inbuf;
185 s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
187 if (s->z_err == Z_STREAM_END)
189 /* Check CRC and original size */
190 s->crc = crc32(s->crc, start, static_cast<uInt>(s->stream.next_out - start));
191 start = s->stream.next_out;
193 if (!getLongEquals(s, s->crc) || !getLongEquals(s, s->stream.total_out))
195 s->z_err = Z_DATA_ERROR;
197 else if (s->z_err == Z_OK)
199 inflateReset(&(s->stream));
200 s->crc = crc32(0, Z_NULL, 0);
203 if (s->z_err != Z_OK || s->z_eof)
204 break;
206 s->crc = crc32(s->crc, start, static_cast<uInt>(s->stream.next_out - start));
207 return len - s->stream.avail_out;
210 /* ===========================================================================
211 Flushes all pending output into the compressed file. The parameter
212 flush is as in the deflate() function.
213 gz_flush should be called only when strictly necessary because it can
214 degrade compression.
216 int gz_flush(gz_stream * file, int flush)
218 uInt len;
219 bool done = false;
220 gz_stream *s = file;
222 if (s == nullptr || s->mode != 'w')
223 return Z_STREAM_ERROR;
225 s->stream.avail_in = 0; /* should be zero already anyway */
227 for (;;)
229 len = Z_BUFSIZE - s->stream.avail_out;
230 if (len != 0)
233 if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) {
234 s->z_err = Z_ERRNO;
235 return Z_ERRNO;
238 s->stream.next_out = nullptr;
239 s->stream.avail_out = Z_BUFSIZE;
241 if (done)
242 break;
243 s->z_err = deflate(&(s->stream), flush);
245 /* deflate has finished flushing only when it hasn't used up
246 * all the available space in the output buffer:
248 done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END);
250 if (s->z_err != Z_OK && s->z_err != Z_STREAM_END)
251 break;
253 return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
257 /* ===========================================================================
258 Reads a long in LSB order from the given gz_stream and compares for equality
259 to val.
261 static bool getLongEquals(gz_stream* s, uLong val)
263 uLong x = get_byte(s);
264 x += static_cast<sal_uInt32>(get_byte(s)) << 8;
265 x += static_cast<sal_uInt32>(get_byte(s)) << 16;
266 x += static_cast<sal_uInt32>(get_byte(s)) << 24;
267 if (s->z_eof)
269 s->z_err = Z_DATA_ERROR;
270 return false;
272 return x == val;
276 /* ===========================================================================
277 Flushes all pending output if necessary, closes the compressed file
278 and deallocates all the (de)compression state.
280 int gz_close(gz_stream * file)
282 // int err;
283 gz_stream *s = file;
285 if (s == nullptr)
286 return Z_STREAM_ERROR;
287 #if 0
288 if (s->mode == 'w')
290 err = gz_flush(file, Z_FINISH);
291 if (err != Z_OK)
292 return destroy(s);
293 putLong(s->file, s->crc);
294 putLong(s->file, s->stream.total_in);
296 #endif
297 return destroy(s);
300 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */