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