LibreOffice Module package (master) 1
Deflater.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <package/Deflater.hxx>
21#include <zlib.h>
22#include <com/sun/star/packages/zip/ZipConstants.hpp>
23#include <osl/diagnose.h>
24#include <string.h>
25
26using namespace com::sun::star::packages::zip::ZipConstants;
27using namespace com::sun::star;
28using namespace ZipUtils;
29
34Deflater::~Deflater()
35{
36 end();
37}
38void Deflater::init (sal_Int32 nLevelArg, bool bNowrap)
39{
40 pStream.reset(new z_stream);
41 /* Memset it to 0...sets zalloc/zfree/opaque to NULL */
42 memset (pStream.get(), 0, sizeof(*pStream));
43
44 switch (deflateInit2(pStream.get(), nLevelArg, Z_DEFLATED, bNowrap? -MAX_WBITS : MAX_WBITS,
45 DEF_MEM_LEVEL, DEFAULT_STRATEGY))
46 {
47 case Z_OK:
48 break;
49 case Z_MEM_ERROR:
50 pStream.reset();
51 break;
52 case Z_STREAM_ERROR:
53 pStream.reset();
54 break;
55 default:
56 break;
57 }
58}
59
60Deflater::Deflater(sal_Int32 nSetLevel, bool bNowrap)
61: bFinish(false)
62, bFinished(false)
63, nOffset(0)
64, nLength(0)
65, nTotalOut64(0)
66, nTotalIn64(0)
67{
68 init(nSetLevel, bNowrap);
69}
70
71sal_Int32 Deflater::doDeflateBytes (uno::Sequence < sal_Int8 > &rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength)
72{
73 sal_Int32 nResult;
74 pStream->next_in = reinterpret_cast<const unsigned char*>( sInBuffer.getConstArray() + nOffset );
75 pStream->next_out = reinterpret_cast<unsigned char*>(rBuffer.getArray())+nNewOffset;
76 pStream->avail_in = nLength;
77 pStream->avail_out = nNewLength;
78 auto nLastTotalIn = pStream->total_in;
79 auto nLastTotalOut = pStream->total_out;
80
81#if !defined Z_PREFIX
82 nResult = deflate(pStream.get(), bFinish ? Z_FINISH : Z_NO_FLUSH);
83#else
84 nResult = z_deflate(pStream.get(), bFinish ? Z_FINISH : Z_NO_FLUSH);
85#endif
86 // total_in / total_out may stored only in 32bit, and can overflow during deflate
87 // 1 deflate call, uncompress only a few data, so only 1 overflow can happen at once.
88 if (pStream->total_in < nLastTotalIn)
89 {
90 nTotalIn64 += 0x100000000;
91 }
92 if (pStream->total_out < nLastTotalOut)
93 {
94 nTotalOut64 += 0x100000000;
95 }
96 switch (nResult)
97 {
98 case Z_STREAM_END:
99 bFinished = true;
100 [[fallthrough]];
101 case Z_OK:
102 nOffset += nLength - pStream->avail_in;
103 nLength = pStream->avail_in;
104 return nNewLength - pStream->avail_out;
105 default:
106 return 0;
107 }
108}
109
110void Deflater::setInputSegment( const uno::Sequence< sal_Int8 >& rBuffer )
111{
112 sInBuffer = rBuffer;
113 nOffset = 0;
114 nLength = rBuffer.getLength();
115}
116
118{
119 return nLength <=0;
120}
122{
123 bFinish = true;
124}
125sal_Int32 Deflater::doDeflateSegment( uno::Sequence< sal_Int8 >& rBuffer, sal_Int32 nNewLength )
126{
127 OSL_ASSERT( !(nNewLength < 0 || nNewLength > rBuffer.getLength()));
128 return doDeflateBytes(rBuffer, /*nNewOffset*/0, nNewLength);
129}
130sal_Int64 Deflater::getTotalIn() const
131{
132 return pStream->total_in + nTotalIn64;
133}
134sal_Int64 Deflater::getTotalOut() const
135{
136 return pStream->total_out + nTotalOut64;
137}
139{
140#if !defined Z_PREFIX
141 deflateReset(pStream.get());
142#else
143 z_deflateReset(pStream.get());
144#endif
145 bFinish = false;
146 bFinished = false;
147 nOffset = nLength = 0;
148}
150{
151 if (pStream)
152 {
153#if !defined Z_PREFIX
154 deflateEnd(pStream.get());
155#else
156 z_deflateEnd(pStream.get());
157#endif
158 pStream.reset();
159 }
160}
161
162/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_Int64 getTotalOut() const
Definition: Deflater.cxx:134
bool needsInput() const
Definition: Deflater.cxx:117
sal_Int64 getTotalIn() const
Definition: Deflater.cxx:130
sal_Int32 doDeflateSegment(css::uno::Sequence< sal_Int8 > &rBuffer, sal_Int32 nNewLength)
Definition: Deflater.cxx:125
Deflater(sal_Int32 nSetLevel, bool bNowrap)
Definition: Deflater.cxx:60
sal_Int32 doDeflateBytes(css::uno::Sequence< sal_Int8 > &rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength)
Definition: Deflater.cxx:71
sal_Int64 nLength
Definition: Deflater.hxx:38
void init(sal_Int32 nLevel, bool bNowrap)
Definition: Deflater.cxx:38
void setInputSegment(const css::uno::Sequence< sal_Int8 > &rBuffer)
Definition: Deflater.cxx:110
std::unique_ptr< z_stream > pStream
Definition: Deflater.hxx:41
sal_uInt64 nTotalOut64
Definition: Deflater.hxx:40
struct z_stream_s z_stream
Definition: Deflater.hxx:33
css::uno::Sequence< sal_Int8 > sInBuffer
Definition: Deflater.hxx:35
sal_Int64 nOffset
Definition: Deflater.hxx:38
sal_uInt64 nTotalIn64
Definition: Deflater.hxx:40
sal_Int32 nLength