xref: /AOO41X/main/package/source/zipapi/Inflater.cxx (revision a38728232e8c39f9058a1a2aa8ee4e6db7b8ca34)
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 
Inflater(sal_Bool bNoWrap)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 
~Inflater()69 Inflater::~Inflater()
70 {
71     end();
72 }
73 
setInput(const Sequence<sal_Int8> & rBuffer)74 void SAL_CALL Inflater::setInput( const Sequence< sal_Int8 >& rBuffer )
75 {
76     sInBuffer = rBuffer;
77     nOffset = 0;
78     nLength = rBuffer.getLength();
79 }
80 
needsDictionary()81 sal_Bool SAL_CALL Inflater::needsDictionary(  )
82 {
83     return bNeedDict;
84 }
85 
finished()86 sal_Bool SAL_CALL Inflater::finished(  )
87 {
88     return bFinished;
89 }
90 
doInflateSegment(Sequence<sal_Int8> & rBuffer,sal_Int32 nNewOffset,sal_Int32 nNewLength)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 
end()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 
doInflateBytes(Sequence<sal_Int8> & rBuffer,sal_Int32 nNewOffset,sal_Int32 nNewLength)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