merged tag ooo/DEV300_m102
[LibreOffice.git] / hwpfilter / source / hgzip.cpp
blob93aa889cfcaad6ee1253cd9d11ef2e554d45816c
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 #include "precompile.h"
30 #include <stdio.h>
31 #include <string.h>
32 #include <stdlib.h>
33 #include <errno.h>
34 #include "hgzip.h"
35 #include "hstream.h"
37 #ifndef local
38 # define local static
39 #endif
41 #define Z_BUFSIZE (1024 * 4)
43 #define ALLOC(size) malloc(size)
44 #define TRYFREE(p) {if (p) free(p);}
46 #define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
47 #define HEAD_CRC 0x02 /* bit 1 set: header CRC present */
48 #define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
49 #define ORIG_NAME 0x08 /* bit 3 set: original file name present */
50 #define COMMENT 0x10 /* bit 4 set: file comment present */
51 #define RESERVED 0xE0 /* bits 5..7: reserved */
53 local int get_byte(gz_stream * s);
54 local int destroy(gz_stream * s);
55 local uLong getLong(gz_stream * s);
57 /* ===========================================================================
58 Opens a gzip (.gz) file for reading or writing. The mode parameter
59 is as in fopen ("rb" or "wb"). The file is given either by file descriptor
60 or path name (if fd == -1).
61 gz_open return NULL if the file could not be opened or if there was
62 insufficient memory to allocate the (de)compression state; errno
63 can be checked to distinguish the two cases (if errno is zero, the
64 zlib error is Z_MEM_ERROR).
66 gz_stream *gz_open(HStream & _stream)
68 int err;
69 //int level = Z_DEFAULT_COMPRESSION; /* compression level */
71 // char *p = (char*)mode;
72 //char fmode[80]; /* copy of mode, without the compression level */
73 //char *m = fmode;
74 gz_stream *s;
76 s = (gz_stream *) ALLOC(sizeof(gz_stream));
77 if (!s)
78 return Z_NULL;
79 s->stream.zalloc = (alloc_func) 0;
80 s->stream.zfree = (free_func) 0;
81 s->stream.opaque = (voidpf) 0;
82 s->stream.next_in = s->inbuf = Z_NULL;
83 s->stream.next_out = s->outbuf = Z_NULL;
84 s->stream.avail_in = s->stream.avail_out = 0;
85 //s->_inputstream = NULL;
86 s->z_err = Z_OK;
87 s->z_eof = 0;
88 s->crc = crc32(0L, Z_NULL, 0);
89 s->msg = NULL;
90 s->transparent = 0;
92 s->mode = 'r';
94 //realking
95 err = inflateInit2(&(s->stream), -MAX_WBITS);
96 s->stream.next_in = s->inbuf = (Byte *) ALLOC(Z_BUFSIZE);
98 if (err != Z_OK || s->inbuf == Z_NULL)
100 return destroy(s), (gz_stream *) Z_NULL;
103 s->stream.avail_out = Z_BUFSIZE;
105 errno = 0;
106 s->_inputstream = &_stream;
108 return (gz_stream *) s;
112 /* ===========================================================================
113 Read a byte from a gz_stream; update next_in and avail_in. Return EOF
114 for end of file.
115 IN assertion: the stream s has been sucessfully opened for reading.
117 local int get_byte(gz_stream * s)
119 if (s->z_eof)
120 return EOF;
121 if (s->stream.avail_in == 0)
123 errno = 0;
125 s->stream.avail_in = s->_inputstream->readBytes(s->inbuf, Z_BUFSIZE);
126 if (s->stream.avail_in == 0)
128 s->z_eof = 1;
129 return EOF;
131 s->stream.next_in = s->inbuf;
133 s->stream.avail_in--;
134 return *(s->stream.next_in)++;
138 /* ===========================================================================
139 * Cleanup then free the given gz_stream. Return a zlib error code.
140 * Try freeing in the reverse order of allocations.
142 local int destroy(gz_stream * s)
144 int err = Z_OK;
146 if (!s)
147 return Z_STREAM_ERROR;
149 TRYFREE(s->msg);
151 if (s->stream.state != NULL)
153 err = inflateEnd(&(s->stream));
155 if (s->z_err < 0)
156 err = s->z_err;
158 TRYFREE(s->inbuf);
159 TRYFREE(s->outbuf);
160 TRYFREE(s);
161 return err;
165 // typedef unsigned char Byte
166 // typedef Byte FAR Bytef;
167 /* ===========================================================================
168 Reads the given number of uncompressed bytes from the compressed file.
169 gz_read returns the number of bytes actually read (0 for end of file).
171 int gz_read(gz_stream * file, voidp buf, unsigned len)
173 //printf("@@ gz_read : len : %d\t",len);
174 gz_stream *s = (gz_stream *) file;
175 Bytef *start = (Bytef *) buf; /* starting point for crc computation */
176 Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */
177 if (s == NULL)
178 return Z_STREAM_ERROR;
180 if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO)
181 return -1;
182 if (s->z_err == Z_STREAM_END)
183 return 0; /* EOF */
185 s->stream.next_out = next_out = (Bytef *) buf;
186 s->stream.avail_out = len;
188 while (s->stream.avail_out != 0)
190 if (s->transparent)
192 /* Copy first the lookahead bytes: */
193 uInt n = s->stream.avail_in;
195 if (n > s->stream.avail_out)
196 n = s->stream.avail_out;
197 if (n > 0)
199 memcpy(s->stream.next_out, s->stream.next_in, n);
200 next_out += n;
201 s->stream.next_out = next_out;
202 s->stream.next_in += n;
203 s->stream.avail_out -= n;
204 s->stream.avail_in -= n;
206 if (s->stream.avail_out > 0)
208 s->stream.avail_out -=
209 s->_inputstream->readBytes(next_out, s->stream.avail_out);
211 return (int) (len - s->stream.avail_out);
213 if (s->stream.avail_in == 0 && !s->z_eof)
216 errno = 0;
217 s->stream.avail_in = s->_inputstream->readBytes(s->inbuf, Z_BUFSIZE);
218 if (s->stream.avail_in == 0)
220 s->z_eof = 1;
221 break;
223 s->stream.next_in = s->inbuf;
225 s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
227 if (s->z_err == Z_STREAM_END)
229 /* Check CRC and original size */
230 s->crc = crc32(s->crc, start, (uInt) (s->stream.next_out - start));
231 start = s->stream.next_out;
233 if (getLong(s) != s->crc || getLong(s) != s->stream.total_out)
235 s->z_err = Z_DATA_ERROR;
237 else if (s->z_err == Z_OK)
239 inflateReset(&(s->stream));
240 s->crc = crc32(0L, Z_NULL, 0);
243 if (s->z_err != Z_OK || s->z_eof)
244 break;
246 s->crc = crc32(s->crc, start, (uInt) (s->stream.next_out - start));
247 return (int) (len - s->stream.avail_out);
250 /* ===========================================================================
251 Flushes all pending output into the compressed file. The parameter
252 flush is as in the deflate() function.
253 gz_flush should be called only when strictly necessary because it can
254 degrade compression.
256 int gz_flush(gz_stream * file, int flush)
258 uInt len;
259 int done = 0;
260 gz_stream *s = (gz_stream *) file;
262 if (s == NULL || s->mode != 'w')
263 return Z_STREAM_ERROR;
265 s->stream.avail_in = 0; /* should be zero already anyway */
267 for (;;)
269 len = Z_BUFSIZE - s->stream.avail_out;
270 if (len != 0)
273 if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) {
274 s->z_err = Z_ERRNO;
275 return Z_ERRNO;
278 s->stream.next_out = s->outbuf;
279 s->stream.avail_out = Z_BUFSIZE;
281 if (done)
282 break;
283 s->z_err = deflate(&(s->stream), flush);
285 /* deflate has finished flushing only when it hasn't used up
286 * all the available space in the output buffer:
288 done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END);
290 if (s->z_err != Z_OK && s->z_err != Z_STREAM_END)
291 break;
293 return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
297 /* ===========================================================================
298 Reads a long in LSB order from the given gz_stream. Sets
300 local uLong getLong(gz_stream * s)
302 uLong x = (uLong) get_byte(s);
303 int c;
305 x += ((uLong) get_byte(s)) << 8;
306 x += ((uLong) get_byte(s)) << 16;
307 c = get_byte(s);
308 if (c == EOF)
309 s->z_err = Z_DATA_ERROR;
310 x += ((uLong) c) << 24;
311 return x;
315 /* ===========================================================================
316 Flushes all pending output if necessary, closes the compressed file
317 and deallocates all the (de)compression state.
319 int gz_close(gz_stream * file)
321 // int err;
322 gz_stream *s = (gz_stream *) file;
324 if (s == NULL)
325 return Z_STREAM_ERROR;
326 #if 0
327 if (s->mode == 'w')
329 err = gz_flush(file, Z_FINISH);
330 if (err != Z_OK)
331 return destroy(s);
332 putLong(s->file, s->crc);
333 putLong(s->file, s->stream.total_in);
335 #endif
336 return destroy(s);