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