include/vcl/BinaryDataContainer.hxx | 6 ++++-- vcl/inc/pdf/ExternalPDFStreams.hxx | 4 ++-- vcl/source/filter/graphicfilter.cxx | 8 ++++---- vcl/source/graphic/BinaryDataContainer.cxx | 23 +++++++++++++++++++++-- 4 files changed, 31 insertions(+), 10 deletions(-)
New commits: commit c55d5586304f23f9d8acbaffefba68a3a11c6175 Author: Michael Meeks <michael.me...@collabora.com> AuthorDate: Sat Apr 1 16:10:33 2023 +0100 Commit: Michael Meeks <michael.me...@collabora.com> CommitDate: Thu Apr 13 22:24:18 2023 +0200 BinaryDataContainer: hand out shared_ptr's to SvStreams. Hide the SvMemoryStream implementation detail better - this could be served from a file in future. Also couple lifecycle of the SvMemoryStream to the vector backing it. Change-Id: Ia9b28b57b8df4ce57286effd4d1753bf345fc10e Signed-off-by: Michael Meeks <michael.me...@collabora.com> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149917 Tested-by: Jenkins diff --git a/include/vcl/BinaryDataContainer.hxx b/include/vcl/BinaryDataContainer.hxx index 2e2e5d4b6264..e9e46a04e667 100644 --- a/include/vcl/BinaryDataContainer.hxx +++ b/include/vcl/BinaryDataContainer.hxx @@ -47,8 +47,10 @@ public: const sal_uInt8* getData() const; css::uno::Sequence<sal_Int8> getCopyAsByteSequence() const; - // Returns the data as a stream open for reading - SvMemoryStream getMemoryStream(); + // Returns the data as a readonly stream open for reading + std::shared_ptr<SvStream> getAsStream(); + + /// writes the contents to the given stream std::size_t writeToStream(SvStream& rStream) const; size_t calculateHash() const; diff --git a/vcl/inc/pdf/ExternalPDFStreams.hxx b/vcl/inc/pdf/ExternalPDFStreams.hxx index e2ddd58b91a5..b2936f01a898 100644 --- a/vcl/inc/pdf/ExternalPDFStreams.hxx +++ b/vcl/inc/pdf/ExternalPDFStreams.hxx @@ -38,9 +38,9 @@ struct VCL_DLLPUBLIC ExternalPDFStream { if (!mpPDFDocument) { - SvMemoryStream aPDFStream = maDataContainer.getMemoryStream(); + std::shared_ptr<SvStream> aPDFStream = maDataContainer.getAsStream(); auto pPDFDocument = std::make_shared<filter::PDFDocument>(); - if (!pPDFDocument->ReadWithPossibleFixup(aPDFStream)) + if (!pPDFDocument->ReadWithPossibleFixup(*aPDFStream)) { SAL_WARN("vcl.pdfwriter", "PDFWriterImpl::writeReferenceXObject: reading the PDF document failed"); diff --git a/vcl/source/filter/graphicfilter.cxx b/vcl/source/filter/graphicfilter.cxx index 53071f6dea76..e51b027be701 100644 --- a/vcl/source/filter/graphicfilter.cxx +++ b/vcl/source/filter/graphicfilter.cxx @@ -914,8 +914,8 @@ Graphic GraphicFilter::ImportUnloadedGraphic(SvStream& rIStream, sal_uInt64 size Size aLogicSize; if (eLinkType == GfxLinkType::NativeGif) { - SvMemoryStream aMemoryStream(aGraphicContent.getMemoryStream()); - bAnimated = IsGIFAnimated(aMemoryStream, aLogicSize); + std::shared_ptr<SvStream> pMemoryStream = aGraphicContent.getAsStream(); + bAnimated = IsGIFAnimated(*pMemoryStream, aLogicSize); if (!pSizeHint && aLogicSize.getWidth() && aLogicSize.getHeight()) { pSizeHint = &aLogicSize; @@ -954,8 +954,8 @@ ErrCode GraphicFilter::readPNG(SvStream & rStream, Graphic & rGraphic, GfxLinkTy if (auto aMSGifChunk = vcl::PngImageReader::getMicrosoftGifChunk(rStream); !aMSGifChunk.isEmpty()) { - SvMemoryStream aIStrm(aMSGifChunk.getMemoryStream()); - ImportGIF(aIStrm, rGraphic); + std::shared_ptr<SvStream> pIStrm(aMSGifChunk.getAsStream()); + ImportGIF(*pIStrm, rGraphic); rLinkType = GfxLinkType::NativeGif; rpGraphicContent = aMSGifChunk; return aReturnCode; diff --git a/vcl/source/graphic/BinaryDataContainer.cxx b/vcl/source/graphic/BinaryDataContainer.cxx index deb676a553f9..72d9bac27940 100644 --- a/vcl/source/graphic/BinaryDataContainer.cxx +++ b/vcl/source/graphic/BinaryDataContainer.cxx @@ -42,9 +42,28 @@ css::uno::Sequence<sal_Int8> BinaryDataContainer::getCopyAsByteSequence() const return aData; } -SvMemoryStream BinaryDataContainer::getMemoryStream() +namespace { - return SvMemoryStream(mpData ? mpData->data() : nullptr, getSize(), StreamMode::READ); +/* + * Hold a reference on the internal state in case we swap out + * and free the vector while someone holds an SvStream pointer. + */ +class ReferencedMemoryStream : public SvMemoryStream +{ + std::shared_ptr<std::vector<sal_uInt8>> mpData; + +public: + ReferencedMemoryStream(const std::shared_ptr<std::vector<sal_uInt8>>& rData) + : SvMemoryStream(rData ? rData->data() : nullptr, rData->size(), StreamMode::READ) + , mpData(rData) + { + } +}; +} + +std::shared_ptr<SvStream> BinaryDataContainer::getAsStream() +{ + return std::make_shared<ReferencedMemoryStream>(mpData); } std::size_t BinaryDataContainer::writeToStream(SvStream& rStream) const