xref: /aoo41x/main/package/source/zipapi/Deflater.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
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.
14  *
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).
20  *
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.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_package.hxx"
30 #include <Deflater.hxx>
31 #ifndef _ZLIB_H
32 #ifdef SYSTEM_ZLIB
33 #include <zlib.h>
34 #else
35 #include <external/zlib/zlib.h>
36 #endif
37 #endif
38 #include <com/sun/star/packages/zip/ZipConstants.hpp>
39 #include <string.h> // for memset
40 
41 using namespace com::sun::star::packages::zip::ZipConstants;
42 using namespace com::sun::star;
43 
44 /** Provides general purpose compression using the ZLIB compression
45  * library.
46  */
47 
48 Deflater::~Deflater(void)
49 {
50 	end();
51 }
52 void Deflater::init (sal_Int32 nLevelArg, sal_Int32 nStrategyArg, sal_Bool bNowrap)
53 {
54 	pStream = new z_stream;
55 	/* Memset it to 0...sets zalloc/zfree/opaque to NULL */
56 	memset (pStream, 0, sizeof(*pStream));
57 
58 	switch (deflateInit2(pStream, nLevelArg, Z_DEFLATED, bNowrap? -MAX_WBITS : MAX_WBITS,
59 				DEF_MEM_LEVEL, nStrategyArg))
60 	{
61 		case Z_OK:
62 			break;
63 		case Z_MEM_ERROR:
64 			delete pStream;
65 			break;
66 		case Z_STREAM_ERROR:
67 			delete pStream;
68 			break;
69 		default:
70 			 break;
71 	}
72 }
73 
74 Deflater::Deflater(sal_Int32 nSetLevel, sal_Bool bNowrap)
75 : bFinish(sal_False)
76 , bFinished(sal_False)
77 , bSetParams(sal_False)
78 , nLevel(nSetLevel)
79 , nStrategy(DEFAULT_STRATEGY)
80 , nOffset(0)
81 , nLength(0)
82 {
83 	init(nSetLevel, DEFAULT_STRATEGY, bNowrap);
84 }
85 
86 sal_Int32 Deflater::doDeflateBytes (uno::Sequence < sal_Int8 > &rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength)
87 {
88 	sal_Int32 nResult;
89 	if (bSetParams)
90 	{
91 		pStream->next_in   = (unsigned char*) sInBuffer.getConstArray() + nOffset;
92 		pStream->next_out  = (unsigned char*) rBuffer.getArray()+nNewOffset;
93 		pStream->avail_in  = nLength;
94 		pStream->avail_out = nNewLength;
95 
96 #if defined SYSTEM_ZLIB || !defined ZLIB_PREFIX
97 		nResult = deflateParams(pStream, nLevel, nStrategy);
98 #else
99 		nResult = z_deflateParams(pStream, nLevel, nStrategy);
100 #endif
101 		switch (nResult)
102 		{
103 			case Z_OK:
104 				bSetParams = sal_False;
105 				nOffset += nLength - pStream->avail_in;
106 				nLength = pStream->avail_in;
107 				return nNewLength - pStream->avail_out;
108 			case Z_BUF_ERROR:
109 				bSetParams = sal_False;
110 				return 0;
111 			default:
112 				return 0;
113 		}
114 	}
115 	else
116 	{
117 		pStream->next_in   = (unsigned char*) sInBuffer.getConstArray() + nOffset;
118 		pStream->next_out  = (unsigned char*) rBuffer.getArray()+nNewOffset;
119 		pStream->avail_in  = nLength;
120 		pStream->avail_out = nNewLength;
121 
122 #if defined SYSTEM_ZLIB || !defined ZLIB_PREFIX
123 		nResult = deflate(pStream, bFinish ? Z_FINISH : Z_NO_FLUSH);
124 #else
125 		nResult = z_deflate(pStream, bFinish ? Z_FINISH : Z_NO_FLUSH);
126 #endif
127 		switch (nResult)
128 		{
129 			case Z_STREAM_END:
130 				bFinished = sal_True;
131 			case Z_OK:
132 				nOffset += nLength - pStream->avail_in;
133 				nLength = pStream->avail_in;
134 				return nNewLength - pStream->avail_out;
135 			case Z_BUF_ERROR:
136 				bSetParams = sal_False;
137 				return 0;
138 			default:
139 				return 0;
140 		}
141 	}
142 }
143 
144 void SAL_CALL Deflater::setInputSegment( const uno::Sequence< sal_Int8 >& rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength )
145 {
146     OSL_ASSERT( !(nNewOffset < 0 || nNewLength < 0 || nNewOffset + nNewLength > rBuffer.getLength()));
147 
148     sInBuffer = rBuffer;
149     nOffset = nNewOffset;
150     nLength = nNewLength;
151 }
152 void SAL_CALL Deflater::setLevel( sal_Int32 nNewLevel )
153 {
154 	if ((nNewLevel < 0 || nNewLevel > 9) && nNewLevel != DEFAULT_COMPRESSION)
155 	{
156 		// do error handling
157 	}
158 	if (nNewLevel != nLevel)
159 	{
160 		nLevel = nNewLevel;
161 		bSetParams = sal_True;
162 	}
163 }
164 sal_Bool SAL_CALL Deflater::needsInput(  )
165 {
166 	return nLength <=0;
167 }
168 void SAL_CALL Deflater::finish(  )
169 {
170 	bFinish = sal_True;
171 }
172 sal_Bool SAL_CALL Deflater::finished(  )
173 {
174 	return bFinished;
175 }
176 sal_Int32 SAL_CALL Deflater::doDeflateSegment( uno::Sequence< sal_Int8 >& rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength )
177 {
178     OSL_ASSERT( !(nNewOffset < 0 || nNewLength < 0 || nNewOffset + nNewLength > rBuffer.getLength()));
179     return doDeflateBytes(rBuffer, nNewOffset, nNewLength);
180 }
181 sal_Int32 SAL_CALL Deflater::getTotalIn(  )
182 {
183 	return pStream->total_in;
184 }
185 sal_Int32 SAL_CALL Deflater::getTotalOut(  )
186 {
187 	return pStream->total_out;
188 }
189 void SAL_CALL Deflater::reset(  )
190 {
191 #if defined SYSTEM_ZLIB || !defined ZLIB_PREFIXB
192 	deflateReset(pStream);
193 #else
194 	z_deflateReset(pStream);
195 #endif
196 	bFinish = sal_False;
197 	bFinished = sal_False;
198 	nOffset = nLength = 0;
199 }
200 void SAL_CALL Deflater::end(  )
201 {
202 	if (pStream != NULL)
203 	{
204 #if defined SYSTEM_ZLIB || !defined ZLIB_PREFIX
205 		deflateEnd(pStream);
206 #else
207 		z_deflateEnd(pStream);
208 #endif
209 		delete pStream;
210 	}
211 	pStream = NULL;
212 }
213