update dev300-m58
[ooovba.git] / hwpfilter / source / hgzip.cpp
blobf7ac9c261b33e59e72efb2449775d75b1bd25b0b
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: hgzip.cpp,v $
10 * $Revision: 1.5 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include "precompile.h"
33 #include <stdio.h>
34 #include <string.h>
35 #include <stdlib.h>
36 #include <errno.h>
37 #include "hgzip.h"
38 #include "hstream.h"
40 #ifndef local
41 # define local static
42 #endif
44 #define Z_BUFSIZE (1024 * 4)
46 #define ALLOC(size) malloc(size)
47 #define TRYFREE(p) {if (p) free(p);}
49 #define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
50 #define HEAD_CRC 0x02 /* bit 1 set: header CRC present */
51 #define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
52 #define ORIG_NAME 0x08 /* bit 3 set: original file name present */
53 #define COMMENT 0x10 /* bit 4 set: file comment present */
54 #define RESERVED 0xE0 /* bits 5..7: reserved */
56 local int get_byte(gz_stream * s);
57 local int destroy(gz_stream * s);
58 local uLong getLong(gz_stream * s);
60 /* ===========================================================================
61 Opens a gzip (.gz) file for reading or writing. The mode parameter
62 is as in fopen ("rb" or "wb"). The file is given either by file descriptor
63 or path name (if fd == -1).
64 gz_open return NULL if the file could not be opened or if there was
65 insufficient memory to allocate the (de)compression state; errno
66 can be checked to distinguish the two cases (if errno is zero, the
67 zlib error is Z_MEM_ERROR).
69 gz_stream *gz_open(HStream & _stream)
71 int err;
72 //int level = Z_DEFAULT_COMPRESSION; /* compression level */
74 // char *p = (char*)mode;
75 //char fmode[80]; /* copy of mode, without the compression level */
76 //char *m = fmode;
77 gz_stream *s;
79 s = (gz_stream *) ALLOC(sizeof(gz_stream));
80 if (!s)
81 return Z_NULL;
82 s->stream.zalloc = (alloc_func) 0;
83 s->stream.zfree = (free_func) 0;
84 s->stream.opaque = (voidpf) 0;
85 s->stream.next_in = s->inbuf = Z_NULL;
86 s->stream.next_out = s->outbuf = Z_NULL;
87 s->stream.avail_in = s->stream.avail_out = 0;
88 //s->_inputstream = NULL;
89 s->z_err = Z_OK;
90 s->z_eof = 0;
91 s->crc = crc32(0L, Z_NULL, 0);
92 s->msg = NULL;
93 s->transparent = 0;
95 s->mode = 'r';
97 //realking
98 err = inflateInit2(&(s->stream), -MAX_WBITS);
99 s->stream.next_in = s->inbuf = (Byte *) ALLOC(Z_BUFSIZE);
101 if (err != Z_OK || s->inbuf == Z_NULL)
103 return destroy(s), (gz_stream *) Z_NULL;
106 s->stream.avail_out = Z_BUFSIZE;
108 errno = 0;
109 s->_inputstream = &_stream;
111 return (gz_stream *) s;
115 /* ===========================================================================
116 Read a byte from a gz_stream; update next_in and avail_in. Return EOF
117 for end of file.
118 IN assertion: the stream s has been sucessfully opened for reading.
120 local int get_byte(gz_stream * s)
122 if (s->z_eof)
123 return EOF;
124 if (s->stream.avail_in == 0)
126 errno = 0;
128 s->stream.avail_in = s->_inputstream->readBytes(s->inbuf, Z_BUFSIZE);
129 if (s->stream.avail_in == 0)
131 s->z_eof = 1;
132 return EOF;
134 s->stream.next_in = s->inbuf;
136 s->stream.avail_in--;
137 return *(s->stream.next_in)++;
141 /* ===========================================================================
142 * Cleanup then free the given gz_stream. Return a zlib error code.
143 * Try freeing in the reverse order of allocations.
145 local int destroy(gz_stream * s)
147 int err = Z_OK;
149 if (!s)
150 return Z_STREAM_ERROR;
152 TRYFREE(s->msg);
154 if (s->stream.state != NULL)
156 err = inflateEnd(&(s->stream));
158 if (s->z_err < 0)
159 err = s->z_err;
161 TRYFREE(s->inbuf);
162 TRYFREE(s->outbuf);
163 TRYFREE(s);
164 return err;
168 // typedef unsigned char Byte
169 // typedef Byte FAR Bytef;
170 /* ===========================================================================
171 Reads the given number of uncompressed bytes from the compressed file.
172 gz_read returns the number of bytes actually read (0 for end of file).
174 int gz_read(gz_stream * file, voidp buf, unsigned len)
176 //printf("@@ gz_read : len : %d\t",len);
177 gz_stream *s = (gz_stream *) file;
178 Bytef *start = (Bytef *) buf; /* starting point for crc computation */
179 Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */
180 if (s == NULL)
181 return Z_STREAM_ERROR;
183 if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO)
184 return -1;
185 if (s->z_err == Z_STREAM_END)
186 return 0; /* EOF */
188 s->stream.next_out = next_out = (Bytef *) buf;
189 s->stream.avail_out = len;
191 while (s->stream.avail_out != 0)
193 if (s->transparent)
195 /* Copy first the lookahead bytes: */
196 uInt n = s->stream.avail_in;
198 if (n > s->stream.avail_out)
199 n = s->stream.avail_out;
200 if (n > 0)
202 memcpy(s->stream.next_out, s->stream.next_in, n);
203 next_out += n;
204 s->stream.next_out = next_out;
205 s->stream.next_in += n;
206 s->stream.avail_out -= n;
207 s->stream.avail_in -= n;
209 if (s->stream.avail_out > 0)
211 s->stream.avail_out -=
212 s->_inputstream->readBytes(next_out, s->stream.avail_out);
214 return (int) (len - s->stream.avail_out);
216 if (s->stream.avail_in == 0 && !s->z_eof)
219 errno = 0;
220 s->stream.avail_in = s->_inputstream->readBytes(s->inbuf, Z_BUFSIZE);
221 if (s->stream.avail_in == 0)
223 s->z_eof = 1;
224 break;
226 s->stream.next_in = s->inbuf;
228 s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
230 if (s->z_err == Z_STREAM_END)
232 /* Check CRC and original size */
233 s->crc = crc32(s->crc, start, (uInt) (s->stream.next_out - start));
234 start = s->stream.next_out;
236 if (getLong(s) != s->crc || getLong(s) != s->stream.total_out)
238 s->z_err = Z_DATA_ERROR;
240 else if (s->z_err == Z_OK)
242 inflateReset(&(s->stream));
243 s->crc = crc32(0L, Z_NULL, 0);
246 if (s->z_err != Z_OK || s->z_eof)
247 break;
249 s->crc = crc32(s->crc, start, (uInt) (s->stream.next_out - start));
250 return (int) (len - s->stream.avail_out);
253 /* ===========================================================================
254 Flushes all pending output into the compressed file. The parameter
255 flush is as in the deflate() function.
256 gz_flush should be called only when strictly necessary because it can
257 degrade compression.
259 int gz_flush(gz_stream * file, int flush)
261 uInt len;
262 int done = 0;
263 gz_stream *s = (gz_stream *) file;
265 if (s == NULL || s->mode != 'w')
266 return Z_STREAM_ERROR;
268 s->stream.avail_in = 0; /* should be zero already anyway */
270 for (;;)
272 len = Z_BUFSIZE - s->stream.avail_out;
273 if (len != 0)
276 if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) {
277 s->z_err = Z_ERRNO;
278 return Z_ERRNO;
281 s->stream.next_out = s->outbuf;
282 s->stream.avail_out = Z_BUFSIZE;
284 if (done)
285 break;
286 s->z_err = deflate(&(s->stream), flush);
288 /* deflate has finished flushing only when it hasn't used up
289 * all the available space in the output buffer:
291 done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END);
293 if (s->z_err != Z_OK && s->z_err != Z_STREAM_END)
294 break;
296 return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
300 /* ===========================================================================
301 Reads a long in LSB order from the given gz_stream. Sets
303 local uLong getLong(gz_stream * s)
305 uLong x = (uLong) get_byte(s);
306 int c;
308 x += ((uLong) get_byte(s)) << 8;
309 x += ((uLong) get_byte(s)) << 16;
310 c = get_byte(s);
311 if (c == EOF)
312 s->z_err = Z_DATA_ERROR;
313 x += ((uLong) c) << 24;
314 return x;
318 /* ===========================================================================
319 Flushes all pending output if necessary, closes the compressed file
320 and deallocates all the (de)compression state.
322 int gz_close(gz_stream * file)
324 // int err;
325 gz_stream *s = (gz_stream *) file;
327 if (s == NULL)
328 return Z_STREAM_ERROR;
329 #if 0
330 if (s->mode == 'w')
332 err = gz_flush(file, Z_FINISH);
333 if (err != Z_OK)
334 return destroy(s);
335 putLong(s->file, s->crc);
336 putLong(s->file, s->stream.total_in);
338 #endif
339 return destroy(s);