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 <Inflater.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 <string.h> // for memset 35 36 using namespace com::sun::star::uno; 37 38 /** Provides general purpose decompression using the ZLIB library */ 39 40 Inflater::Inflater(sal_Bool bNoWrap) 41 : bFinished(sal_False), 42 bSetParams(sal_False), 43 bNeedDict(sal_False), 44 nOffset(0), 45 nLength(0), 46 nLastInflateError(0), 47 pStream(NULL) 48 { 49 pStream = new z_stream; 50 /* memset to 0 to set zalloc/opaque etc */ 51 memset (pStream, 0, sizeof(*pStream)); 52 sal_Int32 nRes; 53 nRes = inflateInit2(pStream, bNoWrap ? -MAX_WBITS : MAX_WBITS); 54 switch (nRes) 55 { 56 case Z_OK: 57 break; 58 case Z_MEM_ERROR: 59 delete pStream; 60 break; 61 case Z_STREAM_ERROR: 62 delete pStream; 63 break; 64 default: 65 break; 66 } 67 } 68 69 Inflater::~Inflater() 70 { 71 end(); 72 } 73 74 void SAL_CALL Inflater::setInput( const Sequence< sal_Int8 >& rBuffer ) 75 { 76 sInBuffer = rBuffer; 77 nOffset = 0; 78 nLength = rBuffer.getLength(); 79 } 80 81 sal_Bool SAL_CALL Inflater::needsDictionary( ) 82 { 83 return bNeedDict; 84 } 85 86 sal_Bool SAL_CALL Inflater::finished( ) 87 { 88 return bFinished; 89 } 90 91 sal_Int32 SAL_CALL Inflater::doInflateSegment( Sequence< sal_Int8 >& rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength ) 92 { 93 if (nNewOffset < 0 || nNewLength < 0 || nNewOffset + nNewLength > rBuffer.getLength()) 94 { 95 // do error handling 96 } 97 return doInflateBytes(rBuffer, nNewOffset, nNewLength); 98 } 99 100 void SAL_CALL Inflater::end( ) 101 { 102 if (pStream != NULL) 103 { 104 #if defined SYSTEM_ZLIB || !defined ZLIB_PREFIX 105 inflateEnd(pStream); 106 #else 107 z_inflateEnd(pStream); 108 #endif 109 delete pStream; 110 } 111 pStream = NULL; 112 } 113 114 sal_Int32 Inflater::doInflateBytes (Sequence < sal_Int8 > &rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength) 115 { 116 if ( !pStream ) 117 { 118 nLastInflateError = Z_STREAM_ERROR; 119 return 0; 120 } 121 122 nLastInflateError = 0; 123 124 pStream->next_in = ( unsigned char* ) ( sInBuffer.getConstArray() + nOffset ); 125 pStream->avail_in = nLength; 126 pStream->next_out = reinterpret_cast < unsigned char* > ( rBuffer.getArray() + nNewOffset ); 127 pStream->avail_out = nNewLength; 128 129 #if defined SYSTEM_ZLIB || !defined ZLIB_PREFIX 130 sal_Int32 nResult = ::inflate(pStream, Z_PARTIAL_FLUSH); 131 #else 132 sal_Int32 nResult = ::z_inflate(pStream, Z_PARTIAL_FLUSH); 133 #endif 134 135 switch (nResult) 136 { 137 case Z_STREAM_END: 138 bFinished = sal_True; 139 case Z_OK: 140 nOffset += nLength - pStream->avail_in; 141 nLength = pStream->avail_in; 142 return nNewLength - pStream->avail_out; 143 144 case Z_NEED_DICT: 145 bNeedDict = sal_True; 146 nOffset += nLength - pStream->avail_in; 147 nLength = pStream->avail_in; 148 return 0; 149 150 default: 151 // it is no error, if there is no input or no output 152 if ( nLength && nNewLength ) 153 nLastInflateError = nResult; 154 } 155 156 return 0; 157 } 158 159