summaryrefslogtreecommitdiff
path: root/sot
diff options
context:
space:
mode:
Diffstat (limited to 'sot')
-rw-r--r--sot/inc/absdev.hxx48
-rw-r--r--sot/inc/agg.hxx68
-rw-r--r--sot/inc/clsids.hxx33
-rw-r--r--sot/inc/filelist.hxx76
-rw-r--r--sot/inc/makefile.mk48
-rw-r--r--sot/inc/pch/precompiled_sot.cxx29
-rw-r--r--sot/inc/pch/precompiled_sot.hxx32
-rw-r--r--sot/inc/sot/exchange.hxx253
-rw-r--r--sot/inc/sot/factory.hxx91
-rw-r--r--sot/inc/sot/formats.hxx191
-rw-r--r--sot/inc/sot/object.hxx470
-rw-r--r--sot/inc/sot/sotdata.hxx60
-rw-r--r--sot/inc/sot/sotdllapi.h41
-rw-r--r--sot/inc/sot/sotref.hxx77
-rw-r--r--sot/inc/sot/storage.hxx272
-rw-r--r--sot/inc/stg.hxx398
-rw-r--r--sot/inc/storinfo.hxx72
-rw-r--r--sot/prj/build.lst8
-rw-r--r--sot/prj/d.lst28
-rw-r--r--sot/qa/complex/olesimplestorage/OLESimpleStorageTest.java5
-rw-r--r--sot/qa/complex/olesimplestorage/OLESimpleStorageUnitTest.java67
-rw-r--r--sot/qa/complex/olesimplestorage/Test01.java126
-rw-r--r--sot/qa/complex/olesimplestorage/TestHelper.java26
-rw-r--r--sot/qa/complex/olesimplestorage/makefile.mk84
-rw-r--r--sot/source/base/exchange.cxx508
-rw-r--r--sot/source/base/factory.cxx406
-rw-r--r--sot/source/base/filelist.cxx199
-rw-r--r--sot/source/base/formats.cxx1663
-rw-r--r--sot/source/base/makefile.mk58
-rw-r--r--sot/source/base/object.cxx489
-rw-r--r--sot/source/sdstor/makefile.mk64
-rw-r--r--sot/source/sdstor/stg.cxx1091
-rw-r--r--sot/source/sdstor/stgavl.cxx419
-rw-r--r--sot/source/sdstor/stgavl.hxx79
-rw-r--r--sot/source/sdstor/stgcache.cxx546
-rw-r--r--sot/source/sdstor/stgcache.hxx132
-rw-r--r--sot/source/sdstor/stgdir.cxx1054
-rw-r--r--sot/source/sdstor/stgdir.hxx132
-rw-r--r--sot/source/sdstor/stgelem.cxx425
-rw-r--r--sot/source/sdstor/stgelem.hxx166
-rw-r--r--sot/source/sdstor/stgio.cxx389
-rw-r--r--sot/source/sdstor/stgio.hxx80
-rw-r--r--sot/source/sdstor/stgole.cxx230
-rw-r--r--sot/source/sdstor/stgole.hxx77
-rw-r--r--sot/source/sdstor/stgstrms.cxx1241
-rw-r--r--sot/source/sdstor/stgstrms.hxx170
-rw-r--r--sot/source/sdstor/storage.cxx1563
-rw-r--r--sot/source/sdstor/storinfo.cxx111
-rw-r--r--sot/source/sdstor/ucbstorage.cxx3600
-rw-r--r--sot/source/sdstor/unostorageholder.cxx197
-rw-r--r--sot/source/sdstor/unostorageholder.hxx77
-rw-r--r--sot/source/unoolestorage/makefile.mk51
-rw-r--r--sot/source/unoolestorage/register.cxx73
-rw-r--r--sot/source/unoolestorage/xolesimplestorage.cxx811
-rw-r--r--sot/source/unoolestorage/xolesimplestorage.hxx195
-rw-r--r--sot/util/makefile.mk89
-rw-r--r--sot/util/makefile.pmk31
-rw-r--r--sot/util/sot.component34
-rw-r--r--sot/util/sot.flt6
-rw-r--r--sot/workben/makefile.mk53
-rw-r--r--sot/workben/testsot.cxx55
61 files changed, 19167 insertions, 0 deletions
diff --git a/sot/inc/absdev.hxx b/sot/inc/absdev.hxx
new file mode 100644
index 000000000000..3d251d98e0b6
--- /dev/null
+++ b/sot/inc/absdev.hxx
@@ -0,0 +1,48 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SOT_ABSDEV_HXX
+#define _SOT_ABSDEV_HXX
+
+#ifndef _TOOLS_SOLAR_H
+#include <tools/solar.h>
+#endif
+
+class JobSetup;
+class AbstractDeviceData
+{
+protected:
+ JobSetup * pJobSetup;
+public:
+ virtual ~AbstractDeviceData() {}
+ virtual AbstractDeviceData * Copy() const = 0;
+ virtual BOOL Equals( const AbstractDeviceData & ) const = 0;
+
+ JobSetup * GetJobSetup() const { return pJobSetup; }
+};
+
+#endif // _SOT_ABSDEV_HXX
diff --git a/sot/inc/agg.hxx b/sot/inc/agg.hxx
new file mode 100644
index 000000000000..2f8cc7587458
--- /dev/null
+++ b/sot/inc/agg.hxx
@@ -0,0 +1,68 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SOT_AGG_HXX
+#define _SOT_AGG_HXX
+
+#include <tools/ownlist.hxx>
+
+/************** class SvAggregate ***************************************/
+/************************************************************************/
+class SotFactory;
+class SotObject;
+struct SvAggregate
+{
+ union
+ {
+ SotFactory * pFact;
+ SotObject * pObj;
+ };
+ BOOL bFactory;
+ BOOL bMainObj; // TRUE, das Objekt, welches das casting steuert
+
+ SvAggregate()
+ : pFact( NULL )
+ , bFactory( FALSE )
+ , bMainObj( FALSE ) {}
+ SvAggregate( SotObject * pObjP, BOOL bMainP )
+ : pObj( pObjP )
+ , bFactory( FALSE )
+ , bMainObj( bMainP ) {}
+ SvAggregate( SotFactory * pFactP )
+ : pFact( pFactP )
+ , bFactory( TRUE )
+ , bMainObj( FALSE ) {}
+};
+
+/************** class SvAggregateMemberList *****************************/
+/************************************************************************/
+class SvAggregateMemberList
+{
+ PRV_SV_DECL_OWNER_LIST(SvAggregateMemberList,SvAggregate)
+};
+
+#endif // _AGG_HXX
diff --git a/sot/inc/clsids.hxx b/sot/inc/clsids.hxx
new file mode 100644
index 000000000000..a64df510dd07
--- /dev/null
+++ b/sot/inc/clsids.hxx
@@ -0,0 +1,33 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _SOT_CLSIDS_HXX
+#define _SOT_CLSIDS_HXX
+
+// all the definitions of the class ids are moved to the comphelper
+#include <comphelper/classids.hxx>
+
+#endif
diff --git a/sot/inc/filelist.hxx b/sot/inc/filelist.hxx
new file mode 100644
index 000000000000..4c6c55534319
--- /dev/null
+++ b/sot/inc/filelist.hxx
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _FILELIST_HXX
+#define _FILELIST_HXX
+
+#include <tools/stream.hxx>
+#include "sot/sotdllapi.h"
+
+class FileStringList;
+
+class SOT_DLLPUBLIC FileList : public SvDataCopyStream
+{
+ FileStringList* pStrList;
+
+protected:
+
+ // SvData-Methoden
+ virtual void Load( SvStream& );
+ virtual void Save( SvStream& );
+ virtual void Assign( const SvDataCopyStream& );
+
+ // Liste loeschen;
+ void ClearAll( void );
+
+public:
+
+ TYPEINFO();
+ FileList();
+ ~FileList();
+
+ // Zuweisungsoperator
+ FileList& operator=( const FileList& rFileList );
+
+
+ // Im-/Export
+ SOT_DLLPUBLIC friend SvStream& operator<<( SvStream& rOStm, const FileList& rFileList );
+ SOT_DLLPUBLIC friend SvStream& operator>>( SvStream& rIStm, FileList& rFileList );
+
+ // Clipboard, D&D usw.
+ static ULONG GetFormat();
+
+
+ // Liste fuellen/abfragen
+ void AppendFile( const String& rStr );
+ String GetFile( ULONG i ) const;
+ ULONG Count( void ) const;
+
+};
+
+#endif // _FILELIST_HXX
+
diff --git a/sot/inc/makefile.mk b/sot/inc/makefile.mk
new file mode 100644
index 000000000000..bc31cd07e06b
--- /dev/null
+++ b/sot/inc/makefile.mk
@@ -0,0 +1,48 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+PRJ=..
+
+PRJNAME=sot
+TARGET=inc
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
+.IF "$(ENABLE_PCH)"!=""
+ALLTAR : \
+ $(SLO)$/precompiled.pch \
+ $(SLO)$/precompiled_ex.pch
+
+.ENDIF # "$(ENABLE_PCH)"!=""
+
diff --git a/sot/inc/pch/precompiled_sot.cxx b/sot/inc/pch/precompiled_sot.cxx
new file mode 100644
index 000000000000..fea8683f8074
--- /dev/null
+++ b/sot/inc/pch/precompiled_sot.cxx
@@ -0,0 +1,29 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "precompiled_sot.hxx"
+
diff --git a/sot/inc/pch/precompiled_sot.hxx b/sot/inc/pch/precompiled_sot.hxx
new file mode 100644
index 000000000000..4edee1275640
--- /dev/null
+++ b/sot/inc/pch/precompiled_sot.hxx
@@ -0,0 +1,32 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): Generated on 2006-09-01 17:50:02.092358
+
+#ifdef PRECOMPILED_HEADERS
+#endif
+
diff --git a/sot/inc/sot/exchange.hxx b/sot/inc/sot/exchange.hxx
new file mode 100644
index 000000000000..dc67e72a4f82
--- /dev/null
+++ b/sot/inc/sot/exchange.hxx
@@ -0,0 +1,253 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SOT_EXCHANGE_HXX
+#define _SOT_EXCHANGE_HXX
+
+#ifndef __SGI_STL_LIST
+#include <list>
+#endif
+#ifndef __SGI_STL_VECTOR
+#include <vector>
+#endif
+#include <tools/string.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/datatransfer/DataFlavor.hpp>
+#ifndef _COM_SUN_STAR_DATATRANSFER_DND_DNDCONSTANTS_HDL_
+#include <com/sun/star/datatransfer/dnd/DNDConstants.hdl>
+#endif
+#include "sot/sotdllapi.h"
+
+class SotDataObject;
+
+namespace com { namespace sun { namespace star { namespace datatransfer {
+ class XTransferable;
+} } } }
+
+// ---------------------
+// - SotFormatStringId -
+// ---------------------
+
+typedef ULONG SotFormatStringId;
+
+// ----------------
+// - DataFlavorEx -
+// ----------------
+
+struct DataFlavorEx : public ::com::sun::star::datatransfer::DataFlavor
+{
+ SotFormatStringId mnSotId;
+};
+
+typedef ::std::vector< ::com::sun::star::datatransfer::DataFlavor > DataFlavorVector;
+typedef ::std::vector< DataFlavorEx > _DataFlavorExVector;
+
+// JP 23.03.2001 - this struct is only for "hide" the STD of the vetor,
+// because our makefile filter all this symbols and so nowbody can use
+// these struct in any interfacses.
+struct DataFlavorExVector : public _DataFlavorExVector
+{
+};
+
+typedef ::std::list< ::com::sun::star::datatransfer::DataFlavor > DataFlavorList;
+typedef ::std::list< DataFlavorEx > DataFlavorExList;
+
+SOT_DLLPUBLIC sal_Bool IsFormatSupported( const DataFlavorExVector& rDataFlavorExVector,
+ ULONG nId );
+
+// -------------------------
+// - Vordefinierte Formate -
+// -------------------------
+
+// Die Reihenfolge und die Werte dürfen nicht geändert werden,
+// da die Implementation sich darauf verläßt.
+// Standard-Formate fuer die es auch Copy/Paste-Methoden gibt
+#define FORMAT_STRING 1
+#define FORMAT_BITMAP 2
+#define FORMAT_GDIMETAFILE 3
+#define FORMAT_PRIVATE 4
+#define FORMAT_FILE 5
+#define FORMAT_FILE_LIST 6
+
+// Weitere Standardformate (diese gehen nur ueber CopyData/PasteData)
+#define FORMAT_RTF 10
+
+// Source-Options
+#define EXCHG_SOURCE_MOVEABLE ((USHORT)0x0001)
+#define EXCHG_SOURCE_COPYABLE ((USHORT)0x0002)
+#define EXCHG_SOURCE_LINKABLE ((USHORT)0x0004)
+#define EXCHG_SOURCE_PRINTABLE ((USHORT)0x0008)
+#define EXCHG_SOURCE_DISCARDABLE ((USHORT)0x0010)
+#define EXCHG_SOURCE_ALL ((USHORT)0x001F)
+#define EXCHG_SOURCE_DEF_COPYABLE ((USHORT)0x0020)
+
+// Aktionen
+#define EXCHG_ACTION_MASK ((USHORT)0x00FF)
+#define EXCHG_INOUT_ACTION_NONE ((USHORT)com::sun::star::datatransfer::dnd::DNDConstants::ACTION_NONE)
+#define EXCHG_IN_ACTION_DEFAULT EXCHG_INOUT_ACTION_NONE
+#define EXCHG_IN_ACTION_MOVE ((USHORT)com::sun::star::datatransfer::dnd::DNDConstants::ACTION_MOVE)
+#define EXCHG_IN_ACTION_COPY ((USHORT)com::sun::star::datatransfer::dnd::DNDConstants::ACTION_COPY)
+#define EXCHG_IN_ACTION_LINK ((USHORT)com::sun::star::datatransfer::dnd::DNDConstants::ACTION_LINK)
+#define EXCHG_INOUT_ACTION_PRINT ((USHORT)8)
+#define EXCHG_INOUT_ACTION_DISCARD ((USHORT)16)
+#define EXCHG_OUT_ACTION_INSERT_OBJ ((USHORT)17)
+#define EXCHG_OUT_ACTION_INSERT_BOOKMARK ((USHORT)18)
+#define EXCHG_OUT_ACTION_INSERT_FILELINK ((USHORT)19)
+#define EXCHG_OUT_ACTION_INSERT_FILE ((USHORT)20)
+#define EXCHG_OUT_ACTION_INSERT_FILELIST ((USHORT)21)
+#define EXCHG_OUT_ACTION_INSERT_IMAGEMAP ((USHORT)22)
+#define EXCHG_OUT_ACTION_INSERT_OLE ((USHORT)23)
+#define EXCHG_OUT_ACTION_INSERT_INTERACTIVE ((USHORT)24)
+#define EXCHG_OUT_ACTION_INSERT_URLBUTTON ((USHORT)25)
+#define EXCHG_OUT_ACTION_INSERT_CHAOSOBJ ((USHORT)26) // OBSOLET ab 500.b ?
+#define EXCHG_OUT_ACTION_REPLACE_OBJ ((USHORT)27)
+#define EXCHG_OUT_ACTION_REPLACE_LINK ((USHORT)28)
+#define EXCHG_OUT_ACTION_REPLACE_IMAGEMAP ((USHORT)29)
+#define EXCHG_OUT_ACTION_GET_ATTRIBUTES ((USHORT)30)
+#define EXCHG_OUT_ACTION_UPLOAD ((USHORT)31) // OBSOLET ab 500.b ?
+#define EXCHG_OUT_ACTION_MOVE_FILE ((USHORT)32)
+#define EXCHG_OUT_ACTION_MOVE_FILELIST ((USHORT)33)
+#define EXCHG_OUT_ACTION_UPDATE_RANGE ((USHORT)34)
+#define EXCHG_OUT_ACTION_INSERT_PRIVATE ((USHORT)35)
+#define EXCHG_OUT_ACTION_INSERT_HTML ((USHORT)36)
+#define EXCHG_OUT_ACTION_MOVE_PRIVATE ((USHORT)37)
+#define EXCHG_OUT_ACTION_INSERT_STRING ((USHORT)38)
+#define EXCHG_OUT_ACTION_INSERT_DRAWOBJ ((USHORT)39)
+#define EXCHG_OUT_ACTION_INSERT_SVXB ((USHORT)40)
+#define EXCHG_OUT_ACTION_INSERT_GDIMETAFILE ((USHORT)41)
+#define EXCHG_OUT_ACTION_INSERT_BITMAP ((USHORT)42)
+#define EXCHG_OUT_ACTION_INSERT_DDE ((USHORT)43)
+#define EXCHG_OUT_ACTION_INSERT_HYPERLINK ((USHORT)44)
+#define EXCHG_OUT_ACTION_REPLACE_DRAWOBJ ((USHORT)45)
+#define EXCHG_OUT_ACTION_REPLACE_SVXB ((USHORT)46)
+#define EXCHG_OUT_ACTION_REPLACE_GDIMETAFILE ((USHORT)47)
+#define EXCHG_OUT_ACTION_REPLACE_BITMAP ((USHORT)48)
+#define EXCHG_OUT_ACTION_REPLACE_GRAPH ((USHORT)49)
+#define EXCHG_OUT_ACTION_INSERT_GRAPH ((USHORT)50)
+#define EXCHG_OUT_ACTION_INSERT_MSGATTACH ((USHORT)51) // obsolet ab 500.b ?
+#define EXCHG_OUT_ACTION_COPY_CHAOSOBJ ((USHORT)52)
+#define EXCHG_OUT_ACTION_MOVE_CHAOSOBJ ((USHORT)53)
+#define EXCHG_OUT_ACTION_COPY_MSGATTACH ((USHORT)54)
+#define EXCHG_OUT_ACTION_COPY_BOOKMARK ((USHORT)55)
+#define EXCHG_OUT_ACTION_COPY_FILE ((USHORT)56)
+
+#define EXCHG_OUT_ACTION_FLAG_CREATE_THEME ((USHORT)0x0100)
+#define EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE ((USHORT)0x0200)
+#define EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP ((USHORT)0x0400)
+#define EXCHG_OUT_ACTION_FLAG_REPLACE_IMAGEMAP ((USHORT)0x0800)
+#define EXCHG_OUT_ACTION_FLAG_FILL ((USHORT)0x1000)
+#define EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL ((USHORT)0x2000)
+
+// Ziele
+#define EXCHG_DEST_DOC_OLEOBJ 1
+#define EXCHG_DEST_CHARTDOC_OLEOBJ 2
+#define EXCHG_DEST_DOC_TEXTFRAME 3
+#define EXCHG_DEST_DOC_GRAPHOBJ 4
+#define EXCHG_DEST_DOC_LNKD_GRAPHOBJ 5
+#define EXCHG_DEST_DOC_GRAPH_W_IMAP 6
+#define EXCHG_DEST_DOC_LNKD_GRAPH_W_IMAP 7
+#define EXCHG_DEST_DOC_IMAPREGION 8
+#define EXCHG_DEST_DOC_DRAWOBJ 9
+#define EXCHG_DEST_DOC_URLBUTTON 10
+#define EXCHG_DEST_DOC_URLFIELD 11
+#define EXCHG_DEST_DOC_GROUPOBJ 12
+#define EXCHG_DEST_SWDOC_FREE_AREA 13
+#define EXCHG_DEST_SCDOC_FREE_AREA 14
+#define EXCHG_DEST_SDDOC_FREE_AREA 15
+#define EXCHG_DEST_DOC_TEXTFRAME_WEB 16
+#define EXCHG_DEST_SWDOC_FREE_AREA_WEB 17
+
+// ------------
+// - Exchange -
+// ------------
+class SvGlobalName;
+class SOT_DLLPUBLIC SotExchange
+{
+public:
+ static ULONG RegisterFormat( const ::com::sun::star::datatransfer::DataFlavor& rFlavor );
+ static ULONG RegisterFormatName( const String& rName );
+ static ULONG RegisterFormatMimeType( const String& rMimeType );
+
+ static ULONG GetFormat( const ::com::sun::star::datatransfer::DataFlavor& rFlavor );
+ static String GetFormatName( ULONG nFormat );
+ static sal_Bool GetFormatDataFlavor( ULONG nFormat, ::com::sun::star::datatransfer::DataFlavor& rFlavor );
+ static String GetFormatMimeType( ULONG nFormat );
+ static BOOL IsInternal( const SvGlobalName& );
+ static ULONG GetFormatIdFromMimeType( const String& rMimeType );
+
+ // bestimme die SotFormatStringId von dem registrierten Format
+ //JP 12.11.98: diese 3 Methoden sind ab sofort ueberfluessig, da
+ // die ClipboardIds statisch sind und aequivalent zur
+ // SotFormatStringId ist!
+ static SotFormatStringId GetFormatStringId( ULONG nFormat )
+ { return nFormat; }
+ static SotFormatStringId GetFormatStringId( const String& rName )
+ { return SotExchange::RegisterFormatMimeType( rName ); }
+ static ULONG RegisterSotFormatName( SotFormatStringId nId )
+ { return nId; }
+
+ // same for XTransferable interface
+ static USHORT GetExchangeAction(
+ // XTransferable
+ const DataFlavorExVector& rDataFlavorExVector,
+ // Ziel der Aktion (EXCHG_DEST_*)
+ USHORT nDestination,
+ // Aktionen, die Quelle unterstuetzt (EXCHG_SOURCE_...)
+ USHORT nSourceOptions,
+ // vom Anwender gewaehlte Aktion (EXCHG_IN_*, EXCHG_INOUT_*)
+ USHORT nUserAction,
+ // In:- Out: Zu benutzendes Format
+ ULONG& rFormat,
+ // In:- Out: Default-Action (EXCHG_IN_*, EXCHG_INOUT_*)
+ USHORT& rDefaultAction,
+ // In:- optional - check only for this specific format
+ ULONG nOnlyTestFormat = 0,
+ // In:- optional - check the contents of Xtransferable
+ const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XTransferable >* pxTransferable = NULL );
+
+ // same for XTransferable interface
+ static USHORT GetExchangeAction(
+ // XTransferable
+ const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XTransferable >& rxTransferable,
+ // Ziel der Aktion (EXCHG_DEST_*)
+ USHORT nDestination,
+ // Aktionen, die Quelle unterstuetzt (EXCHG_SOURCE_...)
+ USHORT nSourceOptions,
+ // vom Anwender gewaehlte Aktion (EXCHG_IN_*, EXCHG_INOUT_*)
+ USHORT nUserAction,
+ // In:- Out: Zu benutzendes Format
+ ULONG& rFormat,
+ // In:- Out: Default-Action (EXCHG_IN_*, EXCHG_INOUT_*)
+ USHORT& rDefaultAction,
+ // In:- optional - check only for this specific format
+ ULONG nOnlyTestFormat = 0 );
+
+ static USHORT IsChart( const SvGlobalName& rName );
+ static USHORT IsMath( const SvGlobalName& rName );
+};
+
+#endif // _EXCHANGE_HXX
diff --git a/sot/inc/sot/factory.hxx b/sot/inc/sot/factory.hxx
new file mode 100644
index 000000000000..08dd21a88aa5
--- /dev/null
+++ b/sot/inc/sot/factory.hxx
@@ -0,0 +1,91 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SOT_FACTORY_HXX
+#define _SOT_FACTORY_HXX
+
+#ifndef _TOOLS_GLOBNAME_HXX
+#include <tools/globname.hxx>
+#endif
+#ifndef _TOOLS_RTTI_HXX
+#include <tools/rtti.hxx>
+#endif
+#include "sot/sotdllapi.h"
+
+/*************************************************************************
+*************************************************************************/
+class SotObject;
+class SotFactory;
+
+DECLARE_LIST( SotFactoryList, SotFactory * )
+typedef void * (*CreateInstanceType)( SotObject ** );
+
+//==================class SotFactory=======================================
+class SOT_DLLPUBLIC SotFactory : public SvGlobalName
+{
+ USHORT nSuperCount; // Anzahl der Superklassen
+ const SotFactory ** pSuperClasses; // Superklassen
+ CreateInstanceType pCreateFunc;
+
+ String aClassName;
+
+ static BOOL ExistTest( const SvGlobalName & );
+protected:
+ virtual ~SotFactory();
+public:
+ TYPEINFO();
+ static void DeInit();
+ static void IncSvObjectCount( SotObject * = NULL );
+ static void DecSvObjectCount( SotObject * = NULL );
+ static UINT32 GetSvObjectCount();
+ static void TestInvariant();
+
+ static const SotFactory * Find( const SvGlobalName & );
+ static const SotFactoryList * GetFactoryList();
+
+ SotFactory( const SvGlobalName &,
+ const String & rClassName, CreateInstanceType );
+
+ void PutSuperClass( const SotFactory * );
+ virtual void * CreateInstance( SotObject ** ppObj = NULL ) const;
+ void * CastAndAddRef( SotObject * ) const;
+ void * AggCastAndAddRef( SotObject * ) const;
+
+ BOOL Is( const SotFactory * pSuperClass ) const;
+ const SotFactory * GetSuper( USHORT nPos ) const
+ {
+ return nPos < nSuperCount ?
+ pSuperClasses[ nPos ]
+ : NULL;
+ }
+
+private:
+ SOT_DLLPRIVATE SotFactory( const SotFactory & );
+ SOT_DLLPRIVATE SotFactory & operator = ( const SotFactory & );
+};
+
+#endif // _FACTORY_HXX
diff --git a/sot/inc/sot/formats.hxx b/sot/inc/sot/formats.hxx
new file mode 100644
index 000000000000..c9d7a3e69d78
--- /dev/null
+++ b/sot/inc/sot/formats.hxx
@@ -0,0 +1,191 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SOT_FORMATS_HXX
+#define _SOT_FORMATS_HXX
+
+#ifdef _SOT_FORMATS_INCLUDE_SYSTEMFORMATS
+
+#ifdef WNT
+#ifdef _MSC_VER
+#pragma warning(push, 1)
+#pragma warning(disable: 4917)
+#endif
+#include <tools/prewin.h>
+#include <shlobj.h>
+#include <tools/postwin.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+#endif
+
+#endif
+#include <sot/exchange.hxx>
+
+#define SOT_FORMAT_SYSTEM_START ((ULONG)0)
+#define SOT_FORMAT_STRING ((ULONG)FORMAT_STRING)
+#define SOT_FORMAT_BITMAP ((ULONG)FORMAT_BITMAP)
+#define SOT_FORMAT_GDIMETAFILE ((ULONG)FORMAT_GDIMETAFILE)
+#define SOT_FORMAT_PRIVATE ((ULONG)FORMAT_PRIVATE)
+#define SOT_FORMAT_FILE ((ULONG)FORMAT_FILE)
+#define SOT_FORMAT_FILE_LIST ((ULONG)FORMAT_FILE_LIST)
+#define SOT_FORMAT_RTF ((ULONG)FORMAT_RTF)
+
+#define SOT_FORMATSTR_ID_DRAWING ((ULONG)11)
+#define SOT_FORMATSTR_ID_SVXB ((ULONG)12)
+#define SOT_FORMATSTR_ID_SVIM ((ULONG)13)
+#define SOT_FORMATSTR_ID_XFA ((ULONG)14)
+#define SOT_FORMATSTR_ID_EDITENGINE ((ULONG)15)
+#define SOT_FORMATSTR_ID_INTERNALLINK_STATE ((ULONG)16)
+#define SOT_FORMATSTR_ID_SOLK ((ULONG)17)
+#define SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ((ULONG)18)
+#define SOT_FORMATSTR_ID_TREELISTBOX ((ULONG)19)
+#define SOT_FORMATSTR_ID_NATIVE ((ULONG)20)
+#define SOT_FORMATSTR_ID_OWNERLINK ((ULONG)21)
+#define SOT_FORMATSTR_ID_STARSERVER ((ULONG)22)
+#define SOT_FORMATSTR_ID_STAROBJECT ((ULONG)23)
+#define SOT_FORMATSTR_ID_APPLETOBJECT ((ULONG)24)
+#define SOT_FORMATSTR_ID_PLUGIN_OBJECT ((ULONG)25)
+#define SOT_FORMATSTR_ID_STARWRITER_30 ((ULONG)26)
+#define SOT_FORMATSTR_ID_STARWRITER_40 ((ULONG)27)
+#define SOT_FORMATSTR_ID_STARWRITER_50 ((ULONG)28)
+#define SOT_FORMATSTR_ID_STARWRITERWEB_40 ((ULONG)29)
+#define SOT_FORMATSTR_ID_STARWRITERWEB_50 ((ULONG)30)
+#define SOT_FORMATSTR_ID_STARWRITERGLOB_40 ((ULONG)31)
+#define SOT_FORMATSTR_ID_STARWRITERGLOB_50 ((ULONG)32)
+#define SOT_FORMATSTR_ID_STARDRAW ((ULONG)33)
+#define SOT_FORMATSTR_ID_STARDRAW_40 ((ULONG)34)
+#define SOT_FORMATSTR_ID_STARIMPRESS_50 ((ULONG)35)
+#define SOT_FORMATSTR_ID_STARDRAW_50 ((ULONG)36)
+#define SOT_FORMATSTR_ID_STARCALC ((ULONG)37)
+#define SOT_FORMATSTR_ID_STARCALC_40 ((ULONG)38)
+#define SOT_FORMATSTR_ID_STARCALC_50 ((ULONG)39)
+#define SOT_FORMATSTR_ID_STARCHART ((ULONG)40)
+#define SOT_FORMATSTR_ID_STARCHART_40 ((ULONG)41)
+#define SOT_FORMATSTR_ID_STARCHART_50 ((ULONG)42)
+#define SOT_FORMATSTR_ID_STARIMAGE ((ULONG)43)
+#define SOT_FORMATSTR_ID_STARIMAGE_40 ((ULONG)44)
+#define SOT_FORMATSTR_ID_STARIMAGE_50 ((ULONG)45)
+#define SOT_FORMATSTR_ID_STARMATH ((ULONG)46)
+#define SOT_FORMATSTR_ID_STARMATH_40 ((ULONG)47)
+#define SOT_FORMATSTR_ID_STARMATH_50 ((ULONG)48)
+#define SOT_FORMATSTR_ID_STAROBJECT_PAINTDOC ((ULONG)49)
+#define SOT_FORMATSTR_ID_FILLED_AREA ((ULONG)50)
+#define SOT_FORMATSTR_ID_HTML ((ULONG)51)
+#define SOT_FORMATSTR_ID_HTML_SIMPLE ((ULONG)52)
+#define SOT_FORMATSTR_ID_CHAOS ((ULONG)53)
+#define SOT_FORMATSTR_ID_CNT_MSGATTACHFILE ((ULONG)54)
+#define SOT_FORMATSTR_ID_BIFF_5 ((ULONG)55)
+#define SOT_FORMATSTR_ID_BIFF__5 ((ULONG)56)
+#define SOT_FORMATSTR_ID_SYLK ((ULONG)57)
+#define SOT_FORMATSTR_ID_SYLK_BIGCAPS ((ULONG)58)
+#define SOT_FORMATSTR_ID_LINK ((ULONG)59)
+#define SOT_FORMATSTR_ID_DIF ((ULONG)60)
+#define SOT_FORMATSTR_ID_STARDRAW_TABBAR ((ULONG)61)
+#define SOT_FORMATSTR_ID_SONLK ((ULONG)62)
+#define SOT_FORMATSTR_ID_MSWORD_DOC ((ULONG)63)
+#define SOT_FORMATSTR_ID_STAR_FRAMESET_DOC ((ULONG)64)
+#define SOT_FORMATSTR_ID_OFFICE_DOC ((ULONG)65)
+#define SOT_FORMATSTR_ID_NOTES_DOCINFO ((ULONG)66)
+#define SOT_FORMATSTR_ID_NOTES_HNOTE ((ULONG)67)
+#define SOT_FORMATSTR_ID_NOTES_NATIVE ((ULONG)68)
+#define SOT_FORMATSTR_ID_SFX_DOC ((ULONG)69)
+#define SOT_FORMATSTR_ID_EVDF ((ULONG)70)
+#define SOT_FORMATSTR_ID_ESDF ((ULONG)71)
+#define SOT_FORMATSTR_ID_IDF ((ULONG)72)
+#define SOT_FORMATSTR_ID_EFTP ((ULONG)73)
+#define SOT_FORMATSTR_ID_EFD ((ULONG)74)
+#define SOT_FORMATSTR_ID_SVX_FORMFIELDEXCH ((ULONG)75)
+#define SOT_FORMATSTR_ID_EXTENDED_TABBAR ((ULONG)76)
+#define SOT_FORMATSTR_ID_SBA_DATAEXCHANGE ((ULONG)77)
+#define SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE ((ULONG)78)
+#define SOT_FORMATSTR_ID_SBA_PRIVATE_URL ((ULONG)79)
+#define SOT_FORMATSTR_ID_SBA_TABED ((ULONG)80)
+#define SOT_FORMATSTR_ID_SBA_TABID ((ULONG)81)
+#define SOT_FORMATSTR_ID_SBA_JOIN ((ULONG)82)
+#define SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ((ULONG)83)
+#define SOT_FORMATSTR_ID_LINKSRCDESCRIPTOR ((ULONG)84)
+#define SOT_FORMATSTR_ID_EMBED_SOURCE ((ULONG)85)
+#define SOT_FORMATSTR_ID_LINK_SOURCE ((ULONG)86)
+#define SOT_FORMATSTR_ID_EMBEDDED_OBJ ((ULONG)87)
+#define SOT_FORMATSTR_ID_FILECONTENT ((ULONG)88)
+#define SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR ((ULONG)89)
+#define SOT_FORMATSTR_ID_FILENAME ((ULONG)90)
+#define SOT_FORMATSTR_ID_SD_OLE ((ULONG)91)
+#define SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE ((ULONG)92)
+#define SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ((ULONG)93)
+#define SOT_FORMATSTR_ID_OBJECTDESCRIPTOR_OLE ((ULONG)94)
+#define SOT_FORMATSTR_ID_LINKSRCDESCRIPTOR_OLE ((ULONG)95)
+#define SOT_FORMATSTR_ID_LINK_SOURCE_OLE ((ULONG)96)
+#define SOT_FORMATSTR_ID_SBA_CTRLDATAEXCHANGE ((ULONG)97)
+#define SOT_FORMATSTR_ID_OUTPLACE_OBJ ((ULONG)98)
+#define SOT_FORMATSTR_ID_CNT_OWN_CLIP ((ULONG)99)
+#define SOT_FORMATSTR_ID_INET_IMAGE ((ULONG)100)
+#define SOT_FORMATSTR_ID_NETSCAPE_IMAGE ((ULONG)101)
+#define SOT_FORMATSTR_ID_SBA_FORMEXCHANGE ((ULONG)102)
+#define SOT_FORMATSTR_ID_SBA_REPORTEXCHANGE ((ULONG)103)
+#define SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ((ULONG)104)
+#define SOT_FORMATSTR_ID_STARCHARTDOCUMENT_50 ((ULONG)105)
+#define SOT_FORMATSTR_ID_GRAPHOBJ ((ULONG)106)
+#define SOT_FORMATSTR_ID_STARWRITER_60 ((ULONG)107)
+#define SOT_FORMATSTR_ID_STARWRITERWEB_60 ((ULONG)108)
+#define SOT_FORMATSTR_ID_STARWRITERGLOB_60 ((ULONG)109)
+#define SOT_FORMATSTR_ID_STARDRAW_60 ((ULONG)110)
+#define SOT_FORMATSTR_ID_STARIMPRESS_60 ((ULONG)111)
+#define SOT_FORMATSTR_ID_STARCALC_60 ((ULONG)112)
+#define SOT_FORMATSTR_ID_STARCHART_60 ((ULONG)113)
+#define SOT_FORMATSTR_ID_STARMATH_60 ((ULONG)114)
+#define SOT_FORMATSTR_ID_WMF ((ULONG)115)
+#define SOT_FORMATSTR_ID_DBACCESS_QUERY ((ULONG)116)
+#define SOT_FORMATSTR_ID_DBACCESS_TABLE ((ULONG)117)
+#define SOT_FORMATSTR_ID_DBACCESS_COMMAND ((ULONG)118)
+#define SOT_FORMATSTR_ID_DIALOG_60 ((ULONG)119)
+#define SOT_FORMATSTR_ID_EMF ((ULONG)120)
+#define SOT_FORMATSTR_ID_BIFF_8 ((ULONG)121)
+#define SOT_FORMATSTR_ID_BMP ((ULONG)122)
+#define SOT_FORMATSTR_ID_HTML_NO_COMMENT ((ULONG)123)
+#define SOT_FORMATSTR_ID_STARWRITER_8 ((ULONG)124)
+#define SOT_FORMATSTR_ID_STARWRITERWEB_8 ((ULONG)125)
+#define SOT_FORMATSTR_ID_STARWRITERGLOB_8 ((ULONG)126)
+#define SOT_FORMATSTR_ID_STARDRAW_8 ((ULONG)127)
+#define SOT_FORMATSTR_ID_STARIMPRESS_8 ((ULONG)128)
+#define SOT_FORMATSTR_ID_STARCALC_8 ((ULONG)129)
+#define SOT_FORMATSTR_ID_STARCHART_8 ((ULONG)130)
+#define SOT_FORMATSTR_ID_STARMATH_8 ((ULONG)131)
+#define SOT_FORMATSTR_ID_XFORMS ((ULONG)132)
+#define SOT_FORMATSTR_ID_STARWRITER_8_TEMPLATE ((ULONG)133)
+#define SOT_FORMATSTR_ID_STARDRAW_8_TEMPLATE ((ULONG)134)
+#define SOT_FORMATSTR_ID_STARIMPRESS_8_TEMPLATE ((ULONG)135)
+#define SOT_FORMATSTR_ID_STARCALC_8_TEMPLATE ((ULONG)136)
+#define SOT_FORMATSTR_ID_STARCHART_8_TEMPLATE ((ULONG)137)
+#define SOT_FORMATSTR_ID_STARMATH_8_TEMPLATE ((ULONG)138)
+#define SOT_FORMATSTR_ID_STARBASE_8 ((ULONG)139)
+#define SOT_FORMATSTR_ID_HC_GDIMETAFILE ((ULONG)140)
+#define SOT_FORMATSTR_ID_USER_END SOT_FORMATSTR_ID_HC_GDIMETAFILE
+
+#endif // _SOT_FORMATS_HXX
+
diff --git a/sot/inc/sot/object.hxx b/sot/inc/sot/object.hxx
new file mode 100644
index 000000000000..db2ac3b30ffc
--- /dev/null
+++ b/sot/inc/sot/object.hxx
@@ -0,0 +1,470 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SOT_OBJECT_HXX
+#define _SOT_OBJECT_HXX
+
+#include <sot/sotref.hxx>
+#ifndef _SOT_SOTDATA_HXX
+#include <sot/sotdata.hxx>
+#endif
+#ifndef _TOOLS_GLOBNAME_HXX
+#include <tools/globname.hxx>
+#endif
+#include "sot/sotdllapi.h"
+
+/*************************************************************************
+*************************************************************************/
+
+#define TEST_INVARIANT
+#ifdef TEST_INVARIANT
+#define SO2_DECL_INVARIANT() \
+ virtual void TestObjRef( BOOL bFree ); \
+ void TestMemberObjRef( BOOL bFree ); \
+ virtual void TestInvariant( BOOL bPrint ); \
+ void TestMemberInvariant( BOOL bPrint );
+
+#define SO2_IMPL_INVARIANT(ClassName) \
+void __EXPORT ClassName::TestObjRef( BOOL bFree ) \
+{ \
+ TestMemberObjRef( bFree ); \
+} \
+void __EXPORT ClassName::TestInvariant( BOOL bPrint ) \
+{ \
+ TestMemberInvariant( bPrint ); \
+}
+
+#define SO2_IMPL_INVARIANT1(ClassName,Super1) \
+void __EXPORT ClassName::TestObjRef( BOOL bFree ) \
+{ \
+ TestMemberObjRef( bFree ); \
+ Super1::TestObjRef( bFree ); \
+} \
+void __EXPORT ClassName::TestInvariant( BOOL bPrint ) \
+{ \
+ TestMemberInvariant( bPrint ); \
+ Super1::TestInvariant( bPrint ); \
+}
+
+#define SO2_IMPL_INVARIANT2(ClassName,Super1,Super2) \
+void __EXPORT ClassName::TestObjRef( BOOL bFree ) \
+{ \
+ TestMemberObjRef( bFree ); \
+ Super1::TestObjRef( bFree ); \
+ Super2::TestObjRef( bFree ); \
+} \
+void __EXPORT ClassName::TestInvariant( BOOL bPrint ) \
+{ \
+ TestMemberInvariant( bPrint ); \
+ Super1::TestInvariant( bPrint ); \
+ Super2::TestInvariant( bPrint ); \
+}
+
+#define SO2_IMPL_INVARIANT3(ClassName,Super1,Super2,Super3) \
+void __EXPORT ClassName::TestObjRef( BOOL bFree ) \
+{ \
+ TestMemberObjRef( bFree ); \
+ Super1::TestObjRef( bFree ); \
+ Super2::TestObjRef( bFree ); \
+ Super3::TestObjRef( bFree ); \
+} \
+void __EXPORT ClassName::TestInvariant( BOOL bPrint ) \
+{ \
+ TestMemberInvariant( bPrint ); \
+ Super1::TestInvariant( bPrint ); \
+ Super2::TestInvariant( bPrint ); \
+ Super3::TestInvariant( bPrint ); \
+}
+
+#define SO2_IMPL_INVARIANT4(ClassName,Super1,Super2,Super3,Super4) \
+void __EXPORT ClassName::TestObjRef( BOOL bFree ) \
+{ \
+ TestMemberObjRef( bFree ); \
+ Super1::TestObjRef( bFree ); \
+ Super2::TestObjRef( bFree ); \
+ Super3::TestObjRef( bFree ); \
+ Super4::TestObjRef( bFree ); \
+} \
+void __EXPORT ClassName::TestInvariant( BOOL bPrint ) \
+{ \
+ TestMemberInvariant( bPrint ); \
+ Super1::TestInvariant( bPrint ); \
+ Super2::TestInvariant( bPrint ); \
+ Super3::TestInvariant( bPrint ); \
+ Super4::TestInvariant( bPrint ); \
+}
+
+#ifdef DBG_UTIL
+#define CALL_TEST_INVARIANT() SotFactory::TestInvariant()
+#else
+#define CALL_TEST_INVARIANT()
+#endif // DBG_UTIL
+
+#else // TEST_INVARIANT
+
+#define SO2_DECL_INVARIANT()
+
+#define SO2_IMPL_INVARIANT(ClassName)
+#define SO2_IMPL_INVARIANT1(ClassName,Super1)
+#define SO2_IMPL_INVARIANT2(ClassName,Super1,Super2)
+#define SO2_IMPL_INVARIANT3(ClassName,Super1,Super2,Super3)
+#define SO2_IMPL_INVARIANT4(ClassName,Super1,Super2,Super3,Super4)
+
+#define CALL_TEST_INVARIANT()
+
+#endif // TEST_INVARIANT
+
+/**************************************************************************
+**************************************************************************/
+#define SO2_DECL_BASIC_CLASS_DLL(ClassName,FacName) \
+private: \
+ static SotFactory ** GetFactoryAdress() \
+ { return &(FacName->p##ClassName##Factory); } \
+public: \
+ static void * CreateInstance( SotObject ** = NULL ); \
+ static SotFactory * ClassFactory(); \
+ virtual const SotFactory * GetSvFactory() const; \
+ virtual void * Cast( const SotFactory * );
+
+#define SO2_DECL_BASIC_CLASS(ClassName) \
+private: \
+ static SotFactory * pFactory; \
+ static SotFactory ** GetFactoryAdress() { return &pFactory; } \
+public: \
+ static void * CreateInstance( SotObject ** = NULL ); \
+ static SotFactory * ClassFactory(); \
+ virtual const SotFactory * GetSvFactory() const; \
+ virtual void * Cast( const SotFactory * );
+
+/**************************************************************************
+**************************************************************************/
+#define SO2_IMPL_BASIC_CLASS_DLL(ClassName,FactoryName,GlobalName) \
+SotFactory * ClassName::ClassFactory() \
+{ \
+ SotFactory **ppFactory = GetFactoryAdress(); \
+ if( !*ppFactory ) \
+ { \
+ *ppFactory = new FactoryName( GlobalName, \
+ String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( #ClassName ) ), \
+ ClassName::CreateInstance ); \
+ } \
+ return *ppFactory; \
+} \
+void * __EXPORT ClassName::CreateInstance( SotObject ** ppObj ) \
+{ \
+ ClassName * p = new ClassName(); \
+ if( ppObj ) \
+ *ppObj = p; \
+ return p; \
+} \
+const SotFactory * __EXPORT ClassName::GetSvFactory() const \
+{ \
+ return ClassFactory(); \
+} \
+void * __EXPORT ClassName::Cast( const SotFactory * pFact ) \
+{ \
+ void * pRet = NULL; \
+ if( !pFact || pFact == ClassFactory() ) \
+ pRet = this; \
+ return pRet; \
+}
+
+#define SO2_IMPL_BASIC_CLASS(ClassName,FactoryName,GlobalName) \
+SotFactory * ClassName::pFactory = NULL; \
+ SO2_IMPL_BASIC_CLASS_DLL(ClassName,FactoryName,GlobalName)
+
+/**************************************************************************
+**************************************************************************/
+#define SO2_IMPL_BASIC_CLASS1_DLL(ClassName,FactoryName,Super1,GlobalName)\
+SotFactory * ClassName::ClassFactory() \
+{ \
+ SotFactory **ppFactory = GetFactoryAdress(); \
+ if( !*ppFactory ) \
+ { \
+ *ppFactory = new FactoryName( GlobalName, \
+ String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( #ClassName ) ), \
+ ClassName::CreateInstance ); \
+ (*ppFactory)->PutSuperClass( Super1::ClassFactory() ); \
+ } \
+ return *ppFactory; \
+} \
+void * __EXPORT ClassName::CreateInstance( SotObject ** ppObj ) \
+{ \
+ ClassName * p = new ClassName(); \
+ Super1* pSuper1 = p; \
+ SotObject* pBasicObj = pSuper1; \
+ if( ppObj ) \
+ *ppObj = pBasicObj; \
+ return p; \
+} \
+const SotFactory * __EXPORT ClassName::GetSvFactory() const \
+{ \
+ return ClassFactory(); \
+} \
+void * __EXPORT ClassName::Cast( const SotFactory * pFact ) \
+{ \
+ void * pRet = NULL; \
+ if( !pFact || pFact == ClassFactory() ) \
+ pRet = this; \
+ if( !pRet ) \
+ pRet = Super1::Cast( pFact ); \
+ return pRet; \
+}
+
+#define SO2_IMPL_BASIC_CLASS1(ClassName,FactoryName,Super1,GlobalName) \
+SotFactory * ClassName::pFactory = NULL; \
+ SO2_IMPL_BASIC_CLASS1_DLL(ClassName,FactoryName,Super1,GlobalName)
+
+/**************************************************************************
+**************************************************************************/
+#define SO2_IMPL_BASIC_CLASS2_DLL(ClassName,FactoryName,Super1,Super2,GlobalName) \
+SotFactory * ClassName::ClassFactory() \
+{ \
+ SotFactory **ppFactory = GetFactoryAdress(); \
+ if( !*ppFactory ) \
+ { \
+ *ppFactory = new FactoryName( GlobalName, \
+ String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( #ClassName ) ), \
+ ClassName::CreateInstance ); \
+ (*ppFactory)->PutSuperClass( Super1::ClassFactory() ); \
+ (*ppFactory)->PutSuperClass( Super2::ClassFactory() ); \
+ } \
+ return *ppFactory; \
+} \
+void * __EXPORT ClassName::CreateInstance( SotObject ** ppObj ) \
+{ \
+ ClassName * p = new ClassName(); \
+ if( ppObj ) \
+ *ppObj = p; \
+ return p; \
+} \
+const SotFactory * __EXPORT ClassName::GetSvFactory() const \
+{ \
+ return ClassFactory(); \
+} \
+void * __EXPORT ClassName::Cast( const SotFactory * pFact ) \
+{ \
+ void * pRet = NULL; \
+ if( !pFact || pFact == ClassFactory() ) \
+ pRet = this; \
+ if( !pRet ) \
+ pRet = Super1::Cast( pFact ); \
+ if( !pRet ) \
+ pRet = Super2::Cast( pFact ); \
+ return pRet; \
+}
+#define SO2_IMPL_BASIC_CLASS2(ClassName,FactoryName,Super1,Super2,GlobalName) \
+SotFactory * ClassName::pFactory = NULL; \
+ SO2_IMPL_BASIC_CLASS2_DLL(ClassName,FactoryName,Super1,Super2,GlobalName)
+
+/**************************************************************************
+**************************************************************************/
+#define SO2_IMPL_BASIC_CLASS3_DLL(ClassName,FactoryName,Super1,Super2,Super3,GlobalName) \
+SotFactory * ClassName::ClassFactory() \
+{ \
+ SotFactory **ppFactory = GetFactoryAdress(); \
+ if( !*ppFactory ) \
+ { \
+ *ppFactory = new FactoryName( GlobalName, \
+ String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( #ClassName ) ), \
+ ClassName::CreateInstance );\
+ (*ppFactory)->PutSuperClass( Super1::ClassFactory() ); \
+ (*ppFactory)->PutSuperClass( Super2::ClassFactory() ); \
+ (*ppFactory)->PutSuperClass( Super3::ClassFactory() ); \
+ } \
+ return *pFactory; \
+} \
+void * __EXPORT ClassName::CreateInstance( SotObject ** ppObj ) \
+{ \
+ ClassName * p = new ClassName(); \
+ if( ppObj ) \
+ *ppObj = p; \
+ return p; \
+} \
+const SotFactory * __EXPORT ClassName::GetSvFactory() const \
+{ \
+ return ClassFactory(); \
+} \
+void * __EXPORT ClassName::Cast( const SotFactory * pFact ) \
+{ \
+ void * pRet = NULL; \
+ if( !pFact || pFact == ClassFactory() ) \
+ pRet = this; \
+ if( !pRet ) \
+ pRet = Super1::Cast( pFact ); \
+ if( !pRet ) \
+ pRet = Super2::Cast( pFact ); \
+ if( !pRet ) \
+ pRet = Super3::Cast( pFact ); \
+ return pRet; \
+}
+
+#define SO2_IMPL_BASIC_CLASS3(ClassName,FactoryName,Super1,Super2,Super3,GlobalName) \
+SotFactory * ClassName::pFactory = NULL; \
+ SO2_IMPL_BASIC_CLASS3_DLL(ClassName,FactoryName,Super1,Super2,Super3,GlobalName)
+
+/**************************************************************************
+**************************************************************************/
+#define SO2_IMPL_BASIC_CLASS4_DLL(ClassName,FactoryName,Super1,Super2,Super3,Super4,GlobalName) \
+SotFactory * ClassName::ClassFactory() \
+{ \
+ SotFactory **ppFactory = GetFactoryAdress(); \
+ if( !*ppFactory ) \
+ { \
+ *ppFactory = new SotFactory( GlobalName, \
+ String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( #ClassName ) ), \
+ ClassName::CreateInstance );\
+ (*ppFactory)->PutSuperClass( Super1::ClassFactory() ); \
+ (*ppFactory)->PutSuperClass( Super2::ClassFactory() ); \
+ (*ppFactory)->PutSuperClass( Super3::ClassFactory() ); \
+ (*ppFactory)->PutSuperClass( Super4::ClassFactory() ); \
+ } \
+ return *ppFactory; \
+} \
+void * __EXPORT ClassName::CreateInstance( SotObject ** ppObj ) \
+{ \
+ ClassName * p = new ClassName(); \
+ if( ppObj ) \
+ *ppObj = p; \
+ return p; \
+} \
+const SotFactory * __EXPORT ClassName::GetSvFactory() const \
+{ \
+ return ClassFactory(); \
+} \
+void * __EXPORT ClassName::Cast( const SotFactory * pFact ) \
+{ \
+ void * pRet = NULL; \
+ if( !pFact || pFact == ClassFactory() ) \
+ pRet = this; \
+ if( !pRet ) \
+ pRet = Super1::Cast( pFact ); \
+ if( !pRet ) \
+ pRet = Super2::Cast( pFact ); \
+ if( !pRet ) \
+ pRet = Super3::Cast( pFact ); \
+ if( !pRet ) \
+ pRet = Super4::Cast( pFact ); \
+ return pRet; \
+}
+
+#define SO2_IMPL_BASIC_CLASS4(ClassName,FactoryName,Super1,Super2,Super3,Super4,GlobalName) \
+SotFactory * ClassName::pFactory = NULL; \
+ SO2_IMPL_BASIC_CLASS4_DLL(ClassName,FactoryName,Super1,Super2,Super3,Super4,GlobalName)
+
+//==================class SotObject========================================
+#ifdef _MSC_VER
+#pragma warning(disable: 4250)
+#endif
+
+class SvAggregateMemberList;
+struct IUnknown;
+class SOT_DLLPUBLIC SotObject : virtual public SvRefBase
+{
+friend class SotFactory;
+friend class SvObject;
+ SvAggregateMemberList * pAggList; // fuer Aggregation, erstes ist das MainObj
+ USHORT nStrongLockCount;
+ USHORT nOwnerLockCount;
+ BOOL bOwner:1,
+ bSVObject:1, // Ist Proxy, dann TRUE wenn andere Seite SV ist
+ bInClose:1; // TRUE, im DoClose
+
+ void * DownAggCast( const SotFactory * pFact );
+ void RemoveInterface( ULONG );
+ void RemoveInterface( SotObject * );
+#if defined (GCC) && (defined (C281) || defined (C290) || defined (C291))
+public:
+#else
+protected:
+#endif
+ virtual ~SotObject();
+ void SetExtern() { bOwner = FALSE; }
+ virtual BOOL Close();
+public:
+ SotObject();
+ SO2_DECL_BASIC_CLASS_DLL(SotObject,SOTDATA())
+ SO2_DECL_INVARIANT()
+
+ // Nur damit die Makros in So3 nicht ganz ausufern
+ virtual IUnknown * GetInterface( const SvGlobalName & );
+
+ BOOL Owner() const { return bOwner; }
+ BOOL IsSvObject() const;
+
+ // Methoden fuer die Aggregation (siehe OLE2-Spec)
+ BOOL ShouldDelete();
+ virtual void QueryDelete();
+ SvAggregateMemberList & GetAggList();
+ void AddInterface( SotObject * );
+ void AddInterface( SotFactory * );
+ virtual SotObjectRef CreateAggObj( const SotFactory * );
+ void * AggCast( const SotFactory * pFact );
+ void * CastAndAddRef( const SotFactory * pFact );
+ SotObject * GetMainObj() const;
+
+ // !!! Read the Manual !!!
+ virtual USHORT FuzzyLock( BOOL bLock, BOOL bIntern, BOOL bClose );
+ void Lock( BOOL bLock )
+ {
+ FuzzyLock( bLock, TRUE, TRUE );
+ }
+ USHORT GetOwnerLockCount() const { return nOwnerLockCount; }
+ USHORT GetStrongLockCount() const { return nStrongLockCount; }
+
+ void OwnerLock( BOOL bLock );
+ void RemoveOwnerLock();
+ BOOL DoClose();
+ BOOL IsInClose() const { return bInClose; }
+
+private:
+ // Kopieren und Zuweisen dieses Objekttyps ist nicht erlaubt
+ SOT_DLLPRIVATE SotObject & operator = ( const SotObject & );
+ SOT_DLLPRIVATE SotObject( const SotObject & );
+};
+
+//==================class SotObjectRef======================================
+SV_IMPL_REF(SotObject)
+
+inline SotObjectRef::SotObjectRef( SotObject * pObjP, SvCastEnum )
+{
+ if( pObjP )
+ {
+ pObj = (SotObject *)pObjP->AggCast( SotObject::ClassFactory() );
+ if( pObj )
+ pObj->AddRef();
+ }
+ else
+ pObj = NULL;
+}
+
+//==================class SotObject*List====================================
+SV_DECL_REF_LIST(SotObject,SotObject*)
+SV_IMPL_REF_LIST(SotObject,SotObject*)
+
+#endif // _IFACE_HXX
+
diff --git a/sot/inc/sot/sotdata.hxx b/sot/inc/sot/sotdata.hxx
new file mode 100644
index 000000000000..8d8775b5e181
--- /dev/null
+++ b/sot/inc/sot/sotdata.hxx
@@ -0,0 +1,60 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SOT_DATA_HXX
+#define _SOT_DATA_HXX
+
+/*************************************************************************
+*************************************************************************/
+
+#ifndef _TOOLS_SOLAR_H
+#include <tools/solar.h>
+#endif
+#include "sot/sotdllapi.h"
+
+//==================class SotData_Impl====================================
+
+class List;
+class SotFactory;
+class SotFactoryList;
+class SotObjectList;
+
+struct SotData_Impl
+{
+ UINT32 nSvObjCount;
+ SotObjectList * pObjectList;
+ SotFactoryList * pFactoryList;
+ SotFactory * pSotObjectFactory;
+ SotFactory * pSotStorageStreamFactory;
+ SotFactory * pSotStorageFactory;
+ List* pDataFlavorList;
+ SotData_Impl();
+};
+
+SOT_DLLPUBLIC SotData_Impl* SOTDATA();
+
+#endif
diff --git a/sot/inc/sot/sotdllapi.h b/sot/inc/sot/sotdllapi.h
new file mode 100644
index 000000000000..032fef762715
--- /dev/null
+++ b/sot/inc/sot/sotdllapi.h
@@ -0,0 +1,41 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_SOTDLLAPI_H
+#define INCLUDED_SOTDLLAPI_H
+
+#include "sal/types.h"
+
+#if defined(SOT_DLLIMPLEMENTATION)
+#define SOT_DLLPUBLIC SAL_DLLPUBLIC_EXPORT
+#else
+#define SOT_DLLPUBLIC SAL_DLLPUBLIC_IMPORT
+#endif
+#define SOT_DLLPRIVATE SAL_DLLPRIVATE
+
+#endif /* INCLUDED_SOTDLLAPI_H */
+
diff --git a/sot/inc/sot/sotref.hxx b/sot/inc/sot/sotref.hxx
new file mode 100644
index 000000000000..ae03032e286e
--- /dev/null
+++ b/sot/inc/sot/sotref.hxx
@@ -0,0 +1,77 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SOT_SOTREF_HXX
+#define _SOT_SOTREF_HXX
+
+#ifndef _TOOLS_REF_HXX
+#include <tools/ref.hxx>
+#endif
+
+//========================================================================
+enum SvCastEnum { SV_AGGREGATION_CAST };
+#ifndef SVT_DECL_SOTOBJECT_DEFINED
+#define SVT_DECL_SOTOBJECT_DEFINED
+class SotObject;
+class SotObjectRef
+{
+ PRV_SV_DECL_REF(SotObject)
+ inline SotObjectRef( SotObject * pObjP, SvCastEnum );
+};
+#endif
+
+//========================================================================
+#define SO2_DECL_REF(ClassName) \
+class ClassName; \
+class ClassName##Ref \
+{ \
+ PRV_SV_DECL_REF(ClassName) \
+ inline ClassName##Ref( const SotObjectRef & ); \
+ inline ClassName##Ref( SotObject * pObjP ); \
+ inline ClassName##Ref( SotObject * pObjP, SvCastEnum ); \
+};
+
+#define SO2_IMPL_REF(ClassName) \
+SV_IMPL_REF(ClassName) \
+inline ClassName##Ref::ClassName##Ref( const SotObjectRef & r ) \
+{ \
+ pObj = (ClassName *)ClassName::ClassFactory()->CastAndAddRef( &r ); \
+} \
+inline ClassName##Ref::ClassName##Ref( SotObject * pObjP ) \
+{ \
+ pObj = (ClassName *)ClassName::ClassFactory()->CastAndAddRef( pObjP );\
+} \
+inline ClassName##Ref::ClassName##Ref( SotObject * pObjP, SvCastEnum ) \
+{ \
+ pObj = (ClassName *)ClassName::ClassFactory()->AggCastAndAddRef( pObjP );\
+}
+
+#define SO2_DECL_IMPL_REF(ClassName) \
+ SO2_DECL_REF(ClassName) \
+ SO2_IMPL_REF(ClassName)
+
+#endif // _SO2REF_HXX
diff --git a/sot/inc/sot/storage.hxx b/sot/inc/sot/storage.hxx
new file mode 100644
index 000000000000..572e100c7299
--- /dev/null
+++ b/sot/inc/sot/storage.hxx
@@ -0,0 +1,272 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SOT_STORAGE_HXX
+#define _SOT_STORAGE_HXX
+
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Reference.h>
+
+#ifndef _COM_SUN_STAR_IO_XINPUTSTREAM_H_
+#include <com/sun/star/io/XInputStream.hpp>
+#endif
+#include <com/sun/star/embed/XStorage.hpp>
+#include <sot/object.hxx>
+#include <sot/factory.hxx>
+#ifndef _TOOLS_STREAM_HXX
+#include <tools/stream.hxx>
+#endif
+#ifndef _TOOLS_ERRCODE_HXX
+#include <tools/errcode.hxx>
+#endif
+#include "sot/sotdllapi.h"
+
+#define STORAGE_FAILIFTHERE 0x02
+#define STORAGE_TRANSACTED 0x04
+#define STORAGE_PRIORITY 0x08
+#define STORAGE_DELETEONRELEASE 0x10
+#define STORAGE_CONVERT 0x20
+#define STORAGE_UNPACKED_MODE 0x40
+#define STORAGE_DISKSPANNED_MODE 0x80
+#define STORAGE_CREATE_UNPACKED 0x44
+typedef short StorageMode;
+
+class SvStorage;
+namespace binfilter
+{
+ class SvStorage;
+}
+
+/*************************************************************************
+*************************************************************************/
+class SotStorage;
+class BaseStorageStream;
+class SOT_DLLPUBLIC SotStorageStream : virtual public SotObject, public SvStream
+{
+friend class SotStorage;
+friend class ImpStream;
+ BaseStorageStream * pOwnStm;// Zeiger auf den eigenen Stream
+protected:
+ virtual ULONG GetData( void* pData, ULONG nSize );
+ virtual ULONG PutData( const void* pData, ULONG nSize );
+ virtual ULONG SeekPos( ULONG nPos );
+ virtual void FlushData();
+ ~SotStorageStream();
+public:
+ SotStorageStream( const String &,
+ StreamMode = STREAM_STD_READWRITE,
+ StorageMode = 0 );
+ SotStorageStream( BaseStorageStream *pStm );
+ SotStorageStream();
+ SO2_DECL_BASIC_CLASS_DLL(SotStorageStream,SOTDATA())
+ SO2_DECL_INVARIANT()
+
+ using SvStream::SyncSvStream;
+ virtual void SyncSvStream();
+ void SyncSysStream() { SvStream::SyncSysStream(); }
+
+ virtual void ResetError();
+
+ virtual void SetSize( ULONG nNewSize );
+ UINT32 GetSize() const;
+ BOOL CopyTo( SotStorageStream * pDestStm );
+ virtual BOOL Commit();
+ virtual BOOL Revert();
+ BOOL SetProperty( const String& rName, const ::com::sun::star::uno::Any& rValue );
+ BOOL GetProperty( const String& rName, ::com::sun::star::uno::Any& rValue );
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >
+ GetXInputStream() const;
+};
+
+#ifndef SOT_DECL_SOTSTORAGESTREAM_DEFINED
+#define SOT_DECL_SOTSTORAGESTREAM_DEFINED
+SO2_DECL_REF(SotStorageStream)
+#endif
+SO2_IMPL_REF(SotStorageStream)
+
+namespace ucbhelper
+{
+ class Content;
+}
+
+class SvStorageInfoList;
+class BaseStorage;
+class UNOStorageHolder;
+class SOT_DLLPUBLIC SotStorage : virtual public SotObject
+{
+friend class SotStorageStream;
+friend class SvStorage;
+friend class ::binfilter::SvStorage;
+
+ BaseStorage * m_pTmpStg; // Temp-Storage fuer Transacted, nur auf diesem schreiben! ??? Useless ???
+ BaseStorage * m_pOwnStg; // Zielstorage
+ SvStream * m_pStorStm; // nur fuer SDSTORAGES
+ ULONG m_nError;
+ String m_aName; // Name des Storage
+ BOOL m_bIsRoot:1, // z.B.: File-Storage
+ m_bDelStm:1;
+ ByteString m_aKey; // aKey.Len != 0 -> Verschluesselung
+ long m_nVersion;
+
+protected:
+ ~SotStorage();
+ void CreateStorage( BOOL bUCBStorage, StreamMode, StorageMode );
+public:
+ SotStorage( const String &,
+ StreamMode = STREAM_STD_READWRITE,
+ StorageMode = 0 );
+ SotStorage( BOOL bUCBStorage, const String &,
+ StreamMode = STREAM_STD_READWRITE,
+ StorageMode = 0 );
+ SotStorage( const ::ucbhelper::Content& rContent, const String &,
+ StreamMode = STREAM_STD_READWRITE,
+ StorageMode = 0 );
+ SotStorage( BaseStorage * );
+ SotStorage( SvStream & rStm );
+ SotStorage( BOOL bUCBStorage, SvStream & rStm );
+ SotStorage( SvStream * pStm, BOOL bDelete );
+ SotStorage();
+ SO2_DECL_BASIC_CLASS_DLL(SotStorage,SOTDATA())
+ SO2_DECL_INVARIANT()
+
+ SvMemoryStream * CreateMemoryStream();
+ const SvStream * GetSvStream();
+
+ static BOOL IsStorageFile( const String & rFileName );
+ static BOOL IsStorageFile( SvStream* pStream );
+
+ virtual const String & GetName() const;
+
+ virtual BOOL Validate();
+
+ void SetKey( const ByteString& rKey );
+ const ByteString & GetKey() const { return m_aKey; }
+
+ void SetVersion( long nVers )
+ {
+ m_nVersion = nVers;
+ }
+ long GetVersion() const
+ {
+ return m_nVersion;
+ }
+
+ ULONG GetErrorCode() const { return m_nError; }
+ ULONG GetError() const { return ERRCODE_TOERROR(m_nError); }
+ void SetError( ULONG nErrorCode )
+ {
+ if( m_nError == SVSTREAM_OK )
+ m_nError = nErrorCode;
+ }
+ virtual void ResetError();
+
+ BOOL IsRoot() const { return m_bIsRoot; }
+ void SignAsRoot( BOOL b = TRUE ) { m_bIsRoot = b; }
+ void SetDeleteStream( BOOL bDelete ) { m_bDelStm = bDelete; }
+
+ // eigener Datenbereich
+ virtual void SetClass( const SvGlobalName & rClass,
+ ULONG bOriginalClipFormat,
+ const String & rUserTypeName );
+ virtual void SetConvertClass( const SvGlobalName & rConvertClass,
+ ULONG bOriginalClipFormat,
+ const String & rUserTypeName );
+ virtual SvGlobalName GetClassName();// Typ der Daten im Storage
+ virtual ULONG GetFormat();
+ virtual String GetUserName();
+ virtual BOOL ShouldConvert();
+ void SetName( const String& rName );
+
+ // Liste aller Elemente
+ virtual void FillInfoList( SvStorageInfoList * ) const;
+ virtual BOOL CopyTo( SotStorage * pDestStg );
+ virtual BOOL Commit();
+ virtual BOOL Revert();
+
+ /* Element Methoden */
+ // Stream mit Verbindung zu Storage erzeugen,
+ // in etwa eine Parent-Child Beziehung
+ SotStorageStream * OpenSotStream( const String & rEleName,
+ StreamMode = STREAM_STD_READWRITE,
+ StorageMode = 0 );
+ SotStorageStream * OpenEncryptedSotStream( const String & rEleName, const ByteString& rKey,
+ StreamMode = STREAM_STD_READWRITE,
+ StorageMode = 0 );
+ SotStorage * OpenSotStorage( const String & rEleName,
+ StreamMode = STREAM_STD_READWRITE,
+ StorageMode = STORAGE_TRANSACTED );
+ SotStorage * OpenUCBStorage( const String & rEleName,
+ StreamMode = STREAM_STD_READWRITE,
+ StorageMode = STORAGE_TRANSACTED );
+ SotStorage * OpenOLEStorage( const String & rEleName,
+ StreamMode = STREAM_STD_READWRITE,
+ StorageMode = STORAGE_TRANSACTED );
+ // Abfrage auf Storage oder Stream
+ virtual BOOL IsStream( const String & rEleName ) const;
+ virtual BOOL IsStorage( const String & rEleName ) const;
+ virtual BOOL IsContained( const String & rEleName ) const;
+ // Element loeschen
+ virtual BOOL Remove( const String & rEleName );
+ // Elementnamen aendern
+ virtual BOOL Rename( const String & rEleName,
+ const String & rNewName );
+ virtual BOOL CopyTo( const String & rEleName, SotStorage * pDest,
+ const String & rNewName );
+ virtual BOOL MoveTo( const String & rEleName, SotStorage * pDest,
+ const String & rNewName );
+
+ SvStream* GetTargetSvStream() const;
+ BOOL SetProperty( const String& rName, const ::com::sun::star::uno::Any& rValue );
+ BOOL GetProperty( const String& rName, ::com::sun::star::uno::Any& rValue );
+ BOOL GetProperty( const String& rEleName, const String& rName, ::com::sun::star::uno::Any& rValue );
+ BOOL IsOLEStorage() const;
+ static BOOL IsOLEStorage( const String & rFileName );
+ static BOOL IsOLEStorage( SvStream* pStream );
+
+ // this is temporary HACK, _MUST_ be removed before release
+ ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >
+ GetUNOAPIDuplicate( const String& rEleName, sal_Int32 nUNOStorageMode );
+ void RemoveUNOStorageHolder( UNOStorageHolder* pHolder );
+
+ static SotStorage* OpenOLEStorage( const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >& xStorage,
+ const String& rEleName, StreamMode = STREAM_STD_READWRITE );
+ static sal_Int32 GetFormatID( const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >& xStorage );
+ static sal_Int32 GetVersion( const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >& xStorage );
+};
+
+#ifndef SOT_DECL_SOTSTORAGE_DEFINED
+#define SOT_DECL_SOTSTORAGE_DEFINED
+SO2_DECL_REF(SotStorage)
+#endif
+SO2_IMPL_REF(SotStorage)
+
+#define SvStorage SotStorage
+#define SvStorageRef SotStorageRef
+#define SvStorageStream SotStorageStream
+#define SvStorageStreamRef SotStorageStreamRef
+
+#endif // _SVSTOR_HXX
diff --git a/sot/inc/stg.hxx b/sot/inc/stg.hxx
new file mode 100644
index 000000000000..84373e26d596
--- /dev/null
+++ b/sot/inc/stg.hxx
@@ -0,0 +1,398 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _STG_HXX
+#define _STG_HXX
+
+#include <com/sun/star/uno/Any.h>
+#include <com/sun/star/uno/Reference.h>
+
+#ifndef _COM_SUN_STAR_IO_XINPUTSTREAM_H_
+#include <com/sun/star/io/XInputStream.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_UCB_XCOMMANDENVIRONMENT_H_
+#include <com/sun/star/ucb/XCommandEnvironment.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_EMBED_XSTORAGE_H_
+#include <com/sun/star/embed/XStorage.hpp>
+#endif
+
+
+#include <tools/rtti.hxx>
+#ifndef _TOOLS_STREAM_HXX //autogen
+#include <tools/stream.hxx>
+#endif
+#ifndef _TOOLS_GLOBNAME_HXX //autogen
+#include <tools/globname.hxx>
+#endif
+#include "sot/sotdllapi.h"
+
+#include <list>
+class UNOStorageHolder;
+typedef ::std::list< UNOStorageHolder* > UNOStorageHolderList;
+
+class Storage;
+class StorageStream;
+class StgIo;
+class StgDirEntry;
+class StgStrm;
+class SvGlobalName;
+struct ClsId
+{
+ INT32 n1;
+ INT16 n2, n3;
+ UINT8 n4, n5, n6, n7, n8, n9, n10, n11;
+};
+
+class SOT_DLLPUBLIC StorageBase : public SvRefBase
+{
+protected:
+ ULONG m_nError; // error code
+ StreamMode m_nMode; // open mode
+ BOOL m_bAutoCommit;
+ StorageBase();
+ virtual ~StorageBase();
+public:
+ TYPEINFO();
+ virtual const SvStream* GetSvStream() const = 0;
+ virtual BOOL Validate( BOOL=FALSE ) const = 0;
+ virtual BOOL ValidateMode( StreamMode ) const = 0;
+ void ResetError() const;
+ void SetError( ULONG ) const;
+ ULONG GetError() const;
+ BOOL Good() const { return BOOL( m_nError == SVSTREAM_OK ); }
+ StreamMode GetMode() const { return m_nMode; }
+ void SetAutoCommit( BOOL bSet )
+ { m_bAutoCommit = bSet; }
+};
+
+class BaseStorageStream : public StorageBase
+{
+public:
+ TYPEINFO();
+ virtual ULONG Read( void * pData, ULONG nSize ) = 0;
+ virtual ULONG Write( const void* pData, ULONG nSize ) = 0;
+ virtual ULONG Seek( ULONG nPos ) = 0;
+ virtual ULONG Tell() = 0;
+ virtual void Flush() = 0;
+ virtual BOOL SetSize( ULONG nNewSize ) = 0;
+ virtual BOOL CopyTo( BaseStorageStream * pDestStm ) = 0;
+ virtual BOOL Commit() = 0;
+ virtual BOOL Revert() = 0;
+ virtual BOOL Equals( const BaseStorageStream& rStream ) const = 0;
+};
+
+class SvStorageInfoList;
+class BaseStorage : public StorageBase
+{
+public:
+ TYPEINFO();
+ virtual const String& GetName() const = 0;
+ virtual BOOL IsRoot() const = 0;
+ virtual void SetClassId( const ClsId& ) = 0;
+ virtual const ClsId& GetClassId() const = 0;
+ virtual void SetDirty() = 0;
+ virtual void SetClass( const SvGlobalName & rClass,
+ ULONG nOriginalClipFormat,
+ const String & rUserTypeName ) = 0;
+ virtual void SetConvertClass( const SvGlobalName & rConvertClass,
+ ULONG nOriginalClipFormat,
+ const String & rUserTypeName ) = 0;
+ virtual SvGlobalName GetClassName() = 0;
+ virtual ULONG GetFormat() = 0;
+ virtual String GetUserName() = 0;
+ virtual BOOL ShouldConvert() = 0;
+ virtual void FillInfoList( SvStorageInfoList* ) const = 0;
+ virtual BOOL CopyTo( BaseStorage* pDestStg ) const = 0;
+ virtual BOOL Commit() = 0;
+ virtual BOOL Revert() = 0;
+ virtual BaseStorageStream* OpenStream( const String & rEleName,
+ StreamMode = STREAM_STD_READWRITE,
+ BOOL bDirect = TRUE, const ByteString* pKey=0 ) = 0;
+ virtual BaseStorage* OpenStorage( const String & rEleName,
+ StreamMode = STREAM_STD_READWRITE,
+ BOOL bDirect = FALSE ) = 0;
+ virtual BaseStorage* OpenUCBStorage( const String & rEleName,
+ StreamMode = STREAM_STD_READWRITE,
+ BOOL bDirect = FALSE ) = 0;
+ virtual BaseStorage* OpenOLEStorage( const String & rEleName,
+ StreamMode = STREAM_STD_READWRITE,
+ BOOL bDirect = FALSE ) = 0;
+ virtual BOOL IsStream( const String& rEleName ) const = 0;
+ virtual BOOL IsStorage( const String& rEleName ) const = 0;
+ virtual BOOL IsContained( const String& rEleName ) const = 0;
+ virtual BOOL Remove( const String & rEleName ) = 0;
+ virtual BOOL Rename( const String & rEleName, const String & rNewName ) = 0;
+ virtual BOOL CopyTo( const String & rEleName, BaseStorage * pDest, const String & rNewName ) = 0;
+ virtual BOOL MoveTo( const String & rEleName, BaseStorage * pDest, const String & rNewName ) = 0;
+ virtual BOOL ValidateFAT() = 0;
+ virtual BOOL Equals( const BaseStorage& rStream ) const = 0;
+};
+
+class OLEStorageBase
+{
+protected:
+ StreamMode& nStreamMode; // open mode
+ StgIo* pIo; // I/O subsystem
+ StgDirEntry* pEntry; // the dir entry
+ OLEStorageBase( StgIo*, StgDirEntry*, StreamMode& );
+ ~OLEStorageBase();
+ BOOL Validate_Impl( BOOL=FALSE ) const;
+ BOOL ValidateMode_Impl( StreamMode, StgDirEntry* p = NULL ) const ;
+ const SvStream* GetSvStream_Impl() const;
+public:
+};
+
+class StorageStream : public BaseStorageStream, public OLEStorageBase
+{
+//friend class Storage;
+ ULONG nPos; // current position
+protected:
+ ~StorageStream();
+public:
+ TYPEINFO();
+ StorageStream( StgIo*, StgDirEntry*, StreamMode );
+ virtual ULONG Read( void * pData, ULONG nSize );
+ virtual ULONG Write( const void* pData, ULONG nSize );
+ virtual ULONG Seek( ULONG nPos );
+ virtual ULONG Tell() { return nPos; }
+ virtual void Flush();
+ virtual BOOL SetSize( ULONG nNewSize );
+ virtual BOOL CopyTo( BaseStorageStream * pDestStm );
+ virtual BOOL Commit();
+ virtual BOOL Revert();
+ virtual BOOL Validate( BOOL=FALSE ) const;
+ virtual BOOL ValidateMode( StreamMode ) const;
+ BOOL ValidateMode( StreamMode, StgDirEntry* p ) const;
+ const SvStream* GetSvStream() const;
+ virtual BOOL Equals( const BaseStorageStream& rStream ) const;
+};
+
+class UCBStorageStream;
+
+class SOT_DLLPUBLIC Storage : public BaseStorage, public OLEStorageBase
+{
+ String aName;
+ BOOL bIsRoot;
+ void Init( BOOL bCreate );
+ Storage( StgIo*, StgDirEntry*, StreamMode );
+protected:
+ ~Storage();
+public:
+ TYPEINFO();
+ Storage( const String &, StreamMode = STREAM_STD_READWRITE, BOOL bDirect = TRUE );
+ Storage( SvStream& rStrm, BOOL bDirect = TRUE );
+ Storage( UCBStorageStream& rStrm, BOOL bDirect = TRUE );
+
+ static BOOL IsStorageFile( const String & rFileName );
+ static BOOL IsStorageFile( SvStream* );
+
+ virtual const String& GetName() const;
+ virtual BOOL IsRoot() const { return bIsRoot; }
+ virtual void SetClassId( const ClsId& );
+ virtual const ClsId& GetClassId() const;
+ virtual void SetDirty();
+ virtual void SetClass( const SvGlobalName & rClass,
+ ULONG nOriginalClipFormat,
+ const String & rUserTypeName );
+ virtual void SetConvertClass( const SvGlobalName & rConvertClass,
+ ULONG nOriginalClipFormat,
+ const String & rUserTypeName );
+ virtual SvGlobalName GetClassName();
+ virtual ULONG GetFormat();
+ virtual String GetUserName();
+ virtual BOOL ShouldConvert();
+ virtual void FillInfoList( SvStorageInfoList* ) const;
+ virtual BOOL CopyTo( BaseStorage* pDestStg ) const;
+ virtual BOOL Commit();
+ virtual BOOL Revert();
+ virtual BaseStorageStream* OpenStream( const String & rEleName,
+ StreamMode = STREAM_STD_READWRITE,
+ BOOL bDirect = TRUE, const ByteString* pKey=0 );
+ virtual BaseStorage* OpenStorage( const String & rEleName,
+ StreamMode = STREAM_STD_READWRITE,
+ BOOL bDirect = FALSE );
+ virtual BaseStorage* OpenUCBStorage( const String & rEleName,
+ StreamMode = STREAM_STD_READWRITE,
+ BOOL bDirect = FALSE );
+ virtual BaseStorage* OpenOLEStorage( const String & rEleName,
+ StreamMode = STREAM_STD_READWRITE,
+ BOOL bDirect = FALSE );
+ virtual BOOL IsStream( const String& rEleName ) const;
+ virtual BOOL IsStorage( const String& rEleName ) const;
+ virtual BOOL IsContained( const String& rEleName ) const;
+ virtual BOOL Remove( const String & rEleName );
+ virtual BOOL Rename( const String & rEleName, const String & rNewName );
+ virtual BOOL CopyTo( const String & rEleName, BaseStorage * pDest, const String & rNewName );
+ virtual BOOL MoveTo( const String & rEleName, BaseStorage * pDest, const String & rNewName );
+ virtual BOOL ValidateFAT();
+ virtual BOOL Validate( BOOL=FALSE ) const;
+ virtual BOOL ValidateMode( StreamMode ) const;
+ BOOL ValidateMode( StreamMode, StgDirEntry* p ) const;
+ virtual const SvStream* GetSvStream() const;
+ virtual BOOL Equals( const BaseStorage& rStream ) const;
+};
+
+class UCBStorageStream_Impl;
+class UCBStorageStream : public BaseStorageStream
+{
+friend class UCBStorage;
+
+ UCBStorageStream_Impl*
+ pImp;
+protected:
+ ~UCBStorageStream();
+public:
+ TYPEINFO();
+ UCBStorageStream( const String& rName, StreamMode nMode, BOOL bDirect, const ByteString* pKey=0 );
+ UCBStorageStream( const String& rName, StreamMode nMode, BOOL bDirect, const ByteString* pKey, BOOL bRepair, ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XProgressHandler > xProgress );
+ UCBStorageStream( UCBStorageStream_Impl* );
+
+ virtual ULONG Read( void * pData, ULONG nSize );
+ virtual ULONG Write( const void* pData, ULONG nSize );
+ virtual ULONG Seek( ULONG nPos );
+ virtual ULONG Tell();
+ virtual void Flush();
+ virtual BOOL SetSize( ULONG nNewSize );
+ virtual BOOL CopyTo( BaseStorageStream * pDestStm );
+ virtual BOOL Commit();
+ virtual BOOL Revert();
+ virtual BOOL Validate( BOOL=FALSE ) const;
+ virtual BOOL ValidateMode( StreamMode ) const;
+ const SvStream* GetSvStream() const;
+ virtual BOOL Equals( const BaseStorageStream& rStream ) const;
+ BOOL SetProperty( const String& rName, const ::com::sun::star::uno::Any& rValue );
+ BOOL GetProperty( const String& rName, ::com::sun::star::uno::Any& rValue );
+
+ SvStream* GetModifySvStream();
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > GetXInputStream() const;
+};
+
+namespace ucbhelper
+{
+ class Content;
+}
+
+class UCBStorage_Impl;
+struct UCBStorageElement_Impl;
+class SOT_DLLPUBLIC UCBStorage : public BaseStorage
+{
+ UCBStorage_Impl* pImp;
+
+protected:
+ ~UCBStorage();
+public:
+ static BOOL IsStorageFile( SvStream* );
+ static BOOL IsStorageFile( const String& rName );
+ static BOOL IsDiskSpannedFile( SvStream* );
+ static String GetLinkedFile( SvStream& );
+ static String CreateLinkFile( const String& rName );
+
+ UCBStorage( const ::ucbhelper::Content& rContent, const String& rName, StreamMode nMode, BOOL bDirect = TRUE, BOOL bIsRoot = TRUE );
+ UCBStorage( const String& rName,
+ StreamMode nMode,
+ BOOL bDirect = TRUE,
+ BOOL bIsRoot = TRUE );
+
+ UCBStorage( const String& rName,
+ StreamMode nMode,
+ BOOL bDirect,
+ BOOL bIsRoot,
+ BOOL bIsRepair,
+ ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XProgressHandler >
+ xProgressHandler );
+
+ UCBStorage( UCBStorage_Impl* );
+ UCBStorage( SvStream& rStrm, BOOL bDirect = TRUE );
+
+ TYPEINFO();
+ virtual const String& GetName() const;
+ virtual BOOL IsRoot() const;
+ virtual void SetClassId( const ClsId& );
+ virtual const ClsId& GetClassId() const;
+ virtual void SetDirty();
+ virtual void SetClass( const SvGlobalName & rClass,
+ ULONG nOriginalClipFormat,
+ const String & rUserTypeName );
+ virtual void SetConvertClass( const SvGlobalName & rConvertClass,
+ ULONG nOriginalClipFormat,
+ const String & rUserTypeName );
+ virtual SvGlobalName GetClassName();
+ virtual ULONG GetFormat();
+ virtual String GetUserName();
+ virtual BOOL ShouldConvert();
+ virtual void FillInfoList( SvStorageInfoList* ) const;
+ virtual BOOL CopyTo( BaseStorage* pDestStg ) const;
+ virtual BOOL Commit();
+ virtual BOOL Revert();
+ virtual BaseStorageStream* OpenStream( const String & rEleName,
+ StreamMode = STREAM_STD_READWRITE,
+ BOOL bDirect = TRUE, const ByteString* pKey=0 );
+ virtual BaseStorage* OpenStorage( const String & rEleName,
+ StreamMode = STREAM_STD_READWRITE,
+ BOOL bDirect = FALSE );
+ virtual BaseStorage* OpenUCBStorage( const String & rEleName,
+ StreamMode = STREAM_STD_READWRITE,
+ BOOL bDirect = FALSE );
+ virtual BaseStorage* OpenOLEStorage( const String & rEleName,
+ StreamMode = STREAM_STD_READWRITE,
+ BOOL bDirect = FALSE );
+ virtual BOOL IsStream( const String& rEleName ) const;
+ virtual BOOL IsStorage( const String& rEleName ) const;
+ virtual BOOL IsContained( const String& rEleName ) const;
+ virtual BOOL Remove( const String & rEleName );
+ virtual BOOL Rename( const String & rEleName, const String & rNewName );
+ virtual BOOL CopyTo( const String & rEleName, BaseStorage * pDest, const String & rNewName );
+ virtual BOOL MoveTo( const String & rEleName, BaseStorage * pDest, const String & rNewName );
+ virtual BOOL ValidateFAT();
+ virtual BOOL Validate( BOOL=FALSE ) const;
+ virtual BOOL ValidateMode( StreamMode ) const;
+ virtual const SvStream* GetSvStream() const;
+ virtual BOOL Equals( const BaseStorage& rStream ) const;
+ BOOL SetProperty( const String& rName, const ::com::sun::star::uno::Any& rValue );
+ BOOL GetProperty( const String& rName, ::com::sun::star::uno::Any& rValue );
+ BOOL GetProperty( const String& rEleName, const String& rName, ::com::sun::star::uno::Any& rValue );
+
+ // HACK to avoid incompatible build, can be done since this feature is only for development
+ // should be removed before release
+ UNOStorageHolderList* GetUNOStorageHolderList();
+
+//#if _SOLAR__PRIVATE
+ UCBStorageElement_Impl* FindElement_Impl( const String& rName ) const;
+ BOOL CopyStorageElement_Impl( UCBStorageElement_Impl& rElement,
+ BaseStorage* pDest, const String& rNew ) const;
+ BaseStorage* OpenStorage_Impl( const String & rEleName,
+ StreamMode, BOOL bDirect, BOOL bForceUCBStorage );
+//#endif
+
+};
+
+
+#endif
diff --git a/sot/inc/storinfo.hxx b/sot/inc/storinfo.hxx
new file mode 100644
index 000000000000..dab1f6d4540e
--- /dev/null
+++ b/sot/inc/storinfo.hxx
@@ -0,0 +1,72 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SOT_STORINFO_HXX
+#define _SOT_STORINFO_HXX
+
+#include <tools/pstm.hxx>
+#include <tools/globname.hxx>
+#include <tools/ownlist.hxx>
+#include "sot/sotdllapi.h"
+
+class StgDirEntry;
+class SvStorageInfo
+{
+friend class SvStorage;
+ String aName;
+ SvGlobalName aClassName;
+ ULONG nSize;
+ BOOL bStream:1,
+ bStorage:1;
+
+ SvStorageInfo(){}; // Fuer SvStorage
+public:
+ SvStorageInfo( const StgDirEntry& );
+ SvStorageInfo( const String& rName, ULONG nSz, BOOL bIsStorage )
+ : aName( rName )
+ , nSize( nSz )
+ , bStream( !bIsStorage )
+ , bStorage( bIsStorage )
+ {}
+
+ const SvGlobalName & GetClassName() const { return aClassName; }
+ const String & GetName() const { return aName; }
+ BOOL IsStream() const { return bStream; }
+ BOOL IsStorage() const { return bStorage; }
+ ULONG GetSize() const { return nSize; }
+};
+
+class SOT_DLLPUBLIC SvStorageInfoList
+{
+ PRV_SV_DECL_OWNER_LIST(SvStorageInfoList,SvStorageInfo)
+ const SvStorageInfo * Get( const String & rName );
+};
+
+SOT_DLLPUBLIC ULONG ReadClipboardFormat( SvStream & rStm );
+SOT_DLLPUBLIC void WriteClipboardFormat( SvStream & rStm, ULONG nFormat );
+
+#endif // _STORINFO_HXX
diff --git a/sot/prj/build.lst b/sot/prj/build.lst
new file mode 100644
index 000000000000..f2696155fd97
--- /dev/null
+++ b/sot/prj/build.lst
@@ -0,0 +1,8 @@
+to sot : tools ucbhelper unotools NULL
+to sot usr1 - all sot_mkout NULL
+to sot\inc nmake - all sot_inc NULL
+to sot\prj get - all sot_prj NULL
+to sot\source\base nmake - all sot_base sot_inc NULL
+to sot\source\sdstor nmake - all sot_sdst sot_inc NULL
+to sot\source\unoolestorage nmake - all sot_unoolestor sot_inc NULL
+to sot\util nmake - all sot_ut sot_base sot_sdst sot_unoolestor NULL
diff --git a/sot/prj/d.lst b/sot/prj/d.lst
new file mode 100644
index 000000000000..10bed8c9fe5e
--- /dev/null
+++ b/sot/prj/d.lst
@@ -0,0 +1,28 @@
+mkdir: %_DEST%\inc%_EXT%\sot
+..\inc\clsids.hxx %_DEST%\inc%_EXT%\sot\clsids.hxx
+..\inc\sot\object.hxx %_DEST%\inc%_EXT%\sot\object.hxx
+..\inc\sot\factory.hxx %_DEST%\inc%_EXT%\sot\factory.hxx
+..\inc\sot\sotdata.hxx %_DEST%\inc%_EXT%\sot\sotdata.hxx
+..\inc\agg.hxx %_DEST%\inc%_EXT%\sot\agg.hxx
+..\inc\sot\storage.hxx %_DEST%\inc%_EXT%\sot\storage.hxx
+..\inc\storinfo.hxx %_DEST%\inc%_EXT%\sot\storinfo.hxx
+..\inc\sot\sotref.hxx %_DEST%\inc%_EXT%\sot\sotref.hxx
+..\inc\sot\exchange.hxx %_DEST%\inc%_EXT%\sot\exchange.hxx
+..\inc\sot\formats.hxx %_DEST%\inc%_EXT%\sot\formats.hxx
+..\inc\absdev.hxx %_DEST%\inc%_EXT%\sot\absdev.hxx
+..\inc\stg.hxx %_DEST%\inc%_EXT%\sot\stg.hxx
+..\inc\filelist.hxx %_DEST%\inc%_EXT%\sot\filelist.hxx
+..\inc\sot\sotdllapi.h %_DEST%\inc%_EXT%\sot\sotdllapi.h
+
+..\%__SRC%\inc\sdintern.hxx %_DEST%\inc%_EXT%\sot\sdintern.hxx
+..\%__SRC%\lib\sot.lib %_DEST%\lib%_EXT%\sot.lib
+..\%__SRC%\lib\lib*.so %_DEST%\lib%_EXT%
+..\%__SRC%\lib\lib*.so.* %_DEST%\lib%_EXT%
+..\%__SRC%\lib\*.dylib %_DEST%\lib%_EXT%\*.dylib
+..\%__SRC%\lib\*.sl %_DEST%\lib%_EXT%\*.sl
+..\%__SRC%\lib\*.a %_DEST%\lib%_EXT%\*.a
+..\%__SRC%\slb\sot.lib %_DEST%\lib%_EXT%\xsot.lib
+..\%__SRC%\bin\sot?????.dll %_DEST%\bin%_EXT%\sot?????.dll
+..\%__SRC%\bin\sot?????.sym %_DEST%\bin%_EXT%\sot?????.sym
+..\%__SRC%\misc\sot?????.map %_DEST%\bin%_EXT%\sot?????.map
+..\%__SRC%\misc\sot.component %_DEST%\xml%_EXT%\sot.component
diff --git a/sot/qa/complex/olesimplestorage/OLESimpleStorageTest.java b/sot/qa/complex/olesimplestorage/OLESimpleStorageTest.java
new file mode 100644
index 000000000000..a2d8bee83713
--- /dev/null
+++ b/sot/qa/complex/olesimplestorage/OLESimpleStorageTest.java
@@ -0,0 +1,5 @@
+package complex.olesimplestorage;
+
+public interface OLESimpleStorageTest {
+ boolean test();
+}
diff --git a/sot/qa/complex/olesimplestorage/OLESimpleStorageUnitTest.java b/sot/qa/complex/olesimplestorage/OLESimpleStorageUnitTest.java
new file mode 100644
index 000000000000..054480d377d1
--- /dev/null
+++ b/sot/qa/complex/olesimplestorage/OLESimpleStorageUnitTest.java
@@ -0,0 +1,67 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+package complex.olesimplestorage;
+
+import complexlib.ComplexTestCase;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.uno.UnoRuntime;
+
+/* Document.
+ */
+
+public class OLESimpleStorageUnitTest extends ComplexTestCase {
+ private XMultiServiceFactory m_xMSF = null;
+
+ public String[] getTestMethodNames() {
+ return new String[] {
+ "ExecuteTest01"};
+ }
+
+ public String getTestObjectName() {
+ return "OLESimpleStorageUnitTest";
+ }
+
+ public void before () {
+ try {
+ m_xMSF = (XMultiServiceFactory)param.getMSF();
+ } catch ( Exception e ){
+ failed ( "Cannot create service factory!" );
+ }
+ if ( m_xMSF == null ) {
+ failed ( "Cannot create service factory!" );
+ }
+ }
+
+ public void after () {
+ m_xMSF = null;
+ }
+
+ public void ExecuteTest01() {
+ OLESimpleStorageTest aTest = new Test01( m_xMSF, log );
+ assure( "Test01 failed!", aTest.test() );
+ }
+} \ No newline at end of file
diff --git a/sot/qa/complex/olesimplestorage/Test01.java b/sot/qa/complex/olesimplestorage/Test01.java
new file mode 100644
index 000000000000..c9010e61231a
--- /dev/null
+++ b/sot/qa/complex/olesimplestorage/Test01.java
@@ -0,0 +1,126 @@
+package complex.olesimplestorage;
+
+import complexlib.ComplexTestCase;
+
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.io.XInputStream;
+import com.sun.star.io.XOutputStream;
+import com.sun.star.io.XTempFile;
+import com.sun.star.embed.XOLESimpleStorage;
+import com.sun.star.uno.UnoRuntime;
+
+import java.util.Random;
+import share.LogWriter;
+
+public class Test01 implements OLESimpleStorageTest
+{
+ XMultiServiceFactory m_xMSF = null;
+ TestHelper m_aTestHelper = null;
+ final int pStreamCnt = 5;
+ final int pBytesCnt = 10;
+
+ public Test01 ( XMultiServiceFactory xMSF, LogWriter aLogWriter )
+ {
+ m_xMSF = xMSF;
+ m_aTestHelper = new TestHelper (aLogWriter, "Test01: ");
+ }
+
+ public boolean test ()
+ {
+ try
+ {
+ //create a new temporary stream
+ Object oTempFile = m_xMSF.createInstance ( "com.sun.star.io.TempFile" );
+ XTempFile xTempFile = (XTempFile) UnoRuntime.queryInterface ( XTempFile.class, oTempFile );
+ m_aTestHelper.Message ( "A new temporary stream created." );
+
+ //create OLESimpleStorage based on it
+ Object pArgs[] = new Object[2];
+ pArgs[0] = (Object) xTempFile;
+ pArgs[1] = new Boolean( true );
+ Object oOLESimpleStorage = m_xMSF.createInstanceWithArguments ( "com.sun.star.embed.OLESimpleStorage", pArgs );
+ XOLESimpleStorage xOLESimpleStorage = (XOLESimpleStorage) UnoRuntime.queryInterface ( XOLESimpleStorage.class, oOLESimpleStorage );
+ m_aTestHelper.Message ( "OLESimpleStorage based on XStream created." );
+
+ //fill it with some streams
+ Object oStream[] = new Object[pStreamCnt];
+ byte pBytesIn[][][] = new byte [pStreamCnt][1][pBytesCnt];
+ byte pBytesOut[][] = new byte [pStreamCnt][pBytesCnt];
+ XTempFile xTempStream[] = new XTempFile[pStreamCnt];
+ Random oRandom = new Random ();
+ final String sSubStreamPrefix = "SubStream";
+ for ( int i = 0; i < pStreamCnt; i++ )
+ {
+ oRandom.nextBytes (pBytesOut[i]);
+ oStream[i] = m_xMSF.createInstance ( "com.sun.star.io.TempFile" );
+ xTempStream[i] = (XTempFile) UnoRuntime.queryInterface ( XTempFile.class, oStream[i] );
+ xTempStream[i].getOutputStream ().writeBytes (pBytesOut[i]);
+ xTempStream[i].seek (0);
+ m_aTestHelper.Message ( "Substream " + i + " initialized." );
+ if (xOLESimpleStorage.hasByName (sSubStreamPrefix + i))
+ {
+ xOLESimpleStorage.replaceByName ( sSubStreamPrefix + i, xTempStream[i] );
+ }
+ else
+ {
+ xOLESimpleStorage.insertByName ( sSubStreamPrefix + i, xTempStream[i] );
+ m_aTestHelper.Message ( "Substream " + i + " inserted." );
+ }
+ }
+
+ //commit the storage and close it
+ xOLESimpleStorage.commit ();
+ m_aTestHelper.Message ( "Storage commited." );
+ xOLESimpleStorage.dispose ();
+ for ( int i = 0; i < pStreamCnt; ++i )
+ {
+ xTempStream[i].setRemoveFile ( true );
+ xTempStream[i].getInputStream ().closeInput ();
+ xTempStream[i].getOutputStream ().closeOutput ();
+ }
+ m_aTestHelper.Message ( "Storage closed." );
+
+ //open the same stream with the constructor for inputstream
+ pArgs[0] = (Object)xTempFile.getInputStream ();
+ oOLESimpleStorage = m_xMSF.createInstanceWithArguments ( "com.sun.star.embed.OLESimpleStorage", pArgs );
+ xOLESimpleStorage = (XOLESimpleStorage)UnoRuntime.queryInterface ( XOLESimpleStorage.class, oOLESimpleStorage );
+ m_aTestHelper.Message ( "Storage reopened, based on XInputStream." );
+
+ //check that all the streams contain correct information
+ m_aTestHelper.Message ( "Checking data contained in all the substreams..." );
+ for ( int i = 0; i < pStreamCnt; ++i )
+ {
+ if ( xOLESimpleStorage.hasByName (sSubStreamPrefix + i) )
+ {
+ xTempStream[i] = (XTempFile)UnoRuntime.queryInterface (
+ XTempFile.class, xOLESimpleStorage.getByName (sSubStreamPrefix + i) );
+ xTempStream[i].seek (0);
+ xTempStream[i].getInputStream ().readBytes (pBytesIn[i], pBytesIn[i][0].length + 1 );
+ for ( int j = 0; j < pBytesCnt; ++j )
+ {
+ if ( pBytesIn[i][0][j] != pBytesOut[i][j] )
+ {
+ m_aTestHelper.Error ( "Stream " + i + " byte " + j + ": INCORRECT DATA!");
+ return false;
+ }
+ else
+ {
+ m_aTestHelper.Message ( "Stream " + i + " byte " + j + ": CORRECT." );
+ }
+ }
+ }
+ else
+ {
+ m_aTestHelper.Error( "Stream " + i + " is lost!");
+ return false;
+ }
+ }
+ m_aTestHelper.Message ( "All substreams contain correct data. SUCCESS." );
+ }
+ catch ( Exception e )
+ {
+ m_aTestHelper.Error ( "Exception: " + e );
+ }
+ return true;
+ }
+}
diff --git a/sot/qa/complex/olesimplestorage/TestHelper.java b/sot/qa/complex/olesimplestorage/TestHelper.java
new file mode 100644
index 000000000000..4b29ed15e393
--- /dev/null
+++ b/sot/qa/complex/olesimplestorage/TestHelper.java
@@ -0,0 +1,26 @@
+package complex.olesimplestorage;
+
+import share.LogWriter;
+
+public class TestHelper
+{
+ LogWriter m_aLogWriter;
+ String m_sTestPrefix;
+
+ /** Creates a new instance of TestHelper */
+ public TestHelper ( LogWriter aLogWriter, String sTestPrefix )
+ {
+ m_aLogWriter = aLogWriter;
+ m_sTestPrefix = sTestPrefix;
+ }
+
+ public void Error ( String sError )
+ {
+ m_aLogWriter.println ( m_sTestPrefix + "Error: " + sError );
+ }
+
+ public void Message ( String sMessage )
+ {
+ m_aLogWriter.println ( m_sTestPrefix + sMessage );
+ }
+}
diff --git a/sot/qa/complex/olesimplestorage/makefile.mk b/sot/qa/complex/olesimplestorage/makefile.mk
new file mode 100644
index 000000000000..3420d798c9bc
--- /dev/null
+++ b/sot/qa/complex/olesimplestorage/makefile.mk
@@ -0,0 +1,84 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ = ..$/..$/..
+TARGET = OLESimpleStorageUnitTest
+PRJNAME = sot
+PACKAGE = complex$/olesimplestorage
+
+# --- Settings -----------------------------------------------------
+.INCLUDE: settings.mk
+
+
+#----- compile .java files -----------------------------------------
+
+JARFILES = ridl.jar unoil.jar jurt.jar juh.jar java_uno.jar OOoRunner.jar
+
+JAVAFILES =\
+ OLESimpleStorageUnitTest.java\
+ OLESimpleStorageTest.java\
+ TestHelper.java\
+ Test01.java
+
+JAVACLASSFILES = $(foreach,i,$(JAVAFILES) $(CLASSDIR)$/$(PACKAGE)$/$(i:b).class)
+
+#----- make a jar from compiled files ------------------------------
+
+MAXLINELENGTH = 100000
+
+JARCLASSDIRS = $(PACKAGE)
+JARTARGET = $(TARGET).jar
+JARCOMPRESS = TRUE
+
+# --- Parameters for the test --------------------------------------
+
+# start an office if the parameter is set for the makefile
+.IF "$(OFFICE)" == ""
+CT_APPEXECCOMMAND =
+.ELSE
+CT_APPEXECCOMMAND = -AppExecutionCommand "$(OFFICE)$/soffice -accept=socket,host=localhost,port=8100;urp;"
+.ENDIF
+
+# test base is java complex
+CT_TESTBASE = -TestBase java_complex
+
+# test looks something like the.full.package.TestName
+CT_TEST = -o $(PACKAGE:s\$/\.\).$(JAVAFILES:b)
+
+# start the runner application
+CT_APP = org.openoffice.Runner
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE: target.mk
+
+RUN: run
+
+run:
+ +java -cp $(CLASSPATH) $(CT_APP) $(CT_TESTBASE) $(CT_APPEXECCOMMAND) $(CT_TEST)
+
+
diff --git a/sot/source/base/exchange.cxx b/sot/source/base/exchange.cxx
new file mode 100644
index 000000000000..67c2b64f105f
--- /dev/null
+++ b/sot/source/base/exchange.cxx
@@ -0,0 +1,508 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sot.hxx"
+#define _SOT_EXCHANGE_CXX
+#define SOT_STRING_LIST
+#define _SOT_FORMATS_INCLUDE_SYSTEMFORMATS
+#include <tools/debug.hxx>
+#include <tools/solar.h>
+#include <tools/globname.hxx>
+#include <tools/string.hxx>
+#include <sot/sotdata.hxx>
+#include <sot/exchange.hxx>
+#include <sot/formats.hxx>
+#include <clsids.hxx>
+#include <rtl/instance.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/datatransfer/DataFlavor.hpp>
+#include <comphelper/documentconstants.hxx>
+
+using namespace::com::sun::star::uno;
+using namespace::com::sun::star::datatransfer;
+
+/*
+ In diesen Tabellen stehen alle im Office verwendeten MimeTypes,
+ Format-Bezeichner und Types.
+ Die Tabelle ist nach den Formatstring-Ids sortiert und jede Id
+ ist um genau 1 groesser als ihre Vorgaenger-Id, damit die Id als
+ Tabellenindex benutzt werden kann.
+*/
+struct DataFlavorRepresentation
+{
+ const char* pMimeType;
+ const char* pName;
+ const ::com::sun::star::uno::Type* pType;
+};
+
+// -----------------------------------------------------------------------------
+
+namespace
+{
+ struct ImplFormatArray_Impl
+ {
+ const DataFlavorRepresentation* operator()()
+ {
+ static const DataFlavorRepresentation aInstance[] =
+ {
+ /* 0 SOT_FORMAT_SYSTEM_START*/ { "", "", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 1 SOT_FORMAT_STRING*/ { "text/plain;charset=utf-16", "Text", &::getCppuType( (const ::rtl::OUString*) 0 ) },
+ /* 2 SOT_FORMAT_BITMAP*/ { "application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"", "Bitmap", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 3 SOT_FORMAT_GDIMETAFILE*/ { "application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"", "GDIMetaFile", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 4 SOT_FORMAT_PRIVATE*/ { "application/x-openoffice-private;windows_formatname=\"Private\"", "Private", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 5 SOT_FORMAT_FILE*/ { "application/x-openoffice-file;windows_formatname=\"FileName\"", "FileName", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 6 SOT_FORMAT_FILE_LIST*/ { "application/x-openoffice-filelist;windows_formatname=\"FileList\"", "FileList", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 7 EMPTY*/ { "", "", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 8 EMPTY*/ { "", "", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 9 EMPTY*/ { "", "", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 10 SOT_FORMAT_RTF*/ { "text/richtext", "Rich Text Format", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 11 SOT_FORMATSTR_ID_DRAWING*/ { "application/x-openoffice-drawing;windows_formatname=\"Drawing Format\"", "Drawing Format", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 12 SOT_FORMATSTR_ID_SVXB*/ { "application/x-openoffice-svxb;windows_formatname=\"SVXB (StarView Bitmap/Animation)\"", "SVXB (StarView Bitmap/Animation)", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 13 SOT_FORMATSTR_ID_SVIM*/ { "application/x-openoffice-svim;windows_formatname=\"SVIM (StarView ImageMap)\"", "SVIM (StarView ImageMap)", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 14 SOT_FORMATSTR_ID_XFA*/ { "application/x-openoffice-xfa;windows_formatname=\"XFA (XOutDev FillAttr)\"", "XFA (XOutDev FillAttr)", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 15 SOT_FORMATSTR_ID_EDITENGINE*/ { "application/x-openoffice-editengine;windows_formatname=\"EditEngineFormat\"", "EditEngineFormat", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 16 SOT_FORMATSTR_ID_INTERNALLINK_STATE*/ { "application/x-openoffice-internallink-state;windows_formatname=\"StatusInfo vom SvxInternalLink\"", "StatusInfo vom SvxInternalLink", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 17 SOT_FORMATSTR_ID_SOLK*/ { "application/x-openoffice-solk;windows_formatname=\"SOLK (StarOffice Link)\"", "SOLK (StarOffice Link)", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 18 SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK*/ { "application/x-openoffice-netscape-bookmark;windows_formatname=\"Netscape Bookmark\"", "Netscape Bookmark", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 19 SOT_FORMATSTR_ID_TREELISTBOX*/ { "application/x-openoffice-treelistbox;windows_formatname=\"SV_LBOX_DD_FORMAT\"", "SV_LBOX_DD_FORMAT", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 20 SOT_FORMATSTR_ID_NATIVE*/ { "application/x-openoffice-native;windows_formatname=\"Native\"", "Native", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 21 SOT_FORMATSTR_ID_OWNERLINK*/ { "application/x-openoffice-ownerlink;windows_formatname=\"OwnerLink\"", "OwnerLink", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 22 SOT_FORMATSTR_ID_STARSERVER*/ { "application/x-openoffice-starserver;windows_formatname=\"StarServerFormat\"", "StarServerFormat", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 23 SOT_FORMATSTR_ID_STAROBJECT*/ { "application/x-openoffice-starobject;windows_formatname=\"StarObjectFormat\"", "StarObjectFormat", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 24 SOT_FORMATSTR_ID_APPLETOBJECT*/ { "application/x-openoffice-appletobject;windows_formatname=\"Applet Object\"", "Applet Object", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 25 SOT_FORMATSTR_ID_PLUGIN_OBJECT*/ { "application/x-openoffice-plugin-object;windows_formatname=\"PlugIn Object\"", "PlugIn Object", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 26 SOT_FORMATSTR_ID_STARWRITER_30*/ { "application/x-openoffice-starwriter-30;windows_formatname=\"StarWriter 3.0\"", "StarWriter 3.0", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 27 SOT_FORMATSTR_ID_STARWRITER_40*/ { "application/x-openoffice-starwriter-40;windows_formatname=\"StarWriter 4.0\"", "StarWriter 4.0", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 28 SOT_FORMATSTR_ID_STARWRITER_50*/ { "application/x-openoffice-starwriter-50;windows_formatname=\"StarWriter 5.0\"", "StarWriter 5.0", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 29 SOT_FORMATSTR_ID_STARWRITERWEB_40*/ { "application/x-openoffice-starwriterweb-40;windows_formatname=\"StarWriter/Web 4.0\"", "StarWriter/Web 4.0", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 30 SOT_FORMATSTR_ID_STARWRITERWEB_50*/ { "application/x-openoffice-starwriterweb-50;windows_formatname=\"StarWriter/Web 5.0\"", "StarWriter/Web 5.0", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 31 SOT_FORMATSTR_ID_STARWRITERGLOB_40*/ { "application/x-openoffice-starwriterglob-40;windows_formatname=\"StarWriter/Global 4.0\"", "StarWriter/Global 4.0", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 32 SOT_FORMATSTR_ID_STARWRITERGLOB_50*/ { "application/x-openoffice-starwriterglob-50;windows_formatname=\"StarWriter/Global 5.0\"", "StarWriter/Global 5.0", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 33 SOT_FORMATSTR_ID_STARDRAW*/ { "application/x-openoffice-stardraw;windows_formatname=\"StarDrawDocument\"", "StarDrawDocument", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 34 SOT_FORMATSTR_ID_STARDRAW_40*/ { "application/x-openoffice-stardraw-40;windows_formatname=\"StarDrawDocument 4.0\"", "StarDrawDocument 4.0", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 35 SOT_FORMATSTR_ID_STARIMPRESS_50*/ { "application/x-openoffice-starimpress-50;windows_formatname=\"StarImpress 5.0\"", "StarImpress 5.0", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 36 SOT_FORMATSTR_ID_STARDRAW_50*/ { "application/x-openoffice-stardraw-50;windows_formatname=\"StarDraw 5.0\"", "StarDraw 5.0", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 37 SOT_FORMATSTR_ID_STARCALC*/ { "application/x-openoffice-starcalc;windows_formatname=\"StarCalcDocument\"", "StarCalcDocument", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 38 SOT_FORMATSTR_ID_STARCALC_40*/ { "application/x-openoffice-starcalc-40;windows_formatname=\"StarCalc 4.0\"", "StarCalc 4.0", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 39 SOT_FORMATSTR_ID_STARCALC_50*/ { "application/x-openoffice-starcalc-50;windows_formatname=\"StarCalc 5.0\"", "StarCalc 5.0", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 40 SOT_FORMATSTR_ID_STARCHART*/ { "application/x-openoffice-starchart;windows_formatname=\"StarChartDocument\"", "StarChartDocument", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 41 SOT_FORMATSTR_ID_STARCHART_40*/ { "application/x-openoffice-starchart-40;windows_formatname=\"StarChartDocument 4.0\"", "StarChartDocument 4.0", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 42 SOT_FORMATSTR_ID_STARCHART_50*/ { "application/x-openoffice-starchart-50;windows_formatname=\"StarChart 5.0\"", "StarChart 5.0", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 43 SOT_FORMATSTR_ID_STARIMAGE*/ { "application/x-openoffice-starimage;windows_formatname=\"StarImageDocument\"", "StarImageDocument", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 44 SOT_FORMATSTR_ID_STARIMAGE_40*/ { "application/x-openoffice-starimage-40;windows_formatname=\"StarImageDocument 4.0\"", "StarImageDocument 4.0", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 45 SOT_FORMATSTR_ID_STARIMAGE_50*/ { "application/x-openoffice-starimage-50;windows_formatname=\"StarImage 5.0\"", "StarImage 5.0", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 46 SOT_FORMATSTR_ID_STARMATH*/ { "application/x-openoffice-starmath;windows_formatname=\"StarMath\"", "StarMath", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 47 SOT_FORMATSTR_ID_STARMATH_40*/ { "application/x-openoffice-starmath-40;windows_formatname=\"StarMathDocument 4.0\"", "StarMathDocument 4.0", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 48 SOT_FORMATSTR_ID_STARMATH_50*/ { "application/x-openoffice-starmath-50;windows_formatname=\"StarMath 5.0\"", "StarMath 5.0", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 49 SOT_FORMATSTR_ID_STAROBJECT_PAINTDOC*/ { "application/x-openoffice-starobject-paintdoc;windows_formatname=\"StarObjectPaintDocument\"", "StarObjectPaintDocument", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 50 SOT_FORMATSTR_ID_FILLED_AREA*/ { "application/x-openoffice-filled-area;windows_formatname=\"FilledArea\"", "FilledArea", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 51 SOT_FORMATSTR_ID_HTML*/ { "text/html", "HTML (HyperText Markup Language)", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 52 SOT_FORMATSTR_ID_HTML_SIMPLE*/ { "application/x-openoffice-html-simple;windows_formatname=\"HTML Format\"", "HTML Format", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 53 SOT_FORMATSTR_ID_CHAOS*/ { "application/x-openoffice-chaos;windows_formatname=\"FORMAT_CHAOS\"", "FORMAT_CHAOS", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 54 SOT_FORMATSTR_ID_CNT_MSGATTACHFILE*/ { "application/x-openoffice-cnt-msgattachfile;windows_formatname=\"CNT_MSGATTACHFILE_FORMAT\"", "CNT_MSGATTACHFILE_FORMAT", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 55 SOT_FORMATSTR_ID_BIFF_5*/ { "application/x-openoffice-biff5;windows_formatname=\"Biff5\"", "Biff5", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 56 SOT_FORMATSTR_ID_BIFF__5*/ { "application/x-openoffice-biff-5;windows_formatname=\"Biff 5\"", "Biff 5", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 57 SOT_FORMATSTR_ID_SYLK*/ { "application/x-openoffice-sylk;windows_formatname=\"Sylk\"", "Sylk", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 58 SOT_FORMATSTR_ID_SYLK_BIGCAPS*/ { "application/x-openoffice-sylk-bigcaps;windows_formatname=\"SYLK\"", "SYLK", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 59 SOT_FORMATSTR_ID_LINK*/ { "application/x-openoffice-link;windows_formatname=\"Link\"", "Link", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 60 SOT_FORMATSTR_ID_DIF*/ { "application/x-openoffice-dif;windows_formatname=\"DIF\"", "DIF", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 61 SOT_FORMATSTR_ID_STARDRAW_TABBAR*/ { "application/x-openoffice-stardraw-tabbar;windows_formatname=\"StarDraw TabBar\"", "StarDraw TabBar", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 62 SOT_FORMATSTR_ID_SONLK*/ { "application/x-openoffice-sonlk;windows_formatname=\"SONLK (StarOffice Navi Link)\"", "SONLK (StarOffice Navi Link)", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 63 SOT_FORMATSTR_ID_MSWORD_DOC*/ { "application/msword", "MSWordDoc", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 64 SOT_FORMATSTR_ID_STAR_FRAMESET_DOC*/ { "application/x-openoffice-star-frameset-doc;windows_formatname=\"StarFrameSetDocument\"", "StarFrameSetDocument", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 65 SOT_FORMATSTR_ID_OFFICE_DOC*/ { "application/x-openoffice-office-doc;windows_formatname=\"OfficeDocument\"", "OfficeDocument", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 66 SOT_FORMATSTR_ID_NOTES_DOCINFO*/ { "application/x-openoffice-notes-docinfo;windows_formatname=\"NotesDocInfo\"", "NotesDocInfo", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 67 SOT_FORMATSTR_ID_NOTES_HNOTE*/ { "application/x-openoffice-notes-hnote;windows_formatname=\"NoteshNote\"", "NoteshNote", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 68 SOT_FORMATSTR_ID_NOTES_NATIVE*/ { "application/x-openoffice-notes-native;windows_formatname=\"Native\"", "Native", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 69 SOT_FORMATSTR_ID_SFX_DOC*/ { "application/x-openoffice-sfx-doc;windows_formatname=\"SfxDocument\"", "SfxDocument", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 70 SOT_FORMATSTR_ID_EVDF*/ { "application/x-openoffice-evdf;windows_formatname=\"EVDF (Explorer View Dummy Format)\"", "EVDF (Explorer View Dummy Format)", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 71 SOT_FORMATSTR_ID_ESDF*/ { "application/x-openoffice-esdf;windows_formatname=\"ESDF (Explorer Search Dummy Format)\"", "ESDF (Explorer Search Dummy Format)", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 72 SOT_FORMATSTR_ID_IDF*/ { "application/x-openoffice-idf;windows_formatname=\"IDF (Iconview Dummy Format)\"", "IDF (Iconview Dummy Format)", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 73 SOT_FORMATSTR_ID_EFTP*/ { "application/x-openoffice-eftp;windows_formatname=\"EFTP (Explorer Ftp File)\"", "EFTP (Explorer Ftp File)", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 74 SOT_FORMATSTR_ID_EFD*/ { "application/x-openoffice-efd;windows_formatname=\"EFD (Explorer Ftp Dir)\"", "EFD (Explorer Ftp Dir)", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 75 SOT_FORMATSTR_ID_SVX_FORMFIELDEXCH*/ { "application/x-openoffice-svx-formfieldexch;windows_formatname=\"SvxFormFieldExch\"", "SvxFormFieldExch", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 76 SOT_FORMATSTR_ID_EXTENDED_TABBAR*/ { "application/x-openoffice-extended-tabbar;windows_formatname=\"ExtendedTabBar\"", "ExtendedTabBar", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 77 SOT_FORMATSTR_ID_SBA_DATAEXCHANGE*/ { "application/x-openoffice-sba-dataexchange;windows_formatname=\"SBA-DATAFORMAT\"", "SBA-DATAFORMAT", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 78 SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE*/ { "application/x-openoffice-sba-fielddataexchange;windows_formatname=\"SBA-FIELDFORMAT\"", "SBA-FIELDFORMAT", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 79 SOT_FORMATSTR_ID_SBA_PRIVATE_URL*/ { "application/x-openoffice-sba-private-url;windows_formatname=\"SBA-PRIVATEURLFORMAT\"", "SBA-PRIVATEURLFORMAT", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 80 SOT_FORMATSTR_ID_SBA_TABED*/ { "application/x-openofficesba-tabed;windows_formatname=\"Tabed\"", "Tabed", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 81 SOT_FORMATSTR_ID_SBA_TABID*/ { "application/x-openoffice-sba-tabid;windows_formatname=\"Tabid\"", "Tabid", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 82 SOT_FORMATSTR_ID_SBA_JOIN*/ { "application/x-openoffice-sba-join;windows_formatname=\"SBA-JOINFORMAT\"", "SBA-JOINFORMAT", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 83 SOT_FORMATSTR_ID_OBJECTDESCRIPTOR*/ { "application/x-openoffice-objectdescriptor-xml;windows_formatname=\"Star Object Descriptor (XML)\"", "Star Object Descriptor (XML)", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 84 SOT_FORMATSTR_ID_LINKSRCDESCRIPTOR*/ { "application/x-openoffice-linksrcdescriptor-xml;windows_formatname=\"Star Link Source Descriptor (XML)\"", "Star Link Source Descriptor (XML)", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 85 SOT_FORMATSTR_ID_EMBED_SOURCE*/ { "application/x-openoffice-embed-source-xml;windows_formatname=\"Star Embed Source (XML)\"", "Star Embed Source (XML)", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 86 SOT_FORMATSTR_ID_LINK_SOURCE*/ { "application/x-openoffice-link-source-xml;windows_formatname=\"Star Link Source (XML)\"", "Star Link Source (XML)", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 87 SOT_FORMATSTR_ID_EMBEDDED_OBJ*/ { "application/x-openoffice-embedded-obj-xml;windows_formatname=\"Star Embedded Object (XML)\"", "Star Embedded Object (XML)", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 88 SOT_FORMATSTR_ID_FILECONTENT*/ { "application/x-openoffice-filecontent;windows_formatname=\"FileContents\"", "FileContents", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 89 SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR*/ { "application/x-openoffice-filegrpdescriptor;windows_formatname=\"FileGroupDescriptor\"", "FileGroupDescriptor", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 90 SOT_FORMATSTR_ID_FILENAME*/ { "application/x-openoffice-filename;windows_formatname=\"FileName\"", "FileName", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 91 SOT_FORMATSTR_ID_SD_OLE*/ { "application/x-openoffice-sd-ole;windows_formatname=\"SD-OLE\"", "SD-OLE", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 92 SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE*/ { "application/x-openoffice-embedded-obj-ole;windows_formatname=\"Embedded Object\"", "Embedded Object", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 93 SOT_FORMATSTR_ID_EMBED_SOURCE_OLE*/ { "application/x-openoffice-embed-source-ole;windows_formatname=\"Embed Source\"", "Embed Source", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 94 SOT_FORMATSTR_ID_OBJECTDESCRIPTOR_OLE*/ { "application/x-openoffice-objectdescriptor-ole;windows_formatname=\"Object Descriptor\"", "Object Descriptor", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 95 SOT_FORMATSTR_ID_LINKSRCDESCRIPTOR_OLE*/ { "application/x-openoffice-linkdescriptor-ole;windows_formatname=\"Link Source Descriptor\"", "Link Source Descriptor", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 96 SOT_FORMATSTR_ID_LINK_SOURCE_OLE*/ { "application/x-openoffice-link-source-ole;windows_formatname=\"Link Source\"", "Link Source", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 97 SOT_FORMATSTR_ID_SBA_CTRLDATAEXCHANGE*/ { "application/x-openoffice-sba-ctrldataexchange;windows_formatname=\"SBA-CTRLFORMAT\"", "SBA-CTRLFORMAT", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 98 SOT_FORMATSTR_ID_OUTPLACE_OBJ*/ { "application/x-openoffice-outplace-obj;windows_formatname=\"OutPlace Object\"", "OutPlace Object", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /* 99 SOT_FORMATSTR_ID_CNT_OWN_CLIP*/ { "application/x-openoffice-cnt-own-clip;windows_formatname=\"CntOwnClipboard\"", "CntOwnClipboard", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /*100 SOT_FORMATSTR_ID_INET_IMAGE*/ { "application/x-openoffice-inet-image;windows_formatname=\"SO-INet-Image\"", "SO-INet-Image", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /*101 SOT_FORMATSTR_ID_NETSCAPE_IMAGE*/ { "application/x-openoffice-netscape-image;windows_formatname=\"Netscape Image Format\"", "Netscape Image Format", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /*102 SOT_FORMATSTR_ID_SBA_FORMEXCHANGE*/ { "application/x-openoffice-sba-formexchange;windows_formatname=\"SBA_FORMEXCHANGE\"", "SBA_FORMEXCHANGE", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /*103 SOT_FORMATSTR_ID_SBA_REPORTEXCHANGE*/ { "application/x-openoffice-sba-reportexchange;windows_formatname=\"SBA_REPORTEXCHANGE\"", "SBA_REPORTEXCHANGE", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /*104 SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR*/ { "application/x-openoffice-uniformresourcelocator;windows_formatname=\"UniformResourceLocator\"", "UniformResourceLocator", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /*105 SOT_FORMATSTR_ID_STARCHARTDOCUMENT_50*/ { "application/x-openoffice-starchartdocument-50;windows_formatname=\"StarChartDocument 5.0\"", "StarChartDocument 5.0", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /*106 SOT_FORMATSTR_ID_GRAPHOBJ*/ { "application/x-openoffice-graphobj;windows_formatname=\"Graphic Object\"", "Graphic Object", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /*107 SOT_FORMATSTR_ID_STARWRITER_60*/ { MIMETYPE_VND_SUN_XML_WRITER_ASCII, "Writer 6.0", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /*108 SOT_FORMATSTR_ID_STARWRITERWEB_60*/ { MIMETYPE_VND_SUN_XML_WRITER_WEB_ASCII, "Writer/Web 6.0", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /*109 SOT_FORMATSTR_ID_STARWRITERGLOB_60*/ { MIMETYPE_VND_SUN_XML_WRITER_GLOBAL_ASCII, "Writer/Global 6.0", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /*110 SOT_FORMATSTR_ID_STARWDRAW_60*/ { MIMETYPE_VND_SUN_XML_DRAW_ASCII, "Draw 6.0", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /*111 SOT_FORMATSTR_ID_STARIMPRESS_60*/ { MIMETYPE_VND_SUN_XML_IMPRESS_ASCII, "Impress 6.0", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /*112 SOT_FORMATSTR_ID_STARCALC_60*/ { MIMETYPE_VND_SUN_XML_CALC_ASCII, "Calc 6.0", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /*113 SOT_FORMATSTR_ID_STARCHART_60*/ { MIMETYPE_VND_SUN_XML_CHART_ASCII, "Chart 6.0", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /*114 SOT_FORMATSTR_ID_STARMATH_60*/ { MIMETYPE_VND_SUN_XML_MATH_ASCII, "Math 6.0", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /*115 SOT_FORMATSTR_ID_WMF*/ { "application/x-openoffice-wmf;windows_formatname=\"Image WMF\"", "Windows MetaFile", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /*116 SOT_FORMATSTR_ID_DBACCESS_QUERY*/ { "application/x-openoffice-dbaccess-query;windows_formatname=\"Data source Query Object\"", "Data source Query Object", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /*117 SOT_FORMATSTR_ID_DBACCESS_TABLE*/ { "application/x-openoffice-dbaccess-table;windows_formatname=\"Data source Table\"", "Data source Table", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /*118 SOT_FORMATSTR_ID_DBACCESS_COMMAND*/ { "application/x-openoffice-dbaccess-command;windows_formatname=\"SQL query\"", "SQL query", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /*119 SOT_FORMATSTR_ID_DIALOG_60*/ { "application/vnd.sun.xml.dialog", "Dialog 6.0", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /*120 SOT_FORMATSTR_ID_EMF*/ { "application/x-openoffice-emf;windows_formatname=\"Image EMF\"", "Windows Enhanced MetaFile", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /*121 SOT_FORMATSTR_ID_BIFF_8*/ { "application/x-openoffice-biff-8;windows_formatname=\"Biff8\"", "Biff8", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /*122 SOT_FORMATSTR_ID_BMP*/ { "image/bmp", "Windows Bitmap", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /*123 SOT_FORMATSTR_ID_HTML_NO_COMMENT */ { "application/x-openoffice-html-no-comment;windows_formatname=\"HTML Format\"", "HTML (no comment)", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /*124 SOT_FORMATSTR_ID_STARWRITER_8*/ { MIMETYPE_OASIS_OPENDOCUMENT_TEXT_ASCII, "Writer 8", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /*125 SOT_FORMATSTR_ID_STARWRITERWEB_8*/ { MIMETYPE_OASIS_OPENDOCUMENT_TEXT_WEB_ASCII, "Writer/Web 8", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /*126 SOT_FORMATSTR_ID_STARWRITERGLOB_8*/ { MIMETYPE_OASIS_OPENDOCUMENT_TEXT_GLOBAL_ASCII, "Writer/Global 8", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /*127 SOT_FORMATSTR_ID_STARWDRAW_8*/ { MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_ASCII, "Draw 8", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /*128 SOT_FORMATSTR_ID_STARIMPRESS_8*/ { MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_ASCII, "Impress 8", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /*129 SOT_FORMATSTR_ID_STARCALC_8*/ { MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_ASCII, "Calc 8", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /*130 SOT_FORMATSTR_ID_STARCHART_8*/ { MIMETYPE_OASIS_OPENDOCUMENT_CHART_ASCII, "Chart 8", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /*131 SOT_FORMATSTR_ID_STARMATH_8*/ { MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_ASCII, "Math 8", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /*132 SOT_FORMATSTR_ID_XFORMS */ { "application/x-openoffice-xforms;windows_formatname=\"??? Format\"", "???", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /*133 SOT_FORMATSTR_ID_STARWRITER_8_TEMPLATE*/ { MIMETYPE_OASIS_OPENDOCUMENT_TEXT_TEMPLATE_ASCII, "Writer 8 Template", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /*134 SOT_FORMATSTR_ID_STARWDRAW_8_TEMPLATE*/ { MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_TEMPLATE_ASCII, "Draw 8 Template", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /*135 SOT_FORMATSTR_ID_STARIMPRESS_8_TEMPLATE*/ { MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_TEMPLATE_ASCII, "Impress 8 Template", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /*136 SOT_FORMATSTR_ID_STARCALC_8_TEMPLATE*/ { MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_TEMPLATE_ASCII, "Calc 8 Template", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /*137 SOT_FORMATSTR_ID_STARCHART_8_TEMPLATE*/ { MIMETYPE_OASIS_OPENDOCUMENT_CHART_TEMPLATE_ASCII, "Chart 8 Template", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /*138 SOT_FORMATSTR_ID_STARMATH_8_TEMPLATE*/ { MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_TEMPLATE_ASCII, "Math 8 Template", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /*139 SOT_FORMATSTR_ID_STARBASE_8*/ { MIMETYPE_OASIS_OPENDOCUMENT_DATABASE_ASCII, "StarBase 8", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ /*140 SOT_FORMAT_GDIMETAFILE*/ { "application/x-openoffice-highcontrast-gdimetafile;windows_formatname=\"GDIMetaFile\"", "High Contrast GDIMetaFile", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) },
+ };
+ return &aInstance[0];
+ }
+ };
+
+ struct FormatArray_Impl
+ : public rtl::StaticAggregate<
+ const DataFlavorRepresentation, ImplFormatArray_Impl > {};
+}
+
+//-----------------------------------------------------------------------
+
+static List& InitFormats_Impl()
+{
+ SotData_Impl * pSotData = SOTDATA();
+ if( !pSotData->pDataFlavorList )
+ pSotData->pDataFlavorList = new List();
+ return *pSotData->pDataFlavorList;
+}
+
+/*************************************************************************
+|*
+|* SotExchange::RegisterFormatName()
+|*
+|* Beschreibung CLIP.SDW
+*************************************************************************/
+ULONG SotExchange::RegisterFormatName( const String& rName )
+{
+ const DataFlavorRepresentation *pFormatArray_Impl = FormatArray_Impl::get();
+ // teste zuerst die Standard - Name
+ ULONG i, nMax = SOT_FORMAT_FILE_LIST;
+ for( i = SOT_FORMAT_STRING; i <= nMax; ++i )
+ if( COMPARE_EQUAL == rName.CompareToAscii( pFormatArray_Impl[ i ].pName ) )
+ return i;
+
+ // BM: the chart format 105 ("StarChartDocument 5.0") was written
+ // only into 5.1 chart documents - in 5.0 and 5.2 it was 42 ("StarChart 5.0")
+ // The registry only contains the entry for the 42 format id.
+ nMax = SOT_FORMATSTR_ID_USER_END;
+ for( i = SOT_FORMAT_RTF; i <= nMax; ++i )
+ if( rName.EqualsAscii( pFormatArray_Impl[ i ].pName ) )
+ return ( (i == SOT_FORMATSTR_ID_STARCHARTDOCUMENT_50)
+ ? SOT_FORMATSTR_ID_STARCHART_50
+ : i );
+
+ // dann in der dynamischen Liste
+ List& rL = InitFormats_Impl();
+ for( i = 0, nMax = rL.Count(); i < nMax; i++ )
+ {
+ DataFlavor* pFlavor = (DataFlavor*) rL.GetObject( i );
+ if( pFlavor && rName == String( pFlavor->HumanPresentableName ) )
+ return i + SOT_FORMATSTR_ID_USER_END + 1;
+ }
+
+ // nMax ist der neue Platz
+ DataFlavor* pNewFlavor = new DataFlavor;
+
+ pNewFlavor->MimeType = rName;
+ pNewFlavor->HumanPresentableName = rName;
+ pNewFlavor->DataType = ::getCppuType( (const ::rtl::OUString*) 0 );
+
+ rL.Insert( pNewFlavor, LIST_APPEND );
+
+ return nMax + SOT_FORMATSTR_ID_USER_END + 1;
+}
+
+ULONG SotExchange::RegisterFormatMimeType( const String& rMimeType )
+{
+ const DataFlavorRepresentation *pFormatArray_Impl = FormatArray_Impl::get();
+ // teste zuerst die Standard - Name
+ ULONG i, nMax = SOT_FORMAT_FILE_LIST;
+ for( i = SOT_FORMAT_STRING; i <= nMax; ++i )
+ if( rMimeType.EqualsAscii( pFormatArray_Impl[ i ].pMimeType ) )
+ return i;
+
+ nMax = SOT_FORMATSTR_ID_USER_END;
+ for( i = SOT_FORMAT_RTF; i <= nMax; ++i )
+ if( rMimeType.EqualsAscii( pFormatArray_Impl[ i ].pMimeType ) )
+ return i;
+
+ // dann in der dynamischen Liste
+ List& rL = InitFormats_Impl();
+ for( i = 0, nMax = rL.Count(); i < nMax; i++ )
+ {
+ DataFlavor* pFlavor = (DataFlavor*) rL.GetObject( i );
+ if( pFlavor && rMimeType == String( pFlavor->MimeType ) )
+ return i + SOT_FORMATSTR_ID_USER_END + 1;
+ }
+
+ // nMax ist der neue Platz
+ DataFlavor* pNewFlavor = new DataFlavor;
+
+ pNewFlavor->MimeType = rMimeType;
+ pNewFlavor->HumanPresentableName = rMimeType;
+ pNewFlavor->DataType = ::getCppuType( (const ::rtl::OUString*) 0 );
+
+ rL.Insert( pNewFlavor, LIST_APPEND );
+
+ return nMax + SOT_FORMATSTR_ID_USER_END + 1;
+}
+
+/*************************************************************************
+|*
+|* SotExchange::RegisterFormatName()
+|*
+|* Beschreibung CLIP.SDW
+*************************************************************************/
+ULONG SotExchange::RegisterFormat( const DataFlavor& rFlavor )
+{
+ ULONG nRet = GetFormat( rFlavor );
+
+ if( !nRet )
+ {
+ List& rL = InitFormats_Impl();
+ nRet = rL.Count() + SOT_FORMATSTR_ID_USER_END + 1;
+ rL.Insert( new DataFlavor( rFlavor ), LIST_APPEND );
+ }
+
+ return nRet;
+}
+
+/*************************************************************************
+|*
+|* SotExchange::GetFormatDataFlavor()
+|*
+*************************************************************************/
+
+sal_Bool SotExchange::GetFormatDataFlavor( ULONG nFormat, DataFlavor& rFlavor )
+{
+ sal_Bool bRet;
+
+ if( SOT_FORMATSTR_ID_USER_END >= nFormat )
+ {
+ const DataFlavorRepresentation& rData = FormatArray_Impl::get()[nFormat];
+ rFlavor.MimeType = ::rtl::OUString::createFromAscii( rData.pMimeType );
+ rFlavor.HumanPresentableName = ::rtl::OUString::createFromAscii( rData.pName );
+ rFlavor.DataType = *rData.pType;
+
+ bRet = sal_True;
+ }
+ else
+ {
+ List& rL = InitFormats_Impl();
+
+ nFormat -= SOT_FORMATSTR_ID_USER_END + 1;
+
+ if( rL.Count() > nFormat )
+ {
+ rFlavor = *(DataFlavor*) rL.GetObject( nFormat );
+ bRet = sal_True;
+ }
+ else
+ {
+ rFlavor = DataFlavor();
+ bRet = sal_False;
+ }
+ }
+
+ DBG_ASSERT( bRet, "SotExchange::GetFormatDataFlavor(): DataFlavor not initialized" );
+
+ return bRet;
+}
+
+/*************************************************************************
+|*
+|* SotExchange::GetFormatMimeType( ULONG nFormat )
+|*
+*************************************************************************/
+
+String SotExchange::GetFormatMimeType( ULONG nFormat )
+{
+ String sMimeType;
+ if( SOT_FORMATSTR_ID_USER_END >= nFormat )
+ sMimeType.AssignAscii( FormatArray_Impl::get()[nFormat].pMimeType );
+ else
+ {
+ List& rL = InitFormats_Impl();
+
+ nFormat -= SOT_FORMATSTR_ID_USER_END + 1;
+
+ if( rL.Count() > nFormat )
+ sMimeType = ((DataFlavor*) rL.GetObject( nFormat ))->MimeType;
+ }
+
+ DBG_ASSERT( sMimeType.Len(), "SotExchange::GetFormatMimeType(): DataFlavor not initialized" );
+
+ return sMimeType;
+}
+
+/*************************************************************************
+|*
+|* SotExchange::GetFormatIdFromMimeType( const String& rMimeType )
+|*
+*************************************************************************/
+
+ULONG SotExchange::GetFormatIdFromMimeType( const String& rMimeType )
+{
+ const DataFlavorRepresentation *pFormatArray_Impl = FormatArray_Impl::get();
+ ULONG i, nMax = SOT_FORMAT_FILE_LIST;
+ for( i = SOT_FORMAT_STRING; i <= nMax; ++i )
+ if( rMimeType.EqualsAscii( pFormatArray_Impl[ i ].pMimeType ) )
+ return i;
+
+ // BM: the chart format 105 ("StarChartDocument 5.0") was written
+ // only into 5.1 chart documents - in 5.0 and 5.2 it was 42 ("StarChart 5.0")
+ // The registry only contains the entry for the 42 format id.
+ nMax = SOT_FORMATSTR_ID_USER_END;
+ for( i = SOT_FORMAT_RTF; i <= nMax; ++i )
+ if( rMimeType.EqualsAscii( pFormatArray_Impl[ i ].pMimeType ) )
+ return ( (i == SOT_FORMATSTR_ID_STARCHARTDOCUMENT_50)
+ ? SOT_FORMATSTR_ID_STARCHART_50
+ : i );
+
+ // dann in der dynamischen Liste
+ List& rL = InitFormats_Impl();
+ ::rtl::OUString aMimeType( rMimeType );
+ for( i = 0, nMax = rL.Count(); i < nMax; i++ )
+ {
+ DataFlavor* pFlavor = (DataFlavor*) rL.GetObject( i );
+ if( pFlavor && aMimeType == pFlavor->MimeType )
+ return i + SOT_FORMATSTR_ID_USER_END + 1;
+ }
+
+ return 0;
+}
+
+/*************************************************************************
+|*
+|* SotExchange::GetFormatName()
+|*
+|* Beschreibung CLIP.SDW
+*************************************************************************/
+ULONG SotExchange::GetFormat( const DataFlavor& rFlavor )
+{
+ // teste zuerst die Standard - Name
+ const ::rtl::OUString& rMimeType = rFlavor.MimeType;
+ const String aMimeType( rMimeType );
+ ULONG i, nMax = SOT_FORMAT_FILE_LIST;
+ const DataFlavorRepresentation *pFormatArray_Impl = FormatArray_Impl::get();
+ for( i = SOT_FORMAT_STRING; i <= nMax; ++i )
+ if( aMimeType.EqualsAscii( pFormatArray_Impl[ i ].pMimeType ) )
+ return i;
+
+ // BM: the chart format 105 ("StarChartDocument 5.0") was written
+ // only into 5.1 chart documents - in 5.0 and 5.2 it was 42 ("StarChart 5.0")
+ // The registry only contains the entry for the 42 format id.
+ nMax = SOT_FORMATSTR_ID_USER_END;
+ for( i = SOT_FORMAT_RTF; i <= nMax; ++i )
+ if( aMimeType.EqualsAscii( pFormatArray_Impl[ i ].pMimeType ) )
+ return ( (i == SOT_FORMATSTR_ID_STARCHARTDOCUMENT_50)
+ ? SOT_FORMATSTR_ID_STARCHART_50
+ : i );
+
+ // dann in der dynamischen Liste
+ List& rL = InitFormats_Impl();
+ for( i = 0, nMax = rL.Count(); i < nMax; i++ )
+ {
+ DataFlavor* pFlavor = (DataFlavor*) rL.GetObject( i );
+ if( pFlavor && rMimeType == pFlavor->MimeType )
+ return i + SOT_FORMATSTR_ID_USER_END + 1;
+ }
+
+ return 0;
+}
+
+/*************************************************************************
+|*
+|* SotExchange::GetFormatName()
+|*
+|* Beschreibung CLIP.SDW
+*************************************************************************/
+String SotExchange::GetFormatName( ULONG nFormat )
+{
+ DataFlavor aFlavor;
+ String aRet;
+
+ if( GetFormatDataFlavor( nFormat, aFlavor ) )
+ aRet = aFlavor.HumanPresentableName;
+
+ return aRet;
+}
+
+BOOL SotExchange::IsInternal( const SvGlobalName& rName )
+{
+ if ( rName == SvGlobalName(SO3_SW_CLASSID_60) ||
+ rName == SvGlobalName(SO3_SC_CLASSID_60) ||
+ rName == SvGlobalName(SO3_SIMPRESS_CLASSID_60) ||
+ rName == SvGlobalName(SO3_SDRAW_CLASSID_60) ||
+ rName == SvGlobalName(SO3_SCH_CLASSID_60) ||
+ rName == SvGlobalName(SO3_SM_CLASSID_60) ||
+ rName == SvGlobalName(SO3_SWWEB_CLASSID_60) ||
+ rName == SvGlobalName(SO3_SWGLOB_CLASSID_60) )
+ return TRUE;
+ return FALSE;
+}
diff --git a/sot/source/base/factory.cxx b/sot/source/base/factory.cxx
new file mode 100644
index 000000000000..4934f99e78c6
--- /dev/null
+++ b/sot/source/base/factory.cxx
@@ -0,0 +1,406 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sot.hxx"
+
+#define _SOT_FACTORY_CXX
+#define SOT_STRING_LIST
+
+#include <sot/factory.hxx>
+#include <tools/debug.hxx>
+#include <tools/string.hxx>
+#include <sot/object.hxx>
+#include <sot/sotdata.hxx>
+#include <clsids.hxx>
+#include <rtl/instance.hxx>
+#include <com/sun/star/datatransfer/DataFlavor.hpp>
+
+/************** class SotData_Impl *********************************************/
+/*************************************************************************
+|* SotData_Impl::SotData_Impl
+|*
+|* Beschreibung
+*************************************************************************/
+SotData_Impl::SotData_Impl()
+ : nSvObjCount( 0 )
+ , pObjectList( NULL )
+ , pFactoryList( NULL )
+ , pSotObjectFactory( NULL )
+ , pSotStorageStreamFactory( NULL )
+ , pSotStorageFactory( NULL )
+ , pDataFlavorList( NULL )
+{
+}
+/*************************************************************************
+|* SOTDATA()
+|*
+|* Beschreibung
+*************************************************************************/
+namespace { struct ImplData : public rtl::Static<SotData_Impl, ImplData> {}; }
+SotData_Impl * SOTDATA()
+{
+ return &ImplData::get();
+}
+
+/*************************************************************************
+|* SotFactory::DeInit()
+|*
+|* Beschreibung
+*************************************************************************/
+void SotFactory::DeInit()
+{
+ SotData_Impl * pSotData = SOTDATA();
+
+ if( pSotData->nSvObjCount )
+ {
+#ifdef DBG_UTIL
+ ByteString aStr( "Objects alive: " );
+ aStr.Append( ByteString::CreateFromInt32( pSotData->nSvObjCount ) );
+ DBG_WARNING( aStr.GetBuffer() );
+
+/*
+ SotObjectList *pObjList = pSotData->pObjectList;
+
+ if( pObjList )
+ {
+ SotObject * p = pObjList->First();
+ while( p )
+ {
+ String aStr( "Factory: " );
+ aStr += p->GetSvFactory()->GetClassName();
+ aStr += " Count: ";
+ aStr += p->GetRefCount();
+ DBG_TRACE( "\tReferences:" );
+ p->TestObjRef( FALSE );
+#ifdef TEST_INVARIANT
+ DBG_TRACE( "\tInvariant:" );
+ p->TestInvariant( TRUE );
+#endif
+ p = pObjList->Next();
+ }
+ }
+*/
+#endif
+ return;
+ }
+
+ // Muss von hinten nach vorne zerstoert werden. Das ist die umgekehrte
+ // Reihenfolge der Erzeugung
+ SotFactoryList* pFactoryList = pSotData->pFactoryList;
+ if( pFactoryList )
+ {
+ SotFactory * pFact = pFactoryList->Last();
+ while( NULL != (pFact = pFactoryList->Remove()) )
+ {
+ delete pFact;
+ pFact = pFactoryList->Last();
+ }
+ delete pFactoryList;
+ pSotData->pFactoryList = NULL;
+ }
+
+ delete pSotData->pObjectList;
+ pSotData->pObjectList = NULL;
+ if( pSotData->pDataFlavorList )
+ {
+
+ for( ULONG i = 0, nMax = pSotData->pDataFlavorList->Count(); i < nMax; i++ )
+ delete (::com::sun::star::datatransfer::DataFlavor*) pSotData->pDataFlavorList->GetObject( i );
+ delete pSotData->pDataFlavorList;
+ pSotData->pDataFlavorList = NULL;
+ }
+ //delete pSOTDATA();
+ //SOTDATA() = NULL;
+}
+
+
+/************** class SotFactory *****************************************/
+/*************************************************************************
+|* SotFactory::SotFactory()
+|*
+|* Beschreibung
+*************************************************************************/
+TYPEINIT0(SotFactory);
+
+SotFactory::SotFactory( const SvGlobalName & rName,
+ const String & rClassName,
+ CreateInstanceType pCreateFuncP )
+ : SvGlobalName ( rName )
+ , nSuperCount ( 0 )
+ , pSuperClasses ( NULL )
+ , pCreateFunc ( pCreateFuncP )
+ , aClassName ( rClassName )
+{
+#ifdef DBG_UTIL
+ SvGlobalName aEmptyName;
+ if( aEmptyName != *this )
+ { // wegen Sfx-BasicFactories
+ DBG_ASSERT( aEmptyName != *this, "create factory without SvGlobalName" );
+ if( Find( *this ) )
+ {
+ /*
+ String aStr( GetClassName() );
+ aStr += ", UniqueName: ";
+ aStr += GetHexName();
+ aStr += ", create factories with the same unique name";
+ DBG_ERROR( aStr );
+ */
+ DBG_ERROR( "create factories with the same unique name" );
+ }
+ }
+#endif
+ SotData_Impl * pSotData = SOTDATA();
+ if( !pSotData->pFactoryList )
+ pSotData->pFactoryList = new SotFactoryList();
+ // muss nach hinten, wegen Reihenfolge beim zerstoeren
+ pSotData->pFactoryList->Insert( this, LIST_APPEND );
+}
+
+
+//=========================================================================
+SotFactory::~SotFactory()
+{
+ delete [] pSuperClasses;
+}
+
+
+/*************************************************************************
+|* SotFactory::
+|*
+|* Beschreibung Zugriffsmethoden auf SotData_Impl-Daten
+*************************************************************************/
+UINT32 SotFactory::GetSvObjectCount()
+{
+ return SOTDATA()->nSvObjCount;
+}
+
+
+const SotFactoryList * SotFactory::GetFactoryList()
+{
+ return SOTDATA()->pFactoryList;
+}
+
+/*************************************************************************
+|* SotFactory::Find()
+|*
+|* Beschreibung
+*************************************************************************/
+const SotFactory* SotFactory::Find( const SvGlobalName & rFactName )
+{
+ SvGlobalName aEmpty;
+ SotData_Impl * pSotData = SOTDATA();
+ if( rFactName != aEmpty && pSotData->pFactoryList )
+ {
+ SotFactory * pFact = pSotData->pFactoryList->First();
+ while( pFact )
+ {
+ if( *pFact == rFactName )
+ return pFact;
+ pFact = pSotData->pFactoryList->Next();
+ }
+ }
+
+ return 0;
+}
+
+/*************************************************************************
+|* SotFactory::PutSuperClass()
+|*
+|* Beschreibung
+*************************************************************************/
+void SotFactory::PutSuperClass( const SotFactory * pFact )
+{
+ nSuperCount++;
+ if( !pSuperClasses )
+ pSuperClasses = new const SotFactory * [ nSuperCount ];
+ else
+ {
+ const SotFactory ** pTmp = new const SotFactory * [ nSuperCount ];
+ memcpy( (void *)pTmp, (void *)pSuperClasses,
+ sizeof( void * ) * (nSuperCount -1) );
+ delete [] pSuperClasses;
+ pSuperClasses = pTmp;
+ }
+ pSuperClasses[ nSuperCount -1 ] = pFact;
+}
+
+
+/*************************************************************************
+|* SotFactory::IncSvObjectCount()
+|*
+|* Beschreibung
+*************************************************************************/
+void SotFactory::IncSvObjectCount( SotObject * pObj )
+{
+ SotData_Impl * pSotData = SOTDATA();
+ pSotData->nSvObjCount++;
+ if( !pSotData->pObjectList )
+ pSotData->pObjectList = new SotObjectList();
+ if( pObj )
+ pSotData->pObjectList->Insert( pObj );
+}
+
+
+/*************************************************************************
+|* SotFactory::DecSvObjectCount()
+|*
+|* Beschreibung
+*************************************************************************/
+void SotFactory::DecSvObjectCount( SotObject * pObj )
+{
+ SotData_Impl * pSotData = SOTDATA();
+ pSotData->nSvObjCount--;
+ if( pObj )
+ pSotData->pObjectList->Remove( pObj );
+ if( !pSotData->nSvObjCount )
+ {
+ //keine internen und externen Referenzen mehr
+ }
+}
+
+
+/*************************************************************************
+|* SotFactory::TestInvariant()
+|*
+|* Beschreibung
+*************************************************************************/
+void SotFactory::TestInvariant()
+{
+#ifdef TEST_INVARIANT
+ SotData_Impl * pSotData = SOTDATA();
+ if( pSotData->pObjectList )
+ {
+ ULONG nCount = pSotData->pObjectList->Count();
+ for( ULONG i = 0; i < nCount ; i++ )
+ {
+ pSotData->pObjectList->GetObject( i )->TestInvariant( FALSE );
+ }
+ }
+#endif
+}
+
+/*************************************************************************
+|* SotFactory::CreateInstance()
+|*
+|* Beschreibung
+*************************************************************************/
+void * SotFactory::CreateInstance( SotObject ** ppObj ) const
+{
+ DBG_ASSERT( pCreateFunc, "SotFactory::CreateInstance: pCreateFunc == 0" );
+ return pCreateFunc( ppObj );
+}
+
+//=========================================================================
+void * SotFactory::CastAndAddRef
+(
+ SotObject * pObj /* Das Objekt von dem der Typ gepr"uft wird. */
+) const
+/* [Beschreibung]
+
+ Ist eine Optimierung, damit die Ref-Klassen k"urzer implementiert
+ werden k"onnen. pObj wird auf den Typ der Factory gecastet.
+ In c++ (wenn es immer erlaubt w"are) w"urde der void * wie im
+ Beispiel gebildet.
+ Factory der Klasse SvPersist.
+ void * p = (void *)(SvPersist *)pObj;
+
+ [R"uckgabewert]
+
+ void *, NULL, pObj war NULL oder das Objekt war nicht vom Typ
+ der Factory.
+ Ansonsten wird pObj zuerst auf den Typ der Factory
+ gecastet und dann auf void *.
+
+ [Querverweise]
+
+ <SotObject::CastAndAddRef>
+*/
+{
+ return pObj ? pObj->CastAndAddRef( this ) : NULL;
+}
+
+//=========================================================================
+void * SotFactory::AggCastAndAddRef
+(
+ SotObject * pObj /* Das Objekt von dem der Typ gepr"uft wird. */
+) const
+/* [Beschreibung]
+
+ Ist eine Optimierung, damit die Ref-Klassen k"urzer implementiert
+ werden k"onnen. pObj wird auf den Typ der Factory gecastet.
+ In c++ (wenn es immer erlaubt w"are) w"urde der void * wie im
+ Beispiel gebildet.
+ Factory der Klasse SvPersist.
+ void * p = (void *)(SvPersist *)pObj;
+ Hinzu kommt noch, dass ein Objekt aus meheren c++ Objekten
+ zusammengesetzt sein kann. Diese Methode sucht nach einem
+ passenden Objekt.
+
+ [R"uckgabewert]
+
+ void *, NULL, pObj war NULL oder das Objekt war nicht vom Typ
+ der Factory.
+ Ansonsten wird pObj zuerst auf den Typ der Factory
+ gecastet und dann auf void *.
+
+ [Querverweise]
+
+ <SvObject::AggCast>
+*/
+{
+ void * pRet = NULL;
+ if( pObj )
+ {
+ pRet = pObj->AggCast( this );
+ if( pRet )
+ pObj->AddRef();
+ }
+ return pRet;
+}
+
+/*************************************************************************
+|* SotFactory::Is()
+|*
+|* Beschreibung
+*************************************************************************/
+BOOL SotFactory::Is( const SotFactory * pSuperCl ) const
+{
+ if( this == pSuperCl )
+ return TRUE;
+
+ for( USHORT i = 0; i < nSuperCount; i++ )
+ {
+ if( pSuperClasses[ i ]->Is( pSuperCl ) )
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+
+
diff --git a/sot/source/base/filelist.cxx b/sot/source/base/filelist.cxx
new file mode 100644
index 000000000000..4f854add304d
--- /dev/null
+++ b/sot/source/base/filelist.cxx
@@ -0,0 +1,199 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sot.hxx"
+
+#include<tools/list.hxx>
+#include<tools/stream.hxx>
+#include<tools/string.hxx>
+#include<tools/rtti.hxx>
+#include<sot/exchange.hxx>
+#include<filelist.hxx>
+#include <osl/thread.h>
+
+TYPEINIT1_AUTOFACTORY( FileList, SvDataCopyStream );
+
+// String-Liste zum Speichern der Namen deklarieren
+DECLARE_LIST( FileStringList, String* )
+
+
+/*************************************************************************
+|*
+|* FileList - Ctor/Dtor
+|*
+\*************************************************************************/
+
+FileList::FileList()
+{
+ pStrList = new FileStringList();
+}
+
+FileList::~FileList()
+{
+ ClearAll();
+}
+
+void FileList::ClearAll( void )
+{
+ // Strings in der Liste loeschen
+ ULONG nCount = pStrList->Count();
+ for( ULONG i = 0 ; i < nCount ; i++ )
+ delete pStrList->GetObject( i );
+
+ // Liste loeschen
+ delete pStrList;
+}
+
+/*************************************************************************
+|*
+|* FileList - Zuweisungsoperator
+|*
+\*************************************************************************/
+
+FileList& FileList::operator=( const FileList& rFileList )
+{
+ // Liste duplizieren
+ *pStrList = *rFileList.pStrList;
+
+ // Strings in der Liste kopieren
+ ULONG nCount = pStrList->Count();
+ for( ULONG i = 0 ; i < nCount ; i++ )
+ pStrList->Replace( new String( *rFileList.pStrList->GetObject( i ) ), i );
+
+ return *this;
+}
+
+/*************************************************************************
+|*
+|* FileList::GetFormatName()
+|*
+\*************************************************************************/
+
+ULONG FileList::GetFormat()
+{
+ return FORMAT_FILE_LIST;
+}
+
+/******************************************************************************
+|*
+|* virtuelle SvData-Methoden
+|*
+\******************************************************************************/
+
+void FileList::Load( SvStream& rIStm )
+{
+ rIStm >> *this;
+}
+
+void FileList::Save( SvStream& rOStm )
+{
+ rOStm << *this;
+}
+
+void FileList::Assign( const SvDataCopyStream& rCopyStream )
+{
+ *this = (const FileList&)rCopyStream;
+}
+
+/******************************************************************************
+|*
+|* Stream-Operatoren
+|*
+\******************************************************************************/
+
+/*
+ * NOTE: to correctly handle this Protocol with Unicode, native Win32 must be called:
+ * e.g. DropQueryFile
+ */
+
+SvStream& operator<<( SvStream& rOStm, const FileList& /*rFileList*/ )
+{
+ OSL_ENSURE(false, "Not implemented!");
+ return rOStm;
+}
+
+/* #i28176#
+ The Windows clipboard bridge now provides a double '\0'
+ terminated list of file names for format SOT_FORMAT_FILE_LIST
+ instead of the original Windows Sv_DROPFILES structure. All strings
+ in this list are UTF16 strings. Shell link files will be already
+ resolved by the Windows clipboard bridge.*/
+SvStream& operator>>( SvStream& rIStm, FileList& rFileList )
+{
+ rFileList.ClearAll();
+ rFileList.pStrList = new FileStringList();
+
+ String aStr;
+ sal_uInt16 c;
+
+ while (!rIStm.IsEof())
+ {
+ aStr.Erase();
+
+ // read first character of filepath; c==0 > reach end of stream
+ rIStm >> c;
+ if (!c)
+ break;
+
+ // read string till c==0
+ while (c && !rIStm.IsEof())
+ {
+ aStr += (sal_Unicode)c;
+ rIStm >> c;
+ }
+
+ // append the filepath
+ rFileList.AppendFile(aStr);
+ }
+ return rIStm;
+}
+
+/******************************************************************************
+|*
+|* Liste fuellen/abfragen
+|*
+\******************************************************************************/
+
+void FileList::AppendFile( const String& rStr )
+{
+ pStrList->Insert( new String( rStr ) , pStrList->Count() );
+}
+
+String FileList::GetFile( ULONG i ) const
+{
+ String aStr;
+ if( i < pStrList->Count() )
+ aStr = *pStrList->GetObject( i );
+ return aStr;
+}
+
+ULONG FileList::Count( void ) const
+{
+ return pStrList->Count();
+}
+
diff --git a/sot/source/base/formats.cxx b/sot/source/base/formats.cxx
new file mode 100644
index 000000000000..baddde6e716f
--- /dev/null
+++ b/sot/source/base/formats.cxx
@@ -0,0 +1,1663 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sot.hxx"
+
+#define _SOT_FORMATS_INCLUDE_SYSTEMFORMATS
+#include <tools/debug.hxx>
+#include <tools/solar.h>
+
+#include <sot/exchange.hxx>
+#include <sot/formats.hxx>
+#include "filelist.hxx"
+#include "clsids.hxx"
+
+#include <tools/globname.hxx>
+#include <com/sun/star/datatransfer/DataFlavor.hpp>
+#include <com/sun/star/datatransfer/XTransferable.hpp>
+
+using namespace::com::sun::star::uno;
+using namespace::com::sun::star::datatransfer;
+
+struct SotAction_Impl
+{
+ ULONG nFormatId; // Clipboard Id
+ USHORT nAction; // Action Id
+ BYTE nContextCheckId; // additional check of content in clipboard
+};
+
+
+// define a context check Id for every formatid
+#define FILEGRPDSC_ONLY_URL 1
+
+/*
+ Fuer jedes Ziel existiert in der Tabelle genau ein SotDestinationEntry_Impl.
+ Dieser Eintrag enthaelt u.a. fuer jedes vom Ziel auswertbare Format eine
+ Default-Action. Die Default-Aktionen verweisen fuer jedes Format auf
+ die auszuwertende Tabelle, d.h. sie enthalten nur EXCHG_IN_ACTION_MOVE,
+ EXCHG_IN_ACTION_COPY oder EXCHG_IN_ACTION_LINK. Entsprechend dieser Aktion
+ ist dann aMoveActions, aCopyActions oder aLinkActions auszuwerten.
+ Die Aktionen sind nach Prioritaet sortiert, d.h. je "wichtiger" das
+ Format ist, desto eher erscheint es in der Liste.
+*/
+
+struct SotDestinationEntry_Impl
+{
+ USHORT nDestination;
+ const SotAction_Impl* aDefaultActions;
+ const SotAction_Impl* aMoveActions;
+ const SotAction_Impl* aCopyActions;
+ const SotAction_Impl* aLinkActions;
+};
+
+
+/*
+ Ueber diese Tabelle erfolgt die Zuordnung von Destination, vorhandenen
+ Datenformaten sowie gewuenschter Aktion zu einer Aktion und dem in
+ ihr zu benutzenden Datenformat. Die Tabelle ist nach den Exchange-Zielen
+ (EXCHG_DEST_*) sortiert. Innerhalb des Zieleintrages befinden sich genau
+ vier Tabellen fuer Default-, Move-, Copy- und Linkaktionen. Ueber
+ die Default-Tabelle erfolgt das Mapping zwischen Default-Aktion
+ (DropEvent::IsDefaultAction()) und daraus resultierender wirklicher
+ Aktion. Diese Tabelle enthaelt deshalb nur die Aktionen
+ EXCHG_IN_ACTION_COPY, EXCHG_IN_ACTION_MOVE und EXCHG_IN_ACTION_LINK,
+ die auf die spezielle Tabelle verweisen. Die uebrigen Tabellen
+ koennen beliebige Aktionen enthalten. Jede Tabelle ist nach der
+ Format-Prioritaet sortiert. Eintrag Null hat die hoechste Prioritaet.
+*/
+
+#define EXCHG_EMPYT_ARRAY \
+static SotAction_Impl __READONLY_DATA aEmptyArr[] = \
+ { \
+ { 0xffff, 0, 0 } \
+ };
+
+/* */
+#define EXCHG_DEST_DOC_OLEOBJ_ARRAY \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_OLEOBJ_Def[] = \
+ { \
+ { SOT_FORMATSTR_ID_INET_IMAGE, EXCHG_IN_ACTION_LINK, 0 }, \
+ { SOT_FORMATSTR_ID_NETSCAPE_IMAGE, EXCHG_IN_ACTION_LINK, 0 }, \
+ { SOT_FORMAT_FILE_LIST, EXCHG_IN_ACTION_LINK, 0 }, \
+ { SOT_FORMAT_FILE, EXCHG_IN_ACTION_LINK, 0 }, \
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_IN_ACTION_LINK, 0 }, \
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_IN_ACTION_LINK, FILEGRPDSC_ONLY_URL }, \
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_IN_ACTION_LINK, 0 }, \
+ { 0xffff, 0, 0 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_OLEOBJ_Move[] = \
+ { \
+ { SOT_FORMATSTR_ID_SVIM, EXCHG_OUT_ACTION_INSERT_IMAGEMAP, 0 }, \
+ { 0xffff, 0, 0 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_OLEOBJ_Link[] = \
+ { \
+ { SOT_FORMATSTR_ID_INET_IMAGE, EXCHG_OUT_ACTION_INSERT_INTERACTIVE, 0 }, \
+ { SOT_FORMATSTR_ID_NETSCAPE_IMAGE, EXCHG_OUT_ACTION_INSERT_INTERACTIVE, 0 }, \
+ { SOT_FORMAT_FILE_LIST, EXCHG_OUT_ACTION_INSERT_INTERACTIVE, 0 }, \
+ { SOT_FORMAT_FILE, EXCHG_OUT_ACTION_INSERT_INTERACTIVE, 0 }, \
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_OUT_ACTION_INSERT_INTERACTIVE, 0 },\
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_OUT_ACTION_INSERT_INTERACTIVE, FILEGRPDSC_ONLY_URL },\
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_OUT_ACTION_INSERT_INTERACTIVE, 0 },\
+ { SOT_FORMATSTR_ID_SVIM, EXCHG_OUT_ACTION_INSERT_IMAGEMAP, 0 }, \
+ { 0xffff, 0, 0 } \
+ };
+
+/* */
+#define EXCHG_DEST_CHARTDOC_OLEOBJ_ARRAY \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_CHARTDOC_OLEOBJ_Def[] = \
+ { \
+ { SOT_FORMAT_FILE_LIST, EXCHG_IN_ACTION_LINK, 0 }, \
+ { SOT_FORMAT_FILE, EXCHG_IN_ACTION_LINK, 0 }, \
+ { SOT_FORMATSTR_ID_INET_IMAGE, EXCHG_IN_ACTION_LINK, 0 }, \
+ { SOT_FORMATSTR_ID_NETSCAPE_IMAGE, EXCHG_IN_ACTION_LINK, 0 }, \
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_IN_ACTION_LINK, 0 }, \
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_IN_ACTION_LINK, FILEGRPDSC_ONLY_URL }, \
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_IN_ACTION_LINK, 0 }, \
+ { 0xffff, 0, 0 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_CHARTDOC_OLEOBJ_Move[] = \
+ { \
+ { SOT_FORMATSTR_ID_SVIM, EXCHG_OUT_ACTION_INSERT_IMAGEMAP, 0 }, \
+ { 0xffff, 0, 0 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_CHARTDOC_OLEOBJ_Link[] = \
+ { \
+ { SOT_FORMAT_FILE_LIST, EXCHG_OUT_ACTION_INSERT_INTERACTIVE, 0 }, \
+ { SOT_FORMAT_FILE, EXCHG_OUT_ACTION_INSERT_INTERACTIVE, 0 }, \
+ { SOT_FORMATSTR_ID_INET_IMAGE, EXCHG_OUT_ACTION_INSERT_INTERACTIVE, 0 }, \
+ { SOT_FORMATSTR_ID_NETSCAPE_IMAGE, EXCHG_OUT_ACTION_INSERT_INTERACTIVE, 0 }, \
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_OUT_ACTION_INSERT_INTERACTIVE, 0 },\
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_OUT_ACTION_INSERT_INTERACTIVE, FILEGRPDSC_ONLY_URL },\
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_OUT_ACTION_INSERT_INTERACTIVE, 0 },\
+ { SOT_FORMATSTR_ID_SVIM, EXCHG_OUT_ACTION_INSERT_IMAGEMAP, 0 }, \
+ { 0xffff, 0, 0 } \
+ };
+
+/* */
+#define EXCHG_DEST_DOC_TEXTFRAME_ARRAY \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_TEXTFRAME_Def[] = \
+ { \
+ { SOT_FORMAT_GDIMETAFILE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_DRAWING, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_BITMAP, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_SVXB, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_HTML, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_HTML_NO_COMMENT, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_HTML_SIMPLE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_STRING, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_SONLK, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_INET_IMAGE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_NETSCAPE_IMAGE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_FILE_LIST, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_FILE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_SOLK, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_IN_ACTION_COPY, FILEGRPDSC_ONLY_URL }, \
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_SD_OLE, EXCHG_IN_ACTION_MOVE, 0 }, \
+ { SOT_FORMATSTR_ID_EMBED_SOURCE, EXCHG_IN_ACTION_MOVE, 0 }, \
+ { SOT_FORMATSTR_ID_EMBEDDED_OBJ, EXCHG_IN_ACTION_MOVE, 0 }, \
+ { SOT_FORMATSTR_ID_EMBED_SOURCE_OLE, EXCHG_IN_ACTION_MOVE, 0 }, \
+ { SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE, EXCHG_IN_ACTION_MOVE, 0 }, \
+ { SOT_FORMATSTR_ID_LINK, EXCHG_IN_ACTION_MOVE, 0 }, \
+ { 0xffff, 0, 0 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_TEXTFRAME_Move[] = \
+ { \
+ { SOT_FORMATSTR_ID_SONLK, EXCHG_IN_ACTION_MOVE, 0 }, \
+ { SOT_FORMAT_FILE_LIST, EXCHG_IN_ACTION_MOVE, 0 },\
+ { SOT_FORMAT_FILE, EXCHG_OUT_ACTION_INSERT_FILE | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_DRAWING, EXCHG_OUT_ACTION_INSERT_DRAWOBJ| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SVXB, EXCHG_OUT_ACTION_INSERT_SVXB| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SD_OLE, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_EMBED_SOURCE, EXCHG_OUT_ACTION_INSERT_OLE, 0 }, \
+ { SOT_FORMATSTR_ID_EMBEDDED_OBJ, EXCHG_OUT_ACTION_INSERT_OLE, 0 }, \
+ { SOT_FORMATSTR_ID_HTML, EXCHG_OUT_ACTION_INSERT_HTML| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_HTML_NO_COMMENT, EXCHG_OUT_ACTION_INSERT_HTML| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_HTML_SIMPLE, EXCHG_OUT_ACTION_INSERT_HTML| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_RTF, EXCHG_IN_ACTION_COPY| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_NETSCAPE_IMAGE, EXCHG_IN_ACTION_COPY | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMAT_STRING, EXCHG_OUT_ACTION_INSERT_STRING| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_GDIMETAFILE, EXCHG_OUT_ACTION_INSERT_GDIMETAFILE| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_BITMAP, EXCHG_OUT_ACTION_INSERT_BITMAP| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_EMBED_SOURCE_OLE, EXCHG_OUT_ACTION_INSERT_OLE, 0 }, \
+ { SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE, EXCHG_OUT_ACTION_INSERT_OLE, 0 }, \
+ { SOT_FORMATSTR_ID_LINK, EXCHG_OUT_ACTION_INSERT_DDE, 0 }, \
+ { SOT_FORMATSTR_ID_SVIM, EXCHG_OUT_ACTION_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { 0xffff, 0, 0 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_TEXTFRAME_Copy[] = \
+ { \
+ { SOT_FORMATSTR_ID_SBA_DATAEXCHANGE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_SBA_CTRLDATAEXCHANGE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_XFORMS, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_SONLK, EXCHG_IN_ACTION_COPY | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_SOLK, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_FILE_LIST, EXCHG_IN_ACTION_COPY, 0 },\
+ { SOT_FORMAT_FILE, EXCHG_OUT_ACTION_INSERT_FILE | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_DRAWING, EXCHG_OUT_ACTION_INSERT_DRAWOBJ| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SVXB, EXCHG_OUT_ACTION_INSERT_SVXB| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SD_OLE, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_EMBED_SOURCE, EXCHG_OUT_ACTION_INSERT_OLE, 0 }, \
+ { SOT_FORMATSTR_ID_EMBEDDED_OBJ, EXCHG_OUT_ACTION_INSERT_OLE, 0 }, \
+ { SOT_FORMATSTR_ID_HTML, EXCHG_OUT_ACTION_INSERT_HTML| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_HTML_NO_COMMENT, EXCHG_OUT_ACTION_INSERT_HTML| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_HTML_SIMPLE, EXCHG_OUT_ACTION_INSERT_HTML| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_RTF, EXCHG_IN_ACTION_COPY| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_NETSCAPE_IMAGE, EXCHG_IN_ACTION_COPY | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMAT_STRING, EXCHG_OUT_ACTION_INSERT_STRING| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, FILEGRPDSC_ONLY_URL },\
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_GDIMETAFILE, EXCHG_OUT_ACTION_INSERT_GDIMETAFILE| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_EMBED_SOURCE_OLE, EXCHG_OUT_ACTION_INSERT_OLE, 0 }, \
+ { SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE, EXCHG_OUT_ACTION_INSERT_OLE, 0 }, \
+ { SOT_FORMATSTR_ID_LINK, EXCHG_OUT_ACTION_INSERT_DDE, 0 }, \
+ { SOT_FORMATSTR_ID_SVIM, EXCHG_OUT_ACTION_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { 0xffff, 0, 0 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_TEXTFRAME_Link[] = \
+ { \
+ { SOT_FORMATSTR_ID_SONLK, EXCHG_IN_ACTION_LINK, 0 }, \
+ { SOT_FORMATSTR_ID_SBA_DATAEXCHANGE, EXCHG_IN_ACTION_LINK, 0 }, \
+ { SOT_FORMATSTR_ID_SBA_CTRLDATAEXCHANGE, EXCHG_IN_ACTION_LINK, 0 }, \
+ { SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE, EXCHG_IN_ACTION_LINK, 0 }, \
+ { SOT_FORMATSTR_ID_SOLK, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, FILEGRPDSC_ONLY_URL },\
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_FILE_LIST, EXCHG_IN_ACTION_LINK | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_FILE, EXCHG_IN_ACTION_LINK | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_LINK, EXCHG_OUT_ACTION_INSERT_DDE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_EMBED_SOURCE, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_EMBEDDED_OBJ, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_EMBED_SOURCE_OLE, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { 0xffff, 0, 0 } \
+ };
+
+#define EXCHG_DEST_DOC_TEXTFRAME_WEB_ARRAY \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_TEXTFRAME_WEB_Def[] = \
+ { \
+ { SOT_FORMAT_GDIMETAFILE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_BITMAP, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_SVXB, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_HTML, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_HTML_NO_COMMENT, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_HTML_SIMPLE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_STRING, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_SONLK, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_INET_IMAGE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_NETSCAPE_IMAGE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_FILE_LIST, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_FILE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_SOLK, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_IN_ACTION_COPY, FILEGRPDSC_ONLY_URL }, \
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_LINK, EXCHG_IN_ACTION_MOVE, 0 }, \
+ { 0xffff, 0, 0 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_TEXTFRAME_WEB_Move[] = \
+ { \
+ { SOT_FORMATSTR_ID_SONLK, EXCHG_IN_ACTION_MOVE, 0 }, \
+ { SOT_FORMAT_FILE_LIST, EXCHG_IN_ACTION_MOVE, 0 },\
+ { SOT_FORMAT_FILE, EXCHG_OUT_ACTION_INSERT_FILE | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SVXB, EXCHG_OUT_ACTION_INSERT_SVXB| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_HTML, EXCHG_OUT_ACTION_INSERT_HTML| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_HTML_NO_COMMENT, EXCHG_OUT_ACTION_INSERT_HTML| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_HTML_SIMPLE, EXCHG_OUT_ACTION_INSERT_HTML| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_RTF, EXCHG_IN_ACTION_COPY| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_NETSCAPE_IMAGE, EXCHG_IN_ACTION_COPY | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMAT_STRING, EXCHG_OUT_ACTION_INSERT_STRING| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_GDIMETAFILE, EXCHG_OUT_ACTION_INSERT_GDIMETAFILE| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_BITMAP, EXCHG_OUT_ACTION_INSERT_BITMAP| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_LINK, EXCHG_OUT_ACTION_INSERT_DDE, 0 }, \
+ { SOT_FORMATSTR_ID_SVIM, EXCHG_OUT_ACTION_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { 0xffff, 0, 0 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_TEXTFRAME_WEB_Copy[] = \
+ { \
+ { SOT_FORMATSTR_ID_SBA_DATAEXCHANGE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_SBA_CTRLDATAEXCHANGE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_XFORMS, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_SONLK, EXCHG_IN_ACTION_COPY | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_SOLK, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_FILE_LIST, EXCHG_IN_ACTION_COPY, 0 },\
+ { SOT_FORMAT_FILE, EXCHG_OUT_ACTION_INSERT_FILE | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SVXB, EXCHG_OUT_ACTION_INSERT_SVXB| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_HTML, EXCHG_OUT_ACTION_INSERT_HTML| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_HTML_NO_COMMENT, EXCHG_OUT_ACTION_INSERT_HTML| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_HTML_SIMPLE, EXCHG_OUT_ACTION_INSERT_HTML| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_RTF, EXCHG_IN_ACTION_COPY| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_NETSCAPE_IMAGE, EXCHG_IN_ACTION_COPY | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMAT_STRING, EXCHG_OUT_ACTION_INSERT_STRING| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, FILEGRPDSC_ONLY_URL },\
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_GDIMETAFILE, EXCHG_OUT_ACTION_INSERT_GDIMETAFILE| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_LINK, EXCHG_OUT_ACTION_INSERT_DDE, 0 }, \
+ { SOT_FORMATSTR_ID_SVIM, EXCHG_OUT_ACTION_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { 0xffff, 0, 0 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_TEXTFRAME_WEB_Link[] = \
+ { \
+ { SOT_FORMATSTR_ID_SONLK, EXCHG_IN_ACTION_LINK, 0 }, \
+ { SOT_FORMATSTR_ID_SOLK, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, FILEGRPDSC_ONLY_URL },\
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_FILE_LIST, EXCHG_IN_ACTION_LINK | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_FILE, EXCHG_IN_ACTION_LINK | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_LINK, EXCHG_OUT_ACTION_INSERT_DDE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { 0xffff, 0, 0 } \
+ };
+
+/* */
+#define EXCHG_DEST_DOC_GRAPHOBJ_ARRAY \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_GRAPHOBJ_Def[] = \
+ { \
+ { SOT_FORMAT_GDIMETAFILE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_DRAWING, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_BITMAP, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_SVXB, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_HTML, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_HTML_NO_COMMENT, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_HTML_SIMPLE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_STRING, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_FILE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_SOLK, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_IN_ACTION_COPY, FILEGRPDSC_ONLY_URL }, \
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_IN_ACTION_COPY, 0 }, \
+ { 0xffff, 0, 0 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_GRAPHOBJ_Move[] = \
+ { \
+ { SOT_FORMATSTR_ID_DRAWING, EXCHG_OUT_ACTION_REPLACE_DRAWOBJ | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SVXB, EXCHG_OUT_ACTION_REPLACE_SVXB| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_GDIMETAFILE, EXCHG_OUT_ACTION_REPLACE_GDIMETAFILE| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_BITMAP, EXCHG_OUT_ACTION_REPLACE_BITMAP| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SOLK, EXCHG_OUT_ACTION_REPLACE_GRAPH | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_OUT_ACTION_REPLACE_GRAPH | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_OUT_ACTION_REPLACE_GRAPH | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, FILEGRPDSC_ONLY_URL },\
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_OUT_ACTION_REPLACE_GRAPH | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_FILE, EXCHG_OUT_ACTION_REPLACE_GRAPH | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { 0xffff, 0, 0 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_GRAPHOBJ_Copy[] = \
+ { \
+ { SOT_FORMATSTR_ID_DRAWING, EXCHG_OUT_ACTION_INSERT_DRAWOBJ | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SVXB, EXCHG_OUT_ACTION_INSERT_SVXB| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_GDIMETAFILE, EXCHG_OUT_ACTION_INSERT_GDIMETAFILE| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_BITMAP, EXCHG_OUT_ACTION_INSERT_BITMAP| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SOLK, EXCHG_OUT_ACTION_INSERT_GRAPH | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_OUT_ACTION_INSERT_GRAPH | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_OUT_ACTION_INSERT_GRAPH | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, FILEGRPDSC_ONLY_URL },\
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_OUT_ACTION_INSERT_GRAPH | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_FILE, EXCHG_OUT_ACTION_INSERT_FILE | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { 0xffff, 0, 0 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_GRAPHOBJ_Link[] = \
+ { \
+ { SOT_FORMATSTR_ID_DRAWING, EXCHG_OUT_ACTION_GET_ATTRIBUTES | EXCHG_OUT_ACTION_FLAG_FILL | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SVXB, EXCHG_OUT_ACTION_GET_ATTRIBUTES| EXCHG_OUT_ACTION_FLAG_FILL | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_GDIMETAFILE, EXCHG_OUT_ACTION_GET_ATTRIBUTES| EXCHG_OUT_ACTION_FLAG_FILL | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_BITMAP, EXCHG_OUT_ACTION_GET_ATTRIBUTES | EXCHG_OUT_ACTION_FLAG_FILL | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SOLK, EXCHG_OUT_ACTION_GET_ATTRIBUTES | EXCHG_OUT_ACTION_FLAG_FILL | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_OUT_ACTION_GET_ATTRIBUTES | EXCHG_OUT_ACTION_FLAG_FILL | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_OUT_ACTION_GET_ATTRIBUTES | EXCHG_OUT_ACTION_FLAG_FILL | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, FILEGRPDSC_ONLY_URL },\
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_OUT_ACTION_GET_ATTRIBUTES | EXCHG_OUT_ACTION_FLAG_FILL | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_FILE, EXCHG_OUT_ACTION_GET_ATTRIBUTES | EXCHG_OUT_ACTION_FLAG_FILL | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { 0xffff, 0, 0 } \
+ };
+
+/* */
+#define EXCHG_DEST_DOC_LNKD_GRAPHOBJ_ARRAY \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_LNKD_GRAPHOBJ_Def[] = \
+ { \
+ { SOT_FORMAT_GDIMETAFILE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_DRAWING, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_BITMAP, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_SVXB, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_HTML, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_HTML_NO_COMMENT, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_HTML_SIMPLE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_STRING, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_SOLK, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_IN_ACTION_COPY, FILEGRPDSC_ONLY_URL }, \
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_FILE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { 0xffff, 0, 0 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_LNKD_GRAPHOBJ_Move[] =\
+ { \
+ { SOT_FORMATSTR_ID_DRAWING, EXCHG_OUT_ACTION_REPLACE_DRAWOBJ | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SVXB, EXCHG_OUT_ACTION_REPLACE_SVXB| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_GDIMETAFILE, EXCHG_OUT_ACTION_REPLACE_GDIMETAFILE| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_BITMAP, EXCHG_OUT_ACTION_REPLACE_BITMAP| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SOLK, EXCHG_OUT_ACTION_REPLACE_GRAPH | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_OUT_ACTION_REPLACE_GRAPH | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_OUT_ACTION_REPLACE_GRAPH | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, FILEGRPDSC_ONLY_URL },\
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_OUT_ACTION_REPLACE_GRAPH | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_FILE, EXCHG_OUT_ACTION_REPLACE_GRAPH | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { 0xffff, 0, 0 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_LNKD_GRAPHOBJ_Copy[] =\
+ { \
+ { SOT_FORMATSTR_ID_DRAWING, EXCHG_OUT_ACTION_INSERT_DRAWOBJ | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SVXB, EXCHG_OUT_ACTION_INSERT_SVXB| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_GDIMETAFILE, EXCHG_OUT_ACTION_INSERT_GDIMETAFILE| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_BITMAP, EXCHG_OUT_ACTION_INSERT_BITMAP| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SOLK, EXCHG_OUT_ACTION_INSERT_GRAPH | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_OUT_ACTION_INSERT_GRAPH | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_OUT_ACTION_INSERT_GRAPH | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, FILEGRPDSC_ONLY_URL },\
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_OUT_ACTION_INSERT_GRAPH | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_FILE, EXCHG_OUT_ACTION_INSERT_FILE | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { 0xffff, 0, 0 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_LNKD_GRAPHOBJ_Link[] =\
+ { \
+ { SOT_FORMATSTR_ID_DRAWING, EXCHG_OUT_ACTION_GET_ATTRIBUTES | EXCHG_OUT_ACTION_FLAG_FILL | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SVXB, EXCHG_OUT_ACTION_GET_ATTRIBUTES| EXCHG_OUT_ACTION_FLAG_FILL | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_GDIMETAFILE, EXCHG_OUT_ACTION_GET_ATTRIBUTES| EXCHG_OUT_ACTION_FLAG_FILL | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_BITMAP, EXCHG_OUT_ACTION_GET_ATTRIBUTES | EXCHG_OUT_ACTION_FLAG_FILL | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SOLK, EXCHG_OUT_ACTION_GET_ATTRIBUTES | EXCHG_OUT_ACTION_FLAG_FILL | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_OUT_ACTION_GET_ATTRIBUTES | EXCHG_OUT_ACTION_FLAG_FILL | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_OUT_ACTION_GET_ATTRIBUTES | EXCHG_OUT_ACTION_FLAG_FILL | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, FILEGRPDSC_ONLY_URL },\
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_OUT_ACTION_GET_ATTRIBUTES | EXCHG_OUT_ACTION_FLAG_FILL | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_FILE, EXCHG_OUT_ACTION_GET_ATTRIBUTES | EXCHG_OUT_ACTION_FLAG_FILL | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { 0xffff, 0, 0 } \
+ };
+
+/* */
+#define EXCHG_DEST_DOC_GRAPH_W_IMAP_ARRAY \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_GRAPH_W_IMAP_Def[] = \
+ { \
+ { SOT_FORMAT_GDIMETAFILE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_DRAWING, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_BITMAP, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_SVXB, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_HTML, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_HTML_NO_COMMENT, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_HTML_SIMPLE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_STRING, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_FILE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_SOLK, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_IN_ACTION_COPY, FILEGRPDSC_ONLY_URL }, \
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_FILE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { 0xffff, 0, 0 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_GRAPH_W_IMAP_Move[] = \
+ { \
+ { SOT_FORMATSTR_ID_DRAWING, EXCHG_OUT_ACTION_REPLACE_DRAWOBJ | EXCHG_OUT_ACTION_FLAG_REPLACE_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SVXB, EXCHG_OUT_ACTION_REPLACE_SVXB| EXCHG_OUT_ACTION_FLAG_REPLACE_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_GDIMETAFILE, EXCHG_OUT_ACTION_REPLACE_GDIMETAFILE| EXCHG_OUT_ACTION_FLAG_REPLACE_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_BITMAP, EXCHG_OUT_ACTION_REPLACE_BITMAP| EXCHG_OUT_ACTION_FLAG_REPLACE_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SOLK, EXCHG_OUT_ACTION_REPLACE_GRAPH | EXCHG_OUT_ACTION_FLAG_REPLACE_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_OUT_ACTION_REPLACE_GRAPH | EXCHG_OUT_ACTION_FLAG_REPLACE_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_OUT_ACTION_REPLACE_GRAPH | EXCHG_OUT_ACTION_FLAG_REPLACE_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, FILEGRPDSC_ONLY_URL },\
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_OUT_ACTION_REPLACE_GRAPH | EXCHG_OUT_ACTION_FLAG_REPLACE_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_FILE, EXCHG_OUT_ACTION_REPLACE_GRAPH | EXCHG_OUT_ACTION_FLAG_REPLACE_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { 0xffff, 0, 0 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_GRAPH_W_IMAP_Copy[] = \
+ { \
+ { SOT_FORMATSTR_ID_DRAWING, EXCHG_OUT_ACTION_INSERT_DRAWOBJ | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SVXB, EXCHG_OUT_ACTION_INSERT_SVXB| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_GDIMETAFILE, EXCHG_OUT_ACTION_INSERT_GDIMETAFILE| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_BITMAP, EXCHG_OUT_ACTION_INSERT_BITMAP| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SOLK, EXCHG_OUT_ACTION_INSERT_GRAPH | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_OUT_ACTION_INSERT_GRAPH | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_OUT_ACTION_INSERT_GRAPH | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, FILEGRPDSC_ONLY_URL },\
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_OUT_ACTION_INSERT_GRAPH | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_FILE, EXCHG_OUT_ACTION_INSERT_FILE | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { 0xffff, 0, 0 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_GRAPH_W_IMAP_Link[] = \
+ { \
+ { SOT_FORMATSTR_ID_DRAWING, EXCHG_OUT_ACTION_GET_ATTRIBUTES | EXCHG_OUT_ACTION_FLAG_FILL | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SVXB, EXCHG_OUT_ACTION_GET_ATTRIBUTES| EXCHG_OUT_ACTION_FLAG_FILL | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_GDIMETAFILE, EXCHG_OUT_ACTION_GET_ATTRIBUTES| EXCHG_OUT_ACTION_FLAG_FILL | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_BITMAP, EXCHG_OUT_ACTION_GET_ATTRIBUTES | EXCHG_OUT_ACTION_FLAG_FILL | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SOLK, EXCHG_OUT_ACTION_GET_ATTRIBUTES | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_OUT_ACTION_GET_ATTRIBUTES | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_OUT_ACTION_GET_ATTRIBUTES | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, FILEGRPDSC_ONLY_URL },\
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_OUT_ACTION_GET_ATTRIBUTES | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_FILE, EXCHG_OUT_ACTION_GET_ATTRIBUTES | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { 0xffff, 0, 0 } \
+ };
+
+/* */
+#define EXCHG_DEST_DOC_LNKD_GRAPH_W_IMAP_ARRAY \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_LNKD_GRAPH_W_IMAP_Def[] =\
+ { \
+ { SOT_FORMAT_GDIMETAFILE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_DRAWING, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_BITMAP, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_SVXB, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_HTML, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_HTML_NO_COMMENT, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_HTML_SIMPLE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_STRING, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_FILE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_SOLK, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_IN_ACTION_COPY, FILEGRPDSC_ONLY_URL }, \
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_FILE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { 0xffff, 0, 0 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_LNKD_GRAPH_W_IMAP_Move[] =\
+ { \
+ { SOT_FORMATSTR_ID_DRAWING, EXCHG_OUT_ACTION_REPLACE_DRAWOBJ | EXCHG_OUT_ACTION_FLAG_REPLACE_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SVXB, EXCHG_OUT_ACTION_REPLACE_SVXB| EXCHG_OUT_ACTION_FLAG_REPLACE_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_GDIMETAFILE, EXCHG_OUT_ACTION_REPLACE_GDIMETAFILE| EXCHG_OUT_ACTION_FLAG_REPLACE_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_BITMAP, EXCHG_OUT_ACTION_REPLACE_BITMAP| EXCHG_OUT_ACTION_FLAG_REPLACE_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SOLK, EXCHG_OUT_ACTION_REPLACE_GRAPH | EXCHG_OUT_ACTION_FLAG_REPLACE_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_OUT_ACTION_REPLACE_GRAPH | EXCHG_OUT_ACTION_FLAG_REPLACE_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_OUT_ACTION_REPLACE_GRAPH | EXCHG_OUT_ACTION_FLAG_REPLACE_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, FILEGRPDSC_ONLY_URL },\
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_OUT_ACTION_REPLACE_GRAPH | EXCHG_OUT_ACTION_FLAG_REPLACE_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_FILE, EXCHG_OUT_ACTION_REPLACE_GRAPH | EXCHG_OUT_ACTION_FLAG_REPLACE_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { 0xffff, 0, 0 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_LNKD_GRAPH_W_IMAP_Copy[] =\
+ { \
+ { SOT_FORMATSTR_ID_DRAWING, EXCHG_OUT_ACTION_INSERT_DRAWOBJ | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SVXB, EXCHG_OUT_ACTION_INSERT_SVXB| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_GDIMETAFILE, EXCHG_OUT_ACTION_INSERT_GDIMETAFILE| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_BITMAP, EXCHG_OUT_ACTION_INSERT_BITMAP| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SOLK, EXCHG_OUT_ACTION_INSERT_GRAPH | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_OUT_ACTION_INSERT_GRAPH | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_OUT_ACTION_INSERT_GRAPH | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, FILEGRPDSC_ONLY_URL },\
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_OUT_ACTION_INSERT_GRAPH | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_FILE, EXCHG_OUT_ACTION_INSERT_FILE | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { 0xffff, 0, 0 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_LNKD_GRAPH_W_IMAP_Link[] =\
+ { \
+ { SOT_FORMATSTR_ID_DRAWING, EXCHG_OUT_ACTION_GET_ATTRIBUTES | EXCHG_OUT_ACTION_FLAG_FILL | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SVXB, EXCHG_OUT_ACTION_GET_ATTRIBUTES| EXCHG_OUT_ACTION_FLAG_FILL | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_GDIMETAFILE, EXCHG_OUT_ACTION_GET_ATTRIBUTES| EXCHG_OUT_ACTION_FLAG_FILL | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_BITMAP, EXCHG_OUT_ACTION_GET_ATTRIBUTES | EXCHG_OUT_ACTION_FLAG_FILL | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SOLK, EXCHG_OUT_ACTION_GET_ATTRIBUTES | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_OUT_ACTION_GET_ATTRIBUTES | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_OUT_ACTION_GET_ATTRIBUTES | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, FILEGRPDSC_ONLY_URL },\
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_OUT_ACTION_GET_ATTRIBUTES | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_FILE, EXCHG_OUT_ACTION_GET_ATTRIBUTES | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { 0xffff, 0, 0 } \
+ };
+
+
+/* */
+#define EXCHG_DEST_DOC_IMAPREGION_ARRAY \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_IMAPREGION_Def[] = \
+ { \
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_IN_ACTION_COPY, FILEGRPDSC_ONLY_URL }, \
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_FILE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { 0xffff, 0, 0 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_IMAPREGION_Copy[] = \
+ { \
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, FILEGRPDSC_ONLY_URL },\
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_FILE, EXCHG_OUT_ACTION_INSERT_FILE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { 0xffff, 0, 0 } \
+ };
+
+
+/* */
+#define EXCHG_DEST_DOC_DRAWOBJ_ARRAY \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_DRAWOBJ_Def[] = \
+ { \
+ { SOT_FORMAT_GDIMETAFILE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_DRAWING, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_BITMAP, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_SVXB, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_HTML, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_HTML_NO_COMMENT, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_HTML_SIMPLE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_STRING, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_FILE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_SOLK, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_IN_ACTION_COPY, FILEGRPDSC_ONLY_URL }, \
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_IN_ACTION_COPY, 0 }, \
+ { 0xffff, 0, 0 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_DRAWOBJ_Copy[] = \
+ { \
+ { SOT_FORMATSTR_ID_DRAWING, EXCHG_OUT_ACTION_REPLACE_DRAWOBJ | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SVXB, EXCHG_OUT_ACTION_REPLACE_SVXB| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_GDIMETAFILE, EXCHG_OUT_ACTION_REPLACE_GDIMETAFILE| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_BITMAP, EXCHG_OUT_ACTION_REPLACE_BITMAP| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SOLK, EXCHG_OUT_ACTION_REPLACE_GRAPH | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_OUT_ACTION_REPLACE_GRAPH | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_OUT_ACTION_REPLACE_GRAPH | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, FILEGRPDSC_ONLY_URL },\
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_OUT_ACTION_REPLACE_GRAPH | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_FILE, EXCHG_OUT_ACTION_REPLACE_GRAPH | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { 0xffff, 0, 0 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_DRAWOBJ_Move[] = \
+ { \
+ { SOT_FORMATSTR_ID_DRAWING, EXCHG_OUT_ACTION_INSERT_DRAWOBJ | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SVXB, EXCHG_OUT_ACTION_INSERT_SVXB| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_GDIMETAFILE, EXCHG_OUT_ACTION_INSERT_GDIMETAFILE| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_BITMAP, EXCHG_OUT_ACTION_INSERT_BITMAP| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SOLK, EXCHG_OUT_ACTION_INSERT_GRAPH | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_OUT_ACTION_INSERT_GRAPH | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_OUT_ACTION_INSERT_GRAPH | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, FILEGRPDSC_ONLY_URL },\
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_OUT_ACTION_INSERT_GRAPH | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_FILE, EXCHG_OUT_ACTION_INSERT_FILE | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { 0xffff, 0, 0 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_DRAWOBJ_Link[] = \
+ { \
+ { SOT_FORMATSTR_ID_DRAWING, EXCHG_OUT_ACTION_GET_ATTRIBUTES | EXCHG_OUT_ACTION_FLAG_FILL | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SVXB, EXCHG_OUT_ACTION_GET_ATTRIBUTES| EXCHG_OUT_ACTION_FLAG_FILL | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_GDIMETAFILE, EXCHG_OUT_ACTION_GET_ATTRIBUTES| EXCHG_OUT_ACTION_FLAG_FILL | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_BITMAP, EXCHG_OUT_ACTION_GET_ATTRIBUTES | EXCHG_OUT_ACTION_FLAG_FILL | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SOLK, EXCHG_OUT_ACTION_GET_ATTRIBUTES | EXCHG_OUT_ACTION_FLAG_FILL | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_OUT_ACTION_GET_ATTRIBUTES | EXCHG_OUT_ACTION_FLAG_FILL | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_OUT_ACTION_GET_ATTRIBUTES | EXCHG_OUT_ACTION_FLAG_FILL | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, FILEGRPDSC_ONLY_URL },\
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_OUT_ACTION_GET_ATTRIBUTES | EXCHG_OUT_ACTION_FLAG_FILL | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_FILE, EXCHG_OUT_ACTION_GET_ATTRIBUTES | EXCHG_OUT_ACTION_FLAG_FILL | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { 0xffff, 0, 0 } \
+ };
+
+
+/* */
+#define EXCHG_DEST_DOC_URLBUTTON_ARRAY \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_URLBUTTON_Def[] = \
+ { \
+ { SOT_FORMAT_GDIMETAFILE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_DRAWING, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_BITMAP, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_SVXB, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_FILE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_SOLK, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_IN_ACTION_COPY, FILEGRPDSC_ONLY_URL }, \
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_IN_ACTION_COPY, 0 }, \
+ { 0xffff, 0, 0 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_URLBUTTON_Move[] = \
+ { \
+ { SOT_FORMATSTR_ID_DRAWING, EXCHG_OUT_ACTION_REPLACE_DRAWOBJ | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SVXB, EXCHG_OUT_ACTION_REPLACE_SVXB | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_GDIMETAFILE, EXCHG_OUT_ACTION_REPLACE_GDIMETAFILE | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { 0xffff, 0, 0 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_URLBUTTON_Copy[] = \
+ { \
+ { SOT_FORMATSTR_ID_DRAWING, EXCHG_OUT_ACTION_INSERT_DRAWOBJ | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_SVXB, EXCHG_OUT_ACTION_INSERT_SVXB | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMAT_GDIMETAFILE, EXCHG_OUT_ACTION_INSERT_GDIMETAFILE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMAT_BITMAP, EXCHG_OUT_ACTION_INSERT_BITMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_SOLK, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, FILEGRPDSC_ONLY_URL },\
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_FILE, EXCHG_OUT_ACTION_INSERT_FILE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { 0xffff, 0, 0 } \
+ };
+
+
+/* */
+#define EXCHG_DEST_DOC_URLFIELD_ARRAY \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_URLFIELD_Def[] = \
+ { \
+ { SOT_FORMAT_FILE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_IN_ACTION_COPY, FILEGRPDSC_ONLY_URL }, \
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_IN_ACTION_COPY, 0 }, \
+ { 0xffff, 0, 0 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_URLFIELD_Copy[] = \
+ { \
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, FILEGRPDSC_ONLY_URL },\
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_FILE, EXCHG_OUT_ACTION_INSERT_FILE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { 0xffff, 0, 0 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_URLFIELD_Link[] = \
+ { \
+ { SOT_FORMAT_FILE, EXCHG_OUT_ACTION_INSERT_HYPERLINK, 0 }, \
+ { 0xffff, 0, 0 } \
+ };
+
+/* */
+#define EXCHG_DEST_DOC_GROUPOBJ_ARRAY \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_GROUPOBJ_Def[] = \
+ { \
+ { SOT_FORMAT_GDIMETAFILE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_DRAWING, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_BITMAP, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_SVXB, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_HTML, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_HTML_NO_COMMENT, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_HTML_SIMPLE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_STRING, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_FILE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_SOLK, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_IN_ACTION_COPY, FILEGRPDSC_ONLY_URL }, \
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_IN_ACTION_COPY, 0 }, \
+ { 0xffff, 0, 0 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_GROUPOBJ_Move[] = \
+ { \
+ { SOT_FORMATSTR_ID_DRAWING, EXCHG_OUT_ACTION_REPLACE_DRAWOBJ | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SVXB, EXCHG_OUT_ACTION_REPLACE_SVXB| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_GDIMETAFILE, EXCHG_OUT_ACTION_REPLACE_GDIMETAFILE| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_BITMAP, EXCHG_OUT_ACTION_REPLACE_BITMAP| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SOLK, EXCHG_OUT_ACTION_REPLACE_GRAPH | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_OUT_ACTION_REPLACE_GRAPH | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_OUT_ACTION_REPLACE_GRAPH | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, FILEGRPDSC_ONLY_URL },\
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_OUT_ACTION_REPLACE_GRAPH | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_FILE, EXCHG_OUT_ACTION_REPLACE_GRAPH | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_KEEP_POSSIZE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { 0xffff, 0, 0 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_GROUPOBJ_Copy[] = \
+ { \
+ { SOT_FORMATSTR_ID_DRAWING, EXCHG_OUT_ACTION_INSERT_DRAWOBJ | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SVXB, EXCHG_OUT_ACTION_INSERT_SVXB| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_GDIMETAFILE, EXCHG_OUT_ACTION_INSERT_GDIMETAFILE| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_BITMAP, EXCHG_OUT_ACTION_INSERT_BITMAP| EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SOLK, EXCHG_OUT_ACTION_INSERT_GRAPH | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_OUT_ACTION_INSERT_GRAPH | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_OUT_ACTION_INSERT_GRAPH | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, FILEGRPDSC_ONLY_URL },\
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_OUT_ACTION_INSERT_GRAPH | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_FILE, EXCHG_OUT_ACTION_INSERT_FILE | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { 0xffff, 0, 0 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_GROUPOBJ_Link[] = \
+ { \
+ { SOT_FORMATSTR_ID_DRAWING, EXCHG_OUT_ACTION_GET_ATTRIBUTES | EXCHG_OUT_ACTION_FLAG_FILL | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SVXB, EXCHG_OUT_ACTION_GET_ATTRIBUTES| EXCHG_OUT_ACTION_FLAG_FILL | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_GDIMETAFILE, EXCHG_OUT_ACTION_GET_ATTRIBUTES| EXCHG_OUT_ACTION_FLAG_FILL | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_BITMAP, EXCHG_OUT_ACTION_GET_ATTRIBUTES | EXCHG_OUT_ACTION_FLAG_FILL | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SOLK, EXCHG_OUT_ACTION_GET_ATTRIBUTES | EXCHG_OUT_ACTION_FLAG_FILL | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_OUT_ACTION_GET_ATTRIBUTES | EXCHG_OUT_ACTION_FLAG_FILL | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_OUT_ACTION_GET_ATTRIBUTES | EXCHG_OUT_ACTION_FLAG_FILL | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, FILEGRPDSC_ONLY_URL },\
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_OUT_ACTION_GET_ATTRIBUTES | EXCHG_OUT_ACTION_FLAG_FILL | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_FILE, EXCHG_OUT_ACTION_GET_ATTRIBUTES | EXCHG_OUT_ACTION_FLAG_FILL | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { 0xffff, 0, 0 } \
+ };
+
+
+/* */
+#define EXCHG_DEST_SWDOC_FREE_AREA_ARRAY \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_SWDOC_FREE_AREA_Def[] = \
+ { \
+ { SOT_FORMAT_FILE_LIST, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_FILE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_HTML, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_HTML_NO_COMMENT, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_HTML_SIMPLE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_RTF, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_SVIM, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_NETSCAPE_IMAGE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_STRING, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_IN_ACTION_COPY, FILEGRPDSC_ONLY_URL }, \
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_DRAWING, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_SVXB, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_GDIMETAFILE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_BITMAP, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_SONLK, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_SOLK, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_SD_OLE, EXCHG_IN_ACTION_MOVE, 0 }, \
+ { SOT_FORMATSTR_ID_EMBED_SOURCE, EXCHG_IN_ACTION_MOVE, 0 }, \
+ { SOT_FORMATSTR_ID_EMBEDDED_OBJ, EXCHG_IN_ACTION_MOVE, 0 }, \
+ { SOT_FORMATSTR_ID_EMBED_SOURCE_OLE, EXCHG_IN_ACTION_MOVE, 0 }, \
+ { SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE, EXCHG_IN_ACTION_MOVE, 0 }, \
+ { SOT_FORMATSTR_ID_LINK, EXCHG_IN_ACTION_MOVE, 0 }, \
+ { 0xffff, 0, 0 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_SWDOC_FREE_AREA_Move[] = \
+ { \
+ { SOT_FORMATSTR_ID_SONLK, EXCHG_IN_ACTION_MOVE, 0 }, \
+ { SOT_FORMAT_FILE_LIST, EXCHG_IN_ACTION_MOVE, 0 },\
+ { SOT_FORMAT_FILE, EXCHG_OUT_ACTION_INSERT_FILE | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_DRAWING, EXCHG_OUT_ACTION_INSERT_DRAWOBJ | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SVXB, EXCHG_OUT_ACTION_INSERT_SVXB | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SD_OLE, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_EMBED_SOURCE, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_EMBEDDED_OBJ, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_HTML, EXCHG_OUT_ACTION_INSERT_HTML | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_HTML_NO_COMMENT, EXCHG_OUT_ACTION_INSERT_HTML | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_HTML_SIMPLE, EXCHG_OUT_ACTION_INSERT_HTML | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_RTF, EXCHG_IN_ACTION_COPY | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMAT_STRING, EXCHG_OUT_ACTION_INSERT_STRING, 0 }, \
+ { SOT_FORMAT_GDIMETAFILE, EXCHG_OUT_ACTION_INSERT_GDIMETAFILE | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_BITMAP, EXCHG_OUT_ACTION_INSERT_BITMAP | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_EMBED_SOURCE_OLE, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_LINK, EXCHG_OUT_ACTION_INSERT_DDE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_SVIM, EXCHG_OUT_ACTION_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { 0xffff, 0, 0 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_SWDOC_FREE_AREA_Copy[] = \
+ { \
+ { SOT_FORMATSTR_ID_SBA_DATAEXCHANGE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_SBA_CTRLDATAEXCHANGE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_XFORMS, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_FILE_LIST, EXCHG_IN_ACTION_COPY, 0 },\
+ { SOT_FORMAT_FILE, EXCHG_OUT_ACTION_INSERT_FILE | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SONLK, EXCHG_IN_ACTION_COPY | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_SOLK, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_DRAWING, EXCHG_OUT_ACTION_INSERT_DRAWOBJ | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SVXB, EXCHG_OUT_ACTION_INSERT_SVXB | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SD_OLE, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_EMBED_SOURCE, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_EMBEDDED_OBJ, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_HTML, EXCHG_OUT_ACTION_INSERT_HTML | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_HTML_NO_COMMENT, EXCHG_OUT_ACTION_INSERT_HTML | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_HTML_SIMPLE, EXCHG_OUT_ACTION_INSERT_HTML | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_RTF, EXCHG_IN_ACTION_COPY | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_NETSCAPE_IMAGE, EXCHG_IN_ACTION_COPY | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMAT_STRING, EXCHG_OUT_ACTION_INSERT_STRING | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, FILEGRPDSC_ONLY_URL },\
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_GDIMETAFILE, EXCHG_OUT_ACTION_INSERT_GDIMETAFILE | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_BITMAP, EXCHG_OUT_ACTION_INSERT_BITMAP | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_EMBED_SOURCE_OLE, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_LINK, EXCHG_OUT_ACTION_INSERT_DDE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_SVIM, EXCHG_OUT_ACTION_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { 0xffff, 0, 0 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_SWDOC_FREE_AREA_Link[] = \
+ { \
+ { SOT_FORMATSTR_ID_SONLK, EXCHG_IN_ACTION_LINK, 0 }, \
+ { SOT_FORMATSTR_ID_SBA_DATAEXCHANGE, EXCHG_IN_ACTION_LINK, 0 }, \
+ { SOT_FORMATSTR_ID_SBA_CTRLDATAEXCHANGE, EXCHG_IN_ACTION_LINK, 0 }, \
+ { SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE, EXCHG_IN_ACTION_LINK, 0 }, \
+ { SOT_FORMAT_FILE_LIST, EXCHG_IN_ACTION_LINK, 0 }, \
+ { SOT_FORMAT_FILE, EXCHG_IN_ACTION_LINK | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_SOLK, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, FILEGRPDSC_ONLY_URL },\
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_LINK, EXCHG_OUT_ACTION_INSERT_DDE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_EMBED_SOURCE, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_EMBEDDED_OBJ, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_EMBED_SOURCE_OLE, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { 0xffff, 0, 0 } \
+ };
+
+#define EXCHG_DEST_SWDOC_FREE_AREA_WEB_ARRAY \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_SWDOC_FREE_AREA_WEB_Def[] = \
+ { \
+ { SOT_FORMAT_FILE_LIST, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_FILE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_SOLK, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_HTML, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_HTML_NO_COMMENT, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_HTML_SIMPLE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_RTF, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_SVIM, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_NETSCAPE_IMAGE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_STRING, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_IN_ACTION_COPY, FILEGRPDSC_ONLY_URL }, \
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_SVXB, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_GDIMETAFILE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_BITMAP, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_SONLK, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_LINK, EXCHG_IN_ACTION_MOVE, 0 }, \
+ { 0xffff, 0, 0 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_SWDOC_FREE_AREA_WEB_Move[] = \
+ { \
+ { SOT_FORMATSTR_ID_SONLK, EXCHG_IN_ACTION_MOVE, 0 }, \
+ { SOT_FORMAT_FILE_LIST, EXCHG_IN_ACTION_MOVE, 0 },\
+ { SOT_FORMAT_FILE, EXCHG_OUT_ACTION_INSERT_FILE | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SVXB, EXCHG_OUT_ACTION_INSERT_SVXB | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_HTML, EXCHG_OUT_ACTION_INSERT_HTML | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_HTML_NO_COMMENT, EXCHG_OUT_ACTION_INSERT_HTML | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_HTML_SIMPLE, EXCHG_OUT_ACTION_INSERT_HTML | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_RTF, EXCHG_IN_ACTION_COPY | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMAT_STRING, EXCHG_OUT_ACTION_INSERT_STRING, 0 }, \
+ { SOT_FORMAT_GDIMETAFILE, EXCHG_OUT_ACTION_INSERT_GDIMETAFILE | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_BITMAP, EXCHG_OUT_ACTION_INSERT_BITMAP | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_LINK, EXCHG_OUT_ACTION_INSERT_DDE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_SVIM, EXCHG_OUT_ACTION_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { 0xffff, 0, 0 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_SWDOC_FREE_AREA_WEB_Copy[] = \
+ { \
+ { SOT_FORMAT_FILE_LIST, EXCHG_IN_ACTION_COPY, 0 },\
+ { SOT_FORMAT_FILE, EXCHG_OUT_ACTION_INSERT_FILE | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SONLK, EXCHG_IN_ACTION_COPY | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_SOLK, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SVXB, EXCHG_OUT_ACTION_INSERT_SVXB | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_HTML, EXCHG_OUT_ACTION_INSERT_HTML | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_HTML_NO_COMMENT, EXCHG_OUT_ACTION_INSERT_HTML | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_HTML_SIMPLE, EXCHG_OUT_ACTION_INSERT_HTML | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_RTF, EXCHG_IN_ACTION_COPY | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_NETSCAPE_IMAGE, EXCHG_IN_ACTION_COPY | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMAT_STRING, EXCHG_OUT_ACTION_INSERT_STRING | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, FILEGRPDSC_ONLY_URL },\
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_GDIMETAFILE, EXCHG_OUT_ACTION_INSERT_GDIMETAFILE | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_BITMAP, EXCHG_OUT_ACTION_INSERT_BITMAP | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_LINK, EXCHG_OUT_ACTION_INSERT_DDE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_SVIM, EXCHG_OUT_ACTION_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { 0xffff, 0, 0 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_SWDOC_FREE_AREA_WEB_Link[] = \
+ { \
+ { SOT_FORMATSTR_ID_SONLK, EXCHG_IN_ACTION_LINK, 0 }, \
+ { SOT_FORMAT_FILE_LIST, EXCHG_IN_ACTION_LINK, 0 }, \
+ { SOT_FORMAT_FILE, EXCHG_IN_ACTION_LINK | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_SOLK, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, FILEGRPDSC_ONLY_URL },\
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_LINK, EXCHG_OUT_ACTION_INSERT_DDE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { 0xffff, 0, 0 } \
+ };
+
+
+/* */
+#define EXCHG_DEST_SCDOC_FREE_AREA_ARRAY \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_SCDOC_FREE_AREA_Def[] = \
+ { \
+ { SOT_FORMAT_FILE_LIST, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_FILE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_HTML, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_HTML_NO_COMMENT, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_HTML_SIMPLE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_SVIM, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_STRING, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_IN_ACTION_COPY, FILEGRPDSC_ONLY_URL }, \
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_DRAWING, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_SVXB, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_GDIMETAFILE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_BITMAP, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_SD_OLE, EXCHG_IN_ACTION_MOVE, 0 }, \
+ { SOT_FORMATSTR_ID_EMBED_SOURCE, EXCHG_IN_ACTION_MOVE, 0 }, \
+ { SOT_FORMATSTR_ID_EMBEDDED_OBJ, EXCHG_IN_ACTION_MOVE, 0 }, \
+ { SOT_FORMATSTR_ID_EMBED_SOURCE_OLE, EXCHG_IN_ACTION_MOVE, 0 }, \
+ { SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE, EXCHG_IN_ACTION_MOVE, 0 }, \
+ { SOT_FORMATSTR_ID_LINK, EXCHG_IN_ACTION_MOVE, 0 }, \
+ { 0xffff, 0, 0 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_SCDOC_FREE_AREA_Move[] = \
+ { \
+ { SOT_FORMAT_FILE_LIST, EXCHG_IN_ACTION_MOVE, 0 },\
+ { SOT_FORMAT_FILE, EXCHG_OUT_ACTION_INSERT_FILE | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_DRAWING, EXCHG_OUT_ACTION_INSERT_DRAWOBJ | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SVXB, EXCHG_OUT_ACTION_INSERT_SVXB | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SD_OLE, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_EMBED_SOURCE, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_EMBEDDED_OBJ, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_BIFF_5, EXCHG_IN_ACTION_MOVE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_BIFF__5,EXCHG_IN_ACTION_MOVE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_HTML, EXCHG_OUT_ACTION_INSERT_HTML | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_HTML_NO_COMMENT, EXCHG_OUT_ACTION_INSERT_HTML | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_HTML_SIMPLE, EXCHG_OUT_ACTION_INSERT_HTML | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_STRING, EXCHG_OUT_ACTION_INSERT_STRING | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMAT_GDIMETAFILE, EXCHG_OUT_ACTION_INSERT_GDIMETAFILE | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_BITMAP, EXCHG_OUT_ACTION_INSERT_BITMAP | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_EMBED_SOURCE_OLE, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_LINK, EXCHG_OUT_ACTION_INSERT_DDE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_SVIM, EXCHG_OUT_ACTION_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_BIFF_8, EXCHG_IN_ACTION_MOVE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { 0xffff, 0, 0 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_SCDOC_FREE_AREA_Copy[] = \
+ { \
+ { SOT_FORMAT_FILE_LIST, EXCHG_IN_ACTION_COPY, 0 },\
+ { SOT_FORMAT_FILE, EXCHG_OUT_ACTION_INSERT_FILE | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_DRAWING, EXCHG_OUT_ACTION_INSERT_DRAWOBJ | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SVXB, EXCHG_OUT_ACTION_INSERT_SVXB | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SD_OLE, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_EMBED_SOURCE, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_EMBEDDED_OBJ, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_BIFF_5, EXCHG_IN_ACTION_COPY | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_BIFF__5,EXCHG_IN_ACTION_COPY | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_HTML, EXCHG_OUT_ACTION_INSERT_HTML | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_HTML_NO_COMMENT, EXCHG_OUT_ACTION_INSERT_HTML | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_HTML_SIMPLE, EXCHG_OUT_ACTION_INSERT_HTML | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_STRING, EXCHG_OUT_ACTION_INSERT_STRING | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, FILEGRPDSC_ONLY_URL },\
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_GDIMETAFILE, EXCHG_OUT_ACTION_INSERT_GDIMETAFILE | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_BITMAP, EXCHG_OUT_ACTION_INSERT_BITMAP | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_EMBED_SOURCE_OLE, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_LINK, EXCHG_OUT_ACTION_INSERT_DDE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_SVIM, EXCHG_OUT_ACTION_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_BIFF_8, EXCHG_IN_ACTION_COPY | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { 0xffff, 0, 0 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_SCDOC_FREE_AREA_Link[] = \
+ { \
+ { SOT_FORMAT_FILE_LIST, EXCHG_IN_ACTION_LINK, 0 }, \
+ { SOT_FORMAT_FILE, EXCHG_IN_ACTION_LINK | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, FILEGRPDSC_ONLY_URL },\
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_LINK, EXCHG_OUT_ACTION_INSERT_DDE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_EMBED_SOURCE, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_EMBEDDED_OBJ, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_EMBED_SOURCE_OLE, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { 0xffff, 0, 0 } \
+ };
+
+
+/* */
+#define EXCHG_DEST_SDDOC_FREE_AREA_ARRAY \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_SDDOC_FREE_AREA_Def[] = \
+ { \
+ { SOT_FORMAT_FILE_LIST, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_FILE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_HTML, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_HTML_NO_COMMENT, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_HTML_SIMPLE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_SVIM, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_STRING, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_IN_ACTION_COPY, FILEGRPDSC_ONLY_URL }, \
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_DRAWING, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_SVXB, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_GDIMETAFILE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMAT_BITMAP, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_SD_OLE, EXCHG_IN_ACTION_MOVE, 0 }, \
+ { SOT_FORMATSTR_ID_EMBED_SOURCE, EXCHG_IN_ACTION_MOVE, 0 }, \
+ { SOT_FORMATSTR_ID_EMBEDDED_OBJ, EXCHG_IN_ACTION_MOVE, 0 }, \
+ { SOT_FORMATSTR_ID_EMBED_SOURCE_OLE, EXCHG_IN_ACTION_MOVE, 0 }, \
+ { SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE, EXCHG_IN_ACTION_MOVE, 0 }, \
+ { SOT_FORMATSTR_ID_LINK, EXCHG_IN_ACTION_MOVE, 0 }, \
+ { 0xffff, 0, 0 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_SDDOC_FREE_AREA_Move[] = \
+ { \
+ { SOT_FORMAT_FILE_LIST, EXCHG_IN_ACTION_MOVE, 0 },\
+ { SOT_FORMAT_FILE, EXCHG_OUT_ACTION_INSERT_FILE | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_DRAWING, EXCHG_OUT_ACTION_INSERT_DRAWOBJ | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SVXB, EXCHG_OUT_ACTION_INSERT_SVXB | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SD_OLE, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_EMBED_SOURCE, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_EMBEDDED_OBJ, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_HTML, EXCHG_OUT_ACTION_INSERT_HTML | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_HTML_NO_COMMENT, EXCHG_OUT_ACTION_INSERT_HTML | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_HTML_SIMPLE, EXCHG_OUT_ACTION_INSERT_HTML | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_STRING, EXCHG_OUT_ACTION_INSERT_STRING | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMAT_GDIMETAFILE, EXCHG_OUT_ACTION_INSERT_GDIMETAFILE | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_BITMAP, EXCHG_OUT_ACTION_INSERT_BITMAP | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_EMBED_SOURCE_OLE, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_LINK, EXCHG_OUT_ACTION_INSERT_DDE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_SVIM, EXCHG_OUT_ACTION_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { 0xffff, 0, 0 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_SDDOC_FREE_AREA_Copy[] = \
+ { \
+ { SOT_FORMAT_FILE_LIST, EXCHG_IN_ACTION_COPY, 0 },\
+ { SOT_FORMAT_FILE, EXCHG_OUT_ACTION_INSERT_FILE | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_DRAWING, EXCHG_OUT_ACTION_INSERT_DRAWOBJ | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SVXB, EXCHG_OUT_ACTION_INSERT_SVXB | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_SD_OLE, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_EMBED_SOURCE, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_EMBEDDED_OBJ, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_HTML, EXCHG_OUT_ACTION_INSERT_HTML | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_HTML_NO_COMMENT, EXCHG_OUT_ACTION_INSERT_HTML | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_HTML_SIMPLE, EXCHG_OUT_ACTION_INSERT_HTML | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_STRING, EXCHG_OUT_ACTION_INSERT_STRING | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, FILEGRPDSC_ONLY_URL },\
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_GDIMETAFILE, EXCHG_OUT_ACTION_INSERT_GDIMETAFILE | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMAT_BITMAP, EXCHG_OUT_ACTION_INSERT_BITMAP | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_EMBED_SOURCE_OLE, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_LINK, EXCHG_OUT_ACTION_INSERT_DDE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_SVIM, EXCHG_OUT_ACTION_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { 0xffff, 0, 0 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_SDDOC_FREE_AREA_Link[] = \
+ { \
+ { SOT_FORMAT_FILE_LIST, EXCHG_IN_ACTION_LINK, 0 }, \
+ { SOT_FORMAT_FILE, EXCHG_IN_ACTION_LINK | EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, FILEGRPDSC_ONLY_URL },\
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_OUT_ACTION_INSERT_HYPERLINK | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 },\
+ { SOT_FORMATSTR_ID_LINK, EXCHG_OUT_ACTION_INSERT_DDE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_EMBED_SOURCE, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_EMBEDDED_OBJ, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_EMBED_SOURCE_OLE, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE, EXCHG_OUT_ACTION_INSERT_OLE | EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL, 0 }, \
+ { 0xffff, 0, 0 } \
+ };
+
+
+/* */
+
+#define IMPL_DATA_ARRAY_1 \
+EXCHG_EMPYT_ARRAY \
+EXCHG_DEST_DOC_OLEOBJ_ARRAY \
+EXCHG_DEST_CHARTDOC_OLEOBJ_ARRAY \
+EXCHG_DEST_DOC_TEXTFRAME_ARRAY \
+EXCHG_DEST_DOC_GRAPHOBJ_ARRAY \
+EXCHG_DEST_DOC_LNKD_GRAPHOBJ_ARRAY \
+EXCHG_DEST_DOC_TEXTFRAME_WEB_ARRAY
+
+#define IMPL_DATA_ARRAY_2 \
+EXCHG_DEST_DOC_GRAPH_W_IMAP_ARRAY \
+EXCHG_DEST_DOC_LNKD_GRAPH_W_IMAP_ARRAY \
+EXCHG_DEST_DOC_IMAPREGION_ARRAY \
+EXCHG_DEST_DOC_DRAWOBJ_ARRAY \
+EXCHG_DEST_DOC_URLBUTTON_ARRAY \
+EXCHG_DEST_DOC_URLFIELD_ARRAY \
+EXCHG_DEST_DOC_GROUPOBJ_ARRAY \
+EXCHG_DEST_SWDOC_FREE_AREA_ARRAY \
+EXCHG_DEST_SCDOC_FREE_AREA_ARRAY \
+EXCHG_DEST_SDDOC_FREE_AREA_ARRAY \
+EXCHG_DEST_SWDOC_FREE_AREA_WEB_ARRAY \
+
+#define IMPL_DATA_ARRAY_3 \
+static SotDestinationEntry_Impl __READONLY_DATA aDestinationArray[] = \
+{ \
+ { EXCHG_DEST_DOC_OLEOBJ, \
+ aEXCHG_DEST_DOC_OLEOBJ_Def, \
+ aEXCHG_DEST_DOC_OLEOBJ_Move, \
+ aEmptyArr, \
+ aEXCHG_DEST_DOC_OLEOBJ_Link \
+ }, \
+ { EXCHG_DEST_CHARTDOC_OLEOBJ, \
+ aEXCHG_DEST_CHARTDOC_OLEOBJ_Def, \
+ aEXCHG_DEST_CHARTDOC_OLEOBJ_Move, \
+ aEmptyArr, \
+ aEXCHG_DEST_CHARTDOC_OLEOBJ_Link \
+ }, \
+ { EXCHG_DEST_DOC_TEXTFRAME, \
+ aEXCHG_DEST_DOC_TEXTFRAME_Def, \
+ aEXCHG_DEST_DOC_TEXTFRAME_Move, \
+ aEXCHG_DEST_DOC_TEXTFRAME_Copy, \
+ aEXCHG_DEST_DOC_TEXTFRAME_Link \
+ }, \
+ { EXCHG_DEST_DOC_GRAPHOBJ, \
+ aEXCHG_DEST_DOC_GRAPHOBJ_Def, \
+ aEXCHG_DEST_DOC_GRAPHOBJ_Move, \
+ aEXCHG_DEST_DOC_GRAPHOBJ_Copy, \
+ aEXCHG_DEST_DOC_GRAPHOBJ_Link \
+ }, \
+ { EXCHG_DEST_DOC_LNKD_GRAPHOBJ, \
+ aEXCHG_DEST_DOC_LNKD_GRAPHOBJ_Def, \
+ aEXCHG_DEST_DOC_LNKD_GRAPHOBJ_Move, \
+ aEXCHG_DEST_DOC_LNKD_GRAPHOBJ_Copy, \
+ aEXCHG_DEST_DOC_LNKD_GRAPHOBJ_Link \
+ }, \
+ { EXCHG_DEST_DOC_GRAPH_W_IMAP, \
+ aEXCHG_DEST_DOC_GRAPH_W_IMAP_Def, \
+ aEXCHG_DEST_DOC_GRAPH_W_IMAP_Move, \
+ aEXCHG_DEST_DOC_GRAPH_W_IMAP_Copy, \
+ aEXCHG_DEST_DOC_GRAPH_W_IMAP_Link \
+ }, \
+ { EXCHG_DEST_DOC_LNKD_GRAPH_W_IMAP, \
+ aEXCHG_DEST_DOC_LNKD_GRAPH_W_IMAP_Def, \
+ aEXCHG_DEST_DOC_LNKD_GRAPH_W_IMAP_Move, \
+ aEXCHG_DEST_DOC_LNKD_GRAPH_W_IMAP_Copy, \
+ aEXCHG_DEST_DOC_LNKD_GRAPH_W_IMAP_Link \
+ }, \
+ { EXCHG_DEST_DOC_IMAPREGION, \
+ aEXCHG_DEST_DOC_IMAPREGION_Def, \
+ aEXCHG_DEST_DOC_IMAPREGION_Copy, \
+ aEmptyArr, \
+ aEmptyArr \
+ }, \
+ { EXCHG_DEST_DOC_DRAWOBJ, \
+ aEXCHG_DEST_DOC_DRAWOBJ_Def, \
+ aEXCHG_DEST_DOC_DRAWOBJ_Copy, \
+ aEXCHG_DEST_DOC_DRAWOBJ_Move, \
+ aEXCHG_DEST_DOC_DRAWOBJ_Link \
+ }, \
+ { EXCHG_DEST_DOC_URLBUTTON, \
+ aEXCHG_DEST_DOC_URLBUTTON_Def, \
+ aEXCHG_DEST_DOC_URLBUTTON_Move, \
+ aEXCHG_DEST_DOC_URLBUTTON_Copy, \
+ aEmptyArr \
+ }, \
+ { EXCHG_DEST_DOC_URLFIELD, \
+ aEXCHG_DEST_DOC_URLFIELD_Def, \
+ aEmptyArr, \
+ aEXCHG_DEST_DOC_URLFIELD_Copy, \
+ aEXCHG_DEST_DOC_URLFIELD_Link \
+ }, \
+ { EXCHG_DEST_DOC_GROUPOBJ, \
+ aEXCHG_DEST_DOC_GROUPOBJ_Def, \
+ aEXCHG_DEST_DOC_GROUPOBJ_Move, \
+ aEXCHG_DEST_DOC_GROUPOBJ_Copy, \
+ aEXCHG_DEST_DOC_GROUPOBJ_Link \
+ }, \
+ { EXCHG_DEST_SWDOC_FREE_AREA, \
+ aEXCHG_DEST_SWDOC_FREE_AREA_Def, \
+ aEXCHG_DEST_SWDOC_FREE_AREA_Move, \
+ aEXCHG_DEST_SWDOC_FREE_AREA_Copy, \
+ aEXCHG_DEST_SWDOC_FREE_AREA_Link \
+ }, \
+ { EXCHG_DEST_SCDOC_FREE_AREA, \
+ aEXCHG_DEST_SCDOC_FREE_AREA_Def, \
+ aEXCHG_DEST_SCDOC_FREE_AREA_Move, \
+ aEXCHG_DEST_SCDOC_FREE_AREA_Copy, \
+ aEXCHG_DEST_SCDOC_FREE_AREA_Link \
+ }, \
+ { EXCHG_DEST_SDDOC_FREE_AREA, \
+ aEXCHG_DEST_SDDOC_FREE_AREA_Def, \
+ aEXCHG_DEST_SDDOC_FREE_AREA_Move, \
+ aEXCHG_DEST_SDDOC_FREE_AREA_Copy, \
+ aEXCHG_DEST_SDDOC_FREE_AREA_Link \
+ }, \
+ { EXCHG_DEST_DOC_TEXTFRAME_WEB, \
+ aEXCHG_DEST_DOC_TEXTFRAME_WEB_Def, \
+ aEXCHG_DEST_DOC_TEXTFRAME_WEB_Move, \
+ aEXCHG_DEST_DOC_TEXTFRAME_WEB_Copy, \
+ aEXCHG_DEST_DOC_TEXTFRAME_WEB_Link \
+ }, \
+ { EXCHG_DEST_SWDOC_FREE_AREA_WEB, \
+ aEXCHG_DEST_SWDOC_FREE_AREA_WEB_Def, \
+ aEXCHG_DEST_SWDOC_FREE_AREA_WEB_Move, \
+ aEXCHG_DEST_SWDOC_FREE_AREA_WEB_Copy, \
+ aEXCHG_DEST_SWDOC_FREE_AREA_WEB_Link \
+ }, \
+ { \
+ 0xffff, 0, 0, 0, 0 \
+ } \
+};
+
+
+
+
+// ---------------------------------
+// - new style GetExchange methods -
+// ---------------------------------
+
+sal_Bool IsFormatSupported( const DataFlavorExVector& rDataFlavorExVector, ULONG nId )
+{
+ DataFlavorExVector::iterator aIter( ( (DataFlavorExVector&) rDataFlavorExVector ).begin() );
+ DataFlavorExVector::iterator aEnd( ( (DataFlavorExVector&) rDataFlavorExVector ).end() );
+ sal_Bool bRet = sal_False;
+
+ while( aIter != aEnd )
+ {
+ if( nId == (*aIter++).mnSotId )
+ {
+ bRet = sal_True;
+ aIter = aEnd;
+ }
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+static BOOL CheckTransferableContext_Impl( const Reference< XTransferable >* pxTransferable, const SotAction_Impl&
+#ifdef WNT
+rEntry
+#endif
+)
+{
+ DataFlavor aFlavor;
+ BOOL bRet = TRUE;
+
+ try
+ {
+ if( pxTransferable && (*pxTransferable).is() &&
+ SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, aFlavor ) &&
+ (*pxTransferable)->isDataFlavorSupported( aFlavor ) )
+ {
+#ifdef WNT
+ switch( rEntry.nContextCheckId )
+ {
+ case FILEGRPDSC_ONLY_URL:
+ {
+ bRet = FALSE;
+
+ if( SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_FILECONTENT, aFlavor ) &&
+ (*pxTransferable)->isDataFlavorSupported( aFlavor ) &&
+ SotExchange::GetFormatDataFlavor( rEntry.nFormatId, aFlavor ) &&
+ (*pxTransferable)->isDataFlavorSupported( aFlavor ) )
+ {
+ Any aAny( (*pxTransferable)->getTransferData( aFlavor ) );
+
+ if( aAny.hasValue() )
+ {
+ Sequence< sal_Int8 > aSeq; aAny >>= aSeq;
+
+ if( aSeq.getLength() )
+ {
+ FILEGROUPDESCRIPTOR* pFDesc = (FILEGROUPDESCRIPTOR*) aSeq.getConstArray();
+
+ if( pFDesc->cItems )
+ {
+ ByteString sDesc( pFDesc->fgd[ 0 ].cFileName );
+ bRet = 4 < sDesc.Len() && sDesc.Copy( sDesc.Len()-4 ).EqualsIgnoreCaseAscii( ".URL" );
+ }
+ }
+ }
+ }
+ }
+ break;
+ }
+#endif
+ }
+ }
+ catch( const UnsupportedFlavorException& )
+ {
+ }
+ catch( const RuntimeException& )
+ {
+ }
+
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+static USHORT GetTransferableAction_Impl(
+ const DataFlavorExVector& rDataFlavorExVector,
+ const SotAction_Impl* pArray,
+ ULONG& rFormat,
+ ULONG nOnlyTestFormat,
+ const Reference< XTransferable >* pxTransferable )
+{
+ try
+ {
+ if( rDataFlavorExVector.size() )
+ {
+ DataFlavor aFlavor;
+ const SotAction_Impl* pArrayStart = pArray;
+ ULONG nId = pArray->nFormatId;
+
+#if OSL_DEBUG_LEVEL > 1
+// used for testing a specific format - change in the debugger the value
+ static ULONG nChkFormat = 0;
+ if( nChkFormat )
+ {
+ for( ; 0xffff != pArray->nFormatId &&
+ nChkFormat != pArray->nFormatId; ++pArray )
+ ;
+ nId = pArray->nFormatId;
+ }
+#endif
+
+ while( nId != 0xffff )
+ {
+ rFormat = nId;
+
+ if( ( !nOnlyTestFormat || nOnlyTestFormat == nId ) &&
+ IsFormatSupported( rDataFlavorExVector, nId ) &&
+ ( !pArray->nContextCheckId || CheckTransferableContext_Impl( pxTransferable, *pArray ) ) )
+ {
+ if( pxTransferable && (*pxTransferable).is() && ( SOT_FORMAT_FILE_LIST == rFormat ) )
+ {
+ if( IsFormatSupported( rDataFlavorExVector, SOT_FORMAT_FILE ) )
+ {
+ DataFlavor aFileListFlavor;
+ SotExchange::GetFormatDataFlavor( SOT_FORMAT_FILE_LIST, aFileListFlavor );
+ Any aAny( (*pxTransferable)->getTransferData( aFileListFlavor ) );
+
+ if( aAny.hasValue() )
+ {
+ Sequence< sal_Int8 > aSeq; aAny >>= aSeq;
+ SvMemoryStream aMemStm( (void*) aSeq.getConstArray(), aSeq.getLength(), STREAM_READ );
+ FileList aFileList;
+
+ aMemStm >> aFileList;
+
+ if( !aMemStm.GetError() && ( aFileList.Count() == 1 ) )
+ {
+ const SotAction_Impl* pCur = pArrayStart;
+
+ while( pCur->nFormatId != 0xffff )
+ {
+ if( pCur->nFormatId == SOT_FORMAT_FILE )
+ {
+ rFormat = SOT_FORMAT_FILE;
+ return pCur->nAction;
+ }
+ pCur++;
+ }
+ }
+ }
+ }
+ }
+ return pArray->nAction;
+ }
+ pArray++;
+ nId = pArray->nFormatId;
+ }
+ }
+ }
+ catch( const UnsupportedFlavorException& )
+ {
+ }
+ catch( const RuntimeException& )
+ {
+ }
+
+ return EXCHG_INOUT_ACTION_NONE;
+}
+
+// -----------------------------------------------------------------------------
+
+USHORT SotExchange::GetExchangeAction( const DataFlavorExVector& rDataFlavorExVector,
+ USHORT nDestination,
+ USHORT nSourceOptions,
+ USHORT nUserAction,
+ ULONG& rFormat,
+ USHORT& rDefaultAction,
+ ULONG nOnlyTestFormat,
+ const Reference< XTransferable >* pxTransferable )
+{
+ // hier wird jetzt die oben definierte Tabelle "implementiert"
+ IMPL_DATA_ARRAY_1;
+ IMPL_DATA_ARRAY_2;
+ IMPL_DATA_ARRAY_3;
+
+ rFormat = SOT_FORMAT_STRING;
+
+ //Todo: Binaere Suche einbauen
+ const SotDestinationEntry_Impl* pEntry = aDestinationArray;
+ while( 0xffff != pEntry->nDestination )
+ {
+ if( pEntry->nDestination == nDestination )
+ break;
+ ++pEntry;
+ }
+
+ if( 0xffff == pEntry->nDestination )
+ {
+ return EXCHG_INOUT_ACTION_NONE;
+ }
+
+ nUserAction &= EXCHG_ACTION_MASK;
+ rFormat = 0;
+
+ /* Behandlung der Default-Action nach folgender Vorgehensweise:
+
+ - Das Ziel wird nach der Default-Action gefragt
+ - Unterstuetzt die Quelle diese Aktion so wird sie uebernommen
+ - Anderenfalls wird aus den von der Quelle zur Verfuegung gestellten
+ Aktionen eine ausgewaehlt, die zu einer moeglichst nicht leeren
+ Ergebnisaktion fuehrt. Hierbei wird in dieser Reihenfolge
+ vorgegangen: Copy -> Link -> Move
+ */
+ if( nUserAction == EXCHG_IN_ACTION_DEFAULT )
+ {
+ nUserAction = GetTransferableAction_Impl(
+ rDataFlavorExVector, pEntry->aDefaultActions,
+ rFormat, nOnlyTestFormat, pxTransferable );
+ // Unterstuetzt die Quelle die Aktion?
+ if( !(nUserAction & nSourceOptions ))
+ {
+ // Nein -> Alle Aktionen der Quelle checken
+ rDefaultAction = (EXCHG_IN_ACTION_COPY & nSourceOptions);
+ if( rDefaultAction )
+ {
+ nUserAction = GetTransferableAction_Impl(
+ rDataFlavorExVector, pEntry->aCopyActions,
+ rFormat, nOnlyTestFormat, pxTransferable );
+ if ( nUserAction )
+ return nUserAction;
+ }
+ rDefaultAction = (EXCHG_IN_ACTION_LINK & nSourceOptions);
+ if( rDefaultAction )
+ {
+ nUserAction = GetTransferableAction_Impl(
+ rDataFlavorExVector, pEntry->aLinkActions,
+ rFormat, nOnlyTestFormat, pxTransferable );
+ if ( nUserAction )
+ return nUserAction;
+ }
+ rDefaultAction = (EXCHG_IN_ACTION_MOVE & nSourceOptions);
+ if( rDefaultAction )
+ {
+ nUserAction = GetTransferableAction_Impl(
+ rDataFlavorExVector, pEntry->aMoveActions,
+ rFormat, nOnlyTestFormat, pxTransferable );
+ if ( nUserAction )
+ return nUserAction;
+ }
+ rDefaultAction = 0;
+ return 0;
+ }
+ rDefaultAction = nUserAction;
+ }
+ else
+ rDefaultAction = nUserAction;
+
+ switch( nUserAction )
+ {
+ case EXCHG_IN_ACTION_MOVE:
+ nUserAction = GetTransferableAction_Impl(
+ rDataFlavorExVector, pEntry->aMoveActions,
+ rFormat, nOnlyTestFormat, pxTransferable );
+ break;
+
+ case EXCHG_IN_ACTION_COPY:
+ nUserAction = GetTransferableAction_Impl(
+ rDataFlavorExVector, pEntry->aCopyActions,
+ rFormat, nOnlyTestFormat, pxTransferable );
+ break;
+
+ case EXCHG_IN_ACTION_LINK:
+ nUserAction = GetTransferableAction_Impl(
+ rDataFlavorExVector, pEntry->aLinkActions,
+ rFormat, nOnlyTestFormat, pxTransferable );
+ break;
+
+ default:
+ nUserAction = EXCHG_INOUT_ACTION_NONE;
+ }
+ return nUserAction;
+}
+
+// -----------------------------------------------------------------------------
+
+USHORT SotExchange::GetExchangeAction(
+ const Reference< XTransferable >& rxTransferable,
+ USHORT nDestination, USHORT nSourceOptions,
+ USHORT nUserAction, ULONG& rFormat,
+ USHORT& rDefaultAction, ULONG nOnlyTestFormat )
+{
+ DataFlavorExVector aVector;
+
+ if( rxTransferable.is() )
+ {
+ try
+ {
+ const Sequence< DataFlavor > aFlavors( rxTransferable->getTransferDataFlavors() );
+
+ for( sal_Int32 i = 0; i < aFlavors.getLength(); i++ )
+ {
+ DataFlavorEx aFlavorEx;
+ const DataFlavor& rFlavor = aFlavors[ i ];
+
+ aFlavorEx.MimeType = rFlavor.MimeType;
+ aFlavorEx.HumanPresentableName = rFlavor.HumanPresentableName;
+ aFlavorEx.DataType = rFlavor.DataType;
+ aFlavorEx.mnSotId = SotExchange::RegisterFormat( rFlavor );
+
+ aVector.push_back( aFlavorEx );
+
+ if( ( SOT_FORMATSTR_ID_BMP == aFlavorEx.mnSotId ) &&
+ !IsFormatSupported( aVector, SOT_FORMAT_BITMAP ) )
+ {
+ if( SotExchange::GetFormatDataFlavor( SOT_FORMAT_BITMAP, aFlavorEx ) )
+ {
+ aFlavorEx.mnSotId = SOT_FORMAT_BITMAP;
+ aVector.push_back( aFlavorEx );
+ }
+ }
+ else if( ( ( SOT_FORMATSTR_ID_WMF == aFlavorEx.mnSotId ) ||
+ ( SOT_FORMATSTR_ID_EMF == aFlavorEx.mnSotId ) ) &&
+ !IsFormatSupported( aVector, SOT_FORMAT_GDIMETAFILE ) )
+ {
+ if( SotExchange::GetFormatDataFlavor( SOT_FORMAT_GDIMETAFILE, aFlavorEx ) )
+ {
+ aFlavorEx.mnSotId = SOT_FORMAT_GDIMETAFILE;
+ aVector.push_back( aFlavorEx );
+ }
+ }
+ }
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+ }
+ }
+
+ return( SotExchange::GetExchangeAction( aVector, nDestination, nSourceOptions,
+ nUserAction, rFormat, rDefaultAction,
+ nOnlyTestFormat, &rxTransferable ) );
+}
+
+USHORT SotExchange::IsChart( const SvGlobalName& rName )
+{
+ USHORT nRet=0;
+// if ( rName == SvGlobalName( SO3_SCH_CLASSID_8 ) )
+// nRet = SOFFICE_FILEFORMAT_8;
+// else
+ if ( rName == SvGlobalName( SO3_SCH_CLASSID_60 ) )
+ nRet = SOFFICE_FILEFORMAT_60;
+ else if ( rName == SvGlobalName( SO3_SCH_CLASSID_50 ) )
+ nRet = SOFFICE_FILEFORMAT_50;
+ else if ( rName == SvGlobalName( SO3_SCH_CLASSID_40 ) )
+ nRet = SOFFICE_FILEFORMAT_40;
+ else if ( rName == SvGlobalName( SO3_SCH_CLASSID_30 ) )
+ nRet = SOFFICE_FILEFORMAT_31;
+
+ return nRet;
+}
+
+USHORT SotExchange::IsMath( const SvGlobalName& rName )
+{
+ USHORT nRet=0;
+// if ( rName == SvGlobalName( SO3_SM_CLASSID_8 ) )
+// nRet = SOFFICE_FILEFORMAT_8;
+// else
+ if ( rName == SvGlobalName( SO3_SM_CLASSID_60 ) )
+ nRet = SOFFICE_FILEFORMAT_60;
+ else if ( rName == SvGlobalName( SO3_SM_CLASSID_50 ) )
+ nRet = SOFFICE_FILEFORMAT_50;
+ else if ( rName == SvGlobalName( SO3_SM_CLASSID_40 ) )
+ nRet = SOFFICE_FILEFORMAT_40;
+ else if ( rName == SvGlobalName( SO3_SM_CLASSID_30 ) )
+ nRet = SOFFICE_FILEFORMAT_31;
+
+ return nRet;
+}
+
diff --git a/sot/source/base/makefile.mk b/sot/source/base/makefile.mk
new file mode 100644
index 000000000000..861b7cc5969b
--- /dev/null
+++ b/sot/source/base/makefile.mk
@@ -0,0 +1,58 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=sot
+TARGET=base
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(COM)"=="GCC"
+NOOPTFILES= \
+ $(SLO)$/exchange.obj
+.ENDIF # GCC
+
+SLOFILES= \
+ $(SLO)$/factory.obj \
+ $(SLO)$/object.obj \
+ $(SLO)$/exchange.obj \
+ $(SLO)$/filelist.obj \
+ $(SLO)$/formats.obj
+
+EXCEPTIONSFILES= \
+ $(SLO)$/formats.obj
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/sot/source/base/object.cxx b/sot/source/base/object.cxx
new file mode 100644
index 000000000000..403a1c6bb61d
--- /dev/null
+++ b/sot/source/base/object.cxx
@@ -0,0 +1,489 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sot.hxx"
+
+#define _SOT_OBJECT_CXX
+
+#include <tools/debug.hxx>
+#include <sot/object.hxx>
+#include <sot/factory.hxx>
+#include <agg.hxx>
+
+/************** class SvAggregateMemberList *****************************/
+/************************************************************************/
+PRV_SV_IMPL_OWNER_LIST(SvAggregateMemberList,SvAggregate);
+
+/************** class SotObject ******************************************/
+class SotObjectFactory : public SotFactory
+{
+public:
+ TYPEINFO();
+ SotObjectFactory( const SvGlobalName & rName,
+ const String & rClassName,
+ CreateInstanceType pCreateFuncP )
+ : SotFactory( rName, rClassName, pCreateFuncP )
+ {}
+};
+TYPEINIT1(SotObjectFactory,SotFactory);
+
+
+SO2_IMPL_BASIC_CLASS_DLL(SotObject,SotObjectFactory,
+ SvGlobalName( 0xf44b7830, 0xf83c, 0x11d0,
+ 0xaa, 0xa1, 0x0, 0xa0, 0x24, 0x9d, 0x55, 0x90 ) )
+SO2_IMPL_INVARIANT(SotObject)
+
+/*************************************************************************
+|* SotObject::TestMemberObjRef()
+|*
+|* Beschreibung:
+*************************************************************************/
+void SotObject::TestMemberObjRef( BOOL /*bFree*/ )
+{
+}
+
+/*************************************************************************
+|* SotObject::TestMemberObjRef()
+|*
+|* Beschreibung:
+*************************************************************************/
+#ifdef TEST_INVARIANT
+void SotObject::TestMemberInvariant( BOOL /*bPrint*/ )
+{
+}
+#endif
+
+/*************************************************************************
+|* SotObject::SotObject()
+|*
+|* Beschreibung
+*************************************************************************/
+SotObject::SotObject()
+ : pAggList ( NULL )
+ , nStrongLockCount( 0 )
+ , nOwnerLockCount( 0 )
+ , bOwner ( TRUE )
+ , bSVObject ( FALSE )
+ , bInClose ( FALSE )
+{
+ SotFactory::IncSvObjectCount( this );
+}
+
+/*************************************************************************
+|*
+|* SotObject::~SotObject()
+|*
+|* Beschreibung
+|* Ersterstellung MM 05.06.94
+|* Letzte Aenderung MM 05.06.94
+|*
+*************************************************************************/
+SotObject::~SotObject()
+{
+ SotFactory::DecSvObjectCount( this );
+}
+
+/*************************************************************************
+|* SotObject::GetInterface()
+|*
+|* Beschreibung: Um so3 zu helfen
+*************************************************************************/
+IUnknown * SotObject::GetInterface( const SvGlobalName & )
+{
+ return NULL;
+}
+
+/*************************************************************************
+|* SotObject::IsSvClass()
+|*
+|* Beschreibung
+*************************************************************************/
+BOOL SotObject::IsSvObject() const
+{
+ return Owner() || bSVObject;
+}
+
+/*************************************************************************
+|* SotObject::QueryDelete()
+|*
+|* Beschreibung: Bei allen aggregierten Objekte muss der RefCount auf
+|* 0 gehen, damit das Gesammt-Objekt zerstoert wird. Das
+|* zerst�ren von Teilen ist verboten. Da der Aggregator
+|* (oder Cast-Verwalter) den Zaehler der aggregierten
+|* Objekte um 1 erhoeht, muss dies bei der Berechnung
+|* des 0-RefCounts beruecksichtigt werden.
+*************************************************************************/
+BOOL SotObject::ShouldDelete()
+{
+ if( !pAggList )
+ return TRUE;
+
+ SvAggregate & rMO = pAggList->GetObject( 0 );
+ if( rMO.bMainObj )
+ {
+ AddRef();
+ pAggList->GetObject( 0 ).pObj->ReleaseRef();
+ return FALSE;
+ }
+
+ ULONG i;
+ for( i = 1; i < pAggList->Count(); i++ )
+ {
+ SvAggregate & rAgg = pAggList->GetObject( i );
+ // Groesser 1, wegen AddRef() bei AddInterface
+ if( !rAgg.bFactory && rAgg.pObj->GetRefCount() > 1 )
+ {
+ // den eigenen hochzaehelen
+ AddRef();
+ // einen Aggregierten runterzaehlen
+ rAgg.pObj->ReleaseRef();
+ return FALSE;
+ }
+ }
+ AddNextRef(); // rekursion stoppen
+ for( i = pAggList->Count() -1; i > 0; i-- )
+ {
+ // Referenzen aufloesen
+ DBG_ASSERT( !pAggList->GetObject( i ).bMainObj, "main object reference is opened" );
+ RemoveInterface( i );
+ }
+ delete pAggList;
+ pAggList = NULL;
+ // und zerstoeren, dies ist unabhaengig vom RefCount
+ return TRUE;
+}
+
+/*************************************************************************
+|* SotObject::QueryDelete()
+|*
+|* Beschreibung
+*************************************************************************/
+void SotObject::QueryDelete()
+{
+ if( ShouldDelete() )
+ SvRefBase::QueryDelete();
+}
+
+
+
+/*************************************************************************
+|* SotObject::GetAggList()
+|*
+|* Beschreibung
+*************************************************************************/
+SvAggregateMemberList & SotObject::GetAggList()
+{
+ if( !pAggList )
+ {
+ pAggList = new SvAggregateMemberList( 2, 1 );
+ pAggList->Append( SvAggregate() );
+ }
+ return *pAggList;
+}
+
+
+/*************************************************************************
+|* SotObject::RemoveInterface()
+|*
+|* Beschreibung
+*************************************************************************/
+void SotObject::RemoveInterface( ULONG nPos )
+{
+ SvAggregate & rAgg = pAggList->GetObject( nPos );
+ if( !rAgg.bFactory )
+ {
+ DBG_ASSERT( rAgg.pObj->pAggList, "no aggregation list" );
+ DBG_ASSERT( rAgg.pObj->pAggList->GetObject( 0 ).pObj == this,
+ "not owner of aggregated object" );
+ // sich selbst als Cast-Verwalter austragen
+ rAgg.pObj->pAggList->GetObject( 0 ) = SvAggregate();
+ // Referenz aufloesen
+ rAgg.pObj->ReleaseRef();
+ // Aus der eigenen List austragen
+ pAggList->Remove( nPos );
+ }
+}
+
+/*************************************************************************
+|* SotObject::RemoveInterface()
+|*
+|* Beschreibung
+*************************************************************************/
+void SotObject::RemoveInterface( SotObject * pObjP )
+{
+ DBG_ASSERT( pObjP, "null pointer" );
+ DBG_ASSERT( pAggList, "no aggregation list" );
+ ULONG i;
+ for( i = 0; i < pAggList->Count(); i++ )
+ {
+ SvAggregate & rAgg = pAggList->GetObject( i );
+ if( !rAgg.bFactory && pObjP == rAgg.pObj )
+ RemoveInterface( i );
+ }
+ DBG_ASSERT( i < pAggList->Count(), "object not found" );
+}
+
+/*************************************************************************
+|* SotObject::AddInterface()
+|*
+|* Beschreibung
+*************************************************************************/
+void SotObject::AddInterface( SotObject * pObjP )
+{
+ pObjP->AddRef(); // Objekt festhalten
+ GetAggList();
+ pAggList->Append( SvAggregate( pObjP, FALSE ) );
+
+ // sich selbst als Typecast-Verwalter eintragen
+ SvAggregateMemberList & rAList = pObjP->GetAggList();
+ DBG_ASSERT( !rAList.GetObject( 0 ).bMainObj, "try to aggregate twice" );
+ rAList[ 0 ] = SvAggregate( this, TRUE );
+}
+
+/*************************************************************************
+|* SotObject::AddInterface()
+|*
+|* Beschreibung
+*************************************************************************/
+void SotObject::AddInterface( SotFactory * pFactP )
+{
+ GetAggList();
+ pAggList->Append( SvAggregate( pFactP ) );
+}
+
+/*************************************************************************
+|* SotObject::CreateAggObj()
+|*
+|* Beschreibung
+*************************************************************************/
+SotObjectRef SotObject::CreateAggObj( const SotFactory * )
+{
+ return SotObjectRef();
+}
+
+
+/*************************************************************************
+|* SotObject::DownAggCast()
+|*
+|* Beschreibung
+*************************************************************************/
+void * SotObject::DownAggCast( const SotFactory * pFact )
+{
+ void * pCast = NULL;
+ // geht den Pfad nur Richtung aggregierte Objekte
+ if( pAggList )
+ {
+ for( ULONG i = 1; !pCast || i < pAggList->Count(); i++ )
+ {
+ SvAggregate & rAgg = pAggList->GetObject( i );
+ if( rAgg.bFactory )
+ {
+ if( rAgg.pFact->Is( pFact ) )
+ {
+ // On-Demand erzeugen, wenn Typ gebraucht
+ SotObjectRef aObj( CreateAggObj( rAgg.pFact ) );
+ rAgg.bFactory = FALSE;
+ rAgg.pObj = aObj;
+ rAgg.pObj->AddRef();
+
+ // sich selbst als Typecast-Verwalter eintragen
+ SvAggregateMemberList & rAList = rAgg.pObj->GetAggList();
+ DBG_ASSERT( !rAList.GetObject( 0 ).bMainObj, "try to aggregate twice" );
+ rAList[ 0 ] = SvAggregate( this, TRUE );
+ }
+ }
+ if( !rAgg.bFactory )
+ {
+ // muss der (void *) auf Klasse pFact sein
+ pCast = rAgg.pObj->Cast( pFact );
+ if( !pCast )
+ pCast = rAgg.pObj->DownAggCast( pFact );
+ if( pCast )
+ break;
+ }
+ }
+ }
+ return pCast;
+}
+
+/*************************************************************************
+|* SotObject::AggCast()
+|*
+|* Beschreibung
+*************************************************************************/
+void * SotObject::AggCast( const SotFactory * pFact )
+{
+ void * pCast = NULL;
+ if( pAggList )
+ {
+ SvAggregate & rAgg = pAggList->GetObject( 0 );
+ if( rAgg.bMainObj )
+ return rAgg.pObj->AggCast( pFact );
+ pCast = Cast( pFact );
+ if( !pCast )
+ pCast = DownAggCast( pFact );
+ }
+ else
+ pCast = Cast( pFact );
+ return pCast;
+}
+
+/*************************************************************************
+|* SotObject::CastAndAddRef()
+|*
+|* Beschreibung
+*************************************************************************/
+void * SotObject::CastAndAddRef( const SotFactory * pFact )
+{
+ void * pCast = Cast( pFact );
+ if( pCast )
+ AddRef();
+ return pCast;
+}
+
+/*************************************************************************
+|* SotObject::GetMainObj()
+|*
+|* Beschreibung
+*************************************************************************/
+SotObject * SotObject::GetMainObj() const
+{
+ if( pAggList )
+ {
+ if( pAggList->GetObject( 0 ).bMainObj )
+ return pAggList->GetObject( 0 ).pObj->GetMainObj();
+ }
+ return (SotObject *)this;
+}
+
+//=========================================================================
+USHORT SotObject::FuzzyLock
+(
+ BOOL bLock, /* TRUE, lock. FALSE, unlock. */
+ BOOL /*bIntern*/, /* TRUE, es handelt sich um einen internen Lock.
+ FALSE, der Lock kam von aussen (Ole2, Ipc2) */
+ BOOL bClose /* TRUE, Close aufrufen wenn letzte Lock */
+)
+/* [Beschreibung]
+
+ Erlaubte Parameterkombinationen:
+ ( TRUE, TRUE, * ) -> interner Lock.
+ ( FALSE, TRUE, TRUE ) -> interner Unlock mit Close,
+ wenn LockCount() == 0
+ ( TRUE, FALSE, * ) -> externer Lock.
+ ( FALSE, FALSE, TRUE ) -> externer Unlock mit Close,
+ wenn LockCount() == 0
+ ( FALSE, FALSE, FALSE ) -> externer Unlock
+
+ F"ur !Owner() wird der Aufruf an das externe Objekt weitergeleitet.
+ F"ur diese muss das <IOleItemContainer>-Interface zur Vef"ugung stehen.
+ bIntern und bClose werden dann ignoriert.
+ Wenn der LockCount auf 0 wechselt, wird <SotObject::DoClose>
+ gerufen, wenn kein OwnerLock besteht.
+
+ [Anmerkung]
+
+*/
+{
+ SotObjectRef xHoldAlive( this );
+ USHORT nRet;
+ if( bLock )
+ {
+ AddRef();
+ nRet = ++nStrongLockCount;
+ }
+ else
+ {
+ nRet = --nStrongLockCount;
+ ReleaseRef();
+ }
+
+ if( !nRet && bClose && !nOwnerLockCount )
+ DoClose();
+ return nRet;
+}
+
+//=========================================================================
+void SotObject::OwnerLock
+(
+ BOOL bLock /* TRUE, lock. FALSE, unlock. */
+)
+/* [Beschreibung]
+
+ Wenn der OwnerLock auf Null dekrementiert, dann wird die Methode
+ DoClose gerufen. Dies geschieht unabh"angig vom Lock. bzw. RefCount.
+ Ist der OwnerLock-Z"ahler != Null, dann wird kein DoClose durch
+ <SotObject::FuzzyLock> gerufen.
+*/
+{
+ if( bLock )
+ {
+ nOwnerLockCount++;
+ AddRef();
+ }
+ else if ( nOwnerLockCount )
+ {
+ if( 0 == --nOwnerLockCount )
+ DoClose();
+ ReleaseRef();
+ }
+}
+
+void SotObject::RemoveOwnerLock()
+{
+ if ( nOwnerLockCount )
+ {
+ --nOwnerLockCount;
+ ReleaseRef();
+ }
+ else {
+ DBG_ERROR("OwnerLockCount underflow!");
+ }
+}
+
+//=========================================================================
+BOOL SotObject::DoClose()
+{
+ BOOL bRet = FALSE;
+ if( !bInClose )
+ {
+ SotObjectRef xHoldAlive( this );
+ bInClose = TRUE;
+ bRet = Close();
+ bInClose = FALSE;
+ }
+ return bRet;
+}
+
+//=========================================================================
+BOOL SotObject::Close()
+{
+ return TRUE;
+}
+
+
diff --git a/sot/source/sdstor/makefile.mk b/sot/source/sdstor/makefile.mk
new file mode 100644
index 000000000000..f5c6d81548c9
--- /dev/null
+++ b/sot/source/sdstor/makefile.mk
@@ -0,0 +1,64 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=sot
+TARGET=sdstor
+
+# --- Settings -----------------------------------------------------
+
+ENABLE_EXCEPTIONS=true
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/unostorageholder.obj \
+ $(SLO)$/ucbstorage.obj \
+ $(SLO)$/stg.obj \
+ $(SLO)$/stgcache.obj \
+ $(SLO)$/stgstrms.obj \
+ $(SLO)$/stgelem.obj \
+ $(SLO)$/stgio.obj \
+ $(SLO)$/stgole.obj \
+ $(SLO)$/stgdir.obj \
+ $(SLO)$/stgavl.obj \
+ $(SLO)$/storinfo.obj \
+ $(SLO)$/storage.obj
+
+EXCEPTIONSFILES= \
+ $(SLO)$/unostorageholder.obj\
+ $(SLO)$/ucbstorage.obj\
+ $(SLO)$/storage.obj
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/sot/source/sdstor/stg.cxx b/sot/source/sdstor/stg.cxx
new file mode 100644
index 000000000000..1c749aa05cb8
--- /dev/null
+++ b/sot/source/sdstor/stg.cxx
@@ -0,0 +1,1091 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sot.hxx"
+
+#include <storinfo.hxx>
+#include <osl/file.hxx>
+#include <tools/tempfile.hxx>
+#include <tools/ownlist.hxx>
+#include <tools/string.hxx>
+#ifndef _TOOLS_FSYS_HXX
+#include <tools/fsys.hxx>
+#endif
+#ifndef _TOOLS_STREAM_HXX
+#include <tools/stream.hxx>
+#endif
+#include <tools/pstm.hxx>
+#include <tools/debug.hxx>
+
+#include "stg.hxx"
+#include "stgelem.hxx"
+#include "stgcache.hxx"
+#include "stgstrms.hxx"
+#include "stgdir.hxx"
+#include "stgio.hxx"
+#include "stgole.hxx"
+
+static long nTmpCount = 0;
+
+// The internal open mode is STREAM_READ | STREAM_TRUNC, which is silly
+// by itself. It inhibits the checking of sharing modes and is used
+// during CopyTo() and MoveTo() for opening a stream in read mode
+// although it may be open in DENYALL mode
+
+#define INTERNAL_MODE ( STREAM_READ | STREAM_TRUNC )
+
+///////////////////////// class StorageBase //////////////////////////////
+
+TYPEINIT0( StorageBase );
+TYPEINIT1( BaseStorageStream, StorageBase );
+TYPEINIT1( BaseStorage, StorageBase );
+
+StorageBase::StorageBase()
+ : m_bAutoCommit( FALSE )
+{
+ m_nMode = STREAM_READ;
+ m_nError = SVSTREAM_OK;
+}
+
+StorageBase::~StorageBase()
+{
+}
+
+// The following three methods are declared as const, since they
+// may be called from within a const method.
+
+ULONG StorageBase::GetError() const
+{
+ ULONG n = m_nError;
+ ((StorageBase*) this)->m_nError = SVSTREAM_OK;
+ return n;
+}
+
+void StorageBase::SetError( ULONG n ) const
+{
+ if( !m_nError )
+ ((StorageBase*) this)->m_nError = n;
+}
+
+void StorageBase::ResetError() const
+{
+ ((StorageBase*) this)->m_nError = SVSTREAM_OK;
+}
+
+// Retrieve the underlying SvStream for info purposes
+
+const SvStream* OLEStorageBase::GetSvStream_Impl() const
+{
+ return pIo ? pIo->GetStrm() : NULL;
+}
+
+OLEStorageBase::OLEStorageBase( StgIo* p, StgDirEntry* pe, StreamMode& nMode )
+ : nStreamMode( nMode ), pIo( p ), pEntry( pe )
+{
+ p->IncRef();
+ if( pe )
+ pe->nRefCnt++;
+}
+
+OLEStorageBase::~OLEStorageBase()
+{
+ if( pEntry )
+ {
+ DBG_ASSERT( pEntry->nRefCnt, "RefCount unter 0" );
+ if( !--pEntry->nRefCnt )
+ {
+ if( pEntry->bZombie )
+ delete pEntry;
+ else
+ pEntry->Close();
+ }
+ }
+
+
+ if( !pIo->DecRef() )
+ delete pIo;
+}
+
+// Validate the instance for I/O
+
+BOOL OLEStorageBase::Validate_Impl( BOOL bWrite ) const
+{
+ if( pEntry
+ && !pEntry->bInvalid
+ && ( !bWrite || !pEntry->bDirect || ( nStreamMode & STREAM_WRITE ) ) )
+ return TRUE;
+ return FALSE;
+}
+
+BOOL OLEStorageBase::ValidateMode_Impl( StreamMode m, StgDirEntry* p ) const
+{
+ if( m == INTERNAL_MODE )
+ return TRUE;
+ USHORT nCurMode = ( p && p->nRefCnt ) ? p->nMode : 0xFFFF;
+ if( ( m & 3 ) == STREAM_READ )
+ {
+ // only SHARE_DENYWRITE or SHARE_DENYALL allowed
+ if( ( ( m & STREAM_SHARE_DENYWRITE )
+ && ( nCurMode & STREAM_SHARE_DENYWRITE ) )
+ || ( ( m & STREAM_SHARE_DENYALL )
+ && ( nCurMode & STREAM_SHARE_DENYALL ) ) )
+ return TRUE;
+ }
+ else
+ {
+ // only SHARE_DENYALL allowed
+ // storages open in r/o mode are OK, since only
+ // the commit may fail
+ if( ( m & STREAM_SHARE_DENYALL )
+ && ( nCurMode & STREAM_SHARE_DENYALL ) )
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+//////////////////////// class StorageStream /////////////////////////////
+
+TYPEINIT1( StorageStream, BaseStorageStream );
+
+StorageStream::StorageStream( StgIo* p, StgDirEntry* q, StreamMode m )
+ : OLEStorageBase( p, q, m_nMode ), nPos( 0L )
+{
+ // The dir entry may be 0; this means that the stream is invalid.
+ if( q )
+ {
+ if( q->nRefCnt == 1 )
+ {
+ q->nMode = m;
+ q->OpenStream( *p );
+ }
+ }
+ else
+ m &= ~STREAM_READWRITE;
+ m_nMode = m;
+}
+
+StorageStream::~StorageStream()
+{
+ // Do an auto-commit if the entry is open in direct mode
+ if( m_bAutoCommit )
+ Commit();
+ if( pEntry && pEntry->nRefCnt && pEntry->bDirect && (m_nMode & STREAM_WRITE) )
+ pEntry->Commit();
+}
+
+BOOL StorageStream::Equals( const BaseStorageStream& rStream ) const
+{
+ const StorageStream* pOther = PTR_CAST( StorageStream, &rStream );
+ return pOther && ( pOther->pEntry == pEntry );
+}
+
+ULONG StorageStream::Read( void* pData, ULONG nSize )
+{
+ if( Validate() )
+ {
+ pEntry->Seek( nPos );
+ nSize = pEntry->Read( pData, (INT32) nSize );
+ pIo->MoveError( *this );
+ nPos += nSize;
+ }
+ else
+ nSize = 0L;
+ return nSize;
+}
+
+ULONG StorageStream::Write( const void* pData, ULONG nSize )
+{
+ if( Validate( TRUE ) )
+ {
+ pEntry->Seek( nPos );
+ nSize = pEntry->Write( pData, (INT32) nSize );
+ pIo->MoveError( *this );
+ nPos += nSize;
+ }
+ else
+ nSize = 0L;
+ return nSize;
+}
+
+ULONG StorageStream::Seek( ULONG n )
+{
+ if( Validate() )
+ return nPos = pEntry->Seek( n );
+ else
+ return n;
+}
+
+void StorageStream::Flush()
+{
+ // Flushing means committing, since streams are never transacted
+ Commit();
+}
+
+BOOL StorageStream::SetSize( ULONG nNewSize )
+{
+ if( Validate( TRUE ) )
+ {
+ BOOL b = pEntry->SetSize( (INT32) nNewSize );
+ pIo->MoveError( *this );
+ return b;
+ }
+ else
+ return FALSE;
+}
+
+BOOL StorageStream::Commit()
+{
+ if( !Validate() )
+ return FALSE;
+ if( !( m_nMode & STREAM_WRITE ) )
+ {
+ SetError( SVSTREAM_ACCESS_DENIED );
+ return FALSE;
+ }
+ else
+ {
+ pEntry->Commit();
+ pIo->MoveError( *this );
+ return Good();
+ }
+}
+
+BOOL StorageStream::Revert()
+{
+ pEntry->Revert();
+ pIo->MoveError( *this );
+ return Good();
+}
+
+BOOL StorageStream::CopyTo( BaseStorageStream* pDest )
+{
+ if( !Validate() || !pDest->Validate( TRUE ) || Equals( *pDest ) )
+ return FALSE;
+ pEntry->Copy( *pDest );
+ pDest->Commit();
+ pIo->MoveError( *this );
+ SetError( pDest->GetError() );
+ return BOOL( Good() && pDest->Good() );
+}
+
+const SvStream* StorageStream::GetSvStream() const
+{
+ return GetSvStream_Impl();
+}
+
+BOOL StorageStream::Validate( BOOL bValidate ) const
+{
+ BOOL bRet = Validate_Impl( bValidate );
+ if ( !bRet )
+ SetError( SVSTREAM_ACCESS_DENIED );
+ return bRet;
+}
+
+BOOL StorageStream::ValidateMode( StreamMode nMode ) const
+{
+ BOOL bRet = ValidateMode_Impl( nMode, NULL );
+ if ( !bRet )
+ SetError( SVSTREAM_ACCESS_DENIED );
+ return bRet;
+}
+
+BOOL StorageStream::ValidateMode( StreamMode nMode, StgDirEntry* p ) const
+{
+ BOOL bRet = ValidateMode_Impl( nMode, p );
+ if ( !bRet )
+ SetError( SVSTREAM_ACCESS_DENIED );
+ return bRet;
+}
+
+///////////////////////// class SvStorageInfo //////////////////////////////
+
+SvStorageInfo::SvStorageInfo( const StgDirEntry& rE )
+{
+ rE.aEntry.GetName( aName );
+ bStorage = BOOL( rE.aEntry.GetType() == STG_STORAGE );
+ bStream = BOOL( rE.aEntry.GetType() == STG_STREAM );
+ nSize = bStorage ? 0 : rE.aEntry.GetSize();
+}
+
+/////////////////////////// class Storage ////////////////////////////////
+
+BOOL Storage::IsStorageFile( const String & rFileName )
+{
+ StgIo aIo;
+ if( aIo.Open( rFileName, STREAM_STD_READ ) )
+ return aIo.Load();
+ return FALSE;
+}
+
+BOOL Storage::IsStorageFile( SvStream* pStream )
+{
+ StgHeader aHdr;
+ ULONG nPos = pStream->Tell();
+ BOOL bRet = ( aHdr.Load( *pStream ) && aHdr.Check() );
+
+ // It's not a stream error if it is too small for a OLE storage header
+ if ( pStream->GetErrorCode() == ERRCODE_IO_CANTSEEK )
+ pStream->ResetError();
+ pStream->Seek( nPos );
+ return bRet;
+}
+
+// Open the storage file. If writing is permitted and the file is not
+// a storage file, initialize it.
+
+TYPEINIT1( Storage, BaseStorage );
+
+Storage::Storage( const String& rFile, StreamMode m, BOOL bDirect )
+ : OLEStorageBase( new StgIo, NULL, m_nMode ), aName( rFile ), bIsRoot( FALSE )
+{
+ BOOL bTemp = FALSE;
+ if( !aName.Len() )
+ {
+ // no name = temporary name!
+ aName = TempFile::CreateTempName();
+ bTemp = TRUE;
+ }
+ // the root storage creates the I/O system
+ m_nMode = m;
+ if( pIo->Open( aName, m ) )
+ {
+ Init( BOOL( ( m & ( STREAM_TRUNC | STREAM_NOCREATE ) ) == STREAM_TRUNC ) );
+ if( pEntry )
+ {
+ pEntry->bDirect = bDirect;
+ pEntry->nMode = m;
+ pEntry->bTemp = bTemp;
+ }
+ }
+ else
+ {
+ pIo->MoveError( *this );
+ pEntry = NULL;
+ }
+}
+
+// Create a storage on a given stream.
+
+Storage::Storage( SvStream& r, BOOL bDirect )
+ : OLEStorageBase( new StgIo, NULL, m_nMode ), bIsRoot( FALSE )
+{
+ m_nMode = STREAM_READ;
+ if( r.IsWritable() )
+ m_nMode = STREAM_READ | STREAM_WRITE;
+ if( r.GetError() == SVSTREAM_OK )
+ {
+ pIo->SetStrm( &r, FALSE );
+ ULONG nSize = r.Seek( STREAM_SEEK_TO_END );
+ r.Seek( 0L );
+ // Initializing is OK if the stream is empty
+ Init( BOOL( nSize == 0 ) );
+ if( pEntry )
+ {
+ pEntry->bDirect = bDirect;
+ pEntry->nMode = m_nMode;
+ }
+ pIo->MoveError( *this );
+ }
+ else
+ {
+ SetError( r.GetError() );
+ pEntry = NULL;
+ }
+}
+
+
+Storage::Storage( UCBStorageStream& rStrm, BOOL bDirect )
+ : OLEStorageBase( new StgIo, NULL, m_nMode ), bIsRoot( FALSE )
+{
+ m_nMode = STREAM_READ;
+
+ if ( rStrm.GetError() != SVSTREAM_OK )
+ {
+ SetError( rStrm.GetError() );
+ pEntry = NULL;
+ return;
+ }
+
+ SvStream* pStream = rStrm.GetModifySvStream();
+ if ( !pStream )
+ {
+ OSL_ENSURE( FALSE, "UCBStorageStream can not provide SvStream implementation!\n" );
+ SetError( SVSTREAM_GENERALERROR );
+ pEntry = NULL;
+ return;
+ }
+
+ if( pStream->IsWritable() )
+ m_nMode = STREAM_READ | STREAM_WRITE;
+
+ pIo->SetStrm( &rStrm );
+
+ ULONG nSize = pStream->Seek( STREAM_SEEK_TO_END );
+ pStream->Seek( 0L );
+ // Initializing is OK if the stream is empty
+ Init( BOOL( nSize == 0 ) );
+ if( pEntry )
+ {
+ pEntry->bDirect = bDirect;
+ pEntry->nMode = m_nMode;
+ }
+
+ pIo->MoveError( *this );
+}
+
+
+// Perform common code for both ctors above.
+
+void Storage::Init( BOOL bCreate )
+{
+ pEntry = NULL;
+ BOOL bHdrLoaded = FALSE;
+ bIsRoot = TRUE;
+ if( pIo->Good() )
+ {
+ ULONG nSize = pIo->GetStrm()->Seek( STREAM_SEEK_TO_END );
+ pIo->GetStrm()->Seek( 0L );
+ if( nSize )
+ {
+ bHdrLoaded = pIo->Load();
+ if( !bHdrLoaded && !bCreate )
+ {
+ // File is not a storage and not empty; do not destroy!
+ SetError( SVSTREAM_FILEFORMAT_ERROR );
+ return;
+ }
+ }
+ }
+ // file is a storage, empty or should be overwritten
+ pIo->ResetError();
+ // we have to set up the data structures, since
+ // the file is empty
+ if( !bHdrLoaded )
+ pIo->Init();
+ if( pIo->Good() )
+ {
+ pEntry = pIo->pTOC->GetRoot();
+ pEntry->nRefCnt++;
+ }
+}
+
+// Internal ctor
+
+Storage::Storage( StgIo* p, StgDirEntry* q, StreamMode m )
+ : OLEStorageBase( p, q, m_nMode ), bIsRoot( FALSE )
+{
+ if( q )
+ q->aEntry.GetName( aName );
+ else
+ m &= ~STREAM_READWRITE;
+ m_nMode = m;
+ if( q && q->nRefCnt == 1 )
+ q->nMode = m;
+}
+
+Storage::~Storage()
+{
+ // Invalidate all open substorages
+ if( m_bAutoCommit )
+ Commit();
+ if( pEntry )
+ {
+ // Do an auto-commit if the entry is open in direct mode
+ if( pEntry->nRefCnt && pEntry->bDirect && (m_nMode & STREAM_WRITE) )
+ Commit();
+ if( pEntry->nRefCnt == 1 )
+ pEntry->Invalidate();
+ }
+ // close the stream is root storage
+ if( bIsRoot )
+ pIo->Close();
+ // remove the file if temporary root storage
+ if( bIsRoot && pEntry && pEntry->bTemp )
+ {
+ osl::File::remove( GetName() );
+ }
+}
+
+const String& Storage::GetName() const
+{
+ if( !bIsRoot && Validate() )
+ pEntry->aEntry.GetName( ((Storage*) this)->aName );
+ return aName;
+}
+
+// Fill in the info list for this storage
+
+void Storage::FillInfoList( SvStorageInfoList* pList ) const
+{
+ if( Validate() )
+ {
+ StgIterator aIter( *pEntry );
+ StgDirEntry* p = aIter.First();
+ while( p )
+ {
+ if( !p->bInvalid )
+ {
+ SvStorageInfo aInfo( *p );
+ pList->Append( aInfo );
+ }
+ p = aIter.Next();
+ }
+ }
+}
+
+// Open or create a substorage
+
+BaseStorage* Storage::OpenUCBStorage( const String& rName, StreamMode m, BOOL bDirect )
+{
+ DBG_ERROR("Not supported!");
+/*
+ BaseStorage* pStorage = new Storage( pIo, NULL, m );
+ SetError( ERRCODE_IO_NOTSUPPORTED );
+ return pStorage;
+ */
+ return OpenStorage( rName, m, bDirect );
+}
+
+BaseStorage* Storage::OpenOLEStorage( const String& rName, StreamMode m, BOOL bDirect )
+{
+ return OpenStorage( rName, m, bDirect );
+}
+
+BaseStorage* Storage::OpenStorage( const String& rName, StreamMode m, BOOL bDirect )
+{
+ if( !Validate() || !ValidateMode( m ) )
+ return new Storage( pIo, NULL, m );
+ BOOL bSetAutoCommit = FALSE;
+ if( bDirect && !pEntry->bDirect )
+ {
+ bSetAutoCommit = TRUE;
+ bDirect = FALSE;
+ }
+
+ StgDirEntry* p = pIo->pTOC->Find( *pEntry, rName );
+ if( !p )
+ {
+ if( !( m & STREAM_NOCREATE ) )
+ {
+ BOOL bTemp = FALSE;
+ // create a new storage
+ String aNewName = rName;
+ if( !aNewName.Len() )
+ {
+ aNewName.AssignAscii( "Temp Stg " );
+ aNewName.Append( String::CreateFromInt32( ++nTmpCount ) );
+ bTemp = TRUE;
+ }
+ p = pIo->pTOC->Create( *pEntry, aNewName, STG_STORAGE );
+ if( p )
+ p->bTemp = bTemp;
+ }
+ if( !p )
+ pIo->SetError( ( m & STREAM_WRITE )
+ ? SVSTREAM_CANNOT_MAKE : SVSTREAM_FILE_NOT_FOUND );
+ }
+ else if( !ValidateMode( m, p ) )
+ p = NULL;
+ if( p && p->aEntry.GetType() != STG_STORAGE )
+ {
+ pIo->SetError( SVSTREAM_FILE_NOT_FOUND );
+ p = NULL;
+ }
+
+ // Either direct or transacted mode is supported
+ if( p && pEntry->nRefCnt == 1 )
+ p->bDirect = bDirect;
+
+ // Dont check direct conflict if opening readonly
+ if( p && (m & STREAM_WRITE ))
+ {
+ if( p->bDirect != bDirect )
+ SetError( SVSTREAM_ACCESS_DENIED );
+ }
+ Storage* pStg = new Storage( pIo, p, m );
+ pIo->MoveError( *pStg );
+ if( m & STREAM_WRITE ) pStg->m_bAutoCommit = TRUE;
+ return pStg;
+}
+
+// Open a stream
+
+BaseStorageStream* Storage::OpenStream( const String& rName, StreamMode m, BOOL,
+const ByteString*
+#ifdef DBG_UTIL
+pB
+#endif
+)
+{
+ DBG_ASSERT(!pB, "Encryption not supported");
+
+ if( !Validate() || !ValidateMode( m ) )
+ return new StorageStream( pIo, NULL, m );
+ StgDirEntry* p = pIo->pTOC->Find( *pEntry, rName );
+ BOOL bTemp = FALSE;
+ if( !p )
+ {
+ if( !( m & STREAM_NOCREATE ) )
+ {
+ // create a new stream
+ // make a name if the stream is temporary (has no name)
+ String aNewName( rName );
+ if( !aNewName.Len() )
+ {
+ aNewName.AssignAscii( "Temp Strm " );
+ aNewName.Append( String::CreateFromInt32( ++nTmpCount ) );
+ bTemp = TRUE;
+ }
+ p = pIo->pTOC->Create( *pEntry, aNewName, STG_STREAM );
+ }
+ if( !p )
+ pIo->SetError( ( m & STREAM_WRITE )
+ ? SVSTREAM_CANNOT_MAKE : SVSTREAM_FILE_NOT_FOUND );
+ }
+ else if( !ValidateMode( m, p ) )
+ p = NULL;
+ if( p && p->aEntry.GetType() != STG_STREAM )
+ {
+ pIo->SetError( SVSTREAM_FILE_NOT_FOUND );
+ p = NULL;
+ }
+ if( p )
+ {
+ p->bTemp = bTemp;
+ p->bDirect = pEntry->bDirect;
+ }
+ StorageStream* pStm = new StorageStream( pIo, p, m );
+ if( p && !p->bDirect )
+ pStm->SetAutoCommit( TRUE );
+ pIo->MoveError( *pStm );
+ return pStm;
+}
+
+// Delete a stream or substorage by setting the temp bit.
+
+BOOL Storage::Remove( const String& rName )
+{
+ if( !Validate( TRUE ) )
+ return FALSE;
+ StgDirEntry* p = pIo->pTOC->Find( *pEntry, rName );
+ if( p )
+ {
+ p->Invalidate( TRUE );
+ return TRUE;
+ }
+ else
+ {
+ SetError( SVSTREAM_FILE_NOT_FOUND );
+ return FALSE;
+ }
+}
+
+// Rename a storage element
+
+BOOL Storage::Rename( const String& rOld, const String& rNew )
+{
+ if( Validate( TRUE ) )
+ {
+ BOOL b = pIo->pTOC->Rename( *pEntry, rOld, rNew );
+ pIo->MoveError( *this );
+ return b;
+ }
+ else
+ return FALSE;
+}
+
+// Copy one element
+
+BOOL Storage::CopyTo( const String& rElem, BaseStorage* pDest, const String& rNew )
+{
+ if( !Validate() || !pDest || !pDest->Validate( TRUE ) )
+ return FALSE;
+ StgDirEntry* pElem = pIo->pTOC->Find( *pEntry, rElem );
+ if( pElem )
+ {
+ /*
+ this lines are misterious !!! MM
+ if( !pElem->IsContained( pDest->pEntry ) )
+ {
+ SetError( SVSTREAM_ACCESS_DENIED );
+ return FALSE;
+ }
+ */
+ if( pElem->aEntry.GetType() == STG_STORAGE )
+ {
+ // copy the entire storage
+ BaseStorage* p1 = OpenStorage( rElem, INTERNAL_MODE );
+ BaseStorage* p2 = pDest->OpenOLEStorage( rNew, STREAM_WRITE | STREAM_SHARE_DENYALL, pEntry->bDirect );
+
+ ULONG nTmpErr = p2->GetError();
+ if( !nTmpErr )
+ {
+ p2->SetClassId( p1->GetClassId() );
+ p1->CopyTo( p2 );
+ SetError( p1->GetError() );
+
+ nTmpErr = p2->GetError();
+ if( !nTmpErr )
+ p2->Commit();
+ else
+ pDest->SetError( nTmpErr );
+ }
+ else
+ pDest->SetError( nTmpErr );
+
+ delete p1;
+ delete p2;
+ return BOOL( Good() && pDest->Good() );
+ }
+ else
+ {
+ // stream copy
+ BaseStorageStream* p1 = OpenStream( rElem, INTERNAL_MODE );
+ BaseStorageStream* p2 = pDest->OpenStream( rNew, STREAM_WRITE | STREAM_SHARE_DENYALL, pEntry->bDirect );
+
+ ULONG nTmpErr = p2->GetError();
+ if( !nTmpErr )
+ {
+ p1->CopyTo( p2 );
+ SetError( p1->GetError() );
+
+ nTmpErr = p2->GetError();
+ if( !nTmpErr )
+ p2->Commit();
+ else
+ pDest->SetError( nTmpErr );
+ }
+ else
+ pDest->SetError( nTmpErr );
+
+ delete p1;
+ delete p2;
+ return BOOL( Good() && pDest->Good() );
+ }
+ }
+ SetError( SVSTREAM_FILE_NOT_FOUND );
+ return FALSE;
+}
+
+BOOL Storage::CopyTo( BaseStorage* pDest ) const
+{
+ if( !Validate() || !pDest || !pDest->Validate( TRUE ) || Equals( *pDest ) )
+ {
+ SetError( SVSTREAM_ACCESS_DENIED );
+ return FALSE;
+ }
+ Storage* pThis = (Storage*) this;
+ /*
+ if( !pThis->pEntry->IsContained( pDest->pEntry ) )
+ {
+ SetError( SVSTREAM_ACCESS_DENIED );
+ return FALSE;
+ }
+ */
+ pDest->SetClassId( GetClassId() );
+ pDest->SetDirty();
+ SvStorageInfoList aList;
+ FillInfoList( &aList );
+ BOOL bRes = TRUE;
+ for( USHORT i = 0; i < aList.Count() && bRes; i++ )
+ {
+ SvStorageInfo& rInfo = aList.GetObject( i );
+ bRes = pThis->CopyTo( rInfo.GetName(), pDest, rInfo.GetName() );
+ }
+ if( !bRes )
+ SetError( pDest->GetError() );
+ return BOOL( Good() && pDest->Good() );
+}
+
+// Move one element
+
+BOOL Storage::MoveTo( const String& rElem, BaseStorage* pODest, const String& rNew )
+{
+ if( !Validate() || !pODest || !pODest->Validate( TRUE ) || Equals( *pODest ) )
+ {
+ SetError( SVSTREAM_ACCESS_DENIED );
+ return FALSE;
+ }
+
+ StgDirEntry* pElem = pIo->pTOC->Find( *pEntry, rElem );
+ if( pElem )
+ {
+ // Simplest case: both storages share the same file
+ BOOL bRes;
+ Storage *pOther = PTR_CAST( Storage, pODest );
+ if( pOther && pIo == pOther->pIo && rElem == rNew )
+ {
+ Storage *p = (Storage*) pODest;
+ Storage *pDest = p;
+ // both storages are conventional storages, use implementation dependent code
+ if( !pElem->IsContained( pDest->pEntry ) )
+ {
+ // cyclic move
+ SetError( SVSTREAM_ACCESS_DENIED );
+ return FALSE;
+ }
+ bRes = pIo->pTOC->Move( *pEntry, *pDest->pEntry, rNew );
+ if( !bRes )
+ {
+ pIo->MoveError( *this );
+ pDest->pIo->MoveError( *pDest );
+ ULONG nErr = GetError();
+ if( !nErr )
+ nErr = pDest->GetError();
+ SetError( nErr );
+ pDest->SetError( nErr );
+ }
+ }
+ else
+ {
+ bRes = CopyTo( rElem, pODest, rNew );
+ if( bRes )
+ bRes = Remove( rElem );
+ }
+ if( !bRes )
+ SetError( pIo->GetError() );
+ return bRes;
+ }
+ SetError( SVSTREAM_FILE_NOT_FOUND );
+ return FALSE;
+}
+
+BOOL Storage::IsStorage( const String& rName ) const
+{
+ if( Validate() )
+ {
+ StgDirEntry* p = pIo->pTOC->Find( *pEntry, rName );
+ if( p )
+ return BOOL( p->aEntry.GetType() == STG_STORAGE );
+ }
+ return FALSE;
+}
+
+BOOL Storage::IsStream( const String& rName ) const
+{
+ if( Validate() )
+ {
+ StgDirEntry* p = pIo->pTOC->Find( *pEntry, rName );
+ if( p )
+ return BOOL( p->aEntry.GetType() == STG_STREAM );
+ }
+ return FALSE;
+}
+
+BOOL Storage::IsContained( const String& rName ) const
+{
+ if( Validate() )
+ return BOOL( pIo->pTOC->Find( *pEntry, rName ) != NULL );
+ else
+ return FALSE;
+}
+
+// Commit all sub-elements within this storage. If this is
+// the root, commit the FAT, the TOC and the header as well.
+
+BOOL Storage::Commit()
+{
+ BOOL bRes = TRUE;
+ if( !Validate() )
+ return FALSE;
+ if( !( m_nMode & STREAM_WRITE ) )
+ {
+ SetError( SVSTREAM_ACCESS_DENIED );
+ return FALSE;
+ }
+ else
+ {
+ // Also commit the sub-streams and Storages
+ StgIterator aIter( *pEntry );
+ for( StgDirEntry* p = aIter.First(); p && bRes; p = aIter.Next() )
+ bRes = p->Commit();
+ if( bRes && bIsRoot )
+ {
+ bRes = pEntry->Commit();
+ if( bRes )
+ bRes = pIo->CommitAll();
+ }
+ pIo->MoveError( *this );
+ }
+ return bRes;
+}
+
+BOOL Storage::Revert()
+{
+ return TRUE;
+}
+
+///////////////////////////// OLE Support ////////////////////////////////
+
+// Set the storage type
+
+void Storage::SetClass( const SvGlobalName & rClass,
+ ULONG nOriginalClipFormat,
+ const String & rUserTypeName )
+{
+ if( Validate( TRUE ) )
+ {
+ // set the class name in the root entry
+ pEntry->aEntry.SetClassId( (const ClsId&) rClass.GetCLSID() );
+ pEntry->SetDirty();
+ // then create the streams
+ StgCompObjStream aCompObj( *this, TRUE );
+ aCompObj.GetClsId() = (const ClsId&) rClass.GetCLSID();
+ aCompObj.GetCbFormat() = nOriginalClipFormat;
+ aCompObj.GetUserName() = rUserTypeName;
+ if( !aCompObj.Store() )
+ SetError( aCompObj.GetError() );
+ else
+ {
+ StgOleStream aOle( *this, STREAM_WRITE );
+ if( !aOle.Store() )
+ SetError( aOle.GetError() );
+ }
+ }
+ else
+ SetError( SVSTREAM_ACCESS_DENIED );
+}
+
+void Storage::SetConvertClass( const SvGlobalName & rConvertClass,
+ ULONG nOriginalClipFormat,
+ const String & rUserTypeName )
+{
+ if( Validate( TRUE ) )
+ {
+ SetClass( rConvertClass, nOriginalClipFormat, rUserTypeName );
+ // plus the convert flag:
+ StgOleStream aOle( *this, TRUE );
+ aOle.GetFlags() |= 4;
+ if( !aOle.Store() )
+ SetError( aOle.GetError() );
+ }
+}
+
+SvGlobalName Storage::GetClassName()
+{
+ StgCompObjStream aCompObj( *this, FALSE );
+ if( aCompObj.Load() )
+ return SvGlobalName( (const CLSID&) aCompObj.GetClsId() );
+ pIo->ResetError();
+
+ if ( pEntry )
+ return SvGlobalName( (const CLSID&) pEntry->aEntry.GetClassId() );
+
+ return SvGlobalName();
+}
+
+ULONG Storage::GetFormat()
+{
+ StgCompObjStream aCompObj( *this, FALSE );
+ if( aCompObj.Load() )
+ return aCompObj.GetCbFormat();
+ pIo->ResetError();
+ return 0;
+}
+
+String Storage::GetUserName()
+{
+ StgCompObjStream aCompObj( *this, FALSE );
+ if( aCompObj.Load() )
+ return aCompObj.GetUserName();
+ pIo->ResetError();
+ return String();
+}
+
+BOOL Storage::ShouldConvert()
+{
+ StgOleStream aOle( *this, FALSE );
+ if( aOle.Load() )
+ return BOOL( ( aOle.GetFlags() & 4 ) != 0 );
+ else
+ {
+ pIo->ResetError();
+ return FALSE;
+ }
+}
+
+BOOL Storage::ValidateFAT()
+{
+ Link aLink = StgIo::GetErrorLink();
+ ErrCode nErr = pIo->ValidateFATs();
+ StgIo::SetErrorLink( aLink );
+ return nErr == ERRCODE_NONE;
+}
+
+void Storage::SetDirty()
+{
+ pEntry->SetDirty();
+}
+
+void Storage::SetClassId( const ClsId& rId )
+{
+ pEntry->aEntry.SetClassId( rId );
+}
+
+const ClsId& Storage::GetClassId() const
+{
+ return pEntry->aEntry.GetClassId();
+}
+
+const SvStream* Storage::GetSvStream() const
+{
+ return GetSvStream_Impl();
+}
+
+BOOL Storage::Validate( BOOL bValidate ) const
+{
+ BOOL bRet = Validate_Impl( bValidate );
+ if ( !bRet )
+ SetError( SVSTREAM_ACCESS_DENIED );
+ return bRet;
+}
+
+BOOL Storage::ValidateMode( StreamMode nMode ) const
+{
+ BOOL bRet = ValidateMode_Impl( nMode );
+ if ( !bRet )
+ SetError( SVSTREAM_ACCESS_DENIED );
+ return bRet;
+}
+
+BOOL Storage::ValidateMode( StreamMode nMode, StgDirEntry* p ) const
+{
+ BOOL bRet = ValidateMode_Impl( nMode, p );
+ if ( !bRet )
+ SetError( SVSTREAM_ACCESS_DENIED );
+ return bRet;
+}
+
+BOOL Storage::Equals( const BaseStorage& rStorage ) const
+{
+ const Storage* pOther = PTR_CAST( Storage, &rStorage );
+ return pOther && ( pOther->pEntry == pEntry );
+}
+
+
diff --git a/sot/source/sdstor/stgavl.cxx b/sot/source/sdstor/stgavl.cxx
new file mode 100644
index 000000000000..3542a965da33
--- /dev/null
+++ b/sot/source/sdstor/stgavl.cxx
@@ -0,0 +1,419 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sot.hxx"
+
+
+#include "stgavl.hxx"
+
+StgAvlNode::StgAvlNode()
+{
+ pLeft = pRight = NULL;
+ nBalance = nId = 0;
+}
+
+StgAvlNode::~StgAvlNode()
+{
+ delete pLeft;
+ delete pRight;
+}
+
+StgAvlNode* StgAvlNode::Find( StgAvlNode* pFind )
+{
+ StgAvlNode* p = this;
+ while( p )
+ {
+ short nRes = p->Compare( pFind );
+ if( !nRes )
+ return p;
+ else p = ( nRes < 0 ) ? p->pLeft : p->pRight;
+ }
+ return NULL;
+}
+
+// find point to add node to AVL tree and returns
+// +/0/- for >/=/< previous
+
+short StgAvlNode::Locate
+ ( StgAvlNode* pFind,
+ StgAvlNode** pPivot, StgAvlNode **pParent, StgAvlNode** pPrev )
+{
+ short nRes = 0;
+ StgAvlNode* pCur = this;
+ *pParent = *pPrev = NULL;
+ *pPivot = this;
+
+ // search tree for insertion point
+
+ while( pCur != NULL )
+ {
+ // check for pPivot
+ if( pCur->nBalance != 0 )
+ *pPivot = pCur, *pParent = *pPrev;
+ // save pPrev location and see what direction to go
+ *pPrev = pCur;
+ nRes = pCur->Compare( pFind );
+ if( nRes == 0 )
+ break;
+ else pCur = ( nRes < 0 ) ? pCur->pLeft : pCur->pRight;
+ }
+ return( nRes );
+}
+
+// adjust balance factors in AVL tree from pivot down.
+// Returns delta balance.
+
+short StgAvlNode::Adjust( StgAvlNode** pHeavy, StgAvlNode* pNew )
+{
+ StgAvlNode* pCur = this;
+ short nDelta;
+ // no traversing
+ if( pCur == pNew )
+ return nBalance;
+ short nRes = Compare( pNew );
+ if( nRes > 0 )
+ {
+ *pHeavy = pCur = pRight;
+ nDelta = -1;
+ }
+ else
+ {
+ *pHeavy = pCur = pLeft;
+ nDelta = 1;
+ }
+ nBalance = 0;
+ while( pCur != pNew )
+ {
+ nRes = pCur->Compare( pNew );
+ if( nRes > 0 )
+ {
+ // height of right increases by 1
+ pCur->nBalance = -1;
+ pCur = pCur->pRight;
+ }
+ else
+ {
+ // height of left increases by 1
+ pCur->nBalance = 1;
+ pCur = pCur->pLeft;
+ }
+ }
+ nBalance = nBalance + nDelta;
+ return nDelta;
+}
+
+// perform LL rotation and return new root
+
+StgAvlNode* StgAvlNode::RotLL()
+{
+ StgAvlNode *pHeavy = pLeft;
+ pLeft = pHeavy->pRight;
+ pHeavy->pRight = this;
+ pHeavy->nBalance = nBalance = 0;
+ return pHeavy;
+}
+
+// perform LR rotation and return new root
+
+StgAvlNode* StgAvlNode::RotLR()
+{
+
+ StgAvlNode* pHeavy = pLeft;
+ StgAvlNode* pNewRoot = pHeavy->pRight;
+
+ pHeavy->pRight = pNewRoot->pLeft;
+ pLeft = pNewRoot->pRight;
+ pNewRoot->pLeft = pHeavy;
+ pNewRoot->pRight = this;
+
+ switch( pNewRoot->nBalance )
+ {
+ case 1: // LR( b )
+ nBalance = -1;
+ pHeavy->nBalance = 0;
+ break;
+ case -1: // LR( c )
+ pHeavy->nBalance = 1;
+ nBalance = 0;
+ break;
+ case 0: // LR( a )
+ nBalance = 0;
+ pHeavy->nBalance = 0;
+ break;
+ }
+ pNewRoot->nBalance = 0;
+ return pNewRoot;
+}
+
+// perform RR rotation and return new root
+
+StgAvlNode* StgAvlNode::RotRR()
+{
+ StgAvlNode* pHeavy = pRight;
+ pRight = pHeavy->pLeft;
+ pHeavy->pLeft = this;
+ nBalance = pHeavy->nBalance = 0;
+ return pHeavy;
+}
+
+// perform the RL rotation and return the new root
+
+StgAvlNode* StgAvlNode::RotRL()
+{
+ StgAvlNode* pHeavy = pRight;
+ StgAvlNode* pNewRoot = pHeavy->pLeft;
+ pHeavy->pLeft = pNewRoot->pRight;
+ pRight = pNewRoot->pLeft;
+ pNewRoot->pRight = pHeavy;
+ pNewRoot->pLeft = this;
+ switch( pNewRoot->nBalance )
+ {
+ case -1: // RL( b )
+ nBalance = 1;
+ pHeavy->nBalance = 0;
+ break;
+ case 1: // RL( c )
+ pHeavy->nBalance = -1;
+ nBalance = 0;
+ break;
+ case 0: // RL( a )
+ nBalance = 0;
+ pHeavy->nBalance = 0;
+ break;
+ }
+ pNewRoot->nBalance = 0;
+ return pNewRoot;
+}
+
+// Remove a tree element. Return the removed element or NULL.
+
+StgAvlNode* StgAvlNode::Rem( StgAvlNode** p, StgAvlNode* pDel, BOOL bPtrs )
+{
+ if( *p )
+ {
+ StgAvlNode* pCur = *p;
+ short nRes = bPtrs ? short( pCur == pDel ) : short(pCur->Compare( pDel ));
+ if( !nRes )
+ {
+ // Element found: remove
+ if( !pCur->pRight )
+ {
+ *p = pCur->pLeft; pCur->pLeft = NULL;
+ }
+ else if( !pCur->pLeft )
+ {
+ *p = pCur->pRight; pCur->pRight = NULL;
+ }
+ else
+ {
+ // The damn element has two leaves. Get the
+ // rightmost element of the left subtree (which
+ // is lexically before this element) and replace
+ // this element with the element found.
+ StgAvlNode* last = pCur;
+ StgAvlNode* l;
+ for( l = pCur->pLeft;
+ l->pRight; last = l, l = l->pRight ) {}
+ // remove the element from chain
+ if( l == last->pRight )
+ last->pRight = l->pLeft;
+ else
+ last->pLeft = l->pLeft;
+ // perform the replacement
+ l->pLeft = pCur->pLeft;
+ l->pRight = pCur->pRight;
+ *p = l;
+ // delete the element
+ pCur->pLeft = pCur->pRight = NULL;
+ }
+ return pCur;
+ }
+ else
+ {
+ if( nRes < 0 )
+ return Rem( &pCur->pLeft, pDel, bPtrs );
+ else
+ return Rem( &pCur->pRight, pDel, bPtrs );
+ }
+ }
+ return NULL;
+}
+
+// Enumerate the tree for later iteration
+
+void StgAvlNode::StgEnum( short& n )
+{
+ if( this )
+ {
+ if( pLeft )
+ pLeft->StgEnum( n );
+ nId = n++;
+ if( pRight )
+ pRight->StgEnum( n );
+ }
+}
+
+// Add node to AVL tree.
+// Return FALSE if the element already exists.
+
+BOOL StgAvlNode::Insert( StgAvlNode** pRoot, StgAvlNode* pIns )
+{
+ StgAvlNode* pPivot, *pHeavy, *pNewRoot, *pParent, *pPrev;
+ // special case - empty tree
+ if( *pRoot == NULL )
+ {
+ *pRoot = pIns;
+ return TRUE;
+ }
+ // find insertion point and return if already present
+ short nRes = (*pRoot)->Locate( pIns, &pPivot, &pParent, &pPrev );
+ if( !nRes )
+ return FALSE;
+ // add new node
+ if( nRes < 0 )
+ pPrev->pLeft = pIns;
+ else
+ pPrev->pRight = pIns;
+ // rebalance tree
+ short nDelta = pPivot->Adjust( &pHeavy, pIns );
+ if( pPivot->nBalance >= 2 || pPivot->nBalance <= -2 )
+ {
+ pHeavy = ( nDelta < 0 ) ? pPivot->pRight : pPivot->pLeft;
+ // left imbalance
+ if( nDelta > 0 )
+ if( pHeavy->nBalance == 1 )
+ pNewRoot = pPivot->RotLL();
+ else
+ pNewRoot = pPivot->RotLR();
+ // right imbalance
+ else if( pHeavy->nBalance == -1 )
+ pNewRoot = pPivot->RotRR();
+ else
+ pNewRoot = pPivot->RotRL();
+ // relink balanced subtree
+ if( pParent == NULL )
+ *pRoot = pNewRoot;
+ else if( pPivot == pParent->pLeft )
+ pParent->pLeft = pNewRoot;
+ else if( pPivot == pParent->pRight )
+ pParent->pRight = pNewRoot;
+ }
+ return TRUE;
+}
+
+// Remove node from tree. Returns TRUE is found and removed.
+// Actually delete if bDel
+
+BOOL StgAvlNode::Remove( StgAvlNode** pRoot, StgAvlNode* pDel, BOOL bDel )
+{
+ // special case - empty tree
+ if( *pRoot == NULL )
+ return FALSE;
+ // delete the element
+ pDel = Rem( pRoot, pDel, FALSE );
+ if( pDel )
+ {
+ if( bDel )
+ delete pDel;
+ // Rebalance the tree the hard way
+ // OS 22.09.95: Auf MD's Wunsch auskommentiert wg. Absturz
+/* StgAvlNode* pNew = NULL;
+ while( *pRoot )
+ {
+ StgAvlNode* p = Rem( pRoot, *pRoot, FALSE );
+ Insert( &pNew, p );
+ }
+ *pRoot = pNew;*/
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+// Move node to a different tree. Returns TRUE is found and moved. This routine
+// may be called when the key has changed.
+
+BOOL StgAvlNode::Move
+ ( StgAvlNode** pRoot1, StgAvlNode** pRoot2, StgAvlNode* pMove )
+{
+ // special case - empty tree
+ if( *pRoot1 == NULL )
+ return FALSE;
+ pMove = Rem( pRoot1, pMove, FALSE );
+ if( pMove )
+ return Insert( pRoot2, pMove );
+ else
+ return FALSE;
+}
+
+////////////////////////// class AvlIterator /////////////////////////
+
+// The iterator walks through a tree one entry by one.
+
+StgAvlIterator::StgAvlIterator( StgAvlNode* p )
+{
+ pRoot = p;
+ nCount = 0;
+ if( p )
+ p->StgEnum( nCount );
+}
+
+StgAvlNode* StgAvlIterator::Find( short n )
+{
+ StgAvlNode* p = pRoot;
+ while( p )
+ {
+ if( n == p->nId )
+ break;
+ else p = ( n < p->nId ) ? p->pLeft : p->pRight;
+ }
+ return p;
+}
+
+StgAvlNode* StgAvlIterator::First()
+{
+ nCur = -1;
+ return Next();
+}
+
+StgAvlNode* StgAvlIterator::Last()
+{
+ nCur = nCount;
+ return Prev();
+}
+
+StgAvlNode* StgAvlIterator::Next()
+{
+ return Find( ++nCur );
+}
+
+StgAvlNode* StgAvlIterator::Prev()
+{
+ return Find( --nCur );
+}
+
diff --git a/sot/source/sdstor/stgavl.hxx b/sot/source/sdstor/stgavl.hxx
new file mode 100644
index 000000000000..66f424888e6d
--- /dev/null
+++ b/sot/source/sdstor/stgavl.hxx
@@ -0,0 +1,79 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _STGAVL_HXX
+#define _STGAVL_HXX
+
+#ifndef _TOOLS_SOLAR_H
+#include <tools/solar.h>
+#endif
+
+// This class must be overloaded to define real, living nodes.
+// Especially, the compare function must be implemented.
+
+class StgAvlNode
+{
+ friend class StgAvlIterator;
+private:
+ short Locate( StgAvlNode*, StgAvlNode**, StgAvlNode**, StgAvlNode** );
+ short Adjust( StgAvlNode**, StgAvlNode* );
+ StgAvlNode* RotLL();
+ StgAvlNode* RotLR();
+ StgAvlNode* RotRR();
+ StgAvlNode* RotRL();
+ void StgEnum( short& );
+ static StgAvlNode* Rem( StgAvlNode**, StgAvlNode*, BOOL );
+protected:
+ short nId; // iterator ID
+ short nBalance; // indicates tree balance
+ StgAvlNode* pLeft, *pRight; // leaves
+ StgAvlNode();
+public:
+ virtual ~StgAvlNode();
+ StgAvlNode* Find( StgAvlNode* );
+ static BOOL Insert( StgAvlNode**, StgAvlNode* );
+ static BOOL Remove( StgAvlNode**, StgAvlNode*, BOOL bDel = TRUE );
+ static BOOL Move( StgAvlNode**, StgAvlNode**, StgAvlNode* );
+ virtual short Compare( const StgAvlNode* ) const = 0;
+};
+
+// The iterator class provides single stepping through an AVL tree.
+
+class StgAvlIterator {
+ StgAvlNode* pRoot; // root entry (parent)
+ short nCount; // tree size
+ short nCur; // current element
+ StgAvlNode* Find( short );
+public:
+ StgAvlIterator( StgAvlNode* );
+ StgAvlNode* First();
+ StgAvlNode* Last();
+ StgAvlNode* Next();
+ StgAvlNode* Prev();
+};
+
+#endif
diff --git a/sot/source/sdstor/stgcache.cxx b/sot/source/sdstor/stgcache.cxx
new file mode 100644
index 000000000000..88a8187ee9dd
--- /dev/null
+++ b/sot/source/sdstor/stgcache.cxx
@@ -0,0 +1,546 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sot.hxx"
+
+#if defined(_MSC_VER) && (_MSC_VER<1200)
+#include <tools/presys.h>
+#endif
+#include <hash_map>
+#if defined(_MSC_VER) && (_MSC_VER<1200)
+#include <tools/postsys.h>
+#endif
+#include <vos/macros.hxx>
+
+#include <string.h>
+#include <osl/endian.h>
+#include <tools/string.hxx>
+
+#include "stg.hxx"
+#include "stgelem.hxx"
+#include "stgcache.hxx"
+#include "stgstrms.hxx"
+#include "stgdir.hxx"
+#include "stgio.hxx"
+
+/*************************************************************************/
+//-----------------------------------------------------------------------------
+typedef std::hash_map
+<
+ INT32,
+ StgPage *,
+ std::hash< INT32 >,
+ NAMESPACE_STD(equal_to)< INT32 >
+> UsrStgPagePtr_Impl;
+#ifdef _MSC_VER
+#pragma warning( disable: 4786 )
+#endif
+
+//#define CHECK_DIRTY 1
+//#define READ_AFTER_WRITE 1
+
+////////////////////////////// class StgPage /////////////////////////////
+// This class implements buffer functionality. The cache will always return
+// a page buffer, even if a read fails. It is up to the caller to determine
+// the correctness of the I/O.
+
+StgPage::StgPage( StgCache* p, short n )
+{
+ pCache = p;
+ nData = n;
+ bDirty = FALSE;
+ nPage = 0;
+ pData = new BYTE[ nData ];
+ pNext1 =
+ pNext2 =
+ pLast1 =
+ pLast2 = NULL;
+ pOwner = NULL;
+}
+
+StgPage::~StgPage()
+{
+ delete [] pData;
+}
+
+void StgPage::SetPage( short nOff, INT32 nVal )
+{
+ if( ( nOff < (short) ( nData / sizeof( INT32 ) ) ) && nOff >= 0 )
+ {
+#ifdef OSL_BIGENDIAN
+ nVal = SWAPLONG(nVal);
+#endif
+ ((INT32*) pData )[ nOff ] = nVal;
+ bDirty = TRUE;
+ }
+}
+
+//////////////////////////////// class StgCache ////////////////////////////
+
+// The disk cache holds the cached sectors. The sector type differ according
+// to their purpose.
+
+INT32 lcl_GetPageCount( ULONG nFileSize, short nPageSize )
+{
+// return (nFileSize >= 512) ? (nFileSize - 512) / nPageSize : 0;
+ // #i61980# reallife: last page may be incomplete, return number of *started* pages
+ return (nFileSize >= 512) ? (nFileSize - 512 + nPageSize - 1) / nPageSize : 0;
+}
+
+StgCache::StgCache()
+{
+ nRef = 0;
+ pStrm = NULL;
+ pCur = pElem1 = NULL;
+ nPageSize = 512;
+ nError = SVSTREAM_OK;
+ bMyStream = FALSE;
+ bFile = FALSE;
+ pLRUCache = NULL;
+ pStorageStream = NULL;
+}
+
+StgCache::~StgCache()
+{
+ Clear();
+ SetStrm( NULL, FALSE );
+ delete (UsrStgPagePtr_Impl*)pLRUCache;
+}
+
+void StgCache::SetPhysPageSize( short n )
+{
+ nPageSize = n;
+ ULONG nPos = pStrm->Tell();
+ ULONG nFileSize = pStrm->Seek( STREAM_SEEK_TO_END );
+ nPages = lcl_GetPageCount( nFileSize, nPageSize );
+ pStrm->Seek( nPos );
+}
+
+// Create a new cache element
+// pCur points to this element
+
+StgPage* StgCache::Create( INT32 nPg )
+{
+ StgPage* pElem = new StgPage( this, nPageSize );
+ pElem->nPage = nPg;
+ // For data security, clear the buffer contents
+ memset( pElem->pData, 0, pElem->nData );
+
+ // insert to LRU
+ if( pCur )
+ {
+ pElem->pNext1 = pCur;
+ pElem->pLast1 = pCur->pLast1;
+ pElem->pNext1->pLast1 =
+ pElem->pLast1->pNext1 = pElem;
+ }
+ else
+ pElem->pNext1 = pElem->pLast1 = pElem;
+ if( !pLRUCache )
+ pLRUCache = new UsrStgPagePtr_Impl();
+ (*(UsrStgPagePtr_Impl*)pLRUCache)[pElem->nPage] = pElem;
+ pCur = pElem;
+
+ // insert to Sorted
+ if( !pElem1 )
+ pElem1 = pElem->pNext2 = pElem->pLast2 = pElem;
+ else
+ {
+ StgPage* p = pElem1;
+ do
+ {
+ if( pElem->nPage < p->nPage )
+ break;
+ p = p->pNext2;
+ } while( p != pElem1 );
+ pElem->pNext2 = p;
+ pElem->pLast2 = p->pLast2;
+ pElem->pNext2->pLast2 =
+ pElem->pLast2->pNext2 = pElem;
+ if( p->nPage < pElem1->nPage )
+ pElem1 = pElem;
+ }
+ return pElem;
+}
+
+// Delete the given element
+
+void StgCache::Erase( StgPage* pElem )
+{
+ //remove from LRU
+ pElem->pNext1->pLast1 = pElem->pLast1;
+ pElem->pLast1->pNext1 = pElem->pNext1;
+ if( pCur == pElem )
+ pCur = ( pElem->pNext1 == pElem ) ? NULL : pElem->pNext1;
+ if( pLRUCache )
+ ((UsrStgPagePtr_Impl*)pLRUCache)->erase( pElem->nPage );
+ // remove from Sorted
+ pElem->pNext2->pLast2 = pElem->pLast2;
+ pElem->pLast2->pNext2 = pElem->pNext2;
+ if( pElem1 == pElem )
+ pElem1 = ( pElem->pNext2 == pElem ) ? NULL : pElem->pNext2;
+ delete pElem;
+}
+
+// remove all cache elements without flushing them
+
+void StgCache::Clear()
+{
+ StgPage* pElem = pCur;
+ if( pCur ) do
+ {
+ StgPage* pDelete = pElem;
+ pElem = pElem->pNext1;
+ delete pDelete;
+ }
+ while( pCur != pElem );
+ pCur = NULL;
+ pElem1 = NULL;
+ delete (UsrStgPagePtr_Impl*)pLRUCache;
+ pLRUCache = NULL;
+}
+
+// Look for a cached page
+
+StgPage* StgCache::Find( INT32 nPage )
+{
+ if( !pLRUCache )
+ return NULL;
+ UsrStgPagePtr_Impl::iterator aIt = ((UsrStgPagePtr_Impl*)pLRUCache)->find( nPage );
+ if( aIt != ((UsrStgPagePtr_Impl*)pLRUCache)->end() )
+ {
+ // page found
+ StgPage* pFound = (*aIt).second;
+
+ if( pFound != pCur )
+ {
+ // remove from LRU
+ pFound->pNext1->pLast1 = pFound->pLast1;
+ pFound->pLast1->pNext1 = pFound->pNext1;
+ // insert to LRU
+ pFound->pNext1 = pCur;
+ pFound->pLast1 = pCur->pLast1;
+ pFound->pNext1->pLast1 =
+ pFound->pLast1->pNext1 = pFound;
+ }
+ return pFound;
+ }
+ return NULL;
+}
+
+// Load a page into the cache
+
+StgPage* StgCache::Get( INT32 nPage, BOOL bForce )
+{
+ StgPage* p = Find( nPage );
+ if( !p )
+ {
+ p = Create( nPage );
+ if( !Read( nPage, p->pData, 1 ) && bForce )
+ {
+ Erase( p );
+ p = NULL;
+ SetError( SVSTREAM_READ_ERROR );
+ }
+ }
+ return p;
+}
+
+// Copy an existing page into a new page. Use this routine
+// to duplicate an existing stream or to create new entries.
+// The new page is initially marked dirty. No owner is copied.
+
+StgPage* StgCache::Copy( INT32 nNew, INT32 nOld )
+{
+ StgPage* p = Find( nNew );
+ if( !p )
+ p = Create( nNew );
+ if( nOld >= 0 )
+ {
+ // old page: we must have this data!
+ StgPage* q = Get( nOld, TRUE );
+ if( q )
+ memcpy( p->pData, q->pData, p->nData );
+ }
+ p->SetDirty();
+ return p;
+}
+
+// Flush the cache whose owner is given. NULL flushes all.
+
+BOOL StgCache::Commit( StgDirEntry* )
+{
+ StgPage* p = pElem1;
+ if( p ) do
+ {
+ if( p->bDirty )
+ {
+ BOOL b = Write( p->nPage, p->pData, 1 );
+ if( !b )
+ return FALSE;
+ p->bDirty = FALSE;
+ }
+ p = p->pNext2;
+ } while( p != pElem1 );
+ pStrm->Flush();
+ SetError( pStrm->GetError() );
+#ifdef CHECK_DIRTY
+ p = pElem1;
+ if( p ) do
+ {
+ if( p->bDirty )
+ {
+ ErrorBox( NULL, WB_OK, String("SO2: Dirty Block in Ordered List") ).Execute();
+ BOOL b = Write( p->nPage, p->pData, 1 );
+ if( !b )
+ return FALSE;
+ p->bDirty = FALSE;
+ }
+ p = p->pNext2;
+ } while( p != pElem1 );
+ p = pElem1;
+ if( p ) do
+ {
+ if( p->bDirty )
+ {
+ ErrorBox( NULL, WB_OK, String("SO2: Dirty Block in LRU List") ).Execute();
+ BOOL b = Write( p->nPage, p->pData, 1 );
+ if( !b )
+ return FALSE;
+ p->bDirty = FALSE;
+ }
+ p = p->pNext1;
+ } while( p != pElem1 );
+#endif
+ return TRUE;
+}
+
+void StgCache::Revert( StgDirEntry* )
+{}
+
+// Set a stream
+
+void StgCache::SetStrm( SvStream* p, BOOL bMy )
+{
+ if( pStorageStream )
+ {
+ pStorageStream->ReleaseRef();
+ pStorageStream = NULL;
+ }
+
+ if( bMyStream )
+ delete pStrm;
+ pStrm = p;
+ bMyStream = bMy;
+}
+
+void StgCache::SetStrm( UCBStorageStream* pStgStream )
+{
+ if( pStorageStream )
+ pStorageStream->ReleaseRef();
+ pStorageStream = pStgStream;
+
+ if( bMyStream )
+ delete pStrm;
+
+ pStrm = NULL;
+
+ if ( pStorageStream )
+ {
+ pStorageStream->AddRef();
+ pStrm = pStorageStream->GetModifySvStream();
+ }
+
+ bMyStream = FALSE;
+}
+
+// Open/close the disk file
+
+BOOL StgCache::Open( const String& rName, StreamMode nMode )
+{
+ // do not open in exclusive mode!
+ if( nMode & STREAM_SHARE_DENYALL )
+ nMode = ( ( nMode & ~STREAM_SHARE_DENYALL ) | STREAM_SHARE_DENYWRITE );
+ SvFileStream* pFileStrm = new SvFileStream( rName, nMode );
+ // SvStream "Feature" Write Open auch erfolgreich, wenns nicht klappt
+ BOOL bAccessDenied = FALSE;
+ if( ( nMode & STREAM_WRITE ) && !pFileStrm->IsWritable() )
+ {
+ pFileStrm->Close();
+ bAccessDenied = TRUE;
+ }
+ SetStrm( pFileStrm, TRUE );
+ if( pFileStrm->IsOpen() )
+ {
+ ULONG nFileSize = pStrm->Seek( STREAM_SEEK_TO_END );
+ nPages = lcl_GetPageCount( nFileSize, nPageSize );
+ pStrm->Seek( 0L );
+ }
+ else
+ nPages = 0;
+ bFile = TRUE;
+ SetError( bAccessDenied ? ERRCODE_IO_ACCESSDENIED : pStrm->GetError() );
+ return Good();
+}
+
+void StgCache::Close()
+{
+ if( bFile )
+ {
+ ((SvFileStream*) pStrm)->Close();
+ SetError( pStrm->GetError() );
+ }
+}
+
+// low level I/O
+
+BOOL StgCache::Read( INT32 nPage, void* pBuf, INT32 nPg )
+{
+ if( Good() )
+ {
+ /* #i73846# real life: a storage may refer to a page one-behind the
+ last valid page (see document attached to the issue). In that case
+ (if nPage==nPages), just do nothing here and let the caller work on
+ the empty zero-filled buffer. */
+ if ( nPage > nPages )
+ SetError( SVSTREAM_READ_ERROR );
+ else if ( nPage < nPages )
+ {
+ ULONG nPos = Page2Pos( nPage );
+ INT32 nPg2 = ( ( nPage + nPg ) > nPages ) ? nPages - nPage : nPg;
+ ULONG nBytes = nPg2 * nPageSize;
+ // fixed address and size for the header
+ if( nPage == -1 )
+ {
+ nPos = 0L, nBytes = 512;
+ nPg2 = nPg;
+ }
+ if( pStrm->Tell() != nPos )
+ {
+ if( pStrm->Seek( nPos ) != nPos ) {
+ #ifdef CHECK_DIRTY
+ ErrorBox( NULL, WB_OK, String("SO2: Seek failed") ).Execute();
+ #endif
+ }
+ }
+ pStrm->Read( pBuf, nBytes );
+ if ( nPg != nPg2 )
+ SetError( SVSTREAM_READ_ERROR );
+ else
+ SetError( pStrm->GetError() );
+ }
+ }
+ return Good();
+}
+
+BOOL StgCache::Write( INT32 nPage, void* pBuf, INT32 nPg )
+{
+ if( Good() )
+ {
+ ULONG nPos = Page2Pos( nPage );
+ ULONG nBytes = nPg * nPageSize;
+ // fixed address and size for the header
+ if( nPage == -1 )
+ nPos = 0L, nBytes = 512;
+ if( pStrm->Tell() != nPos )
+ {
+ if( pStrm->Seek( nPos ) != nPos ) {
+#ifdef CHECK_DIRTY
+ ErrorBox( NULL, WB_OK, String("SO2: Seek failed") ).Execute();
+#endif
+ }
+ }
+ ULONG nRes = pStrm->Write( pBuf, nBytes );
+ if( nRes != nBytes )
+ SetError( SVSTREAM_WRITE_ERROR );
+ else
+ SetError( pStrm->GetError() );
+#ifdef READ_AFTER_WRITE
+ BYTE cBuf[ 512 ];
+ pStrm->Flush();
+ pStrm->Seek( nPos );
+ BOOL bRes = ( pStrm->Read( cBuf, 512 ) == 512 );
+ if( bRes )
+ bRes = !memcmp( cBuf, pBuf, 512 );
+ if( !bRes )
+ {
+ ErrorBox( NULL, WB_OK, String("SO2: Read after Write failed") ).Execute();
+ pStrm->SetError( SVSTREAM_WRITE_ERROR );
+ }
+#endif
+ }
+ return Good();
+}
+
+// set the file size in pages
+
+BOOL StgCache::SetSize( INT32 n )
+{
+ // Add the file header
+ INT32 nSize = n * nPageSize + 512;
+ pStrm->SetStreamSize( nSize );
+ SetError( pStrm->GetError() );
+ if( !nError )
+ nPages = n;
+ return Good();
+}
+
+void StgCache::SetError( ULONG n )
+{
+ if( n && !nError )
+ nError = n;
+}
+
+void StgCache::ResetError()
+{
+ nError = SVSTREAM_OK;
+ pStrm->ResetError();
+}
+
+void StgCache::MoveError( StorageBase& r )
+{
+ if( nError != SVSTREAM_OK )
+ {
+ r.SetError( nError );
+ ResetError();
+ }
+}
+
+// Utility functions
+
+INT32 StgCache::Page2Pos( INT32 nPage )
+{
+ if( nPage < 0 ) nPage = 0;
+ return( nPage * nPageSize ) + nPageSize;
+}
+
+INT32 StgCache::Pos2Page( INT32 nPos )
+{
+ return ( ( nPos + nPageSize - 1 ) / nPageSize ) * nPageSize - 1;
+}
+
diff --git a/sot/source/sdstor/stgcache.hxx b/sot/source/sdstor/stgcache.hxx
new file mode 100644
index 000000000000..5379f837b8b1
--- /dev/null
+++ b/sot/source/sdstor/stgcache.hxx
@@ -0,0 +1,132 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _STGCACHE_HXX
+#define _STGCACHE_HXX
+
+#include <osl/endian.h>
+#ifndef _TOOLS_SOLAR_H
+#include <tools/solar.h>
+#endif
+#ifndef _TOOLS_STREAM_HXX
+#include <tools/stream.hxx>
+#endif
+#include <stgelem.hxx>
+
+class UCBStorageStream;
+
+class StgIo;
+class StgPage;
+class StgDirEntry;
+class StorageBase;
+
+class StgCache {
+ StgPage* pCur; // top of LRU list
+ StgPage* pElem1; // top of ordered list
+ ULONG nError; // error code
+ INT32 nPages; // size of data area in pages
+ USHORT nRef; // reference count
+ void * pLRUCache; // hash table of cached objects
+ short nPageSize; // page size of the file
+ UCBStorageStream* pStorageStream; // holds reference to UCB storage stream
+
+ void Erase( StgPage* ); // delete a cache element
+ void InsertToLRU( StgPage* ); // insert into LRU list
+ void InsertToOrdered( StgPage* ); // insert into ordered list
+ StgPage* Create( INT32 ); // create a cached page
+protected:
+ SvStream* pStrm; // physical stream
+ BOOL bMyStream; // TRUE: delete stream in dtor
+ BOOL bFile; // TRUE: file stream
+ INT32 Page2Pos( INT32 ); // page address --> file position
+ INT32 Pos2Page( INT32 ); // file position --> page address
+public:
+ StgCache();
+ ~StgCache();
+ void IncRef() { nRef++; }
+ USHORT DecRef() { return --nRef; }
+ void SetPhysPageSize( short );
+ INT32 GetPhysPages() { return nPages; }
+ short GetPhysPageSize() { return nPageSize; }
+ SvStream* GetStrm() { return pStrm; }
+ void SetStrm( SvStream*, BOOL );
+ void SetStrm( UCBStorageStream* );
+ BOOL IsWritable() { return pStrm->IsWritable(); }
+ BOOL Good() { return BOOL( nError == SVSTREAM_OK ); }
+ BOOL Bad() { return BOOL( nError != SVSTREAM_OK ); }
+ ULONG GetError() { return nError; }
+ void MoveError( StorageBase& );
+ void SetError( ULONG );
+ void ResetError();
+ BOOL Open( const String& rName, StreamMode );
+ void Close();
+ BOOL Read( INT32 nPage, void* pBuf, INT32 nPages );
+ BOOL Write( INT32 nPage, void* pBuf, INT32 nPages );
+ BOOL SetSize( INT32 nPages );
+ StgPage* Find( INT32 ); // find a cached page
+ StgPage* Get( INT32, BOOL ); // get a cached page
+ StgPage* Copy( INT32, INT32=STG_FREE ); // copy a page
+ BOOL Commit( StgDirEntry* = NULL ); // flush all pages
+ void Revert( StgDirEntry* = NULL ); // revert dirty pages
+ void Clear(); // clear the cache
+};
+
+class StgPage {
+ friend class StgCache;
+ StgCache* pCache; // the cache
+ StgPage *pNext1, *pLast1; // LRU chain
+ StgPage *pNext2, *pLast2; // ordered chain
+ StgDirEntry* pOwner; // owner
+ INT32 nPage; // page #
+ BYTE* pData; // nPageSize characters
+ short nData; // size of this page
+ BOOL bDirty; // dirty flag
+ StgPage( StgCache*, short );
+ ~StgPage();
+public:
+ void SetDirty() { bDirty = TRUE; }
+ INT32 GetPage() { return nPage; }
+ void* GetData() { return pData; }
+ short GetSize() { return nData; }
+ void SetOwner( StgDirEntry* p ) { pOwner = p; }
+ // routines for accessing FAT pages
+ // Assume that the data is a FAT page and get/put FAT data.
+ INT32 GetPage( short nOff )
+ {
+ if( ( nOff >= (short) ( nData / sizeof( INT32 ) ) ) || nOff < 0 )
+ return -1;
+ INT32 n = ((INT32*) pData )[ nOff ];
+#ifdef OSL_BIGENDIAN
+ return SWAPLONG(n);
+#else
+ return n;
+#endif
+ }
+ void SetPage( short, INT32 ); // put an element
+};
+
+#endif
diff --git a/sot/source/sdstor/stgdir.cxx b/sot/source/sdstor/stgdir.cxx
new file mode 100644
index 000000000000..f093dc60cbe7
--- /dev/null
+++ b/sot/source/sdstor/stgdir.cxx
@@ -0,0 +1,1054 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sot.hxx"
+
+#include <string.h> // memcpy()
+
+#include "stg.hxx"
+#include "stgelem.hxx"
+#include "stgcache.hxx"
+#include "stgstrms.hxx"
+#include "stgdir.hxx"
+#include "stgio.hxx"
+
+
+//////////////////////////// class StgDirEntry /////////////////////////////
+
+// This class holds the dir entry data and maintains dirty flags for both
+// the entry and the data.
+
+// Transacted mode for streams: On the first write, a temp stream pTmpStrm
+// is created and operated on. A commit moves pTmpStrm to pCurStrm, which
+// is used for subsequent reads. A new write creates a new copy of pTmpStrm
+// based on pCurStrm. Reverting throws away pTmpStrm.
+// Transacted mode for storages: A copy of the dir ents is kept in aSave.
+// Committing means copying aEntry to aSave. Reverting means to copy aSave
+// to aEntry, delete newly created entries and to reactivate removed entries.
+
+// Problem der Implementation: Keine Hierarchischen commits. Daher nur
+// insgesamt transaktionsorientert oder direkt.
+
+StgDirEntry::StgDirEntry( const void* pFrom, BOOL * pbOk ) : StgAvlNode()
+{
+ *pbOk = aEntry.Load( pFrom );
+
+ InitMembers();
+}
+
+StgDirEntry::StgDirEntry( const StgEntry& r ) : StgAvlNode(), aEntry( r )
+{
+ InitMembers();
+}
+
+// Helper for all ctors
+
+void StgDirEntry::InitMembers()
+{
+ aSave = aEntry;
+ pUp =
+ pDown = NULL;
+ ppRoot = NULL;
+ pStgStrm = NULL;
+ pCurStrm =
+ pTmpStrm = NULL;
+ nPos =
+ nEntry =
+ nRefCnt = 0;
+ nMode = STREAM_READ;
+ bDirect = TRUE;
+ bInvalid =
+ bCreated =
+ bRenamed =
+ bRemoved =
+ bTemp =
+ bDirty =
+ bZombie = FALSE;
+}
+
+StgDirEntry::~StgDirEntry()
+{
+ Close();
+ delete pCurStrm;
+ delete pStgStrm;
+ delete pDown;
+}
+
+// Comparison function
+
+short StgDirEntry::Compare( const StgAvlNode* p ) const
+{
+ const StgDirEntry* pEntry = (const StgDirEntry*) p;
+ return aEntry.Compare( pEntry->aEntry );
+}
+
+// Enumerate the entry numbers.
+// n is incremented to show the total # of entries.
+// These number are later used as page numbers when storing
+// the TOC tree into the TOC stream. Remember that aSave is
+// stored, not aEntry.
+
+void StgDirEntry::Enum( INT32& n )
+{
+ INT32 nLeft = STG_FREE, nRight = STG_FREE, nDown = STG_FREE;
+ nEntry = n++;
+ if( pLeft )
+ {
+ ((StgDirEntry*) pLeft)->Enum( n ); nLeft = ((StgDirEntry*) pLeft)->nEntry;
+ }
+ if( pRight )
+ {
+ ((StgDirEntry*) pRight)->Enum( n ); nRight = ((StgDirEntry*) pRight)->nEntry;
+ }
+ if( pDown )
+ {
+ pDown->Enum( n ); nDown = pDown->nEntry;
+ }
+ aSave.SetLeaf( STG_LEFT, nLeft );
+ aSave.SetLeaf( STG_RIGHT, nRight );
+ aSave.SetLeaf( STG_CHILD, nDown );
+}
+
+// Delete all temporary entries before writing the TOC stream.
+// Until now Deltem is never called with bForce True
+
+void StgDirEntry::DelTemp( BOOL bForce )
+{
+ if( pLeft )
+ ((StgDirEntry*) pLeft)->DelTemp( FALSE );
+ if( pRight )
+ ((StgDirEntry*) pRight)->DelTemp( FALSE );
+ if( pDown )
+ {
+ // If the storage is dead, of course all elements are dead, too
+ if( bInvalid && aEntry.GetType() == STG_STORAGE )
+ bForce = TRUE;
+ pDown->DelTemp( bForce );
+ }
+ if( ( bForce || bInvalid )
+ && ( aEntry.GetType() != STG_ROOT ) /* && ( nRefCnt <= 1 ) */ )
+ {
+ Close();
+ if( pUp )
+ {
+ // this deletes the element if refcnt == 0!
+ BOOL bDel = nRefCnt == 0;
+ StgAvlNode::Remove( (StgAvlNode**) &pUp->pDown, this, bDel );
+ if( !bDel )
+ {
+ pLeft = pRight = pDown = 0;
+ bInvalid = bZombie = TRUE;
+ }
+ }
+ }
+}
+
+// Save the tree into the given dir stream
+
+BOOL StgDirEntry::Store( StgDirStrm& rStrm )
+{
+ void* pEntry = rStrm.GetEntry( nEntry, TRUE );
+ if( !pEntry )
+ return FALSE;
+ // Do not store the current (maybe not commited) entry
+ aSave.Store( pEntry );
+ if( pLeft )
+ if( !((StgDirEntry*) pLeft)->Store( rStrm ) )
+ return FALSE;
+ if( pRight )
+ if( !((StgDirEntry*) pRight)->Store( rStrm ) )
+ return FALSE;
+ if( pDown )
+ if( !pDown->Store( rStrm ) )
+ return FALSE;
+ return TRUE;
+}
+
+BOOL StgDirEntry::StoreStream( StgIo& rIo )
+{
+ if( aEntry.GetType() == STG_STREAM || aEntry.GetType() == STG_ROOT )
+ {
+ if( bInvalid )
+ {
+ // Delete the stream if needed
+ if( !pStgStrm )
+ {
+ OpenStream( rIo );
+ delete pStgStrm, pStgStrm = NULL;
+ }
+ else
+ pStgStrm->SetSize( 0 );
+ }
+ // or write the data stream
+ else if( !Tmp2Strm() )
+ return FALSE;
+ }
+ return TRUE;
+}
+
+// Save all dirty streams
+
+BOOL StgDirEntry::StoreStreams( StgIo& rIo )
+{
+ if( !StoreStream( rIo ) )
+ return FALSE;
+ if( pLeft )
+ if( !((StgDirEntry*) pLeft)->StoreStreams( rIo ) )
+ return FALSE;
+ if( pRight )
+ if( !((StgDirEntry*) pRight)->StoreStreams( rIo ) )
+ return FALSE;
+ if( pDown )
+ if( !pDown->StoreStreams( rIo ) )
+ return FALSE;
+ return TRUE;
+}
+
+// Revert all directory entries after failure to write the TOC stream
+
+void StgDirEntry::RevertAll()
+{
+ aEntry = aSave;
+ if( pLeft )
+ ((StgDirEntry*) pLeft)->RevertAll();
+ if( pRight )
+ ((StgDirEntry*) pRight)->RevertAll();
+ if( pDown )
+ pDown->RevertAll();
+}
+
+// Look if any element of the tree is dirty
+
+BOOL StgDirEntry::IsDirty()
+{
+ if( bDirty || bInvalid )
+ return TRUE;
+ if( pLeft && ((StgDirEntry*) pLeft)->IsDirty() )
+ return TRUE;
+ if( pRight && ((StgDirEntry*) pRight)->IsDirty() )
+ return TRUE;
+ if( pDown && pDown->IsDirty() )
+ return TRUE;
+ return FALSE;
+}
+
+// Set up a stream.
+
+void StgDirEntry::OpenStream( StgIo& rIo, BOOL bForceBig )
+{
+ INT32 nThreshold = (USHORT) rIo.aHdr.GetThreshold();
+ delete pStgStrm;
+ if( !bForceBig && aEntry.GetSize() < nThreshold )
+ pStgStrm = new StgSmallStrm( rIo, this );
+ else
+ pStgStrm = new StgDataStrm( rIo, this );
+ if( bInvalid && aEntry.GetSize() )
+ {
+ // This entry has invalid data, so delete that data
+ SetSize( 0L );
+// bRemoved = bInvalid = FALSE;
+ }
+ nPos = 0;
+}
+
+// Close the open stream without committing. If the entry is marked as
+// temporary, delete it.
+// Do not delete pCurStrm here!
+// (TLX:??? Zumindest pStgStrm muss deleted werden.)
+
+void StgDirEntry::Close()
+{
+ delete pTmpStrm;
+ pTmpStrm = NULL;
+// nRefCnt = 0;
+ bInvalid = bTemp;
+}
+
+// Get the current stream size
+
+INT32 StgDirEntry::GetSize()
+{
+ INT32 n;
+ if( pTmpStrm )
+ n = pTmpStrm->GetSize();
+ else if( pCurStrm )
+ n = pCurStrm->GetSize();
+ else n = aEntry.GetSize();
+ return n;
+}
+
+// Set the stream size. This means also creating a temp stream.
+
+BOOL StgDirEntry::SetSize( INT32 nNewSize )
+{
+ if (
+ !( nMode & STREAM_WRITE ) ||
+ (!bDirect && !pTmpStrm && !Strm2Tmp())
+ )
+ {
+ return FALSE;
+ }
+
+ if( nNewSize < nPos )
+ nPos = nNewSize;
+ if( pTmpStrm )
+ {
+ pTmpStrm->SetSize( nNewSize );
+ pStgStrm->GetIo().SetError( pTmpStrm->GetError() );
+ return BOOL( pTmpStrm->GetError() == SVSTREAM_OK );
+ }
+ else
+ {
+ BOOL bRes = FALSE;
+ StgIo& rIo = pStgStrm->GetIo();
+ INT32 nThreshold = rIo.aHdr.GetThreshold();
+ // ensure the correct storage stream!
+ StgStrm* pOld = NULL;
+ USHORT nOldSize = 0;
+ if( nNewSize >= nThreshold && pStgStrm->IsSmallStrm() )
+ {
+ pOld = pStgStrm;
+ nOldSize = (USHORT) pOld->GetSize();
+ pStgStrm = new StgDataStrm( rIo, STG_EOF, 0 );
+ }
+ else if( nNewSize < nThreshold && !pStgStrm->IsSmallStrm() )
+ {
+ pOld = pStgStrm;
+ nOldSize = (USHORT) nNewSize;
+ pStgStrm = new StgSmallStrm( rIo, STG_EOF, 0 );
+ }
+ // now set the new size
+ if( pStgStrm->SetSize( nNewSize ) )
+ {
+ // did we create a new stream?
+ if( pOld )
+ {
+ // if so, we probably need to copy the old data
+ if( nOldSize )
+ {
+ void* pBuf = new BYTE[ nOldSize ];
+ pOld->Pos2Page( 0L );
+ pStgStrm->Pos2Page( 0L );
+ if( pOld->Read( pBuf, nOldSize )
+ && pStgStrm->Write( pBuf, nOldSize ) )
+ bRes = TRUE;
+ delete[] static_cast<BYTE*>(pBuf);
+ }
+ else
+ bRes = TRUE;
+ if( bRes )
+ {
+ pOld->SetSize( 0 );
+ delete pOld;
+ pStgStrm->Pos2Page( nPos );
+ pStgStrm->SetEntry( *this );
+ }
+ else
+ {
+ pStgStrm->SetSize( 0 );
+ delete pStgStrm;
+ pStgStrm = pOld;
+ }
+ }
+ else
+ {
+ pStgStrm->Pos2Page( nPos );
+ bRes = TRUE;
+ }
+ }
+ return bRes;
+ }
+}
+
+// Seek. On negative values, seek to EOF.
+
+INT32 StgDirEntry::Seek( INT32 nNew )
+{
+ if( pTmpStrm )
+ {
+ if( nNew < 0 )
+ nNew = pTmpStrm->GetSize();
+ nNew = pTmpStrm->Seek( nNew );
+ }
+ else if( pCurStrm )
+ {
+ if( nNew < 0 )
+ nNew = pCurStrm->GetSize();
+ nNew = pCurStrm->Seek( nNew );
+ }
+ else
+ {
+ INT32 nSize = aEntry.GetSize();
+
+ if( nNew < 0 )
+ nNew = nSize;
+
+ // try to enlarge, the readonly streams should not allow this
+ if( nNew > nSize )
+ {
+ if ( !( nMode & STREAM_WRITE ) || !SetSize( nNew ) )
+ {
+ OSL_ENSURE( nMode & STREAM_WRITE, "Trying to resize readonly stream by seeking, could be a wrong offset!" );
+ return nPos;
+ }
+ else
+ return Seek( nNew );
+ }
+ pStgStrm->Pos2Page( nNew );
+ nNew = pStgStrm->GetPos();
+ }
+ return nPos = nNew;
+}
+
+// Read
+
+INT32 StgDirEntry::Read( void* p, INT32 nLen )
+{
+ if( nLen <= 0 )
+ return 0;
+ if( pTmpStrm )
+ nLen = pTmpStrm->Read( p, nLen );
+ else if( pCurStrm )
+ nLen = pCurStrm->Read( p, nLen );
+ else
+ nLen = pStgStrm->Read( p, nLen );
+ nPos += nLen;
+ return nLen;
+}
+
+// Write
+
+INT32 StgDirEntry::Write( const void* p, INT32 nLen )
+{
+ if( nLen <= 0 || !( nMode & STREAM_WRITE ) )
+ return 0;
+
+ // Was this stream committed internally and reopened in direct mode?
+ if( bDirect && ( pCurStrm || pTmpStrm ) && !Tmp2Strm() )
+ return 0;
+ // Is this stream opened in transacted mode? Do we have to make a copy?
+ if( !bDirect && !pTmpStrm && !Strm2Tmp() )
+ return 0;
+ if( pTmpStrm )
+ {
+ nLen = pTmpStrm->Write( p, nLen );
+ pStgStrm->GetIo().SetError( pTmpStrm->GetError() );
+ }
+ else
+ {
+ INT32 nNew = nPos + nLen;
+ if( nNew > pStgStrm->GetSize() )
+ {
+ if( !SetSize( nNew ) )
+ return 0L;
+ pStgStrm->Pos2Page( nPos );
+ }
+ nLen = pStgStrm->Write( p, nLen );
+ }
+ nPos += nLen;
+ return nLen;
+}
+
+// Copy the data of one entry into another entry.
+
+void StgDirEntry::Copy( StgDirEntry& rDest )
+{
+ INT32 n = GetSize();
+ if( rDest.SetSize( n ) && n )
+ {
+ BYTE aTempBytes[ 4096 ];
+ void* p = static_cast<void*>( aTempBytes );
+ Seek( 0L );
+ rDest.Seek( 0L );
+ while( n )
+ {
+ INT32 nn = n;
+ if( nn > 4096 )
+ nn = 4096;
+ if( Read( p, nn ) != nn )
+ break;
+ if( rDest.Write( p, nn ) != nn )
+ break;
+ n -= nn;
+ }
+ }
+}
+
+void StgDirEntry::Copy( BaseStorageStream& rDest )
+{
+ INT32 n = GetSize();
+ if( rDest.SetSize( n ) && n )
+ {
+ ULONG Pos = rDest.Tell();
+ BYTE aTempBytes[ 4096 ];
+ void* p = static_cast<void*>( aTempBytes );
+ Seek( 0L );
+ rDest.Seek( 0L );
+ while( n )
+ {
+ INT32 nn = n;
+ if( nn > 4096 )
+ nn = 4096;
+ if( Read( p, nn ) != nn )
+ break;
+ if( sal::static_int_cast<INT32>(rDest.Write( p, nn )) != nn )
+ break;
+ n -= nn;
+ }
+ rDest.Seek( Pos ); // ?! Seems to be undocumented !
+ }
+}
+
+// Commit this entry
+
+BOOL StgDirEntry::Commit()
+{
+ // OSL_ENSURE( nMode & STREAM_WRITE, "Trying to commit readonly stream!" );
+
+ aSave = aEntry;
+ BOOL bRes = TRUE;
+ if( aEntry.GetType() == STG_STREAM )
+ {
+ if( pTmpStrm )
+ delete pCurStrm, pCurStrm = pTmpStrm, pTmpStrm = NULL;
+ if( bRemoved )
+ // Delete the stream if needed
+ if( pStgStrm )
+ pStgStrm->SetSize( 0 );
+ }
+ else if( aEntry.GetType() == STG_STORAGE && bDirect && bRes )
+ {
+ StgIterator aIter( *this );
+ for( StgDirEntry* p = aIter.First(); p && bRes; p = aIter.Next() )
+ bRes = p->Commit();
+ }
+ return bRes;
+}
+
+// Revert the entry
+
+BOOL StgDirEntry::Revert()
+{
+ aEntry = aSave;
+ switch( aEntry.GetType() )
+ {
+ case STG_STREAM:
+ if( pCurStrm )
+ delete pTmpStrm, pTmpStrm = pCurStrm, pCurStrm = NULL;
+ break;
+ case STG_STORAGE:
+ {
+ BOOL bSomeRenamed = FALSE;
+ StgIterator aOIter( *this );
+ StgDirEntry* op = aOIter.First();
+ while( op )
+ {
+ op->aEntry = op->aSave;
+ op->bDirty = FALSE;
+ bSomeRenamed = BOOL( bSomeRenamed | op->bRenamed );
+ // Remove any new entries
+ if( op->bCreated )
+ {
+ op->bCreated = FALSE;
+ op->Close();
+ op->bInvalid = TRUE;
+ }
+ // Reactivate any removed entries
+ else if( op->bRemoved )
+ op->bRemoved = op->bInvalid = op->bTemp = FALSE;
+ op = aOIter.Next();
+ }
+ // Resort all renamed entries
+ if( bSomeRenamed )
+ {
+ StgIterator aIter( *this );
+ StgDirEntry* p = aIter.First();
+ while( p )
+ {
+ if( p->bRenamed )
+ {
+ StgAvlNode::Move
+ ( (StgAvlNode**) &p->pUp->pDown,
+ (StgAvlNode**) &p->pUp->pDown, p );
+ p->bRenamed = FALSE;
+ }
+ p = aIter.Next();
+ }
+ }
+ DelTemp( FALSE );
+ break;
+ }
+ case STG_EMPTY:
+ case STG_LOCKBYTES:
+ case STG_PROPERTY:
+ case STG_ROOT:
+ break;
+ }
+ return TRUE;
+}
+
+// Copy the stg stream to the temp stream
+
+BOOL StgDirEntry::Strm2Tmp()
+{
+ if( !pTmpStrm )
+ {
+ ULONG n = 0;
+ if( pCurStrm )
+ {
+ // It was already commited once
+ pTmpStrm = new StgTmpStrm;
+ if( pTmpStrm->GetError() == SVSTREAM_OK && pTmpStrm->Copy( *pCurStrm ) )
+ return TRUE;
+ n = 1; // indicates error
+ }
+ else
+ {
+ n = aEntry.GetSize();
+ pTmpStrm = new StgTmpStrm( n );
+ if( pTmpStrm->GetError() == SVSTREAM_OK )
+ {
+ if( n )
+ {
+ BYTE aTempBytes[ 4096 ];
+ void* p = static_cast<void*>( aTempBytes );
+ pStgStrm->Pos2Page( 0L );
+ while( n )
+ {
+ ULONG nn = n;
+ if( nn > 4096 )
+ nn = 4096;
+ if( (ULONG) pStgStrm->Read( p, nn ) != nn )
+ break;
+ if( pTmpStrm->Write( p, nn ) != nn )
+ break;
+ n -= nn;
+ }
+ pStgStrm->Pos2Page( nPos );
+ pTmpStrm->Seek( nPos );
+ }
+ }
+ else
+ n = 1;
+ }
+ if( n )
+ {
+ pStgStrm->GetIo().SetError( pTmpStrm->GetError() );
+ delete pTmpStrm;
+ pTmpStrm = NULL;
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+// Copy the temp stream to the stg stream during the final commit
+
+BOOL StgDirEntry::Tmp2Strm()
+{
+ // We did commit once, but have not written since then
+ if( !pTmpStrm )
+ pTmpStrm = pCurStrm, pCurStrm = NULL;
+ if( pTmpStrm )
+ {
+ ULONG n = pTmpStrm->GetSize();
+ StgStrm* pNewStrm;
+ StgIo& rIo = pStgStrm->GetIo();
+ ULONG nThreshold = (ULONG) rIo.aHdr.GetThreshold();
+ if( n < nThreshold )
+ pNewStrm = new StgSmallStrm( rIo, STG_EOF, 0 );
+ else
+ pNewStrm = new StgDataStrm( rIo, STG_EOF, 0 );
+ if( pNewStrm->SetSize( n ) )
+ {
+ BYTE p[ 4096 ];
+ pTmpStrm->Seek( 0L );
+ while( n )
+ {
+ ULONG nn = n;
+ if( nn > 4096 )
+ nn = 4096;
+ if( pTmpStrm->Read( p, nn ) != nn )
+ break;
+ if( (ULONG) pNewStrm->Write( p, nn ) != nn )
+ break;
+ n -= nn;
+ }
+ if( n )
+ {
+ pTmpStrm->Seek( nPos );
+ pStgStrm->GetIo().SetError( pTmpStrm->GetError() );
+ delete pNewStrm;
+ return FALSE;
+ }
+ else
+ {
+ pStgStrm->SetSize( 0L );
+ delete pStgStrm;
+ pStgStrm = pNewStrm;
+ pNewStrm->SetEntry( *this );
+ pNewStrm->Pos2Page( nPos );
+ delete pTmpStrm;
+ delete pCurStrm;
+ pTmpStrm = pCurStrm = NULL;
+ aSave = aEntry;
+ }
+ }
+ }
+ return TRUE;
+}
+
+// Check if the given entry is contained in this entry
+
+BOOL StgDirEntry::IsContained( StgDirEntry* pStg )
+{
+ if( aEntry.GetType() == STG_STORAGE )
+ {
+ StgIterator aIter( *this );
+ StgDirEntry* p = aIter.First();
+ while( p )
+ {
+ if( !p->aEntry.Compare( pStg->aEntry ) )
+ return FALSE;
+ if( p->aEntry.GetType() == STG_STORAGE )
+ if( !p->IsContained( pStg ) )
+ return FALSE;
+ p = aIter.Next();
+ }
+ }
+ return TRUE;
+}
+
+// Invalidate all open entries by setting the RefCount to 0. If the bDel
+// flag is set, also set the invalid flag to indicate deletion during the
+// next dir stream flush.
+
+void StgDirEntry::Invalidate( BOOL bDel )
+{
+// nRefCnt = 0;
+ if( bDel )
+ bRemoved = bInvalid = TRUE;
+ switch( aEntry.GetType() )
+ {
+ case STG_STORAGE:
+ case STG_ROOT:
+ {
+ StgIterator aIter( *this );
+ for( StgDirEntry* p = aIter.First(); p; p = aIter.Next() )
+ p->Invalidate( bDel );
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+///////////////////////////// class StgDirStrm ////////////////////////////
+
+// This specialized stream is the maintenance stream for the directory tree.
+
+StgDirStrm::StgDirStrm( StgIo& r )
+ : StgDataStrm( r, r.aHdr.GetTOCStart(), -1 )
+ , pRoot( NULL )
+ , nEntries( 0 )
+{
+ if( r.GetError() )
+ return;
+ nEntries = nPageSize / STGENTRY_SIZE;
+ if( nStart == STG_EOF )
+ {
+ StgEntry aRoot;
+ aRoot.Init();
+ aRoot.SetName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "Root Entry" ) ) );
+ aRoot.SetType( STG_ROOT );
+ pRoot = new StgDirEntry( aRoot );
+ pRoot->SetDirty();
+ }
+ else
+ {
+ // temporarily use this instance as owner, so
+ // the TOC pages can be removed.
+ pEntry = (StgDirEntry*) this; // just for a bit pattern
+ SetupEntry( 0, pRoot );
+ rIo.Revert( pEntry );
+ pEntry = NULL;
+ }
+}
+
+StgDirStrm::~StgDirStrm()
+{
+ delete pRoot;
+}
+
+// Recursively parse the directory tree during reading the TOC stream
+
+void StgDirStrm::SetupEntry( INT32 n, StgDirEntry* pUpper )
+{
+ void* p = ( n == STG_FREE ) ? NULL : GetEntry( n );
+ if( p )
+ {
+ BOOL bOk(FALSE);
+ StgDirEntry* pCur = new StgDirEntry( p, &bOk );
+
+ if( !bOk )
+ {
+ delete pCur;
+ rIo.SetError( SVSTREAM_GENERALERROR );
+ // an error occured
+ return;
+ }
+
+ // better it is
+ if( !pUpper )
+ pCur->aEntry.SetType( STG_ROOT );
+
+ INT32 nLeft = pCur->aEntry.GetLeaf( STG_LEFT );
+ INT32 nRight = pCur->aEntry.GetLeaf( STG_RIGHT );
+ // substorage?
+ INT32 nLeaf = STG_FREE;
+ if( pCur->aEntry.GetType() == STG_STORAGE || pCur->aEntry.GetType() == STG_ROOT )
+ {
+ nLeaf = pCur->aEntry.GetLeaf( STG_CHILD );
+ if (nLeaf != STG_FREE && nLeaf == n)
+ {
+ delete pCur;
+ rIo.SetError( SVSTREAM_GENERALERROR );
+ return;
+ }
+ }
+
+ if( nLeaf != 0 && nLeft != 0 && nRight != 0 )
+ {
+ if( StgAvlNode::Insert
+ ( (StgAvlNode**) ( pUpper ? &pUpper->pDown : &pRoot ), pCur ) )
+ {
+ pCur->pUp = pUpper;
+ pCur->ppRoot = &pRoot;
+ }
+ else
+ {
+ rIo.SetError( SVSTREAM_CANNOT_MAKE );
+ delete pCur; pCur = NULL;
+ return;
+ }
+ SetupEntry( nLeft, pUpper );
+ SetupEntry( nRight, pUpper );
+ SetupEntry( nLeaf, pCur );
+ }
+ }
+}
+
+// Extend or shrink the directory stream.
+
+BOOL StgDirStrm::SetSize( INT32 nBytes )
+{
+ // Always allocate full pages
+ nBytes = ( ( nBytes + nPageSize - 1 ) / nPageSize ) * nPageSize;
+ return StgStrm::SetSize( nBytes );
+}
+
+// Save the TOC stream into a new substream after saving all data streams
+
+BOOL StgDirStrm::Store()
+{
+ if( !pRoot->IsDirty() )
+ return TRUE;
+ if( !pRoot->StoreStreams( rIo ) )
+ return FALSE;
+ // After writing all streams, the data FAT stream has changed,
+ // so we have to commit the root again
+ pRoot->Commit();
+ // We want a completely new stream, so fake an empty stream
+ INT32 nOldStart = nStart; // save for later deletion
+ INT32 nOldSize = nSize;
+ nStart = nPage = STG_EOF;
+ nSize = nPos = 0;
+ nOffset = 0;
+ // Delete all temporary entries
+ pRoot->DelTemp( FALSE );
+ // set the entry numbers
+ INT32 n = 0;
+ pRoot->Enum( n );
+ if( !SetSize( n * STGENTRY_SIZE ) )
+ {
+ nStart = nOldStart; nSize = nOldSize;
+ pRoot->RevertAll();
+ return FALSE;
+ }
+ // set up the cache elements for the new stream
+ if( !Copy( STG_FREE, nSize ) )
+ {
+ pRoot->RevertAll();
+ return FALSE;
+ }
+ // Write the data to the new stream
+ if( !pRoot->Store( *this ) )
+ {
+ pRoot->RevertAll();
+ return FALSE;
+ }
+ // fill any remaining entries with empty data
+ INT32 ne = nSize / STGENTRY_SIZE;
+ StgEntry aEmpty;
+ aEmpty.Init();
+ while( n < ne )
+ {
+ void* p = GetEntry( n++, TRUE );
+ if( !p )
+ {
+ pRoot->RevertAll();
+ return FALSE;
+ }
+ aEmpty.Store( p );
+ }
+ // Now we can release the old stream
+ pFat->FreePages( nOldStart, TRUE );
+ rIo.aHdr.SetTOCStart( nStart );
+ return TRUE;
+}
+
+// Get a dir entry.
+
+void* StgDirStrm::GetEntry( INT32 n, BOOL bDirty )
+{
+ n *= STGENTRY_SIZE;
+ if( n >= nSize )
+ return NULL;
+ return GetPtr( n, TRUE, bDirty );
+}
+
+// Find a dir entry.
+
+StgDirEntry* StgDirStrm::Find( StgDirEntry& rStg, const String& rName )
+{
+ if( rStg.pDown )
+ {
+ StgEntry aEntry;
+ aEntry.Init();
+ if( !aEntry.SetName( rName ) )
+ {
+ rIo.SetError( SVSTREAM_GENERALERROR );
+ return NULL;
+ }
+ // Look in the directory attached to the entry
+ StgDirEntry aTest( aEntry );
+ return (StgDirEntry*) rStg.pDown->Find( &aTest );
+ }
+ else
+ return NULL;
+}
+
+// Create a new entry.
+
+StgDirEntry* StgDirStrm::Create
+ ( StgDirEntry& rStg, const String& rName, StgEntryType eType )
+{
+ StgEntry aEntry;
+ aEntry.Init();
+ aEntry.SetType( eType );
+ if( !aEntry.SetName( rName ) )
+ {
+ rIo.SetError( SVSTREAM_GENERALERROR );
+ return NULL;
+ }
+ StgDirEntry* pRes = Find( rStg, rName );
+ if( pRes )
+ {
+ if( !pRes->bInvalid )
+ {
+ rIo.SetError( SVSTREAM_CANNOT_MAKE );
+ return NULL;
+ }
+ pRes->bInvalid =
+ pRes->bRemoved =
+ pRes->bTemp = FALSE;
+ pRes->bCreated =
+ pRes->bDirty = TRUE;
+ }
+ else
+ {
+ pRes = new StgDirEntry( aEntry );
+ if( StgAvlNode::Insert( (StgAvlNode**) &rStg.pDown, pRes ) )
+ {
+ pRes->pUp = &rStg;
+ pRes->ppRoot = &pRoot;
+ pRes->bCreated =
+ pRes->bDirty = TRUE;
+ }
+ else
+ {
+ rIo.SetError( SVSTREAM_CANNOT_MAKE );
+ delete pRes; pRes = NULL;
+ }
+ }
+ return pRes;
+}
+
+// Rename the given entry.
+
+BOOL StgDirStrm::Rename( StgDirEntry& rStg, const String& rOld, const String& rNew )
+{
+ StgDirEntry* p = Find( rStg, rOld );
+ if( p )
+ {
+
+ if( !StgAvlNode::Remove( (StgAvlNode**) &rStg.pDown, p, FALSE ) )
+ return FALSE;
+ p->aEntry.SetName( rNew );
+ if( !StgAvlNode::Insert( (StgAvlNode**) &rStg.pDown, p ) )
+ return FALSE;
+ p->bRenamed = p->bDirty = TRUE;
+ return TRUE;
+ }
+ else
+ {
+ rIo.SetError( SVSTREAM_FILE_NOT_FOUND );
+ return FALSE;
+ }
+}
+
+// Move the given entry to a different storage.
+
+BOOL StgDirStrm::Move( StgDirEntry& rStg1, StgDirEntry& rStg2, const String& rName )
+{
+ StgDirEntry* p = Find( rStg1, rName );
+ if( p )
+ {
+ if( !StgAvlNode::Move
+ ( (StgAvlNode**) &rStg1.pDown, (StgAvlNode**) &rStg2.pDown, p ) )
+ return FALSE;
+ p->bDirty = TRUE;
+ return TRUE;
+ }
+ else
+ {
+ rIo.SetError( SVSTREAM_FILE_NOT_FOUND );
+ return FALSE;
+ }
+}
+
diff --git a/sot/source/sdstor/stgdir.hxx b/sot/source/sdstor/stgdir.hxx
new file mode 100644
index 000000000000..3ef510a12e50
--- /dev/null
+++ b/sot/source/sdstor/stgdir.hxx
@@ -0,0 +1,132 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _STGDIR_HXX
+#define _STGDIR_HXX
+
+#include "stgavl.hxx"
+#include "stgelem.hxx"
+#include "stgstrms.hxx"
+
+class StgIo;
+class StgEntry;
+class StgDirEntry;
+class StgDirStrm;
+
+class BaseStorageStream;
+class StgDirEntry : public StgAvlNode
+{
+ friend class StgIterator;
+ friend class StgDirStrm;
+ StgEntry aSave; // original dir entry
+ StgDirEntry* pUp; // parent directory
+ StgDirEntry* pDown; // child directory for storages
+ StgDirEntry** ppRoot; // root of TOC tree
+ StgStrm* pStgStrm; // storage stream
+ StgTmpStrm* pTmpStrm; // temporary stream
+ StgTmpStrm* pCurStrm; // temp stream after commit
+ INT32 nEntry; // entry # in TOC stream (temp)
+ INT32 nPos; // current position
+ BOOL bDirty; // dirty directory entry
+ BOOL bCreated; // newly created entry
+ BOOL bRemoved; // removed per Invalidate()
+ BOOL bRenamed; // renamed
+ void InitMembers(); // ctor helper
+ virtual short Compare( const StgAvlNode* ) const;
+ BOOL StoreStream( StgIo& ); // store the stream
+ BOOL StoreStreams( StgIo& ); // store all streams
+ void RevertAll(); // revert the whole tree
+ BOOL Strm2Tmp(); // copy stgstream to temp file
+ BOOL Tmp2Strm(); // copy temp file to stgstream
+public:
+ StgEntry aEntry; // entry data
+ INT32 nRefCnt; // reference count
+ StreamMode nMode; // open mode
+ BOOL bTemp; // TRUE: delete on dir flush
+ BOOL bDirect; // TRUE: direct mode
+ BOOL bZombie; // TRUE: Removed From StgIo
+ BOOL bInvalid; // TRUE: invalid entry
+ StgDirEntry( const void*, BOOL * pbOk );
+ StgDirEntry( const StgEntry& );
+ ~StgDirEntry();
+
+ void Invalidate( BOOL=FALSE ); // invalidate all open entries
+ void Enum( INT32& ); // enumerate entries for iteration
+ void DelTemp( BOOL ); // delete temporary entries
+ BOOL Store( StgDirStrm& ); // save entry into dir strm
+ BOOL IsContained( StgDirEntry* ); // check if subentry
+
+ void SetDirty() { bDirty = TRUE; }
+ BOOL IsDirty();
+ void ClearDirty();
+
+ BOOL Commit();
+ BOOL Revert();
+
+ void OpenStream( StgIo&, BOOL=FALSE ); // set up an approbiate stream
+ void Close();
+ INT32 GetSize();
+ BOOL SetSize( INT32 );
+ INT32 Seek( INT32 );
+ INT32 Tell() { return nPos; }
+ INT32 Read( void*, INT32 );
+ INT32 Write( const void*, INT32 );
+ void Copy( StgDirEntry& );
+ void Copy( BaseStorageStream& );
+};
+
+class StgDirStrm : public StgDataStrm
+{
+ friend class StgIterator;
+ StgDirEntry* pRoot; // root of dir tree
+ short nEntries; // entries per page
+ void SetupEntry( INT32, StgDirEntry* );
+public:
+ StgDirStrm( StgIo& );
+ ~StgDirStrm();
+ virtual BOOL SetSize( INT32 ); // change the size
+ BOOL Store();
+ void* GetEntry( INT32 n, BOOL=FALSE );// get an entry
+ StgDirEntry* GetRoot() { return pRoot; }
+ StgDirEntry* Find( StgDirEntry&, const String& );
+ StgDirEntry* Create( StgDirEntry&, const String&, StgEntryType );
+ BOOL Remove( StgDirEntry&, const String& );
+ BOOL Rename( StgDirEntry&, const String&, const String& );
+ BOOL Move( StgDirEntry&, StgDirEntry&, const String& );
+};
+
+class StgIterator : public StgAvlIterator
+{
+public:
+ StgIterator( StgDirEntry& rStg ) : StgAvlIterator( rStg.pDown ) {}
+ StgDirEntry* First() { return (StgDirEntry*) StgAvlIterator::First(); }
+ StgDirEntry* Next() { return (StgDirEntry*) StgAvlIterator::Next(); }
+ StgDirEntry* Last() { return (StgDirEntry*) StgAvlIterator::Last(); }
+ StgDirEntry* Prev() { return (StgDirEntry*) StgAvlIterator::Prev(); }
+};
+
+#endif
diff --git a/sot/source/sdstor/stgelem.cxx b/sot/source/sdstor/stgelem.cxx
new file mode 100644
index 000000000000..46d7f1803140
--- /dev/null
+++ b/sot/source/sdstor/stgelem.cxx
@@ -0,0 +1,425 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sot.hxx"
+
+#include <string.h> // memset(), memcpy()
+#include <rtl/ustring.hxx>
+#include <com/sun/star/lang/Locale.hpp>
+#include <unotools/charclass.hxx>
+#include "stg.hxx"
+#include "stgelem.hxx"
+#include "stgcache.hxx"
+#include "stgstrms.hxx"
+#include "stgdir.hxx"
+#include "stgio.hxx"
+
+static BYTE cStgSignature[ 8 ] = { 0xD0,0xCF,0x11,0xE0,0xA1,0xB1,0x1A,0xE1 };
+
+////////////////////////////// struct ClsId /////////////////////////////
+
+SvStream& operator >>( SvStream& r, ClsId& rId )
+{
+ r >> rId.n1
+ >> rId.n2
+ >> rId.n3
+ >> rId.n4
+ >> rId.n5
+ >> rId.n6
+ >> rId.n7
+ >> rId.n8
+ >> rId.n9
+ >> rId.n10
+ >> rId.n11;
+ return r;
+}
+
+SvStream& operator <<( SvStream& r, const ClsId& rId )
+{
+ return
+ r << (INT32) rId.n1
+ << (INT16) rId.n2
+ << (INT16) rId.n3
+ << (UINT8) rId.n4
+ << (UINT8) rId.n5
+ << (UINT8) rId.n6
+ << (UINT8) rId.n7
+ << (UINT8) rId.n8
+ << (UINT8) rId.n9
+ << (UINT8) rId.n10
+ << (UINT8) rId.n11;
+}
+
+///////////////////////////// class StgHeader ////////////////////////////
+
+StgHeader::StgHeader()
+{
+ memset( this, 0, sizeof( StgHeader ) );
+}
+
+void StgHeader::Init()
+{
+ memset( this, 0, sizeof( StgHeader ) );
+ memcpy( cSignature, cStgSignature, 8 );
+ nVersion = 0x0003003B;
+ nByteOrder = 0xFFFE;
+ nPageSize = 9; // 512 bytes
+ nDataPageSize = 6; // 64 bytes
+ nThreshold = 4096;
+ nDataFATSize = 0;
+ nMasterChain = STG_EOF;
+ SetTOCStart( STG_EOF );
+ SetDataFATStart( STG_EOF );
+ for( short i = 0; i < 109; i++ )
+ SetFATPage( i, STG_FREE );
+}
+
+BOOL StgHeader::Load( StgIo& rIo )
+{
+ SvStream& r = *rIo.GetStrm();
+ Load( r );
+ return rIo.Good();
+}
+
+BOOL StgHeader::Load( SvStream& r )
+{
+ r.Seek( 0L );
+ r.Read( cSignature, 8 );
+ r >> aClsId // 08 Class ID
+ >> nVersion // 1A version number
+ >> nByteOrder // 1C Unicode byte order indicator
+ >> nPageSize // 1E 1 << nPageSize = block size
+ >> nDataPageSize; // 20 1 << this size == data block size
+ r.SeekRel( 10 );
+ r >> nFATSize // 2C total number of FAT pages
+ >> nTOCstrm // 30 starting page for the TOC stream
+ >> nReserved // 34
+ >> nThreshold // 38 minimum file size for big data
+ >> nDataFAT // 3C page # of 1st data FAT block
+ >> nDataFATSize // 40 # of data FATpages
+ >> nMasterChain // 44 chain to the next master block
+ >> nMaster; // 48 # of additional master blocks
+ for( short i = 0; i < 109; i++ )
+ r >> nMasterFAT[ i ];
+ return r.GetErrorCode() == ERRCODE_NONE;
+}
+
+BOOL StgHeader::Store( StgIo& rIo )
+{
+ if( !bDirty )
+ return TRUE;
+ SvStream& r = *rIo.GetStrm();
+ r.Seek( 0L );
+ r.Write( cSignature, 8 + 16 );
+ r << nVersion // 1A version number
+ << nByteOrder // 1C Unicode byte order indicator
+ << nPageSize // 1E 1 << nPageSize = block size
+ << nDataPageSize // 20 1 << this size == data block size
+ << (INT32) 0 << (INT32) 0 << (INT16) 0
+ << nFATSize // 2C total number of FAT pages
+ << nTOCstrm // 30 starting page for the TOC stream
+ << nReserved // 34
+ << nThreshold // 38 minimum file size for big data
+ << nDataFAT // 3C page # of 1st data FAT block
+ << nDataFATSize // 40 # of data FAT pages
+ << nMasterChain // 44 chain to the next master block
+ << nMaster; // 48 # of additional master blocks
+ for( short i = 0; i < 109; i++ )
+ r << nMasterFAT[ i ];
+ bDirty = !rIo.Good();
+ return BOOL( !bDirty );
+}
+
+static bool lcl_wontoverflow(short shift)
+{
+ return shift >= 0 && shift < (short)sizeof(short) * 8 - 1;
+}
+
+// Perform thorough checks also on unknown variables
+BOOL StgHeader::Check()
+{
+ return BOOL( memcmp( cSignature, cStgSignature, 8 ) == 0
+ && (short) ( nVersion >> 16 ) == 3 )
+ && lcl_wontoverflow(nPageSize)
+ && lcl_wontoverflow(nDataPageSize);
+}
+
+INT32 StgHeader::GetFATPage( short n ) const
+{
+ if( n >= 0 && n < 109 )
+ return nMasterFAT[ n ];
+ else
+ return STG_EOF;
+}
+
+void StgHeader::SetFATPage( short n, INT32 nb )
+{
+ if( n >= 0 && n < 109 )
+ {
+ if( nMasterFAT[ n ] != nb )
+ bDirty = TRUE, nMasterFAT[ n ] = nb;
+ }
+}
+
+void StgHeader::SetClassId( const ClsId& r )
+{
+ if( memcmp( &aClsId, &r, sizeof( ClsId ) ) )
+ bDirty = TRUE, memcpy( &aClsId, &r, sizeof( ClsId ) );
+}
+
+void StgHeader::SetTOCStart( INT32 n )
+{
+ if( n != nTOCstrm ) bDirty = TRUE, nTOCstrm = n;
+}
+
+void StgHeader::SetDataFATStart( INT32 n )
+{
+ if( n != nDataFAT ) bDirty = TRUE, nDataFAT = n;
+}
+
+void StgHeader::SetDataFATSize( INT32 n )
+{
+ if( n != nDataFATSize ) bDirty = TRUE, nDataFATSize = n;
+}
+
+void StgHeader::SetFATSize( INT32 n )
+{
+ if( n != nFATSize ) bDirty = TRUE, nFATSize = n;
+}
+
+void StgHeader::SetFATChain( INT32 n )
+{
+ if( n != nMasterChain )
+ bDirty = TRUE, nMasterChain = n;
+}
+
+void StgHeader::SetMasters( INT32 n )
+{
+ if( n != nMaster ) bDirty = TRUE, nMaster = n;
+}
+
+///////////////////////////// class StgEntry /////////////////////////////
+
+// This class is only a wrapper around teh dir entry structure
+// which retrieves and sets data.
+
+// The name must be smaller than 32 chars. Conversion into Unicode
+// is easy, since the 1st 256 characters of the Windows ANSI set
+// equal the 1st 256 Unicode characters.
+/*
+void ToUnicode_Impl( String& rName )
+{
+ rName.Erase( 32 );
+ rName.Convert( ::GetSystemCharSet(), CHARSET_ANSI );
+ // brute force is OK
+ BYTE* p = (BYTE*) rName.GetCharStr();
+ for( USHORT i = 0; i < rName.Len(); i++, p++ )
+ {
+ // check each character and substitute blanks for illegal ones
+ BYTE cChar = *p;
+ if( cChar == '!' || cChar == ':' || cChar == '\\' || cChar == '/' )
+ *p = ' ';
+ }
+}
+*/
+/*
+static void FromUnicode( String& rName )
+{
+ rName.Convert( CHARSET_ANSI, ::GetSystemCharSet() );
+}
+*/
+BOOL StgEntry::Init()
+{
+ memset( this, 0, sizeof (StgEntry) - sizeof( String ) );
+ SetLeaf( STG_LEFT, STG_FREE );
+ SetLeaf( STG_RIGHT, STG_FREE );
+ SetLeaf( STG_CHILD, STG_FREE );
+ SetLeaf( STG_DATA, STG_EOF );
+ return TRUE;
+}
+
+static String ToUpperUnicode( const String & rStr )
+{
+ // I don't know the locale, so en_US is hopefully fine
+ /*
+ com.sun.star.lang.Locale aLocale;
+ aLocale.Language = OUString::createFromAscii( "en" );
+ aLocale.Country = OUString::createFromAscii( "US" );
+ */
+ static rtl::OUString aEN=rtl::OUString::createFromAscii( "en" );
+ static rtl::OUString aUS=rtl::OUString::createFromAscii( "US" );
+ static CharClass aCC( com::sun::star::lang::Locale( aEN, aUS, rtl::OUString() ) );
+ return aCC.toUpper( rStr, 0, rStr.Len() );
+}
+
+
+BOOL StgEntry::SetName( const String& rName )
+{
+ // I don't know the locale, so en_US is hopefully fine
+ aName = ToUpperUnicode( rName );
+ aName.Erase( 31 );
+
+ int i;
+ for( i = 0; i < aName.Len() && i < 32; i++ )
+ nName[ i ] = rName.GetChar( sal_uInt16( i ));
+ while( i < 32 )
+ nName[ i++ ] = 0;
+ nNameLen = ( aName.Len() + 1 ) << 1;
+ return TRUE;
+}
+
+INT32 StgEntry::GetLeaf( StgEntryRef eRef ) const
+{
+ INT32 n = -1;
+ switch( eRef )
+ {
+ case STG_LEFT: n = nLeft; break;
+ case STG_RIGHT: n = nRight; break;
+ case STG_CHILD: n = nChild; break;
+ case STG_DATA: n = nPage1; break;
+ }
+ return n;
+}
+
+void StgEntry::SetLeaf( StgEntryRef eRef, INT32 nPage )
+{
+ switch( eRef )
+ {
+ case STG_LEFT: nLeft = nPage; break;
+ case STG_RIGHT: nRight = nPage; break;
+ case STG_CHILD: nChild = nPage; break;
+ case STG_DATA: nPage1 = nPage; break;
+ }
+}
+
+const INT32* StgEntry::GetTime( StgEntryTime eTime ) const
+{
+ return( eTime == STG_MODIFIED ) ? nMtime : nAtime;
+}
+
+void StgEntry::SetTime( StgEntryTime eTime, INT32* pTime )
+{
+ if( eTime == STG_MODIFIED )
+ nMtime[ 0 ] = *pTime++, nMtime[ 1 ] = *pTime;
+ else
+ nAtime[ 0 ] = *pTime++, nAtime[ 1 ] = *pTime;
+}
+
+void StgEntry::SetClassId( const ClsId& r )
+{
+ memcpy( &aClsId, &r, sizeof( ClsId ) );
+}
+
+void StgEntry::GetName( String& rName ) const
+{
+ UINT16 n = nNameLen;
+ if( n )
+ n = ( n >> 1 ) - 1;
+ rName = String( nName, n );
+}
+
+// Compare two entries. Do this case-insensitive.
+
+short StgEntry::Compare( const StgEntry& r ) const
+{
+ /*
+ short nRes = r.nNameLen - nNameLen;
+ if( !nRes ) return strcmp( r.aName, aName );
+ else return nRes;
+ */
+ sal_Int32 nRes = r.nNameLen - nNameLen;
+ if( !nRes )
+ nRes = r.aName.CompareTo( aName );
+ return (short)nRes;
+ //return aName.CompareTo( r.aName );
+}
+
+// These load/store operations are a bit more complicated,
+// since they have to copy their contents into a packed structure.
+
+BOOL StgEntry::Load( const void* pFrom )
+{
+ SvMemoryStream r( (sal_Char*) pFrom, 128, STREAM_READ );
+ for( short i = 0; i < 32; i++ )
+ r >> nName[ i ]; // 00 name as WCHAR
+ r >> nNameLen // 40 size of name in bytes including 00H
+ >> cType // 42 entry type
+ >> cFlags // 43 0 or 1 (tree balance?)
+ >> nLeft // 44 left node entry
+ >> nRight // 48 right node entry
+ >> nChild // 4C 1st child entry if storage
+ >> aClsId // 50 class ID (optional)
+ >> nFlags // 60 state flags(?)
+ >> nMtime[ 0 ] // 64 modification time
+ >> nMtime[ 1 ] // 64 modification time
+ >> nAtime[ 0 ] // 6C creation and access time
+ >> nAtime[ 1 ] // 6C creation and access time
+ >> nPage1 // 74 starting block (either direct or translated)
+ >> nSize // 78 file size
+ >> nUnknown; // 7C unknown
+
+ UINT16 n = nNameLen;
+ if( n )
+ n = ( n >> 1 ) - 1;
+ if( n > 31 || (nSize < 0 && cType != STG_STORAGE) )
+ {
+ // the size makes no sence for the substorage
+ // TODO/LATER: actually the size should be an unsigned value, but in this case it would mean a stream of more than 2Gb
+ return FALSE;
+ }
+
+ aName = String( nName, n );
+ // I don't know the locale, so en_US is hopefully fine
+ aName = ToUpperUnicode( aName );
+ aName.Erase( 31 );
+
+ return TRUE;
+}
+
+void StgEntry::Store( void* pTo )
+{
+ SvMemoryStream r( (sal_Char *)pTo, 128, STREAM_WRITE );
+ for( short i = 0; i < 32; i++ )
+ r << nName[ i ]; // 00 name as WCHAR
+ r << nNameLen // 40 size of name in bytes including 00H
+ << cType // 42 entry type
+ << cFlags // 43 0 or 1 (tree balance?)
+ << nLeft // 44 left node entry
+ << nRight // 48 right node entry
+ << nChild // 4C 1st child entry if storage;
+ << aClsId // 50 class ID (optional)
+ << nFlags // 60 state flags(?)
+ << nMtime[ 0 ] // 64 modification time
+ << nMtime[ 1 ] // 64 modification time
+ << nAtime[ 0 ] // 6C creation and access time
+ << nAtime[ 1 ] // 6C creation and access time
+ << nPage1 // 74 starting block (either direct or translated)
+ << nSize // 78 file size
+ << nUnknown; // 7C unknown
+}
+
diff --git a/sot/source/sdstor/stgelem.hxx b/sot/source/sdstor/stgelem.hxx
new file mode 100644
index 000000000000..7a5b7bc52b26
--- /dev/null
+++ b/sot/source/sdstor/stgelem.hxx
@@ -0,0 +1,166 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// This file reflects the structure of MS file elements.
+// It is very sensitive to alignment!
+
+#ifndef _STGELEM_HXX
+#define _STGELEM_HXX
+
+#ifndef _TOOLS_SOLAR_H
+#include <tools/solar.h>
+#endif
+
+#include <stg.hxx>
+
+class StgIo;
+class SvStream;
+class String;
+
+SvStream& operator>>( SvStream&, ClsId& );
+SvStream& operator<<( SvStream&, const ClsId& );
+
+class StgHeader
+{
+ BYTE cSignature[ 8 ]; // 00 signature (see below)
+ ClsId aClsId; // 08 Class ID
+ INT32 nVersion; // 18 version number
+ UINT16 nByteOrder; // 1C Unicode byte order indicator
+ INT16 nPageSize; // 1E 1 << nPageSize = block size
+ INT16 nDataPageSize; // 20 1 << this size == data block size
+ BYTE bDirty; // 22 internal dirty flag
+ BYTE cReserved[ 9 ]; // 23
+ INT32 nFATSize; // 2C total number of FAT pages
+ INT32 nTOCstrm; // 30 starting page for the TOC stream
+ INT32 nReserved; // 34
+ INT32 nThreshold; // 38 minimum file size for big data
+ INT32 nDataFAT; // 3C page # of 1st data FAT block
+ INT32 nDataFATSize; // 40 # of data fat blocks
+ INT32 nMasterChain; // 44 chain to the next master block
+ INT32 nMaster; // 48 # of additional master blocks
+ INT32 nMasterFAT[ 109 ]; // 4C first 109 master FAT pages
+public:
+ StgHeader();
+ void Init(); // initialize the header
+ BOOL Load( StgIo& );
+ BOOL Load( SvStream& );
+ BOOL Store( StgIo& );
+ BOOL Check(); // check the signature and version
+ short GetByteOrder() const { return nByteOrder; }
+ INT32 GetTOCStart() const { return nTOCstrm; }
+ void SetTOCStart( INT32 n );
+ INT32 GetDataFATStart() const { return nDataFAT; }
+ void SetDataFATStart( INT32 n );
+ INT32 GetDataFATSize() const { return nDataFATSize; }
+ void SetDataFATSize( INT32 n );
+ INT32 GetThreshold() const { return nThreshold; }
+ short GetPageSize() const { return nPageSize; }
+ short GetDataPageSize() const { return nDataPageSize; }
+ INT32 GetFATSize() const { return nFATSize; }
+ void SetFATSize( INT32 n );
+ INT32 GetFATChain() const { return nMasterChain; }
+ void SetFATChain( INT32 n );
+ INT32 GetMasters() const { return nMaster; }
+ void SetMasters( INT32 n );
+ short GetFAT1Size() const { return 109; }
+ const ClsId& GetClassId() const { return aClsId; }
+ void SetClassId( const ClsId& );
+ INT32 GetFATPage( short ) const;
+ void SetFATPage( short, INT32 );
+};
+
+enum StgEntryType { // dir entry types:
+ STG_EMPTY = 0,
+ STG_STORAGE = 1,
+ STG_STREAM = 2,
+ STG_LOCKBYTES = 3,
+ STG_PROPERTY = 4,
+ STG_ROOT = 5
+};
+
+enum StgEntryRef { // reference blocks:
+ STG_LEFT = 0, // left
+ STG_RIGHT = 1, // right
+ STG_CHILD = 2, // child
+ STG_DATA = 3 // data start
+};
+
+enum StgEntryTime { // time codes:
+ STG_MODIFIED = 0, // last modification
+ STG_ACCESSED = 1 // last access
+};
+
+class StgStream;
+
+#define STGENTRY_SIZE 128
+
+class StgEntry { // directory enty
+ UINT16 nName[ 32 ]; // 00 name as WCHAR
+ INT16 nNameLen; // 40 size of name in bytes including 00H
+ BYTE cType; // 42 entry type
+ BYTE cFlags; // 43 0 or 1 (tree balance?)
+ INT32 nLeft; // 44 left node entry
+ INT32 nRight; // 48 right node entry
+ INT32 nChild; // 4C 1st child entry if storage
+ ClsId aClsId; // 50 class ID (optional)
+ INT32 nFlags; // 60 state flags(?)
+ INT32 nMtime[ 2 ]; // 64 modification time
+ INT32 nAtime[ 2 ]; // 6C creation and access time
+ INT32 nPage1; // 74 starting block (either direct or translated)
+ INT32 nSize; // 78 file size
+ INT32 nUnknown; // 7C unknown
+ String aName; // Name as Compare String (ascii, upper)
+public:
+ BOOL Init(); // initialize the data
+ BOOL SetName( const String& ); // store a name (ASCII, up to 32 chars)
+ void GetName( String& rName ) const;
+ // fill in the name
+ short Compare( const StgEntry& ) const; // compare two entries
+ BOOL Load( const void* );
+ void Store( void* );
+ StgEntryType GetType() const { return (StgEntryType) cType; }
+ INT32 GetStartPage() const { return nPage1; }
+ void SetType( StgEntryType t ) { cType = (BYTE) t; }
+ BYTE GetFlags() const { return cFlags; }
+ void SetFlags( BYTE c ) { cFlags = c; }
+ INT32 GetSize() const { return nSize; }
+ void SetSize( INT32 n ) { nSize = n; }
+ const ClsId& GetClassId() const { return aClsId; }
+ void SetClassId( const ClsId& );
+ INT32 GetLeaf( StgEntryRef ) const;
+ void SetLeaf( StgEntryRef, INT32 );
+ const INT32* GetTime( StgEntryTime ) const;
+ void SetTime( StgEntryTime, INT32* );
+};
+
+
+#define STG_FREE -1L // page is free
+#define STG_EOF -2L // page is last page in chain
+#define STG_FAT -3L // page is FAT page
+#define STG_MASTER -4L // page is master FAT page
+
+#endif
diff --git a/sot/source/sdstor/stgio.cxx b/sot/source/sdstor/stgio.cxx
new file mode 100644
index 000000000000..2c18429b9d64
--- /dev/null
+++ b/sot/source/sdstor/stgio.cxx
@@ -0,0 +1,389 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sot.hxx"
+
+#include "stg.hxx"
+#include "stgelem.hxx"
+#include "stgcache.hxx"
+#include "stgstrms.hxx"
+#include "stgdir.hxx"
+#include "stgio.hxx"
+#include <rtl/instance.hxx>
+
+///////////////////////////// class StgIo //////////////////////////////
+
+// This class holds the storage header and all internal streams.
+
+StgIo::StgIo() : StgCache()
+{
+ pTOC = NULL;
+ pDataFAT = NULL;
+ pDataStrm = NULL;
+ pFAT = NULL;
+ bCopied = FALSE;
+}
+
+StgIo::~StgIo()
+{
+ delete pTOC;
+ delete pDataFAT;
+ delete pDataStrm;
+ delete pFAT;
+}
+
+// Load the header. Do not set an error code if the header is invalid.
+
+BOOL StgIo::Load()
+{
+ if( pStrm )
+ {
+ if( aHdr.Load( *this ) )
+ {
+ if( aHdr.Check() )
+ SetupStreams();
+ else
+ return FALSE;
+ }
+ }
+ return Good();
+}
+
+// Set up an initial, empty storage
+
+BOOL StgIo::Init()
+{
+ aHdr.Init();
+ SetupStreams();
+ return CommitAll();
+}
+
+void StgIo::SetupStreams()
+{
+ delete pTOC;
+ delete pDataFAT;
+ delete pDataStrm;
+ delete pFAT;
+ pTOC = NULL;
+ pDataFAT = NULL;
+ pDataStrm = NULL;
+ pFAT = NULL;
+ ResetError();
+ SetPhysPageSize( 1 << aHdr.GetPageSize() );
+ pFAT = new StgFATStrm( *this );
+ pTOC = new StgDirStrm( *this );
+ if( !GetError() )
+ {
+ StgDirEntry* pRoot = pTOC->GetRoot();
+ if( pRoot )
+ {
+ pDataFAT = new StgDataStrm( *this, aHdr.GetDataFATStart(), -1 );
+ pDataStrm = new StgDataStrm( *this, pRoot );
+ pDataFAT->SetIncrement( 1 << aHdr.GetPageSize() );
+ pDataStrm->SetIncrement( GetDataPageSize() );
+ pDataStrm->SetEntry( *pRoot );
+ }
+ else
+ SetError( SVSTREAM_FILEFORMAT_ERROR );
+ }
+}
+
+// get the logical data page size
+
+short StgIo::GetDataPageSize()
+{
+ return 1 << aHdr.GetDataPageSize();
+}
+
+// Commit everything
+
+BOOL StgIo::CommitAll()
+{
+ // Store the data (all streams and the TOC)
+ if( pTOC->Store() )
+ {
+ if( Commit( NULL ) )
+ {
+ aHdr.SetDataFATStart( pDataFAT->GetStart() );
+ aHdr.SetDataFATSize( pDataFAT->GetPages() );
+ aHdr.SetTOCStart( pTOC->GetStart() );
+ if( aHdr.Store( *this ) )
+ {
+ pStrm->Flush();
+ ULONG n = pStrm->GetError();
+ SetError( n );
+#ifdef DBG_UTIL
+ if( n==0 ) ValidateFATs();
+#endif
+ return BOOL( n == 0 );
+ }
+ }
+ }
+ SetError( SVSTREAM_WRITE_ERROR );
+ return FALSE;
+}
+
+
+class EasyFat
+{
+ INT32 *pFat;
+ BOOL *pFree;
+ INT32 nPages;
+ INT32 nPageSize;
+
+public:
+ EasyFat( StgIo & rIo, StgStrm *pFatStream, INT32 nPSize );
+ ~EasyFat() { delete[] pFat; delete[] pFree; }
+ INT32 GetPageSize() { return nPageSize; }
+ INT32 Count() { return nPages; }
+ INT32 operator[]( INT32 nOffset ) { return pFat[ nOffset ]; }
+
+ ULONG Mark( INT32 nPage, INT32 nCount, INT32 nExpect );
+ BOOL HasUnrefChains();
+};
+
+EasyFat::EasyFat( StgIo& rIo, StgStrm* pFatStream, INT32 nPSize )
+{
+ nPages = pFatStream->GetSize() >> 2;
+ nPageSize = nPSize;
+ pFat = new INT32[ nPages ];
+ pFree = new BOOL[ nPages ];
+
+ StgPage *pPage = NULL;
+ INT32 nFatPageSize = (1 << rIo.aHdr.GetPageSize()) - 2;
+
+ for( INT32 nPage = 0; nPage < nPages; nPage++ )
+ {
+ if( ! (nPage % nFatPageSize) )
+ {
+ pFatStream->Pos2Page( nPage << 2 );
+ INT32 nPhysPage = pFatStream->GetPage();
+ pPage = rIo.Get( nPhysPage, TRUE );
+ }
+
+ pFat[ nPage ] = pPage->GetPage( short( nPage % nFatPageSize ) );
+ pFree[ nPage ] = TRUE;
+ }
+}
+
+BOOL EasyFat::HasUnrefChains()
+{
+ for( INT32 nPage = 0; nPage < nPages; nPage++ )
+ {
+ if( pFree[ nPage ] && pFat[ nPage ] != -1 )
+ return TRUE;
+ }
+ return FALSE;
+}
+
+ULONG EasyFat::Mark( INT32 nPage, INT32 nCount, INT32 nExpect )
+{
+ if( nCount > 0 )
+ --nCount /= GetPageSize(), nCount++;
+
+ INT32 nCurPage = nPage;
+ while( nCount != 0 )
+ {
+ pFree[ nCurPage ] = FALSE;
+ nCurPage = pFat[ nCurPage ];
+ //Stream zu lang
+ if( nCurPage != nExpect && nCount == 1 )
+ return FAT_WRONGLENGTH;
+ //Stream zu kurz
+ if( nCurPage == nExpect && nCount != 1 && nCount != -1 )
+ return FAT_WRONGLENGTH;
+ // letzter Block bei Stream ohne Laenge
+ if( nCurPage == nExpect && nCount == -1 )
+ nCount = 1;
+ if( nCount != -1 )
+ nCount--;
+ // Naechster Block nicht in der FAT
+ if( nCount && ( nCurPage < 0 || nCurPage >= nPages ) )
+ return FAT_OUTOFBOUNDS;
+ }
+ return FAT_OK;
+}
+
+class Validator
+{
+ ULONG nError;
+
+ EasyFat aSmallFat;
+ EasyFat aFat;
+
+ StgIo &rIo;
+
+ ULONG ValidateMasterFATs();
+ ULONG ValidateDirectoryEntries();
+ ULONG FindUnrefedChains();
+ ULONG MarkAll( StgDirEntry *pEntry );
+
+public:
+
+ Validator( StgIo &rIo );
+ BOOL IsError() { return nError != 0; }
+};
+
+Validator::Validator( StgIo &rIoP )
+ : aSmallFat( rIoP, rIoP.pDataFAT, 1 << rIoP.aHdr.GetDataPageSize() ),
+ aFat( rIoP, rIoP.pFAT, 1 << rIoP.aHdr.GetPageSize() ),
+ rIo( rIoP )
+{
+ ULONG nErr = nError = FAT_OK;
+
+ if( ( nErr = ValidateMasterFATs() ) != FAT_OK )
+ nError = nErr;
+ else if( ( nErr = ValidateDirectoryEntries() ) != FAT_OK )
+ nError = nErr;
+ else if( ( nErr = FindUnrefedChains()) != FAT_OK )
+ nError = nErr;
+}
+
+ULONG Validator::ValidateMasterFATs()
+{
+ INT32 nCount = rIo.aHdr.GetFATSize();
+ ULONG nErr;
+ for( INT32 i = 0; i < nCount; i++ )
+ {
+ if( ( nErr = aFat.Mark(rIo.pFAT->GetPage( short(i), FALSE ), aFat.GetPageSize(), -3 )) != FAT_OK )
+ return nErr;
+ }
+ if( rIo.aHdr.GetMasters() )
+ if( ( nErr = aFat.Mark(rIo.aHdr.GetFATChain( ), aFat.GetPageSize(), -4 )) != FAT_OK )
+ return nErr;
+ return FAT_OK;
+}
+
+ULONG Validator::MarkAll( StgDirEntry *pEntry )
+{
+ StgIterator aIter( *pEntry );
+ ULONG nErr = FAT_OK;
+ for( StgDirEntry* p = aIter.First(); p ; p = aIter.Next() )
+ {
+ if( p->aEntry.GetType() == STG_STORAGE )
+ {
+ nErr = MarkAll( p );
+ if( nErr != FAT_OK )
+ return nErr;
+ }
+ else
+ {
+ INT32 nSize = p->aEntry.GetSize();
+ if( nSize < rIo.aHdr.GetThreshold() )
+ nErr = aSmallFat.Mark( p->aEntry.GetStartPage(),nSize, -2 );
+ else
+ nErr = aFat.Mark( p->aEntry.GetStartPage(),nSize, -2 );
+ if( nErr != FAT_OK )
+ return nErr;
+ }
+ }
+ return FAT_OK;
+}
+
+ULONG Validator::ValidateDirectoryEntries()
+{
+ // Normale DirEntries
+ ULONG nErr = MarkAll( rIo.pTOC->GetRoot() );
+ if( nErr != FAT_OK )
+ return nErr;
+ // Small Data
+ nErr = aFat.Mark( rIo.pTOC->GetRoot()->aEntry.GetStartPage(),
+ rIo.pTOC->GetRoot()->aEntry.GetSize(), -2 );
+ if( nErr != FAT_OK )
+ return nErr;
+ // Small Data FAT
+ nErr = aFat.Mark(
+ rIo.aHdr.GetDataFATStart(),
+ rIo.aHdr.GetDataFATSize() * aFat.GetPageSize(), -2 );
+ if( nErr != FAT_OK )
+ return nErr;
+ // TOC
+ nErr = aFat.Mark(
+ rIo.aHdr.GetTOCStart(), -1, -2 );
+ return nErr;
+}
+
+ULONG Validator::FindUnrefedChains()
+{
+ if( aSmallFat.HasUnrefChains() ||
+ aFat.HasUnrefChains() )
+ return FAT_UNREFCHAIN;
+ else
+ return FAT_OK;
+}
+
+namespace { struct ErrorLink : public rtl::Static<Link, ErrorLink > {}; }
+
+void StgIo::SetErrorLink( const Link& rLink )
+{
+ ErrorLink::get() = rLink;
+}
+
+const Link& StgIo::GetErrorLink()
+{
+ return ErrorLink::get();
+}
+
+ULONG StgIo::ValidateFATs()
+{
+ if( bFile )
+ {
+ Validator *pV = new Validator( *this );
+ BOOL bRet1 = !pV->IsError(), bRet2 = TRUE ;
+ delete pV;
+ SvFileStream *pFileStrm = ( SvFileStream *) GetStrm();
+ StgIo aIo;
+ if( aIo.Open( pFileStrm->GetFileName(),
+ STREAM_READ | STREAM_SHARE_DENYNONE) &&
+ aIo.Load() )
+ {
+ pV = new Validator( aIo );
+ bRet2 = !pV->IsError();
+ delete pV;
+ }
+
+ ULONG nErr;
+ if( bRet1 != bRet2 )
+ nErr = bRet1 ? FAT_ONFILEERROR : FAT_INMEMORYERROR;
+ else nErr = bRet1 ? FAT_OK : FAT_BOTHERROR;
+ if( nErr != FAT_OK && !bCopied )
+ {
+ StgLinkArg aArg;
+ aArg.aFile = pFileStrm->GetFileName();
+ aArg.nErr = nErr;
+ ErrorLink::get().Call( &aArg );
+ bCopied = TRUE;
+ }
+// DBG_ASSERT( nErr == FAT_OK ,"Storage kaputt");
+ return nErr;
+ }
+// DBG_ERROR("Validiere nicht (kein FileStorage)");
+ return FAT_OK;
+}
+
+
diff --git a/sot/source/sdstor/stgio.hxx b/sot/source/sdstor/stgio.hxx
new file mode 100644
index 000000000000..db1c00b8d521
--- /dev/null
+++ b/sot/source/sdstor/stgio.hxx
@@ -0,0 +1,80 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _STGIO_HXX
+#define _STGIO_HXX
+
+#include <stgcache.hxx>
+#include <stgelem.hxx>
+#include <tools/string.hxx>
+
+class StgFATStrm;
+class StgDataStrm;
+class StgDirStrm;
+class String;
+
+enum FAT_ERROR
+{
+ FAT_OK,
+ FAT_WRONGLENGTH,
+ FAT_UNREFCHAIN,
+ FAT_OVERWRITE,
+ FAT_OUTOFBOUNDS,
+
+ FAT_INMEMORYERROR,
+ FAT_ONFILEERROR,
+ FAT_BOTHERROR
+};
+
+struct StgLinkArg
+{
+ String aFile;
+ ULONG nErr;
+};
+
+class StgIo : public StgCache {
+ void SetupStreams(); // load all internal streams
+ BOOL bCopied;
+public:
+ StgIo();
+ ~StgIo();
+ StgHeader aHdr; // storage file header
+ StgFATStrm* pFAT; // FAT stream
+ StgDirStrm* pTOC; // TOC stream
+ StgDataStrm* pDataFAT; // small data FAT stream
+ StgDataStrm* pDataStrm; // small data stream
+ short GetDataPageSize(); // get the logical data page size
+ BOOL Load(); // load a storage file
+ BOOL Init(); // set up an empty file
+ BOOL CommitAll(); // commit everything (root commit)
+
+ static void SetErrorLink( const Link& );
+ static const Link& GetErrorLink();
+ ULONG ValidateFATs( );
+};
+
+#endif
diff --git a/sot/source/sdstor/stgole.cxx b/sot/source/sdstor/stgole.cxx
new file mode 100644
index 000000000000..148f1e87585c
--- /dev/null
+++ b/sot/source/sdstor/stgole.cxx
@@ -0,0 +1,230 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sot.hxx"
+
+#include "rtl/string.h"
+#include "rtl/string.h"
+#include "stgole.hxx"
+#include "storinfo.hxx" // Read/WriteClipboardFormat()
+
+#include <tools/debug.hxx>
+#if defined(_MSC_VER) && (_MSC_VER>=1400)
+#pragma warning(disable: 4342)
+#endif
+///////////////////////// class StgInternalStream ////////////////////////
+
+StgInternalStream::StgInternalStream
+ ( BaseStorage& rStg, const String& rName, BOOL bWr )
+{
+ bIsWritable = TRUE;
+ USHORT nMode = bWr
+ ? STREAM_WRITE | STREAM_SHARE_DENYALL
+ : STREAM_READ | STREAM_SHARE_DENYWRITE | STREAM_NOCREATE;
+ pStrm = rStg.OpenStream( rName, nMode );
+
+ // set the error code right here in the stream
+ SetError( rStg.GetError() );
+ SetBufferSize( 1024 );
+}
+
+StgInternalStream::~StgInternalStream()
+{
+ delete pStrm;
+}
+
+ULONG StgInternalStream::GetData( void* pData, ULONG nSize )
+{
+ if( pStrm )
+ {
+ nSize = pStrm->Read( pData, nSize );
+ SetError( pStrm->GetError() );
+ return nSize;
+ }
+ else
+ return 0;
+}
+
+ULONG StgInternalStream::PutData( const void* pData, ULONG nSize )
+{
+ if( pStrm )
+ {
+ nSize = pStrm->Write( pData, nSize );
+ SetError( pStrm->GetError() );
+ return nSize;
+ }
+ else
+ return 0;
+}
+
+ULONG StgInternalStream::SeekPos( ULONG nPos )
+{
+ return pStrm ? pStrm->Seek( nPos ) : 0;
+}
+
+void StgInternalStream::FlushData()
+{
+ if( pStrm )
+ {
+ pStrm->Flush();
+ SetError( pStrm->GetError() );
+ }
+}
+
+void StgInternalStream::Commit()
+{
+ Flush();
+ pStrm->Commit();
+}
+
+///////////////////////// class StgCompObjStream /////////////////////////
+
+StgCompObjStream::StgCompObjStream( BaseStorage& rStg, BOOL bWr )
+ : StgInternalStream( rStg, String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\1CompObj" ) ), bWr )
+{
+ memset( &aClsId, 0, sizeof( ClsId ) );
+ nCbFormat = 0;
+}
+
+BOOL StgCompObjStream::Load()
+{
+ memset( &aClsId, 0, sizeof( ClsId ) );
+ nCbFormat = 0;
+ aUserName.Erase();
+ if( GetError() != SVSTREAM_OK )
+ return FALSE;
+ Seek( 8L ); // skip the first part
+ INT32 nMarker = 0;
+ *this >> nMarker;
+ if( nMarker == -1L )
+ {
+ *this >> aClsId;
+ INT32 nLen1 = 0;
+ *this >> nLen1;
+ // higher bits are ignored
+ nLen1 &= 0xFFFF;
+ sal_Char* p = new sal_Char[ (USHORT) nLen1 ];
+ if( Read( p, nLen1 ) == (ULONG) nLen1 )
+ {
+ aUserName = nLen1 ? String( p, gsl_getSystemTextEncoding() ) : String();
+/* // Now we can read the CB format
+ INT32 nLen2 = 0;
+ *this >> nLen2;
+ if( nLen2 > 0 )
+ {
+ // get a string name
+ if( nLen2 > nLen1 )
+ delete p, p = new char[ nLen2 ];
+ if( Read( p, nLen2 ) == (ULONG) nLen2 && nLen2 )
+ nCbFormat = Exchange::RegisterFormatName( String( p ) );
+ else
+ SetError( SVSTREAM_GENERALERROR );
+ }
+ else if( nLen2 == -1L )
+ // Windows clipboard format
+ *this >> nCbFormat;
+ else
+ // unknown identifier
+ SetError( SVSTREAM_GENERALERROR );
+*/
+ nCbFormat = ReadClipboardFormat( *this );
+ }
+ else
+ SetError( SVSTREAM_GENERALERROR );
+ delete [] p;
+ }
+ return BOOL( GetError() == SVSTREAM_OK );
+}
+
+BOOL StgCompObjStream::Store()
+{
+ if( GetError() != SVSTREAM_OK )
+ return FALSE;
+ Seek( 0L );
+ ByteString aAsciiUserName( aUserName, RTL_TEXTENCODING_ASCII_US );
+ *this << (INT16) 1 // Version?
+ << (INT16) -2 // 0xFFFE = Byte Order Indicator
+ << (INT32) 0x0A03 // Windows 3.10
+ << (INT32) -1L
+ << aClsId // Class ID
+ << (INT32) (aAsciiUserName.Len() + 1)
+ << (const char *)aAsciiUserName.GetBuffer()
+ << (UINT8) 0; // string terminator
+/* // determine the clipboard format string
+ String aCbFmt;
+ if( nCbFormat > FORMAT_GDIMETAFILE )
+ aCbFmt = Exchange::GetFormatName( nCbFormat );
+ if( aCbFmt.Len() )
+ *this << (INT32) aCbFmt.Len() + 1
+ << (const char*) aCbFmt
+ << (UINT8) 0;
+ else if( nCbFormat )
+ *this << (INT32) -1 // for Windows
+ << (INT32) nCbFormat;
+ else
+ *this << (INT32) 0; // no clipboard format
+*/
+ WriteClipboardFormat( *this, nCbFormat );
+ *this << (INT32) 0; // terminator
+ Commit();
+ return BOOL( GetError() == SVSTREAM_OK );
+}
+
+/////////////////////////// class StgOleStream ///////////////////////////
+
+StgOleStream::StgOleStream( BaseStorage& rStg, BOOL bWr )
+ : StgInternalStream( rStg, String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\1Ole" ) ), bWr )
+{
+ nFlags = 0;
+}
+
+BOOL StgOleStream::Load()
+{
+ nFlags = 0;
+ if( GetError() != SVSTREAM_OK )
+ return FALSE;
+ INT32 version = 0;
+ Seek( 0L );
+ *this >> version >> nFlags;
+ return BOOL( GetError() == SVSTREAM_OK );
+}
+
+BOOL StgOleStream::Store()
+{
+ if( GetError() != SVSTREAM_OK )
+ return FALSE;
+ Seek( 0L );
+ *this << (INT32) 0x02000001 // OLE version, format
+ << (INT32) nFlags // Object flags
+ << (INT32) 0 // Update Options
+ << (INT32) 0 // reserved
+ << (INT32) 0; // Moniker 1
+ Commit();
+ return BOOL( GetError() == SVSTREAM_OK );
+}
+
diff --git a/sot/source/sdstor/stgole.hxx b/sot/source/sdstor/stgole.hxx
new file mode 100644
index 000000000000..346f21035f06
--- /dev/null
+++ b/sot/source/sdstor/stgole.hxx
@@ -0,0 +1,77 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SDSTOR_STGOLE_HXX
+#define _SDSTOR_STGOLE_HXX
+
+#include <string.h> // memset()
+
+#include "stg.hxx"
+#include "stgelem.hxx"
+
+class StgInternalStream : public SvStream
+{
+ BaseStorageStream* pStrm;
+ virtual ULONG GetData( void* pData, ULONG nSize );
+ virtual ULONG PutData( const void* pData, ULONG nSize );
+ virtual ULONG SeekPos( ULONG nPos );
+ virtual void FlushData();
+public:
+ StgInternalStream( BaseStorage&, const String&, BOOL );
+ ~StgInternalStream();
+ void Commit();
+};
+
+// standard stream "\1CompObj"
+
+class StgCompObjStream : public StgInternalStream
+{
+ ClsId aClsId;
+ String aUserName;
+ ULONG nCbFormat;
+public:
+ StgCompObjStream( BaseStorage&, BOOL );
+ ClsId& GetClsId() { return aClsId; }
+ String& GetUserName() { return aUserName; }
+ ULONG& GetCbFormat() { return nCbFormat; }
+ BOOL Load();
+ BOOL Store();
+};
+
+// standard stream "\1Ole"
+
+class StgOleStream : public StgInternalStream
+{
+ sal_uInt32 nFlags;
+public:
+ StgOleStream( BaseStorage&, BOOL );
+ sal_uInt32& GetFlags() { return nFlags; }
+ BOOL Load();
+ BOOL Store();
+};
+
+#endif
diff --git a/sot/source/sdstor/stgstrms.cxx b/sot/source/sdstor/stgstrms.cxx
new file mode 100644
index 000000000000..dd6ba6202bbe
--- /dev/null
+++ b/sot/source/sdstor/stgstrms.cxx
@@ -0,0 +1,1241 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sot.hxx"
+
+#include <string.h> // memcpy()
+
+#include <osl/file.hxx>
+#include <tools/tempfile.hxx>
+#include <tools/debug.hxx>
+
+#include "stg.hxx"
+#include "stgelem.hxx"
+#include "stgcache.hxx"
+#include "stgstrms.hxx"
+#include "stgdir.hxx"
+#include "stgio.hxx"
+
+#define __HUGE
+
+///////////////////////////// class StgFAT ///////////////////////////////
+
+// The FAT class performs FAT operations on an underlying storage stream.
+// This stream is either the master FAT stream (m == TRUE ) or a normal
+// storage stream, which then holds the FAT for small data allocations.
+
+StgFAT::StgFAT( StgStrm& r, BOOL m ) : rStrm( r )
+{
+ bPhys = m;
+ nPageSize = rStrm.GetIo().GetPhysPageSize();
+ nEntries = nPageSize >> 2;
+ nOffset = 0;
+ nMaxPage = 0;
+ nLimit = 0;
+}
+
+// Retrieve the physical page for a given byte offset.
+
+StgPage* StgFAT::GetPhysPage( INT32 nByteOff )
+{
+ StgPage* pPg = NULL;
+ // Position within the underlying stream
+ // use the Pos2Page() method of the stream
+ if( rStrm.Pos2Page( nByteOff ) )
+ {
+ nOffset = rStrm.GetOffset();
+ INT32 nPhysPage = rStrm.GetPage();
+ // get the physical page (must be present)
+ pPg = rStrm.GetIo().Get( nPhysPage, TRUE );
+ }
+ return pPg;
+}
+
+// Get the follow page for a certain FAT page.
+
+INT32 StgFAT::GetNextPage( INT32 nPg )
+{
+ if( nPg >= 0 )
+ {
+ StgPage* pPg = GetPhysPage( nPg << 2 );
+ nPg = pPg ? pPg->GetPage( nOffset >> 2 ) : STG_EOF;
+ }
+ return nPg;
+}
+
+// Find the best fit block for the given size. Return
+// the starting block and its size or STG_EOF and 0.
+// nLastPage is a stopper which tells the current
+// underlying stream size. It is treated as a recommendation
+// to abort the search to inhibit excessive file growth.
+
+INT32 StgFAT::FindBlock( INT32& nPgs )
+{
+ INT32 nMinStart = STG_EOF, nMinLen = 0;
+ INT32 nMaxStart = STG_EOF, nMaxLen = 0x7FFFFFFFL;
+ INT32 nTmpStart = STG_EOF, nTmpLen = 0;
+ INT32 nPages = rStrm.GetSize() >> 2;
+ BOOL bFound = FALSE;
+ StgPage* pPg = NULL;
+ short nEntry = 0;
+ for( INT32 i = 0; i < nPages; i++, nEntry++ )
+ {
+ if( !( nEntry % nEntries ) )
+ {
+ // load the next page for that stream
+ nEntry = 0;
+ pPg = GetPhysPage( i << 2 );
+ if( !pPg )
+ return STG_EOF;
+ }
+ INT32 nCur = pPg->GetPage( nEntry );
+ if( nCur == STG_FREE )
+ {
+ // count the size of this area
+ if( nTmpLen )
+ nTmpLen++;
+ else
+ nTmpStart = i,
+ nTmpLen = 1;
+ if( nTmpLen == nPgs
+ // If we already did find a block, stop when reaching the limit
+ || ( bFound && ( nEntry >= nLimit ) ) )
+ break;
+ }
+ else if( nTmpLen )
+ {
+ if( nTmpLen > nPgs && nTmpLen < nMaxLen )
+ // block > requested size
+ nMaxLen = nTmpLen, nMaxStart = nTmpStart, bFound = TRUE;
+ else if( nTmpLen >= nMinLen )
+ {
+ // block < requested size
+ nMinLen = nTmpLen, nMinStart = nTmpStart;
+ bFound = TRUE;
+ if( nTmpLen == nPgs )
+ break;
+ }
+ nTmpStart = STG_EOF;
+ nTmpLen = 0;
+ }
+ }
+ // Determine which block to use.
+ if( nTmpLen )
+ {
+ if( nTmpLen > nPgs && nTmpLen < nMaxLen )
+ // block > requested size
+ nMaxLen = nTmpLen, nMaxStart = nTmpStart;
+ else if( nTmpLen >= nMinLen )
+ // block < requested size
+ nMinLen = nTmpLen, nMinStart = nTmpStart;
+ }
+ if( nMinStart != STG_EOF && nMaxStart != STG_EOF )
+ {
+ // two areas found; return the best fit area
+ INT32 nMinDiff = nPgs - nMinLen;
+ INT32 nMaxDiff = nMaxLen - nPgs;
+ if( nMinDiff > nMaxDiff )
+ nMinStart = STG_EOF;
+ }
+ if( nMinStart != STG_EOF )
+ {
+ nPgs = nMinLen; return nMinStart;
+ }
+ else
+ {
+ return nMaxStart;
+ }
+}
+
+// Set up the consecutive chain for a given block.
+
+BOOL StgFAT::MakeChain( INT32 nStart, INT32 nPgs )
+{
+ INT32 nPos = nStart << 2;
+ StgPage* pPg = GetPhysPage( nPos );
+ if( !pPg || !nPgs )
+ return FALSE;
+ while( --nPgs )
+ {
+ if( nOffset >= nPageSize )
+ {
+ pPg = GetPhysPage( nPos );
+ if( !pPg )
+ return FALSE;
+ }
+ pPg->SetPage( nOffset >> 2, ++nStart );
+ nOffset += 4;
+ nPos += 4;
+ }
+ if( nOffset >= nPageSize )
+ {
+ pPg = GetPhysPage( nPos );
+ if( !pPg )
+ return FALSE;
+ }
+ pPg->SetPage( nOffset >> 2, STG_EOF );
+ return TRUE;
+}
+
+// Allocate a block of data from the given page number on.
+// It the page number is != STG_EOF, chain the block.
+
+INT32 StgFAT::AllocPages( INT32 nBgn, INT32 nPgs )
+{
+ INT32 nOrig = nBgn;
+ INT32 nLast = nBgn;
+ INT32 nBegin = STG_EOF;
+ INT32 nAlloc;
+ INT32 nPages = rStrm.GetSize() >> 2;
+ short nPasses = 0;
+ // allow for two passes
+ while( nPasses < 2 )
+ {
+ // try to satisfy the request from the pool of free pages
+ while( nPgs )
+ {
+ nAlloc = nPgs;
+ nBegin = FindBlock( nAlloc );
+ // no more blocks left in present alloc chain
+ if( nBegin == STG_EOF )
+ break;
+ if( ( nBegin + nAlloc ) > nMaxPage )
+ nMaxPage = nBegin + nAlloc;
+ if( !MakeChain( nBegin, nAlloc ) )
+ return STG_EOF;
+ if( nOrig == STG_EOF )
+ nOrig = nBegin;
+ else
+ {
+ // Patch the chain
+ StgPage* pPg = GetPhysPage( nLast << 2 );
+ if( !pPg )
+ return STG_EOF;
+ pPg->SetPage( nOffset >> 2, nBegin );
+ }
+ nLast = nBegin + nAlloc - 1;
+ nPgs -= nAlloc;
+ }
+ if( nPgs && !nPasses )
+ {
+ // we need new, fresh space, so allocate and retry
+ if( !rStrm.SetSize( ( nPages + nPgs ) << 2 ) )
+ return STG_EOF;
+ if( !bPhys && !InitNew( nPages ) )
+ return FALSE;
+ nPages = rStrm.GetSize() >> 2;
+ nPasses++;
+ }
+ else
+ break;
+ }
+ // now we should have a chain for the complete block
+ if( nBegin == STG_EOF || nPgs )
+ {
+ rStrm.GetIo().SetError( SVSTREAM_FILEFORMAT_ERROR );
+ return STG_EOF; // bad structure
+ }
+ return nOrig;
+}
+
+// Initialize newly allocated pages for a standard FAT stream
+// It can be assumed that the stream size is always on
+// a page boundary
+
+BOOL StgFAT::InitNew( INT32 nPage1 )
+{
+ INT32 n = ( ( rStrm.GetSize() >> 2 ) - nPage1 ) / nEntries;
+ while( n-- )
+ {
+ StgPage* pPg = NULL;
+ // Position within the underlying stream
+ // use the Pos2Page() method of the stream
+ rStrm.Pos2Page( nPage1 << 2 );
+ // Initialize the page
+ pPg = rStrm.GetIo().Copy( rStrm.GetPage(), STG_FREE );
+ if ( !pPg )
+ return FALSE;
+ for( short i = 0; i < nEntries; i++ )
+ pPg->SetPage( i, STG_FREE );
+ nPage1++;
+ }
+ return TRUE;
+}
+
+// Release a chain
+
+BOOL StgFAT::FreePages( INT32 nStart, BOOL bAll )
+{
+ while( nStart >= 0 )
+ {
+ StgPage* pPg = GetPhysPage( nStart << 2 );
+ if( !pPg )
+ return FALSE;
+ nStart = pPg->GetPage( nOffset >> 2 );
+ // The first released page is either set to EOF or FREE
+ pPg->SetPage( nOffset >> 2, bAll ? STG_FREE : STG_EOF );
+ bAll = TRUE;
+ }
+ return TRUE;
+}
+
+///////////////////////////// class StgStrm ////////////////////////////////
+
+// The base stream class provides basic functionality for seeking
+// and accessing the data on a physical basis. It uses the built-in
+// FAT class for the page allocations.
+
+StgStrm::StgStrm( StgIo& r ) : rIo( r )
+{
+ pFat = NULL;
+ nStart = nPage = STG_EOF;
+ nOffset = 0;
+ pEntry = NULL;
+ nPos = nSize = 0;
+ nPageSize = rIo.GetPhysPageSize();
+}
+
+StgStrm::~StgStrm()
+{
+ delete pFat;
+}
+
+// Attach the stream to the given entry.
+
+void StgStrm::SetEntry( StgDirEntry& r )
+{
+ r.aEntry.SetLeaf( STG_DATA, nStart );
+ r.aEntry.SetSize( nSize );
+ pEntry = &r;
+ r.SetDirty();
+}
+
+// Compute page number and offset for the given byte position.
+// If the position is behind the size, set the stream right
+// behind the EOF.
+
+BOOL StgStrm::Pos2Page( INT32 nBytePos )
+{
+ INT32 nRel, nBgn;
+ // Values < 0 seek to the end
+ if( nBytePos < 0 || nBytePos >= nSize )
+ nBytePos = nSize;
+ // Adjust the position back to offset 0
+ nPos -= nOffset;
+ INT32 nMask = ~( nPageSize - 1 );
+ INT32 nOld = nPos & nMask;
+ INT32 nNew = nBytePos & nMask;
+ nOffset = (short) ( nBytePos & ~nMask );
+ nPos = nBytePos;
+ if( nOld == nNew )
+ return TRUE;
+ if( nNew > nOld )
+ {
+ // the new position is behind the current, so an incremental
+ // positioning is OK. Set the page relative position
+ nRel = nNew - nOld;
+ nBgn = nPage;
+ }
+ else
+ {
+ // the new position is before the current, so we have to scan
+ // the entire chain.
+ nRel = nNew;
+ nBgn = nStart;
+ }
+ // now, traverse the FAT chain.
+ nRel /= nPageSize;
+ INT32 nLast = STG_EOF;
+ while( nRel && nBgn >= 0 )
+ {
+ nLast = nBgn;
+ nBgn = pFat->GetNextPage( nBgn );
+ nRel--;
+ }
+ // special case: seek to 1st byte of new, unallocated page
+ // (in case the file size is a multiple of the page size)
+ if( nBytePos == nSize && nBgn == STG_EOF && !nRel && !nOffset )
+ nBgn = nLast, nOffset = nPageSize;
+ if( nBgn < 0 && nBgn != STG_EOF )
+ {
+ rIo.SetError( SVSTREAM_FILEFORMAT_ERROR );
+ nBgn = STG_EOF;
+ nOffset = nPageSize;
+ }
+ nPage = nBgn;
+ return BOOL( nRel == 0 && nPage >= 0 );
+}
+
+// Retrieve the physical page for a given byte offset.
+
+StgPage* StgStrm::GetPhysPage( INT32 nBytePos, BOOL bForce )
+{
+ if( !Pos2Page( nBytePos ) )
+ return NULL;
+ return rIo.Get( nPage, bForce );
+}
+
+// Copy an entire stream. Both streams are allocated in the FAT.
+// The target stream is this stream.
+
+BOOL StgStrm::Copy( INT32 nFrom, INT32 nBytes )
+{
+ INT32 nTo = nStart;
+ INT32 nPgs = ( nBytes + nPageSize - 1 ) / nPageSize;
+ while( nPgs-- )
+ {
+ if( nTo < 0 )
+ {
+ rIo.SetError( SVSTREAM_FILEFORMAT_ERROR );
+ return FALSE;
+ }
+ rIo.Copy( nTo, nFrom );
+ if( nFrom >= 0 )
+ {
+ nFrom = pFat->GetNextPage( nFrom );
+ if( nFrom < 0 )
+ {
+ rIo.SetError( SVSTREAM_FILEFORMAT_ERROR );
+ return FALSE;
+ }
+ }
+ nTo = pFat->GetNextPage( nTo );
+ }
+ return TRUE;
+}
+
+BOOL StgStrm::SetSize( INT32 nBytes )
+{
+ // round up to page size
+ INT32 nOld = ( ( nSize + nPageSize - 1 ) / nPageSize ) * nPageSize;
+ INT32 nNew = ( ( nBytes + nPageSize - 1 ) / nPageSize ) * nPageSize;
+ if( nNew > nOld )
+ {
+ if( !Pos2Page( nSize ) )
+ return FALSE;
+ INT32 nBgn = pFat->AllocPages( nPage, ( nNew - nOld ) / nPageSize );
+ if( nBgn == STG_EOF )
+ return FALSE;
+ if( nStart == STG_EOF )
+ nStart = nPage = nBgn;
+ }
+ else if( nNew < nOld )
+ {
+ BOOL bAll = BOOL( nBytes == 0 );
+ if( !Pos2Page( nBytes ) || !pFat->FreePages( nPage, bAll ) )
+ return FALSE;
+ if( bAll )
+ nStart = nPage = STG_EOF;
+ }
+ if( pEntry )
+ {
+ // change the dir entry?
+ if( !nSize || !nBytes )
+ pEntry->aEntry.SetLeaf( STG_DATA, nStart );
+ pEntry->aEntry.SetSize( nBytes );
+ pEntry->SetDirty();
+ }
+ nSize = nBytes;
+ pFat->SetLimit( GetPages() );
+ return TRUE;
+}
+
+// Return the # of allocated pages
+
+INT32 StgStrm::GetPages()
+{
+ return ( nSize + nPageSize - 1 ) / nPageSize;
+}
+
+//////////////////////////// class StgFATStrm //////////////////////////////
+
+// The FAT stream class provides physical access to the master FAT.
+// Since this access is implemented as a StgStrm, we can use the
+// FAT allocator.
+
+StgFATStrm::StgFATStrm( StgIo& r ) : StgStrm( r )
+{
+ pFat = new StgFAT( *this, TRUE );
+ nSize = rIo.aHdr.GetFATSize() * nPageSize;
+}
+
+BOOL StgFATStrm::Pos2Page( INT32 nBytePos )
+{
+ // Values < 0 seek to the end
+ if( nBytePos < 0 || nBytePos >= nSize )
+ nBytePos = nSize ? nSize - 1 : 0;
+ nPage = nBytePos / nPageSize;
+ nOffset = (short) ( nBytePos % nPageSize );
+ nPos = nBytePos;
+ nPage = GetPage( (short) nPage, FALSE );
+ return BOOL( nPage >= 0 );
+}
+
+// Retrieve the physical page for a given byte offset.
+// Since Pos2Page() already has computed the physical offset,
+// use the byte offset directly.
+
+StgPage* StgFATStrm::GetPhysPage( INT32 nBytePos, BOOL bForce )
+{
+ return rIo.Get( nBytePos / ( nPageSize >> 2 ), bForce );
+}
+
+// Get the page number entry for the given page offset.
+
+INT32 StgFATStrm::GetPage( short nOff, BOOL bMake, USHORT *pnMasterAlloc )
+{
+ if( pnMasterAlloc ) *pnMasterAlloc = 0;
+ if( nOff < rIo.aHdr.GetFAT1Size() )
+ return rIo.aHdr.GetFATPage( nOff );
+ INT32 nMaxPage = nSize >> 2;
+ nOff = nOff - rIo.aHdr.GetFAT1Size();
+ // Anzahl der Masterpages, durch die wir iterieren muessen
+ USHORT nMasterCount = ( nPageSize >> 2 ) - 1;
+ USHORT nBlocks = nOff / nMasterCount;
+ // Offset in letzter Masterpage
+ nOff = nOff % nMasterCount;
+
+ StgPage* pOldPage = 0;
+ StgPage* pMaster = 0;
+ INT32 nFAT = rIo.aHdr.GetFATChain();
+ for( USHORT nCount = 0; nCount <= nBlocks; nCount++ )
+ {
+ if( nFAT == STG_EOF || nFAT == STG_FREE )
+ {
+ if( bMake )
+ {
+ // create a new master page
+ nFAT = nMaxPage++;
+ pMaster = rIo.Copy( nFAT, STG_FREE );
+ if ( pMaster )
+ {
+ for( short k = 0; k < ( nPageSize >> 2 ); k++ )
+ pMaster->SetPage( k, STG_FREE );
+ // Verkettung herstellen
+ if( !pOldPage )
+ rIo.aHdr.SetFATChain( nFAT );
+ else
+ pOldPage->SetPage( nMasterCount, nFAT );
+ if( nMaxPage >= rIo.GetPhysPages() )
+ if( !rIo.SetSize( nMaxPage ) )
+ return STG_EOF;
+ // mark the page as used
+ // Platz fuer Masterpage schaffen
+ if( !pnMasterAlloc ) // Selbst Platz schaffen
+ {
+ if( !Pos2Page( nFAT << 2 ) )
+ return STG_EOF;
+ StgPage* pPg = rIo.Get( nPage, TRUE );
+ if( !pPg )
+ return STG_EOF;
+ pPg->SetPage( nOffset >> 2, STG_MASTER );
+ }
+ else
+ (*pnMasterAlloc)++;
+ rIo.aHdr.SetMasters( nCount + 1 );
+ pOldPage = pMaster;
+ }
+ }
+ }
+ else
+ {
+ pMaster = rIo.Get( nFAT, TRUE );
+ if ( pMaster )
+ {
+ nFAT = pMaster->GetPage( nMasterCount );
+ pOldPage = pMaster;
+ }
+ }
+ }
+ if( pMaster )
+ return pMaster->GetPage( nOff );
+ rIo.SetError( SVSTREAM_GENERALERROR );
+ return STG_EOF;
+}
+
+
+// Set the page number entry for the given page offset.
+
+BOOL StgFATStrm::SetPage( short nOff, INT32 nNewPage )
+{
+ BOOL bRes = TRUE;
+ if( nOff < rIo.aHdr.GetFAT1Size() )
+ rIo.aHdr.SetFATPage( nOff, nNewPage );
+ else
+ {
+ nOff = nOff - rIo.aHdr.GetFAT1Size();
+ // Anzahl der Masterpages, durch die wir iterieren muessen
+ USHORT nMasterCount = ( nPageSize >> 2 ) - 1;
+ USHORT nBlocks = nOff / nMasterCount;
+ // Offset in letzter Masterpage
+ nOff = nOff % nMasterCount;
+
+ StgPage* pMaster = 0;
+ INT32 nFAT = rIo.aHdr.GetFATChain();
+ for( USHORT nCount = 0; nCount <= nBlocks; nCount++ )
+ {
+ if( nFAT == STG_EOF || nFAT == STG_FREE )
+ {
+ pMaster = 0;
+ break;
+ }
+ pMaster = rIo.Get( nFAT, TRUE );
+ if ( pMaster )
+ nFAT = pMaster->GetPage( nMasterCount );
+ }
+ if( pMaster )
+ pMaster->SetPage( nOff, nNewPage );
+ else
+ {
+ rIo.SetError( SVSTREAM_GENERALERROR );
+ bRes = FALSE;
+ }
+ }
+
+ // lock the page against access
+ if( bRes )
+ {
+ Pos2Page( nNewPage << 2 );
+ StgPage* pPg = rIo.Get( nPage, TRUE );
+ if( pPg )
+ pPg->SetPage( nOffset >> 2, STG_FAT );
+ else
+ bRes = FALSE;
+ }
+ return bRes;
+}
+
+BOOL StgFATStrm::SetSize( INT32 nBytes )
+{
+ // Set the number of entries to a multiple of the page size
+ short nOld = (short) ( ( nSize + ( nPageSize - 1 ) ) / nPageSize );
+ short nNew = (short) (
+ ( nBytes + ( nPageSize - 1 ) ) / nPageSize ) ;
+ if( nNew < nOld )
+ {
+ // release master pages
+ for( short i = nNew; i < nOld; i++ )
+ SetPage( i, STG_FREE );
+ }
+ else
+ {
+ while( nOld < nNew )
+ {
+ // allocate master pages
+ // find a free master page slot
+ INT32 nPg = 0;
+ USHORT nMasterAlloc = 0;
+ nPg = GetPage( nOld, TRUE, &nMasterAlloc );
+ if( nPg == STG_EOF )
+ return FALSE;
+ // 4 Bytes have been used for Allocation of each MegaMasterPage
+ nBytes += nMasterAlloc << 2;
+
+ // find a free page using the FAT allocator
+ INT32 n = 1;
+ INT32 nNewPage = pFat->FindBlock( n );
+ if( nNewPage == STG_EOF )
+ {
+ // no free pages found; create a new page
+ // Since all pages are allocated, extend
+ // the file size for the next page!
+ nNewPage = nSize >> 2;
+ // if a MegaMasterPage was created avoid taking
+ // the same Page
+ nNewPage += nMasterAlloc;
+ // adjust the file size if necessary
+ if( nNewPage >= rIo.GetPhysPages() )
+ if( !rIo.SetSize( nNewPage + 1 ) )
+ return FALSE;
+ }
+ // Set up the page with empty entries
+ StgPage* pPg = rIo.Copy( nNewPage, STG_FREE );
+ if ( !pPg )
+ return FALSE;
+ for( short j = 0; j < ( nPageSize >> 2 ); j++ )
+ pPg->SetPage( j, STG_FREE );
+
+ // store the page number into the master FAT
+ // Set the size before so the correct FAT can be found
+ nSize = ( nOld + 1 ) * nPageSize;
+ SetPage( nOld, nNewPage );
+
+ // MegaMasterPages were created, mark it them as used
+
+ UINT32 nMax = rIo.aHdr.GetMasters( );
+ UINT32 nFAT = rIo.aHdr.GetFATChain();
+ if( nMasterAlloc )
+ for( USHORT nCount = 0; nCount < nMax; nCount++ )
+ {
+ if( !Pos2Page( nFAT << 2 ) )
+ return FALSE;
+ if( nMax - nCount <= nMasterAlloc )
+ {
+ StgPage* piPg = rIo.Get( nPage, TRUE );
+ if( !piPg )
+ return FALSE;
+ piPg->SetPage( nOffset >> 2, STG_MASTER );
+ }
+ StgPage* pPage = rIo.Get( nFAT, TRUE );
+ if( !pPage ) return FALSE;
+ nFAT = pPage->GetPage( (nPageSize >> 2 ) - 1 );
+ }
+
+ nOld++;
+ // We have used up 4 bytes for the STG_FAT entry
+ nBytes += 4;
+ nNew = (short) (
+ ( nBytes + ( nPageSize - 1 ) ) / nPageSize );
+ }
+ }
+ nSize = nNew * nPageSize;
+ rIo.aHdr.SetFATSize( nNew );
+ return TRUE;
+}
+
+/////////////////////////// class StgDataStrm //////////////////////////////
+
+// This class is a normal physical stream which can be initialized
+// either with an existing dir entry or an existing FAT chain.
+// The stream has a size increment which normally is 1, but which can be
+// set to any value is you want the size to be incremented by certain values.
+
+StgDataStrm::StgDataStrm( StgIo& r, INT32 nBgn, INT32 nLen ) : StgStrm( r )
+{
+ Init( nBgn, nLen );
+}
+
+StgDataStrm::StgDataStrm( StgIo& r, StgDirEntry* p ) : StgStrm( r )
+{
+ pEntry = p;
+ Init( p->aEntry.GetLeaf( STG_DATA ),
+ p->aEntry.GetSize() );
+}
+
+void StgDataStrm::Init( INT32 nBgn, INT32 nLen )
+{
+ pFat = new StgFAT( *rIo.pFAT, TRUE );
+ nStart = nPage = nBgn;
+ nSize = nLen;
+ nIncr = 1;
+ nOffset = 0;
+ if( nLen < 0 )
+ {
+ // determine the actual size of the stream by scanning
+ // the FAT chain and counting the # of pages allocated
+ nSize = 0;
+ INT32 nOldBgn = -1;
+ while( nBgn >= 0 && nBgn != nOldBgn )
+ {
+ nOldBgn = nBgn;
+ nBgn = pFat->GetNextPage( nBgn );
+ if( nBgn == nOldBgn )
+ rIo.SetError( ERRCODE_IO_WRONGFORMAT );
+ nSize += nPageSize;
+ }
+ }
+}
+
+// Set the size of a physical stream.
+
+BOOL StgDataStrm::SetSize( INT32 nBytes )
+{
+ nBytes = ( ( nBytes + nIncr - 1 ) / nIncr ) * nIncr;
+ INT32 nOldSz = nSize;
+ if( ( nOldSz != nBytes ) )
+ {
+ if( !StgStrm::SetSize( nBytes ) )
+ return FALSE;
+ INT32 nMaxPage = pFat->GetMaxPage();
+ if( nMaxPage > rIo.GetPhysPages() )
+ if( !rIo.SetSize( nMaxPage ) )
+ return FALSE;
+ // If we only allocated one page or less, create this
+ // page in the cache for faster throughput. The current
+ // position is the former EOF point.
+ if( ( nSize - 1 ) / nPageSize - ( nOldSz - 1 ) / nPageSize == 1 )
+ {
+ Pos2Page( nBytes );
+ if( nPage >= 0 )
+ rIo.Copy( nPage, STG_FREE );
+ }
+ }
+ return TRUE;
+}
+
+// Get the address of the data byte at a specified offset.
+// If bForce = TRUE, a read of non-existent data causes
+// a read fault.
+
+void* StgDataStrm::GetPtr( INT32 Pos, BOOL bForce, BOOL bDirty )
+{
+ if( Pos2Page( Pos ) )
+ {
+ StgPage* pPg = rIo.Get( nPage, bForce );
+ if( pPg )
+ {
+ pPg->SetOwner( pEntry );
+ if( bDirty )
+ pPg->SetDirty();
+ return ((BYTE *)pPg->GetData()) + nOffset;
+ }
+ }
+ return NULL;
+}
+
+// This could easily be adapted to a better algorithm by determining
+// the amount of consecutable blocks before doing a read. The result
+// is the number of bytes read. No error is generated on EOF.
+
+INT32 StgDataStrm::Read( void* pBuf, INT32 n )
+{
+ if ( n < 0 )
+ return 0;
+
+ if( ( nPos + n ) > nSize )
+ n = nSize - nPos;
+ INT32 nDone = 0;
+ while( n )
+ {
+ short nBytes = nPageSize - nOffset;
+ short nRes;
+ StgPage* pPg;
+ if( (INT32) nBytes > n )
+ nBytes = (short) n;
+ if( nBytes )
+ {
+ void *p = (BYTE *) pBuf + nDone;
+ if( nBytes == nPageSize )
+ {
+ pPg = rIo.Find( nPage );
+ if( pPg )
+ {
+ // data is present, so use the cached data
+ pPg->SetOwner( pEntry );
+ memcpy( p, pPg->GetData(), nBytes );
+ nRes = nBytes;
+ }
+ else
+ // do a direct (unbuffered) read
+ nRes = (short) rIo.Read( nPage, p, 1 ) * nPageSize;
+ }
+ else
+ {
+ // partial block read thru the cache.
+ pPg = rIo.Get( nPage, FALSE );
+ if( !pPg )
+ break;
+ pPg->SetOwner( pEntry );
+ memcpy( p, (BYTE*)pPg->GetData() + nOffset, nBytes );
+ nRes = nBytes;
+ }
+ nDone += nRes;
+ nPos += nRes;
+ n -= nRes;
+ nOffset = nOffset + nRes;
+ if( nRes != nBytes )
+ break; // read error or EOF
+ }
+ // Switch to next page if necessary
+ if( nOffset >= nPageSize && !Pos2Page( nPos ) )
+ break;
+ }
+ return nDone;
+}
+
+INT32 StgDataStrm::Write( const void* pBuf, INT32 n )
+{
+ INT32 nDone = 0;
+ if( ( nPos + n ) > nSize )
+ {
+ INT32 nOld = nPos;
+ if( !SetSize( nPos + n ) )
+ return FALSE;
+ Pos2Page( nOld );
+ }
+ while( n )
+ {
+ short nBytes = nPageSize - nOffset;
+ short nRes;
+ StgPage* pPg;
+ if( (INT32) nBytes > n )
+ nBytes = (short) n;
+ if( nBytes )
+ {
+ const void *p = (const BYTE *) pBuf + nDone;
+ if( nBytes == nPageSize )
+ {
+ pPg = rIo.Find( nPage );
+ if( pPg )
+ {
+ // data is present, so use the cached data
+ pPg->SetOwner( pEntry );
+ memcpy( pPg->GetData(), p, nBytes );
+ pPg->SetDirty();
+ nRes = nBytes;
+ }
+ else
+ // do a direct (unbuffered) write
+ nRes = (short) rIo.Write( nPage, (void*) p, 1 ) * nPageSize;
+ }
+ else
+ {
+ // partial block read thru the cache.
+ pPg = rIo.Get( nPage, FALSE );
+ if( !pPg )
+ break;
+ pPg->SetOwner( pEntry );
+ memcpy( (BYTE*)pPg->GetData() + nOffset, p, nBytes );
+ pPg->SetDirty();
+ nRes = nBytes;
+ }
+ nDone += nRes;
+ nPos += nRes;
+ n -= nRes;
+ nOffset = nOffset + nRes;
+ if( nRes != nBytes )
+ break; // read error
+ }
+ // Switch to next page if necessary
+ if( nOffset >= nPageSize && !Pos2Page( nPos ) )
+ break;
+ }
+ return nDone;
+}
+
+//////////////////////////// class StgSmallStream ///////////////////////////
+
+// The small stream class provides access to streams with a size < 4096 bytes.
+// This stream is a StgStream containing small pages. The FAT for this stream
+// is also a StgStream. The start of the FAT is in the header at DataRootPage,
+// the stream itself is pointed to by the root entry (it holds start & size).
+
+StgSmallStrm::StgSmallStrm( StgIo& r, INT32 nBgn, INT32 nLen ) : StgStrm( r )
+{
+ Init( nBgn, nLen );
+}
+
+StgSmallStrm::StgSmallStrm( StgIo& r, StgDirEntry* p ) : StgStrm( r )
+{
+ pEntry = p;
+ Init( p->aEntry.GetLeaf( STG_DATA ),
+ p->aEntry.GetSize() );
+}
+
+void StgSmallStrm::Init( INT32 nBgn, INT32 nLen )
+{
+ pFat = new StgFAT( *rIo.pDataFAT, FALSE );
+ pData = rIo.pDataStrm;
+ nPageSize = rIo.GetDataPageSize();
+ nStart =
+ nPage = nBgn;
+ nSize = nLen;
+}
+
+// This could easily be adapted to a better algorithm by determining
+// the amount of consecutable blocks before doing a read. The result
+// is the number of bytes read. No error is generated on EOF.
+
+INT32 StgSmallStrm::Read( void* pBuf, INT32 n )
+{
+ // We can safely assume that reads are not huge, since the
+ // small stream is likely to be < 64 KBytes.
+ if( ( nPos + n ) > nSize )
+ n = nSize - nPos;
+ short nDone = 0;
+ while( n )
+ {
+ short nBytes = nPageSize - nOffset;
+ if( (INT32) nBytes > n )
+ nBytes = (short) n;
+ if( nBytes )
+ {
+ if( !pData->Pos2Page( nPage * nPageSize + nOffset ) )
+ break;
+ // all reading thru the stream
+ short nRes = (short) pData->Read( (BYTE*)pBuf + nDone, nBytes );
+ nDone = nDone + nRes;
+ nPos += nRes;
+ n -= nRes;
+ nOffset = nOffset + nRes;
+ // read problem?
+ if( nRes != nBytes )
+ break;
+ }
+ // Switch to next page if necessary
+ if( nOffset >= nPageSize && !Pos2Page( nPos ) )
+ break;
+ }
+ return nDone;
+}
+
+INT32 StgSmallStrm::Write( const void* pBuf, INT32 n )
+{
+ // you can safely assume that reads are not huge, since the
+ // small stream is likely to be < 64 KBytes.
+ short nDone = 0;
+ if( ( nPos + n ) > nSize )
+ {
+ INT32 nOld = nPos;
+ if( !SetSize( nPos + n ) )
+ return FALSE;
+ Pos2Page( nOld );
+ }
+ while( n )
+ {
+ short nBytes = nPageSize - nOffset;
+ if( (INT32) nBytes > n )
+ nBytes = (short) n;
+ if( nBytes )
+ {
+ // all writing goes thru the stream
+ INT32 nDataPos = nPage * nPageSize + nOffset;
+ if( pData->GetSize() < ( nDataPos + nBytes ) )
+ if( !pData->SetSize( nDataPos + nBytes ) )
+ break;
+ if( !pData->Pos2Page( nDataPos ) )
+ break;
+ short nRes = (short) pData->Write( (BYTE*)pBuf + nDone, nBytes );
+ nDone = nDone + nRes;
+ nPos += nRes;
+ n -= nRes;
+ nOffset = nOffset + nRes;
+ // write problem?
+ if( nRes != nBytes )
+ break;
+ }
+ // Switch to next page if necessary
+ if( nOffset >= nPageSize && !Pos2Page( nPos ) )
+ break;
+ }
+ return nDone;
+}
+
+/////////////////////////// class StgTmpStrm /////////////////////////////
+
+// The temporary stream uses a memory stream if < 32K, otherwise a
+// temporary file.
+
+#define THRESHOLD 32768L
+
+StgTmpStrm::StgTmpStrm( ULONG nInitSize )
+ : SvMemoryStream( nInitSize > THRESHOLD
+ ? 16
+ : ( nInitSize ? nInitSize : 16 ), 4096 )
+{
+ pStrm = NULL;
+ // this calls FlushData, so all members should be set by this time
+ SetBufferSize( 0 );
+ if( nInitSize > THRESHOLD )
+ SetSize( nInitSize );
+}
+
+BOOL StgTmpStrm::Copy( StgTmpStrm& rSrc )
+{
+ ULONG n = rSrc.GetSize();
+ ULONG nCur = rSrc.Tell();
+ SetSize( n );
+ if( GetError() == SVSTREAM_OK )
+ {
+ BYTE* p = new BYTE[ 4096 ];
+ rSrc.Seek( 0L );
+ Seek( 0L );
+ while( n )
+ {
+ ULONG nn = n;
+ if( nn > 4096 )
+ nn = 4096;
+ if( rSrc.Read( p, nn ) != nn )
+ break;
+ if( Write( p, nn ) != nn )
+ break;
+ n -= nn;
+ }
+ delete [] p;
+ rSrc.Seek( nCur );
+ Seek( nCur );
+ return BOOL( n == 0 );
+ }
+ else
+ return FALSE;
+}
+
+StgTmpStrm::~StgTmpStrm()
+{
+ if( pStrm )
+ {
+ pStrm->Close();
+ osl::File::remove( aName );
+ delete pStrm;
+ }
+}
+
+ULONG StgTmpStrm::GetSize() const
+{
+ ULONG n;
+ if( pStrm )
+ {
+ ULONG old = pStrm->Tell();
+ n = pStrm->Seek( STREAM_SEEK_TO_END );
+ pStrm->Seek( old );
+ }
+ else
+ n = nEndOfData;
+ return n;
+}
+
+void StgTmpStrm::SetSize( ULONG n )
+{
+ if( pStrm )
+ pStrm->SetStreamSize( n );
+ else
+ {
+ if( n > THRESHOLD )
+ {
+ aName = TempFile::CreateTempName();
+ SvFileStream* s = new SvFileStream( aName, STREAM_READWRITE );
+ ULONG nCur = Tell();
+ ULONG i = nEndOfData;
+ if( i )
+ {
+ BYTE* p = new BYTE[ 4096 ];
+ Seek( 0L );
+ while( i )
+ {
+ ULONG nb = ( i > 4096 ) ? 4096 : i;
+ if( Read( p, nb ) == nb
+ && s->Write( p, nb ) == nb )
+ i -= nb;
+ else
+ break;
+ }
+ delete [] p;
+ }
+ if( !i && n > nEndOfData )
+ {
+ // We have to write one byte at the end of the file
+ // if the file is bigger than the memstream to see
+ // if it fits on disk
+ s->Seek( n - 1 );
+ s->Write( &i, 1 );
+ s->Flush();
+ if( s->GetError() != SVSTREAM_OK )
+ i = 1;
+ }
+ Seek( nCur );
+ s->Seek( nCur );
+ if( i )
+ {
+ SetError( s->GetError() );
+ delete s;
+ return;
+ }
+ pStrm = s;
+ // Shrink the memory to 16 bytes, which seems to be the minimum
+ ReAllocateMemory( - ( (long) nEndOfData - 16 ) );
+ }
+ else
+ {
+ if( n > nEndOfData )
+ {
+ ULONG nCur = Tell();
+ Seek( nEndOfData - 1 );
+ *this << (BYTE) 0;
+ Seek( nCur );
+ }
+ else
+ nEndOfData = n;
+ }
+ }
+}
+
+ULONG StgTmpStrm::GetData( void* pData, ULONG n )
+{
+ if( pStrm )
+ {
+ n = pStrm->Read( pData, n );
+ SetError( pStrm->GetError() );
+ return n;
+ }
+ else
+ return SvMemoryStream::GetData( (sal_Char *)pData, n );
+}
+
+ULONG StgTmpStrm::PutData( const void* pData, ULONG n )
+{
+ UINT32 nCur = Tell();
+ UINT32 nNew = nCur + n;
+ if( nNew > THRESHOLD && !pStrm )
+ {
+ SetSize( nNew );
+ if( GetError() != SVSTREAM_OK )
+ return 0;
+ }
+ if( pStrm )
+ {
+ nNew = pStrm->Write( pData, n );
+ SetError( pStrm->GetError() );
+ }
+ else
+ nNew = SvMemoryStream::PutData( (sal_Char*)pData, n );
+ return nNew;
+}
+
+ULONG StgTmpStrm::SeekPos( ULONG n )
+{
+ if( n == STREAM_SEEK_TO_END )
+ n = GetSize();
+ if( n && n > THRESHOLD && !pStrm )
+ {
+ SetSize( n );
+ if( GetError() != SVSTREAM_OK )
+ return Tell();
+ else
+ return n;
+ }
+ else if( pStrm )
+ {
+ n = pStrm->Seek( n );
+ SetError( pStrm->GetError() );
+ return n;
+ }
+ else
+ return SvMemoryStream::SeekPos( n );
+}
+
+void StgTmpStrm::FlushData()
+{
+ if( pStrm )
+ {
+ pStrm->Flush();
+ SetError( pStrm->GetError() );
+ }
+ else
+ SvMemoryStream::FlushData();
+}
+
diff --git a/sot/source/sdstor/stgstrms.hxx b/sot/source/sdstor/stgstrms.hxx
new file mode 100644
index 000000000000..9b09f51db43f
--- /dev/null
+++ b/sot/source/sdstor/stgstrms.hxx
@@ -0,0 +1,170 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _STGSTRMS_HXX
+#define _STGSTRMS_HXX
+
+#ifndef _TOOLS_STREAM_HXX
+#include <tools/stream.hxx>
+#endif
+
+class StgIo;
+class StgStrm;
+class StgPage;
+class StgDirEntry;
+
+// The FAT class performs FAT operations on an underlying storage stream.
+// This stream is either the physical FAT stream (bPhys == TRUE ) or a normal
+// storage stream, which then holds the FAT for small data allocations.
+
+class StgFAT
+{ // FAT allocator
+ StgStrm& rStrm; // underlying stream
+ INT32 nMaxPage; // highest page allocated so far
+ short nPageSize; // physical page size
+ short nEntries; // FAT entries per page
+ short nOffset; // current offset within page
+ INT32 nLimit; // search limit recommendation
+ BOOL bPhys; // TRUE: physical FAT
+ StgPage* GetPhysPage( INT32 nPage );
+ BOOL MakeChain( INT32 nStart, INT32 nPages );
+ BOOL InitNew( INT32 nPage1 );
+public:
+ StgFAT( StgStrm& rStrm, BOOL bMark );
+ INT32 FindBlock( INT32& nPages );
+ INT32 GetNextPage( INT32 nPg );
+ INT32 AllocPages( INT32 nStart, INT32 nPages );
+ BOOL FreePages( INT32 nStart, BOOL bAll );
+ INT32 GetMaxPage() { return nMaxPage; }
+ void SetLimit( INT32 n ) { nLimit = n; }
+};
+
+// The base stream class provides basic functionality for seeking
+// and accessing the data on a physical basis. It uses the built-in
+// FAT class for the page allocations.
+
+class StgStrm { // base class for all streams
+protected:
+ StgIo& rIo; // I/O system
+ StgFAT* pFat; // FAT stream for allocations
+ StgDirEntry* pEntry; // dir entry (for ownership)
+ INT32 nStart; // 1st data page
+ INT32 nSize; // stream size in bytes
+ INT32 nPos; // current byte position
+ INT32 nPage; // current logical page
+ short nOffset; // offset into current page
+ short nPageSize; // logical page size
+ BOOL Copy( INT32 nFrom, INT32 nBytes );
+ StgStrm( StgIo& );
+public:
+ virtual ~StgStrm();
+ StgIo& GetIo() { return rIo; }
+ INT32 GetPos() { return nPos; }
+ INT32 GetStart() { return nStart; }
+ INT32 GetSize() { return nSize; }
+ INT32 GetPage() { return nPage; }
+ short GetPageSize() { return nPageSize; }
+ INT32 GetPages();
+ short GetOffset() { return nOffset;}
+ void SetEntry( StgDirEntry& );
+ virtual BOOL SetSize( INT32 );
+ virtual BOOL Pos2Page( INT32 nBytePos );
+ virtual INT32 Read( void*, INT32 ) { return 0; }
+ virtual INT32 Write( const void*, INT32 ) { return 0; }
+ virtual StgPage* GetPhysPage( INT32 nBytePos, BOOL bForce = FALSE );
+ virtual BOOL IsSmallStrm() { return FALSE; }
+};
+
+// The FAT stream class provides physical access to the master FAT.
+// Since this access is implemented as a StgStrm, we can use the
+// FAT allocator.
+
+class StgFATStrm : public StgStrm { // the master FAT stream
+ virtual BOOL Pos2Page( INT32 nBytePos );
+ BOOL SetPage( short, INT32 );
+public:
+ StgFATStrm( StgIo& );
+ virtual ~StgFATStrm() {}
+ using StgStrm::GetPage;
+ INT32 GetPage( short, BOOL, USHORT *pnMasterAlloc = 0);
+ virtual BOOL SetSize( INT32 );
+ virtual StgPage* GetPhysPage( INT32 nBytePos, BOOL bForce = FALSE );
+};
+
+// The stream has a size increment which normally is 1, but which can be
+// set to any value is you want the size to be incremented by certain values.
+
+class StgDataStrm : public StgStrm // a physical data stream
+{
+ short nIncr; // size adjust increment
+ void Init( INT32 nBgn, INT32 nLen );
+public:
+ StgDataStrm( StgIo&, INT32 nBgn, INT32 nLen=-1 );
+ StgDataStrm( StgIo&, StgDirEntry* );
+ void* GetPtr( INT32 nPos, BOOL bForce, BOOL bDirty );
+ void SetIncrement( short n ) { nIncr = n ; }
+ virtual BOOL SetSize( INT32 );
+ virtual INT32 Read( void*, INT32 );
+ virtual INT32 Write( const void*, INT32 );
+};
+
+// The small stream class provides access to streams with a size < 4096 bytes.
+// This stream is a StgStream containing small pages. The FAT for this stream
+// is also a StgStream. The start of the FAT is in the header at DataRootPage,
+// the stream itself is pointed to by the root entry (it holds start & size).
+
+class StgSmallStrm : public StgStrm // a logical data stream
+{
+ StgStrm* pData; // the data stream
+ void Init( INT32 nBgn, INT32 nLen );
+public:
+ StgSmallStrm( StgIo&, INT32 nBgn, INT32 nLen );
+ StgSmallStrm( StgIo&, StgDirEntry* );
+ virtual INT32 Read( void*, INT32 );
+ virtual INT32 Write( const void*, INT32 );
+ virtual BOOL IsSmallStrm() { return TRUE; }
+};
+
+class StgTmpStrm : public SvMemoryStream
+{
+ String aName;
+ SvFileStream* pStrm;
+ using SvMemoryStream::GetData;
+ virtual ULONG GetData( void* pData, ULONG nSize );
+ virtual ULONG PutData( const void* pData, ULONG nSize );
+ virtual ULONG SeekPos( ULONG nPos );
+ virtual void FlushData();
+
+public:
+ StgTmpStrm( ULONG=16 );
+ ~StgTmpStrm();
+ BOOL Copy( StgTmpStrm& );
+ void SetSize( ULONG );
+ ULONG GetSize() const;
+};
+
+#endif
diff --git a/sot/source/sdstor/storage.cxx b/sot/source/sdstor/storage.cxx
new file mode 100644
index 000000000000..136abb29a98e
--- /dev/null
+++ b/sot/source/sdstor/storage.cxx
@@ -0,0 +1,1563 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sot.hxx"
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/embed/XStorage.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+#include <rtl/digest.h>
+#include <osl/file.hxx>
+#include <stg.hxx>
+#include <storinfo.hxx>
+#include <sot/storage.hxx>
+#include <sot/formats.hxx>
+#include <sot/exchange.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#ifndef _TOOLS_FSYS_HXX
+#include <tools/fsys.hxx>
+#endif
+#include <tools/cachestr.hxx>
+#include <tools/debug.hxx>
+#include <tools/urlobj.hxx>
+#include <unotools/localfilehelper.hxx>
+#include <unotools/ucbhelper.hxx>
+#include <comphelper/processfactory.hxx>
+
+#include "unostorageholder.hxx"
+
+using namespace ::com::sun::star;
+
+/************** class SotStorageStream ***********************************/
+class SotStorageStreamFactory : public SotFactory
+{
+public:
+ TYPEINFO();
+ SotStorageStreamFactory( const SvGlobalName & rName,
+ const String & rClassName,
+ CreateInstanceType pCreateFuncP )
+ : SotFactory( rName, rClassName, pCreateFuncP )
+ {}
+};
+TYPEINIT1(SotStorageStreamFactory,SotFactory);
+
+
+SO2_IMPL_BASIC_CLASS1_DLL(SotStorageStream,SotStorageStreamFactory,SotObject,
+ SvGlobalName( 0xd7deb420, 0xf902, 0x11d0,
+ 0xaa, 0xa1, 0x0, 0xa0, 0x24, 0x9d, 0x55, 0x90 ) )
+SO2_IMPL_INVARIANT(SotStorageStream)
+
+
+void SotStorageStream::TestMemberObjRef( BOOL /*bFree*/ )
+{
+}
+
+#ifdef TEST_INVARIANT
+void SotStorageStream::TestMemberInvariant( BOOL /*bPrint*/ )
+{
+}
+#endif
+
+/************************************************************************
+|* SotStorageStream::SotStorageStream()
+|*
+|* Beschreibung
+*************************************************************************/
+SvLockBytesRef MakeLockBytes_Impl( const String & rName, StreamMode nMode )
+{
+ SvLockBytesRef xLB;
+ if( rName.Len() )
+ {
+ SvStream * pFileStm = new SvFileStream( rName, nMode );
+ xLB = new SvLockBytes( pFileStm, TRUE );
+ }
+ else
+ {
+ SvStream * pCacheStm = new SvCacheStream();
+ xLB = new SvLockBytes( pCacheStm, TRUE );
+ }
+ return xLB;
+}
+
+SotStorageStream::SotStorageStream( const String & rName, StreamMode nMode,
+ StorageMode
+ #ifdef DBG_UTIL
+ nStorageMode
+ #endif
+ )
+ : SvStream( MakeLockBytes_Impl( rName, nMode ) )
+ , pOwnStm( NULL )
+{
+ if( nMode & STREAM_WRITE )
+ bIsWritable = TRUE;
+ else
+ bIsWritable = FALSE;
+
+ DBG_ASSERT( !nStorageMode,"StorageModes ignored" );
+}
+
+SotStorageStream::SotStorageStream( BaseStorageStream * pStm )
+{
+ if( pStm )
+ {
+ if( STREAM_WRITE & pStm->GetMode() )
+ bIsWritable = TRUE;
+ else
+ bIsWritable = FALSE;
+
+ pOwnStm = pStm;
+ SetError( pStm->GetError() );
+ pStm->ResetError();
+ }
+ else
+ {
+ pOwnStm = NULL;
+ bIsWritable = TRUE;
+ SetError( SVSTREAM_INVALID_PARAMETER );
+ }
+}
+
+SotStorageStream::SotStorageStream()
+ : pOwnStm( NULL )
+{
+ // ??? wenn Init virtuell ist, entsprechen setzen
+ bIsWritable = TRUE;
+}
+
+/************************************************************************
+|* SotStorageStream::~SotStorageStream()
+|*
+|* Beschreibung
+*************************************************************************/
+SotStorageStream::~SotStorageStream()
+{
+ Flush(); //SetBufferSize(0);
+ delete pOwnStm;
+}
+
+/*************************************************************************
+|* SotStorageStream::SyncSvStream()
+|*
+|* Beschreibung: Der SvStream wird auf den Zustand des Standard-Streams
+|* gesetzt. Der Puffer des SvStreams wird weggeworfen.
+*************************************************************************/
+void SotStorageStream::SyncSvStream()
+{
+ ULONG nPos = 0;
+ if( pOwnStm )
+ {
+ pOwnStm->Flush();
+ nPos = pOwnStm->Tell();
+ SetError( pOwnStm->GetError() );
+ SvStream::SyncSvStream( nPos );
+ }
+}
+
+/*************************************************************************
+|* SotStorageStream::ResetError()
+|*
+|* Beschreibung
+*************************************************************************/
+void SotStorageStream::ResetError()
+{
+ SvStream::ResetError();
+ if( pOwnStm )
+ pOwnStm->ResetError();
+}
+
+/*************************************************************************
+|* SotStorageStream::GetData()
+|*
+|* Beschreibung
+*************************************************************************/
+ULONG SotStorageStream::GetData( void* pData, ULONG nSize )
+{
+ ULONG nRet = 0;
+
+ if( pOwnStm )
+ {
+ nRet = pOwnStm->Read( pData, nSize );
+ SetError( pOwnStm->GetError() );
+ }
+ else
+ nRet = SvStream::GetData( (sal_Char *)pData, nSize );
+ return nRet;
+}
+
+/*************************************************************************
+|* SotStorageStream::PutData()
+|*
+|* Beschreibung
+*************************************************************************/
+ULONG SotStorageStream::PutData( const void* pData, ULONG nSize )
+{
+ ULONG nRet = 0;
+
+ if( pOwnStm )
+ {
+ nRet = pOwnStm->Write( pData, nSize );
+ SetError( pOwnStm->GetError() );
+ }
+ else
+ nRet = SvStream::PutData( (sal_Char *)pData, nSize );
+ return nRet;
+}
+
+/*************************************************************************
+|* SotStorageStream::SeekPos()
+|*
+|* Beschreibung
+*************************************************************************/
+ULONG SotStorageStream::SeekPos( ULONG nPos )
+{
+ ULONG nRet = 0;
+
+ if( pOwnStm )
+ {
+ nRet = pOwnStm->Seek( nPos );
+ SetError( pOwnStm->GetError() );
+ }
+ else
+ nRet = SvStream::SeekPos( nPos );
+ return nRet;
+}
+
+/*************************************************************************
+|* SotStorageStream::Flush()
+|*
+|* Beschreibung
+*************************************************************************/
+void SotStorageStream::FlushData()
+{
+ if( pOwnStm )
+ {
+ pOwnStm->Flush();
+ SetError( pOwnStm->GetError() );
+ }
+ else
+ SvStream::FlushData();
+}
+
+/*************************************************************************
+|* SotStorageStream::SetSize()
+|*
+|* Beschreibung
+*************************************************************************/
+void SotStorageStream::SetSize( ULONG nNewSize )
+{
+ ULONG nPos = Tell();
+ if( pOwnStm )
+ {
+ pOwnStm->SetSize( nNewSize );
+ SetError( pOwnStm->GetError() );
+ }
+ else
+ SvStream::SetSize( nNewSize );
+
+ if( nNewSize < nPos )
+ // ans Ende setzen
+ Seek( nNewSize );
+
+ //return GetError() == SVSTREAM_OK;
+}
+
+/*************************************************************************
+|*
+|* SotStorageStream::GetSize()
+|*
+|* Beschreibung
+|*
+*************************************************************************/
+UINT32 SotStorageStream::GetSize() const
+{
+ ULONG nPos = Tell();
+ ((SotStorageStream *)this)->Seek( STREAM_SEEK_TO_END );
+ ULONG nSize = Tell();
+ ((SotStorageStream *)this)->Seek( nPos );
+ return nSize;
+}
+
+/*************************************************************************
+|* SotStorageStream::CopyTo()
+|*
+|* Beschreibung
+*************************************************************************/
+BOOL SotStorageStream::CopyTo( SotStorageStream * pDestStm )
+{
+ Flush(); // alle Daten schreiben
+ pDestStm->ClearBuffer();
+ if( !pOwnStm || !pDestStm->pOwnStm )
+ { // Wenn Ole2 oder nicht nur eigene StorageStreams
+
+ ULONG nPos = Tell(); // Position merken
+ Seek( 0L );
+ pDestStm->SetSize( 0 ); // Ziel-Stream leeren
+
+ void * pMem = new BYTE[ 8192 ];
+ ULONG nRead;
+ while( 0 != (nRead = Read( pMem, 8192 )) )
+ {
+ if( nRead != pDestStm->Write( pMem, nRead ) )
+ {
+ SetError( SVSTREAM_GENERALERROR );
+ break;
+ }
+ }
+ delete [] static_cast<BYTE*>(pMem);
+ // Position setzen
+ pDestStm->Seek( nPos );
+ Seek( nPos );
+ }
+ else
+ {
+ /*
+ // Kopieren
+ nErr = pObjI->CopyTo( pDestStm->pObjI, uSize, NULL, &uWrite );
+ if( SUCCEEDED( nErr ) )
+ {
+ // Ziel-Streamzeiger steht hinter den Daten
+ // SvSeek abgleichen
+ pDestStm->Seek( uWrite.LowPart );
+ }
+ else if( GetScode( nErr ) == E_NOTIMPL )
+ { // Eines Tages werden alle MS... ?!#
+ */
+ pOwnStm->CopyTo( pDestStm->pOwnStm );
+ SetError( pOwnStm->GetError() );
+ }
+ return GetError() == SVSTREAM_OK;
+}
+
+/*************************************************************************
+|* SotStorageStream::Commit()
+|* SotStorageStream::Revert()
+|*
+|* Beschreibung
+*************************************************************************/
+BOOL SotStorageStream::Commit()
+{
+ if( pOwnStm )
+ {
+ pOwnStm->Flush();
+ if( pOwnStm->GetError() == SVSTREAM_OK )
+ pOwnStm->Commit();
+ SetError( pOwnStm->GetError() );
+ }
+ return GetError() == SVSTREAM_OK;
+}
+
+BOOL SotStorageStream::Revert()
+{
+ if( !pOwnStm )
+ {
+ pOwnStm->Revert();
+ SetError( pOwnStm->GetError() );
+ }
+ return GetError() == SVSTREAM_OK;
+}
+
+BOOL SotStorageStream::SetProperty( const String& rName, const ::com::sun::star::uno::Any& rValue )
+{
+ UCBStorageStream* pStg = PTR_CAST( UCBStorageStream, pOwnStm );
+ if ( pStg )
+ {
+ return pStg->SetProperty( rName, rValue );
+ }
+ else
+ {
+ DBG_ERROR("Not implemented!");
+ return FALSE;
+ }
+}
+
+BOOL SotStorageStream::GetProperty( const String& rName, ::com::sun::star::uno::Any& rValue )
+{
+ UCBStorageStream* pStg = PTR_CAST( UCBStorageStream, pOwnStm );
+ if ( pStg )
+ {
+ return pStg->GetProperty( rName, rValue );
+ }
+ else
+ {
+ DBG_ERROR("Not implemented!");
+ return FALSE;
+ }
+}
+
+::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SotStorageStream::GetXInputStream() const
+{
+ UCBStorageStream* pStg = PTR_CAST( UCBStorageStream, pOwnStm );
+ if ( pStg )
+ {
+ return pStg->GetXInputStream();
+ }
+ else
+ {
+ DBG_ERROR("Not implemented!");
+ return ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >();
+ }
+}
+
+
+
+/************** class SotStorage ******************************************
+*************************************************************************/
+class SotStorageFactory : public SotFactory
+{
+public:
+ TYPEINFO();
+ SotStorageFactory( const SvGlobalName & rName,
+ const String & rClassName,
+ CreateInstanceType pCreateFuncP )
+ : SotFactory( rName, rClassName, pCreateFuncP )
+ {}
+};
+TYPEINIT1(SotStorageFactory,SotFactory);
+
+
+SO2_IMPL_BASIC_CLASS1_DLL(SotStorage,SotStorageFactory,SotObject,
+ SvGlobalName( 0x980ce7e0, 0xf905, 0x11d0,
+ 0xaa, 0xa1, 0x0, 0xa0, 0x24, 0x9d, 0x55, 0x90 ) )
+SO2_IMPL_INVARIANT(SotStorage)
+
+
+/************************************************************************
+|*
+|* SotStorage::Tes*()
+|*
+|* Beschreibung
+*************************************************************************/
+void SotStorage::TestMemberObjRef( BOOL /*bFree*/ )
+{
+}
+
+#ifdef TEST_INVARIANT
+void SotStorage::TestMemberInvariant( BOOL /*bPrint*/ )
+{
+}
+#endif
+
+/************************************************************************
+|*
+|* SotStorage::SotStorage()
+|*
+|* Beschreibung Es muss ein I... Objekt an SvObject uebergeben
+|* werden, da es sonst selbst ein IUnknown anlegt und
+|* festlegt, dass alle weiteren I... Objekte mit
+|* delete zerstoert werden (Owner() == TRUE).
+|* Es werden aber nur IStorage Objekte benutzt und nicht
+|* selbst implementiert, deshalb wird so getan, als ob
+|* das IStorage Objekt von aussen kam und es wird mit
+|* Release() freigegeben.
+|* Die CreateStorage Methoden werden benoetigt, um
+|* ein IStorage Objekt vor dem Aufruf von SvObject
+|* zu erzeugen (Own, !Own automatik).
+|* Hat CreateStorage ein Objekt erzeugt, dann wurde
+|* der RefCounter schon um 1 erhoet.
+|* Die Uebergabe erfolgt in pStorageCTor. Die Variable
+|* ist NULL, wenn es nicht geklappt hat.
+|* Ersterstellung MM 23.06.94
+|* Letzte Aenderung MM 23.06.94
+|*
+*************************************************************************/
+#define INIT_SotStorage() \
+ : m_pOwnStg( NULL ) \
+ , m_pStorStm( NULL ) \
+ , m_nError( SVSTREAM_OK ) \
+ , m_bIsRoot( FALSE ) \
+ , m_bDelStm( FALSE ) \
+ , m_nVersion( SOFFICE_FILEFORMAT_CURRENT )
+
+SotStorage::SotStorage()
+ INIT_SotStorage()
+{
+ // ??? What's this ???
+}
+
+#define ERASEMASK ( STREAM_TRUNC | STREAM_WRITE | STREAM_SHARE_DENYALL )
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/ucb/XCommandEnvironment.hpp>
+#include <ucbhelper/content.hxx>
+
+SotStorage::SotStorage( const ::ucbhelper::Content& rContent, const String & rName, StreamMode nMode, StorageMode nStorageMode )
+ INIT_SotStorage()
+{
+ m_aName = rName; // Namen merken
+ m_pOwnStg = new UCBStorage( rContent, m_aName, nMode, (nStorageMode & STORAGE_TRANSACTED) ? FALSE : TRUE );
+
+ SetError( m_pOwnStg->GetError() );
+
+ if ( IsOLEStorage() )
+ m_nVersion = SOFFICE_FILEFORMAT_50;
+
+ SignAsRoot( m_pOwnStg->IsRoot() );
+}
+
+SotStorage::SotStorage( const String & rName, StreamMode nMode, StorageMode nStorageMode )
+ INIT_SotStorage()
+{
+ m_aName = rName; // Namen merken
+ CreateStorage( TRUE, nMode, nStorageMode );
+ if ( IsOLEStorage() )
+ m_nVersion = SOFFICE_FILEFORMAT_50;
+}
+
+void SotStorage::CreateStorage( BOOL bForceUCBStorage, StreamMode nMode, StorageMode nStorageMode )
+{
+ DBG_ASSERT( !m_pStorStm && !m_pOwnStg, "Use only in ctor!" );
+ if( m_aName.Len() )
+ {
+ // named storage
+ if( ( ( nMode & ERASEMASK ) == ERASEMASK ) )
+ ::utl::UCBContentHelper::Kill( m_aName );
+
+ INetURLObject aObj( m_aName );
+ if ( aObj.GetProtocol() == INET_PROT_NOT_VALID )
+ {
+ String aURL;
+ ::utl::LocalFileHelper::ConvertPhysicalNameToURL( m_aName, aURL );
+ aObj.SetURL( aURL );
+ m_aName = aObj.GetMainURL( INetURLObject::NO_DECODE );
+ }
+
+ // a new unpacked storage should be created
+ if ( nStorageMode == STORAGE_CREATE_UNPACKED )
+ {
+ // don't open stream readwrite, content provider may not support this !
+ String aURL = UCBStorage::CreateLinkFile( m_aName );
+ if ( aURL.Len() )
+ {
+ ::ucbhelper::Content aContent( aURL, ::com::sun::star::uno::Reference < ::com::sun::star::ucb::XCommandEnvironment >() );
+ m_pOwnStg = new UCBStorage( aContent, aURL, nMode, FALSE );
+ }
+ else
+ {
+ m_pOwnStg = new Storage( m_aName, nMode, (nStorageMode & STORAGE_TRANSACTED) ? FALSE : TRUE );
+ SetError( ERRCODE_IO_NOTSUPPORTED );
+ }
+ }
+ else
+ {
+ // check the stream
+ m_pStorStm = ::utl::UcbStreamHelper::CreateStream( m_aName, nMode );
+ if ( m_pStorStm && m_pStorStm->GetError() )
+ DELETEZ( m_pStorStm );
+
+ if ( m_pStorStm )
+ {
+ // try as UCBStorage, next try as OLEStorage
+ BOOL bIsUCBStorage = UCBStorage::IsStorageFile( m_pStorStm );
+ if ( !bIsUCBStorage && bForceUCBStorage )
+ // if UCBStorage has priority, it should not be used only if it is really an OLEStorage
+ bIsUCBStorage = !Storage::IsStorageFile( m_pStorStm );
+
+ if ( bIsUCBStorage )
+ {
+ if ( UCBStorage::GetLinkedFile( *m_pStorStm ).Len() )
+ {
+ // detect special unpacked storages
+ m_pOwnStg = new UCBStorage( *m_pStorStm, (nStorageMode & STORAGE_TRANSACTED) ? FALSE : TRUE );
+ m_bDelStm = TRUE;
+ }
+ else
+ {
+ // detect special disk spanned storages
+ if ( UCBStorage::IsDiskSpannedFile( m_pStorStm ) )
+ nMode |= STORAGE_DISKSPANNED_MODE;
+
+ // UCBStorage always works directly on the UCB content, so discard the stream first
+ DELETEZ( m_pStorStm );
+ m_pOwnStg = new UCBStorage( m_aName, nMode, (nStorageMode & STORAGE_TRANSACTED) ? FALSE : TRUE );
+ }
+ }
+ else
+ {
+ // OLEStorage can be opened with a stream
+ m_pOwnStg = new Storage( *m_pStorStm, (nStorageMode & STORAGE_TRANSACTED) ? FALSE : TRUE );
+ m_bDelStm = TRUE;
+ }
+ }
+ else if ( bForceUCBStorage )
+ {
+ m_pOwnStg = new UCBStorage( m_aName, nMode, (nStorageMode & STORAGE_TRANSACTED) ? FALSE : TRUE );
+ SetError( ERRCODE_IO_NOTSUPPORTED );
+ }
+ else
+ {
+ m_pOwnStg = new Storage( m_aName, nMode, (nStorageMode & STORAGE_TRANSACTED) ? FALSE : TRUE );
+ SetError( ERRCODE_IO_NOTSUPPORTED );
+ }
+ }
+ }
+ else
+ {
+ // temporary storage
+ if ( bForceUCBStorage )
+ m_pOwnStg = new UCBStorage( m_aName, nMode, (nStorageMode & STORAGE_TRANSACTED) ? FALSE : TRUE );
+ else
+ m_pOwnStg = new Storage( m_aName, nMode, (nStorageMode & STORAGE_TRANSACTED) ? FALSE : TRUE );
+ m_aName = m_pOwnStg->GetName();
+ }
+
+ SetError( m_pOwnStg->GetError() );
+
+ SignAsRoot( m_pOwnStg->IsRoot() );
+}
+
+SotStorage::SotStorage( BOOL bUCBStorage, const String & rName, StreamMode nMode, StorageMode nStorageMode )
+ INIT_SotStorage()
+{
+ m_aName = rName;
+ CreateStorage( bUCBStorage, nMode, nStorageMode );
+ if ( IsOLEStorage() )
+ m_nVersion = SOFFICE_FILEFORMAT_50;
+}
+
+SotStorage::SotStorage( BaseStorage * pStor )
+ INIT_SotStorage()
+{
+ if ( pStor )
+ {
+ m_aName = pStor->GetName(); // Namen merken
+ SignAsRoot( pStor->IsRoot() );
+ SetError( pStor->GetError() );
+ }
+
+ m_pOwnStg = pStor;
+ ULONG nErr = m_pOwnStg ? m_pOwnStg->GetError() : SVSTREAM_CANNOT_MAKE;
+ SetError( nErr );
+ if ( IsOLEStorage() )
+ m_nVersion = SOFFICE_FILEFORMAT_50;
+}
+
+SotStorage::SotStorage( BOOL bUCBStorage, SvStream & rStm )
+ INIT_SotStorage()
+{
+ SetError( rStm.GetError() );
+
+ // try as UCBStorage, next try as OLEStorage
+ if ( UCBStorage::IsStorageFile( &rStm ) || bUCBStorage )
+ m_pOwnStg = new UCBStorage( rStm, FALSE );
+ else
+ m_pOwnStg = new Storage( rStm, FALSE );
+
+ SetError( m_pOwnStg->GetError() );
+
+ if ( IsOLEStorage() )
+ m_nVersion = SOFFICE_FILEFORMAT_50;
+
+ SignAsRoot( m_pOwnStg->IsRoot() );
+}
+
+SotStorage::SotStorage( SvStream & rStm )
+ INIT_SotStorage()
+{
+ SetError( rStm.GetError() );
+
+ // try as UCBStorage, next try as OLEStorage
+ if ( UCBStorage::IsStorageFile( &rStm ) )
+ m_pOwnStg = new UCBStorage( rStm, FALSE );
+ else
+ m_pOwnStg = new Storage( rStm, FALSE );
+
+ SetError( m_pOwnStg->GetError() );
+
+ if ( IsOLEStorage() )
+ m_nVersion = SOFFICE_FILEFORMAT_50;
+
+ SignAsRoot( m_pOwnStg->IsRoot() );
+}
+
+SotStorage::SotStorage( SvStream * pStm, BOOL bDelete )
+ INIT_SotStorage()
+{
+ SetError( pStm->GetError() );
+
+ // try as UCBStorage, next try as OLEStorage
+ if ( UCBStorage::IsStorageFile( pStm ) )
+ m_pOwnStg = new UCBStorage( *pStm, FALSE );
+ else
+ m_pOwnStg = new Storage( *pStm, FALSE );
+
+ SetError( m_pOwnStg->GetError() );
+
+ m_pStorStm = pStm;
+ m_bDelStm = bDelete;
+ if ( IsOLEStorage() )
+ m_nVersion = SOFFICE_FILEFORMAT_50;
+
+ SignAsRoot( m_pOwnStg->IsRoot() );
+}
+
+/*************************************************************************
+|* SotStorage::~SotStorage()
+|*
+|* Beschreibung
+*************************************************************************/
+SotStorage::~SotStorage()
+{
+ delete m_pOwnStg;
+ if( m_bDelStm )
+ delete m_pStorStm;
+}
+
+/*************************************************************************
+|* SotStorage::RemoveUNOStorageHolder()
+|*
+|* Beschreibung
+*************************************************************************/
+void SotStorage::RemoveUNOStorageHolder( UNOStorageHolder* pHolder )
+{
+ UCBStorage* pStg = PTR_CAST( UCBStorage, m_pOwnStg );
+ if ( pStg )
+ {
+ pStg->GetUNOStorageHolderList()->remove( pHolder );
+ pHolder->release();
+ }
+ else
+ {
+ DBG_ERROR("Not implemented!");
+ }
+}
+
+/*************************************************************************
+|* SotStorage::GetUNOAPIDuplicate()
+|*
+|* Beschreibung
+*************************************************************************/
+uno::Reference< embed::XStorage > SotStorage::GetUNOAPIDuplicate( const String& rEleName, sal_Int32 nUNOStorageMode )
+{
+ // after we create a duplicate we will register wrapper
+ // for storage messages, the wrapper will control the real storage
+ // the real storage will be able to ask the duplicate to dispose if it's parent is disposed
+
+ uno::Reference< embed::XStorage > xResult;
+
+ UCBStorage* pStg = PTR_CAST( UCBStorage, m_pOwnStg );
+ if ( !pStg )
+ return xResult;
+
+ UNOStorageHolderList* pUNOStorageHolderList = pStg->GetUNOStorageHolderList();
+ if ( !pUNOStorageHolderList )
+ return xResult;
+
+ for ( UNOStorageHolderList::iterator aIter = pUNOStorageHolderList->begin();
+ aIter != pUNOStorageHolderList->end(); aIter++ )
+ if ( (*aIter) && (*aIter)->GetStorageName().Equals( rEleName ) )
+ {
+ // the storage is already in use
+ return xResult;
+ }
+
+ if ( IsStream( rEleName ) )
+ return xResult;
+
+ if ( GetError() == ERRCODE_NONE )
+ {
+ StreamMode nMode = ( ( nUNOStorageMode & embed::ElementModes::WRITE ) == embed::ElementModes::WRITE ) ?
+ STREAM_WRITE : ( STREAM_READ | STREAM_NOCREATE );
+ if ( nUNOStorageMode & embed::ElementModes::NOCREATE )
+ nMode |= STREAM_NOCREATE;
+
+ sal_Bool bStorageReady = !IsStorage( rEleName );
+ SotStorageRef pChildStorage = OpenUCBStorage( rEleName, nMode, STORAGE_TRANSACTED );
+ if ( pChildStorage->GetError() == ERRCODE_NONE && pChildStorage->m_pOwnStg )
+ {
+ ::utl::TempFile* pTempFile = new ::utl::TempFile();
+ if ( pTempFile->GetURL().Len() )
+ {
+ if ( !bStorageReady )
+ {
+ UCBStorage* pChildUCBStg = PTR_CAST( UCBStorage, pChildStorage->m_pOwnStg );
+ if ( pChildUCBStg )
+ {
+ UCBStorage* pTempStorage = new UCBStorage( pTempFile->GetURL(), STREAM_WRITE, FALSE, TRUE );
+ if ( pTempStorage )
+ {
+ pChildUCBStg->CopyTo( pTempStorage );
+
+ // CopyTo does not transport unknown media type
+ // just workaround it
+ uno::Any aMediaType;
+
+ if ( pChildUCBStg->GetProperty(
+ ::rtl::OUString::createFromAscii( "MediaType" ), aMediaType ) )
+ pTempStorage->SetProperty( ::rtl::OUString::createFromAscii( "MediaType" ), aMediaType );
+
+ bStorageReady = !pChildUCBStg->GetError() && !pTempStorage->GetError()
+ && pTempStorage->Commit();
+
+ delete ((BaseStorage*)pTempStorage);
+ pTempStorage = NULL;
+ }
+ }
+
+ OSL_ENSURE( bStorageReady, "Problem on storage copy!\n" );
+ }
+
+ if ( bStorageReady )
+ {
+ try {
+ uno::Reference< lang::XSingleServiceFactory > xStorageFactory(
+ ::comphelper::getProcessServiceFactory()->createInstance(
+ ::rtl::OUString::createFromAscii( "com.sun.star.embed.StorageFactory" ) ),
+ uno::UNO_QUERY );
+
+ OSL_ENSURE( xStorageFactory.is(), "Can't create storage factory!\n" );
+ if ( xStorageFactory.is() )
+ {
+ uno::Sequence< uno::Any > aArg( 2 );
+ aArg[0] <<= ::rtl::OUString( pTempFile->GetURL() );
+ aArg[1] <<= nUNOStorageMode;
+ uno::Reference< embed::XStorage > xDuplStorage(
+ xStorageFactory->createInstanceWithArguments( aArg ),
+ uno::UNO_QUERY );
+
+ OSL_ENSURE( xDuplStorage.is(), "Can't open storage!\n" );
+ if ( xDuplStorage.is() )
+ {
+ UNOStorageHolder* pHolder =
+ new UNOStorageHolder( *this, *pChildStorage, xDuplStorage, pTempFile );
+ pHolder->acquire();
+ pTempFile = NULL;
+ pUNOStorageHolderList->push_back( pHolder );
+ xResult = xDuplStorage;
+ }
+ }
+ }
+ catch( uno::Exception& e )
+ {
+ (void)e;
+ OSL_ENSURE( sal_False, ::rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ) );
+ }
+ }
+ }
+
+ if ( pTempFile != NULL )
+ delete pTempFile;
+ }
+ else
+ SetError( pChildStorage->GetError() );
+ }
+
+ return xResult;
+}
+
+/*************************************************************************
+|* SotStorage::CreateMemoryStream()
+|*
+|* Beschreibung
+*************************************************************************/
+SvMemoryStream * SotStorage::CreateMemoryStream()
+{
+ SvMemoryStream * pStm = NULL;
+ pStm = new SvMemoryStream( 0x8000, 0x8000 );
+ SotStorageRef aStg = new SotStorage( *pStm );
+ if( CopyTo( aStg ) )
+ aStg->Commit();
+ else
+ {
+ aStg.Clear(); // Storage vorher freigeben
+ delete pStm;
+ pStm = NULL;
+ }
+ return pStm;
+}
+
+/*************************************************************************
+|* SotStorage::GetStorage()
+|*
+|* Beschreibung
+*************************************************************************/
+BOOL SotStorage::IsStorageFile( const String & rFileName )
+{
+ String aName( rFileName );
+ INetURLObject aObj( aName );
+ if ( aObj.GetProtocol() == INET_PROT_NOT_VALID )
+ {
+ String aURL;
+ ::utl::LocalFileHelper::ConvertPhysicalNameToURL( aName, aURL );
+ aObj.SetURL( aURL );
+ aName = aObj.GetMainURL( INetURLObject::NO_DECODE );
+ }
+
+ SvStream * pStm = ::utl::UcbStreamHelper::CreateStream( aName, STREAM_STD_READ );
+ BOOL bRet = SotStorage::IsStorageFile( pStm );
+ delete pStm;
+ return bRet;
+}
+
+BOOL SotStorage::IsStorageFile( SvStream* pStream )
+{
+ /** code for new storages must come first! **/
+ if ( pStream )
+ {
+ long nPos = pStream->Tell();
+ BOOL bRet = UCBStorage::IsStorageFile( pStream );
+ if ( !bRet )
+ bRet = Storage::IsStorageFile( pStream );
+ pStream->Seek( nPos );
+ return bRet;
+ }
+ else
+ return FALSE;
+}
+/*************************************************************************
+|* SotStorage::GetStorage()
+|*
+|* Beschreibung
+*************************************************************************/
+const String & SotStorage::GetName() const
+{
+ if( !m_aName.Len() )
+ {
+ DBG_ASSERT( Owner(), "must be owner" );
+ if( m_pOwnStg )
+ ((SotStorage *)this)->m_aName = m_pOwnStg->GetName();
+ }
+ return m_aName;
+}
+
+void SotStorage::SetName( const String& rName )
+{
+ // This method is necessary because most storages will not be opened with a FileName, but an external stream instead
+ // This stream is a stream opened by a UCP and so aName is only used as a transport for all client code of the SotStorage
+ // class that depends on the fact that a root storage has a name
+ DBG_ASSERT( !GetName().Len(), "SetName() must not be called when the storage already has a name!" );
+ m_aName = rName;
+}
+
+/*************************************************************************
+|* SotStorage::ResetError()
+|*
+|* Beschreibung
+*************************************************************************/
+void SotStorage::ResetError()
+{
+ m_nError = SVSTREAM_OK;
+ if( m_pOwnStg )
+ m_pOwnStg->ResetError();
+}
+
+/*************************************************************************
+|* SotStorage::SetClass()
+|* SotStorage::SetConvertClass()
+|*
+|* Beschreibung
+*************************************************************************/
+void SotStorage::SetClass( const SvGlobalName & rName,
+ ULONG nOriginalClipFormat,
+ const String & rUserTypeName )
+{
+ DBG_ASSERT( Owner(), "must be owner" );
+ if( m_pOwnStg )
+ m_pOwnStg->SetClass( rName, nOriginalClipFormat, rUserTypeName );
+ else
+ SetError( SVSTREAM_GENERALERROR );
+}
+
+void SotStorage::SetConvertClass( const SvGlobalName & rName,
+ ULONG nOriginalClipFormat,
+ const String & rUserTypeName )
+{
+ DBG_ASSERT( Owner(), "must be owner" );
+ if( m_pOwnStg )
+ m_pOwnStg->SetConvertClass( rName, nOriginalClipFormat, rUserTypeName );
+ else
+ SetError( SVSTREAM_GENERALERROR );
+}
+
+/*************************************************************************
+|* SotStorage::GetClassName()
+|* SotStorage::GetFormat()
+|* SotStorage::GetUserName()
+|* SotStorage::ShouldConvert()
+|*
+|* Beschreibung
+*************************************************************************/
+SvGlobalName SotStorage::GetClassName()
+{
+ SvGlobalName aGN;
+ DBG_ASSERT( Owner(), "must be owner" );
+ if( m_pOwnStg )
+ aGN = m_pOwnStg->GetClassName();
+ else
+ SetError( SVSTREAM_GENERALERROR );
+ return aGN;
+}
+
+ULONG SotStorage::GetFormat()
+{
+ ULONG nFormat = 0;
+ DBG_ASSERT( Owner(), "must be owner" );
+ if( m_pOwnStg )
+ nFormat = m_pOwnStg->GetFormat();
+ else
+ SetError( SVSTREAM_GENERALERROR );
+ return nFormat;
+}
+
+String SotStorage::GetUserName()
+{
+ String aName;
+ DBG_ASSERT( Owner(), "must be owner" );
+ if( m_pOwnStg )
+ aName = m_pOwnStg->GetUserName();
+ else
+ SetError( SVSTREAM_GENERALERROR );
+ return aName;
+}
+
+BOOL SotStorage::ShouldConvert()
+{
+ DBG_ASSERT( Owner(), "must be owner" );
+ if( m_pOwnStg )
+ return m_pOwnStg->ShouldConvert();
+ else
+ SetError( SVSTREAM_GENERALERROR );
+ return FALSE;
+}
+
+/*************************************************************************
+|* SotStorage::FillInfoList()
+|*
+|* Beschreibung
+*************************************************************************/
+void SotStorage::FillInfoList( SvStorageInfoList * pFillList ) const
+{
+ DBG_ASSERT( Owner(), "must be owner" );
+ if( m_pOwnStg )
+ m_pOwnStg->FillInfoList( pFillList );
+}
+
+/*************************************************************************
+|* SotStorage::CopyTo()
+|*
+|* Beschreibung
+*************************************************************************/
+BOOL SotStorage::CopyTo( SotStorage * pDestStg )
+{
+ DBG_ASSERT( Owner(), "must be owner" );
+ DBG_ASSERT( pDestStg->Owner(), "must be owner" );
+ if( m_pOwnStg && pDestStg->m_pOwnStg )
+ {
+ m_pOwnStg->CopyTo( pDestStg->m_pOwnStg );
+ SetError( m_pOwnStg->GetError() );
+ pDestStg->m_aKey = m_aKey;
+ pDestStg->m_nVersion = m_nVersion;
+ }
+ else
+ SetError( SVSTREAM_GENERALERROR );
+ return SVSTREAM_OK == GetError();
+}
+
+/*************************************************************************
+|* SotStorage::Commit()
+|*
+|* Beschreibung
+*************************************************************************/
+BOOL SotStorage::Commit()
+{
+ DBG_ASSERT( Owner(), "must be owner" );
+ if( m_pOwnStg )
+ {
+ if( !m_pOwnStg->Commit() )
+ SetError( m_pOwnStg->GetError() );
+ }
+ else
+ SetError( SVSTREAM_GENERALERROR );
+ return SVSTREAM_OK == GetError();
+}
+
+/*************************************************************************
+|* SotStorage::Revert()
+|*
+|* Beschreibung
+*************************************************************************/
+BOOL SotStorage::Revert()
+{
+ DBG_ASSERT( Owner(), "must be owner" );
+ if( m_pOwnStg )
+ {
+ if( !m_pOwnStg->Revert() )
+ SetError( m_pOwnStg->GetError() );
+ }
+ else
+ SetError( SVSTREAM_GENERALERROR );
+ return SVSTREAM_OK == GetError();
+}
+
+/*************************************************************************
+|* SotStorage::OpenStream()
+|*
+|* Beschreibung
+*************************************************************************/
+SotStorageStream * SotStorage::OpenEncryptedSotStream( const String & rEleName, const ByteString& rKey,
+ StreamMode nMode,
+ StorageMode nStorageMode )
+{
+ DBG_ASSERT( !nStorageMode, "StorageModes ignored" );
+ SotStorageStream * pStm = NULL;
+ DBG_ASSERT( Owner(), "must be owner" );
+ if( m_pOwnStg )
+ {
+ // volle Ole-Patches einschalten
+ // egal was kommt, nur exclusiv gestattet
+ nMode |= STREAM_SHARE_DENYALL;
+ ErrCode nE = m_pOwnStg->GetError();
+ BaseStorageStream* p = m_pOwnStg->OpenStream( rEleName, nMode,
+ (nStorageMode & STORAGE_TRANSACTED) ? FALSE : TRUE, &rKey );
+ pStm = new SotStorageStream( p );
+
+ if( !nE )
+ m_pOwnStg->ResetError(); // kein Fehler setzen
+ if( nMode & STREAM_TRUNC )
+ pStm->SetSize( 0 );
+ }
+ else
+ SetError( SVSTREAM_GENERALERROR );
+ return pStm;
+}
+
+SotStorageStream * SotStorage::OpenSotStream( const String & rEleName,
+ StreamMode nMode,
+ StorageMode nStorageMode )
+{
+ DBG_ASSERT( !nStorageMode, "StorageModes ignored" );
+ SotStorageStream * pStm = NULL;
+ DBG_ASSERT( Owner(), "must be owner" );
+ if( m_pOwnStg )
+ {
+ // volle Ole-Patches einschalten
+ // egal was kommt, nur exclusiv gestattet
+ nMode |= STREAM_SHARE_DENYALL;
+ ErrCode nE = m_pOwnStg->GetError();
+ BaseStorageStream * p = m_pOwnStg->OpenStream( rEleName, nMode,
+ (nStorageMode & STORAGE_TRANSACTED) ? FALSE : TRUE );
+ pStm = new SotStorageStream( p );
+
+ if( !nE )
+ m_pOwnStg->ResetError(); // kein Fehler setzen
+ if( nMode & STREAM_TRUNC )
+ pStm->SetSize( 0 );
+ }
+ else
+ SetError( SVSTREAM_GENERALERROR );
+ return pStm;
+}
+
+/*************************************************************************
+|* SotStorage::OpenStorage()
+|*
+|* Beschreibung
+*************************************************************************/
+SotStorage * SotStorage::OpenSotStorage( const String & rEleName,
+ StreamMode nMode,
+ StorageMode nStorageMode )
+{
+ SotStorage * pStor = NULL;
+ DBG_ASSERT( Owner(), "must be owner" );
+ if( m_pOwnStg )
+ {
+ nMode |= STREAM_SHARE_DENYALL;
+ ErrCode nE = m_pOwnStg->GetError();
+ BaseStorage * p = m_pOwnStg->OpenStorage( rEleName, nMode,
+ (nStorageMode & STORAGE_TRANSACTED) ? FALSE : TRUE );
+ if( p )
+ {
+ pStor = new SotStorage( p );
+ if( !nE )
+ m_pOwnStg->ResetError(); // kein Fehler setzen
+
+ return pStor;
+ }
+ }
+
+ SetError( SVSTREAM_GENERALERROR );
+
+ return NULL;
+}
+
+SotStorage * SotStorage::OpenUCBStorage( const String & rEleName,
+ StreamMode nMode,
+ StorageMode nStorageMode )
+{
+ SotStorage * pStor = NULL;
+ DBG_ASSERT( Owner(), "must be owner" );
+ if( m_pOwnStg )
+ {
+ nMode |= STREAM_SHARE_DENYALL;
+ ErrCode nE = m_pOwnStg->GetError();
+ BaseStorage * p = m_pOwnStg->OpenUCBStorage( rEleName, nMode,
+ (nStorageMode & STORAGE_TRANSACTED) ? FALSE : TRUE );
+ pStor = new SotStorage( p );
+ if( !nE )
+ m_pOwnStg->ResetError(); // kein Fehler setzen
+ }
+ else
+ SetError( SVSTREAM_GENERALERROR );
+ return pStor;
+}
+
+SotStorage * SotStorage::OpenOLEStorage( const String & rEleName,
+ StreamMode nMode,
+ StorageMode nStorageMode )
+{
+ SotStorage * pStor = NULL;
+ DBG_ASSERT( Owner(), "must be owner" );
+ if( m_pOwnStg )
+ {
+ nMode |= STREAM_SHARE_DENYALL;
+ ErrCode nE = m_pOwnStg->GetError();
+ BaseStorage * p = m_pOwnStg->OpenOLEStorage( rEleName, nMode,
+ (nStorageMode & STORAGE_TRANSACTED) ? FALSE : TRUE );
+ pStor = new SotStorage( p );
+ if( !nE )
+ m_pOwnStg->ResetError(); // kein Fehler setzen
+ }
+ else
+ SetError( SVSTREAM_GENERALERROR );
+ return pStor;
+}
+
+/*************************************************************************
+|* SotStorage::IsStream()
+|* SotStorage::IsStorage()
+|* SotStorage::IsContained()
+|*
+|* Beschreibung
+*************************************************************************/
+BOOL SotStorage::IsStorage( const String & rEleName ) const
+{
+ DBG_ASSERT( Owner(), "must be owner" );
+ // ein bisschen schneller
+ if( m_pOwnStg )
+ return m_pOwnStg->IsStorage( rEleName );
+ return FALSE;
+}
+
+BOOL SotStorage::IsStream( const String & rEleName ) const
+{
+ DBG_ASSERT( Owner(), "must be owner" );
+ // ein bisschen schneller
+ if( m_pOwnStg )
+ return m_pOwnStg->IsStream( rEleName );
+ return FALSE;
+}
+
+BOOL SotStorage::IsContained( const String & rEleName ) const
+{
+ DBG_ASSERT( Owner(), "must be owner" );
+ // ein bisschen schneller
+ if( m_pOwnStg )
+ return m_pOwnStg->IsContained( rEleName );
+ return FALSE;
+}
+
+/*************************************************************************
+|* SotStorage::Remove()
+|*
+|* Beschreibung
+*************************************************************************/
+BOOL SotStorage::Remove( const String & rEleName )
+{
+ DBG_ASSERT( Owner(), "must be owner" );
+ if( m_pOwnStg )
+ {
+ m_pOwnStg->Remove( rEleName );
+ SetError( m_pOwnStg->GetError() );
+ }
+ else
+ SetError( SVSTREAM_GENERALERROR );
+ return SVSTREAM_OK == GetError();
+}
+
+/*************************************************************************
+|* SotStorage::Rename()
+|*
+|* Beschreibung
+*************************************************************************/
+BOOL SotStorage::Rename( const String & rEleName, const String & rNewName )
+{
+ DBG_ASSERT( Owner(), "must be owner" );
+ if( m_pOwnStg )
+ {
+ m_pOwnStg->Rename( rEleName, rNewName );
+ SetError( m_pOwnStg->GetError() );
+ }
+ else
+ SetError( SVSTREAM_GENERALERROR );
+ return SVSTREAM_OK == GetError();
+}
+
+/*************************************************************************
+|* SotStorage::CopyTo()
+|*
+|* Beschreibung
+*************************************************************************/
+BOOL SotStorage::CopyTo( const String & rEleName,
+ SotStorage * pNewSt, const String & rNewName )
+{
+ DBG_ASSERT( Owner(), "must be owner" );
+ DBG_ASSERT( pNewSt->Owner(), "must be owner" );
+ if( m_pOwnStg )
+ {
+ m_pOwnStg->CopyTo( rEleName, pNewSt->m_pOwnStg, rNewName );
+ SetError( m_pOwnStg->GetError() );
+ SetError( pNewSt->GetError() );
+ }
+ else
+ SetError( SVSTREAM_GENERALERROR );
+ return SVSTREAM_OK == GetError();
+}
+
+/*************************************************************************
+|* SotStorage::MoveTo()
+|*
+|* Beschreibung
+*************************************************************************/
+BOOL SotStorage::MoveTo( const String & rEleName,
+ SotStorage * pNewSt, const String & rNewName )
+{
+ DBG_ASSERT( Owner(), "must be owner" );
+ DBG_ASSERT( pNewSt->Owner(), "must be owner" );
+ if( m_pOwnStg )
+ {
+ m_pOwnStg->MoveTo( rEleName, pNewSt->m_pOwnStg, rNewName );
+ SetError( m_pOwnStg->GetError() );
+ SetError( pNewSt->GetError() );
+ }
+ else
+ SetError( SVSTREAM_GENERALERROR );
+ return SVSTREAM_OK == GetError();
+}
+
+const SvStream* SotStorage::GetSvStream()
+{
+ const SvStream* pResult = 0;
+ DBG_ASSERT( Owner(), "must be owner" );
+ if( m_pOwnStg )
+ pResult = m_pOwnStg->GetSvStream();
+ return pResult;
+}
+
+SvStream* SotStorage::GetTargetSvStream() const
+{
+ SvStream* pResult = 0;
+ DBG_ASSERT( Owner(), "must be owner" );
+ if( m_pOwnStg )
+ pResult = (SvStream*)(m_pOwnStg->GetSvStream());
+ return pResult;
+}
+
+
+BOOL SotStorage::Validate()
+{
+ DBG_ASSERT( m_bIsRoot, "Validate nur an Rootstorage" );
+ if( m_pOwnStg )
+ return m_pOwnStg->ValidateFAT();
+ else
+ return TRUE;
+}
+
+BOOL SotStorage::SetProperty( const String& rName, const ::com::sun::star::uno::Any& rValue )
+{
+ UCBStorage* pStg = PTR_CAST( UCBStorage, m_pOwnStg );
+ if ( pStg )
+ {
+ return pStg->SetProperty( rName, rValue );
+ }
+ else
+ {
+ DBG_WARNING("W1:Not implemented!");
+ return FALSE;
+ }
+}
+
+BOOL SotStorage::GetProperty( const String& rName, ::com::sun::star::uno::Any& rValue )
+{
+ UCBStorage* pStg = PTR_CAST( UCBStorage, m_pOwnStg );
+ if ( pStg )
+ {
+ return pStg->GetProperty( rName, rValue );
+ }
+ else if ( rName.CompareToAscii("MediaType") == COMPARE_EQUAL )
+ {
+ String aStr = SotExchange::GetFormatMimeType( GetFormat() );
+ USHORT nPos = aStr.Search(';');
+ if ( nPos != STRING_NOTFOUND )
+ aStr = aStr.Copy( 0, nPos );
+ rValue <<= (::rtl::OUString) aStr;
+ return TRUE;
+ }
+ else
+ {
+ DBG_WARNING("W1:Not implemented!");
+ return FALSE;
+ }
+}
+
+BOOL SotStorage::GetProperty( const String& rEleName, const String& rName, ::com::sun::star::uno::Any& rValue )
+{
+ UCBStorage* pStg = PTR_CAST( UCBStorage, m_pOwnStg );
+ if ( pStg )
+ {
+ return pStg->GetProperty( rEleName, rName, rValue );
+ }
+ else
+ {
+ DBG_WARNING("W1:Not implemented!");
+ return FALSE;
+ }
+}
+
+BOOL SotStorage::IsOLEStorage() const
+{
+ UCBStorage* pStg = PTR_CAST( UCBStorage, m_pOwnStg );
+ return !pStg;
+}
+
+BOOL SotStorage::IsOLEStorage( const String & rFileName )
+{
+ return Storage::IsStorageFile( rFileName );
+}
+
+BOOL SotStorage::IsOLEStorage( SvStream* pStream )
+{
+ return Storage::IsStorageFile( pStream );
+}
+
+void SotStorage::SetKey( const ByteString& rKey )
+{
+ m_aKey = rKey;
+ if ( !IsOLEStorage() )
+ {
+ sal_uInt8 aBuffer[RTL_DIGEST_LENGTH_SHA1];
+ rtlDigestError nError = rtl_digest_SHA1( m_aKey.GetBuffer(), m_aKey.Len(), aBuffer, RTL_DIGEST_LENGTH_SHA1 );
+ if ( nError == rtl_Digest_E_None )
+ {
+ sal_uInt8* pBuffer = aBuffer;
+ ::com::sun::star::uno::Sequence < sal_Int8 > aSequ( (sal_Int8*) pBuffer, RTL_DIGEST_LENGTH_SHA1 );
+ ::com::sun::star::uno::Any aAny;
+ aAny <<= aSequ;
+ SetProperty( ::rtl::OUString::createFromAscii("EncryptionKey"), aAny );
+ }
+ }
+}
+
+SotStorage* SotStorage::OpenOLEStorage( const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >& xStorage,
+ const String& rEleName, StreamMode nMode )
+{
+ sal_Int32 nEleMode = embed::ElementModes::SEEKABLEREAD;
+ if ( nMode & STREAM_WRITE )
+ nEleMode |= embed::ElementModes::WRITE;
+ if ( nMode & STREAM_TRUNC )
+ nEleMode |= embed::ElementModes::TRUNCATE;
+ if ( nMode & STREAM_NOCREATE )
+ nEleMode |= embed::ElementModes::NOCREATE;
+
+ SvStream* pStream = NULL;
+ try
+ {
+ uno::Reference < io::XStream > xStream = xStorage->openStreamElement( rEleName, nEleMode );
+
+ // TODO/LATER: should it be done this way?
+ if ( nMode & STREAM_WRITE )
+ {
+ uno::Reference < beans::XPropertySet > xStreamProps( xStream, uno::UNO_QUERY_THROW );
+ xStreamProps->setPropertyValue(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ),
+ uno::makeAny( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/vnd.sun.star.oleobject" ) ) ) );
+ }
+
+ pStream = utl::UcbStreamHelper::CreateStream( xStream );
+ }
+ catch ( uno::Exception& )
+ {
+ //TODO/LATER: ErrorHandling
+ pStream = new SvMemoryStream;
+ pStream->SetError( ERRCODE_IO_GENERAL );
+ }
+
+ return new SotStorage( pStream, TRUE );
+}
+
+sal_Int32 SotStorage::GetFormatID( const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >& xStorage )
+{
+ uno::Reference< beans::XPropertySet > xProps( xStorage, uno::UNO_QUERY );
+ if ( !xProps.is() )
+ return 0;
+
+ ::rtl::OUString aMediaType;
+ xProps->getPropertyValue( ::rtl::OUString::createFromAscii( "MediaType" ) ) >>= aMediaType;
+ if ( aMediaType.getLength() )
+ {
+ ::com::sun::star::datatransfer::DataFlavor aDataFlavor;
+ aDataFlavor.MimeType = aMediaType;
+ return SotExchange::GetFormat( aDataFlavor );
+ }
+
+ return 0;
+}
+
+sal_Int32 SotStorage::GetVersion( const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >& xStorage )
+{
+ sal_Int32 nSotFormatID = SotStorage::GetFormatID( xStorage );
+ switch( nSotFormatID )
+ {
+ case SOT_FORMATSTR_ID_STARWRITER_8:
+ case SOT_FORMATSTR_ID_STARWRITER_8_TEMPLATE:
+ case SOT_FORMATSTR_ID_STARWRITERWEB_8:
+ case SOT_FORMATSTR_ID_STARWRITERGLOB_8:
+ case SOT_FORMATSTR_ID_STARDRAW_8:
+ case SOT_FORMATSTR_ID_STARDRAW_8_TEMPLATE:
+ case SOT_FORMATSTR_ID_STARIMPRESS_8:
+ case SOT_FORMATSTR_ID_STARIMPRESS_8_TEMPLATE:
+ case SOT_FORMATSTR_ID_STARCALC_8:
+ case SOT_FORMATSTR_ID_STARCALC_8_TEMPLATE:
+ case SOT_FORMATSTR_ID_STARCHART_8:
+ case SOT_FORMATSTR_ID_STARCHART_8_TEMPLATE:
+ case SOT_FORMATSTR_ID_STARMATH_8:
+ case SOT_FORMATSTR_ID_STARMATH_8_TEMPLATE:
+ return SOFFICE_FILEFORMAT_8;
+ case SOT_FORMATSTR_ID_STARWRITER_60:
+ case SOT_FORMATSTR_ID_STARWRITERWEB_60:
+ case SOT_FORMATSTR_ID_STARWRITERGLOB_60:
+ case SOT_FORMATSTR_ID_STARDRAW_60:
+ case SOT_FORMATSTR_ID_STARIMPRESS_60:
+ case SOT_FORMATSTR_ID_STARCALC_60:
+ case SOT_FORMATSTR_ID_STARCHART_60:
+ case SOT_FORMATSTR_ID_STARMATH_60:
+ return SOFFICE_FILEFORMAT_60;
+ }
+
+ return 0;
+}
+
diff --git a/sot/source/sdstor/storinfo.cxx b/sot/source/sdstor/storinfo.cxx
new file mode 100644
index 000000000000..2aaaadd5a151
--- /dev/null
+++ b/sot/source/sdstor/storinfo.cxx
@@ -0,0 +1,111 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sot.hxx"
+
+#include <stg.hxx>
+#include <storinfo.hxx>
+#include <sot/exchange.hxx>
+
+
+/************** class SvStorageInfoList **********************************
+*************************************************************************/
+PRV_SV_IMPL_OWNER_LIST(SvStorageInfoList,SvStorageInfo)
+
+const SvStorageInfo * SvStorageInfoList::Get( const String & rEleName )
+{
+ for( ULONG i = 0; i < Count(); i++ )
+ {
+ const SvStorageInfo & rType = GetObject( i );
+ if( rType.GetName() == rEleName )
+ return &rType;
+ }
+ return NULL;
+}
+
+/************** class SvStorageInfo **************************************
+*************************************************************************/
+ULONG ReadClipboardFormat( SvStream & rStm )
+{
+ sal_uInt32 nFormat = 0;
+ INT32 nLen = 0;
+ rStm >> nLen;
+ if( rStm.IsEof() )
+ rStm.SetError( SVSTREAM_GENERALERROR );
+ if( nLen > 0 )
+ {
+ // get a string name
+ sal_Char * p = new sal_Char[ nLen ];
+ if( rStm.Read( p, nLen ) == (ULONG) nLen )
+ {
+ nFormat = SotExchange::RegisterFormatName( String::CreateFromAscii( p, short(nLen-1) ) );
+ }
+ else
+ rStm.SetError( SVSTREAM_GENERALERROR );
+ delete [] p;
+ }
+ else if( nLen == -1L )
+ // Windows clipboard format
+ // SV und Win stimmen ueberein (bis einschl. FORMAT_GDIMETAFILE)
+ rStm >> nFormat;
+ else if( nLen == -2L )
+ {
+ rStm >> nFormat;
+ // Mac clipboard format
+ // ??? not implemented
+ rStm.SetError( SVSTREAM_GENERALERROR );
+ }
+ else if( nLen != 0 )
+ {
+ // unknown identifier
+ rStm.SetError( SVSTREAM_GENERALERROR );
+ }
+ return nFormat;
+}
+
+void WriteClipboardFormat( SvStream & rStm, ULONG nFormat )
+{
+ // determine the clipboard format string
+ String aCbFmt;
+ if( nFormat > FORMAT_GDIMETAFILE )
+ aCbFmt = SotExchange::GetFormatName( nFormat );
+ if( aCbFmt.Len() )
+ {
+ ByteString aAsciiCbFmt( aCbFmt, RTL_TEXTENCODING_ASCII_US );
+ rStm << (INT32) (aAsciiCbFmt.Len() + 1);
+ rStm << (const char *)aAsciiCbFmt.GetBuffer();
+ rStm << (UINT8) 0;
+ }
+ else if( nFormat )
+ rStm << (INT32) -1 // for Windows
+ << (INT32) nFormat;
+ else
+ rStm << (INT32) 0; // no clipboard format
+}
+
+
diff --git a/sot/source/sdstor/ucbstorage.cxx b/sot/source/sdstor/ucbstorage.cxx
new file mode 100644
index 000000000000..ea3b656272db
--- /dev/null
+++ b/sot/source/sdstor/ucbstorage.cxx
@@ -0,0 +1,3600 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sot.hxx"
+#include <com/sun/star/io/NotConnectedException.hpp>
+#include <com/sun/star/io/BufferSizeExceededException.hpp>
+#include <com/sun/star/uno/RuntimeException.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <ucbhelper/content.hxx>
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/ucb/XCommandEnvironment.hpp>
+#include <unotools/tempfile.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/ucb/InsertCommandArgument.hpp>
+#include <com/sun/star/ucb/ResultSetException.hpp>
+#include <com/sun/star/uno/Sequence.h>
+#include <com/sun/star/sdbc/XResultSet.hdl>
+#include <com/sun/star/ucb/XContentAccess.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/ucb/CommandAbortedException.hpp>
+#include <com/sun/star/datatransfer/DataFlavor.hpp>
+#include <com/sun/star/ucb/ContentInfo.hpp>
+#include <com/sun/star/ucb/ContentInfoAttribute.hpp>
+#include <com/sun/star/beans/Property.hpp>
+#include <com/sun/star/packages/manifest/XManifestWriter.hpp>
+#include <com/sun/star/packages/manifest/XManifestReader.hpp>
+#include <com/sun/star/ucb/InteractiveIOException.hpp>
+
+#include <rtl/digest.h>
+#include <tools/ref.hxx>
+#include <tools/debug.hxx>
+#include <unotools/streamhelper.hxx>
+#include <unotools/streamwrap.hxx>
+#include <unotools/ucbhelper.hxx>
+#include <unotools/localfilehelper.hxx>
+#include <tools/list.hxx>
+#include <tools/urlobj.hxx>
+#include <unotools/streamwrap.hxx>
+#include <comphelper/processfactory.hxx>
+#include <cppuhelper/implbase2.hxx>
+#include <ucbhelper/commandenvironment.hxx>
+
+#include "stg.hxx"
+#include "storinfo.hxx"
+#include <sot/storage.hxx>
+#include <sot/exchange.hxx>
+#include <sot/formats.hxx>
+#include "clsids.hxx"
+
+#include "unostorageholder.hxx"
+
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ucb;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::sdbc;
+using namespace ::ucbhelper;
+
+#if OSL_DEBUG_LEVEL > 1
+#include <stdio.h>
+static int nOpenFiles=0;
+static int nOpenStreams=0;
+#endif
+
+typedef ::cppu::WeakImplHelper2 < XInputStream, XSeekable > FileInputStreamWrapper_Base;
+class FileStreamWrapper_Impl : public FileInputStreamWrapper_Base
+{
+protected:
+ ::osl::Mutex m_aMutex;
+ String m_aURL;
+ SvStream* m_pSvStream;
+
+public:
+ FileStreamWrapper_Impl( const String& rName );
+ virtual ~FileStreamWrapper_Impl();
+
+ //DECLARE_UNO3_AGG_DEFAULTS( FileStreamWrapper_Impl, FileInputStreamWrapper_Base);
+
+ virtual void SAL_CALL seek( sal_Int64 _nLocation ) throw ( IllegalArgumentException, IOException, RuntimeException);
+ virtual sal_Int64 SAL_CALL getPosition( ) throw ( IOException, RuntimeException);
+ virtual sal_Int64 SAL_CALL getLength( ) throw ( IOException, RuntimeException);
+ virtual sal_Int32 SAL_CALL readBytes( Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead) throw( NotConnectedException, BufferSizeExceededException, RuntimeException );
+ virtual sal_Int32 SAL_CALL readSomeBytes( Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead) throw( NotConnectedException, BufferSizeExceededException, RuntimeException );
+ virtual void SAL_CALL skipBytes(sal_Int32 nBytesToSkip) throw( NotConnectedException, BufferSizeExceededException, RuntimeException);
+ virtual sal_Int32 SAL_CALL available() throw( NotConnectedException, RuntimeException );
+ virtual void SAL_CALL closeInput() throw( NotConnectedException, RuntimeException );
+
+protected:
+ void checkConnected();
+ void checkError();
+};
+
+//------------------------------------------------------------------
+FileStreamWrapper_Impl::FileStreamWrapper_Impl( const String& rName )
+ : m_aURL( rName )
+ , m_pSvStream(0)
+{
+ // if no URL is provided the stream is empty
+}
+
+//------------------------------------------------------------------
+FileStreamWrapper_Impl::~FileStreamWrapper_Impl()
+{
+ if ( m_pSvStream )
+ {
+ delete m_pSvStream;
+#if OSL_DEBUG_LEVEL > 1
+ --nOpenFiles;
+#endif
+ }
+
+ if ( m_aURL.Len() )
+ ::utl::UCBContentHelper::Kill( m_aURL );
+}
+
+//------------------------------------------------------------------------------
+sal_Int32 SAL_CALL FileStreamWrapper_Impl::readBytes(Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead)
+ throw( NotConnectedException, BufferSizeExceededException, RuntimeException )
+{
+ if ( !m_aURL.Len() )
+ {
+ aData.realloc( 0 );
+ return 0;
+ }
+
+ checkConnected();
+
+ if (nBytesToRead < 0)
+ throw BufferSizeExceededException(::rtl::OUString(),static_cast<XWeak*>(this));
+
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ aData.realloc(nBytesToRead);
+
+ sal_uInt32 nRead = m_pSvStream->Read((void*)aData.getArray(), nBytesToRead);
+ checkError();
+
+ // Wenn gelesene Zeichen < MaxLength, Sequence anpassen
+ if (nRead < (sal_uInt32)nBytesToRead)
+ aData.realloc( nRead );
+
+ return nRead;
+}
+
+//------------------------------------------------------------------------------
+sal_Int32 SAL_CALL FileStreamWrapper_Impl::readSomeBytes(Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead) throw( NotConnectedException, BufferSizeExceededException, RuntimeException )
+{
+ if ( !m_aURL.Len() )
+ {
+ aData.realloc( 0 );
+ return 0;
+ }
+
+ checkError();
+
+ if (nMaxBytesToRead < 0)
+ throw BufferSizeExceededException(::rtl::OUString(),static_cast<XWeak*>(this));
+
+ if (m_pSvStream->IsEof())
+ {
+ aData.realloc(0);
+ return 0;
+ }
+ else
+ return readBytes(aData, nMaxBytesToRead);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL FileStreamWrapper_Impl::skipBytes(sal_Int32 nBytesToSkip) throw( NotConnectedException, BufferSizeExceededException, RuntimeException )
+{
+ if ( !m_aURL.Len() )
+ return;
+
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkError();
+
+#ifdef DBG_UTIL
+ sal_uInt32 nCurrentPos = m_pSvStream->Tell();
+#endif
+
+ m_pSvStream->SeekRel(nBytesToSkip);
+ checkError();
+
+#ifdef DBG_UTIL
+ nCurrentPos = m_pSvStream->Tell();
+#endif
+}
+
+//------------------------------------------------------------------------------
+sal_Int32 SAL_CALL FileStreamWrapper_Impl::available() throw( NotConnectedException, RuntimeException )
+{
+ if ( !m_aURL.Len() )
+ return 0;
+
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkConnected();
+
+ sal_uInt32 nPos = m_pSvStream->Tell();
+ checkError();
+
+ m_pSvStream->Seek(STREAM_SEEK_TO_END);
+ checkError();
+
+ sal_Int32 nAvailable = (sal_Int32)m_pSvStream->Tell() - nPos;
+ m_pSvStream->Seek(nPos);
+ checkError();
+
+ return nAvailable;
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL FileStreamWrapper_Impl::closeInput() throw( NotConnectedException, RuntimeException )
+{
+ if ( !m_aURL.Len() )
+ return;
+
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkConnected();
+ DELETEZ( m_pSvStream );
+#if OSL_DEBUG_LEVEL > 1
+ --nOpenFiles;
+#endif
+ ::utl::UCBContentHelper::Kill( m_aURL );
+ m_aURL.Erase();
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL FileStreamWrapper_Impl::seek( sal_Int64 _nLocation ) throw (IllegalArgumentException, IOException, RuntimeException)
+{
+ if ( !m_aURL.Len() )
+ return;
+
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkConnected();
+
+ m_pSvStream->Seek((sal_uInt32)_nLocation);
+ checkError();
+}
+
+//------------------------------------------------------------------------------
+sal_Int64 SAL_CALL FileStreamWrapper_Impl::getPosition( ) throw (IOException, RuntimeException)
+{
+ if ( !m_aURL.Len() )
+ return 0;
+
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkConnected();
+
+ sal_uInt32 nPos = m_pSvStream->Tell();
+ checkError();
+ return (sal_Int64)nPos;
+}
+
+//------------------------------------------------------------------------------
+sal_Int64 SAL_CALL FileStreamWrapper_Impl::getLength( ) throw (IOException, RuntimeException)
+{
+ if ( !m_aURL.Len() )
+ return 0;
+
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkConnected();
+
+ sal_uInt32 nCurrentPos = m_pSvStream->Tell();
+ checkError();
+
+ m_pSvStream->Seek(STREAM_SEEK_TO_END);
+ sal_uInt32 nEndPos = m_pSvStream->Tell();
+ m_pSvStream->Seek(nCurrentPos);
+
+ checkError();
+
+ return (sal_Int64)nEndPos;
+}
+
+//------------------------------------------------------------------------------
+void FileStreamWrapper_Impl::checkConnected()
+{
+ if ( !m_aURL.Len() )
+ throw NotConnectedException(::rtl::OUString(), const_cast<XWeak*>(static_cast<const XWeak*>(this)));
+ if ( !m_pSvStream )
+ {
+ m_pSvStream = ::utl::UcbStreamHelper::CreateStream( m_aURL, STREAM_STD_READ );
+#if OSL_DEBUG_LEVEL > 1
+ ++nOpenFiles;
+#endif
+ }
+}
+
+//------------------------------------------------------------------------------
+void FileStreamWrapper_Impl::checkError()
+{
+ checkConnected();
+
+ if (m_pSvStream->SvStream::GetError() != ERRCODE_NONE)
+ // TODO: really evaluate the error
+ throw NotConnectedException(::rtl::OUString(), const_cast<XWeak*>(static_cast<const XWeak*>(this)));
+}
+
+TYPEINIT1( UCBStorageStream, BaseStorageStream );
+TYPEINIT1( UCBStorage, BaseStorage );
+
+#define COMMIT_RESULT_FAILURE 0
+#define COMMIT_RESULT_NOTHING_TO_DO 1
+#define COMMIT_RESULT_SUCCESS 2
+
+#define min( x, y ) (( x < y ) ? x : y)
+#define max( x, y ) (( x > y ) ? x : y)
+
+sal_Int32 GetFormatId_Impl( SvGlobalName aName )
+{
+// if ( aName == SvGlobalName( SO3_SW_CLASSID_8 ) )
+// return SOT_FORMATSTR_ID_STARWRITER_8;
+// if ( aName == SvGlobalName( SO3_SWWEB_CLASSID_8 ) )
+// return SOT_FORMATSTR_ID_STARWRITERWEB_8;
+// if ( aName == SvGlobalName( SO3_SWGLOB_CLASSID_8 ) )
+// return SOT_FORMATSTR_ID_STARWRITERGLOB_8;
+// if ( aName == SvGlobalName( SO3_SDRAW_CLASSID_8 ) )
+// return SOT_FORMATSTR_ID_STARDRAW_8;
+// if ( aName == SvGlobalName( SO3_SIMPRESS_CLASSID_8 ) )
+// return SOT_FORMATSTR_ID_STARIMPRESS_8;
+// if ( aName == SvGlobalName( SO3_SC_CLASSID_8 ) )
+// return SOT_FORMATSTR_ID_STARCALC_8;
+// if ( aName == SvGlobalName( SO3_SCH_CLASSID_8 ) )
+// return SOT_FORMATSTR_ID_STARCHART_8;
+// if ( aName == SvGlobalName( SO3_SM_CLASSID_8 ) )
+// return SOT_FORMATSTR_ID_STARMATH_8;
+ if ( aName == SvGlobalName( SO3_SW_CLASSID_60 ) )
+ return SOT_FORMATSTR_ID_STARWRITER_60;
+ if ( aName == SvGlobalName( SO3_SWWEB_CLASSID_60 ) )
+ return SOT_FORMATSTR_ID_STARWRITERWEB_60;
+ if ( aName == SvGlobalName( SO3_SWGLOB_CLASSID_60 ) )
+ return SOT_FORMATSTR_ID_STARWRITERGLOB_60;
+ if ( aName == SvGlobalName( SO3_SDRAW_CLASSID_60 ) )
+ return SOT_FORMATSTR_ID_STARDRAW_60;
+ if ( aName == SvGlobalName( SO3_SIMPRESS_CLASSID_60 ) )
+ return SOT_FORMATSTR_ID_STARIMPRESS_60;
+ if ( aName == SvGlobalName( SO3_SC_CLASSID_60 ) )
+ return SOT_FORMATSTR_ID_STARCALC_60;
+ if ( aName == SvGlobalName( SO3_SCH_CLASSID_60 ) )
+ return SOT_FORMATSTR_ID_STARCHART_60;
+ if ( aName == SvGlobalName( SO3_SM_CLASSID_60 ) )
+ return SOT_FORMATSTR_ID_STARMATH_60;
+ if ( aName == SvGlobalName( SO3_OUT_CLASSID ) ||
+ aName == SvGlobalName( SO3_APPLET_CLASSID ) ||
+ aName == SvGlobalName( SO3_PLUGIN_CLASSID ) ||
+ aName == SvGlobalName( SO3_IFRAME_CLASSID ) )
+ // allowed, but not supported
+ return 0;
+ else
+ {
+ DBG_ERROR( "Unknown UCB storage format!" );
+ return 0;
+ }
+}
+
+
+SvGlobalName GetClassId_Impl( sal_Int32 nFormat )
+{
+ switch ( nFormat )
+ {
+ case SOT_FORMATSTR_ID_STARWRITER_8 :
+ case SOT_FORMATSTR_ID_STARWRITER_8_TEMPLATE :
+ return SvGlobalName( SO3_SW_CLASSID_60 );
+ case SOT_FORMATSTR_ID_STARWRITERWEB_8 :
+ return SvGlobalName( SO3_SWWEB_CLASSID_60 );
+ case SOT_FORMATSTR_ID_STARWRITERGLOB_8 :
+ return SvGlobalName( SO3_SWGLOB_CLASSID_60 );
+ case SOT_FORMATSTR_ID_STARDRAW_8 :
+ case SOT_FORMATSTR_ID_STARDRAW_8_TEMPLATE :
+ return SvGlobalName( SO3_SDRAW_CLASSID_60 );
+ case SOT_FORMATSTR_ID_STARIMPRESS_8 :
+ case SOT_FORMATSTR_ID_STARIMPRESS_8_TEMPLATE :
+ return SvGlobalName( SO3_SIMPRESS_CLASSID_60 );
+ case SOT_FORMATSTR_ID_STARCALC_8 :
+ case SOT_FORMATSTR_ID_STARCALC_8_TEMPLATE :
+ return SvGlobalName( SO3_SC_CLASSID_60 );
+ case SOT_FORMATSTR_ID_STARCHART_8 :
+ case SOT_FORMATSTR_ID_STARCHART_8_TEMPLATE :
+ return SvGlobalName( SO3_SCH_CLASSID_60 );
+ case SOT_FORMATSTR_ID_STARMATH_8 :
+ case SOT_FORMATSTR_ID_STARMATH_8_TEMPLATE :
+ return SvGlobalName( SO3_SM_CLASSID_60 );
+ case SOT_FORMATSTR_ID_STARWRITER_60 :
+ return SvGlobalName( SO3_SW_CLASSID_60 );
+ case SOT_FORMATSTR_ID_STARWRITERWEB_60 :
+ return SvGlobalName( SO3_SWWEB_CLASSID_60 );
+ case SOT_FORMATSTR_ID_STARWRITERGLOB_60 :
+ return SvGlobalName( SO3_SWGLOB_CLASSID_60 );
+ case SOT_FORMATSTR_ID_STARDRAW_60 :
+ return SvGlobalName( SO3_SDRAW_CLASSID_60 );
+ case SOT_FORMATSTR_ID_STARIMPRESS_60 :
+ return SvGlobalName( SO3_SIMPRESS_CLASSID_60 );
+ case SOT_FORMATSTR_ID_STARCALC_60 :
+ return SvGlobalName( SO3_SC_CLASSID_60 );
+ case SOT_FORMATSTR_ID_STARCHART_60 :
+ return SvGlobalName( SO3_SCH_CLASSID_60 );
+ case SOT_FORMATSTR_ID_STARMATH_60 :
+ return SvGlobalName( SO3_SM_CLASSID_60 );
+ default :
+ //DBG_ERROR( "Unknown UCB storage format!" );
+ return SvGlobalName();
+ }
+}
+
+// All storage and streams are refcounted internally; outside of this classes they are only accessible through a handle
+// class, that uses the refcounted object as impl-class.
+
+enum RepresentModes {
+ nonset,
+ svstream,
+ xinputstream
+};
+
+class UCBStorageStream_Impl : public SvRefBase, public SvStream
+{
+ ~UCBStorageStream_Impl();
+public:
+
+ virtual ULONG GetData( void* pData, ULONG nSize );
+ virtual ULONG PutData( const void* pData, ULONG nSize );
+ virtual ULONG SeekPos( ULONG nPos );
+ virtual void SetSize( ULONG nSize );
+ virtual void FlushData();
+ virtual void ResetError();
+
+ UCBStorageStream* m_pAntiImpl; // only valid if an external reference exists
+
+ String m_aOriginalName;// the original name before accessing the stream
+ String m_aName; // the actual name ( changed with a Rename command at the parent )
+ String m_aURL; // the full path name to create the content
+ String m_aContentType;
+ String m_aOriginalContentType;
+ ByteString m_aKey;
+ ::ucbhelper::Content* m_pContent; // the content that provides the data
+ Reference<XInputStream> m_rSource; // the stream covering the original data of the content
+ SvStream* m_pStream; // the stream worked on; for readonly streams it is the original stream of the content
+ // for read/write streams it's a copy into a temporary file
+ String m_aTempURL; // URL of this temporary stream
+ RepresentModes m_nRepresentMode; // should it be used as XInputStream or as SvStream
+ long m_nError;
+ StreamMode m_nMode; // open mode ( read/write/trunc/nocreate/sharing )
+ BOOL m_bSourceRead; // Source still contains useful information
+ BOOL m_bModified; // only modified streams will be sent to the original content
+ BOOL m_bCommited; // sending the streams is coordinated by the root storage of the package
+ BOOL m_bDirect; // the storage and its streams are opened in direct mode; for UCBStorages
+ // this means that the root storage does an autocommit when its external
+ // reference is destroyed
+ BOOL m_bIsOLEStorage;// an OLEStorage on a UCBStorageStream makes this an Autocommit-stream
+
+ UCBStorageStream_Impl( const String&, StreamMode, UCBStorageStream*, BOOL, const ByteString* pKey=0, BOOL bRepair = FALSE, Reference< XProgressHandler > xProgress = Reference< XProgressHandler >() );
+
+ void Free();
+ BOOL Init();
+ BOOL Clear();
+ sal_Int16 Commit(); // if modified and commited: transfer an XInputStream to the content
+ BOOL Revert(); // discard all changes
+ BaseStorage* CreateStorage();// create an OLE Storage on the UCBStorageStream
+ ULONG GetSize();
+
+ ULONG ReadSourceWriteTemporary( ULONG aLength ); // read aLength from source and copy to temporary,
+ // no seeking is produced
+ ULONG ReadSourceWriteTemporary(); // read source till the end and copy to temporary,
+ // no seeking is produced
+#if 0
+ ULONG CopySourceToTemporary( ULONG aLength ); // same as ReadSourceWriteToTemporary( aLength )
+ // but the writing is done at the end of temporary
+ // pointer position is not changed
+#endif
+
+ ULONG CopySourceToTemporary(); // same as ReadSourceWriteToTemporary()
+ // but the writing is done at the end of temporary
+ // pointer position is not changed
+ Reference<XInputStream> GetXInputStream(); // return XInputStream, after that
+ // this class is close to be unusable
+ // since it can not read and write
+ using SvStream::SetError;
+ void SetError( sal_uInt32 nError );
+ void PrepareCachedForReopen( StreamMode nMode );
+};
+
+SV_DECL_IMPL_REF( UCBStorageStream_Impl );
+
+struct UCBStorageElement_Impl;
+DECLARE_LIST( UCBStorageElementList_Impl, UCBStorageElement_Impl* )
+
+class UCBStorage_Impl : public SvRefBase
+{
+ ~UCBStorage_Impl();
+public:
+ UCBStorage* m_pAntiImpl; // only valid if external references exists
+
+ String m_aOriginalName;// the original name before accessing the storage
+ String m_aName; // the actual name ( changed with a Rename command at the parent )
+ String m_aURL; // the full path name to create the content
+ String m_aContentType;
+ String m_aOriginalContentType;
+ ::ucbhelper::Content* m_pContent; // the content that provides the storage elements
+ ::utl::TempFile* m_pTempFile; // temporary file, only for storages on stream
+ SvStream* m_pSource; // original stream, only for storages on a stream
+ //SvStream* m_pStream; // the corresponding editable stream, only for storage on a stream
+ long m_nError;
+ StreamMode m_nMode; // open mode ( read/write/trunc/nocreate/sharing )
+ BOOL m_bModified; // only modified elements will be sent to the original content
+ BOOL m_bCommited; // sending the streams is coordinated by the root storage of the package
+ BOOL m_bDirect; // the storage and its streams are opened in direct mode; for UCBStorages
+ // this means that the root storage does an autocommit when its external
+ // reference is destroyed
+ BOOL m_bIsRoot; // marks this storage as root storages that manages all oommits and reverts
+ BOOL m_bDirty; // ???
+ BOOL m_bIsLinked;
+ BOOL m_bListCreated;
+ ULONG m_nFormat;
+ String m_aUserTypeName;
+ SvGlobalName m_aClassId;
+
+ UCBStorageElementList_Impl m_aChildrenList;
+
+ BOOL m_bRepairPackage;
+ Reference< XProgressHandler > m_xProgressHandler;
+
+ UNOStorageHolderList* m_pUNOStorageHolderList;
+ UCBStorage_Impl( const ::ucbhelper::Content&, const String&, StreamMode, UCBStorage*, BOOL, BOOL, BOOL = FALSE, Reference< XProgressHandler > = Reference< XProgressHandler >() );
+ UCBStorage_Impl( const String&, StreamMode, UCBStorage*, BOOL, BOOL, BOOL = FALSE, Reference< XProgressHandler > = Reference< XProgressHandler >() );
+ UCBStorage_Impl( SvStream&, UCBStorage*, BOOL );
+ void Init();
+ sal_Int16 Commit();
+ BOOL Revert();
+ BOOL Insert( ::ucbhelper::Content *pContent );
+ UCBStorage_Impl* OpenStorage( UCBStorageElement_Impl* pElement, StreamMode nMode, BOOL bDirect );
+ UCBStorageStream_Impl* OpenStream( UCBStorageElement_Impl*, StreamMode, BOOL, const ByteString* pKey=0 );
+ void SetProps( const Sequence < Sequence < PropertyValue > >& rSequence, const String& );
+ void GetProps( sal_Int32&, Sequence < Sequence < PropertyValue > >& rSequence, const String& );
+ sal_Int32 GetObjectCount();
+ void ReadContent();
+ void CreateContent();
+ ::ucbhelper::Content* GetContent()
+ { if ( !m_pContent ) CreateContent(); return m_pContent; }
+ UCBStorageElementList_Impl& GetChildrenList()
+ {
+ long nError = m_nError;
+ ReadContent();
+ if ( m_nMode & STREAM_WRITE )
+ {
+ m_nError = nError;
+ if ( m_pAntiImpl )
+ {
+ m_pAntiImpl->ResetError();
+ m_pAntiImpl->SetError( nError );
+ }
+ }
+
+ return m_aChildrenList;
+ }
+
+ void SetError( long nError );
+};
+
+SV_DECL_IMPL_REF( UCBStorage_Impl );
+
+// this struct contains all neccessary information on an element inside a UCBStorage
+struct UCBStorageElement_Impl
+{
+ String m_aName; // the actual URL relative to the root "folder"
+ String m_aOriginalName;// the original name in the content
+ ULONG m_nSize;
+ BOOL m_bIsFolder; // Only TRUE when it is a UCBStorage !
+ BOOL m_bIsStorage; // Also TRUE when it is an OLEStorage !
+ BOOL m_bIsRemoved; // element will be removed on commit
+ BOOL m_bIsInserted; // element will be removed on revert
+ UCBStorage_ImplRef m_xStorage; // reference to the "real" storage
+ UCBStorageStream_ImplRef m_xStream; // reference to the "real" stream
+
+ UCBStorageElement_Impl( const ::rtl::OUString& rName,
+ BOOL bIsFolder = FALSE, ULONG nSize = 0 )
+ : m_aName( rName )
+ , m_aOriginalName( rName )
+ , m_nSize( nSize )
+ , m_bIsFolder( bIsFolder )
+ , m_bIsStorage( bIsFolder )
+ , m_bIsRemoved( FALSE )
+ , m_bIsInserted( FALSE )
+ {
+ }
+
+ ::ucbhelper::Content* GetContent();
+ BOOL IsModified();
+ String GetContentType();
+ void SetContentType( const String& );
+ String GetOriginalContentType();
+ BOOL IsLoaded()
+ { return m_xStream.Is() || m_xStorage.Is(); }
+};
+
+::ucbhelper::Content* UCBStorageElement_Impl::GetContent()
+{
+ if ( m_xStream.Is() )
+ return m_xStream->m_pContent;
+ else if ( m_xStorage.Is() )
+ return m_xStorage->GetContent();
+ else
+ return NULL;
+}
+
+String UCBStorageElement_Impl::GetContentType()
+{
+ if ( m_xStream.Is() )
+ return m_xStream->m_aContentType;
+ else if ( m_xStorage.Is() )
+ return m_xStorage->m_aContentType;
+ else
+ {
+ DBG_ERROR("Element not loaded!");
+ return String();
+ }
+}
+
+void UCBStorageElement_Impl::SetContentType( const String& rType )
+{
+ if ( m_xStream.Is() ) {
+ m_xStream->m_aContentType = m_xStream->m_aOriginalContentType = rType;
+ }
+ else if ( m_xStorage.Is() ) {
+ m_xStorage->m_aContentType = m_xStorage->m_aOriginalContentType = rType;
+ }
+ else {
+ DBG_ERROR("Element not loaded!");
+ }
+}
+
+String UCBStorageElement_Impl::GetOriginalContentType()
+{
+ if ( m_xStream.Is() )
+ return m_xStream->m_aOriginalContentType;
+ else if ( m_xStorage.Is() )
+ return m_xStorage->m_aOriginalContentType;
+ else
+ return String();
+}
+
+BOOL UCBStorageElement_Impl::IsModified()
+{
+ BOOL bModified = m_bIsRemoved || m_bIsInserted || m_aName != m_aOriginalName;
+ if ( bModified )
+ {
+ if ( m_xStream.Is() )
+ bModified = m_xStream->m_aContentType != m_xStream->m_aOriginalContentType;
+ else if ( m_xStorage.Is() )
+ bModified = m_xStorage->m_aContentType != m_xStorage->m_aOriginalContentType;
+ }
+
+ return bModified;
+}
+
+UCBStorageStream_Impl::UCBStorageStream_Impl( const String& rName, StreamMode nMode, UCBStorageStream* pStream, BOOL bDirect, const ByteString* pKey, BOOL bRepair, Reference< XProgressHandler > xProgress )
+ : m_pAntiImpl( pStream )
+ , m_aURL( rName )
+ , m_pContent( NULL )
+ , m_pStream( NULL )
+ , m_nRepresentMode( nonset )
+ , m_nError( 0 )
+ , m_nMode( nMode )
+ , m_bSourceRead( !( nMode & STREAM_TRUNC ) )
+ , m_bModified( FALSE )
+ , m_bCommited( FALSE )
+ , m_bDirect( bDirect )
+ , m_bIsOLEStorage( FALSE )
+{
+ // name is last segment in URL
+ INetURLObject aObj( rName );
+ m_aName = m_aOriginalName = aObj.GetLastName();
+ try
+ {
+ // create the content
+ Reference< ::com::sun::star::ucb::XCommandEnvironment > xComEnv;
+
+ ::rtl::OUString aTemp( rName );
+
+ if ( bRepair )
+ {
+ xComEnv = new ::ucbhelper::CommandEnvironment( Reference< ::com::sun::star::task::XInteractionHandler >(),
+ xProgress );
+ aTemp += rtl::OUString::createFromAscii("?repairpackage");
+ }
+
+ m_pContent = new ::ucbhelper::Content( aTemp, xComEnv );
+
+ if ( pKey )
+ {
+ m_aKey = *pKey;
+
+ // stream is encrypted and should be decrypted (without setting the key we'll get the raw data)
+ sal_uInt8 aBuffer[RTL_DIGEST_LENGTH_SHA1];
+ rtlDigestError nErr = rtl_digest_SHA1( pKey->GetBuffer(), pKey->Len(), aBuffer, RTL_DIGEST_LENGTH_SHA1 );
+ if ( nErr == rtl_Digest_E_None )
+ {
+ sal_uInt8* pBuffer = aBuffer;
+ ::com::sun::star::uno::Sequence < sal_Int8 > aSequ( (sal_Int8*) pBuffer, RTL_DIGEST_LENGTH_SHA1 );
+ ::com::sun::star::uno::Any aAny;
+ aAny <<= aSequ;
+ m_pContent->setPropertyValue( ::rtl::OUString::createFromAscii("EncryptionKey"), aAny );
+ }
+ }
+ }
+ catch ( ContentCreationException& )
+ {
+ // content could not be created
+ SetError( SVSTREAM_CANNOT_MAKE );
+ }
+ catch ( RuntimeException& )
+ {
+ // any other error - not specified
+ SetError( ERRCODE_IO_GENERAL );
+ }
+}
+
+UCBStorageStream_Impl::~UCBStorageStream_Impl()
+{
+ if( m_rSource.is() )
+ m_rSource = Reference< XInputStream >();
+
+ if( m_pStream )
+ delete m_pStream;
+
+ if ( m_aTempURL.Len() )
+ ::utl::UCBContentHelper::Kill( m_aTempURL );
+
+ if( m_pContent )
+ delete m_pContent;
+}
+
+
+Reference<XInputStream> UCBStorageStream_Impl::GetXInputStream()
+{
+ Reference< XInputStream > aResult;
+
+ if( m_pAntiImpl && m_nRepresentMode != nonset )
+ {
+ DBG_ERROR( "Misuse of the XInputstream!" );
+ SetError( ERRCODE_IO_ACCESSDENIED );
+ }
+ else
+ {
+ if( m_bModified )
+ {
+ // use wrapper around temporary stream
+ if( Init() )
+ {
+ CopySourceToTemporary();
+
+ // owner transfer of stream to wrapper
+ aResult = new ::utl::OInputStreamWrapper( m_pStream, TRUE );
+ m_pStream->Seek(0);
+
+ if( aResult.is() )
+ {
+ // temporary stream can not be used here any more
+ // and can not be opened untill wrapper is closed
+ // stream is deleted by wrapper after use
+ m_pStream = NULL;
+ m_nRepresentMode = xinputstream;
+ }
+ }
+ }
+ else
+ {
+ Free();
+
+ // open a new instance of XInputStream
+ try
+ {
+ aResult = m_pContent->openStream();
+ }
+ catch ( Exception& )
+ {
+ // usually means that stream could not be opened
+ }
+
+ if( aResult.is() )
+ m_nRepresentMode = xinputstream;
+ else
+ SetError( ERRCODE_IO_ACCESSDENIED );
+ }
+ }
+
+ return aResult;
+}
+
+BOOL UCBStorageStream_Impl::Init()
+{
+ if( m_nRepresentMode == xinputstream )
+ {
+ DBG_ERROR( "XInputStream misuse!" );
+ SetError( ERRCODE_IO_ACCESSDENIED );
+ return FALSE;
+ }
+
+ if( !m_pStream )
+ {
+ // no temporary stream was created
+ // create one
+
+ m_nRepresentMode = svstream; // can not be used as XInputStream
+
+ if ( !m_aTempURL.Len() )
+ m_aTempURL = ::utl::TempFile().GetURL();
+
+ m_pStream = ::utl::UcbStreamHelper::CreateStream( m_aTempURL, STREAM_STD_READWRITE, sal_True /* bFileExists */ );
+#if OSL_DEBUG_LEVEL > 1
+ ++nOpenFiles;
+#endif
+
+ if( !m_pStream )
+ {
+ DBG_ERROR( "Suspicious temporary stream creation!" );
+ SetError( SVSTREAM_CANNOT_MAKE );
+ return FALSE;
+ }
+
+ SetError( m_pStream->GetError() );
+ }
+
+ if( m_bSourceRead && !m_rSource.is() )
+ {
+ // source file contain usefull information and is not opened
+ // open it from the point of noncopied data
+
+ try
+ {
+ m_rSource = m_pContent->openStream();
+ }
+ catch ( Exception& )
+ {
+ // usually means that stream could not be opened
+ }
+
+ if( m_rSource.is() )
+ {
+ m_pStream->Seek( STREAM_SEEK_TO_END );
+
+ try
+ {
+ m_rSource->skipBytes( m_pStream->Tell() );
+ }
+ catch( BufferSizeExceededException& )
+ {
+ // the temporary stream already contain all the data
+ m_bSourceRead = FALSE;
+ }
+ catch( Exception& )
+ {
+ // something is really wrong
+ m_bSourceRead = FALSE;
+ DBG_ERROR( "Can not operate original stream!" );
+ SetError( SVSTREAM_CANNOT_MAKE );
+ }
+
+ m_pStream->Seek( 0 );
+ }
+ else
+ {
+ // if the new file is edited than no source exist
+ m_bSourceRead = FALSE;
+ //SetError( SVSTREAM_CANNOT_MAKE );
+ }
+ }
+
+ DBG_ASSERT( m_rSource.is() || !m_bSourceRead, "Unreadable source stream!" );
+
+ return sal_True;
+}
+
+ULONG UCBStorageStream_Impl::ReadSourceWriteTemporary()
+{
+ // read source stream till the end and copy all the data to
+ // the current position of the temporary stream
+
+ ULONG aResult = 0;
+
+ if( m_bSourceRead )
+ {
+ Sequence<sal_Int8> aData(32000);
+
+ try
+ {
+ ULONG aReaded;
+ do
+ {
+ aReaded = m_rSource->readBytes( aData, 32000 );
+ aResult += m_pStream->Write( aData.getArray(), aReaded );
+ } while( aReaded == 32000 );
+ }
+#if OSL_DEBUG_LEVEL > 1
+ catch( Exception & e )
+ {
+ OSL_ENSURE( FALSE, ::rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
+#else
+ catch( Exception & )
+ {
+#endif
+ }
+ }
+
+ m_bSourceRead = FALSE;
+
+ return aResult;
+
+}
+
+ULONG UCBStorageStream_Impl::ReadSourceWriteTemporary( ULONG aLength )
+{
+ // read aLength bite from the source stream and copy them to the current
+ // position of the temporary stream
+
+ ULONG aResult = 0;
+
+ if( m_bSourceRead )
+ {
+ Sequence<sal_Int8> aData(32000);
+
+ try
+ {
+
+ ULONG aReaded = 32000;
+
+ for( ULONG pInd = 0; pInd < aLength && aReaded == 32000 ; pInd += 32000 )
+ {
+ ULONG aToCopy = min( aLength - pInd, 32000 );
+ aReaded = m_rSource->readBytes( aData, aToCopy );
+ aResult += m_pStream->Write( aData.getArray(), aReaded );
+ }
+
+ if( aResult < aLength )
+ m_bSourceRead = FALSE;
+ }
+#if OSL_DEBUG_LEVEL > 1
+ catch( Exception & e )
+ {
+ OSL_ENSURE( FALSE, ::rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
+#else
+ catch( Exception & )
+ {
+#endif
+ }
+ }
+
+ return aResult;
+}
+
+ULONG UCBStorageStream_Impl::CopySourceToTemporary()
+{
+ // current position of the temporary stream is not changed
+ ULONG aResult = 0;
+
+ if( m_bSourceRead )
+ {
+ ULONG aPos = m_pStream->Tell();
+ m_pStream->Seek( STREAM_SEEK_TO_END );
+ aResult = ReadSourceWriteTemporary();
+ m_pStream->Seek( aPos );
+ }
+
+ return aResult;
+
+}
+
+#if 0
+ULONG UCBStorageStream_Impl::CopySourceToTemporary( ULONG aLength )
+{
+ // current position of the temporary stream is not changed
+ ULONG aResult = 0;
+
+ if( m_bSourceRead )
+ {
+ ULONG aPos = m_pStream->Tell();
+ m_pStream->Seek( STREAM_SEEK_TO_END );
+ aResult = ReadSourceWriteTemporary( aLength );
+ m_pStream->Seek( aPos );
+ }
+
+ return aResult;
+
+}
+#endif
+
+// UCBStorageStream_Impl must have a SvStream interface, because it then can be used as underlying stream
+// of an OLEStorage; so every write access caused by storage operations marks the UCBStorageStream as modified
+ULONG UCBStorageStream_Impl::GetData( void* pData, ULONG nSize )
+{
+ ULONG aResult = 0;
+
+ if( !Init() )
+ return 0;
+
+
+ // read data that is in temporary stream
+ aResult = m_pStream->Read( pData, nSize );
+ if( m_bSourceRead && aResult < nSize )
+ {
+ // read the tail of the data from original stream
+ // copy this tail to the temporary stream
+
+ ULONG aToRead = nSize - aResult;
+ pData = (void*)( (char*)pData + aResult );
+
+ try
+ {
+ Sequence<sal_Int8> aData( aToRead );
+ ULONG aReaded = m_rSource->readBytes( aData, aToRead );
+ aResult += m_pStream->Write( (void*)aData.getArray(), aReaded );
+ memcpy( pData, aData.getArray(), aReaded );
+ }
+#if OSL_DEBUG_LEVEL > 1
+ catch( Exception & e )
+ {
+ OSL_ENSURE( FALSE, ::rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
+#else
+ catch( Exception & )
+ {
+#endif
+ }
+
+ if( aResult < nSize )
+ m_bSourceRead = FALSE;
+ }
+
+ return aResult;
+}
+
+ULONG UCBStorageStream_Impl::PutData( const void* pData, ULONG nSize )
+{
+ if ( !(m_nMode & STREAM_WRITE) )
+ {
+ SetError( ERRCODE_IO_ACCESSDENIED );
+ return 0; // ?mav?
+ }
+
+ if( !nSize || !Init() )
+ return 0;
+
+ ULONG aResult = m_pStream->Write( pData, nSize );
+
+ m_bModified = aResult > 0;
+
+ return aResult;
+
+}
+
+ULONG UCBStorageStream_Impl::SeekPos( ULONG nPos )
+{
+ if( !Init() )
+ return 0;
+
+ ULONG aResult;
+
+ if( nPos == STREAM_SEEK_TO_END )
+ {
+ m_pStream->Seek( STREAM_SEEK_TO_END );
+ ReadSourceWriteTemporary();
+ aResult = m_pStream->Tell();
+ }
+ else
+ {
+ // the problem is that even if nPos is larger the the length
+ // of the stream the stream pointer will be moved to this position
+ // so we have to check if temporary stream does not contain required position
+
+ if( m_pStream->Tell() > nPos
+ || m_pStream->Seek( STREAM_SEEK_TO_END ) > nPos )
+ {
+ // no copiing is required
+ aResult = m_pStream->Seek( nPos );
+ }
+ else
+ {
+ // the temp stream pointer points to the end now
+ aResult = m_pStream->Tell();
+
+ if( aResult < nPos )
+ {
+ if( m_bSourceRead )
+ {
+ aResult += ReadSourceWriteTemporary( nPos - aResult );
+ if( aResult < nPos )
+ m_bSourceRead = FALSE;
+
+ DBG_ASSERT( aResult == m_pStream->Tell(), "Error in stream arithmetic!\n" );
+ }
+
+ if( (m_nMode & STREAM_WRITE) && !m_bSourceRead && aResult < nPos )
+ {
+ // it means that all the Source stream was copied already
+ // but the required position still was not reached
+ // for writable streams it should be done
+ m_pStream->SetStreamSize( nPos );
+ aResult = m_pStream->Seek( STREAM_SEEK_TO_END );
+ DBG_ASSERT( aResult == nPos, "Error in stream arithmetic!\n" );
+ }
+ }
+ }
+ }
+
+ return aResult;
+}
+
+void UCBStorageStream_Impl::SetSize( ULONG nSize )
+{
+ if ( !(m_nMode & STREAM_WRITE) )
+ {
+ SetError( ERRCODE_IO_ACCESSDENIED );
+ return;
+ }
+
+ if( !Init() )
+ return;
+
+ m_bModified = TRUE;
+
+ if( m_bSourceRead )
+ {
+ ULONG aPos = m_pStream->Tell();
+ m_pStream->Seek( STREAM_SEEK_TO_END );
+ if( m_pStream->Tell() < nSize )
+ ReadSourceWriteTemporary( nSize - m_pStream->Tell() );
+ m_pStream->Seek( aPos );
+ }
+
+ m_pStream->SetStreamSize( nSize );
+ m_bSourceRead = FALSE;
+}
+
+void UCBStorageStream_Impl::FlushData()
+{
+ if( m_pStream )
+ {
+ CopySourceToTemporary();
+ m_pStream->Flush();
+ }
+
+ m_bCommited = TRUE;
+}
+
+void UCBStorageStream_Impl::SetError( sal_uInt32 nErr )
+{
+ if ( !m_nError )
+ {
+ m_nError = nErr;
+ SvStream::SetError( nErr );
+ if ( m_pAntiImpl ) m_pAntiImpl->SetError( nErr );
+ }
+}
+
+void UCBStorageStream_Impl::ResetError()
+{
+ m_nError = 0;
+ SvStream::ResetError();
+ if ( m_pAntiImpl )
+ m_pAntiImpl->ResetError();
+}
+
+ULONG UCBStorageStream_Impl::GetSize()
+{
+ if( !Init() )
+ return 0;
+
+ ULONG nPos = m_pStream->Tell();
+ m_pStream->Seek( STREAM_SEEK_TO_END );
+ ReadSourceWriteTemporary();
+ ULONG nRet = m_pStream->Tell();
+ m_pStream->Seek( nPos );
+
+ return nRet;
+}
+
+BaseStorage* UCBStorageStream_Impl::CreateStorage()
+{
+ // create an OLEStorage on a SvStream ( = this )
+ // it gets the root attribute because otherwise it would probably not write before my root is commited
+ UCBStorageStream* pNewStorageStream = new UCBStorageStream( this );
+ Storage *pStorage = new Storage( *pNewStorageStream, m_bDirect );
+
+ // GetError() call cleares error code for OLE storages, must be changed in future
+ long nTmpErr = pStorage->GetError();
+ pStorage->SetError( nTmpErr );
+
+ m_bIsOLEStorage = !nTmpErr;
+ return static_cast< BaseStorage* > ( pStorage );
+}
+
+sal_Int16 UCBStorageStream_Impl::Commit()
+{
+ // send stream to the original content
+ // the parent storage is responsible for the correct handling of deleted contents
+ if ( m_bCommited || m_bIsOLEStorage || m_bDirect )
+ {
+ // modified streams with OLEStorages on it have autocommit; it is assumed that the OLEStorage
+ // was commited as well ( if not opened in direct mode )
+
+ if ( m_bModified )
+ {
+ try
+ {
+ CopySourceToTemporary();
+
+ // release all stream handles
+ Free();
+
+ // the temporary file does not exist only for truncated streams
+ DBG_ASSERT( m_aTempURL.Len() || ( m_nMode & STREAM_TRUNC ), "No temporary file to read from!");
+ if ( !m_aTempURL.Len() && !( m_nMode & STREAM_TRUNC ) )
+ throw RuntimeException();
+
+ // create wrapper to stream that is only used while reading inside package component
+ Reference < XInputStream > xStream = new FileStreamWrapper_Impl( m_aTempURL );
+
+ Any aAny;
+ InsertCommandArgument aArg;
+ aArg.Data = xStream;
+ aArg.ReplaceExisting = sal_True;
+ aAny <<= aArg;
+ m_pContent->executeCommand( ::rtl::OUString::createFromAscii("insert"), aAny );
+
+ // wrapper now controls lifetime of temporary file
+ m_aTempURL.Erase();
+
+ INetURLObject aObj( m_aURL );
+ aObj.SetName( m_aName );
+ m_aURL = aObj.GetMainURL( INetURLObject::NO_DECODE );
+ m_bModified = FALSE;
+ m_bSourceRead = TRUE;
+ }
+ catch ( CommandAbortedException& )
+ {
+ // any command wasn't executed successfully - not specified
+ SetError( ERRCODE_IO_GENERAL );
+ return COMMIT_RESULT_FAILURE;
+ }
+ catch ( RuntimeException& )
+ {
+ // any other error - not specified
+ SetError( ERRCODE_IO_GENERAL );
+ return COMMIT_RESULT_FAILURE;
+ }
+ catch ( Exception& )
+ {
+ // any other error - not specified
+ SetError( ERRCODE_IO_GENERAL );
+ return COMMIT_RESULT_FAILURE;
+ }
+
+ m_bCommited = FALSE;
+ return COMMIT_RESULT_SUCCESS;
+ }
+ }
+
+ return COMMIT_RESULT_NOTHING_TO_DO;
+}
+
+BOOL UCBStorageStream_Impl::Revert()
+{
+ // if an OLEStorage is created on this stream, no "revert" is neccessary because OLEStorages do nothing on "Revert" !
+ if ( m_bCommited )
+ {
+ DBG_ERROR("Revert while commit is in progress!" );
+ return FALSE; // ???
+ }
+
+ Free();
+ if ( m_aTempURL.Len() )
+ {
+ ::utl::UCBContentHelper::Kill( m_aTempURL );
+ m_aTempURL.Erase();
+ }
+
+ m_bSourceRead = FALSE;
+ try
+ {
+ m_rSource = m_pContent->openStream();
+ if( m_rSource.is() )
+ {
+ if ( m_pAntiImpl && ( m_nMode & STREAM_TRUNC ) )
+ // stream is in use and should be truncated
+ m_bSourceRead = FALSE;
+ else
+ {
+ m_nMode &= ~STREAM_TRUNC;
+ m_bSourceRead = TRUE;
+ }
+ }
+ else
+ SetError( SVSTREAM_CANNOT_MAKE );
+ }
+ catch ( ContentCreationException& )
+ {
+ SetError( ERRCODE_IO_GENERAL );
+ }
+ catch ( RuntimeException& )
+ {
+ SetError( ERRCODE_IO_GENERAL );
+ }
+ catch ( Exception& )
+ {
+ }
+
+ m_bModified = FALSE;
+ m_aName = m_aOriginalName;
+ m_aContentType = m_aOriginalContentType;
+ return ( GetError() == ERRCODE_NONE );
+}
+
+BOOL UCBStorageStream_Impl::Clear()
+{
+ BOOL bRet = ( m_pAntiImpl == NULL );
+ DBG_ASSERT( bRet, "Removing used stream!" );
+ if( bRet )
+ {
+ Free();
+ }
+
+ return bRet;
+}
+
+void UCBStorageStream_Impl::Free()
+{
+#if OSL_DEBUG_LEVEL > 1
+ if ( m_pStream )
+ {
+ if ( m_aTempURL.Len() )
+ --nOpenFiles;
+ else
+ --nOpenStreams;
+ }
+#endif
+
+ m_nRepresentMode = nonset;
+ m_rSource = Reference< XInputStream >();
+ DELETEZ( m_pStream );
+}
+
+void UCBStorageStream_Impl::PrepareCachedForReopen( StreamMode nMode )
+{
+ sal_Bool isWritable = (( m_nMode & STREAM_WRITE ) != 0 );
+ if ( isWritable )
+ {
+ // once stream was writable, never reset to readonly
+ nMode |= STREAM_WRITE;
+ }
+
+ m_nMode = nMode;
+ Free();
+
+ if ( nMode & STREAM_TRUNC )
+ {
+ m_bSourceRead = 0; // usually it should be 0 already but just in case...
+
+ if ( m_aTempURL.Len() )
+ {
+ ::utl::UCBContentHelper::Kill( m_aTempURL );
+ m_aTempURL.Erase();
+ }
+ }
+}
+
+UCBStorageStream::UCBStorageStream( const String& rName, StreamMode nMode, BOOL bDirect, const ByteString* pKey )
+{
+ // pImp must be initialized in the body, because otherwise the vtable of the stream is not initialized
+ // to class UCBStorageStream !
+ pImp = new UCBStorageStream_Impl( rName, nMode, this, bDirect, pKey );
+ pImp->AddRef(); // use direct refcounting because in header file only a pointer should be used
+ StorageBase::m_nMode = pImp->m_nMode;
+}
+
+UCBStorageStream::UCBStorageStream( const String& rName, StreamMode nMode, BOOL bDirect, const ByteString* pKey, BOOL bRepair, Reference< XProgressHandler > xProgress )
+{
+ // pImp must be initialized in the body, because otherwise the vtable of the stream is not initialized
+ // to class UCBStorageStream !
+ pImp = new UCBStorageStream_Impl( rName, nMode, this, bDirect, pKey, bRepair, xProgress );
+ pImp->AddRef(); // use direct refcounting because in header file only a pointer should be used
+ StorageBase::m_nMode = pImp->m_nMode;
+}
+
+UCBStorageStream::UCBStorageStream( UCBStorageStream_Impl *pImpl )
+ : pImp( pImpl )
+{
+ pImp->AddRef(); // use direct refcounting because in header file only a pointer should be used
+ pImp->m_pAntiImpl = this;
+ SetError( pImp->m_nError );
+ StorageBase::m_nMode = pImp->m_nMode;
+}
+
+UCBStorageStream::~UCBStorageStream()
+{
+ if ( pImp->m_nMode & STREAM_WRITE )
+ pImp->Flush();
+ pImp->m_pAntiImpl = NULL;
+ pImp->Free();
+ pImp->ReleaseRef();
+}
+
+ULONG UCBStorageStream::Read( void * pData, ULONG nSize )
+{
+ //return pImp->m_pStream->Read( pData, nSize );
+ return pImp->GetData( pData, nSize );
+}
+
+ULONG UCBStorageStream::Write( const void* pData, ULONG nSize )
+{
+/*
+ // mba: does occur in writer !
+ if ( pImp->m_bCommited )
+ {
+ DBG_ERROR("Writing while commit is in progress!" );
+ return 0;
+ }
+*/
+ // pImp->m_bModified = TRUE;
+ //return pImp->m_pStream->Write( pData, nSize );
+ return pImp->PutData( pData, nSize );
+}
+
+ULONG UCBStorageStream::Seek( ULONG nPos )
+{
+ //return pImp->m_pStream->Seek( nPos );
+ return pImp->Seek( nPos );
+}
+
+ULONG UCBStorageStream::Tell()
+{
+ if( !pImp->Init() )
+ return 0;
+ return pImp->m_pStream->Tell();
+}
+
+void UCBStorageStream::Flush()
+{
+ // streams are never really transacted, so flush also means commit !
+ Commit();
+}
+
+BOOL UCBStorageStream::SetSize( ULONG nNewSize )
+{
+/*
+ if ( pImp->m_bCommited )
+ {
+ DBG_ERROR("Changing stream size while commit is in progress!" );
+ return FALSE;
+ }
+*/
+ // pImp->m_bModified = TRUE;
+ //return pImp->m_pStream->SetStreamSize( nNewSize );
+ pImp->SetSize( nNewSize );
+ return !pImp->GetError();
+}
+
+BOOL UCBStorageStream::Validate( BOOL bWrite ) const
+{
+ return ( !bWrite || ( pImp->m_nMode & STREAM_WRITE ) );
+}
+
+BOOL UCBStorageStream::ValidateMode( StreamMode m ) const
+{
+ // ???
+ if( m == ( STREAM_READ | STREAM_TRUNC ) ) // from stg.cxx
+ return TRUE;
+ USHORT nCurMode = 0xFFFF;
+ if( ( m & 3 ) == STREAM_READ )
+ {
+ // only SHARE_DENYWRITE or SHARE_DENYALL allowed
+ if( ( ( m & STREAM_SHARE_DENYWRITE )
+ && ( nCurMode & STREAM_SHARE_DENYWRITE ) )
+ || ( ( m & STREAM_SHARE_DENYALL )
+ && ( nCurMode & STREAM_SHARE_DENYALL ) ) )
+ return TRUE;
+ }
+ else
+ {
+ // only SHARE_DENYALL allowed
+ // storages open in r/o mode are OK, since only
+ // the commit may fail
+ if( ( m & STREAM_SHARE_DENYALL )
+ && ( nCurMode & STREAM_SHARE_DENYALL ) )
+ return TRUE;
+ }
+
+ return TRUE;
+}
+
+const SvStream* UCBStorageStream::GetSvStream() const
+{
+ if( !pImp->Init() )
+ return NULL;
+
+ pImp->CopySourceToTemporary();
+ return pImp->m_pStream; // should not live longer then pImp!!!
+}
+
+SvStream* UCBStorageStream::GetModifySvStream()
+{
+ return (SvStream*)pImp;
+}
+
+Reference< XInputStream > UCBStorageStream::GetXInputStream() const
+{
+ return pImp->GetXInputStream();
+}
+
+BOOL UCBStorageStream::Equals( const BaseStorageStream& rStream ) const
+{
+ // ???
+ return ((BaseStorageStream*) this ) == &rStream;
+}
+
+BOOL UCBStorageStream::Commit()
+{
+ // mark this stream for sending it on root commit
+ pImp->FlushData();
+ return TRUE;
+}
+
+BOOL UCBStorageStream::Revert()
+{
+ return pImp->Revert();
+}
+
+BOOL UCBStorageStream::CopyTo( BaseStorageStream* pDestStm )
+{
+ if( !pImp->Init() )
+ return FALSE;
+
+ UCBStorageStream* pStg = PTR_CAST( UCBStorageStream, pDestStm );
+ if ( pStg )
+ pStg->pImp->m_aContentType = pImp->m_aContentType;
+
+ pDestStm->SetSize( 0 );
+ Seek( STREAM_SEEK_TO_END );
+ INT32 n = Tell();
+ if( n < 0 )
+ return FALSE;
+
+ if( pDestStm->SetSize( n ) && n )
+ {
+ BYTE* p = new BYTE[ 4096 ];
+ Seek( 0L );
+ pDestStm->Seek( 0L );
+ while( n )
+ {
+ UINT32 nn = n;
+ if( nn > 4096 )
+ nn = 4096;
+ if( Read( p, nn ) != nn )
+ break;
+ if( pDestStm->Write( p, nn ) != nn )
+ break;
+ n -= nn;
+ }
+
+ delete[] p;
+ }
+
+ return TRUE;
+}
+
+BOOL UCBStorageStream::SetProperty( const String& rName, const ::com::sun::star::uno::Any& rValue )
+{
+ if ( rName.CompareToAscii("Title") == COMPARE_EQUAL )
+ return FALSE;
+
+ if ( rName.CompareToAscii("MediaType") == COMPARE_EQUAL )
+ {
+ ::rtl::OUString aTmp;
+ rValue >>= aTmp;
+ pImp->m_aContentType = aTmp;
+ }
+
+ try
+ {
+ if ( pImp->m_pContent )
+ {
+ pImp->m_pContent->setPropertyValue( rName, rValue );
+ return TRUE;
+ }
+ }
+ catch ( Exception& )
+ {
+ }
+
+ return FALSE;
+}
+
+BOOL UCBStorageStream::GetProperty( const String& rName, ::com::sun::star::uno::Any& rValue )
+{
+ try
+ {
+ if ( pImp->m_pContent )
+ {
+ rValue = pImp->m_pContent->getPropertyValue( rName );
+ return TRUE;
+ }
+ }
+ catch ( Exception& )
+ {
+ }
+
+ return FALSE;
+}
+
+UCBStorage::UCBStorage( SvStream& rStrm, BOOL bDirect )
+{
+ String aURL = GetLinkedFile( rStrm );
+ if ( aURL.Len() )
+ {
+ StreamMode nMode = STREAM_READ;
+ if( rStrm.IsWritable() )
+ nMode = STREAM_READ | STREAM_WRITE;
+
+ ::ucbhelper::Content aContent( aURL, Reference < XCommandEnvironment >() );
+ pImp = new UCBStorage_Impl( aContent, aURL, nMode, this, bDirect, TRUE );
+ }
+ else
+ {
+ // pImp must be initialized in the body, because otherwise the vtable of the stream is not initialized
+ // to class UCBStorage !
+ pImp = new UCBStorage_Impl( rStrm, this, bDirect );
+ }
+
+ pImp->AddRef();
+ pImp->Init();
+ StorageBase::m_nMode = pImp->m_nMode;
+}
+
+UCBStorage::UCBStorage( const ::ucbhelper::Content& rContent, const String& rName, StreamMode nMode, BOOL bDirect, BOOL bIsRoot )
+{
+ // pImp must be initialized in the body, because otherwise the vtable of the stream is not initialized
+ // to class UCBStorage !
+ pImp = new UCBStorage_Impl( rContent, rName, nMode, this, bDirect, bIsRoot );
+ pImp->AddRef();
+ pImp->Init();
+ StorageBase::m_nMode = pImp->m_nMode;
+}
+
+UCBStorage::UCBStorage( const String& rName, StreamMode nMode, BOOL bDirect, BOOL bIsRoot, BOOL bIsRepair, Reference< XProgressHandler > xProgressHandler )
+{
+ // pImp must be initialized in the body, because otherwise the vtable of the stream is not initialized
+ // to class UCBStorage !
+ pImp = new UCBStorage_Impl( rName, nMode, this, bDirect, bIsRoot, bIsRepair, xProgressHandler );
+ pImp->AddRef();
+ pImp->Init();
+ StorageBase::m_nMode = pImp->m_nMode;
+}
+
+UCBStorage::UCBStorage( const String& rName, StreamMode nMode, BOOL bDirect, BOOL bIsRoot )
+{
+ // pImp must be initialized in the body, because otherwise the vtable of the stream is not initialized
+ // to class UCBStorage !
+ pImp = new UCBStorage_Impl( rName, nMode, this, bDirect, bIsRoot, sal_False, Reference< XProgressHandler >() );
+ pImp->AddRef();
+ pImp->Init();
+ StorageBase::m_nMode = pImp->m_nMode;
+}
+
+UCBStorage::UCBStorage( UCBStorage_Impl *pImpl )
+ : pImp( pImpl )
+{
+ pImp->m_pAntiImpl = this;
+ SetError( pImp->m_nError );
+ pImp->AddRef(); // use direct refcounting because in header file only a pointer should be used
+ StorageBase::m_nMode = pImp->m_nMode;
+}
+
+UCBStorage::~UCBStorage()
+{
+ if ( pImp->m_bIsRoot && pImp->m_bDirect && ( !pImp->m_pTempFile || pImp->m_pSource ) )
+ // DirectMode is simulated with an AutoCommit
+ Commit();
+
+ pImp->m_pAntiImpl = NULL;
+ pImp->ReleaseRef();
+}
+
+UCBStorage_Impl::UCBStorage_Impl( const ::ucbhelper::Content& rContent, const String& rName, StreamMode nMode, UCBStorage* pStorage, BOOL bDirect, BOOL bIsRoot, BOOL bIsRepair, Reference< XProgressHandler > xProgressHandler )
+ : m_pAntiImpl( pStorage )
+ , m_pContent( new ::ucbhelper::Content( rContent ) )
+ , m_pTempFile( NULL )
+ , m_pSource( NULL )
+ //, m_pStream( NULL )
+ , m_nError( 0 )
+ , m_nMode( nMode )
+ , m_bModified( FALSE )
+ , m_bCommited( FALSE )
+ , m_bDirect( bDirect )
+ , m_bIsRoot( bIsRoot )
+ , m_bDirty( FALSE )
+ , m_bIsLinked( TRUE )
+ , m_bListCreated( FALSE )
+ , m_nFormat( 0 )
+ , m_aClassId( SvGlobalName() )
+ , m_bRepairPackage( bIsRepair )
+ , m_xProgressHandler( xProgressHandler )
+ , m_pUNOStorageHolderList( NULL )
+
+{
+ String aName( rName );
+ if( !aName.Len() )
+ {
+ // no name given = use temporary name!
+ DBG_ASSERT( m_bIsRoot, "SubStorage must have a name!" );
+ m_pTempFile = new ::utl::TempFile;
+ m_pTempFile->EnableKillingFile( TRUE );
+ m_aName = m_aOriginalName = aName = m_pTempFile->GetURL();
+ }
+
+ m_aURL = rName;
+}
+
+UCBStorage_Impl::UCBStorage_Impl( const String& rName, StreamMode nMode, UCBStorage* pStorage, BOOL bDirect, BOOL bIsRoot, BOOL bIsRepair, Reference< XProgressHandler > xProgressHandler )
+ : m_pAntiImpl( pStorage )
+ , m_pContent( NULL )
+ , m_pTempFile( NULL )
+ , m_pSource( NULL )
+ //, m_pStream( NULL )
+ , m_nError( 0 )
+ , m_nMode( nMode )
+ , m_bModified( FALSE )
+ , m_bCommited( FALSE )
+ , m_bDirect( bDirect )
+ , m_bIsRoot( bIsRoot )
+ , m_bDirty( FALSE )
+ , m_bIsLinked( FALSE )
+ , m_bListCreated( FALSE )
+ , m_nFormat( 0 )
+ , m_aClassId( SvGlobalName() )
+ , m_bRepairPackage( bIsRepair )
+ , m_xProgressHandler( xProgressHandler )
+ , m_pUNOStorageHolderList( NULL )
+{
+ String aName( rName );
+ if( !aName.Len() )
+ {
+ // no name given = use temporary name!
+ DBG_ASSERT( m_bIsRoot, "SubStorage must have a name!" );
+ m_pTempFile = new ::utl::TempFile;
+ m_pTempFile->EnableKillingFile( TRUE );
+ m_aName = m_aOriginalName = aName = m_pTempFile->GetURL();
+ }
+
+ if ( m_bIsRoot )
+ {
+ // create the special package URL for the package content
+ String aTemp = String::CreateFromAscii("vnd.sun.star.pkg://");
+ aTemp += String(INetURLObject::encode( aName, INetURLObject::PART_AUTHORITY, '%', INetURLObject::ENCODE_ALL ));
+ m_aURL = aTemp;
+
+ if ( m_nMode & STREAM_WRITE )
+ {
+ // the root storage opens the package, so make sure that there is any
+ SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( aName, STREAM_STD_READWRITE, m_pTempFile != 0 /* bFileExists */ );
+ delete pStream;
+ }
+ }
+ else
+ {
+ // substorages are opened like streams: the URL is a "child URL" of the root package URL
+ m_aURL = rName;
+ if ( m_aURL.CompareToAscii( "vnd.sun.star.pkg://", 19 ) != 0 )
+ m_bIsLinked = TRUE;
+ }
+}
+
+UCBStorage_Impl::UCBStorage_Impl( SvStream& rStream, UCBStorage* pStorage, BOOL bDirect )
+ : m_pAntiImpl( pStorage )
+ , m_pContent( NULL )
+ , m_pTempFile( new ::utl::TempFile )
+ , m_pSource( &rStream )
+ , m_nError( 0 )
+ , m_bModified( FALSE )
+ , m_bCommited( FALSE )
+ , m_bDirect( bDirect )
+ , m_bIsRoot( TRUE )
+ , m_bDirty( FALSE )
+ , m_bIsLinked( FALSE )
+ , m_bListCreated( FALSE )
+ , m_nFormat( 0 )
+ , m_aClassId( SvGlobalName() )
+ , m_bRepairPackage( FALSE )
+ , m_pUNOStorageHolderList( NULL )
+{
+ // opening in direct mode is too fuzzy because the data is transferred to the stream in the Commit() call,
+ // which will be called in the storages' dtor
+ m_pTempFile->EnableKillingFile( TRUE );
+ DBG_ASSERT( !bDirect, "Storage on a stream must not be opened in direct mode!" );
+
+ // UCBStorages work on a content, so a temporary file for a content must be created, even if the stream is only
+ // accessed readonly
+ // the root storage opens the package; create the special package URL for the package content
+ String aTemp = String::CreateFromAscii("vnd.sun.star.pkg://");
+ aTemp += String(INetURLObject::encode( m_pTempFile->GetURL(), INetURLObject::PART_AUTHORITY, '%', INetURLObject::ENCODE_ALL ));
+ m_aURL = aTemp;
+
+ // copy data into the temporary file
+ SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( m_pTempFile->GetURL(), STREAM_STD_READWRITE, sal_True /* bFileExists */ );
+ if ( pStream )
+ {
+ rStream.Seek(0);
+ rStream >> *pStream;
+ pStream->Flush();
+ DELETEZ( pStream );
+ }
+
+ // close stream and let content access the file
+ m_pSource->Seek(0);
+
+ // check opening mode
+ m_nMode = STREAM_READ;
+ if( rStream.IsWritable() )
+ m_nMode = STREAM_READ | STREAM_WRITE;
+}
+
+void UCBStorage_Impl::Init()
+{
+ // name is last segment in URL
+ INetURLObject aObj( m_aURL );
+ if ( !m_aName.Len() )
+ // if the name was not already set to a temp name
+ m_aName = m_aOriginalName = aObj.GetLastName();
+
+ // don't create the content for disk spanned files, avoid too early access to directory and/or manifest
+ if ( !m_pContent && !( m_nMode & STORAGE_DISKSPANNED_MODE ) )
+ CreateContent();
+
+ if ( m_nMode & STORAGE_DISKSPANNED_MODE )
+ {
+ // Hack! Avoid access to the manifest file until mediatype is not available in the first segment of a
+ // disk spanned file
+ m_aContentType = m_aOriginalContentType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("application/vnd.sun.xml.impress") );
+ }
+ else if ( m_pContent )
+ {
+ if ( m_bIsLinked )
+ {
+ if( m_bIsRoot )
+ {
+ ReadContent();
+ if ( m_nError == ERRCODE_NONE )
+ {
+ // read the manifest.xml file
+ aObj.Append( String( RTL_CONSTASCII_USTRINGPARAM("META-INF") ) );
+ aObj.Append( String( RTL_CONSTASCII_USTRINGPARAM("manifest.xml") ) );
+
+ // create input stream
+ SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( aObj.GetMainURL( INetURLObject::NO_DECODE ), STREAM_STD_READ );
+ // no stream means no manifest.xml
+ if ( pStream )
+ {
+ if ( !pStream->GetError() )
+ {
+ ::utl::OInputStreamWrapper* pHelper = new ::utl::OInputStreamWrapper( *pStream );
+ com::sun::star::uno::Reference < ::com::sun::star::io::XInputStream > xInputStream( pHelper );
+
+ // create a manifest reader object that will read in the manifest from the stream
+ Reference < ::com::sun::star::packages::manifest::XManifestReader > xReader =
+ Reference< ::com::sun::star::packages::manifest::XManifestReader >
+ ( ::comphelper::getProcessServiceFactory()->createInstance(
+ ::rtl::OUString::createFromAscii( "com.sun.star.packages.manifest.ManifestReader" )), UNO_QUERY) ;
+ Sequence < Sequence < PropertyValue > > aProps = xReader->readManifestSequence( xInputStream );
+
+ // cleanup
+ xReader = NULL;
+ xInputStream = NULL;
+ SetProps( aProps, String() );
+ }
+
+ delete pStream;
+ }
+ }
+ }
+ else
+ ReadContent();
+ }
+ else
+ {
+ // get the manifest information from the package
+ try {
+ Any aAny = m_pContent->getPropertyValue( ::rtl::OUString::createFromAscii( "MediaType" ) );
+ rtl::OUString aTmp;
+ if ( ( aAny >>= aTmp ) && aTmp.getLength() )
+ m_aContentType = m_aOriginalContentType = aTmp;
+ }
+ catch( Exception& )
+ {
+ DBG_ASSERT( sal_False,
+ "getPropertyValue has thrown an exception! Please let developers know the scenario!" );
+ }
+ }
+ }
+
+ if ( m_aContentType.Len() )
+ {
+ // get the clipboard format using the content type
+ ::com::sun::star::datatransfer::DataFlavor aDataFlavor;
+ aDataFlavor.MimeType = m_aContentType;
+ m_nFormat = SotExchange::GetFormat( aDataFlavor );
+
+ // get the ClassId using the clipboard format ( internal table )
+ m_aClassId = GetClassId_Impl( m_nFormat );
+
+ // get human presentable name using the clipboard format
+ SotExchange::GetFormatDataFlavor( m_nFormat, aDataFlavor );
+ m_aUserTypeName = aDataFlavor.HumanPresentableName;
+
+ if( m_pContent && !m_bIsLinked && m_aClassId != SvGlobalName() )
+ ReadContent();
+ }
+}
+
+void UCBStorage_Impl::CreateContent()
+{
+ try
+ {
+ // create content; where to put StreamMode ?! ( already done when opening the file of the package ? )
+ Reference< ::com::sun::star::ucb::XCommandEnvironment > xComEnv;
+
+ ::rtl::OUString aTemp( m_aURL );
+
+ if ( m_bRepairPackage )
+ {
+ xComEnv = new ::ucbhelper::CommandEnvironment( Reference< ::com::sun::star::task::XInteractionHandler >(),
+ m_xProgressHandler );
+ aTemp += rtl::OUString::createFromAscii("?repairpackage");
+ }
+
+ m_pContent = new ::ucbhelper::Content( aTemp, xComEnv );
+ }
+ catch ( ContentCreationException& )
+ {
+ // content could not be created
+ SetError( SVSTREAM_CANNOT_MAKE );
+ }
+ catch ( RuntimeException& )
+ {
+ // any other error - not specified
+ SetError( SVSTREAM_CANNOT_MAKE );
+ }
+}
+
+void UCBStorage_Impl::ReadContent()
+{
+ if ( m_bListCreated )
+ return;
+
+ m_bListCreated = TRUE;
+
+ // create cursor for access to children
+ Sequence< ::rtl::OUString > aProps(4);
+ ::rtl::OUString* pProps = aProps.getArray();
+ pProps[0] = ::rtl::OUString::createFromAscii( "Title" );
+ pProps[1] = ::rtl::OUString::createFromAscii( "IsFolder" );
+ pProps[2] = ::rtl::OUString::createFromAscii( "MediaType" );
+ pProps[3] = ::rtl::OUString::createFromAscii( "Size" );
+ ::ucbhelper::ResultSetInclude eInclude = ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS;
+
+ try
+ {
+ GetContent();
+ if ( !m_pContent )
+ return;
+
+ Reference< XResultSet > xResultSet = m_pContent->createCursor( aProps, eInclude );
+ Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
+ Reference< XRow > xRow( xResultSet, UNO_QUERY );
+ if ( xResultSet.is() )
+ {
+ while ( xResultSet->next() )
+ {
+ // insert all into the children list
+ ::rtl::OUString aTitle( xRow->getString(1) );
+ ::rtl::OUString aContentType;
+ if ( m_bIsLinked )
+ {
+ // unpacked storages have to deal with the meta-inf folder by themselves
+ if( aTitle.equalsAscii("META-INF") )
+ continue;
+ }
+ else
+ {
+ aContentType = xRow->getString(3);
+ }
+
+ BOOL bIsFolder( xRow->getBoolean(2) );
+ sal_Int64 nSize = xRow->getLong(4);
+ UCBStorageElement_Impl* pElement = new UCBStorageElement_Impl( aTitle, bIsFolder, (ULONG) nSize );
+ m_aChildrenList.Insert( pElement, LIST_APPEND );
+
+ sal_Bool bIsOfficeDocument = m_bIsLinked || ( m_aClassId != SvGlobalName() );
+ if ( bIsFolder )
+ {
+ if ( m_bIsLinked )
+ OpenStorage( pElement, m_nMode, m_bDirect );
+ if ( pElement->m_xStorage.Is() )
+ pElement->m_xStorage->Init();
+ }
+ else if ( bIsOfficeDocument )
+ {
+ // streams can be external OLE objects, so they are now folders, but storages!
+ String aName( m_aURL );
+ aName += '/';
+ aName += String( xRow->getString(1) );
+
+ Reference< ::com::sun::star::ucb::XCommandEnvironment > xComEnv;
+ if ( m_bRepairPackage )
+ {
+ xComEnv = new ::ucbhelper::CommandEnvironment( Reference< ::com::sun::star::task::XInteractionHandler >(),
+ m_xProgressHandler );
+ aName += String( RTL_CONSTASCII_USTRINGPARAM( "?repairpackage" ) );
+ }
+
+ ::ucbhelper::Content aContent( aName, xComEnv );
+
+ ::rtl::OUString aMediaType;
+ Any aAny = aContent.getPropertyValue( ::rtl::OUString::createFromAscii( "MediaType" ) );
+ if ( ( aAny >>= aMediaType ) && ( aMediaType.compareToAscii("application/vnd.sun.star.oleobject") == 0 ) )
+ pElement->m_bIsStorage = TRUE;
+ else if ( !aMediaType.getLength() )
+ {
+ // older files didn't have that special content type, so they must be detected
+ OpenStream( pElement, STREAM_STD_READ, m_bDirect );
+ if ( Storage::IsStorageFile( pElement->m_xStream ) )
+ pElement->m_bIsStorage = TRUE;
+ else
+ pElement->m_xStream->Free();
+ }
+ }
+ }
+ }
+ }
+ catch ( InteractiveIOException& r )
+ {
+ if ( r.Code != IOErrorCode_NOT_EXISTING )
+ SetError( ERRCODE_IO_GENERAL );
+ }
+ catch ( CommandAbortedException& )
+ {
+ // any command wasn't executed successfully - not specified
+ if ( !( m_nMode & STREAM_WRITE ) )
+ // if the folder was just inserted and not already commited, this is not an error!
+ SetError( ERRCODE_IO_GENERAL );
+ }
+ catch ( RuntimeException& )
+ {
+ // any other error - not specified
+ SetError( ERRCODE_IO_GENERAL );
+ }
+ catch ( ResultSetException& )
+ {
+ // means that the package file is broken
+ SetError( ERRCODE_IO_BROKENPACKAGE );
+ }
+ catch ( SQLException& )
+ {
+ // means that the file can be broken
+ SetError( ERRCODE_IO_WRONGFORMAT );
+ }
+ catch ( Exception& )
+ {
+ // any other error - not specified
+ SetError( ERRCODE_IO_GENERAL );
+ }
+}
+
+void UCBStorage_Impl::SetError( long nError )
+{
+ if ( !m_nError )
+ {
+ m_nError = nError;
+ if ( m_pAntiImpl ) m_pAntiImpl->SetError( nError );
+ }
+}
+
+sal_Int32 UCBStorage_Impl::GetObjectCount()
+{
+ sal_Int32 nCount = m_aChildrenList.Count();
+ UCBStorageElement_Impl* pElement = m_aChildrenList.First();
+ while ( pElement )
+ {
+ DBG_ASSERT( !pElement->m_bIsFolder || pElement->m_xStorage.Is(), "Storage should be open!" );
+ if ( pElement->m_bIsFolder && pElement->m_xStorage.Is() )
+ nCount += pElement->m_xStorage->GetObjectCount();
+ pElement = m_aChildrenList.Next();
+ }
+
+ return nCount;
+}
+
+::rtl::OUString Find_Impl( const Sequence < Sequence < PropertyValue > >& rSequence, const ::rtl::OUString& rPath )
+{
+ BOOL bFound = FALSE;
+ for ( sal_Int32 nSeqs=0; nSeqs<rSequence.getLength(); nSeqs++ )
+ {
+ const Sequence < PropertyValue >& rMyProps = rSequence[nSeqs];
+ ::rtl::OUString aType;
+
+ for ( sal_Int32 nProps=0; nProps<rMyProps.getLength(); nProps++ )
+ {
+ const PropertyValue& rAny = rMyProps[nProps];
+ if ( rAny.Name.equalsAscii("FullPath") )
+ {
+ rtl::OUString aTmp;
+ if ( ( rAny.Value >>= aTmp ) && aTmp == rPath )
+ bFound = TRUE;
+ if ( aType.getLength() )
+ break;
+ }
+ else if ( rAny.Name.equalsAscii("MediaType") )
+ {
+ if ( ( rAny.Value >>= aType ) && aType.getLength() && bFound )
+ break;
+ }
+ }
+
+ if ( bFound )
+ return aType;
+ }
+
+ return ::rtl::OUString();
+}
+
+void UCBStorage_Impl::SetProps( const Sequence < Sequence < PropertyValue > >& rSequence, const String& rPath )
+{
+ String aPath( rPath );
+ if ( !m_bIsRoot )
+ aPath += m_aName;
+ aPath += '/';
+
+ m_aContentType = m_aOriginalContentType = Find_Impl( rSequence, aPath );
+
+ if ( m_bIsRoot )
+ // the "FullPath" of a child always starts without '/'
+ aPath.Erase();
+
+ UCBStorageElement_Impl* pElement = m_aChildrenList.First();
+ while ( pElement )
+ {
+ DBG_ASSERT( !pElement->m_bIsFolder || pElement->m_xStorage.Is(), "Storage should be open!" );
+ if ( pElement->m_bIsFolder && pElement->m_xStorage.Is() )
+ pElement->m_xStorage->SetProps( rSequence, aPath );
+ else
+ {
+ String aElementPath( aPath );
+ aElementPath += pElement->m_aName;
+ pElement->SetContentType( Find_Impl( rSequence, aElementPath ) );
+ }
+
+ pElement = m_aChildrenList.Next();
+ }
+
+ if ( m_aContentType.Len() )
+ {
+ // get the clipboard format using the content type
+ ::com::sun::star::datatransfer::DataFlavor aDataFlavor;
+ aDataFlavor.MimeType = m_aContentType;
+ m_nFormat = SotExchange::GetFormat( aDataFlavor );
+
+ // get the ClassId using the clipboard format ( internal table )
+ m_aClassId = GetClassId_Impl( m_nFormat );
+
+ // get human presentable name using the clipboard format
+ SotExchange::GetFormatDataFlavor( m_nFormat, aDataFlavor );
+ m_aUserTypeName = aDataFlavor.HumanPresentableName;
+ }
+}
+
+void UCBStorage_Impl::GetProps( sal_Int32& nProps, Sequence < Sequence < PropertyValue > >& rSequence, const String& rPath )
+{
+ // first my own properties
+ Sequence < PropertyValue > aProps(2);
+
+ // first property is the "FullPath" name
+ // it's '/' for the root storage and m_aName for each element, followed by a '/' if it's a folder
+ String aPath( rPath );
+ if ( !m_bIsRoot )
+ aPath += m_aName;
+ aPath += '/';
+ aProps[0].Name = ::rtl::OUString::createFromAscii("MediaType");
+ aProps[0].Value <<= (::rtl::OUString ) m_aContentType;
+ aProps[1].Name = ::rtl::OUString::createFromAscii("FullPath");
+ aProps[1].Value <<= (::rtl::OUString ) aPath;
+ rSequence[ nProps++ ] = aProps;
+
+ if ( m_bIsRoot )
+ // the "FullPath" of a child always starts without '/'
+ aPath.Erase();
+
+ // now the properties of my elements
+ UCBStorageElement_Impl* pElement = m_aChildrenList.First();
+ while ( pElement )
+ {
+ DBG_ASSERT( !pElement->m_bIsFolder || pElement->m_xStorage.Is(), "Storage should be open!" );
+ if ( pElement->m_bIsFolder && pElement->m_xStorage.Is() )
+ // storages add there properties by themselves ( see above )
+ pElement->m_xStorage->GetProps( nProps, rSequence, aPath );
+ else
+ {
+ // properties of streams
+ String aElementPath( aPath );
+ aElementPath += pElement->m_aName;
+ aProps[0].Name = ::rtl::OUString::createFromAscii("MediaType");
+ aProps[0].Value <<= (::rtl::OUString ) pElement->GetContentType();
+ aProps[1].Name = ::rtl::OUString::createFromAscii("FullPath");
+ aProps[1].Value <<= (::rtl::OUString ) aElementPath;
+ rSequence[ nProps++ ] = aProps;
+ }
+
+ pElement = m_aChildrenList.Next();
+ }
+}
+
+UCBStorage_Impl::~UCBStorage_Impl()
+{
+ if ( m_pUNOStorageHolderList )
+ {
+ for ( UNOStorageHolderList::iterator aIter = m_pUNOStorageHolderList->begin();
+ aIter != m_pUNOStorageHolderList->end(); aIter++ )
+ if ( *aIter )
+ {
+ (*aIter)->InternalDispose();
+ (*aIter)->release();
+ (*aIter) = NULL;
+ }
+
+ m_pUNOStorageHolderList->clear();
+ DELETEZ( m_pUNOStorageHolderList );
+ }
+
+ // first delete elements!
+ UCBStorageElement_Impl* pElement = m_aChildrenList.First();
+ while ( pElement )
+ {
+ delete pElement;
+ pElement = m_aChildrenList.Next();
+ }
+
+ m_aChildrenList.Clear();
+ delete m_pContent;
+ delete m_pTempFile;
+}
+
+BOOL UCBStorage_Impl::Insert( ::ucbhelper::Content *pContent )
+{
+ // a new substorage is inserted into a UCBStorage ( given by the parameter pContent )
+ // it must be inserted with a title and a type
+ BOOL bRet = FALSE;
+
+ try
+ {
+ Sequence< ContentInfo > aInfo = pContent->queryCreatableContentsInfo();
+ sal_Int32 nCount = aInfo.getLength();
+ if ( nCount == 0 )
+ return sal_False;
+
+ for ( sal_Int32 i = 0; i < nCount; ++i )
+ {
+ // Simply look for the first KIND_FOLDER...
+ const ContentInfo & rCurr = aInfo[i];
+ if ( rCurr.Attributes & ContentInfoAttribute::KIND_FOLDER )
+ {
+ // Make sure the only required bootstrap property is "Title",
+ const Sequence< Property > & rProps = rCurr.Properties;
+ if ( rProps.getLength() != 1 )
+ continue;
+
+ if ( !rProps[ 0 ].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Title" ) ) )
+ continue;
+
+ Sequence < ::rtl::OUString > aNames(1);
+ ::rtl::OUString* pNames = aNames.getArray();
+ pNames[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) );
+ Sequence < Any > aValues(1);
+ Any* pValues = aValues.getArray();
+ pValues[0] = makeAny( ::rtl::OUString( m_aName ) );
+
+ Content aNewFolder;
+ if ( !pContent->insertNewContent( rCurr.Type, aNames, aValues, aNewFolder ) )
+ continue;
+
+ // remove old content, create an "empty" new one and initialize it with the new inserted
+ DELETEZ( m_pContent );
+ m_pContent = new ::ucbhelper::Content( aNewFolder );
+ bRet = TRUE;
+ }
+ }
+ }
+ catch ( CommandAbortedException& )
+ {
+ // any command wasn't executed successfully - not specified
+ SetError( ERRCODE_IO_GENERAL );
+ }
+ catch ( RuntimeException& )
+ {
+ // any other error - not specified
+ SetError( ERRCODE_IO_GENERAL );
+ }
+ catch ( Exception& )
+ {
+ // any other error - not specified
+ SetError( ERRCODE_IO_GENERAL );
+ }
+
+ return bRet;
+}
+
+sal_Int16 UCBStorage_Impl::Commit()
+{
+ // send all changes to the package
+ UCBStorageElement_Impl* pElement = m_aChildrenList.First();
+ sal_Int16 nRet = COMMIT_RESULT_NOTHING_TO_DO;
+
+ // there is nothing to do if the storage has been opened readonly or if it was opened in transacted mode and no
+ // commit command has been sent
+ if ( ( m_nMode & STREAM_WRITE ) && ( m_bCommited || m_bDirect ) )
+ {
+ try
+ {
+ // all errors will be caught in the "catch" statement outside the loop
+ while ( pElement && nRet )
+ {
+ ::ucbhelper::Content* pContent = pElement->GetContent();
+ BOOL bDeleteContent = FALSE;
+ if ( !pContent && pElement->IsModified() )
+ {
+ // if the element has never been opened, no content has been created until now
+ bDeleteContent = TRUE; // remember to delete it later
+ String aName( m_aURL );
+ aName += '/';
+ aName += pElement->m_aOriginalName;
+ pContent = new ::ucbhelper::Content( aName, Reference< ::com::sun::star::ucb::XCommandEnvironment > () );
+ }
+
+ if ( pElement->m_bIsRemoved )
+ {
+ // was it inserted, then removed (so there would be nothing to do!)
+ if ( !pElement->m_bIsInserted )
+ {
+ // first remove all open stream handles
+ if( !pElement->m_xStream.Is() || pElement->m_xStream->Clear() )
+ {
+ pContent->executeCommand( ::rtl::OUString::createFromAscii("delete"), makeAny( sal_Bool( sal_True ) ) );
+ nRet = COMMIT_RESULT_SUCCESS;
+ }
+ else
+ // couldn't release stream because there are external references to it
+ nRet = COMMIT_RESULT_FAILURE;
+ }
+ }
+ else
+ {
+ sal_Int16 nLocalRet = COMMIT_RESULT_NOTHING_TO_DO;
+ if ( pElement->m_xStorage.Is() )
+ {
+ // element is a storage
+ // do a commit in the following cases:
+ // - if storage is already inserted, and changed
+ // - storage is not in a package
+ // - it's a new storage, try to insert and commit if successful inserted
+ if ( !pElement->m_bIsInserted || m_bIsLinked || pElement->m_xStorage->Insert( m_pContent ) )
+ {
+ nLocalRet = pElement->m_xStorage->Commit();
+ pContent = pElement->GetContent();
+ }
+ }
+ else if ( pElement->m_xStream.Is() )
+ {
+ // element is a stream
+ nLocalRet = pElement->m_xStream->Commit();
+ if ( pElement->m_xStream->m_bIsOLEStorage )
+ {
+ // OLE storage should be stored encrytped, if the storage uses encryption
+ pElement->m_xStream->m_aContentType = String::CreateFromAscii("application/vnd.sun.star.oleobject");
+ Any aValue;
+ aValue <<= (BOOL) TRUE;
+ pElement->m_xStream->m_pContent->setPropertyValue(String::CreateFromAscii("Encrypted"), aValue );
+ }
+
+ pContent = pElement->GetContent();
+ }
+
+ if ( pElement->m_aName != pElement->m_aOriginalName )
+ {
+ // name ( title ) of the element was changed
+ nLocalRet = COMMIT_RESULT_SUCCESS;
+ Any aAny;
+ aAny <<= (rtl::OUString) pElement->m_aName;
+ pContent->setPropertyValue( ::rtl::OUString::createFromAscii("Title"), aAny );
+ }
+
+ if ( pElement->IsLoaded() && pElement->GetContentType() != pElement->GetOriginalContentType() )
+ {
+ // mediatype of the element was changed
+ nLocalRet = COMMIT_RESULT_SUCCESS;
+ Any aAny;
+ aAny <<= (rtl::OUString) pElement->GetContentType();
+ pContent->setPropertyValue( ::rtl::OUString::createFromAscii("MediaType"), aAny );
+ }
+
+ if ( nLocalRet != COMMIT_RESULT_NOTHING_TO_DO )
+ nRet = nLocalRet;
+ }
+
+ if ( bDeleteContent )
+ // content was created inside the loop
+ delete pContent;
+
+ if ( nRet == COMMIT_RESULT_FAILURE )
+ break;
+
+ pElement = m_aChildrenList.Next();
+ }
+ }
+ catch ( ContentCreationException& )
+ {
+ // content could not be created
+ SetError( ERRCODE_IO_NOTEXISTS );
+ return COMMIT_RESULT_FAILURE;
+ }
+ catch ( CommandAbortedException& )
+ {
+ // any command wasn't executed successfully - not specified
+ SetError( ERRCODE_IO_GENERAL );
+ return COMMIT_RESULT_FAILURE;
+ }
+ catch ( RuntimeException& )
+ {
+ // any other error - not specified
+ SetError( ERRCODE_IO_GENERAL );
+ return COMMIT_RESULT_FAILURE;
+ }
+ catch ( Exception& )
+ {
+ // any other error - not specified
+ SetError( ERRCODE_IO_GENERAL );
+ return COMMIT_RESULT_FAILURE;
+ }
+
+ if ( m_bIsRoot && m_pContent )
+ {
+ // the root storage must flush the root package content
+ if ( nRet == COMMIT_RESULT_SUCCESS )
+ {
+ try
+ {
+ // commit the media type to the JAR file
+ // clipboard format and ClassId will be retrieved from the media type when the file is loaded again
+ Any aType;
+ aType <<= (rtl::OUString) m_aContentType;
+ m_pContent->setPropertyValue( ::rtl::OUString::createFromAscii( "MediaType" ), aType );
+
+ if ( m_bIsLinked )
+ {
+ // write a manifest file
+ // first create a subfolder "META-inf"
+ Content aNewSubFolder;
+ BOOL bRet = ::utl::UCBContentHelper::MakeFolder( *m_pContent, String::CreateFromAscii("META-INF"), aNewSubFolder );
+ if ( bRet )
+ {
+ // create a stream to write the manifest file - use a temp file
+ String aURL( aNewSubFolder.getURL() );
+ ::utl::TempFile* pTempFile = new ::utl::TempFile( &aURL );
+
+ // get the stream from the temp file and create an output stream wrapper
+ SvStream* pStream = pTempFile->GetStream( STREAM_STD_READWRITE );
+ ::utl::OOutputStreamWrapper* pHelper = new ::utl::OOutputStreamWrapper( *pStream );
+ com::sun::star::uno::Reference < ::com::sun::star::io::XOutputStream > xOutputStream( pHelper );
+
+ // create a manifest writer object that will fill the stream
+ Reference < ::com::sun::star::packages::manifest::XManifestWriter > xWriter =
+ Reference< ::com::sun::star::packages::manifest::XManifestWriter >
+ ( ::comphelper::getProcessServiceFactory()->createInstance(
+ ::rtl::OUString::createFromAscii( "com.sun.star.packages.manifest.ManifestWriter" )), UNO_QUERY) ;
+ sal_Int32 nCount = GetObjectCount() + 1;
+ Sequence < Sequence < PropertyValue > > aProps( nCount );
+ sal_Int32 nProps = 0;
+ GetProps( nProps, aProps, String() );
+ xWriter->writeManifestSequence( xOutputStream, aProps );
+
+ // move the stream to its desired location
+ Content aSource( pTempFile->GetURL(), Reference < XCommandEnvironment >() );
+ xWriter = NULL;
+ xOutputStream = NULL;
+ DELETEZ( pTempFile );
+ aNewSubFolder.transferContent( aSource, InsertOperation_MOVE, ::rtl::OUString::createFromAscii("manifest.xml"), NameClash::OVERWRITE );
+ }
+ }
+ else
+ {
+#if OSL_DEBUG_LEVEL > 1
+ fprintf ( stderr, "Files: %i\n", nOpenFiles );
+ fprintf ( stderr, "Streams: %i\n", nOpenStreams );
+#endif
+ // force writing
+ Any aAny;
+ m_pContent->executeCommand( ::rtl::OUString::createFromAscii("flush"), aAny );
+ if ( m_pSource != 0 )
+ {
+ SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( m_pTempFile->GetURL(), STREAM_STD_READ );
+ m_pSource->SetStreamSize(0);
+ // m_pSource->Seek(0);
+ *pStream >> *m_pSource;
+ DELETEZ( pStream );
+ m_pSource->Seek(0);
+ }
+ }
+ }
+ catch ( CommandAbortedException& )
+ {
+ // how to tell the content : forget all changes ?!
+ // or should we assume that the content does it by itself because he throwed an exception ?!
+ // any command wasn't executed successfully - not specified
+ SetError( ERRCODE_IO_GENERAL );
+ return COMMIT_RESULT_FAILURE;
+ }
+ catch ( RuntimeException& )
+ {
+ // how to tell the content : forget all changes ?!
+ // or should we assume that the content does it by itself because he throwed an exception ?!
+ // any other error - not specified
+ SetError( ERRCODE_IO_GENERAL );
+ return COMMIT_RESULT_FAILURE;
+ }
+ catch ( InteractiveIOException& r )
+ {
+ if ( r.Code == IOErrorCode_ACCESS_DENIED || r.Code == IOErrorCode_LOCKING_VIOLATION )
+ SetError( ERRCODE_IO_ACCESSDENIED );
+ else if ( r.Code == IOErrorCode_NOT_EXISTING )
+ SetError( ERRCODE_IO_NOTEXISTS );
+ else if ( r.Code == IOErrorCode_CANT_READ )
+ SetError( ERRCODE_IO_CANTREAD );
+ else if ( r.Code == IOErrorCode_CANT_WRITE )
+ SetError( ERRCODE_IO_CANTWRITE );
+ else
+ SetError( ERRCODE_IO_GENERAL );
+
+ return COMMIT_RESULT_FAILURE;
+ }
+ catch ( Exception& )
+ {
+ // how to tell the content : forget all changes ?!
+ // or should we assume that the content does it by itself because he throwed an exception ?!
+ // any other error - not specified
+ SetError( ERRCODE_IO_GENERAL );
+ return COMMIT_RESULT_FAILURE;
+ }
+ }
+ else if ( nRet != COMMIT_RESULT_NOTHING_TO_DO )
+ {
+ // how to tell the content : forget all changes ?! Should we ?!
+ SetError( ERRCODE_IO_GENERAL );
+ return nRet;
+ }
+
+ // after successfull root commit all elements names and types are adjusted and all removed elements
+ // are also removed from the lists
+ UCBStorageElement_Impl* pInnerElement = m_aChildrenList.First();
+ BOOL bRet = TRUE;
+ while ( pInnerElement && bRet )
+ {
+ UCBStorageElement_Impl* pNext = m_aChildrenList.Next();
+ if ( pInnerElement->m_bIsRemoved )
+ {
+ // is this correct use of our list class ?!
+ m_aChildrenList.Remove( pInnerElement );
+ }
+ else
+ {
+ pInnerElement->m_aOriginalName = pInnerElement->m_aName;
+ pInnerElement->m_bIsInserted = FALSE;
+ }
+
+ pInnerElement = pNext;
+ }
+ }
+
+ m_bCommited = FALSE;
+ }
+
+ return nRet;
+}
+
+BOOL UCBStorage_Impl::Revert()
+{
+ UCBStorageElement_Impl* pElement = m_aChildrenList.First();
+ BOOL bRet = TRUE;
+ while ( pElement && bRet )
+ {
+ pElement->m_bIsRemoved = FALSE;
+ if ( pElement->m_bIsInserted )
+ {
+ m_aChildrenList.Remove( pElement ); // correct usage of list ???
+ }
+ else
+ {
+ if ( pElement->m_xStream.Is() )
+ {
+ pElement->m_xStream->m_bCommited = sal_False;
+ pElement->m_xStream->Revert();
+ }
+ else if ( pElement->m_xStorage.Is() )
+ {
+ pElement->m_xStorage->m_bCommited = sal_False;
+ pElement->m_xStorage->Revert();
+ }
+
+ pElement->m_aName = pElement->m_aOriginalName;
+ pElement->m_bIsRemoved = FALSE;
+ }
+
+ pElement = m_aChildrenList.Next();
+ }
+
+ return bRet;
+}
+
+const String& UCBStorage::GetName() const
+{
+ return pImp->m_aName; // pImp->m_aURL ?!
+}
+
+BOOL UCBStorage::IsRoot() const
+{
+ return pImp->m_bIsRoot;
+}
+
+void UCBStorage::SetDirty()
+{
+ pImp->m_bDirty = TRUE;
+}
+
+void UCBStorage::SetClass( const SvGlobalName & rClass, ULONG nOriginalClipFormat, const String & rUserTypeName )
+{
+ pImp->m_aClassId = rClass;
+ pImp->m_nFormat = nOriginalClipFormat;
+ pImp->m_aUserTypeName = rUserTypeName;
+
+ // in UCB storages only the content type will be stored, all other information can be reconstructed
+ // ( see the UCBStorage_Impl::Init() method )
+ ::com::sun::star::datatransfer::DataFlavor aDataFlavor;
+ SotExchange::GetFormatDataFlavor( pImp->m_nFormat, aDataFlavor );
+ pImp->m_aContentType = aDataFlavor.MimeType;
+}
+
+void UCBStorage::SetClassId( const ClsId& rClsId )
+{
+ pImp->m_aClassId = SvGlobalName( (const CLSID&) rClsId );
+ if ( pImp->m_aClassId == SvGlobalName() )
+ return;
+
+ // in OLE storages the clipboard format an the user name will be transferred when a storage is copied because both are
+ // stored in one the substreams
+ // UCB storages store the content type information as content type in the manifest file and so this information must be
+ // kept up to date, and also the other type information that is hold only at runtime because it can be reconstructed from
+ // the content type
+ pImp->m_nFormat = GetFormatId_Impl( pImp->m_aClassId );
+ if ( pImp->m_nFormat )
+ {
+ ::com::sun::star::datatransfer::DataFlavor aDataFlavor;
+ SotExchange::GetFormatDataFlavor( pImp->m_nFormat, aDataFlavor );
+ pImp->m_aUserTypeName = aDataFlavor.HumanPresentableName;
+ pImp->m_aContentType = aDataFlavor.MimeType;
+ }
+}
+
+const ClsId& UCBStorage::GetClassId() const
+{
+ return ( const ClsId& ) pImp->m_aClassId.GetCLSID();
+}
+
+void UCBStorage::SetConvertClass( const SvGlobalName & /*rConvertClass*/, ULONG /*nOriginalClipFormat*/, const String & /*rUserTypeName*/ )
+{
+ // ???
+}
+
+BOOL UCBStorage::ShouldConvert()
+{
+ // ???
+ return FALSE;
+}
+
+SvGlobalName UCBStorage::GetClassName()
+{
+ return pImp->m_aClassId;
+}
+
+ULONG UCBStorage::GetFormat()
+{
+ return pImp->m_nFormat;
+}
+
+String UCBStorage::GetUserName()
+{
+ DBG_ERROR("UserName is not implemented in UCB storages!" );
+ return pImp->m_aUserTypeName;
+}
+
+void UCBStorage::FillInfoList( SvStorageInfoList* pList ) const
+{
+ // put information in childrenlist into StorageInfoList
+ UCBStorageElement_Impl* pElement = pImp->GetChildrenList().First();
+ while ( pElement )
+ {
+ if ( !pElement->m_bIsRemoved )
+ {
+ // problem: what about the size of a substorage ?!
+ ULONG nSize = pElement->m_nSize;
+ if ( pElement->m_xStream.Is() )
+ nSize = pElement->m_xStream->GetSize();
+ SvStorageInfo aInfo( pElement->m_aName, nSize, pElement->m_bIsStorage );
+ pList->Append( aInfo );
+ }
+
+ pElement = pImp->m_aChildrenList.Next();
+ }
+}
+
+BOOL UCBStorage::CopyStorageElement_Impl( UCBStorageElement_Impl& rElement, BaseStorage* pDest, const String& rNew ) const
+{
+ // insert stream or storage into the list or stream of the destination storage
+ // not into the content, this will be done on commit !
+ // be aware of name changes !
+ if ( !rElement.m_bIsStorage )
+ {
+ // copy the streams data
+ // the destination stream must not be open
+ BaseStorageStream* pOtherStream = pDest->OpenStream( rNew, STREAM_WRITE | STREAM_SHARE_DENYALL, pImp->m_bDirect );
+ BaseStorageStream* pStream = NULL;
+ BOOL bDeleteStream = FALSE;
+
+ // if stream is already open, it is allowed to copy it, so be aware of this
+ if ( rElement.m_xStream.Is() )
+ pStream = rElement.m_xStream->m_pAntiImpl;
+ if ( !pStream )
+ {
+ pStream = ( const_cast < UCBStorage* > (this) )->OpenStream( rElement.m_aName, STREAM_STD_READ, pImp->m_bDirect );
+ bDeleteStream = TRUE;
+ }
+
+ pStream->CopyTo( pOtherStream );
+ SetError( pStream->GetError() );
+ if( pOtherStream->GetError() )
+ pDest->SetError( pOtherStream->GetError() );
+ else
+ pOtherStream->Commit();
+
+ if ( bDeleteStream )
+ delete pStream;
+ delete pOtherStream;
+ }
+ else
+ {
+ // copy the storage content
+ // the destination storage must not be open
+ BaseStorage* pStorage = NULL;
+
+ // if stream is already open, it is allowed to copy it, so be aware of this
+ BOOL bDeleteStorage = FALSE;
+ if ( rElement.m_xStorage.Is() )
+ pStorage = rElement.m_xStorage->m_pAntiImpl;
+ if ( !pStorage )
+ {
+ pStorage = ( const_cast < UCBStorage* > (this) )->OpenStorage( rElement.m_aName, pImp->m_nMode, pImp->m_bDirect );
+ bDeleteStorage = TRUE;
+ }
+
+ UCBStorage* pUCBDest = PTR_CAST( UCBStorage, pDest );
+ UCBStorage* pUCBCopy = PTR_CAST( UCBStorage, pStorage );
+
+ BOOL bOpenUCBStorage = pUCBDest && pUCBCopy;
+ BaseStorage* pOtherStorage = bOpenUCBStorage ?
+ pDest->OpenUCBStorage( rNew, STREAM_WRITE | STREAM_SHARE_DENYALL, pImp->m_bDirect ) :
+ pDest->OpenOLEStorage( rNew, STREAM_WRITE | STREAM_SHARE_DENYALL, pImp->m_bDirect );
+
+ // For UCB storages, the class id and the format id may differ,
+ // do passing the class id is not sufficient.
+ if( bOpenUCBStorage )
+ pOtherStorage->SetClass( pStorage->GetClassName(),
+ pStorage->GetFormat(),
+ pUCBCopy->pImp->m_aUserTypeName );
+ else
+ pOtherStorage->SetClassId( pStorage->GetClassId() );
+ pStorage->CopyTo( pOtherStorage );
+ SetError( pStorage->GetError() );
+ if( pOtherStorage->GetError() )
+ pDest->SetError( pOtherStorage->GetError() );
+ else
+ pOtherStorage->Commit();
+
+ if ( bDeleteStorage )
+ delete pStorage;
+ delete pOtherStorage;
+ }
+
+ return BOOL( Good() && pDest->Good() );
+}
+
+UCBStorageElement_Impl* UCBStorage::FindElement_Impl( const String& rName ) const
+{
+ DBG_ASSERT( rName.Len(), "Name is empty!" );
+ UCBStorageElement_Impl* pElement = pImp->GetChildrenList().First();
+ while ( pElement )
+ {
+ if ( pElement->m_aName == rName && !pElement->m_bIsRemoved )
+ break;
+ pElement = pImp->m_aChildrenList.Next();
+ }
+
+ return pElement;
+}
+
+BOOL UCBStorage::CopyTo( BaseStorage* pDestStg ) const
+{
+ DBG_ASSERT( pDestStg != ((BaseStorage*)this), "Self-Copying is not possible!" );
+ if ( pDestStg == ((BaseStorage*)this) )
+ return FALSE;
+
+ // perhaps it's also a problem if one storage is a parent of the other ?!
+ // or if not: could be optimized ?!
+
+ // For UCB storages, the class id and the format id may differ,
+ // do passing the class id is not sufficient.
+ if( pDestStg->ISA( UCBStorage ) )
+ pDestStg->SetClass( pImp->m_aClassId, pImp->m_nFormat,
+ pImp->m_aUserTypeName );
+ else
+ pDestStg->SetClassId( GetClassId() );
+ pDestStg->SetDirty();
+
+ BOOL bRet = TRUE;
+ UCBStorageElement_Impl* pElement = pImp->GetChildrenList().First();
+ while ( pElement && bRet )
+ {
+ if ( !pElement->m_bIsRemoved )
+ bRet = CopyStorageElement_Impl( *pElement, pDestStg, pElement->m_aName );
+ pElement = pImp->m_aChildrenList.Next();
+ }
+
+ if( !bRet )
+ SetError( pDestStg->GetError() );
+ return BOOL( Good() && pDestStg->Good() );
+}
+
+BOOL UCBStorage::CopyTo( const String& rElemName, BaseStorage* pDest, const String& rNew )
+{
+ if( !rElemName.Len() )
+ return FALSE;
+
+ if ( pDest == ((BaseStorage*) this) )
+ {
+ // can't double an element
+ return FALSE;
+ }
+ else
+ {
+ // for copying no optimization is usefull, because in every case the stream data must be copied
+ UCBStorageElement_Impl* pElement = FindElement_Impl( rElemName );
+ if ( pElement )
+ return CopyStorageElement_Impl( *pElement, pDest, rNew );
+ else
+ {
+ SetError( SVSTREAM_FILE_NOT_FOUND );
+ return FALSE;
+ }
+ }
+}
+
+BOOL UCBStorage::Commit()
+{
+ // mark this storage for sending it on root commit
+ pImp->m_bCommited = TRUE;
+ if ( pImp->m_bIsRoot )
+ // the root storage coordinates commiting by sending a Commit command to its content
+ return ( pImp->Commit() != COMMIT_RESULT_FAILURE );
+ else
+ return TRUE;
+}
+
+BOOL UCBStorage::Revert()
+{
+ return pImp->Revert();
+}
+
+BaseStorageStream* UCBStorage::OpenStream( const String& rEleName, StreamMode nMode, BOOL bDirect, const ByteString* pKey )
+{
+ if( !rEleName.Len() )
+ return NULL;
+
+ // try to find the storage element
+ UCBStorageElement_Impl *pElement = FindElement_Impl( rEleName );
+ if ( !pElement )
+ {
+ // element does not exist, check if creation is allowed
+ if( ( nMode & STREAM_NOCREATE ) )
+ {
+ SetError( ( nMode & STREAM_WRITE ) ? SVSTREAM_CANNOT_MAKE : SVSTREAM_FILE_NOT_FOUND );
+ String aName( pImp->m_aURL );
+ aName += '/';
+ aName += rEleName;
+ UCBStorageStream* pStream = new UCBStorageStream( aName, nMode, bDirect, pKey, pImp->m_bRepairPackage, pImp->m_xProgressHandler );
+ pStream->SetError( GetError() );
+ pStream->pImp->m_aName = rEleName;
+ return pStream;
+ }
+ else
+ {
+ // create a new UCBStorageElement and insert it into the list
+ pElement = new UCBStorageElement_Impl( rEleName );
+ pElement->m_bIsInserted = TRUE;
+ pImp->m_aChildrenList.Insert( pElement, LIST_APPEND );
+ }
+ }
+
+ if ( pElement && !pElement->m_bIsFolder )
+ {
+ // check if stream is already created
+ if ( pElement->m_xStream.Is() )
+ {
+ // stream has already been created; if it has no external reference, it may be opened another time
+ if ( pElement->m_xStream->m_pAntiImpl )
+ {
+ DBG_ERROR("Stream is already open!" );
+ SetError( SVSTREAM_ACCESS_DENIED ); // ???
+ return NULL;
+ }
+ else
+ {
+ // check if stream is opened with the same keyword as before
+ // if not, generate a new stream because it could be encrypted vs. decrypted!
+ ByteString aKey;
+ if ( pKey )
+ aKey = *pKey;
+ if ( pElement->m_xStream->m_aKey == aKey )
+ {
+ pElement->m_xStream->PrepareCachedForReopen( nMode );
+
+ // DBG_ASSERT( bDirect == pElement->m_xStream->m_bDirect, "Wrong DirectMode!" );
+ return new UCBStorageStream( pElement->m_xStream );
+ }
+ }
+ }
+
+ // stream is opened the first time
+ pImp->OpenStream( pElement, nMode, bDirect, pKey );
+
+ // if name has been changed before creating the stream: set name!
+ pElement->m_xStream->m_aName = rEleName;
+ return new UCBStorageStream( pElement->m_xStream );
+ }
+
+ return NULL;
+}
+
+UCBStorageStream_Impl* UCBStorage_Impl::OpenStream( UCBStorageElement_Impl* pElement, StreamMode nMode, BOOL bDirect, const ByteString* pKey )
+{
+ String aName( m_aURL );
+ aName += '/';
+ aName += pElement->m_aOriginalName;
+ pElement->m_xStream = new UCBStorageStream_Impl( aName, nMode, NULL, bDirect, pKey, m_bRepairPackage, m_xProgressHandler );
+ return pElement->m_xStream;
+}
+
+BaseStorage* UCBStorage::OpenUCBStorage( const String& rEleName, StreamMode nMode, BOOL bDirect )
+{
+ if( !rEleName.Len() )
+ return NULL;
+
+ return OpenStorage_Impl( rEleName, nMode, bDirect, TRUE );
+}
+
+BaseStorage* UCBStorage::OpenOLEStorage( const String& rEleName, StreamMode nMode, BOOL bDirect )
+{
+ if( !rEleName.Len() )
+ return NULL;
+
+ return OpenStorage_Impl( rEleName, nMode, bDirect, FALSE );
+}
+
+BaseStorage* UCBStorage::OpenStorage( const String& rEleName, StreamMode nMode, BOOL bDirect )
+{
+ if( !rEleName.Len() )
+ return NULL;
+
+ return OpenStorage_Impl( rEleName, nMode, bDirect, TRUE );
+}
+
+BaseStorage* UCBStorage::OpenStorage_Impl( const String& rEleName, StreamMode nMode, BOOL bDirect, BOOL bForceUCBStorage )
+{
+ // try to find the storage element
+ UCBStorageElement_Impl *pElement = FindElement_Impl( rEleName );
+ if ( !pElement )
+ {
+ // element does not exist, check if creation is allowed
+ if( ( nMode & STREAM_NOCREATE ) )
+ {
+ SetError( ( nMode & STREAM_WRITE ) ? SVSTREAM_CANNOT_MAKE : SVSTREAM_FILE_NOT_FOUND );
+ String aName( pImp->m_aURL );
+ aName += '/';
+ aName += rEleName; // ???
+ UCBStorage *pStorage = new UCBStorage( aName, nMode, bDirect, FALSE, pImp->m_bRepairPackage, pImp->m_xProgressHandler );
+ pStorage->pImp->m_bIsRoot = FALSE;
+ pStorage->pImp->m_bListCreated = sal_True; // the storage is pretty new, nothing to read
+ pStorage->SetError( GetError() );
+ return pStorage;
+ }
+
+ // create a new UCBStorageElement and insert it into the list
+ // problem: perhaps an OLEStorage should be created ?!
+ // Because nothing is known about the element that should be created, an external parameter is needed !
+ pElement = new UCBStorageElement_Impl( rEleName );
+ pElement->m_bIsInserted = TRUE;
+ pImp->m_aChildrenList.Insert( pElement, LIST_APPEND );
+ }
+
+ if ( !pElement->m_bIsFolder && ( pElement->m_bIsStorage || !bForceUCBStorage ) )
+ {
+ // create OLE storages on a stream ( see ctor of SotStorage )
+ // Such a storage will be created on a UCBStorageStream; it will write into the stream
+ // if it is opened in direct mode or when it is committed. In this case the stream will be
+ // modified and then it MUST be treated as commited.
+ if ( !pElement->m_xStream.Is() )
+ {
+ BaseStorageStream* pStr = OpenStream( rEleName, nMode, bDirect );
+ UCBStorageStream* pStream = PTR_CAST( UCBStorageStream, pStr );
+ if ( !pStream )
+ {
+ SetError( ( nMode & STREAM_WRITE ) ? SVSTREAM_CANNOT_MAKE : SVSTREAM_FILE_NOT_FOUND );
+ return NULL;
+ }
+
+ pElement->m_xStream = pStream->pImp;
+ delete pStream;
+ }
+
+ pElement->m_xStream->PrepareCachedForReopen( nMode );
+ pElement->m_xStream->Init();
+
+ pElement->m_bIsStorage = TRUE;
+ return pElement->m_xStream->CreateStorage(); // can only be created in transacted mode
+ }
+ else if ( pElement->m_xStorage.Is() )
+ {
+ // storage has already been opened; if it has no external reference, it may be opened another time
+ if ( pElement->m_xStorage->m_pAntiImpl )
+ {
+ DBG_ERROR("Storage is already open!" );
+ SetError( SVSTREAM_ACCESS_DENIED ); // ???
+ }
+ else
+ {
+ BOOL bIsWritable = (( pElement->m_xStorage->m_nMode & STREAM_WRITE ) != 0);
+ if ( !bIsWritable && (( nMode & STREAM_WRITE ) != 0 ))
+ {
+ String aName( pImp->m_aURL );
+ aName += '/';
+ aName += pElement->m_aOriginalName;
+ UCBStorage* pStorage = new UCBStorage( aName, nMode, bDirect, FALSE, pImp->m_bRepairPackage, pImp->m_xProgressHandler );
+ pElement->m_xStorage = pStorage->pImp;
+ return pStorage;
+ }
+ else
+ {
+// DBG_ASSERT( bDirect == pElement->m_xStorage->m_bDirect, "Wrong DirectMode!" );
+ return new UCBStorage( pElement->m_xStorage );
+ }
+ }
+ }
+ else if ( !pElement->m_xStream.Is() )
+ {
+ // storage is opened the first time
+ BOOL bIsWritable = (( pImp->m_nMode & STREAM_WRITE ) != 0 );
+ if ( pImp->m_bIsLinked && pImp->m_bIsRoot && bIsWritable )
+ {
+ // make sure that the root storage object has been created before substorages will be created
+ INetURLObject aFolderObj( pImp->m_aURL );
+ String aName = aFolderObj.GetName();
+ aFolderObj.removeSegment();
+
+ Content aFolder( aFolderObj.GetMainURL( INetURLObject::NO_DECODE ), Reference < XCommandEnvironment >() );
+ pImp->m_pContent = new Content;
+ BOOL bRet = ::utl::UCBContentHelper::MakeFolder( aFolder, pImp->m_aName, *pImp->m_pContent );
+ if ( !bRet )
+ {
+ SetError( SVSTREAM_CANNOT_MAKE );
+ return NULL;
+ }
+ }
+
+ UCBStorage_Impl* pStor = pImp->OpenStorage( pElement, nMode, bDirect );
+ if ( pStor )
+ {
+ if ( pElement->m_bIsInserted )
+ pStor->m_bListCreated = sal_True; // the storage is pretty new, nothing to read
+
+ return new UCBStorage( pStor );
+ }
+ }
+
+ return NULL;
+}
+
+UCBStorage_Impl* UCBStorage_Impl::OpenStorage( UCBStorageElement_Impl* pElement, StreamMode nMode, BOOL bDirect )
+{
+ UCBStorage_Impl* pRet = NULL;
+ String aName( m_aURL );
+ aName += '/';
+ aName += pElement->m_aOriginalName; // ???
+
+ pElement->m_bIsStorage = pElement->m_bIsFolder = TRUE;
+
+ if ( m_bIsLinked && !::utl::UCBContentHelper::Exists( aName ) )
+ {
+ Content aNewFolder;
+ BOOL bRet = ::utl::UCBContentHelper::MakeFolder( *m_pContent, pElement->m_aOriginalName, aNewFolder );
+ if ( bRet )
+ pRet = new UCBStorage_Impl( aNewFolder, aName, nMode, NULL, bDirect, FALSE, m_bRepairPackage, m_xProgressHandler );
+ }
+ else
+ {
+ pRet = new UCBStorage_Impl( aName, nMode, NULL, bDirect, FALSE, m_bRepairPackage, m_xProgressHandler );
+ }
+
+ if ( pRet )
+ {
+ pRet->m_bIsLinked = m_bIsLinked;
+ pRet->m_bIsRoot = FALSE;
+
+ // if name has been changed before creating the stream: set name!
+ pRet->m_aName = pElement->m_aOriginalName;
+ pElement->m_xStorage = pRet;
+ }
+
+ if ( pRet )
+ pRet->Init();
+
+ return pRet;
+}
+
+BOOL UCBStorage::IsStorage( const String& rEleName ) const
+{
+ if( !rEleName.Len() )
+ return FALSE;
+
+ const UCBStorageElement_Impl *pElement = FindElement_Impl( rEleName );
+ return ( pElement && pElement->m_bIsStorage );
+}
+
+BOOL UCBStorage::IsStream( const String& rEleName ) const
+{
+ if( !rEleName.Len() )
+ return FALSE;
+
+ const UCBStorageElement_Impl *pElement = FindElement_Impl( rEleName );
+ return ( pElement && !pElement->m_bIsStorage );
+}
+
+BOOL UCBStorage::IsContained( const String & rEleName ) const
+{
+ if( !rEleName.Len() )
+ return FALSE;
+ const UCBStorageElement_Impl *pElement = FindElement_Impl( rEleName );
+ return ( pElement != NULL );
+}
+
+BOOL UCBStorage::Remove( const String& rEleName )
+{
+ if( !rEleName.Len() )
+ return FALSE;
+
+ UCBStorageElement_Impl *pElement = FindElement_Impl( rEleName );
+ if ( pElement )
+ {
+ pElement->m_bIsRemoved = TRUE;
+ }
+ else
+ SetError( SVSTREAM_FILE_NOT_FOUND );
+
+ return ( pElement != NULL );
+}
+
+BOOL UCBStorage::Rename( const String& rEleName, const String& rNewName )
+{
+ if( !rEleName.Len()|| !rNewName.Len() )
+ return FALSE;
+
+ UCBStorageElement_Impl *pAlreadyExisting = FindElement_Impl( rNewName );
+ if ( pAlreadyExisting )
+ {
+ SetError( SVSTREAM_ACCESS_DENIED );
+ return FALSE; // can't change to a name that is already used
+ }
+
+ UCBStorageElement_Impl *pElement = FindElement_Impl( rEleName );
+ if ( pElement )
+ {
+ pElement->m_aName = rNewName;
+ }
+ else
+ SetError( SVSTREAM_FILE_NOT_FOUND );
+
+ return pElement != NULL;
+}
+
+BOOL UCBStorage::MoveTo( const String& rEleName, BaseStorage* pNewSt, const String& rNewName )
+{
+ if( !rEleName.Len() || !rNewName.Len() )
+ return FALSE;
+
+ if ( pNewSt == ((BaseStorage*) this) && !FindElement_Impl( rNewName ) )
+ {
+ return Rename( rEleName, rNewName );
+ }
+ else
+ {
+/*
+ if ( PTR_CAST( UCBStorage, pNewSt ) )
+ {
+ // because the element is moved, not copied, a special optimization is possible :
+ // first copy the UCBStorageElement; flag old element as "Removed" and new as "Inserted",
+ // clear original name/type of the new element
+ // if moved element is open: copy content, but change absolute URL ( and those of all children of the element! ),
+ // clear original name/type of new content, keep the old original stream/storage, but forget its working streams,
+ // close original UCBContent and original stream, only the TempFile and its stream may remain unchanged, but now
+ // belong to the new content
+ // if original and editable stream are identical ( readonly element ), it has to be copied to the editable
+ // stream of the destination object
+ // Not implemented at the moment ( risky?! ), perhaps later
+ }
+*/
+ // MoveTo is done by first copying to the new destination and then removing the old element
+ BOOL bRet = CopyTo( rEleName, pNewSt, rNewName );
+ if ( bRet )
+ bRet = Remove( rEleName );
+ return bRet;
+ }
+}
+
+BOOL UCBStorage::ValidateFAT()
+{
+ // ???
+ return TRUE;
+}
+
+BOOL UCBStorage::Validate( BOOL bWrite ) const
+{
+ // ???
+ return ( !bWrite || ( pImp->m_nMode & STREAM_WRITE ) );
+}
+
+BOOL UCBStorage::ValidateMode( StreamMode m ) const
+{
+ // ???
+ if( m == ( STREAM_READ | STREAM_TRUNC ) ) // from stg.cxx
+ return TRUE;
+ USHORT nCurMode = 0xFFFF;
+ if( ( m & 3 ) == STREAM_READ )
+ {
+ // only SHARE_DENYWRITE or SHARE_DENYALL allowed
+ if( ( ( m & STREAM_SHARE_DENYWRITE )
+ && ( nCurMode & STREAM_SHARE_DENYWRITE ) )
+ || ( ( m & STREAM_SHARE_DENYALL )
+ && ( nCurMode & STREAM_SHARE_DENYALL ) ) )
+ return TRUE;
+ }
+ else
+ {
+ // only SHARE_DENYALL allowed
+ // storages open in r/o mode are OK, since only
+ // the commit may fail
+ if( ( m & STREAM_SHARE_DENYALL )
+ && ( nCurMode & STREAM_SHARE_DENYALL ) )
+ return TRUE;
+ }
+
+ return TRUE;
+}
+
+const SvStream* UCBStorage::GetSvStream() const
+{
+ // this would cause a complete download of the file
+ // as it looks, this method is NOT used inside of SOT, only exported by class SotStorage - but for what ???
+ return pImp->m_pSource;
+}
+
+BOOL UCBStorage::Equals( const BaseStorage& rStorage ) const
+{
+ // ???
+ return ((BaseStorage*)this) == &rStorage;
+}
+
+BOOL UCBStorage::IsStorageFile( const String& rFileName )
+{
+ String aFileURL = rFileName;
+ INetURLObject aObj( aFileURL );
+ if ( aObj.GetProtocol() == INET_PROT_NOT_VALID )
+ {
+ ::utl::LocalFileHelper::ConvertPhysicalNameToURL( rFileName, aFileURL );
+ aObj.SetURL( aFileURL );
+ aFileURL = aObj.GetMainURL( INetURLObject::NO_DECODE );
+ }
+
+ SvStream * pStm = ::utl::UcbStreamHelper::CreateStream( aFileURL, STREAM_STD_READ );
+ BOOL bRet = UCBStorage::IsStorageFile( pStm );
+ delete pStm;
+ return bRet;
+}
+
+BOOL UCBStorage::IsStorageFile( SvStream* pFile )
+{
+ if ( !pFile )
+ return FALSE;
+
+ ULONG nPos = pFile->Tell();
+ pFile->Seek( STREAM_SEEK_TO_END );
+ if ( pFile->Tell() < 4 )
+ return FALSE;
+
+ pFile->Seek(0);
+ UINT32 nBytes;
+ *pFile >> nBytes;
+
+ // search for the magic bytes
+ BOOL bRet = ( nBytes == 0x04034b50 );
+ if ( !bRet )
+ {
+ // disk spanned file have an additional header in front of the usual one
+ bRet = ( nBytes == 0x08074b50 );
+ if ( bRet )
+ {
+ *pFile >> nBytes;
+ bRet = ( nBytes == 0x04034b50 );
+ }
+ }
+
+ pFile->Seek( nPos );
+ return bRet;
+}
+
+BOOL UCBStorage::IsDiskSpannedFile( SvStream* pFile )
+{
+ if ( !pFile )
+ return FALSE;
+
+ ULONG nPos = pFile->Tell();
+ pFile->Seek( STREAM_SEEK_TO_END );
+ if ( !pFile->Tell() )
+ return FALSE;
+
+ pFile->Seek(0);
+ UINT32 nBytes;
+ *pFile >> nBytes;
+
+ // disk spanned file have an additional header in front of the usual one
+ BOOL bRet = ( nBytes == 0x08074b50 );
+ if ( bRet )
+ {
+ *pFile >> nBytes;
+ bRet = ( nBytes == 0x04034b50 );
+ }
+
+ pFile->Seek( nPos );
+ return bRet;
+}
+
+String UCBStorage::GetLinkedFile( SvStream &rStream )
+{
+ String aString;
+ ULONG nPos = rStream.Tell();
+ rStream.Seek( STREAM_SEEK_TO_END );
+ if ( !rStream.Tell() )
+ return aString;
+
+ rStream.Seek(0);
+ UINT32 nBytes;
+ rStream >> nBytes;
+ if( nBytes == 0x04034b50 )
+ {
+ ByteString aTmp;
+ rStream.ReadByteString( aTmp );
+ if ( aTmp.CompareTo( "ContentURL=", 11 ) == COMPARE_EQUAL )
+ {
+ aTmp.Erase( 0, 11 );
+ aString = String( aTmp, RTL_TEXTENCODING_UTF8 );
+ }
+ }
+
+ rStream.Seek( nPos );
+ return aString;
+}
+
+String UCBStorage::CreateLinkFile( const String& rName )
+{
+ // create a stream to write the link file - use a temp file, because it may be no file content
+ INetURLObject aFolderObj( rName );
+ String aName = aFolderObj.GetName();
+ aFolderObj.removeSegment();
+ String aFolderURL( aFolderObj.GetMainURL( INetURLObject::NO_DECODE ) );
+ ::utl::TempFile* pTempFile = new ::utl::TempFile( &aFolderURL );
+
+ // get the stream from the temp file
+ SvStream* pStream = pTempFile->GetStream( STREAM_STD_READWRITE | STREAM_TRUNC );
+
+ // write header
+ *pStream << ( UINT32 ) 0x04034b50;
+
+ // assemble a new folder name in the destination folder
+ INetURLObject aObj( rName );
+ String aTmpName = aObj.GetName();
+ String aTitle = String::CreateFromAscii( "content." );
+ aTitle += aTmpName;
+
+ // create a folder and store its URL
+ Content aFolder( aFolderURL, Reference < XCommandEnvironment >() );
+ Content aNewFolder;
+ BOOL bRet = ::utl::UCBContentHelper::MakeFolder( aFolder, aTitle, aNewFolder );
+ if ( !bRet )
+ {
+ aFolderObj.insertName( aTitle );
+ if ( ::utl::UCBContentHelper::Exists( aFolderObj.GetMainURL( INetURLObject::NO_DECODE ) ) )
+ {
+ // Hack, because already existing files give the same CommandAbortedException as any other error !
+ // append a number until the name can be used for a new folder
+ aTitle += '.';
+ for ( sal_Int32 i=0; !bRet; i++ )
+ {
+ String aTmp( aTitle );
+ aTmp += String::CreateFromInt32( i );
+ bRet = ::utl::UCBContentHelper::MakeFolder( aFolder, aTmp, aNewFolder );
+ if ( bRet )
+ aTitle = aTmp;
+ else
+ {
+ aFolderObj.SetName( aTmp );
+ if ( !::utl::UCBContentHelper::Exists( aFolderObj.GetMainURL( INetURLObject::NO_DECODE ) ) )
+ // Hack, because already existing files give the same CommandAbortedException as any other error !
+ break;
+ }
+ }
+ }
+ }
+
+ if ( bRet )
+ {
+ // get the URL
+ aObj.SetName( aTitle );
+ String aURL = aObj.GetMainURL( INetURLObject::NO_DECODE );
+
+ // store it as key/value pair
+ String aLink = String::CreateFromAscii("ContentURL=");
+ aLink += aURL;
+ pStream->WriteByteString( aLink, RTL_TEXTENCODING_UTF8 );
+ pStream->Flush();
+
+ // move the stream to its desired location
+ Content aSource( pTempFile->GetURL(), Reference < XCommandEnvironment >() );
+ DELETEZ( pTempFile );
+ aFolder.transferContent( aSource, InsertOperation_MOVE, aName, NameClash::OVERWRITE );
+ return aURL;
+ }
+
+ pTempFile->EnableKillingFile( TRUE );
+ delete pTempFile;
+ return String();
+}
+
+BOOL UCBStorage::SetProperty( const String& rName, const ::com::sun::star::uno::Any& rValue )
+{
+ if ( rName.CompareToAscii("Title") == COMPARE_EQUAL )
+ return FALSE;
+
+ if ( rName.CompareToAscii("MediaType") == COMPARE_EQUAL )
+ {
+ ::rtl::OUString aTmp;
+ rValue >>= aTmp;
+ pImp->m_aContentType = aTmp;
+ }
+
+ try
+ {
+ if ( pImp->GetContent() )
+ {
+ pImp->m_pContent->setPropertyValue( rName, rValue );
+ return TRUE;
+ }
+ }
+ catch ( Exception& )
+ {
+ }
+
+ return FALSE;
+}
+
+BOOL UCBStorage::GetProperty( const String& rName, ::com::sun::star::uno::Any& rValue )
+{
+ try
+ {
+ if ( pImp->GetContent() )
+ {
+ rValue = pImp->m_pContent->getPropertyValue( rName );
+ return TRUE;
+ }
+ }
+ catch ( Exception& )
+ {
+ }
+
+ return FALSE;
+}
+
+BOOL UCBStorage::GetProperty( const String& rEleName, const String& rName, ::com::sun::star::uno::Any& rValue )
+{
+ UCBStorageElement_Impl *pEle = FindElement_Impl( rEleName );
+ if ( !pEle )
+ return FALSE;
+
+ if ( !pEle->m_bIsFolder )
+ {
+ if ( !pEle->m_xStream.Is() )
+ pImp->OpenStream( pEle, pImp->m_nMode, pImp->m_bDirect );
+ if ( pEle->m_xStream->m_nError )
+ {
+ pEle->m_xStream.Clear();
+ return FALSE;
+ }
+
+ try
+ {
+ if ( pEle->m_xStream->m_pContent )
+ {
+ rValue = pEle->m_xStream->m_pContent->getPropertyValue( rName );
+ return TRUE;
+ }
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+ else
+ {
+ if ( !pEle->m_xStorage.Is() )
+ pImp->OpenStorage( pEle, pImp->m_nMode, pImp->m_bDirect );
+ if ( pEle->m_xStorage->m_nError )
+ {
+ pEle->m_xStorage.Clear();
+ return FALSE;
+ }
+
+ try
+ {
+ if ( pEle->m_xStorage->GetContent() )
+ {
+ rValue = pEle->m_xStorage->m_pContent->getPropertyValue( rName );
+ return TRUE;
+ }
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+
+ return FALSE;
+}
+
+UNOStorageHolderList* UCBStorage::GetUNOStorageHolderList()
+{
+ if ( !pImp->m_pUNOStorageHolderList )
+ pImp->m_pUNOStorageHolderList = new UNOStorageHolderList;
+
+ return pImp->m_pUNOStorageHolderList;
+}
+
diff --git a/sot/source/sdstor/unostorageholder.cxx b/sot/source/sdstor/unostorageholder.cxx
new file mode 100644
index 000000000000..55c205557648
--- /dev/null
+++ b/sot/source/sdstor/unostorageholder.cxx
@@ -0,0 +1,197 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sot.hxx"
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/embed/XTransactionBroadcaster.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+
+#include <comphelper/processfactory.hxx>
+
+#include "unostorageholder.hxx"
+#include <storinfo.hxx>
+
+
+using namespace ::com::sun::star;
+
+UNOStorageHolder::UNOStorageHolder( SotStorage& aParentStorage,
+ SotStorage& aStorage,
+ uno::Reference< embed::XStorage > xStorage,
+ ::utl::TempFile* pTempFile )
+: m_pParentStorage( &aParentStorage )
+, m_rSotStorage( &aStorage )
+, m_xStorage( xStorage )
+, m_pTempFile( pTempFile )
+{
+ OSL_ENSURE( m_xStorage.is() && m_pTempFile, "Wrong initialization!\n" );
+ if ( !m_xStorage.is() || !m_pTempFile )
+ throw uno::RuntimeException();
+
+ uno::Reference< embed::XTransactionBroadcaster > xTrBroadcast( m_xStorage, uno::UNO_QUERY );
+ if ( !xTrBroadcast.is() )
+ throw uno::RuntimeException();
+
+ xTrBroadcast->addTransactionListener( (embed::XTransactionListener*)this );
+}
+
+void UNOStorageHolder::InternalDispose()
+{
+ uno::Reference< embed::XTransactionBroadcaster > xTrBroadcast( m_xStorage, uno::UNO_QUERY );
+ if ( xTrBroadcast.is() )
+ xTrBroadcast->removeTransactionListener( (embed::XTransactionListener*)this );
+
+ uno::Reference< lang::XComponent > xComponent( m_xStorage, uno::UNO_QUERY );
+ if ( xComponent.is() )
+ xComponent->dispose();
+ m_xStorage = uno::Reference< embed::XStorage >();
+
+ if ( m_pParentStorage )
+ m_pParentStorage = NULL;
+
+ if ( m_pTempFile )
+ {
+ delete m_pTempFile;
+ m_pTempFile = NULL;
+ }
+
+ if ( m_rSotStorage.Is() )
+ m_rSotStorage = NULL;
+}
+
+String UNOStorageHolder::GetStorageName()
+{
+ if ( m_rSotStorage.Is() )
+ return m_rSotStorage->GetName();
+
+ return String();
+}
+
+void SAL_CALL UNOStorageHolder::preCommit( const lang::EventObject& /*aEvent*/ )
+ throw ( uno::Exception,
+ uno::RuntimeException )
+{
+ // do nothing
+}
+
+void SAL_CALL UNOStorageHolder::commited( const lang::EventObject& /*aEvent*/ )
+ throw ( uno::RuntimeException )
+{
+ ::utl::TempFile aTmpStorFile;
+ if ( !aTmpStorFile.GetURL().Len() )
+ throw uno::RuntimeException();
+
+ uno::Reference< lang::XSingleServiceFactory > xStorageFactory(
+ ::comphelper::getProcessServiceFactory()->createInstance(
+ ::rtl::OUString::createFromAscii( "com.sun.star.embed.StorageFactory" ) ),
+ uno::UNO_QUERY );
+
+ OSL_ENSURE( xStorageFactory.is(), "Can't create storage factory!\n" );
+ if ( !xStorageFactory.is() )
+ throw uno::RuntimeException();
+
+ uno::Sequence< uno::Any > aArg( 2 );
+ aArg[0] <<= ::rtl::OUString( aTmpStorFile.GetURL() );
+ aArg[1] <<= embed::ElementModes::READWRITE;
+ uno::Reference< embed::XStorage > xTempStorage( xStorageFactory->createInstanceWithArguments( aArg ), uno::UNO_QUERY );
+
+ OSL_ENSURE( xTempStorage.is(), "Can't open storage!\n" );
+ if ( !xTempStorage.is() )
+ throw uno::RuntimeException();
+
+ m_xStorage->copyToStorage( xTempStorage );
+
+ uno::Reference< lang::XComponent > xComp( xTempStorage, uno::UNO_QUERY );
+ if ( !xComp.is() )
+ throw uno::RuntimeException();
+
+ xComp->dispose();
+
+ SotStorageRef rTempStorage = new SotStorage( TRUE, aTmpStorFile.GetURL(), STREAM_WRITE, STORAGE_TRANSACTED );
+ if ( !rTempStorage.Is() || rTempStorage->GetError() != ERRCODE_NONE )
+ throw uno::RuntimeException();
+
+ SvStorageInfoList aSubStorInfoList;
+ m_rSotStorage->FillInfoList( &aSubStorInfoList );
+ for ( sal_uInt32 nInd = 0; nInd < aSubStorInfoList.Count(); nInd++ )
+ {
+ m_rSotStorage->Remove( aSubStorInfoList[nInd].GetName() );
+ if ( m_rSotStorage->GetError() )
+ {
+ m_rSotStorage->ResetError();
+ throw uno::RuntimeException();
+ }
+ }
+
+ rTempStorage->CopyTo( m_rSotStorage );
+
+ // CopyTo does not transport unknown media type
+ // just workaround it
+ uno::Any aMediaType;
+ if ( rTempStorage->GetProperty( ::rtl::OUString::createFromAscii( "MediaType" ), aMediaType ) )
+ m_rSotStorage->SetProperty( ::rtl::OUString::createFromAscii( "MediaType" ), aMediaType );
+
+ m_rSotStorage->Commit();
+}
+
+void SAL_CALL UNOStorageHolder::preRevert( const lang::EventObject& /*aEvent*/ )
+ throw ( uno::Exception,
+ uno::RuntimeException )
+{
+ // do nothing
+}
+
+void SAL_CALL UNOStorageHolder::reverted( const lang::EventObject& /*aEvent*/ )
+ throw ( uno::RuntimeException )
+{
+ // do nothing, since reverting of the duplicate storage just means
+ // not to copy changes done for it to the original storage
+}
+
+void SAL_CALL UNOStorageHolder::disposing( const lang::EventObject& /*Source*/ )
+ throw ( uno::RuntimeException )
+{
+ if ( m_pTempFile )
+ {
+ delete m_pTempFile;
+ m_pTempFile = NULL;
+ }
+
+ if ( m_rSotStorage.Is() )
+ m_rSotStorage = NULL;
+
+ if ( m_pParentStorage )
+ {
+ SotStorage* pTmp = m_pParentStorage;
+ m_pParentStorage = NULL;
+ pTmp->RemoveUNOStorageHolder( this ); // this statement can lead to destruction of the holder
+ }
+}
+
+
diff --git a/sot/source/sdstor/unostorageholder.hxx b/sot/source/sdstor/unostorageholder.hxx
new file mode 100644
index 000000000000..5e70804745a8
--- /dev/null
+++ b/sot/source/sdstor/unostorageholder.hxx
@@ -0,0 +1,77 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _UNOSTORAGEHOLDER_HXX
+#define _UNOSTORAGEHOLDER_HXX
+
+#include <com/sun/star/embed/XTransactionListener.hpp>
+#include <cppuhelper/implbase1.hxx>
+
+#include <unotools/tempfile.hxx>
+#include <sot/storage.hxx>
+
+class SotStorage;
+class UNOStorageHolder : public ::cppu::WeakImplHelper1<
+ ::com::sun::star::embed::XTransactionListener >
+
+{
+ SotStorage* m_pParentStorage; // parent storage
+ SotStorageRef m_rSotStorage; // original substorage
+ ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > m_xStorage; // duplicate storage
+ ::utl::TempFile* m_pTempFile; // temporary file used by duplicate storage
+
+public:
+ UNOStorageHolder( SotStorage& aParentStorage,
+ SotStorage& aStorage,
+ ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > xStorage,
+ ::utl::TempFile* pTempFile );
+
+ void InternalDispose();
+ String GetStorageName();
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > GetDuplicateStorage() { return m_xStorage; }
+
+ virtual void SAL_CALL preCommit( const ::com::sun::star::lang::EventObject& aEvent )
+ throw ( ::com::sun::star::uno::Exception,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL commited( const ::com::sun::star::lang::EventObject& aEvent )
+ throw ( ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL preRevert( const ::com::sun::star::lang::EventObject& aEvent )
+ throw ( ::com::sun::star::uno::Exception,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL reverted( const ::com::sun::star::lang::EventObject& aEvent )
+ throw ( ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source )
+ throw ( ::com::sun::star::uno::RuntimeException );
+};
+
+#endif
+
diff --git a/sot/source/unoolestorage/makefile.mk b/sot/source/unoolestorage/makefile.mk
new file mode 100644
index 000000000000..d88f72f14e51
--- /dev/null
+++ b/sot/source/unoolestorage/makefile.mk
@@ -0,0 +1,51 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=sot
+TARGET=unoolestorage
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/xolesimplestorage.obj \
+ $(SLO)$/register.obj
+
+EXCEPTIONSFILES= \
+ $(SLO)$/xolesimplestorage.obj \
+ $(SLO)$/register.obj
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/sot/source/unoolestorage/register.cxx b/sot/source/unoolestorage/register.cxx
new file mode 100644
index 000000000000..083a4d585ca1
--- /dev/null
+++ b/sot/source/unoolestorage/register.cxx
@@ -0,0 +1,73 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sot.hxx"
+
+
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#include <com/sun/star/registry/InvalidRegistryException.hpp>
+#include <cppuhelper/factory.hxx>
+
+#include "xolesimplestorage.hxx"
+
+using namespace ::com::sun::star;
+
+
+extern "C" {
+
+SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment( const sal_Char ** ppEnvTypeName, uno_Environment ** /*ppEnv*/ )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * /*pRegistryKey*/ )
+{
+ void * pRet = 0;
+
+ ::rtl::OUString aImplName( ::rtl::OUString::createFromAscii( pImplName ) );
+ uno::Reference< lang::XSingleServiceFactory > xFactory;
+
+ if ( pServiceManager && aImplName.equals( OLESimpleStorage::impl_staticGetImplementationName() ) )
+ {
+ xFactory= ::cppu::createSingleFactory( reinterpret_cast< lang::XMultiServiceFactory*>( pServiceManager ),
+ OLESimpleStorage::impl_staticGetImplementationName(),
+ OLESimpleStorage::impl_staticCreateSelfInstance,
+ OLESimpleStorage::impl_staticGetSupportedServiceNames() );
+ }
+
+ if ( xFactory.is() )
+ {
+ xFactory->acquire();
+ pRet = xFactory.get();
+ }
+
+ return pRet;
+}
+
+} // extern "C"
+
diff --git a/sot/source/unoolestorage/xolesimplestorage.cxx b/sot/source/unoolestorage/xolesimplestorage.cxx
new file mode 100644
index 000000000000..1780e45c5ed6
--- /dev/null
+++ b/sot/source/unoolestorage/xolesimplestorage.cxx
@@ -0,0 +1,811 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sot.hxx"
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/io/XStream.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+#include <com/sun/star/io/XTruncate.hpp>
+
+#include <comphelper/storagehelper.hxx>
+
+#include <unotools/ucbstreamhelper.hxx>
+
+#include <cppuhelper/exc_hlp.hxx>
+
+#include <storinfo.hxx>
+
+#include "xolesimplestorage.hxx"
+
+
+using namespace ::com::sun::star;
+
+const sal_Int32 nBytesCount = 32000;
+
+
+// --------------------------------------------------------------------------------
+OLESimpleStorage::OLESimpleStorage( uno::Reference< lang::XMultiServiceFactory > xFactory )
+: m_bDisposed( sal_False )
+, m_pStream( NULL )
+, m_pStorage( NULL )
+, m_pListenersContainer( NULL )
+, m_xFactory( xFactory )
+, m_bNoTemporaryCopy( sal_False )
+{
+ OSL_ENSURE( m_xFactory.is(), "No factory is provided on creation!\n" );
+ if ( !m_xFactory.is() )
+ throw uno::RuntimeException();
+}
+
+// --------------------------------------------------------------------------------
+OLESimpleStorage::~OLESimpleStorage()
+{
+ try {
+ m_refCount++;
+ dispose();
+ } catch( uno::Exception& )
+ {}
+
+ if ( m_pListenersContainer )
+ {
+ delete m_pListenersContainer;
+ m_pListenersContainer = NULL;
+ }
+}
+
+//-------------------------------------------------------------------------
+uno::Sequence< ::rtl::OUString > SAL_CALL OLESimpleStorage::impl_staticGetSupportedServiceNames()
+{
+ uno::Sequence< ::rtl::OUString > aRet(1);
+ aRet[0] = ::rtl::OUString::createFromAscii("com.sun.star.embed.OLESimpleStorage");
+ return aRet;
+}
+
+//-------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OLESimpleStorage::impl_staticGetImplementationName()
+{
+ return ::rtl::OUString::createFromAscii("com.sun.star.comp.embed.OLESimpleStorage");
+}
+
+//-------------------------------------------------------------------------
+uno::Reference< uno::XInterface > SAL_CALL OLESimpleStorage::impl_staticCreateSelfInstance(
+ const uno::Reference< lang::XMultiServiceFactory >& xServiceManager )
+{
+ return uno::Reference< uno::XInterface >( *new OLESimpleStorage( xServiceManager ) );
+}
+
+//-------------------------------------------------------------------------
+void OLESimpleStorage::UpdateOriginal_Impl()
+{
+ if ( !m_bNoTemporaryCopy )
+ {
+ uno::Reference< io::XSeekable > xSeek( m_xStream, uno::UNO_QUERY_THROW );
+ xSeek->seek( 0 );
+
+ uno::Reference< io::XSeekable > xTempSeek( m_xTempStream, uno::UNO_QUERY_THROW );
+ sal_Int64 nPos = xTempSeek->getPosition();
+ xTempSeek->seek( 0 );
+
+ uno::Reference< io::XInputStream > xTempInp = m_xTempStream->getInputStream();
+ uno::Reference< io::XOutputStream > xOutputStream = m_xStream->getOutputStream();
+ if ( !xTempInp.is() || !xOutputStream.is() )
+ throw uno::RuntimeException();
+
+ uno::Reference< io::XTruncate > xTrunc( xOutputStream, uno::UNO_QUERY_THROW );
+ xTrunc->truncate();
+
+ ::comphelper::OStorageHelper::CopyInputToOutput( xTempInp, xOutputStream );
+ xOutputStream->flush();
+ xTempSeek->seek( nPos );
+ }
+}
+
+//-------------------------------------------------------------------------
+void OLESimpleStorage::InsertInputStreamToStorage_Impl( BaseStorage* pStorage, ::rtl::OUString aName, const uno::Reference< io::XInputStream >& xInputStream )
+ throw ( uno::Exception )
+{
+ if ( !pStorage || !aName.getLength() || !xInputStream.is() )
+ throw uno::RuntimeException();
+
+ if ( pStorage->IsContained( aName ) )
+ throw container::ElementExistException(); // TODO:
+
+ BaseStorageStream* pNewStream = pStorage->OpenStream( aName );
+ if ( !pNewStream || pNewStream->GetError() || pStorage->GetError() )
+ {
+ if ( pNewStream )
+ DELETEZ( pNewStream );
+ pStorage->ResetError();
+ throw io::IOException(); // TODO
+ }
+
+ try
+ {
+ uno::Sequence< sal_Int8 > aData( nBytesCount );
+ sal_Int32 nRead = 0;
+ do
+ {
+ nRead = xInputStream->readBytes( aData, nBytesCount );
+ if ( nRead < nBytesCount )
+ aData.realloc( nRead );
+
+ sal_Int32 nWritten = pNewStream->Write( aData.getArray(), nRead );
+ if ( nWritten < nRead )
+ throw io::IOException();
+ } while( nRead == nBytesCount );
+ }
+ catch( uno::Exception& )
+ {
+ DELETEZ( pNewStream );
+ pStorage->Remove( aName );
+
+ throw;
+ }
+
+ DELETEZ( pNewStream );
+}
+
+//-------------------------------------------------------------------------
+void OLESimpleStorage::InsertNameAccessToStorage_Impl( BaseStorage* pStorage, ::rtl::OUString aName, const uno::Reference< container::XNameAccess >& xNameAccess )
+ throw ( uno::Exception )
+{
+ if ( !pStorage || !aName.getLength() || !xNameAccess.is() )
+ throw uno::RuntimeException();
+
+ if ( pStorage->IsContained( aName ) )
+ throw container::ElementExistException(); // TODO:
+
+ BaseStorage* pNewStorage = pStorage->OpenStorage( aName );
+ if ( !pNewStorage || pNewStorage->GetError() || pStorage->GetError() )
+ {
+ if ( pNewStorage )
+ DELETEZ( pNewStorage );
+ pStorage->ResetError();
+ throw io::IOException(); // TODO
+ }
+
+ try
+ {
+ uno::Sequence< ::rtl::OUString > aElements = xNameAccess->getElementNames();
+ for ( sal_Int32 nInd = 0; nInd < aElements.getLength(); nInd++ )
+ {
+ uno::Reference< io::XInputStream > xInputStream;
+ uno::Reference< container::XNameAccess > xSubNameAccess;
+ uno::Any aAny = xNameAccess->getByName( aElements[nInd] );
+ if ( aAny >>= xInputStream )
+ InsertInputStreamToStorage_Impl( pNewStorage, aElements[nInd], xInputStream );
+ else if ( aAny >>= xSubNameAccess )
+ InsertNameAccessToStorage_Impl( pNewStorage, aElements[nInd], xSubNameAccess );
+ }
+ }
+ catch( uno::Exception& )
+ {
+ DELETEZ( pNewStorage );
+ pStorage->Remove( aName );
+
+ throw;
+ }
+
+ DELETEZ( pNewStorage );
+}
+
+//____________________________________________________________________________________________________
+// XInitialization
+//____________________________________________________________________________________________________
+
+void SAL_CALL OLESimpleStorage::initialize( const uno::Sequence< uno::Any >& aArguments )
+ throw ( uno::Exception,
+ uno::RuntimeException)
+{
+ if ( m_pStream || m_pStorage )
+ throw io::IOException(); // TODO: already initilized
+
+ sal_Int32 nArgNum = aArguments.getLength();
+ OSL_ENSURE( nArgNum >= 1 && nArgNum <= 2, "Wrong parameter number" );
+
+ if ( nArgNum < 1 || nArgNum > 2 )
+ throw lang::IllegalArgumentException(); // TODO:
+
+ uno::Reference< io::XStream > xStream;
+ uno::Reference< io::XInputStream > xInputStream;
+ if ( !( aArguments[0] >>= xStream ) && !( aArguments[0] >>= xInputStream ) )
+ throw lang::IllegalArgumentException(); // TODO:
+
+ if ( nArgNum == 2 )
+ {
+ if ( !( aArguments[1] >>= m_bNoTemporaryCopy ) )
+ throw lang::IllegalArgumentException(); // TODO:
+ }
+
+ if ( m_bNoTemporaryCopy )
+ {
+ // TODO: ???
+ // If the temporary stream is not created, the original stream must be wrapped
+ // since SvStream wrapper closes the stream is owns
+ if ( xInputStream.is() )
+ {
+ // the stream must be seekable for direct access
+ uno::Reference< io::XSeekable > xSeek( xInputStream, uno::UNO_QUERY_THROW );
+ m_pStream = ::utl::UcbStreamHelper::CreateStream( xInputStream, sal_False );
+ }
+ else if ( xStream.is() )
+ {
+ // the stream must be seekable for direct access
+ uno::Reference< io::XSeekable > xSeek( xStream, uno::UNO_QUERY_THROW );
+ m_pStream = ::utl::UcbStreamHelper::CreateStream( xStream, sal_False );
+ }
+ else
+ throw lang::IllegalArgumentException(); // TODO:
+ }
+ else
+ {
+ uno::Reference < io::XStream > xTempFile(
+ m_xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ),
+ uno::UNO_QUERY_THROW );
+ uno::Reference < io::XSeekable > xTempSeek( xTempFile, uno::UNO_QUERY_THROW );
+ uno::Reference< io::XOutputStream > xTempOut = xTempFile->getOutputStream();
+ if ( !xTempOut.is() )
+ throw uno::RuntimeException();
+
+ if ( xInputStream.is() )
+ {
+ try
+ {
+ uno::Reference< io::XSeekable > xSeek( xInputStream, uno::UNO_QUERY_THROW );
+ xSeek->seek( 0 );
+ }
+ catch( uno::Exception& )
+ {}
+
+ ::comphelper::OStorageHelper::CopyInputToOutput( xInputStream, xTempOut );
+ xTempOut->closeOutput();
+ xTempSeek->seek( 0 );
+ uno::Reference< io::XInputStream > xTempInput = xTempFile->getInputStream();
+ m_pStream = ::utl::UcbStreamHelper::CreateStream( xTempInput, sal_False );
+ }
+ else if ( xStream.is() )
+ {
+ // not sure that the storage flashes the stream on commit
+ m_xStream = xStream;
+ m_xTempStream = xTempFile;
+
+ uno::Reference< io::XSeekable > xSeek( xStream, uno::UNO_QUERY_THROW );
+ xSeek->seek( 0 );
+ uno::Reference< io::XInputStream > xInpStream = xStream->getInputStream();
+ if ( !xInpStream.is() || !xStream->getOutputStream().is() )
+ throw uno::RuntimeException();
+
+ ::comphelper::OStorageHelper::CopyInputToOutput( xInpStream, xTempOut );
+ xTempOut->flush();
+ xTempSeek->seek( 0 );
+
+ m_pStream = ::utl::UcbStreamHelper::CreateStream( xTempFile, sal_False );
+ }
+ else
+ throw lang::IllegalArgumentException(); // TODO:
+ }
+
+ if ( !m_pStream || m_pStream->GetError() )
+ throw io::IOException(); // TODO
+
+ m_pStorage = new Storage( *m_pStream, sal_False );
+}
+
+
+//____________________________________________________________________________________________________
+// XNameContainer
+//____________________________________________________________________________________________________
+
+// --------------------------------------------------------------------------------
+void SAL_CALL OLESimpleStorage::insertByName( const ::rtl::OUString& aName, const uno::Any& aElement )
+ throw ( lang::IllegalArgumentException,
+ container::ElementExistException,
+ lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( m_bDisposed )
+ throw lang::DisposedException();
+
+ if ( !m_pStorage )
+ throw uno::RuntimeException();
+
+ uno::Reference< io::XStream > xStream;
+ uno::Reference< io::XInputStream > xInputStream;
+ uno::Reference< container::XNameAccess > xNameAccess;
+
+ try
+ {
+ if ( !m_bNoTemporaryCopy && !m_xStream.is() )
+ throw io::IOException(); // TODO
+
+ if ( aElement >>= xStream )
+ xInputStream = xStream->getInputStream();
+ else if ( !( aElement >>= xInputStream ) && !( aElement >>= xNameAccess ) )
+ throw lang::IllegalArgumentException(); // TODO:
+
+ if ( xInputStream.is() )
+ InsertInputStreamToStorage_Impl( m_pStorage, aName, xInputStream );
+ else if ( xNameAccess.is() )
+ InsertNameAccessToStorage_Impl( m_pStorage, aName, xNameAccess );
+ else
+ throw uno::RuntimeException();
+ }
+ catch( uno::RuntimeException& )
+ {
+ throw;
+ }
+ catch( container::ElementExistException& )
+ {
+ throw;
+ }
+ catch( uno::Exception& e )
+ {
+ throw lang::WrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Insert has failed!" ) ),
+ uno::Reference< uno::XInterface >(),
+ uno::makeAny( e ) );
+ }
+}
+
+// --------------------------------------------------------------------------------
+void SAL_CALL OLESimpleStorage::removeByName( const ::rtl::OUString& aName )
+ throw ( container::NoSuchElementException,
+ lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( m_bDisposed )
+ throw lang::DisposedException();
+
+ if ( !m_pStorage )
+ throw uno::RuntimeException();
+
+ if ( !m_bNoTemporaryCopy && !m_xStream.is() )
+ throw lang::WrappedTargetException(); // io::IOException(); // TODO
+
+ if ( !m_pStorage->IsContained( aName ) )
+ throw container::NoSuchElementException(); // TODO:
+
+ m_pStorage->Remove( aName );
+
+ if ( m_pStorage->GetError() )
+ {
+ m_pStorage->ResetError();
+ throw lang::WrappedTargetException(); // io::IOException(); // TODO
+ }
+}
+
+// --------------------------------------------------------------------------------
+void SAL_CALL OLESimpleStorage::replaceByName( const ::rtl::OUString& aName, const uno::Any& aElement )
+ throw ( lang::IllegalArgumentException,
+ container::NoSuchElementException,
+ lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( m_bDisposed )
+ throw lang::DisposedException();
+
+ removeByName( aName );
+
+ try
+ {
+ insertByName( aName, aElement );
+ }
+ catch( container::ElementExistException& )
+ {
+ uno::Any aCaught( ::cppu::getCaughtException() );
+
+ throw lang::WrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy raw stream" ),
+ uno::Reference< uno::XInterface >(),
+ aCaught );
+ }
+}
+
+// --------------------------------------------------------------------------------
+uno::Any SAL_CALL OLESimpleStorage::getByName( const ::rtl::OUString& aName )
+ throw ( container::NoSuchElementException,
+ lang::WrappedTargetException,
+ uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( m_bDisposed )
+ throw lang::DisposedException();
+
+ if ( !m_pStorage )
+ throw uno::RuntimeException();
+
+ if ( !m_pStorage->IsContained( aName ) )
+ throw container::NoSuchElementException(); // TODO:
+
+ uno::Any aResult;
+
+ uno::Reference< io::XStream > xTempFile(
+ m_xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ),
+ uno::UNO_QUERY );
+ uno::Reference< io::XSeekable > xSeekable( xTempFile, uno::UNO_QUERY_THROW );
+ uno::Reference< io::XOutputStream > xOutputStream = xTempFile->getOutputStream();
+ uno::Reference< io::XInputStream > xInputStream = xTempFile->getInputStream();
+ if ( !xOutputStream.is() || !xInputStream.is() )
+ throw uno::RuntimeException();
+
+ if ( m_pStorage->IsStorage( aName ) )
+ {
+ BaseStorage* pStrg = m_pStorage->OpenStorage( aName );
+ m_pStorage->ResetError();
+ if ( !pStrg )
+ throw io::IOException();
+
+ SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( xTempFile, sal_False ); // do not close the original stream
+ if ( !pStream )
+ throw uno::RuntimeException();
+
+ BaseStorage* pNewStor = new Storage( *pStream, sal_False );
+ sal_Bool bSuccess =
+ ( pStrg->CopyTo( pNewStor ) && pNewStor->Commit() && !pNewStor->GetError() && !pStrg->GetError() );
+
+ DELETEZ( pNewStor );
+ DELETEZ( pStrg );
+ DELETEZ( pStream );
+
+ if ( !bSuccess )
+ throw uno::RuntimeException();
+
+ uno::Sequence< uno::Any > aArgs( 2 );
+ aArgs[0] <<= xInputStream; // allow readonly access only
+ aArgs[1] <<= (sal_Bool)sal_True; // do not create copy
+
+ uno::Reference< container::XNameContainer > xResultNameContainer(
+ m_xFactory->createInstanceWithArguments(
+ ::rtl::OUString::createFromAscii( "com.sun.star.embed.OLESimpleStorage" ),
+ aArgs ),
+ uno::UNO_QUERY_THROW );
+
+ aResult <<= xResultNameContainer;
+ }
+ else
+ {
+ BaseStorageStream* pStream = m_pStorage->OpenStream( aName, STREAM_READ | STREAM_SHARE_DENYALL | STREAM_NOCREATE );
+ if ( !pStream || pStream->GetError() || m_pStorage->GetError() )
+ {
+ m_pStorage->ResetError();
+ DELETEZ( pStream );
+ throw io::IOException(); // TODO
+ }
+
+ try
+ {
+ uno::Sequence< sal_Int8 > aData( nBytesCount );
+ sal_Int32 nSize = nBytesCount;
+ sal_Int32 nRead = 0;
+ while( 0 != ( nRead = pStream->Read( aData.getArray(), nSize ) ) )
+ {
+ if ( nRead < nSize )
+ {
+ nSize = nRead;
+ aData.realloc( nSize );
+ }
+
+ xOutputStream->writeBytes( aData );
+ }
+
+ if ( pStream->GetError() )
+ throw io::IOException(); // TODO
+
+ xOutputStream->closeOutput();
+ xSeekable->seek( 0 );
+ }
+ catch( uno::RuntimeException& )
+ {
+ DELETEZ( pStream );
+ throw;
+ }
+ catch( uno::Exception& )
+ {
+ DELETEZ( pStream );
+ throw lang::WrappedTargetException(); // TODO:
+ }
+
+ DELETEZ( pStream );
+
+ aResult <<= xInputStream;
+ }
+
+ return aResult;
+}
+
+// --------------------------------------------------------------------------------
+uno::Sequence< ::rtl::OUString > SAL_CALL OLESimpleStorage::getElementNames()
+ throw ( uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( m_bDisposed )
+ throw lang::DisposedException();
+
+ if ( !m_pStorage )
+ throw uno::RuntimeException();
+
+ SvStorageInfoList aList;
+ m_pStorage->FillInfoList( &aList );
+
+ if ( m_pStorage->GetError() )
+ {
+ m_pStorage->ResetError();
+ throw uno::RuntimeException(); // TODO:
+ }
+
+ uno::Sequence< ::rtl::OUString > aSeq( aList.Count() );
+ for ( sal_uInt32 nInd = 0; nInd < aList.Count(); nInd++ )
+ aSeq[nInd] = aList[nInd].GetName();
+
+ return aSeq;
+}
+
+// --------------------------------------------------------------------------------
+sal_Bool SAL_CALL OLESimpleStorage::hasByName( const ::rtl::OUString& aName )
+ throw ( uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( m_bDisposed )
+ throw lang::DisposedException();
+
+ if ( !m_pStorage )
+ throw uno::RuntimeException();
+
+ sal_Bool bResult = m_pStorage->IsContained( aName );
+
+ if ( m_pStorage->GetError() )
+ {
+ m_pStorage->ResetError();
+ throw uno::RuntimeException(); // TODO:
+ }
+
+ return bResult;
+}
+
+// --------------------------------------------------------------------------------
+uno::Type SAL_CALL OLESimpleStorage::getElementType()
+ throw ( uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( m_bDisposed )
+ throw lang::DisposedException();
+
+ return getCppuType( (const uno::Reference< io::XInputStream >*)NULL );
+}
+
+// --------------------------------------------------------------------------------
+sal_Bool SAL_CALL OLESimpleStorage::hasElements()
+ throw ( uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( m_bDisposed )
+ throw lang::DisposedException();
+
+ if ( !m_pStorage )
+ throw uno::RuntimeException();
+
+ SvStorageInfoList aList;
+ m_pStorage->FillInfoList( &aList );
+
+ if ( m_pStorage->GetError() )
+ {
+ m_pStorage->ResetError();
+ throw uno::RuntimeException(); // TODO:
+ }
+
+ return ( aList.Count() != 0 );
+}
+
+//____________________________________________________________________________________________________
+// XComponent
+//____________________________________________________________________________________________________
+
+// --------------------------------------------------------------------------------
+void SAL_CALL OLESimpleStorage::dispose()
+ throw ( uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( m_bDisposed )
+ throw lang::DisposedException();
+
+ if ( m_pListenersContainer )
+ {
+ lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >(this) );
+ m_pListenersContainer->disposeAndClear( aSource );
+ }
+
+ DELETEZ( m_pStorage );
+ DELETEZ( m_pStream );
+
+ m_xStream = uno::Reference< io::XStream >();
+ m_xTempStream = uno::Reference< io::XStream >();
+
+ m_bDisposed = sal_True;
+}
+
+// --------------------------------------------------------------------------------
+void SAL_CALL OLESimpleStorage::addEventListener(
+ const uno::Reference< lang::XEventListener >& xListener )
+ throw ( uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( m_bDisposed )
+ throw lang::DisposedException();
+
+ if ( !m_pListenersContainer )
+ m_pListenersContainer = new ::cppu::OInterfaceContainerHelper( m_aMutex );
+
+ m_pListenersContainer->addInterface( xListener );
+}
+
+// --------------------------------------------------------------------------------
+void SAL_CALL OLESimpleStorage::removeEventListener(
+ const uno::Reference< lang::XEventListener >& xListener )
+ throw ( uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( m_bDisposed )
+ throw lang::DisposedException();
+
+ if ( m_pListenersContainer )
+ m_pListenersContainer->removeInterface( xListener );
+}
+
+//____________________________________________________________________________________________________
+// XTransactedObject
+//____________________________________________________________________________________________________
+
+// --------------------------------------------------------------------------------
+void SAL_CALL OLESimpleStorage::commit()
+ throw ( ::com::sun::star::io::IOException,
+ ::com::sun::star::lang::WrappedTargetException,
+ ::com::sun::star::uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( m_bDisposed )
+ throw lang::DisposedException();
+
+ if ( !m_pStorage )
+ throw uno::RuntimeException();
+
+ if ( !m_bNoTemporaryCopy && !m_xStream.is() )
+ throw io::IOException(); // TODO
+
+ if ( !m_pStorage->Commit() || m_pStorage->GetError() )
+ {
+ m_pStorage->ResetError();
+ throw io::IOException(); // TODO
+ }
+
+ UpdateOriginal_Impl();
+}
+
+// --------------------------------------------------------------------------------
+void SAL_CALL OLESimpleStorage::revert()
+ throw ( ::com::sun::star::io::IOException,
+ ::com::sun::star::lang::WrappedTargetException,
+ ::com::sun::star::uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( m_bDisposed )
+ throw lang::DisposedException();
+
+ if ( !m_pStorage )
+ throw uno::RuntimeException();
+
+ if ( !m_bNoTemporaryCopy && !m_xStream.is() )
+ throw io::IOException(); // TODO
+
+ if ( !m_pStorage->Revert() || m_pStorage->GetError() )
+ {
+ m_pStorage->ResetError();
+ throw io::IOException(); // TODO
+ }
+
+ UpdateOriginal_Impl();
+}
+
+//____________________________________________________________________________________________________
+// XClassifiedObject
+//____________________________________________________________________________________________________
+
+uno::Sequence< sal_Int8 > SAL_CALL OLESimpleStorage::getClassID()
+ throw ( uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( m_bDisposed )
+ throw lang::DisposedException();
+
+ if ( !m_pStorage )
+ throw uno::RuntimeException();
+
+ return m_pStorage->GetClassName().GetByteSequence();
+}
+
+::rtl::OUString SAL_CALL OLESimpleStorage::getClassName()
+ throw ( uno::RuntimeException )
+{
+ return ::rtl::OUString();
+}
+
+void SAL_CALL OLESimpleStorage::setClassInfo( const uno::Sequence< sal_Int8 >& /*aClassID*/,
+ const ::rtl::OUString& /*sClassName*/ )
+ throw ( lang::NoSupportException,
+ uno::RuntimeException )
+{
+ throw lang::NoSupportException();
+}
+
+//____________________________________________________________________________________________________
+// XServiceInfo
+//____________________________________________________________________________________________________
+
+// --------------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OLESimpleStorage::getImplementationName()
+ throw ( uno::RuntimeException )
+{
+ return impl_staticGetImplementationName();
+}
+
+// --------------------------------------------------------------------------------
+::sal_Bool SAL_CALL OLESimpleStorage::supportsService( const ::rtl::OUString& ServiceName )
+ throw ( uno::RuntimeException )
+{
+ uno::Sequence< ::rtl::OUString > aSeq = impl_staticGetSupportedServiceNames();
+
+ for ( sal_Int32 nInd = 0; nInd < aSeq.getLength(); nInd++ )
+ if ( ServiceName.compareTo( aSeq[nInd] ) == 0 )
+ return sal_True;
+
+ return sal_False;
+}
+
+// --------------------------------------------------------------------------------
+uno::Sequence< ::rtl::OUString > SAL_CALL OLESimpleStorage::getSupportedServiceNames()
+ throw ( uno::RuntimeException )
+{
+ return impl_staticGetSupportedServiceNames();
+}
+
+
diff --git a/sot/source/unoolestorage/xolesimplestorage.hxx b/sot/source/unoolestorage/xolesimplestorage.hxx
new file mode 100644
index 000000000000..c9f1b5c68b0a
--- /dev/null
+++ b/sot/source/unoolestorage/xolesimplestorage.hxx
@@ -0,0 +1,195 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef __XOLESIMPLESTORAGE_HXX_
+#define __XOLESIMPLESTORAGE_HXX_
+
+#include <com/sun/star/embed/XOLESimpleStorage.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/embed/XTransactedObject.hpp>
+#include <com/sun/star/embed/XClassifiedObject.hpp>
+
+
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <cppuhelper/implbase3.hxx>
+#include <cppuhelper/interfacecontainer.h>
+
+#include <osl/mutex.hxx>
+
+#include <stg.hxx>
+
+
+class OLESimpleStorage : public ::cppu::WeakImplHelper3
+ < ::com::sun::star::embed::XOLESimpleStorage
+ , ::com::sun::star::lang::XInitialization
+ , ::com::sun::star::lang::XServiceInfo >
+{
+ ::osl::Mutex m_aMutex;
+
+ sal_Bool m_bDisposed;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream > m_xStream;
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream > m_xTempStream;
+ SvStream* m_pStream;
+ BaseStorage* m_pStorage;
+
+ ::cppu::OInterfaceContainerHelper* m_pListenersContainer; // list of listeners
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xFactory;
+
+ sal_Bool m_bNoTemporaryCopy;
+
+ void UpdateOriginal_Impl();
+
+ static void InsertInputStreamToStorage_Impl( BaseStorage* pStorage, ::rtl::OUString aName, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& xInputStream )
+ throw ( ::com::sun::star::uno::Exception );
+
+ static void InsertNameAccessToStorage_Impl( BaseStorage* pStorage, ::rtl::OUString aName, const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& xNameAccess )
+ throw ( ::com::sun::star::uno::Exception );
+
+public:
+
+ OLESimpleStorage( ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xFactory );
+
+ virtual ~OLESimpleStorage();
+
+ static ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL impl_staticGetSupportedServiceNames();
+ static ::rtl::OUString SAL_CALL impl_staticGetImplementationName();
+ static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL
+ impl_staticCreateSelfInstance(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceManager );
+
+
+ //____________________________________________________________________________________________________
+ // XInitialization
+ //____________________________________________________________________________________________________
+
+ virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments )
+ throw ( ::com::sun::star::uno::Exception,
+ ::com::sun::star::uno::RuntimeException);
+
+ //____________________________________________________________________________________________________
+ // XNameContainer
+ //____________________________________________________________________________________________________
+
+ virtual void SAL_CALL insertByName( const ::rtl::OUString& aName, const ::com::sun::star::uno::Any& aElement )
+ throw ( ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::container::ElementExistException,
+ ::com::sun::star::lang::WrappedTargetException,
+ ::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL removeByName( const ::rtl::OUString& Name )
+ throw ( ::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::lang::WrappedTargetException,
+ ::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL replaceByName( const ::rtl::OUString& aName, const ::com::sun::star::uno::Any& aElement )
+ throw ( ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::lang::WrappedTargetException,
+ ::com::sun::star::uno::RuntimeException);
+
+ virtual ::com::sun::star::uno::Any SAL_CALL getByName( const ::rtl::OUString& aName )
+ throw ( ::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::lang::WrappedTargetException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames()
+ throw ( ::com::sun::star::uno::RuntimeException );
+
+ virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName )
+ throw ( ::com::sun::star::uno::RuntimeException );
+
+ virtual ::com::sun::star::uno::Type SAL_CALL getElementType()
+ throw ( ::com::sun::star::uno::RuntimeException );
+
+ virtual sal_Bool SAL_CALL hasElements()
+ throw ( ::com::sun::star::uno::RuntimeException );
+
+ //____________________________________________________________________________________________________
+ // XComponent
+ //____________________________________________________________________________________________________
+
+ virtual void SAL_CALL dispose()
+ throw ( ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL addEventListener(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& xListener )
+ throw ( ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL removeEventListener(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& xListener )
+ throw ( ::com::sun::star::uno::RuntimeException );
+
+ //____________________________________________________________________________________________________
+ // XTransactedObject
+ //____________________________________________________________________________________________________
+
+ virtual void SAL_CALL commit()
+ throw ( ::com::sun::star::io::IOException,
+ ::com::sun::star::lang::WrappedTargetException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL revert()
+ throw ( ::com::sun::star::io::IOException,
+ ::com::sun::star::lang::WrappedTargetException,
+ ::com::sun::star::uno::RuntimeException );
+
+ //____________________________________________________________________________________________________
+ // XClassifiedObject
+ //____________________________________________________________________________________________________
+
+ virtual ::com::sun::star::uno::Sequence< ::sal_Int8 > SAL_CALL getClassID()
+ throw ( ::com::sun::star::uno::RuntimeException );
+
+ virtual ::rtl::OUString SAL_CALL getClassName()
+ throw ( ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL setClassInfo( const ::com::sun::star::uno::Sequence< ::sal_Int8 >& aClassID,
+ const ::rtl::OUString& sClassName )
+ throw ( ::com::sun::star::lang::NoSupportException,
+ ::com::sun::star::uno::RuntimeException );
+
+ //____________________________________________________________________________________________________
+ // XServiceInfo
+ //____________________________________________________________________________________________________
+
+ virtual ::rtl::OUString SAL_CALL getImplementationName()
+ throw ( ::com::sun::star::uno::RuntimeException );
+
+ virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName )
+ throw ( ::com::sun::star::uno::RuntimeException );
+
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames()
+ throw ( ::com::sun::star::uno::RuntimeException );
+
+};
+
+#endif
+
diff --git a/sot/util/makefile.mk b/sot/util/makefile.mk
new file mode 100644
index 000000000000..72d17db189be
--- /dev/null
+++ b/sot/util/makefile.mk
@@ -0,0 +1,89 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..
+
+PRJNAME=sot
+TARGET=sot
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+LIB1TARGET= $(SLB)$/$(TARGET).lib
+.IF "$(GUI)$(COM)"=="WNTGCC"
+LIB1ARCHIV= $(LB)$/lib$(TARGET)$(DLLPOSTFIX)_static.a
+.ELSE
+LIB1ARCHIV= $(LB)$/lib$(TARGET)$(DLLPOSTFIX).a
+.ENDIF
+LIB1FILES= $(SLB)$/base.lib \
+ $(SLB)$/sdstor.lib \
+ $(SLB)$/unoolestorage.lib
+
+SHL1TARGET= $(TARGET)$(DLLPOSTFIX)
+SHL1IMPLIB= $(TARGET)
+SHL1USE_EXPORTS=name
+SHL1LIBS= $(SLB)$/$(TARGET).lib
+
+SHL1STDLIBS=$(TOOLSLIB) $(SALLIB) $(UNOTOOLSLIB) $(CPPUHELPERLIB) $(COMPHELPERLIB) $(UCBHELPERLIB) $(CPPULIB)
+
+SHL1DEF= $(MISC)$/$(SHL1TARGET).def
+
+DEF1NAME =$(SHL1TARGET)
+DEF1DEPN =$(MISC)$/$(SHL1TARGET).flt \
+ $(PRJ)$/inc$/absdev.hxx \
+ $(PRJ)$/inc$/agg.hxx \
+ $(PRJ)$/inc$/sot$/exchange.hxx \
+ $(PRJ)$/inc$/sot$/factory.hxx \
+ $(PRJ)$/inc$/sot$/object.hxx \
+ $(PRJ)$/inc$/sot$/sotdata.hxx \
+ $(PRJ)$/inc$/sot$/sotref.hxx \
+ $(PRJ)$/inc$/stg.hxx \
+ $(PRJ)$/inc$/sot$/storage.hxx \
+ $(PRJ)$/inc$/storinfo.hxx
+DEFLIB1NAME =$(TARGET)
+DEF1DES =StarObjectsTools
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
+$(MISC)$/$(SHL1TARGET).flt: makefile.mk
+ @echo ------------------------------
+ @echo Making: $@
+ $(TYPE) sot.flt > $@
+
+
+ALLTAR : $(MISC)/sot.component
+
+$(MISC)/sot.component .ERRREMOVE : $(SOLARENV)/bin/createcomponent.xslt \
+ sot.component
+ $(XSLTPROC) --nonet --stringparam uri \
+ '$(COMPONENTPREFIX_BASIS_NATIVE)$(SHL1TARGETN:f)' -o $@ \
+ $(SOLARENV)/bin/createcomponent.xslt sot.component
diff --git a/sot/util/makefile.pmk b/sot/util/makefile.pmk
new file mode 100644
index 000000000000..2d79b8068815
--- /dev/null
+++ b/sot/util/makefile.pmk
@@ -0,0 +1,31 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+# define SOT_DLLIMPLEMENTATION (see @ = sotdllapi.h)
+CDEFS += -DSOT_DLLIMPLEMENTATION
+
+VISIBILITY_HIDDEN=TRUE
diff --git a/sot/util/sot.component b/sot/util/sot.component
new file mode 100644
index 000000000000..7d17c7d54475
--- /dev/null
+++ b/sot/util/sot.component
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--**********************************************************************
+*
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* Copyright 2000, 2010 Oracle and/or its affiliates.
+*
+* OpenOffice.org - a multi-platform office productivity suite
+*
+* This file is part of OpenOffice.org.
+*
+* OpenOffice.org is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License version 3
+* only, as published by the Free Software Foundation.
+*
+* OpenOffice.org 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 version 3 for more details
+* (a copy is included in the LICENSE file that accompanied this code).
+*
+* You should have received a copy of the GNU Lesser General Public License
+* version 3 along with OpenOffice.org. If not, see
+* <http://www.openoffice.org/license.html>
+* for a copy of the LGPLv3 License.
+*
+**********************************************************************-->
+
+<component loader="com.sun.star.loader.SharedLibrary"
+ xmlns="http://openoffice.org/2010/uno-components">
+ <implementation name="com.sun.star.comp.embed.OLESimpleStorage">
+ <service name="com.sun.star.embed.OLESimpleStorage"/>
+ </implementation>
+</component>
diff --git a/sot/util/sot.flt b/sot/util/sot.flt
new file mode 100644
index 000000000000..ac2ea9c6a19d
--- /dev/null
+++ b/sot/util/sot.flt
@@ -0,0 +1,6 @@
+WEP
+LIBMAIN
+LibMain
+CT??_R0?AV
+CTA2?AV
+CTA3?AV
diff --git a/sot/workben/makefile.mk b/sot/workben/makefile.mk
new file mode 100644
index 000000000000..c1c8a8d0a2ca
--- /dev/null
+++ b/sot/workben/makefile.mk
@@ -0,0 +1,53 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org 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 version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..
+
+PRJNAME=sot
+TARGET=workben
+LIBTARGET=NO
+TARGETTYPE=CUI
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+OBJFILES= \
+ $(OBJ)$/testsot.obj
+
+APP1TARGET= testsot
+APP1OBJS= $(OBJ)$/testsot.obj
+APP1STDLIBS=$(SOTLIB) \
+ $(TOOLSLIB)
+
+APP1DEF= $(MISC)$/$(APP1TARGET).def
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/sot/workben/testsot.cxx b/sot/workben/testsot.cxx
new file mode 100644
index 000000000000..0bdc3113870f
--- /dev/null
+++ b/sot/workben/testsot.cxx
@@ -0,0 +1,55 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sot.hxx"
+
+#include <sot/storage.hxx>
+
+/*
+ * main.
+ */
+int main (int argc, sal_Char **argv)
+{
+ SotStorageRef xStor = new SotStorage( "c:\\temp\\65254.ppt" );
+/*
+ SotStorageRef xStor = new SotStorage( "c:\\temp\\video.sdb" );
+ SotStorageRef xStor = new SotStorage( "c:\\temp\\video.sdb" );
+ SotStorageRef x2Stor = xStor->OpenSotStorage( "1117" );
+
+ SotStorageStreamRef xStm = x2Stor->OpenSotStream( "Genres", STREAM_STD_READWRITE | STREAM_TRUNC);
+ //BYTE szData[100];
+ //xStm->Write( szData, 100 );
+ UINT32 nSize = xStm->GetSize();
+ xStm->SetSize( 0 );
+ nSize = xStm->GetSize();
+ x2Stor->Commit();
+ xStor->Commit();
+*/
+ return 0;
+}
+