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