summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--svx/inc/xmleohlp.hxx173
-rw-r--r--svx/prj/d.lst1
-rw-r--r--svx/source/xml/makefile.mk10
-rw-r--r--svx/source/xml/xmleohlp.cxx577
4 files changed, 757 insertions, 4 deletions
diff --git a/svx/inc/xmleohlp.hxx b/svx/inc/xmleohlp.hxx
new file mode 100644
index 000000000000..d55b9cffee55
--- /dev/null
+++ b/svx/inc/xmleohlp.hxx
@@ -0,0 +1,173 @@
+/*************************************************************************
+ *
+ * $RCSfile: xmleohlp.hxx,v $
+ *
+ * $Revision: 1.1 $
+ *
+ * last change: $Author: mib $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _XMLEOHLP_HXX
+#define _XMLEOHLP_HXX
+
+#ifndef _CPPUHELPER_COMPBASE1_HXX_
+#include <cppuhelper/compbase1.hxx>
+#endif
+#ifndef _OSL_MUTEX_HXX_
+#include <osl/mutex.hxx>
+#endif
+#ifndef _SVSTOR_HXX
+#include <so3/svstor.hxx>
+#endif
+#ifndef __SGI_STL_VECTOR
+#include <stl/vector>
+#endif
+
+#ifndef _COM_SUN_STAR_DOCUMENT_XEMBEDDEDOBJECTRESOLVER_HPP_
+#include <com/sun/star/document/XEmbeddedObjectResolver.hpp>
+#endif
+
+// -----------------------------
+// - SvXMLEmbeddedObjectHelper -
+// -----------------------------
+
+enum SvXMLEmbeddedObjectHelperMode
+{
+ EMBEDDEDOBJECTHELPER_MODE_READ = 0,
+ EMBEDDEDOBJECTHELPER_MODE_WRITE = 1
+};
+
+// -----------------------------
+// - SvXMLEmbeddedObjectHelper -
+// -----------------------------
+
+class SvPersist;
+class SvGlobalName;
+
+class SvXMLEmbeddedObjectHelper : public ::cppu::WeakComponentImplHelper1< ::com::sun::star::document::XEmbeddedObjectResolver >
+{
+private:
+
+ typedef ::_STL::vector< ::rtl::OUString > URLVector;
+
+ ::osl::Mutex maMutex;
+
+ const ::rtl::OUString maDefaultContainerStorageName;
+ ::rtl::OUString maCurContainerStorageName;
+
+ URLVector maEmbeddedObjectURLs;
+
+ SvStorage* mpRootStorage; // package
+ SvPersist* mpDocPersist;
+ SvStorageRef mxContainerStorage; // container sub package for
+ // objects
+ SvGlobalName** mpGlobalNameMap;
+
+
+ SvXMLEmbeddedObjectHelperMode meCreateMode;
+ void* mpDummy1;
+ void* mpDummy2;
+ BOOL mbDirect : 1;
+
+ sal_Bool ImplGetStorageNames(
+ const ::rtl::OUString& rURLStr,
+ ::rtl::OUString& rContainerStorageName,
+ ::rtl::OUString& rObjectStorageName,
+ sal_Bool bInternalToExternal ) const;
+ sal_uInt16 ImplGetFlags(
+ const SvGlobalName& rClassId ) const;
+ SvStorageRef ImplGetContainerStorage(
+ const ::rtl::OUString& rStorageName );
+ SvStorageRef ImplGetObjectStorage(
+ const ::rtl::OUString& rContainerStorageName,
+ const ::rtl::OUString& rObjectStorageName,
+ sal_Bool bUCBStorage );
+ String ImplGetUniqueName( SvStorage* pStg,
+ const sal_Char* p ) const;
+ sal_Bool ImplReadObject(
+ const ::rtl::OUString& rContainerStorageName,
+ const ::rtl::OUString& rObjName,
+ const SvGlobalName *pClassId );
+ sal_Bool ImplWriteObject(
+ const ::rtl::OUString& rContainerStorageName,
+ const ::rtl::OUString& rObjName );
+ ::rtl::OUString ImplInsertEmbeddedObjectURL(
+ const ::rtl::OUString& rURLStr );
+
+protected:
+
+ SvXMLEmbeddedObjectHelper();
+ ~SvXMLEmbeddedObjectHelper();
+ void Init( SvStorage& rRootStorage,
+ SvPersist& rDocPersist,
+ SvXMLEmbeddedObjectHelperMode eCreateMode,
+ sal_Bool bDirect );
+
+public:
+
+ static SvXMLEmbeddedObjectHelper* Create(
+ SvStorage& rRootStorage,
+ SvPersist& rDocPersist,
+ SvXMLEmbeddedObjectHelperMode eCreateMode,
+ sal_Bool bDirect = sal_True );
+ static void Destroy( SvXMLEmbeddedObjectHelper* pSvXMLEmbeddedObjectHelper );
+
+ void Flush();
+
+ // XEmbeddedObjectResolver
+ virtual ::rtl::OUString SAL_CALL resolveEmbeddedObjectURL( const ::rtl::OUString& aURL ) throw(::com::sun::star::uno::RuntimeException);
+};
+
+#endif
diff --git a/svx/prj/d.lst b/svx/prj/d.lst
index 3b25fa0eabb6..9f3c22e44fe4 100644
--- a/svx/prj/d.lst
+++ b/svx/prj/d.lst
@@ -561,6 +561,7 @@ hedabu: ..\inc\scriptspaceitem.hxx %_DEST%\inc%_EXT%\svx\scriptspaceitem.hxx
hedabu: ..\inc\hngpnctitem.hxx %_DEST%\inc%_EXT%\svx\hngpnctitem.hxx
hedabu: ..\inc\forbiddenruleitem.hxx %_DEST%\inc%_EXT%\svx\forbiddenruleitem.hxx
hedabu: ..\inc\xmlgrhlp.hxx %_DEST%\inc%_EXT%\svx\xmlgrhlp.hxx
+hedabu: ..\inc\xmleohlp.hxx %_DEST%\inc%_EXT%\svx\xmleohlp.hxx
..\xml\SvxDrawPage.xml %_DEST%\xml%_EXT%\SvxDrawPage.xml
..\xml\SvxGraphicObject.xml %_DEST%\xml%_EXT%\SvxGraphicObject.xml
diff --git a/svx/source/xml/makefile.mk b/svx/source/xml/makefile.mk
index 8732bf56adec..675792414305 100644
--- a/svx/source/xml/makefile.mk
+++ b/svx/source/xml/makefile.mk
@@ -2,9 +2,9 @@
#
# $RCSfile: makefile.mk,v $
#
-# $Revision: 1.1 $
+# $Revision: 1.2 $
#
-# last change: $Author: ka $ $Date: 2000-11-30 07:32:41 $
+# last change: $Author: mib $ $Date: 2001-01-26 11:22:09 $
#
# The Contents of this file are made available subject to the terms of
# either of the following licenses
@@ -71,10 +71,12 @@ TARGET=xml
# --- Files --------------------------------------------------------
SLOFILES = \
- $(SLO)$/xmlgrhlp.obj
+ $(SLO)$/xmlgrhlp.obj \
+ $(SLO)$/xmleohlp.obj
EXCEPTIONSFILES = \
- $(SLO)$/xmlgrhlp.obj
+ $(SLO)$/xmlgrhlp.obj \
+ $(SLO)$/xmleohlp.obj
# --- Targets --------------------------------------------------------------
diff --git a/svx/source/xml/xmleohlp.cxx b/svx/source/xml/xmleohlp.cxx
new file mode 100644
index 000000000000..b93c943f063f
--- /dev/null
+++ b/svx/source/xml/xmleohlp.cxx
@@ -0,0 +1,577 @@
+/*************************************************************************
+ *
+ * $RCSfile: xmleohlp.cxx,v $
+ *
+ * $Revision: 1.1 $
+ *
+ * last change: $Author: mib $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <stdio.h>
+
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#ifndef _SO_CLSIDS_HXX
+#include <so3/clsids.hxx>
+#endif
+#ifndef _PERSIST_HXX
+#include <so3/persist.hxx>
+#endif
+#ifndef _EMBOBJ_HXX
+#include <so3/embobj.hxx>
+#endif
+
+#ifndef _XMLEOHLP_HXX
+#include "xmleohlp.hxx"
+#endif
+
+// -----------
+// - Defines -
+// -----------
+
+using namespace ::rtl;
+using namespace ::osl;
+using namespace ::cppu;
+using namespace ::com::sun::star::document;
+using namespace ::com::sun::star::uno;
+
+#define XML_CONTAINERSTORAGE_NAME "Objects"
+#define XML_EMBEDDEDOBJECT_URL_BASE "vnd.sun.star.EmbeddedObject:"
+
+#define EO_FLAG_STAR_OBJECT 0x0001
+#define EO_FLAG_UCB_STORAGE 0x0002
+#define EO_FLAG_NEEDS_CONVERSION 0x0004
+
+struct ClassNameInfo
+{
+ struct GUIDDummy
+ {
+ sal_uInt32 n1;
+ sal_uInt16 n2, n3;
+ sal_uInt8 n4, n5, n6, n7, n8, n9, n10, n11;
+ } aGUID;
+ sal_uInt16 nFlags;
+};
+
+typedef SvGlobalName *SvGlobalNamePtr;
+
+static ClassNameInfo aFlagsMap[] =
+{
+ { SO3_SM_CLASSID_50, EO_FLAG_STAR_OBJECT|EO_FLAG_NEEDS_CONVERSION },
+ { SO3_SCH_CLASSID_50, EO_FLAG_STAR_OBJECT|EO_FLAG_NEEDS_CONVERSION },
+ { SO3_SIM_CLASSID_50 , EO_FLAG_STAR_OBJECT|EO_FLAG_NEEDS_CONVERSION },
+ { SO3_SDRAW_CLASSID_50, EO_FLAG_STAR_OBJECT|EO_FLAG_NEEDS_CONVERSION },
+ { SO3_SIMPRESS_CLASSID_50, EO_FLAG_STAR_OBJECT|EO_FLAG_NEEDS_CONVERSION },
+ { SO3_SC_CLASSID_50, EO_FLAG_STAR_OBJECT|EO_FLAG_NEEDS_CONVERSION },
+ { SO3_SW_CLASSID_50, EO_FLAG_STAR_OBJECT|EO_FLAG_NEEDS_CONVERSION },
+ { SO3_SWWEB_CLASSID_50, EO_FLAG_STAR_OBJECT|EO_FLAG_NEEDS_CONVERSION },
+ { SO3_SWGLOB_CLASSID_50, EO_FLAG_STAR_OBJECT|EO_FLAG_NEEDS_CONVERSION },
+
+ { SO3_SM_CLASSID_40, EO_FLAG_STAR_OBJECT|EO_FLAG_NEEDS_CONVERSION },
+ { SO3_SCH_CLASSID_40, EO_FLAG_STAR_OBJECT|EO_FLAG_NEEDS_CONVERSION },
+ { SO3_SIM_CLASSID_40 , EO_FLAG_STAR_OBJECT|EO_FLAG_NEEDS_CONVERSION },
+ { SO3_SIMPRESS_CLASSID_40, EO_FLAG_STAR_OBJECT|EO_FLAG_NEEDS_CONVERSION },
+ { SO3_SC_CLASSID_40, EO_FLAG_STAR_OBJECT|EO_FLAG_NEEDS_CONVERSION },
+ { SO3_SW_CLASSID_40, EO_FLAG_STAR_OBJECT|EO_FLAG_NEEDS_CONVERSION },
+ { SO3_SWWEB_CLASSID_40, EO_FLAG_STAR_OBJECT|EO_FLAG_NEEDS_CONVERSION },
+ { SO3_SWGLOB_CLASSID_40, EO_FLAG_STAR_OBJECT|EO_FLAG_NEEDS_CONVERSION },
+
+ { SO3_SM_CLASSID_30, EO_FLAG_STAR_OBJECT|EO_FLAG_NEEDS_CONVERSION },
+ { SO3_SCH_CLASSID_30, EO_FLAG_STAR_OBJECT|EO_FLAG_NEEDS_CONVERSION },
+ { SO3_SIM_CLASSID_30 , EO_FLAG_STAR_OBJECT|EO_FLAG_NEEDS_CONVERSION },
+ { SO3_SIMPRESS_CLASSID_30, EO_FLAG_STAR_OBJECT|EO_FLAG_NEEDS_CONVERSION },
+ { SO3_SC_CLASSID_30, EO_FLAG_STAR_OBJECT|EO_FLAG_NEEDS_CONVERSION },
+ { SO3_SW_CLASSID_30, EO_FLAG_STAR_OBJECT|EO_FLAG_NEEDS_CONVERSION }
+};
+
+// -----------------------------
+// - SvXMLEmbeddedObjectHelper -
+// -----------------------------
+
+SvXMLEmbeddedObjectHelper::SvXMLEmbeddedObjectHelper() :
+ WeakComponentImplHelper1< XEmbeddedObjectResolver >( maMutex ),
+ maDefaultContainerStorageName( RTL_CONSTASCII_USTRINGPARAM(XML_CONTAINERSTORAGE_NAME) ),
+ mpRootStorage( 0 ),
+ mpDocPersist( 0 ),
+ mpGlobalNameMap( 0 ),
+ meCreateMode( EMBEDDEDOBJECTHELPER_MODE_READ )
+{
+}
+
+// -----------------------------------------------------------------------------
+
+SvXMLEmbeddedObjectHelper::~SvXMLEmbeddedObjectHelper()
+{
+ if( mpGlobalNameMap )
+ {
+ size_t nCount = sizeof(aFlagsMap)/sizeof(ClassNameInfo);
+ SvGlobalNamePtr *p = mpGlobalNameMap;
+ while( nCount-- )
+ delete *p++;
+
+ delete mpGlobalNameMap;
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool SvXMLEmbeddedObjectHelper::ImplGetStorageNames(
+ const OUString& rURLStr,
+ OUString& rContainerStorageName,
+ OUString& rObjectStorageName,
+ sal_Bool bInternalToExternal ) const
+{
+ // internal URL: vnd.sun.star.EmbeddedObject:<object-name>
+ // or: vnd.sun.star.EmbeddedObject:<path>/<object-name>
+ // external URL: #./<path>/<object-name>
+ // or: #<path>/<object-name>
+ // or: #<object-name>
+ // currently, path may only consist of a single directory name
+ sal_Bool bRet = sal_False;
+
+ if( !rURLStr.getLength() )
+ return sal_False;
+
+ if( bInternalToExternal )
+ {
+ sal_Int32 nPos = rURLStr.indexOf( ':' );
+ if( -1 == nPos ||
+ 0 != rURLStr.compareToAscii( XML_EMBEDDEDOBJECT_URL_BASE,
+ sizeof( XML_EMBEDDEDOBJECT_URL_BASE ) -1 ) )
+ return sal_False;
+
+ sal_Int32 nPathStart = nPos + 1;
+ nPos = rURLStr.lastIndexOf( '/' );
+ if( -1 == nPos )
+ {
+ rContainerStorageName = maDefaultContainerStorageName;
+ rObjectStorageName = rURLStr.copy( nPathStart );
+ }
+ else if( nPos > nPathStart )
+ {
+ rContainerStorageName = rURLStr.copy( nPathStart, nPos-nPathStart);
+ rObjectStorageName = rURLStr.copy( nPos+1 );
+ }
+ else
+ return sal_False;
+ }
+ else
+ {
+ if( '#' != rURLStr[0 ] )
+ return sal_False;
+
+ sal_Int32 nPos = rURLStr.lastIndexOf( '/' );
+ if( -1 == nPos )
+ {
+ rContainerStorageName = OUString();
+ rObjectStorageName = rURLStr.copy( 1 );
+ }
+ else
+ {
+ sal_Int32 nPathStart = 1;
+ if( 0 == rURLStr.compareToAscii( "#./", 3 ) )
+ nPathStart = 3;
+ rContainerStorageName = rURLStr.copy( nPathStart, nPos-nPathStart);
+ rObjectStorageName = rURLStr.copy( nPos+1 );
+ }
+ }
+
+ if( -1 != rContainerStorageName.indexOf( '/' ) )
+ {
+ DBG_ERROR( "SvXMLEmbeddedObjectHelper: invalid path name" );
+ return sal_False;
+ }
+
+ return sal_True;
+}
+
+
+// -----------------------------------------------------------------------------
+
+sal_uInt16 SvXMLEmbeddedObjectHelper::ImplGetFlags(
+ const SvGlobalName& rClassId ) const
+{
+ size_t nCount = sizeof(aFlagsMap)/sizeof(ClassNameInfo);
+
+ if( !mpGlobalNameMap )
+ {
+ ((SvXMLEmbeddedObjectHelper *)this)->mpGlobalNameMap =
+ new SvGlobalNamePtr[nCount];
+ size_t i = nCount;
+ SvGlobalNamePtr *p = (SvGlobalNamePtr *)mpGlobalNameMap;
+ while( i-- )
+ *p++ = 0;
+ }
+
+ sal_uInt16 nFlags = 0;
+ SvGlobalNamePtr *pNames = (SvGlobalNamePtr *)mpGlobalNameMap;
+ const ClassNameInfo *pInfo = aFlagsMap;
+ while( nCount-- )
+ {
+ if( !*pNames )
+ *pNames = new SvGlobalName( pInfo->aGUID.n1, pInfo->aGUID.n2,
+ pInfo->aGUID.n3, pInfo->aGUID.n4,
+ pInfo->aGUID.n5, pInfo->aGUID.n6,
+ pInfo->aGUID.n7, pInfo->aGUID.n8,
+ pInfo->aGUID.n9, pInfo->aGUID.n10,
+ pInfo->aGUID.n11 );
+ if( **pNames == rClassId )
+ {
+ nFlags = pInfo->nFlags;
+ break;
+ }
+ pNames++;
+ pInfo++;
+ }
+
+ return nFlags;
+}
+
+SvStorageRef SvXMLEmbeddedObjectHelper::ImplGetContainerStorage(
+ const OUString& rStorageName )
+{
+ DBG_ASSERT( -1 == rStorageName.indexOf( '/' ) &&
+ -1 == rStorageName.indexOf( '\\' ),
+ "nested embedded storages aren't supported" );
+ if( !mxContainerStorage.Is() ||
+ ( rStorageName != maCurContainerStorageName ) )
+ {
+ if( mxContainerStorage.Is() &&
+ EMBEDDEDOBJECTHELPER_MODE_WRITE == meCreateMode )
+ mxContainerStorage->Commit();
+
+ StreamMode eMode = EMBEDDEDOBJECTHELPER_MODE_WRITE == meCreateMode
+ ? STREAM_STD_READWRITE
+ : STREAM_STD_READ;
+ mxContainerStorage = mpRootStorage->OpenUCBStorage( rStorageName,
+ eMode );
+ maCurContainerStorageName = rStorageName;
+ }
+
+ return mxContainerStorage;
+}
+
+// -----------------------------------------------------------------------------
+
+SvStorageRef SvXMLEmbeddedObjectHelper::ImplGetObjectStorage(
+ const OUString& rContainerStorageName,
+ const OUString& rObjectStorageName,
+ sal_Bool bUCBStorage )
+{
+ SvStorageRef xObjStor;
+ SvStorageRef xCntnrStor( ImplGetContainerStorage( rContainerStorageName ) );
+ if( xCntnrStor.Is() )
+ {
+ StreamMode eMode = EMBEDDEDOBJECTHELPER_MODE_WRITE == meCreateMode
+ ? STREAM_STD_READWRITE
+ : STREAM_STD_READ;
+ if( bUCBStorage )
+ xObjStor = xCntnrStor->OpenUCBStorage( rObjectStorageName, eMode );
+ else
+ xObjStor = xCntnrStor->OpenStorage( rObjectStorageName, eMode );
+ }
+
+ return xObjStor;
+}
+
+// -----------------------------------------------------------------------------
+
+String SvXMLEmbeddedObjectHelper::ImplGetUniqueName( SvStorage* pStg,
+ const sal_Char* p ) const
+{
+ String aName;
+ sal_Char cBuf[ 32 ];
+
+ static ULONG nId = (ULONG) cBuf;
+
+ nId++;
+ for( ;; )
+ {
+ sprintf( cBuf, "%s%08lX", p, nId );
+ aName.AssignAscii( cBuf );
+ if( !pStg->IsContained( aName ) )
+ break;
+ nId++;
+ }
+ return aName;
+}
+
+sal_Bool SvXMLEmbeddedObjectHelper::ImplReadObject(
+ const OUString& rContainerStorageName,
+ const OUString& rObjName,
+ const SvGlobalName *pClassId )
+{
+ SvStorageRef xDocStor( mpDocPersist->GetStorage() );
+
+ String aObjName( rObjName );
+ String aSrcObjName( aObjName );
+
+ // Is the object name unique?
+ if( mpDocPersist->GetObjectList() )
+ {
+ sal_uInt32 nCount = mpDocPersist->GetObjectList()->Count();
+ for( sal_uInt32 i = 0; i < nCount; i++ )
+ {
+ SvInfoObject* pTst = mpDocPersist->GetObjectList()->GetObject(i);
+ // TODO: unicode: is this correct?
+ if( aObjName.EqualsIgnoreCaseAscii( pTst->GetObjName() ) ||
+ aObjName.EqualsIgnoreCaseAscii( pTst->GetStorageName() ) )
+ {
+ aObjName = ImplGetUniqueName( xDocStor, "Obj" );
+ break;
+ }
+ }
+ }
+
+ SvStorageRef xCntnrStor( ImplGetContainerStorage(
+ rContainerStorageName ) );
+ if( !xCntnrStor.Is() )
+ return sal_False;
+
+ if( !xCntnrStor->CopyTo( aSrcObjName, xDocStor, aObjName ) )
+ return sal_False;
+
+ SvGlobalName aClassId;
+ if( pClassId )
+ {
+ aClassId = *pClassId;
+ }
+ else
+ {
+ SvStorageRef xObjStor( ImplGetObjectStorage( rContainerStorageName,
+ aSrcObjName, sal_False ) );
+ aClassId = xObjStor->GetClassName();
+ }
+
+ SvInfoObjectRef xInfo = new SvEmbeddedInfoObject( aObjName, aClassId );
+ mpDocPersist->Insert( xInfo );
+
+ return sal_True;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool SvXMLEmbeddedObjectHelper::ImplWriteObject(
+ const OUString& rContainerStorageName,
+ const OUString& rObjName )
+{
+ SvInfoObject *pInfo = mpDocPersist->Find( rObjName );
+ DBG_ASSERT( pInfo, "OLE object not found" );
+
+ if( !pInfo )
+ return sal_False;
+
+ // Get object type
+ sal_uInt16 nFlags = ImplGetFlags( pInfo->GetClassName() );
+
+ // If the objects needs a conversion it has to be loaded and stored
+ // again later. The same would apply if the save into an old format.
+ if( (nFlags & EO_FLAG_NEEDS_CONVERSION) != 0 )
+ mpDocPersist->GetObject( rObjName );
+
+
+ if( pInfo->GetPersist() )
+ {
+ // The object is loaded either because it is stored within the
+ // wrong file format or it has been modified
+ // Create either an UCB or an OLE storage, based on object's type
+ SvStorageRef xObjStor( ImplGetObjectStorage(
+ rContainerStorageName,
+ rObjName,
+ (nFlags&EO_FLAG_UCB_STORAGE) != 0 ) );
+ if( !xObjStor.Is() )
+ return sal_False;
+
+ // Save file (again)
+ xObjStor->SetVersion( mpRootStorage->GetVersion() );
+ if( !pInfo->GetPersist()->DoSaveAs( xObjStor ) )
+ return sal_False;
+
+ // Commit changes
+ if( !xObjStor->Commit() )
+ return sal_False;
+ }
+ else
+ {
+ SvStorageRef xCntnrStor( ImplGetContainerStorage(
+ rContainerStorageName ) );
+ if( !xCntnrStor.Is() )
+ return sal_False;
+
+ if( !mpDocPersist->GetStorage()->CopyTo( pInfo->GetStorageName(),
+ xCntnrStor, rObjName ) )
+ return sal_False;
+ }
+
+ return sal_True;
+}
+
+// -----------------------------------------------------------------------------
+
+OUString SvXMLEmbeddedObjectHelper::ImplInsertEmbeddedObjectURL(
+ const OUString& rURLStr )
+{
+ OUString sRetURL;
+
+ OUString aContainerStorageName, aObjectStorageName;
+ if( !ImplGetStorageNames( rURLStr, aContainerStorageName,
+ aObjectStorageName,
+ EMBEDDEDOBJECTHELPER_MODE_WRITE == meCreateMode ) )
+ return sRetURL;
+
+ if( EMBEDDEDOBJECTHELPER_MODE_READ == meCreateMode )
+ {
+ SvGlobalName aClassId, *pClassId = 0;
+ sal_Int32 nPos = aObjectStorageName.lastIndexOf( '!' );
+ if( -1 != nPos && aClassId.MakeId( aObjectStorageName.copy( nPos+1 ) ) )
+ {
+ aObjectStorageName = aObjectStorageName.copy( 0, nPos );
+ pClassId = &aClassId;
+ }
+ ImplReadObject( aContainerStorageName, aObjectStorageName, pClassId );
+ sRetURL = OUString( RTL_CONSTASCII_USTRINGPARAM(XML_EMBEDDEDOBJECT_URL_BASE ) );
+ sRetURL += aObjectStorageName;
+ }
+ else
+ {
+ if( mbDirect )
+ ImplWriteObject( aContainerStorageName, aObjectStorageName );
+ else
+ maEmbeddedObjectURLs.push_back( rURLStr );
+ sRetURL = OUString( RTL_CONSTASCII_USTRINGPARAM("#./") );
+ sRetURL += aContainerStorageName;
+ sRetURL += OUString( '/' );
+ sRetURL += aObjectStorageName;
+ }
+
+ return sRetURL;
+}
+
+// -----------------------------------------------------------------------------
+
+void SvXMLEmbeddedObjectHelper::Init(
+ SvStorage& rRootStorage,
+ SvPersist& rPersist,
+ SvXMLEmbeddedObjectHelperMode eCreateMode,
+ sal_Bool bDirect )
+{
+ mpRootStorage = &rRootStorage;
+ mpDocPersist = &rPersist;
+ meCreateMode = eCreateMode;
+ mbDirect = bDirect;
+}
+
+// -----------------------------------------------------------------------------
+
+SvXMLEmbeddedObjectHelper* SvXMLEmbeddedObjectHelper::Create(
+ SvStorage& rRootStorage,
+ SvPersist& rDocPersist,
+ SvXMLEmbeddedObjectHelperMode eCreateMode,
+ sal_Bool bDirect )
+{
+ SvXMLEmbeddedObjectHelper* pThis = new SvXMLEmbeddedObjectHelper;
+
+ pThis->acquire();
+ pThis->Init( rRootStorage, rDocPersist, eCreateMode, bDirect );
+
+ return pThis;
+}
+
+// -----------------------------------------------------------------------------
+
+void SvXMLEmbeddedObjectHelper::Destroy(
+ SvXMLEmbeddedObjectHelper* pSvXMLEmbeddedObjectHelper )
+{
+ if( pSvXMLEmbeddedObjectHelper )
+ {
+ pSvXMLEmbeddedObjectHelper->Flush();
+ pSvXMLEmbeddedObjectHelper->release();
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void SvXMLEmbeddedObjectHelper::Flush()
+{
+ if( ( EMBEDDEDOBJECTHELPER_MODE_WRITE == meCreateMode ) && !mbDirect )
+ {
+ OUString aContainerStorageName, aObjectStorageName;
+ URLVector::iterator aIter( maEmbeddedObjectURLs.begin() );
+ URLVector::iterator aEnd( maEmbeddedObjectURLs.end() );
+
+ while( aIter != aEnd )
+ {
+ if( ImplGetStorageNames( *aIter, aContainerStorageName,
+ aObjectStorageName, sal_True ) )
+ ImplWriteObject( aContainerStorageName, aObjectStorageName );
+ aIter++;
+ }
+ }
+
+ if( EMBEDDEDOBJECTHELPER_MODE_WRITE == meCreateMode &&
+ mxContainerStorage.Is() )
+ mxContainerStorage->Commit();
+}
+
+// XGraphicObjectResolver
+OUString SAL_CALL SvXMLEmbeddedObjectHelper::resolveEmbeddedObjectURL( const OUString& aURL )
+ throw(RuntimeException)
+{
+ MutexGuard aGuard( maMutex );
+
+ return ImplInsertEmbeddedObjectURL( aURL );
+}