Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <package/Deflater.hxx>
21 : #ifdef SYSTEM_ZLIB
22 : #include <zlib.h>
23 : #else
24 : #include <external/zlib/zlib.h>
25 : #endif
26 : #include <com/sun/star/packages/zip/ZipConstants.hpp>
27 : #include <string.h> // for memset
28 :
29 : using namespace com::sun::star::packages::zip::ZipConstants;
30 : using namespace com::sun::star;
31 : using namespace ZipUtils;
32 :
33 : /** Provides general purpose compression using the ZLIB compression
34 : * library.
35 : */
36 :
37 66 : Deflater::~Deflater(void)
38 : {
39 33 : end();
40 33 : }
41 33 : void Deflater::init (sal_Int32 nLevelArg, sal_Int32 nStrategyArg, sal_Bool bNowrap)
42 : {
43 33 : pStream = new z_stream;
44 : /* Memset it to 0...sets zalloc/zfree/opaque to NULL */
45 33 : memset (pStream, 0, sizeof(*pStream));
46 :
47 33 : switch (deflateInit2(pStream, nLevelArg, Z_DEFLATED, bNowrap? -MAX_WBITS : MAX_WBITS,
48 : DEF_MEM_LEVEL, nStrategyArg))
49 : {
50 : case Z_OK:
51 33 : break;
52 : case Z_MEM_ERROR:
53 0 : delete pStream;
54 0 : break;
55 : case Z_STREAM_ERROR:
56 0 : delete pStream;
57 0 : break;
58 : default:
59 0 : break;
60 : }
61 33 : }
62 :
63 33 : Deflater::Deflater(sal_Int32 nSetLevel, sal_Bool bNowrap)
64 : : bFinish(sal_False)
65 : , bFinished(sal_False)
66 : , bSetParams(sal_False)
67 : , nLevel(nSetLevel)
68 : , nStrategy(DEFAULT_STRATEGY)
69 : , nOffset(0)
70 33 : , nLength(0)
71 : {
72 33 : init(nSetLevel, DEFAULT_STRATEGY, bNowrap);
73 33 : }
74 :
75 527 : sal_Int32 Deflater::doDeflateBytes (uno::Sequence < sal_Int8 > &rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength)
76 : {
77 : sal_Int32 nResult;
78 527 : if (bSetParams)
79 : {
80 0 : pStream->next_in = (unsigned char*) sInBuffer.getConstArray() + nOffset;
81 0 : pStream->next_out = (unsigned char*) rBuffer.getArray()+nNewOffset;
82 0 : pStream->avail_in = nLength;
83 0 : pStream->avail_out = nNewLength;
84 :
85 : #if !defined Z_PREFIX
86 0 : nResult = deflateParams(pStream, nLevel, nStrategy);
87 : #else
88 : nResult = z_deflateParams(pStream, nLevel, nStrategy);
89 : #endif
90 0 : switch (nResult)
91 : {
92 : case Z_OK:
93 0 : bSetParams = sal_False;
94 0 : nOffset += nLength - pStream->avail_in;
95 0 : nLength = pStream->avail_in;
96 0 : return nNewLength - pStream->avail_out;
97 : case Z_BUF_ERROR:
98 0 : bSetParams = sal_False;
99 0 : return 0;
100 : default:
101 0 : return 0;
102 : }
103 : }
104 : else
105 : {
106 527 : pStream->next_in = (unsigned char*) sInBuffer.getConstArray() + nOffset;
107 527 : pStream->next_out = (unsigned char*) rBuffer.getArray()+nNewOffset;
108 527 : pStream->avail_in = nLength;
109 527 : pStream->avail_out = nNewLength;
110 :
111 : #if !defined Z_PREFIX
112 527 : nResult = deflate(pStream, bFinish ? Z_FINISH : Z_NO_FLUSH);
113 : #else
114 : nResult = z_deflate(pStream, bFinish ? Z_FINISH : Z_NO_FLUSH);
115 : #endif
116 527 : switch (nResult)
117 : {
118 : case Z_STREAM_END:
119 263 : bFinished = sal_True;
120 : case Z_OK:
121 527 : nOffset += nLength - pStream->avail_in;
122 527 : nLength = pStream->avail_in;
123 527 : return nNewLength - pStream->avail_out;
124 : case Z_BUF_ERROR:
125 0 : bSetParams = sal_False;
126 0 : return 0;
127 : default:
128 0 : return 0;
129 : }
130 : }
131 : }
132 :
133 267 : void SAL_CALL Deflater::setInputSegment( const uno::Sequence< sal_Int8 >& rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength )
134 : {
135 : OSL_ASSERT( !(nNewOffset < 0 || nNewLength < 0 || nNewOffset + nNewLength > rBuffer.getLength()));
136 :
137 267 : sInBuffer = rBuffer;
138 267 : nOffset = nNewOffset;
139 267 : nLength = nNewLength;
140 267 : }
141 33 : void SAL_CALL Deflater::setLevel( sal_Int32 nNewLevel )
142 : {
143 : if ((nNewLevel < 0 || nNewLevel > 9) && nNewLevel != DEFAULT_COMPRESSION)
144 : {
145 : // do error handling
146 : }
147 33 : if (nNewLevel != nLevel)
148 : {
149 0 : nLevel = nNewLevel;
150 0 : bSetParams = sal_True;
151 : }
152 33 : }
153 531 : sal_Bool SAL_CALL Deflater::needsInput( )
154 : {
155 531 : return nLength <=0;
156 : }
157 263 : void SAL_CALL Deflater::finish( )
158 : {
159 263 : bFinish = sal_True;
160 263 : }
161 1320 : sal_Bool SAL_CALL Deflater::finished( )
162 : {
163 1320 : return bFinished;
164 : }
165 527 : sal_Int32 SAL_CALL Deflater::doDeflateSegment( uno::Sequence< sal_Int8 >& rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength )
166 : {
167 : OSL_ASSERT( !(nNewOffset < 0 || nNewLength < 0 || nNewOffset + nNewLength > rBuffer.getLength()));
168 527 : return doDeflateBytes(rBuffer, nNewOffset, nNewLength);
169 : }
170 259 : sal_Int64 SAL_CALL Deflater::getTotalIn( )
171 : {
172 259 : return pStream->total_in; // FIXME64: zlib doesn't look 64bit clean here
173 : }
174 259 : sal_Int64 SAL_CALL Deflater::getTotalOut( )
175 : {
176 259 : return pStream->total_out; // FIXME64: zlib doesn't look 64bit clean here
177 : }
178 263 : void SAL_CALL Deflater::reset( )
179 : {
180 : #if !defined Z_PREFIX
181 263 : deflateReset(pStream);
182 : #else
183 : z_deflateReset(pStream);
184 : #endif
185 263 : bFinish = sal_False;
186 263 : bFinished = sal_False;
187 263 : nOffset = nLength = 0;
188 263 : }
189 33 : void SAL_CALL Deflater::end( )
190 : {
191 33 : if (pStream != NULL)
192 : {
193 : #if !defined Z_PREFIX
194 33 : deflateEnd(pStream);
195 : #else
196 : z_deflateEnd(pStream);
197 : #endif
198 33 : delete pStream;
199 : }
200 33 : pStream = NULL;
201 33 : }
202 :
203 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|