sw a11y: clang-format SidebarWinAccessible code
[LibreOffice.git] / vcl / source / graphic / BinaryDataContainer.cxx
blobf5ca4a4b309be57b470d52c23ef719557c243914
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 */
11 #include <vcl/BinaryDataContainer.hxx>
12 #include <o3tl/hash_combine.hxx>
13 #include <unotools/tempfile.hxx>
14 #include <comphelper/lok.hxx>
15 #include <comphelper/seqstream.hxx>
16 #include <sal/log.hxx>
18 #include <vector>
20 struct BinaryDataContainer::Impl
22 // temp file to store the data out of RAM if necessary
23 std::unique_ptr<utl::TempFileFast> mpFile;
24 // the binary data
25 std::shared_ptr<std::vector<sal_uInt8>> mpData;
27 Impl(SvStream& stream, size_t size) { readData(stream, size); }
29 /// Populate mpData from the stream
30 void readData(SvStream& stream, size_t size)
32 auto pData = std::make_shared<std::vector<sal_uInt8>>(size);
33 if (stream.ReadBytes(pData->data(), pData->size()) == size)
34 mpData = std::move(pData);
37 /// ensure the data is in-RAM
38 void ensureSwappedIn()
40 if (mpData || !mpFile)
41 return;
43 auto pStream = mpFile->GetStream(StreamMode::READ);
44 pStream->Seek(0);
45 readData(*pStream, pStream->remainingSize());
47 // Horrifying data loss ...
48 SAL_WARN_IF(pStream->GetError(), "vcl",
49 "Inconsistent system - failed to swap image back in");
52 void swapOut()
54 if (mpFile)
56 // we already have it swapped out.
57 mpData.reset();
58 return;
61 if (!mpData || mpData->empty())
62 return;
64 mpFile.reset(new utl::TempFileFast());
65 auto pStream = mpFile->GetStream(StreamMode::READWRITE);
67 pStream->WriteBytes(mpData->data(), mpData->size());
69 mpData.reset();
73 BinaryDataContainer::BinaryDataContainer(SvStream& stream, size_t size)
74 : mpImpl(new Impl(stream, size))
78 size_t BinaryDataContainer::calculateHash() const
80 size_t nSeed = 0;
81 if (mpImpl && mpImpl->mpData && !mpImpl->mpData->empty())
83 o3tl::hash_combine(nSeed, getSize());
84 for (sal_uInt8 const& rByte : *mpImpl->mpData)
85 o3tl::hash_combine(nSeed, rByte);
87 return nSeed;
90 css::uno::Sequence<sal_Int8> BinaryDataContainer::getCopyAsByteSequence() const
92 if (isEmpty())
93 return css::uno::Sequence<sal_Int8>();
94 assert(mpImpl);
96 css::uno::Sequence<sal_Int8> aData(getSize());
98 std::copy(mpImpl->mpData->cbegin(), mpImpl->mpData->cend(), aData.getArray());
100 return aData;
103 namespace
106 * Hold a reference on the internal state in case we swap out
107 * and free the vector while someone holds an SvStream pointer.
109 class ReferencedMemoryStream : public SvMemoryStream
111 std::shared_ptr<std::vector<sal_uInt8>> mpData;
113 public:
114 ReferencedMemoryStream(const std::shared_ptr<std::vector<sal_uInt8>>& pData)
115 : SvMemoryStream(pData->data(), pData->size(), StreamMode::READ)
116 , mpData(pData)
121 class ReferencedXInputStream : public comphelper::MemoryInputStream
123 std::shared_ptr<std::vector<sal_uInt8>> mpData;
125 public:
126 ReferencedXInputStream(const std::shared_ptr<std::vector<sal_uInt8>>& pData)
127 : comphelper::MemoryInputStream(reinterpret_cast<const sal_Int8*>(pData->data()),
128 pData->size())
129 , mpData(pData)
135 std::shared_ptr<SvStream> BinaryDataContainer::getAsStream()
137 ensureSwappedIn(); // TODO: transfer in streamed chunks
138 return std::make_shared<ReferencedMemoryStream>(mpImpl->mpData);
141 css::uno::Reference<css::io::XInputStream> BinaryDataContainer::getAsXInputStream()
143 ensureSwappedIn(); // TODO: transfer in streamed chunks
144 return new ReferencedXInputStream(mpImpl->mpData);
147 std::size_t BinaryDataContainer::writeToStream(SvStream& rStream) const
149 ensureSwappedIn(); // TODO: transfer in streamed chunks
150 return rStream.WriteBytes(getData(), getSize());
153 size_t BinaryDataContainer::getSize() const
155 ensureSwappedIn();
156 return mpImpl && mpImpl->mpData ? mpImpl->mpData->size() : 0;
159 size_t BinaryDataContainer::getSizeBytes() const
161 return mpImpl && mpImpl->mpData ? mpImpl->mpData->size() : 0;
164 bool BinaryDataContainer::isEmpty() const
166 ensureSwappedIn();
167 return !mpImpl || !mpImpl->mpData || mpImpl->mpData->empty();
170 const sal_uInt8* BinaryDataContainer::getData() const
172 ensureSwappedIn();
173 return mpImpl && mpImpl->mpData ? mpImpl->mpData->data() : nullptr;
176 void BinaryDataContainer::ensureSwappedIn() const
178 if (mpImpl)
179 mpImpl->ensureSwappedIn();
182 void BinaryDataContainer::swapOut() const
184 // Only bother reducing memory footprint in kit mode - for mobile/online etc.
185 if (!mpImpl || !comphelper::LibreOfficeKit::isActive())
186 return;
188 mpImpl->swapOut();
191 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */