xref: /AOO41X/main/package/source/zipapi/Deflater.cxx (revision a38728232e8c39f9058a1a2aa8ee4e6db7b8ca34)
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