From ad5fb8798b295e9ad706a3836ffb53a0630f752f Mon Sep 17 00:00:00 2001 From: Ashod Nakashian Date: Tue, 13 Nov 2018 01:24:40 -0500 Subject: [PATCH] LOK: Fix API for renderShapeSelection Unlike C++, C doesn't allow reference-to-pointer types, and we do have C code that wouldn't compile with ref-to-ptr. Had to change to ptr-to-ptr, which is the proper way of having output arrays. For the same reason, we cannot use new/delete, rather we must use malloc/free. Another (lesser) issue was that we used the renderShapeSelection API to echo back an array we give it as prefix. This made the API unecessarily complex (in undocumented ways) and forced the implementation to both worry about user-data and managing the input memory. This logic is best moved to the client and the API simply returns the output data. Speaking of returning data, the API now returns the size of the array it allocated and wrote to, so the client can do a simple check on the return value directly. Change-Id: Ida216c10d5b37efd1e0861e26b72cabb25c568e6 --- desktop/qa/desktop_lib/test_desktop_lib.cxx | 1 + desktop/source/lib/init.cxx | 50 ++++++++++++++++++----------- include/LibreOfficeKit/LibreOfficeKit.h | 4 +-- include/LibreOfficeKit/LibreOfficeKit.hxx | 7 ++-- 4 files changed, 37 insertions(+), 25 deletions(-) diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx index 81a51de8cde9..5bf343b8c825 100644 --- a/desktop/qa/desktop_lib/test_desktop_lib.cxx +++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx @@ -2459,6 +2459,7 @@ void DesktopLOKTest::testInsertCertificatePEM() comphelper::LibreOfficeKit::setActive(false); } + namespace { constexpr size_t documentClassOffset(int i) diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index 72af9accb971..90994a92c257 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -751,7 +751,7 @@ static bool doc_addCertificate(LibreOfficeKitDocument* pThis, static int doc_getSignatureState(LibreOfficeKitDocument* pThis); -static void doc_renderShapeSelection(LibreOfficeKitDocument* pThis, char*& pOutput, size_t& nOutputSize); +static size_t doc_renderShapeSelection(LibreOfficeKitDocument* pThis, char** pOutput); LibLODocument_Impl::LibLODocument_Impl(const uno::Reference &xComponent) : mxComponent(xComponent) @@ -2602,35 +2602,47 @@ static void doc_postWindowKeyEvent(LibreOfficeKitDocument* /*pThis*/, unsigned n } } -static void doc_renderShapeSelection(LibreOfficeKitDocument* pThis, char*& pOutput, size_t& nOutputSize) +static size_t doc_renderShapeSelection(LibreOfficeKitDocument* pThis, char** pOutput) { SolarMutexGuard aGuard; if (gImpl) gImpl->maLastExceptionMsg.clear(); - LibLODocument_Impl* pDocument = static_cast(pThis); - - uno::Reference xStorable(pDocument->mxComponent, uno::UNO_QUERY_THROW); + try + { + LibLODocument_Impl* pDocument = static_cast(pThis); - SvMemoryStream aOutStream; - uno::Reference < io::XOutputStream > xOut = new utl::OOutputStreamWrapper( aOutStream ); + uno::Reference xStorable(pDocument->mxComponent, uno::UNO_QUERY_THROW); - utl::MediaDescriptor aMediaDescriptor; - aMediaDescriptor["FilterName"] <<= OUString("impress_svg_Export"); - aMediaDescriptor["SelectionOnly"] <<= true; - aMediaDescriptor["OutputStream"] <<= xOut; + SvMemoryStream aOutStream; + uno::Reference xOut = new utl::OOutputStreamWrapper(aOutStream); - xStorable->storeToURL("private:stream", aMediaDescriptor.getAsConstPropertyValueList()); + utl::MediaDescriptor aMediaDescriptor; + aMediaDescriptor["FilterName"] <<= OUString("impress_svg_Export"); + aMediaDescriptor["SelectionOnly"] <<= true; + aMediaDescriptor["OutputStream"] <<= xOut; + xStorable->storeToURL("private:stream", aMediaDescriptor.getAsConstPropertyValueList()); - size_t nStreamSize = aOutStream.GetEndOfData(); - char* pTmp = pOutput; - pOutput = new char[nOutputSize + nStreamSize]; - std::memcpy(pOutput, pTmp, nOutputSize); - std::memcpy(pOutput+nOutputSize, aOutStream.GetData(), nStreamSize); + if (pOutput) + { + const size_t nOutputSize = aOutStream.GetEndOfData(); + *pOutput = static_cast(malloc(nOutputSize)); + if (*pOutput) + { + std::memcpy(*pOutput, aOutStream.GetData(), nOutputSize); + return nOutputSize; + } + } + } + catch (const uno::Exception& exception) + { + if (gImpl) + gImpl->maLastExceptionMsg = exception.Message; + SAL_WARN("lok", "Failed to render shape selection: " << exception); + } - nOutputSize += nStreamSize; - delete [] pTmp; + return 0; } /** Class to react on finishing of a dispatched command. diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h index 0da392467b84..4dd23a2cbc7a 100644 --- a/include/LibreOfficeKit/LibreOfficeKit.h +++ b/include/LibreOfficeKit/LibreOfficeKit.h @@ -348,9 +348,7 @@ struct _LibreOfficeKitDocumentClass int (*getSignatureState) (LibreOfficeKitDocument* pThis); /// @see lok::Document::renderShapeSelection - void (*renderShapeSelection) (LibreOfficeKitDocument* pThis, - char*& pOutput, - size_t& nOutputSize); + size_t (*renderShapeSelection)(LibreOfficeKitDocument* pThis, char** pOutput); #endif // defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY }; diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx index 865ad434417b..5d7771cf80b0 100644 --- a/include/LibreOfficeKit/LibreOfficeKit.hxx +++ b/include/LibreOfficeKit/LibreOfficeKit.hxx @@ -621,11 +621,12 @@ public: /** * Gets an image of the selected shapes. - * + * @param pOutput contains the result; use free to deallocate. + * @return the size ouf *pOutput in bytes. */ - void renderShapeSelection(char*& pOutput, size_t& nOutputSize) + size_t renderShapeSelection(char** pOutput) { - mpDoc->pClass->renderShapeSelection(mpDoc, pOutput, nOutputSize); + return mpDoc->pClass->renderShapeSelection(mpDoc, pOutput); } #endif // defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY -- 2.11.4.GIT