21#include <com/sun/star/io/XStream.hpp>
22#include <com/sun/star/beans/XPropertySet.hpp>
23#include <com/sun/star/embed/XTransactedObject.hpp>
24#include <com/sun/star/embed/ElementModes.hpp>
25#include <com/sun/star/embed/XEmbeddedObject.hpp>
26#include <com/sun/star/embed/XEmbedPersist.hpp>
27#include <com/sun/star/embed/EmbedStates.hpp>
28#include <com/sun/star/embed/Aspects.hpp>
29#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
30#include <osl/diagnose.h>
52using namespace ::
cppu;
70 Reference < XOutputStream >
xOut;
80 virtual void SAL_CALL
flush()
override;
87 : bStreamClosed( false )
104 std::scoped_lock aGuard(
maMutex );
110 std::scoped_lock aGuard(
maMutex );
116 std::scoped_lock aGuard(
maMutex );
122 mpDocPersist( nullptr ),
128 mpDocPersist( nullptr ),
131 Init(
nullptr, rDocPersist, eCreateMode );
148 OUString& rContainerStorageName,
149 OUString& rObjectStorageName)
151 DBG_ASSERT(_aURLNoPar.isEmpty() ||
'#' != _aURLNoPar[0],
"invalid object URL" );
152 OUString aURLNoPar = _aURLNoPar;
154 sal_Int32
_nPos = aURLNoPar.lastIndexOf(
'/' );
157 rContainerStorageName.clear();
158 rObjectStorageName = aURLNoPar;
166 sal_Int32 nStart = 0;
167 sal_Int32
nCount = aURLNoPar.getLength();
168 if( aURLNoPar.startsWith(
"./" ) )
175 sal_Int32 nEnd = aURLNoPar.lastIndexOf(
'/' );
176 if( nEnd == aURLNoPar.getLength()-1 && nEnd != (nStart-1) )
179 aURLNoPar = aURLNoPar.copy( nStart,
nCount );
182 _nPos = aURLNoPar.lastIndexOf(
'/' );
184 rContainerStorageName = aURLNoPar.copy( 0,
_nPos );
185 rObjectStorageName = aURLNoPar.copy(
_nPos+1 );
190 const OUString& rURLStr,
191 OUString& rContainerStorageName,
192 OUString& rObjectStorageName,
193 bool bInternalToExternal,
195 bool *pOasisFormat )
const
209 *pGraphicRepl =
false;
212 *pOasisFormat =
true;
214 if( rURLStr.isEmpty() )
218 sal_Int32
nPos = rURLStr.indexOf(
'?' );
224 aURLNoPar = rURLStr.copy( 0,
nPos );
228 while(
nPos >= 0 &&
nPos < rURLStr.getLength() )
230 OUString aToken = rURLStr.getToken( 0,
',',
nPos );
231 if ( aToken.equalsIgnoreAsciiCase(
"oasis=false" ) )
234 *pOasisFormat =
false;
239 SAL_WARN(
"svx",
"invalid arguments was found in URL!" );
244 if( bInternalToExternal )
246 nPos = aURLNoPar.indexOf(
':' );
250 bool bGrUrl = !bObjUrl &&
252 if( !(bObjUrl || bGrUrl) )
255 sal_Int32 nPathStart =
nPos + 1;
256 nPos = aURLNoPar.lastIndexOf(
'/' );
259 rContainerStorageName.clear();
260 rObjectStorageName = aURLNoPar.copy( nPathStart );
262 else if(
nPos > nPathStart )
264 rContainerStorageName = aURLNoPar.copy( nPathStart,
nPos-nPathStart);
265 rObjectStorageName = aURLNoPar.copy(
nPos+1 );
280 *pGraphicRepl =
true;
287 splitObjectURL(aURLNoPar, rContainerStorageName, rObjectStorageName);
290 if( -1 != rContainerStorageName.indexOf(
'/' ) )
292 OSL_FAIL(
"SvXMLEmbeddedObjectHelper: invalid path name" );
300 const OUString& rStorageName )
302 DBG_ASSERT( -1 == rStorageName.indexOf(
'/' ) &&
303 -1 == rStorageName.indexOf(
'\\' ),
304 "nested embedded storages aren't supported" );
312 uno::Reference < embed::XTransactedObject > xTrans(
mxContainerStorage, uno::UNO_QUERY );
320 ? ::embed::ElementModes::READWRITE
321 : ::embed::ElementModes::READ;
336 const OUString& rContainerStorageName,
344 if( !xCntnrStor.is() && !pTemp )
347 OUString aSrcObjName( rObjName );
354 DBG_ASSERT( !bDuplicate,
"An object in the document is referenced twice!" );
356 if( xDocStor != xCntnrStor || pTemp || bDuplicate )
369 uno::Reference < io::XStream > xStm = xDocStor->openStreamElement( rObjName,
370 embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
377 uno::Reference< beans::XPropertySet > xProps( xStm, uno::UNO_QUERY_THROW );
378 xProps->setPropertyValue(
380 uno::Any( OUString(
"application/vnd.sun.star.oleobject" ) ) );
382 xStm->getOutputStream()->closeOutput();
384 catch ( uno::Exception& )
393 xCntnrStor->copyElementTo( aSrcObjName, xDocStor, rObjName );
395 catch ( uno::Exception& )
404 OUString
aName( rObjName );
416 const OUString& rURLStr )
420 OUString aContainerStorageName, aObjectStorageName;
429 std::map< OUString, rtl::Reference<OutputStorageWrapper_Impl> >::iterator aIter;
434 if( aIter !=
mxStreamMap->end() && aIter->second.is() )
435 pOut = aIter->second.get();
439 sal_Int32
nPos = aObjectStorageName.lastIndexOf(
'!' );
440 if( -1 !=
nPos && aClassId.
MakeId( aObjectStorageName.subView(
nPos+1 ) ) )
442 aObjectStorageName = aObjectStorageName.copy( 0,
nPos );
443 pClassId = &aClassId;
446 ImplReadObject( aContainerStorageName, aObjectStorageName, pClassId,
pOut ?
pOut->GetStream() :
nullptr );
458 if( !aContainerStorageName.isEmpty() )
460 sRetURL += aContainerStorageName +
"/";
462 sRetURL += aObjectStorageName;
469 const uno::Reference< embed::XEmbeddedObject >& xObj )
471 uno::Reference< io::XInputStream >
xStream;
477 bool bSwitchBackToLoaded =
false;
478 sal_Int32 nCurState = xObj->getCurrentState();
479 if ( nCurState == embed::EmbedStates::LOADED || nCurState == embed::EmbedStates::RUNNING )
491 if ( nCurState == embed::EmbedStates::LOADED )
492 bSwitchBackToLoaded =
true;
496 embed::Aspects::MSOLE_CONTENT,
501 if ( bSwitchBackToLoaded )
503 xObj->changeState( embed::EmbedStates::LOADED );
505 catch( uno::Exception& )
513 const uno::Reference < embed::XStorage >& rRootStorage,
523 const uno::Reference < embed::XStorage >& rRootStorage,
529 pThis->Init( rRootStorage, rDocPersist, eCreateMode );
540 pThis->Init(
nullptr, rDocPersist, eCreateMode );
547 std::unique_lock aGuard(
m_aMutex );
561 throw WrappedTargetRuntimeException(
562 "SvXMLEmbeddedObjectHelper::resolveEmbeddedObjectURL non-RuntimeException",
570 const OUString& rURLStr )
572 std::unique_lock aGuard(
m_aMutex );
576 Reference < XOutputStream > xStrm;
580 if( aIter !=
mxStreamMap->end() && aIter->second.is() )
581 xStrm = aIter->second.get();
588 (*mxStreamMap)[rURLStr] = xOut;
596 bool bGraphicRepl =
false;
597 bool bOasisFormat =
true;
598 Reference < XInputStream > xStrm;
599 OUString aContainerStorageName, aObjectStorageName;
611 Reference < embed::XEmbeddedObject > xObj = rContainer.
GetEmbeddedObject( aObjectStorageName );
622 Reference < embed::XEmbedPersist > xPersist( xObj, UNO_QUERY );
628 Sequence < beans::PropertyValue > aDummy,
634 if ( xGrInStream.is() )
636 aEmbDescr.realloc( 2 );
637 auto pEmbDescr = aEmbDescr.getArray();
638 pEmbDescr[1].Name =
"VisualReplacement";
639 pEmbDescr[1].Value <<= xGrInStream;
645 Reference < io::XStream >
xStream =
648 embed::ElementModes::READ);
650 xStrm =
xStream->getInputStream();
655 catch ( uno::Exception& )
673 std::unique_lock aGuard(
m_aMutex );
680 OUString aContainerStorageName, aObjectStorageName;
687 return !aObjectStorageName.isEmpty() &&
695 std::unique_lock aGuard(
m_aMutex );
704 std::unique_lock aGuard(
m_aMutex );
Reference< XOutputStream > xOut
OutputStorageWrapper_Impl()
virtual void SAL_CALL writeBytes(const Sequence< sal_Int8 > &aData) override
virtual void SAL_CALL flush() override
virtual void SAL_CALL closeOutput() override
sal_Int32 GetVersion() const
bool MakeId(std::u16string_view rId)
SvStream & ReadStream(SvStream &rStream)
sal_uInt64 Seek(sal_uInt64 nPos)
SVX_DLLPRIVATE void ImplReadObject(const OUString &rContainerStorageName, OUString &rObjName, const SvGlobalName *pClassId, SvStream *pTemp)
OUString maCurContainerStorageName
virtual sal_Bool SAL_CALL hasByName(const OUString &aName) override
static rtl::Reference< SvXMLEmbeddedObjectHelper > Create(const css::uno::Reference< css::embed::XStorage > &, ::comphelper::IEmbeddedHelper &rDocPersist, SvXMLEmbeddedObjectHelperMode eCreateMode)
css::uno::Reference< css::embed::XStorage > mxRootStorage
virtual ~SvXMLEmbeddedObjectHelper() override
SvXMLEmbeddedObjectHelper()
virtual OUString SAL_CALL resolveEmbeddedObjectURL(const OUString &aURL) override
SVX_DLLPRIVATE css::uno::Reference< css::io::XInputStream > ImplGetReplacementImage(const css::uno::Reference< css::embed::XEmbeddedObject > &xObj)
SVX_DLLPRIVATE OUString ImplInsertEmbeddedObjectURL(const OUString &rURLStr)
::comphelper::IEmbeddedHelper * mpDocPersist
virtual sal_Bool SAL_CALL hasElements() override
virtual void disposing(std::unique_lock< std::mutex > &) override
virtual css::uno::Sequence< OUString > SAL_CALL getElementNames() override
std::optional< std::map< OUString, rtl::Reference< OutputStorageWrapper_Impl > > > mxStreamMap
virtual css::uno::Any SAL_CALL getByName(const OUString &aName) override
css::uno::Reference< css::embed::XStorage > mxTempStorage
virtual css::uno::Type SAL_CALL getElementType() override
void Init(const css::uno::Reference< css::embed::XStorage > &, ::comphelper::IEmbeddedHelper &rDocPersist, SvXMLEmbeddedObjectHelperMode eCreateMode)
SvXMLEmbeddedObjectHelperMode meCreateMode
css::uno::Reference< css::embed::XStorage > mxContainerStorage
SVX_DLLPRIVATE css::uno::Reference< css::embed::XStorage > const & ImplGetContainerStorage(const OUString &rStorageName)
SVX_DLLPRIVATE bool ImplGetStorageNames(const OUString &rURLStr, OUString &rContainerStorageName, OUString &rObjectStorageName, bool bInternalToExternal, bool *pGraphicRepl=nullptr, bool *pOasisFormat=nullptr) const
static void splitObjectURL(const OUString &aURLNoPar, OUString &rContainerStorageName, OUString &rObjectStorageName)
OUString CreateUniqueObjectName()
css::uno::Reference< css::io::XInputStream > GetGraphicStream(const css::uno::Reference< css::embed::XEmbeddedObject > &, OUString *pMediaType=nullptr)
bool HasEmbeddedObject(const OUString &)
bool HasEmbeddedObjects() const
css::uno::Reference< css::embed::XEmbeddedObject > GetEmbeddedObject(const OUString &, OUString const *pBaseURL=nullptr)
bool HasInstantiatedEmbeddedObject(const OUString &)
virtual EmbeddedObjectContainer & getEmbeddedObjectContainer() const=0
virtual css::uno::Reference< css::embed::XStorage > getStorage() const=0
virtual OUString getDocumentBaseURL() const=0
static css::uno::Reference< css::embed::XStorage > GetTemporaryStorage(const css::uno::Reference< css::uno::XComponentContext > &rxContext=css::uno::Reference< css::uno::XComponentContext >())
css::uno::Type const & get()
static css::uno::Reference< css::io::XInputStream > GetGraphicReplacementStream(sal_Int64 nViewAspect, const css::uno::Reference< css::embed::XEmbeddedObject > &, OUString *pMediaType) noexcept
static std::unique_ptr< SvStream > CreateStream(const OUString &rFileName, StreamMode eOpenMode, css::uno::Reference< css::awt::XWindow > xParentWin=nullptr)
#define DBG_ASSERT(sCon, aError)
#define SAL_WARN(area, stream)
constexpr OUStringLiteral aData
css::beans::PropertyValue makePropertyValue(const OUString &rName, T &&rValue)
Any SAL_CALL getCaughtException()
constexpr OUStringLiteral XML_CONTAINERSTORAGE_NAME
constexpr OUStringLiteral XML_EMBEDDEDOBJECT_URL_BASE
constexpr OUStringLiteral XML_CONTAINERSTORAGE_NAME_60
constexpr OUStringLiteral XML_EMBEDDEDOBJECTGRAPHIC_URL_BASE
SvXMLEmbeddedObjectHelperMode