/src/libreoffice/package/source/zipapi/InflateZlib.cxx
Line | Count | Source |
1 | | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ |
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 | | |
10 | | #include <package/InflateZlib.hxx> |
11 | | #include <string.h> |
12 | | #include <zlib.h> |
13 | | |
14 | | using namespace com::sun::star::uno; |
15 | | using namespace ZipUtils; |
16 | | |
17 | | InflateZlib::InflateZlib(bool bNoWrap) |
18 | 207k | : bFinished(false), |
19 | 207k | bNeedDict(false), |
20 | 207k | nOffset(0), |
21 | 207k | nLength(0), |
22 | 207k | nLastInflateError(0), |
23 | 207k | pStream(std::make_unique<z_stream>()) |
24 | 207k | { |
25 | 207k | memset(pStream.get(), 0, sizeof(*pStream)); |
26 | 207k | sal_Int32 nRes = inflateInit2(pStream.get(), bNoWrap ? -MAX_WBITS : MAX_WBITS); |
27 | 207k | switch (nRes) |
28 | 207k | { |
29 | 207k | case Z_OK: |
30 | 207k | break; |
31 | 0 | case Z_MEM_ERROR: |
32 | 0 | case Z_STREAM_ERROR: |
33 | 0 | pStream.reset(); |
34 | 0 | break; |
35 | 0 | default: |
36 | 0 | break; |
37 | 207k | } |
38 | 207k | } |
39 | | |
40 | | InflateZlib::~InflateZlib() |
41 | 207k | { |
42 | 207k | end(); |
43 | 207k | } |
44 | | |
45 | | void InflateZlib::setInput(const Sequence<sal_Int8>& rBuffer) |
46 | 206k | { |
47 | 206k | sInBuffer = rBuffer; |
48 | 206k | nOffset = 0; |
49 | 206k | nLength = rBuffer.getLength(); |
50 | 206k | } |
51 | | |
52 | | sal_Int32 InflateZlib::doInflateSegment(Sequence<sal_Int8>& rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength) |
53 | 428k | { |
54 | 428k | if (nNewOffset < 0 || nNewLength < 0 || nNewOffset + nNewLength > rBuffer.getLength()) |
55 | 0 | { |
56 | 0 | return 0; |
57 | 0 | } |
58 | 428k | return doInflateBytes(rBuffer, nNewOffset, nNewLength); |
59 | 428k | } |
60 | | |
61 | | void InflateZlib::end() |
62 | 207k | { |
63 | 207k | if (pStream) |
64 | 207k | { |
65 | 207k | #if !defined Z_PREFIX |
66 | 207k | inflateEnd(pStream.get()); |
67 | | #else |
68 | | z_inflateEnd(pStream.get()); |
69 | | #endif |
70 | 207k | pStream.reset(); |
71 | 207k | } |
72 | 207k | } |
73 | | |
74 | | sal_Int32 InflateZlib::doInflateBytes(Sequence<sal_Int8>& rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength) |
75 | 428k | { |
76 | 428k | if (!pStream) |
77 | 0 | { |
78 | 0 | nLastInflateError = Z_STREAM_ERROR; |
79 | 0 | return 0; |
80 | 0 | } |
81 | 428k | nLastInflateError = 0; |
82 | | |
83 | 428k | pStream->next_in = reinterpret_cast<const unsigned char*>(sInBuffer.getConstArray() + nOffset); |
84 | 428k | pStream->avail_in = nLength; |
85 | 428k | pStream->next_out = reinterpret_cast<unsigned char*>(rBuffer.getArray() + nNewOffset); |
86 | 428k | pStream->avail_out = nNewLength; |
87 | | |
88 | 428k | #if !defined Z_PREFIX |
89 | 428k | sal_Int32 nResult = ::inflate(pStream.get(), Z_PARTIAL_FLUSH); |
90 | | #else |
91 | | sal_Int32 nResult = ::z_inflate(pStream.get(), Z_PARTIAL_FLUSH); |
92 | | #endif |
93 | | |
94 | 428k | switch (nResult) |
95 | 428k | { |
96 | 180k | case Z_STREAM_END: |
97 | 180k | bFinished = true; |
98 | 180k | [[fallthrough]]; |
99 | 199k | case Z_OK: |
100 | 199k | nOffset += nLength - pStream->avail_in; |
101 | 199k | nLength = pStream->avail_in; |
102 | 199k | return nNewLength - pStream->avail_out; |
103 | 0 | case Z_NEED_DICT: |
104 | 0 | bNeedDict = true; |
105 | 0 | nOffset += nLength - pStream->avail_in; |
106 | 0 | nLength = pStream->avail_in; |
107 | 0 | return 0; |
108 | 228k | default: |
109 | 228k | if (nLength && nNewLength) |
110 | 21.7k | nLastInflateError = nResult; |
111 | 428k | } |
112 | 228k | return 0; |
113 | 428k | } |
114 | | |
115 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ |