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