1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski  *
3*b1cdbd2cSJim Jagielski  * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski  * or more contributor license agreements.  See the NOTICE file
5*b1cdbd2cSJim Jagielski  * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski  * regarding copyright ownership.  The ASF licenses this file
7*b1cdbd2cSJim Jagielski  * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski  * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski  * with the License.  You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski  *
11*b1cdbd2cSJim Jagielski  *   http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski  *
13*b1cdbd2cSJim Jagielski  * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski  * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski  * KIND, either express or implied.  See the License for the
17*b1cdbd2cSJim Jagielski  * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski  * under the License.
19*b1cdbd2cSJim Jagielski  *
20*b1cdbd2cSJim Jagielski  *************************************************************/
21*b1cdbd2cSJim Jagielski 
22*b1cdbd2cSJim Jagielski 
23*b1cdbd2cSJim Jagielski 
24*b1cdbd2cSJim Jagielski // MARKER(update_precomp.py): autogen include statement, do not remove
25*b1cdbd2cSJim Jagielski #include "precompiled_package.hxx"
26*b1cdbd2cSJim Jagielski #include <Deflater.hxx>
27*b1cdbd2cSJim Jagielski #ifndef _ZLIB_H
28*b1cdbd2cSJim Jagielski #ifdef SYSTEM_ZLIB
29*b1cdbd2cSJim Jagielski #include <zlib.h>
30*b1cdbd2cSJim Jagielski #else
31*b1cdbd2cSJim Jagielski #include <external/zlib/zlib.h>
32*b1cdbd2cSJim Jagielski #endif
33*b1cdbd2cSJim Jagielski #endif
34*b1cdbd2cSJim Jagielski #include <com/sun/star/packages/zip/ZipConstants.hpp>
35*b1cdbd2cSJim Jagielski #include <string.h> // for memset
36*b1cdbd2cSJim Jagielski 
37*b1cdbd2cSJim Jagielski using namespace com::sun::star::packages::zip::ZipConstants;
38*b1cdbd2cSJim Jagielski using namespace com::sun::star;
39*b1cdbd2cSJim Jagielski 
40*b1cdbd2cSJim Jagielski /** Provides general purpose compression using the ZLIB compression
41*b1cdbd2cSJim Jagielski  * library.
42*b1cdbd2cSJim Jagielski  */
43*b1cdbd2cSJim Jagielski 
~Deflater(void)44*b1cdbd2cSJim Jagielski Deflater::~Deflater(void)
45*b1cdbd2cSJim Jagielski {
46*b1cdbd2cSJim Jagielski 	end();
47*b1cdbd2cSJim Jagielski }
init(sal_Int32 nLevelArg,sal_Int32 nStrategyArg,sal_Bool bNowrap)48*b1cdbd2cSJim Jagielski void Deflater::init (sal_Int32 nLevelArg, sal_Int32 nStrategyArg, sal_Bool bNowrap)
49*b1cdbd2cSJim Jagielski {
50*b1cdbd2cSJim Jagielski 	pStream = new z_stream;
51*b1cdbd2cSJim Jagielski 	/* Memset it to 0...sets zalloc/zfree/opaque to NULL */
52*b1cdbd2cSJim Jagielski 	memset (pStream, 0, sizeof(*pStream));
53*b1cdbd2cSJim Jagielski 
54*b1cdbd2cSJim Jagielski 	switch (deflateInit2(pStream, nLevelArg, Z_DEFLATED, bNowrap? -MAX_WBITS : MAX_WBITS,
55*b1cdbd2cSJim Jagielski 				DEF_MEM_LEVEL, nStrategyArg))
56*b1cdbd2cSJim Jagielski 	{
57*b1cdbd2cSJim Jagielski 		case Z_OK:
58*b1cdbd2cSJim Jagielski 			break;
59*b1cdbd2cSJim Jagielski 		case Z_MEM_ERROR:
60*b1cdbd2cSJim Jagielski 			delete pStream;
61*b1cdbd2cSJim Jagielski 			break;
62*b1cdbd2cSJim Jagielski 		case Z_STREAM_ERROR:
63*b1cdbd2cSJim Jagielski 			delete pStream;
64*b1cdbd2cSJim Jagielski 			break;
65*b1cdbd2cSJim Jagielski 		default:
66*b1cdbd2cSJim Jagielski 			 break;
67*b1cdbd2cSJim Jagielski 	}
68*b1cdbd2cSJim Jagielski }
69*b1cdbd2cSJim Jagielski 
Deflater(sal_Int32 nSetLevel,sal_Bool bNowrap)70*b1cdbd2cSJim Jagielski Deflater::Deflater(sal_Int32 nSetLevel, sal_Bool bNowrap)
71*b1cdbd2cSJim Jagielski : bFinish(sal_False)
72*b1cdbd2cSJim Jagielski , bFinished(sal_False)
73*b1cdbd2cSJim Jagielski , bSetParams(sal_False)
74*b1cdbd2cSJim Jagielski , nLevel(nSetLevel)
75*b1cdbd2cSJim Jagielski , nStrategy(DEFAULT_STRATEGY)
76*b1cdbd2cSJim Jagielski , nOffset(0)
77*b1cdbd2cSJim Jagielski , nLength(0)
78*b1cdbd2cSJim Jagielski {
79*b1cdbd2cSJim Jagielski 	init(nSetLevel, DEFAULT_STRATEGY, bNowrap);
80*b1cdbd2cSJim Jagielski }
81*b1cdbd2cSJim Jagielski 
doDeflateBytes(uno::Sequence<sal_Int8> & rBuffer,sal_Int32 nNewOffset,sal_Int32 nNewLength)82*b1cdbd2cSJim Jagielski sal_Int32 Deflater::doDeflateBytes (uno::Sequence < sal_Int8 > &rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength)
83*b1cdbd2cSJim Jagielski {
84*b1cdbd2cSJim Jagielski 	sal_Int32 nResult;
85*b1cdbd2cSJim Jagielski 	if (bSetParams)
86*b1cdbd2cSJim Jagielski 	{
87*b1cdbd2cSJim Jagielski 		pStream->next_in   = (unsigned char*) sInBuffer.getConstArray() + nOffset;
88*b1cdbd2cSJim Jagielski 		pStream->next_out  = (unsigned char*) rBuffer.getArray()+nNewOffset;
89*b1cdbd2cSJim Jagielski 		pStream->avail_in  = nLength;
90*b1cdbd2cSJim Jagielski 		pStream->avail_out = nNewLength;
91*b1cdbd2cSJim Jagielski 
92*b1cdbd2cSJim Jagielski #if defined SYSTEM_ZLIB || !defined ZLIB_PREFIX
93*b1cdbd2cSJim Jagielski 		nResult = deflateParams(pStream, nLevel, nStrategy);
94*b1cdbd2cSJim Jagielski #else
95*b1cdbd2cSJim Jagielski 		nResult = z_deflateParams(pStream, nLevel, nStrategy);
96*b1cdbd2cSJim Jagielski #endif
97*b1cdbd2cSJim Jagielski 		switch (nResult)
98*b1cdbd2cSJim Jagielski 		{
99*b1cdbd2cSJim Jagielski 			case Z_OK:
100*b1cdbd2cSJim Jagielski 				bSetParams = sal_False;
101*b1cdbd2cSJim Jagielski 				nOffset += nLength - pStream->avail_in;
102*b1cdbd2cSJim Jagielski 				nLength = pStream->avail_in;
103*b1cdbd2cSJim Jagielski 				return nNewLength - pStream->avail_out;
104*b1cdbd2cSJim Jagielski 			case Z_BUF_ERROR:
105*b1cdbd2cSJim Jagielski 				bSetParams = sal_False;
106*b1cdbd2cSJim Jagielski 				return 0;
107*b1cdbd2cSJim Jagielski 			default:
108*b1cdbd2cSJim Jagielski 				return 0;
109*b1cdbd2cSJim Jagielski 		}
110*b1cdbd2cSJim Jagielski 	}
111*b1cdbd2cSJim Jagielski 	else
112*b1cdbd2cSJim Jagielski 	{
113*b1cdbd2cSJim Jagielski 		pStream->next_in   = (unsigned char*) sInBuffer.getConstArray() + nOffset;
114*b1cdbd2cSJim Jagielski 		pStream->next_out  = (unsigned char*) rBuffer.getArray()+nNewOffset;
115*b1cdbd2cSJim Jagielski 		pStream->avail_in  = nLength;
116*b1cdbd2cSJim Jagielski 		pStream->avail_out = nNewLength;
117*b1cdbd2cSJim Jagielski 
118*b1cdbd2cSJim Jagielski #if defined SYSTEM_ZLIB || !defined ZLIB_PREFIX
119*b1cdbd2cSJim Jagielski 		nResult = deflate(pStream, bFinish ? Z_FINISH : Z_NO_FLUSH);
120*b1cdbd2cSJim Jagielski #else
121*b1cdbd2cSJim Jagielski 		nResult = z_deflate(pStream, bFinish ? Z_FINISH : Z_NO_FLUSH);
122*b1cdbd2cSJim Jagielski #endif
123*b1cdbd2cSJim Jagielski 		switch (nResult)
124*b1cdbd2cSJim Jagielski 		{
125*b1cdbd2cSJim Jagielski 			case Z_STREAM_END:
126*b1cdbd2cSJim Jagielski 				bFinished = sal_True;
127*b1cdbd2cSJim Jagielski 			case Z_OK:
128*b1cdbd2cSJim Jagielski 				nOffset += nLength - pStream->avail_in;
129*b1cdbd2cSJim Jagielski 				nLength = pStream->avail_in;
130*b1cdbd2cSJim Jagielski 				return nNewLength - pStream->avail_out;
131*b1cdbd2cSJim Jagielski 			case Z_BUF_ERROR:
132*b1cdbd2cSJim Jagielski 				bSetParams = sal_False;
133*b1cdbd2cSJim Jagielski 				return 0;
134*b1cdbd2cSJim Jagielski 			default:
135*b1cdbd2cSJim Jagielski 				return 0;
136*b1cdbd2cSJim Jagielski 		}
137*b1cdbd2cSJim Jagielski 	}
138*b1cdbd2cSJim Jagielski }
139*b1cdbd2cSJim Jagielski 
setInputSegment(const uno::Sequence<sal_Int8> & rBuffer,sal_Int32 nNewOffset,sal_Int32 nNewLength)140*b1cdbd2cSJim Jagielski void SAL_CALL Deflater::setInputSegment( const uno::Sequence< sal_Int8 >& rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength )
141*b1cdbd2cSJim Jagielski {
142*b1cdbd2cSJim Jagielski     OSL_ASSERT( !(nNewOffset < 0 || nNewLength < 0 || nNewOffset + nNewLength > rBuffer.getLength()));
143*b1cdbd2cSJim Jagielski 
144*b1cdbd2cSJim Jagielski     sInBuffer = rBuffer;
145*b1cdbd2cSJim Jagielski     nOffset = nNewOffset;
146*b1cdbd2cSJim Jagielski     nLength = nNewLength;
147*b1cdbd2cSJim Jagielski }
setLevel(sal_Int32 nNewLevel)148*b1cdbd2cSJim Jagielski void SAL_CALL Deflater::setLevel( sal_Int32 nNewLevel )
149*b1cdbd2cSJim Jagielski {
150*b1cdbd2cSJim Jagielski 	if ((nNewLevel < 0 || nNewLevel > 9) && nNewLevel != DEFAULT_COMPRESSION)
151*b1cdbd2cSJim Jagielski 	{
152*b1cdbd2cSJim Jagielski 		// do error handling
153*b1cdbd2cSJim Jagielski 	}
154*b1cdbd2cSJim Jagielski 	if (nNewLevel != nLevel)
155*b1cdbd2cSJim Jagielski 	{
156*b1cdbd2cSJim Jagielski 		nLevel = nNewLevel;
157*b1cdbd2cSJim Jagielski 		bSetParams = sal_True;
158*b1cdbd2cSJim Jagielski 	}
159*b1cdbd2cSJim Jagielski }
needsInput()160*b1cdbd2cSJim Jagielski sal_Bool SAL_CALL Deflater::needsInput(  )
161*b1cdbd2cSJim Jagielski {
162*b1cdbd2cSJim Jagielski 	return nLength <=0;
163*b1cdbd2cSJim Jagielski }
finish()164*b1cdbd2cSJim Jagielski void SAL_CALL Deflater::finish(  )
165*b1cdbd2cSJim Jagielski {
166*b1cdbd2cSJim Jagielski 	bFinish = sal_True;
167*b1cdbd2cSJim Jagielski }
finished()168*b1cdbd2cSJim Jagielski sal_Bool SAL_CALL Deflater::finished(  )
169*b1cdbd2cSJim Jagielski {
170*b1cdbd2cSJim Jagielski 	return bFinished;
171*b1cdbd2cSJim Jagielski }
doDeflateSegment(uno::Sequence<sal_Int8> & rBuffer,sal_Int32 nNewOffset,sal_Int32 nNewLength)172*b1cdbd2cSJim Jagielski sal_Int32 SAL_CALL Deflater::doDeflateSegment( uno::Sequence< sal_Int8 >& rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength )
173*b1cdbd2cSJim Jagielski {
174*b1cdbd2cSJim Jagielski     OSL_ASSERT( !(nNewOffset < 0 || nNewLength < 0 || nNewOffset + nNewLength > rBuffer.getLength()));
175*b1cdbd2cSJim Jagielski     return doDeflateBytes(rBuffer, nNewOffset, nNewLength);
176*b1cdbd2cSJim Jagielski }
getTotalIn()177*b1cdbd2cSJim Jagielski sal_Int32 SAL_CALL Deflater::getTotalIn(  )
178*b1cdbd2cSJim Jagielski {
179*b1cdbd2cSJim Jagielski 	return pStream->total_in;
180*b1cdbd2cSJim Jagielski }
getTotalOut()181*b1cdbd2cSJim Jagielski sal_Int32 SAL_CALL Deflater::getTotalOut(  )
182*b1cdbd2cSJim Jagielski {
183*b1cdbd2cSJim Jagielski 	return pStream->total_out;
184*b1cdbd2cSJim Jagielski }
reset()185*b1cdbd2cSJim Jagielski void SAL_CALL Deflater::reset(  )
186*b1cdbd2cSJim Jagielski {
187*b1cdbd2cSJim Jagielski #if defined SYSTEM_ZLIB || !defined ZLIB_PREFIXB
188*b1cdbd2cSJim Jagielski 	deflateReset(pStream);
189*b1cdbd2cSJim Jagielski #else
190*b1cdbd2cSJim Jagielski 	z_deflateReset(pStream);
191*b1cdbd2cSJim Jagielski #endif
192*b1cdbd2cSJim Jagielski 	bFinish = sal_False;
193*b1cdbd2cSJim Jagielski 	bFinished = sal_False;
194*b1cdbd2cSJim Jagielski 	nOffset = nLength = 0;
195*b1cdbd2cSJim Jagielski }
end()196*b1cdbd2cSJim Jagielski void SAL_CALL Deflater::end(  )
197*b1cdbd2cSJim Jagielski {
198*b1cdbd2cSJim Jagielski 	if (pStream != NULL)
199*b1cdbd2cSJim Jagielski 	{
200*b1cdbd2cSJim Jagielski #if defined SYSTEM_ZLIB || !defined ZLIB_PREFIX
201*b1cdbd2cSJim Jagielski 		deflateEnd(pStream);
202*b1cdbd2cSJim Jagielski #else
203*b1cdbd2cSJim Jagielski 		z_deflateEnd(pStream);
204*b1cdbd2cSJim Jagielski #endif
205*b1cdbd2cSJim Jagielski 		delete pStream;
206*b1cdbd2cSJim Jagielski 	}
207*b1cdbd2cSJim Jagielski 	pStream = NULL;
208*b1cdbd2cSJim Jagielski }
209