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 44 Deflater::~Deflater(void) 45 { 46 end(); 47 } 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 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 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 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 } 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 } 160 sal_Bool SAL_CALL Deflater::needsInput( ) 161 { 162 return nLength <=0; 163 } 164 void SAL_CALL Deflater::finish( ) 165 { 166 bFinish = sal_True; 167 } 168 sal_Bool SAL_CALL Deflater::finished( ) 169 { 170 return bFinished; 171 } 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 } 177 sal_Int32 SAL_CALL Deflater::getTotalIn( ) 178 { 179 return pStream->total_in; 180 } 181 sal_Int32 SAL_CALL Deflater::getTotalOut( ) 182 { 183 return pStream->total_out; 184 } 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 } 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