fix toolbar import
[ooovba.git] / tools / source / zcodec / zcodec.cxx
blobd0a60ddf45f2a19b97fa309c0c5dec77e920089b
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: zcodec.cxx,v $
10 * $Revision: 1.11 $
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 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_tools.hxx"
33 #include <tools/stream.hxx>
34 #ifndef _ZLIB_H
35 #ifdef SYSTEM_ZLIB
36 #include "zlib.h"
37 #else
38 #include "zlib/zlib.h"
39 #endif
40 #endif
41 #include <tools/zcodec.hxx>
42 #include <rtl/crc.h>
43 #include <osl/endian.h>
45 // -----------
46 // - Defines -
47 // -----------
49 #define PZSTREAM ((z_stream*) mpsC_Stream)
51 /* gzip flag byte */
52 #define GZ_ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
53 #define GZ_HEAD_CRC 0x02 /* bit 1 set: header CRC present */
54 #define GZ_EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
55 #define GZ_ORIG_NAME 0x08 /* bit 3 set: original file name present */
56 #define GZ_COMMENT 0x10 /* bit 4 set: file comment present */
57 #define GZ_RESERVED 0xE0 /* bits 5..7: reserved */
59 static int gz_magic[2] = { 0x1f, 0x8b }; /* gzip magic header */
62 // ----------
63 // - ZCodec -
64 // ----------
66 ZCodec::ZCodec( ULONG nInBufSize, ULONG nOutBufSize, ULONG nMemUsage )
67 : mnCRC(0)
69 mnMemUsage = nMemUsage;
70 mnInBufSize = nInBufSize;
71 mnOutBufSize = nOutBufSize;
72 mpsC_Stream = new z_stream;
75 ZCodec::ZCodec( void )
76 : mnCRC(0)
78 mnMemUsage = MAX_MEM_USAGE;
79 mnInBufSize = DEFAULT_IN_BUFSIZE;
80 mnOutBufSize = DEFAULT_OUT_BUFSIZE;
81 mpsC_Stream = new z_stream;
84 // ------------------------------------------------------------------------
86 ZCodec::~ZCodec()
88 delete (z_stream*) mpsC_Stream;
91 // ------------------------------------------------------------------------
93 void ZCodec::BeginCompression( ULONG nCompressMethod )
95 mbInit = 0;
96 mbStatus = TRUE;
97 mbFinish = FALSE;
98 mpIStm = mpOStm = NULL;
99 mnInToRead = 0xffffffff;
100 mpInBuf = mpOutBuf = NULL;
101 PZSTREAM->total_out = PZSTREAM->total_in = 0;
102 mnCompressMethod = nCompressMethod;
103 PZSTREAM->zalloc = ( alloc_func )0;
104 PZSTREAM->zfree = ( free_func )0;
105 PZSTREAM->opaque = ( voidpf )0;
106 PZSTREAM->avail_out = PZSTREAM->avail_in = 0;
109 // ------------------------------------------------------------------------
111 long ZCodec::EndCompression()
113 long retvalue = 0;
115 if ( mbInit != 0 )
117 if ( mbInit & 2 ) // 1->decompress, 3->compress
121 ImplWriteBack();
123 while ( deflate( PZSTREAM, Z_FINISH ) != Z_STREAM_END );
125 ImplWriteBack();
127 retvalue = PZSTREAM->total_in;
128 deflateEnd( PZSTREAM );
130 else
132 retvalue = PZSTREAM->total_out;
133 inflateEnd( PZSTREAM );
135 delete[] mpOutBuf;
136 delete[] mpInBuf;
138 return ( mbStatus ) ? retvalue : -1;
142 // ------------------------------------------------------------------------
144 long ZCodec::Compress( SvStream& rIStm, SvStream& rOStm )
146 long nOldTotal_In = PZSTREAM->total_in;
148 if ( mbInit == 0 )
150 mpIStm = &rIStm;
151 mpOStm = &rOStm;
152 ImplInitBuf( FALSE );
153 mpInBuf = new BYTE[ mnInBufSize ];
155 while (( PZSTREAM->avail_in = mpIStm->Read( PZSTREAM->next_in = mpInBuf, mnInBufSize )) != 0 )
157 if ( PZSTREAM->avail_out == 0 )
158 ImplWriteBack();
159 if ( deflate( PZSTREAM, Z_NO_FLUSH ) < 0 )
161 mbStatus = FALSE;
162 break;
165 return ( mbStatus ) ? (long)(PZSTREAM->total_in - nOldTotal_In) : -1;
168 // ------------------------------------------------------------------------
170 long ZCodec::Decompress( SvStream& rIStm, SvStream& rOStm )
172 int err;
173 ULONG nInToRead;
174 long nOldTotal_Out = PZSTREAM->total_out;
176 if ( mbFinish )
177 return PZSTREAM->total_out - nOldTotal_Out;
179 if ( mbInit == 0 )
181 mpIStm = &rIStm;
182 mpOStm = &rOStm;
183 ImplInitBuf( TRUE );
184 PZSTREAM->next_out = mpOutBuf = new BYTE[ PZSTREAM->avail_out = mnOutBufSize ];
188 if ( PZSTREAM->avail_out == 0 ) ImplWriteBack();
189 if ( PZSTREAM->avail_in == 0 && mnInToRead )
191 nInToRead = ( mnInBufSize > mnInToRead ) ? mnInToRead : mnInBufSize;
192 PZSTREAM->avail_in = mpIStm->Read( PZSTREAM->next_in = mpInBuf, nInToRead );
193 mnInToRead -= nInToRead;
195 if ( mnCompressMethod & ZCODEC_UPDATE_CRC )
196 mnCRC = UpdateCRC( mnCRC, mpInBuf, nInToRead );
199 err = inflate( PZSTREAM, Z_NO_FLUSH );
200 if ( err < 0 )
202 mbStatus = FALSE;
203 break;
207 while ( ( err != Z_STREAM_END) && ( PZSTREAM->avail_in || mnInToRead ) );
208 ImplWriteBack();
210 if ( err == Z_STREAM_END )
211 mbFinish = TRUE;
212 return ( mbStatus ) ? (long)(PZSTREAM->total_out - nOldTotal_Out) : -1;
215 // ------------------------------------------------------------------------
217 long ZCodec::Write( SvStream& rOStm, const BYTE* pData, ULONG nSize )
219 if ( mbInit == 0 )
221 mpOStm = &rOStm;
222 ImplInitBuf( FALSE );
225 PZSTREAM->avail_in = nSize;
226 PZSTREAM->next_in = (unsigned char*)pData;
228 while ( PZSTREAM->avail_in || ( PZSTREAM->avail_out == 0 ) )
230 if ( PZSTREAM->avail_out == 0 )
231 ImplWriteBack();
233 if ( deflate( PZSTREAM, Z_NO_FLUSH ) < 0 )
235 mbStatus = FALSE;
236 break;
239 return ( mbStatus ) ? (long)nSize : -1;
242 // ------------------------------------------------------------------------
244 long ZCodec::Read( SvStream& rIStm, BYTE* pData, ULONG nSize )
246 int err;
247 ULONG nInToRead;
249 if ( mbFinish )
250 return 0; // PZSTREAM->total_out;
252 mpIStm = &rIStm;
253 if ( mbInit == 0 )
255 ImplInitBuf( TRUE );
257 PZSTREAM->avail_out = nSize;
258 PZSTREAM->next_out = pData;
261 if ( PZSTREAM->avail_in == 0 && mnInToRead )
263 nInToRead = (mnInBufSize > mnInToRead) ? mnInToRead : mnInBufSize;
264 PZSTREAM->avail_in = mpIStm->Read (
265 PZSTREAM->next_in = mpInBuf, nInToRead);
266 mnInToRead -= nInToRead;
268 if ( mnCompressMethod & ZCODEC_UPDATE_CRC )
269 mnCRC = UpdateCRC( mnCRC, mpInBuf, nInToRead );
272 err = inflate( PZSTREAM, Z_NO_FLUSH );
273 if ( err < 0 )
275 // Accept Z_BUF_ERROR as EAGAIN or EWOULDBLOCK.
276 mbStatus = (err == Z_BUF_ERROR);
277 break;
280 while ( (err != Z_STREAM_END) &&
281 (PZSTREAM->avail_out != 0) &&
282 (PZSTREAM->avail_in || mnInToRead) );
283 if ( err == Z_STREAM_END )
284 mbFinish = TRUE;
286 return (mbStatus ? (long)(nSize - PZSTREAM->avail_out) : -1);
289 // ------------------------------------------------------------------------
291 long ZCodec::ReadAsynchron( SvStream& rIStm, BYTE* pData, ULONG nSize )
293 int err = 0;
294 ULONG nInToRead;
296 if ( mbFinish )
297 return 0; // PZSTREAM->total_out;
299 if ( mbInit == 0 )
301 mpIStm = &rIStm;
302 ImplInitBuf( TRUE );
304 PZSTREAM->avail_out = nSize;
305 PZSTREAM->next_out = pData;
308 if ( PZSTREAM->avail_in == 0 && mnInToRead )
310 nInToRead = (mnInBufSize > mnInToRead) ? mnInToRead : mnInBufSize;
312 ULONG nStreamPos = rIStm.Tell();
313 rIStm.Seek( STREAM_SEEK_TO_END );
314 ULONG nMaxPos = rIStm.Tell();
315 rIStm.Seek( nStreamPos );
316 if ( ( nMaxPos - nStreamPos ) < nInToRead )
318 rIStm.SetError( ERRCODE_IO_PENDING );
319 err= ! Z_STREAM_END; // TODO What is appropriate code for this?
320 break;
323 PZSTREAM->avail_in = mpIStm->Read (
324 PZSTREAM->next_in = mpInBuf, nInToRead);
325 mnInToRead -= nInToRead;
327 if ( mnCompressMethod & ZCODEC_UPDATE_CRC )
328 mnCRC = UpdateCRC( mnCRC, mpInBuf, nInToRead );
331 err = inflate( PZSTREAM, Z_NO_FLUSH );
332 if ( err < 0 )
334 // Accept Z_BUF_ERROR as EAGAIN or EWOULDBLOCK.
335 mbStatus = (err == Z_BUF_ERROR);
336 break;
339 while ( (err != Z_STREAM_END) &&
340 (PZSTREAM->avail_out != 0) &&
341 (PZSTREAM->avail_in || mnInToRead) );
342 if ( err == Z_STREAM_END )
343 mbFinish = TRUE;
345 return (mbStatus ? (long)(nSize - PZSTREAM->avail_out) : -1);
348 // ------------------------------------------------------------------------
350 void ZCodec::ImplWriteBack()
352 ULONG nAvail = mnOutBufSize - PZSTREAM->avail_out;
354 if ( nAvail )
356 if ( mbInit & 2 && ( mnCompressMethod & ZCODEC_UPDATE_CRC ) )
357 mnCRC = UpdateCRC( mnCRC, mpOutBuf, nAvail );
358 mpOStm->Write( PZSTREAM->next_out = mpOutBuf, nAvail );
359 PZSTREAM->avail_out = mnOutBufSize;
363 // ------------------------------------------------------------------------
365 void ZCodec::SetBreak( ULONG nInToRead )
367 mnInToRead = nInToRead;
370 // ------------------------------------------------------------------------
372 ULONG ZCodec::GetBreak( void )
374 return ( mnInToRead + PZSTREAM->avail_in );
377 // ------------------------------------------------------------------------
379 void ZCodec::SetCRC( ULONG nCRC )
381 mnCRC = nCRC;
384 // ------------------------------------------------------------------------
386 ULONG ZCodec::GetCRC()
388 return mnCRC;
391 // ------------------------------------------------------------------------
393 void ZCodec::ImplInitBuf ( BOOL nIOFlag )
395 if ( mbInit == 0 )
397 if ( nIOFlag )
399 mbInit = 1;
400 if ( mbStatus && ( mnCompressMethod & ZCODEC_GZ_LIB ) )
402 BYTE n1, n2, j, nMethod, nFlags;
403 for ( int i = 0; i < 2; i++ ) // gz - magic number
405 *mpIStm >> j;
406 if ( j != gz_magic[ i ] )
407 mbStatus = FALSE;
409 *mpIStm >> nMethod;
410 *mpIStm >> nFlags;
411 if ( nMethod != Z_DEFLATED )
412 mbStatus = FALSE;
413 if ( ( nFlags & GZ_RESERVED ) != 0 )
414 mbStatus = FALSE;
415 /* Discard time, xflags and OS code: */
416 mpIStm->SeekRel( 6 );
417 /* skip the extra field */
418 if ( nFlags & GZ_EXTRA_FIELD )
420 *mpIStm >> n1 >> n2;
421 mpIStm->SeekRel( n1 + ( n2 << 8 ) );
423 /* skip the original file name */
424 if ( nFlags & GZ_ORIG_NAME)
428 *mpIStm >> j;
430 while ( j && !mpIStm->IsEof() );
432 /* skip the .gz file comment */
433 if ( nFlags & GZ_COMMENT )
437 *mpIStm >> j;
439 while ( j && !mpIStm->IsEof() );
441 /* skip the header crc */
442 if ( nFlags & GZ_HEAD_CRC )
443 mpIStm->SeekRel( 2 );
444 if ( mbStatus )
445 mbStatus = ( inflateInit2( PZSTREAM, -MAX_WBITS) != Z_OK ) ? FALSE : TRUE;
447 else
449 mbStatus = ( inflateInit( PZSTREAM ) >= 0 );
451 mpInBuf = new BYTE[ mnInBufSize ];
453 else
455 mbInit = 3;
457 mbStatus = ( deflateInit2_( PZSTREAM, mnCompressMethod & 0xff, Z_DEFLATED,
458 MAX_WBITS, mnMemUsage, ( mnCompressMethod >> 8 ) & 0xff,
459 ZLIB_VERSION, sizeof( z_stream ) ) >= 0 );
461 PZSTREAM->next_out = mpOutBuf = new BYTE[ PZSTREAM->avail_out = mnOutBufSize ];
466 // ------------------------------------------------------------------------
468 ULONG ZCodec::UpdateCRC ( ULONG nLatestCRC, ULONG nNumber )
471 #ifdef OSL_LITENDIAN
472 nNumber = SWAPLONG( nNumber );
473 #endif
474 return rtl_crc32( nLatestCRC, &nNumber, 4 );
477 // ------------------------------------------------------------------------
479 ULONG ZCodec::UpdateCRC ( ULONG nLatestCRC, BYTE* pSource, long nDatSize)
481 return rtl_crc32( nLatestCRC, pSource, nDatSize );
484 // ------------------------------------------------------------------------
486 void GZCodec::BeginCompression( ULONG nCompressMethod )
488 ZCodec::BeginCompression( nCompressMethod | ZCODEC_GZ_LIB );