summaryrefslogtreecommitdiff
path: root/sot/source
diff options
context:
space:
mode:
authorJens-Heiner Rechtien <hr@openoffice.org>2000-09-18 16:07:07 +0000
committerJens-Heiner Rechtien <hr@openoffice.org>2000-09-18 16:07:07 +0000
commit8ab086b6cc054501bfbf7ef6fa509c393691e860 (patch)
tree324d51845d7f1a2f4e02a14db22fb5947137c822 /sot/source
parent411e68cc54ae97eebd79ae3a9cb2971b74cb2a9e (diff)
initial import
Diffstat (limited to 'sot/source')
-rw-r--r--sot/source/base/exchange.cxx295
-rw-r--r--sot/source/base/factory.cxx442
-rw-r--r--sot/source/base/filelist.cxx302
-rw-r--r--sot/source/base/formats.cxx1835
-rw-r--r--sot/source/base/makefile.mk109
-rw-r--r--sot/source/base/object.cxx510
-rw-r--r--sot/source/sdstor/makefile.mk114
-rw-r--r--sot/source/sdstor/sdintern.hdb22
-rw-r--r--sot/source/sdstor/stg.cxx925
-rw-r--r--sot/source/sdstor/stgavl.cxx451
-rw-r--r--sot/source/sdstor/stgavl.hxx113
-rw-r--r--sot/source/sdstor/stgcache.cxx535
-rw-r--r--sot/source/sdstor/stgcache.hxx164
-rw-r--r--sot/source/sdstor/stgdir.cxx1032
-rw-r--r--sot/source/sdstor/stgdir.hxx170
-rw-r--r--sot/source/sdstor/stgelem.cxx433
-rw-r--r--sot/source/sdstor/stgelem.hxx204
-rw-r--r--sot/source/sdstor/stgio.cxx416
-rw-r--r--sot/source/sdstor/stgio.hxx121
-rw-r--r--sot/source/sdstor/stgole.cxx255
-rw-r--r--sot/source/sdstor/stgole.hxx111
-rw-r--r--sot/source/sdstor/stgstrms.cxx1268
-rw-r--r--sot/source/sdstor/stgstrms.hxx201
-rw-r--r--sot/source/sdstor/storage.cxx948
-rw-r--r--sot/source/sdstor/storinfo.cxx143
25 files changed, 11119 insertions, 0 deletions
diff --git a/sot/source/base/exchange.cxx b/sot/source/base/exchange.cxx
new file mode 100644
index 000000000000..f7e450c33afe
--- /dev/null
+++ b/sot/source/base/exchange.cxx
@@ -0,0 +1,295 @@
+/*************************************************************************
+ *
+ * $RCSfile: exchange.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:56:51 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#define _SOT_EXCHANGE_CXX
+#define SOT_STRING_LIST
+#define _SOT_FORMATS_INCLUDE_SYSTEMFORMATS
+
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#ifndef _SOLAR_H
+#include <tools/solar.h>
+#endif
+
+#include <tools/string.hxx>
+#include <sotdata.hxx>
+#include <exchange.hxx>
+#include <formats.hxx>
+
+#pragma hdrstop
+
+/*
+ In dieser Tabelle stehen alle im Office verwendeten Format-Bezeichner.
+ 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.
+*/
+
+static const sal_Char* aFormatArray_Impl[] =
+{
+/* 0 SOT_FORMAT_SYSTEM_START*/ "",
+/* 1 SOT_FORMAT_STRING*/ "Text",
+/* 2 SOT_FORMAT_BITMAP*/ "Bitmap",
+/* 3 SOT_FORMAT_GDIMETAFILE*/ "GDIMetaFile",
+/* 4 SOT_FORMAT_PRIVATE*/ "Private",
+/* 5 SOT_FORMAT_FILE*/ "FileName",
+/* 6 SOT_FORMAT_FILE_LIST*/ "FileList",
+/* 7 EMPTY*/ "",
+/* 8 EMPTY*/ "",
+/* 9 EMPTY*/ "",
+/* 10 SOT_FORMAT_RTF*/ "Rich Text Format",
+
+/* 11 SOT_FORMATSTR_ID_DRAWING*/ "StarOffice Drawing Format",
+/* 12 SOT_FORMATSTR_ID_SVXB*/ "SVXB (StarView Bitmap/Animation)",
+/* 13 SOT_FORMATSTR_ID_SVIM*/ "SVIM (StarView ImageMap)",
+/* 14 SOT_FORMATSTR_ID_XFA*/ "XFA (XOutDev FillAttr)",
+/* 15 SOT_FORMATSTR_ID_EDITENGINE*/ "EditEngineFormat",
+/* 16 SOT_FORMATSTR_ID_INTERNALLINK_STATE*/ "StatusInfo vom SvxInternalLink",
+/* 17 SOT_FORMATSTR_ID_SOLK*/ "SOLK (StarOffice Link)",
+/* 18 SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK*/ "Netscape Bookmark",
+/* 19 SOT_FORMATSTR_ID_TREELISTBOX*/ "SV_LBOX_DD_FORMAT",
+/* 20 SOT_FORMATSTR_ID_NATIVE*/ "Native",
+/* 21 SOT_FORMATSTR_ID_OWNERLINK*/ "OwnerLink",
+/* 22 SOT_FORMATSTR_ID_STARSERVER*/ "StarServerFormat",
+/* 23 SOT_FORMATSTR_ID_STAROBJECT*/ "StarObjectFormat",
+/* 24 SOT_FORMATSTR_ID_APPLETOBJECT*/ "Applet Object",
+/* 25 SOT_FORMATSTR_ID_PLUGIN_OBJECT*/ "PlugIn Object",
+/* 26 SOT_FORMATSTR_ID_STARWRITER_30*/ "StarWriter 3.0",
+/* 27 SOT_FORMATSTR_ID_STARWRITER_40*/ "StarWriter 4.0",
+/* 28 SOT_FORMATSTR_ID_STARWRITER_50*/ "StarWriter 5.0",
+/* 29 SOT_FORMATSTR_ID_STARWRITERWEB_40*/ "StarWriter/Web 4.0",
+/* 30 SOT_FORMATSTR_ID_STARWRITERWEB_50*/ "StarWriter/Web 5.0",
+/* 31 SOT_FORMATSTR_ID_STARWRITERGLOB_40*/ "StarWriter/Global 4.0",
+/* 32 SOT_FORMATSTR_ID_STARWRITERGLOB_50*/ "StarWriter/Global 5.0",
+/* 33 SOT_FORMATSTR_ID_STARDRAW*/ "StarDrawDocument",
+/* 34 SOT_FORMATSTR_ID_STARDRAW_40*/ "StarDrawDocument 4.0",
+/* 35 SOT_FORMATSTR_ID_STARIMPRESS_50*/ "StarImpress 5.0",
+/* 36 SOT_FORMATSTR_ID_STARDRAW_50*/ "StarDraw 5.0",
+/* 37 SOT_FORMATSTR_ID_STARCALC*/ "StarCalcDocument",
+/* 38 SOT_FORMATSTR_ID_STARCALC_40*/ "StarCalc 4.0",
+/* 39 SOT_FORMATSTR_ID_STARCALC_50*/ "StarCalc 5.0",
+/* 40 SOT_FORMATSTR_ID_STARCHART*/ "StarChartDocument",
+/* 41 SOT_FORMATSTR_ID_STARCHART_40*/ "StarChartDocument 4.0",
+/* 42 SOT_FORMATSTR_ID_STARCHART_50*/ "StarChart 5.0",
+/* 43 SOT_FORMATSTR_ID_STARIMAGE*/ "StarImageDocument",
+/* 44 SOT_FORMATSTR_ID_STARIMAGE_40*/ "StarImageDocument 4.0",
+/* 45 SOT_FORMATSTR_ID_STARIMAGE_50*/ "StarImage 5.0",
+/* 46 SOT_FORMATSTR_ID_STARMATH*/ "StarMath",
+/* 47 SOT_FORMATSTR_ID_STARMATH_40*/ "StarMathDocument 4.0",
+/* 48 SOT_FORMATSTR_ID_STARMATH_50*/ "StarMath 5.0",
+/* 49 SOT_FORMATSTR_ID_STAROBJECT_PAINTDOC*/ "StarObjectPaintDocument",
+/* 50 SOT_FORMATSTR_ID_FILLED_AREA*/ "FilledArea",
+/* 51 SOT_FORMATSTR_ID_HTML*/ "HTML (HyperText Markup Language)",
+/* 52 SOT_FORMATSTR_ID_HTML_SIMPLE*/ "HTML Format",
+/* 53 SOT_FORMATSTR_ID_CHAOS*/ "FORMAT_CHAOS",
+/* 54 SOT_FORMATSTR_ID_CNT_MSGATTACHFILE*/ "CNT_MSGATTACHFILE_FORMAT",
+/* 55 SOT_FORMATSTR_ID_BIFF_5*/ "Biff5",
+/* 56 SOT_FORMATSTR_ID_BIFF__5*/ "Biff 5",
+/* 57 SOT_FORMATSTR_ID_SYLK*/ "Sylk",
+/* 58 SOT_FORMATSTR_ID_SYLK_BIGCAPS*/ "SYLK",
+/* 59 SOT_FORMATSTR_ID_LINK*/ "Link",
+/* 60 SOT_FORMATSTR_ID_DIF*/ "DIF",
+/* 61 SOT_FORMATSTR_ID_STARDRAW_TABBAR*/ "StarDraw TabBar",
+/* 62 SOT_FORMATSTR_ID_SONLK*/ "SONLK (StarOffice Navi Link)",
+/* 63 SOT_FORMATSTR_ID_MSWORD_DOC*/ "MSWordDoc",
+/* 64 SOT_FORMATSTR_ID_STAR_FRAMESET_DOC*/ "StarFrameSetDocument",
+/* 65 SOT_FORMATSTR_ID_OFFICE_DOC*/ "OfficeDocument",
+/* 66 SOT_FORMATSTR_ID_NOTES_DOCINFO*/ "NotesDocInfo",
+/* 67 SOT_FORMATSTR_ID_NOTES_HNOTE*/ "NoteshNote",
+/* 68 SOT_FORMATSTR_ID_NOTES_NATIVE*/ "Native",
+/* 69 SOT_FORMATSTR_ID_SFX_DOC*/ "SfxDocument",
+/* 70 SOT_FORMATSTR_ID_EVDF*/ "EVDF (Explorer View Dummy Format)",
+/* 71 SOT_FORMATSTR_ID_ESDF*/ "ESDF (Explorer Search Dummy Format)",
+/* 72 SOT_FORMATSTR_ID_IDF*/ "IDF (Iconview Dummy Format)",
+/* 73 SOT_FORMATSTR_ID_EFTP*/ "EFTP (Explorer Ftp File)",
+/* 74 SOT_FORMATSTR_ID_EFD*/ "EFD (Explorer Ftp Dir)",
+/* 75 SOT_FORMATSTR_ID_SVX_FORMFIELDEXCH*/ "SvxFormFieldExch",
+/* 76 SOT_FORMATSTR_ID_EXTENDED_TABBAR*/ "ExtendedTabBar",
+/* 77 SOT_FORMATSTR_ID_SBA_DATAEXCHANGE*/ "SBA-DATAFORMAT",
+/* 78 SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE*/ "SBA-FIELDFORMAT",
+/* 79 SOT_FORMATSTR_ID_SBA_PRIVATE_URL*/ "SBA-PRIVATEURLFORMAT",
+/* 80 SOT_FORMATSTR_ID_SBA_TABED*/ "Tabed",
+/* 81 SOT_FORMATSTR_ID_SBA_TABID*/ "Tabid",
+/* 82 SOT_FORMATSTR_ID_SBA_JOIN*/ "SBA-JOINFORMAT",
+
+#ifdef MAC
+/* 83 SOT_FORMATSTR_ID_OBJECTDESCRIPTOR*/ "Star OBJD",
+/* 84 SOT_FORMATSTR_ID_LINKSRCDESCRIPTOR*/ "Star LKSD",
+/* 85 SOT_FORMATSTR_ID_EMBED_SOURCE*/ "Star EMBS",
+/* 86 SOT_FORMATSTR_ID_LINK_SOURCE*/ "Star LNKS",
+/* 87 SOT_FORMATSTR_ID_EMBEDDED_OBJ*/ "Star EMBO",
+#else
+/* 83 SOT_FORMATSTR_ID_OBJECTDESCRIPTOR*/ "Star Object Descriptor",
+/* 84 SOT_FORMATSTR_ID_LINKSRCDESCRIPTOR*/ "Star Link Source Descriptor",
+/* 85 SOT_FORMATSTR_ID_EMBED_SOURCE*/ "Star Embed Source",
+/* 86 SOT_FORMATSTR_ID_LINK_SOURCE*/ "Star Link Source",
+/* 87 SOT_FORMATSTR_ID_EMBEDDED_OBJ*/ "Star Embedded Object",
+#endif
+
+#ifdef WNT
+/* 88 SOT_FORMATSTR_ID_FILECONTENT*/ CFSTR_FILECONTENTS,
+/* 89 SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR*/ CFSTR_FILEDESCRIPTOR,
+/* 90 SOT_FORMATSTR_ID_FILENAME*/ CFSTR_FILENAME,
+#else
+/* 88 SOT_FORMATSTR_ID_FILECONTENT*/ "FileContents",
+/* 89 SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR*/ "FileGroupDescriptor",
+/* 90 SOT_FORMATSTR_ID_FILENAME*/ "FileName",
+#endif
+
+/* 91 SOT_FORMATSTR_ID_SD_OLE*/ "SD-OLE",
+/* 92 SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE*/ "Embedded Object",
+/* 93 SOT_FORMATSTR_ID_EMBED_SOURCE_OLE*/ "Embed Source",
+/* 94 SOT_FORMATSTR_ID_OBJECTDESCRIPTOR_OLE*/ "Object Descriptor",
+/* 95 SOT_FORMATSTR_ID_LINKSRCDESCRIPTOR_OLE*/ "Link Source Descriptor",
+/* 96 SOT_FORMATSTR_ID_LINK_SOURCE_OLE*/ "Link Source",
+
+/* 97 SOT_FORMATSTR_ID_SBA_CTRLDATAEXCHANGE*/ "SBA-CTRLFORMAT",
+/* 98 SOT_FORMATSTR_ID_OUTPLACE_OBJ*/ "OutPlace Object",
+/* 99 SOT_FORMATSTR_ID_CNT_OWN_CLIP*/ "CntOwnClipboard",
+/*100 SOT_FORMATSTR_ID_INET_IMAGE*/ "SO-INet-Image",
+/*101 SOT_FORMATSTR_ID_NETSCAPE_IMAGE*/ "Netscape Image Format",
+/*102 SOT_FORMATSTR_ID_SBA_FORMEXCHANGE*/ "SBA_FORMEXCHANGE",
+/*103 SOT_FORMATSTR_ID_SBA_REPORTEXCHANGE*/ "SBA_REPORTEXCHANGE",
+/*104 SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR*/ "UniformResourceLocator",
+
+/*105 SOT_FORMATSTR_ID_STARCHARTDOCUMENT_50*/"StarChartDocument 5.0",
+/*106 SOT_FORMATSTR_ID_GRAPHOBJ*/ "Graphic Object",
+/*107 SOT_FORMATSTR_ID_DUMMY3*/ "SO_DUMMYFORMAT_3",
+/*108 SOT_FORMATSTR_ID_DUMMY4*/ "SO_DUMMYFORMAT_4"
+};
+
+
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+static StringList & Init_Impl()
+{
+ SotData_Impl * pSotData = SOTDATA();
+ if( !pSotData->pAtomList )
+ StringList * pSL = pSotData->pAtomList = new StringList();
+ return *pSotData->pAtomList;
+}
+
+/*************************************************************************
+|*
+|* SotExchange::RegisterFormatName()
+|*
+|* Beschreibung CLIP.SDW
+*************************************************************************/
+ULONG SotExchange::RegisterFormatName( const String& rName )
+{
+ // 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( *(aFormatArray_Impl + i ) ) )
+ return i;
+
+ nMax = SOT_FORMATSTR_ID_USER_END;
+ for( i = SOT_FORMAT_RTF; i <= nMax; ++i )
+ if( COMPARE_EQUAL == rName.CompareToAscii( *(aFormatArray_Impl + i ) ) )
+ return i;
+
+ // dann in der dynamischen Liste
+ StringList & rSL = Init_Impl();
+ nMax = rSL.Count();
+ for( i = 0; i < nMax; i++ )
+ {
+ String * pStr = rSL.GetObject( i );
+ if( pStr && *pStr == rName )
+ return i + SOT_FORMATSTR_ID_USER_END + 1;
+ }
+ // nMax ist der neue Platz
+ rSL.Insert( new String( rName ), LIST_APPEND );
+ return nMax + SOT_FORMATSTR_ID_USER_END + 1;
+}
+
+/*************************************************************************
+|*
+|* SotExchange::GetFormatName()
+|*
+|* Beschreibung CLIP.SDW
+*************************************************************************/
+String SotExchange::GetFormatName( ULONG nFormat )
+{
+ String sRet;
+ if( SOT_FORMATSTR_ID_USER_END >= nFormat )
+ sRet.AppendAscii( *( aFormatArray_Impl + nFormat ) );
+ else
+ {
+ nFormat -= SOT_FORMATSTR_ID_USER_END + 1;
+ StringList & rSL = Init_Impl();
+ String* pStr;
+ if( rSL.Count() > nFormat && (pStr = rSL.GetObject( nFormat )) )
+ sRet = *pStr;
+ }
+ return sRet;
+}
+
+/*************************************************************************
+|*
+|* SotExchange::GetMaxFormat()
+|*
+*************************************************************************/
+ULONG SotExchange::GetMaxFormat( void )
+{
+ StringList & rSL = Init_Impl();
+ return SOT_FORMATSTR_ID_USER_END + rSL.Count();
+}
+
diff --git a/sot/source/base/factory.cxx b/sot/source/base/factory.cxx
new file mode 100644
index 000000000000..a1bf66d83e28
--- /dev/null
+++ b/sot/source/base/factory.cxx
@@ -0,0 +1,442 @@
+/*************************************************************************
+ *
+ * $RCSfile: factory.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:56:51 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SOT_FACTORY_CXX
+#define SOT_STRING_LIST
+
+#include <factory.hxx>
+#include <tools/debug.hxx>
+#include <tools/string.hxx>
+#include <object.hxx>
+#include <dtrans.hxx>
+#include <sotdata.hxx>
+#pragma hdrstop
+
+/************** class SotData_Impl *********************************************/
+/*************************************************************************
+|* SotData_Impl::SotData_Impl
+|*
+|* Beschreibung
+*************************************************************************/
+SotData_Impl::SotData_Impl()
+ : nSvObjCount( 0 )
+ , pObjectList( NULL )
+ , pFactoryList( NULL )
+ , pSotObjectFactory( NULL )
+ , pSotStorageStreamFactory( NULL )
+ , pSotStorageFactory( NULL )
+ , pSotDataObjectFactory( NULL )
+ , pEmptyList( NULL )
+ , pSotDataMemberObjectFactory( NULL )
+ , pAtomList( NULL )
+{
+}
+
+/*************************************************************************
+|* SOTDATA()
+|*
+|* Beschreibung
+*************************************************************************/
+static SotData_Impl aData;
+SotData_Impl * SOTDATA()
+{
+ return &aData;
+}
+
+/*************************************************************************
+|* 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;
+ delete pSotData->pEmptyList;
+ pSotData->pEmptyList = NULL;
+ if( pSotData->pAtomList )
+ {
+
+ ULONG nMax = pSotData->pAtomList->Count();
+ for( ULONG i = 0; i < nMax; i++ )
+ delete pSotData->pAtomList->GetObject( i );
+ delete pSotData->pAtomList;
+ pSotData->pAtomList = NULL;
+ }
+ //delete pSOTDATA();
+ //SOTDATA() = NULL;
+}
+
+
+/************** class SotFactory *****************************************/
+/*************************************************************************
+|* SotFactory::SotFactory()
+|*
+|* Beschreibung
+*************************************************************************/
+TYPEINIT0(SotFactory);
+
+SotFactory::SotFactory( const SvGlobalName & rName,
+ const String & rClassName,
+ CreateInstanceType pCreateFuncP )
+ : SvGlobalName ( rName )
+ , pCreateFunc ( pCreateFuncP )
+ , aClassName ( rClassName )
+ , nSuperCount ( 0 )
+ , pSuperClasses ( NULL )
+{
+#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 (void*)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 NULL;
+}
+
+/*************************************************************************
+|* 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 (void *)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..50cf320bc05b
--- /dev/null
+++ b/sot/source/base/filelist.cxx
@@ -0,0 +1,302 @@
+/*************************************************************************
+ *
+ * $RCSfile: filelist.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:56:51 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+
+
+#include<tools/list.hxx>
+#include<tools/stream.hxx>
+#include<tools/string.hxx>
+#include<tools/rtti.hxx>
+#include<exchange.hxx>
+#include<filelist.hxx>
+#pragma hdrstop
+
+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
+|*
+\******************************************************************************/
+
+// Windows-Struktur nachdefinieren
+// Typen entsprechend der Groesse der Original-Typen gewaehlt
+// In den Kommentaren sind jeweils die Original-Typen angegeben.
+// Hier werden immer die 32-Bit-Varianten der Typen gewaehlt, um
+// eine einheitliche Struktur fuer alle Plattformen zu erhalten.
+// Diese Struktor ist zwar nicht Win16-kompatibel, dort kann aber
+// die Struktur auch nicht direkt per Drag&Drop uebertragen werden.
+struct Sv_DROPFILES
+{
+ /*DWORD = unsigned long*/ UINT32 pFiles; // offset of file list
+ /*POINT = { long, long }*/ INT32 pt_x; // drop point
+ INT32 pt_y;
+ /*BOOL = int*/ INT32 fNC;
+ /*BOOL = int*/ INT32 fWide; // wide character-flag
+
+ // Konstruktor
+ Sv_DROPFILES( void )
+ {
+ pFiles = 20; // 5 x 4 Bytes, sizeof gefaehrlich wegen alignment
+ pt_x = 0L;
+ pt_y = 0L;
+ fNC = FALSE;
+ fWide = FALSE; // NOTE: Unicode not allowed for Windows 95 !!
+ }
+
+};
+
+// Stream-Operatoren fuer Sv_DROPFILES
+SvStream& operator<<( SvStream& rOStm, const Sv_DROPFILES& r )
+{
+ rOStm << r.pFiles << r.pt_x << r.pt_y << r.fNC << r.fWide;
+ return rOStm;
+}
+SvStream& operator>>( SvStream& rIStm, Sv_DROPFILES& r )
+{
+ rIStm >> r.pFiles >> r.pt_x >> r.pt_y >> r.fNC >> r.fWide;
+ return rIStm;
+}
+
+/*
+ * NOTE: to correctly handle this Protocol with Unicode, native Win32 must be called:
+ * e.g. DropQueryFile
+ */
+
+SvStream& operator<<( SvStream& rOStm, const FileList& rFileList )
+{
+ // Windows-kompatible Struktur anlegen und streamen
+ Sv_DROPFILES aSv_DROPFILES;
+ rOStm << aSv_DROPFILES;
+
+ // String-Liste anhaengen
+ ULONG nCount = rFileList.pStrList->Count();
+ for( ULONG i = 0 ; i < nCount ; i++ )
+ {
+ String* pStr = rFileList.pStrList->GetObject( i );
+// rOStm << pStr->GetBuffer();
+ rOStm << "invalid.txt"; //
+
+ // Noch eine 0 anhaengen
+ rOStm << (char)0;
+ }
+ // Noch eine 0 anhaengen
+ rOStm << (char)0;
+
+ return rOStm;
+}
+
+SvStream& operator>>( SvStream& rIStm, FileList& rFileList )
+{
+ // Windows-kompatible Struktur anlegen und aus Stream lesen
+ Sv_DROPFILES aSv_DROPFILES;
+ rIStm >> aSv_DROPFILES;
+
+ // Bestehende Liste loeschen und neue anlegen
+ rFileList.ClearAll();
+ rFileList.pStrList = new FileStringList();
+
+ // String-Liste aufbauen
+ ByteString aStr;
+ char c, cLast;
+
+ // 1. Zeichen lesen
+ rIStm >> c;
+ do
+ {
+ aStr = ByteString();
+
+ // String bis '\0' lesen
+ do
+ {
+ if( c )
+ aStr += c;
+ cLast = c; // Zeichen merken
+
+ // Bei Unicode eins mehr weg
+ if( aSv_DROPFILES.fWide )
+ rIStm >> c;
+
+ rIStm >> c;
+ }
+ while( cLast );
+
+ // String in die Liste stopfen
+ rFileList.AppendFile( String(aStr, RTL_TEXTENCODING_ASCII_US));
+ }
+ while( c ); // c == 0 && cLast == 0 -> Ende
+
+ 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..ca610ef449e4
--- /dev/null
+++ b/sot/source/base/formats.cxx
@@ -0,0 +1,1835 @@
+/*************************************************************************
+ *
+ * $RCSfile: formats.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:56:51 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SOT_FORMATS_INCLUDE_SYSTEMFORMATS
+
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#ifndef _SOLAR_H
+#include <tools/solar.h>
+#endif
+
+#pragma hdrstop
+
+#include "exchange.hxx"
+#include "formats.hxx"
+#include "dtrans.hxx"
+#include "filelist.hxx"
+
+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 } \
+ };
+
+/* */
+#define EXCHG_DEST_FTP_BOX_ARRAY \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_FTP_BOX_Def[] = \
+ { \
+ { SOT_FORMAT_FILE_LIST, EXCHG_IN_ACTION_COPY, 0 }, \
+ { 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 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_FTP_BOX_Copy[] = \
+ { \
+ { SOT_FORMAT_FILE_LIST, EXCHG_OUT_ACTION_COPY_FILE, 0 }, \
+ { SOT_FORMAT_FILE, EXCHG_OUT_ACTION_COPY_FILE, 0 }, \
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_OUT_ACTION_COPY_FILE, 0 }, \
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_OUT_ACTION_COPY_FILE, FILEGRPDSC_ONLY_URL }, \
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_OUT_ACTION_COPY_FILE, 0 },\
+ { 0xffff } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_FTP_BOX_Link[] = \
+ { \
+ { SOT_FORMAT_FILE_LIST, EXCHG_OUT_ACTION_COPY_FILE, 0 }, \
+ { SOT_FORMAT_FILE, EXCHG_OUT_ACTION_COPY_FILE, 0 }, \
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_OUT_ACTION_COPY_FILE, 0 }, \
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_OUT_ACTION_COPY_FILE, FILEGRPDSC_ONLY_URL }, \
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_OUT_ACTION_COPY_FILE, 0 },\
+ { 0xffff } \
+ };
+
+/* */
+#define EXCHG_DEST_FTP_FLD_ARRAY \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_FTP_FLD_Def[] = \
+ { \
+ { SOT_FORMATSTR_ID_CNT_MSGATTACHFILE, 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_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 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_FTP_FLD_Move[] = \
+ { \
+ { SOT_FORMATSTR_ID_CHAOS, EXCHG_OUT_ACTION_MOVE_CHAOSOBJ, 0 }, \
+ { SOT_FORMAT_FILE_LIST, EXCHG_OUT_ACTION_MOVE_FILE, 0 }, \
+ { SOT_FORMAT_FILE, EXCHG_OUT_ACTION_MOVE_FILE, 0 }, \
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_OUT_ACTION_MOVE_FILE, 0 }, \
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_OUT_ACTION_MOVE_FILE, FILEGRPDSC_ONLY_URL }, \
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_OUT_ACTION_MOVE_FILE, 0 }, \
+ { 0xffff } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_FTP_FLD_Copy[] = \
+ { \
+ { SOT_FORMATSTR_ID_CNT_MSGATTACHFILE, EXCHG_OUT_ACTION_COPY_MSGATTACH, 0 },\
+ { SOT_FORMATSTR_ID_CHAOS, EXCHG_OUT_ACTION_COPY_CHAOSOBJ, 0 }, \
+ { SOT_FORMAT_FILE_LIST, EXCHG_OUT_ACTION_COPY_FILE, 0 }, \
+ { SOT_FORMAT_FILE, EXCHG_OUT_ACTION_COPY_FILE, 0 }, \
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_OUT_ACTION_COPY_FILE, 0 }, \
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_OUT_ACTION_COPY_FILE, FILEGRPDSC_ONLY_URL }, \
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_OUT_ACTION_COPY_FILE, 0 }, \
+ { 0xffff } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_FTP_FLD_Link[] = \
+ { \
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_OUT_ACTION_COPY_FILE, 0 }, \
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_OUT_ACTION_COPY_FILE, FILEGRPDSC_ONLY_URL }, \
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_OUT_ACTION_COPY_FILE, 0 }, \
+ { 0xffff } \
+ };
+
+/* */
+#define EXCHG_DEST_FSYS_FLD_ARRAY \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_FSYS_FLD_Def[] = \
+ { \
+ { SOT_FORMAT_FILE, EXCHG_IN_ACTION_MOVE, 0 }, \
+ { SOT_FORMATSTR_ID_CHAOS, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_SOLK, 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 }, \
+ { SOT_FORMATSTR_ID_CNT_MSGATTACHFILE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { SOT_FORMATSTR_ID_INET_IMAGE, EXCHG_IN_ACTION_LINK, 0 }, \
+ { SOT_FORMATSTR_ID_NETSCAPE_IMAGE, EXCHG_IN_ACTION_LINK, 0 }, \
+ { 0xffff } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_FSYS_FLD_Move[] = \
+ { \
+ { SOT_FORMAT_FILE, EXCHG_OUT_ACTION_MOVE_FILE, 0 }, \
+ { SOT_FORMATSTR_ID_CHAOS, EXCHG_OUT_ACTION_MOVE_CHAOSOBJ, 0 }, \
+ { SOT_FORMATSTR_ID_CNT_MSGATTACHFILE, EXCHG_OUT_ACTION_COPY_MSGATTACH, 0 },\
+ { 0xffff } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_FSYS_FLD_Copy[] = \
+ { \
+ { SOT_FORMAT_FILE, EXCHG_OUT_ACTION_INSERT_FILE, 0 }, \
+ { SOT_FORMATSTR_ID_CHAOS, EXCHG_OUT_ACTION_COPY_CHAOSOBJ, 0 }, \
+ { SOT_FORMATSTR_ID_CNT_MSGATTACHFILE, EXCHG_OUT_ACTION_COPY_MSGATTACH, 0 },\
+ { SOT_FORMATSTR_ID_SOLK, EXCHG_OUT_ACTION_INSERT_BOOKMARK, 0 }, \
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_OUT_ACTION_INSERT_BOOKMARK, 0 }, \
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_OUT_ACTION_INSERT_BOOKMARK, FILEGRPDSC_ONLY_URL }, \
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_OUT_ACTION_INSERT_BOOKMARK, 0 }, \
+ { 0xffff } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_FSYS_FLD_Link[] = \
+ { \
+ { SOT_FORMATSTR_ID_SOLK, EXCHG_OUT_ACTION_INSERT_BOOKMARK, 0 }, \
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_OUT_ACTION_INSERT_BOOKMARK, 0 }, \
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_OUT_ACTION_INSERT_BOOKMARK, FILEGRPDSC_ONLY_URL }, \
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_OUT_ACTION_INSERT_BOOKMARK, 0 }, \
+ { SOT_FORMAT_FILE, EXCHG_OUT_ACTION_INSERT_FILELINK, 0 }, \
+ { SOT_FORMATSTR_ID_INET_IMAGE, EXCHG_IN_ACTION_LINK, 0 }, \
+ { SOT_FORMATSTR_ID_NETSCAPE_IMAGE, EXCHG_IN_ACTION_LINK, 0 }, \
+ { 0xffff } \
+ };
+
+#define EXCHG_DEST_IMAP_FLD_ARRAY \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_IMAP_FLD_Def[] = \
+ { \
+ { 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 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_IMAP_FLD_Move[] = \
+ { \
+ { SOT_FORMATSTR_ID_SOLK, EXCHG_IN_ACTION_MOVE, 0 }, \
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_IN_ACTION_MOVE, 0 }, \
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_IN_ACTION_MOVE, FILEGRPDSC_ONLY_URL }, \
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_IN_ACTION_MOVE, 0 }, \
+ { 0xffff } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_IMAP_FLD_Copy[] = \
+ { \
+ { 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 } \
+ }; \
+ static SotAction_Impl __READONLY_DATA aEXCHG_DEST_IMAP_FLD_Link[] = \
+ { \
+ { 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 } \
+ };
+
+/* */
+#define EXCHG_DEST_SEARCH_BOX_ARRAY \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_SEARCH_BOX_Def[] = \
+ { \
+ { SOT_FORMATSTR_ID_CHAOS, EXCHG_IN_ACTION_LINK , 0 }, \
+ { SOT_FORMATSTR_ID_LINK, 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 }, \
+ { SOT_FORMAT_FILE, EXCHG_IN_ACTION_LINK, 0 }, \
+ { 0xffff } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_SEARCH_BOX_Link[] = \
+ { \
+ { SOT_FORMATSTR_ID_CHAOS, EXCHG_IN_ACTION_LINK , 0 }, \
+ { SOT_FORMATSTR_ID_SOLK, 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 }, \
+ { SOT_FORMAT_FILE, EXCHG_IN_ACTION_LINK, 0 }, \
+ { 0xffff } \
+ };
+
+/* */
+#define EXCHG_DEST_SEARCH_LOC_ARRAY \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_SEARCH_LOC_Def[] = \
+ { \
+ { SOT_FORMATSTR_ID_CHAOS, EXCHG_IN_ACTION_LINK , 0 }, \
+ { SOT_FORMATSTR_ID_SOLK, 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 }, \
+ { SOT_FORMAT_FILE, EXCHG_IN_ACTION_LINK, 0 }, \
+ { 0xffff } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_SEARCH_LOC_Link[] = \
+ { \
+ { SOT_FORMATSTR_ID_CHAOS, EXCHG_IN_ACTION_LINK , 0 }, \
+ { SOT_FORMATSTR_ID_SOLK, 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 }, \
+ { SOT_FORMAT_FILE, EXCHG_IN_ACTION_LINK, 0 }, \
+ { 0xffff } \
+ };
+
+
+/* */
+#define EXCHG_DEST_TRASH_ARRAY \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_TRASH_Def[] = \
+ { \
+ { SOT_FORMATSTR_ID_CHAOS, EXCHG_IN_ACTION_MOVE , 0 }, \
+ { SOT_FORMAT_FILE, EXCHG_IN_ACTION_MOVE, 0 }, \
+ { 0xffff } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_TRASH_Move[] = \
+ { \
+ { SOT_FORMATSTR_ID_CHAOS, EXCHG_IN_ACTION_MOVE , 0 }, \
+ { SOT_FORMAT_FILE, EXCHG_IN_ACTION_MOVE, 0 }, \
+ { 0xffff } \
+ };
+
+
+/* */
+#define EXCHG_DEST_SEARCH_FLD_ARRAY \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_SEARCH_FLD_Def[] = \
+ { \
+ { SOT_FORMATSTR_ID_CHAOS, EXCHG_IN_ACTION_LINK , 0 }, \
+ { SOT_FORMATSTR_ID_SOLK, 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 }, \
+ { SOT_FORMAT_FILE, EXCHG_IN_ACTION_LINK, 0 }, \
+ { 0xffff } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_SEARCH_FLD_Link[] = \
+ { \
+ { SOT_FORMATSTR_ID_CHAOS, EXCHG_IN_ACTION_LINK , 0 }, \
+ { SOT_FORMATSTR_ID_SOLK, 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 }, \
+ { SOT_FORMAT_FILE, EXCHG_IN_ACTION_LINK, 0 }, \
+ { 0xffff } \
+ };
+
+/* */
+#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 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_OLEOBJ_Move[] = \
+ { \
+ { SOT_FORMATSTR_ID_SVIM, EXCHG_OUT_ACTION_INSERT_IMAGEMAP, 0 }, \
+ { 0xffff } \
+ }; \
+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 } \
+ };
+
+/* */
+#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 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_CHARTDOC_OLEOBJ_Move[] = \
+ { \
+ { SOT_FORMATSTR_ID_SVIM, EXCHG_OUT_ACTION_INSERT_IMAGEMAP, 0 }, \
+ { 0xffff } \
+ }; \
+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 } \
+ };
+
+/* */
+#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_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_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 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_TEXTFRAME_Move[] = \
+ { \
+ { SOT_FORMATSTR_ID_SONLK, EXCHG_IN_ACTION_MOVE, 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_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 } \
+ }; \
+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_SONLK, EXCHG_IN_ACTION_COPY | 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_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_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_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 } \
+ }; \
+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_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 } \
+ };
+
+#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_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_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 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_TEXTFRAME_WEB_Move[] = \
+ { \
+ { SOT_FORMATSTR_ID_SONLK, EXCHG_IN_ACTION_MOVE, 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_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 } \
+ }; \
+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_SONLK, EXCHG_IN_ACTION_COPY | 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_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_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_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 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_TEXTFRAME_WEB_Link[] = \
+ { \
+ { SOT_FORMATSTR_ID_SONLK, EXCHG_IN_ACTION_LINK, 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 } \
+ };
+
+/* */
+#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_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_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 } \
+ }; \
+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_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 } \
+ }; \
+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_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 } \
+ }; \
+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_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 } \
+ };
+
+/* */
+#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_SIMPLE, 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_FORMAT_FILE, EXCHG_IN_ACTION_COPY, 0 }, \
+ { 0xffff } \
+ }; \
+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_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 } \
+ }; \
+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_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 } \
+ }; \
+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_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 } \
+ };
+
+/* */
+#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_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_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 } \
+ }; \
+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_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 } \
+ }; \
+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_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 } \
+ }; \
+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_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 } \
+ };
+
+/* */
+#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_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_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 } \
+ }; \
+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_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 } \
+ }; \
+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_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 } \
+ }; \
+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_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 } \
+ };
+
+
+/* */
+#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 } \
+ }; \
+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 } \
+ };
+
+
+/* */
+#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_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_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 } \
+ }; \
+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_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 } \
+ }; \
+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_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 } \
+ }; \
+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_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 } \
+ };
+
+
+/* */
+#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_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 } \
+ }; \
+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 } \
+ }; \
+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_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 } \
+ };
+
+
+/* */
+#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 } \
+ }; \
+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 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_URLFIELD_Link[] = \
+ { \
+ { SOT_FORMAT_FILE, EXCHG_OUT_ACTION_INSERT_HYPERLINK, 0 }, \
+ { 0xffff } \
+ };
+
+/* */
+#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_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_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 } \
+ }; \
+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_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 } \
+ }; \
+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_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 } \
+ }; \
+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_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 } \
+ };
+
+
+/* */
+#define EXCHG_DEST_DOC_MAILATTACHFRAME_ARRAY \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_MAILATTACHFRAME_Def[] =\
+ { \
+ { SOT_FORMAT_FILE_LIST, EXCHG_IN_ACTION_COPY, 0 }, \
+ { 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 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_MAILATTACHFRAME_Copy[] =\
+ { \
+ { SOT_FORMAT_FILE_LIST, EXCHG_OUT_ACTION_INSERT_FILE, 0 }, \
+ { SOT_FORMAT_FILE, EXCHG_OUT_ACTION_INSERT_FILE, 0 }, \
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_OUT_ACTION_INSERT_HYPERLINK, 0 },\
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_OUT_ACTION_INSERT_HYPERLINK, FILEGRPDSC_ONLY_URL },\
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_OUT_ACTION_INSERT_HYPERLINK, 0 },\
+ { 0xffff } \
+ };
+
+/* */
+#define EXCHG_DEST_DOC_MAILADDRESSFIELD_ARRAY \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_MAILADDRESSFIELD_Def[] =\
+ { \
+ { SOT_FORMAT_STRING, EXCHG_IN_ACTION_COPY, 0 }, \
+ { 0xffff } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_DOC_MAILADDRESSFIELD_Copy[] =\
+ { \
+ { SOT_FORMAT_STRING, EXCHG_OUT_ACTION_INSERT_STRING, 0 }, \
+ { 0xffff } \
+ };
+
+/* */
+#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_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_HTML, 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_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_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 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_SWDOC_FREE_AREA_Move[] = \
+ { \
+ { SOT_FORMATSTR_ID_SONLK, EXCHG_IN_ACTION_MOVE, 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_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 } \
+ }; \
+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_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_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_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_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_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 } \
+ }; \
+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_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 } \
+ };
+
+#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_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_HTML, 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_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 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_SWDOC_FREE_AREA_WEB_Move[] = \
+ { \
+ { SOT_FORMATSTR_ID_SONLK, EXCHG_IN_ACTION_MOVE, 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_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 } \
+ }; \
+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_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_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_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_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 } \
+ }; \
+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_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 } \
+ };
+
+
+/* */
+#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_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_HTML, 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_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 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_SCDOC_FREE_AREA_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_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_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 } \
+ }; \
+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_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_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_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 } \
+ }; \
+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 } \
+ };
+
+
+/* */
+#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_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_HTML, 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_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 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_SDDOC_FREE_AREA_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_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_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 } \
+ }; \
+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_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_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_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 } \
+ }; \
+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 } \
+ };
+
+
+/* */
+#define EXCHG_DEST_SUBSCR_BOX_ARRAY \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_SUBSCR_BOX_Def[] = \
+ { \
+ { 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 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_SUBSCR_BOX_Move[] = \
+ { \
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_OUT_ACTION_INSERT_BOOKMARK, 0 },\
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_OUT_ACTION_INSERT_BOOKMARK, FILEGRPDSC_ONLY_URL },\
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_OUT_ACTION_INSERT_BOOKMARK, 0 },\
+ { 0xffff } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_SUBSCR_BOX_Copy[] = \
+ { \
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_OUT_ACTION_INSERT_BOOKMARK, 0 },\
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_OUT_ACTION_INSERT_BOOKMARK, FILEGRPDSC_ONLY_URL },\
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_OUT_ACTION_INSERT_BOOKMARK, 0 },\
+ { 0xffff } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_SUBSCR_BOX_Link[] = \
+ { \
+ { SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, EXCHG_OUT_ACTION_INSERT_BOOKMARK, 0 },\
+ { SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, EXCHG_OUT_ACTION_INSERT_BOOKMARK, FILEGRPDSC_ONLY_URL },\
+ { SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR, EXCHG_OUT_ACTION_INSERT_BOOKMARK, 0 },\
+ { 0xffff } \
+ };
+
+/* */
+#define EXCHG_DEST_GROUPVIEW_ARRAY \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_GROUPVIEW_Def[] = \
+ { \
+ { SOT_FORMAT_FILE, EXCHG_IN_ACTION_LINK, 0 }, \
+ { SOT_FORMATSTR_ID_CHAOS, EXCHG_IN_ACTION_LINK, 0 }, \
+ { SOT_FORMATSTR_ID_SOLK, 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 } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_GROUPVIEW_Move[] = \
+ { \
+ { 0xffff } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_GROUPVIEW_Copy[] = \
+ { \
+ { 0xffff } \
+ }; \
+static SotAction_Impl __READONLY_DATA aEXCHG_DEST_GROUPVIEW_Link[] = \
+ { \
+ { SOT_FORMAT_FILE, EXCHG_IN_ACTION_LINK, 0 }, \
+ { SOT_FORMATSTR_ID_CHAOS, EXCHG_IN_ACTION_LINK, 0 }, \
+ { SOT_FORMATSTR_ID_SOLK, 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 } \
+ };
+
+/* */
+
+#define IMPL_DATA_ARRAY_1 \
+EXCHG_EMPYT_ARRAY \
+EXCHG_DEST_FTP_BOX_ARRAY \
+EXCHG_DEST_FTP_FLD_ARRAY \
+EXCHG_DEST_FSYS_FLD_ARRAY \
+EXCHG_DEST_SEARCH_BOX_ARRAY \
+EXCHG_DEST_SEARCH_LOC_ARRAY \
+EXCHG_DEST_TRASH_ARRAY \
+EXCHG_DEST_SEARCH_FLD_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_IMAP_FLD_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_DOC_MAILATTACHFRAME_ARRAY \
+EXCHG_DEST_DOC_MAILADDRESSFIELD_ARRAY \
+EXCHG_DEST_SWDOC_FREE_AREA_ARRAY \
+EXCHG_DEST_SCDOC_FREE_AREA_ARRAY \
+EXCHG_DEST_SDDOC_FREE_AREA_ARRAY \
+EXCHG_DEST_SUBSCR_BOX_ARRAY \
+EXCHG_DEST_SWDOC_FREE_AREA_WEB_ARRAY \
+EXCHG_DEST_GROUPVIEW_ARRAY
+
+#define IMPL_DATA_ARRAY_3 \
+static SotDestinationEntry_Impl __READONLY_DATA aDestinationArray[] = \
+{ \
+ { EXCHG_DEST_FTP_BOX, \
+ aEXCHG_DEST_FTP_BOX_Def, \
+ aEmptyArr, \
+ aEXCHG_DEST_FTP_BOX_Copy, \
+ aEXCHG_DEST_FTP_BOX_Link, \
+ }, \
+ { EXCHG_DEST_FTP_FLD, \
+ aEXCHG_DEST_FTP_FLD_Def, \
+ aEXCHG_DEST_FTP_FLD_Move, \
+ aEXCHG_DEST_FTP_FLD_Copy, \
+ aEXCHG_DEST_FTP_FLD_Link, \
+ }, \
+ { EXCHG_DEST_FSYS_BOX, \
+ aEmptyArr, \
+ aEmptyArr, \
+ aEmptyArr, \
+ aEmptyArr \
+ }, \
+ { EXCHG_DEST_FSYS_FLD, \
+ aEXCHG_DEST_FSYS_FLD_Def, \
+ aEXCHG_DEST_FSYS_FLD_Move, \
+ aEXCHG_DEST_FSYS_FLD_Copy, \
+ aEXCHG_DEST_FSYS_FLD_Link \
+ }, \
+ { EXCHG_DEST_IMAP_FLD, \
+ aEXCHG_DEST_IMAP_FLD_Def, \
+ aEXCHG_DEST_IMAP_FLD_Move, \
+ aEXCHG_DEST_IMAP_FLD_Copy, \
+ aEXCHG_DEST_IMAP_FLD_Link, \
+ }, \
+ { EXCHG_DEST_SEARCH_BOX, \
+ aEXCHG_DEST_SEARCH_BOX_Def, \
+ aEmptyArr, \
+ aEmptyArr, \
+ aEXCHG_DEST_SEARCH_BOX_Link \
+ }, \
+ { EXCHG_DEST_SEARCH_LOCATIONS, \
+ aEXCHG_DEST_SEARCH_LOC_Def, \
+ aEmptyArr, \
+ aEmptyArr, \
+ aEXCHG_DEST_SEARCH_LOC_Link \
+ }, \
+ { EXCHG_DEST_TRASH, \
+ aEXCHG_DEST_TRASH_Def, \
+ aEXCHG_DEST_TRASH_Move, \
+ aEmptyArr, \
+ aEmptyArr \
+ }, \
+ { EXCHG_DEST_SEARCH_FLD, \
+ aEXCHG_DEST_SEARCH_FLD_Def, \
+ aEmptyArr, \
+ aEmptyArr, \
+ aEXCHG_DEST_SEARCH_FLD_Link \
+ }, \
+ { 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_DOC_MAILATTACHFRAME, \
+ aEXCHG_DEST_DOC_MAILATTACHFRAME_Def, \
+ aEmptyArr, \
+ aEXCHG_DEST_DOC_MAILATTACHFRAME_Copy, \
+ aEmptyArr \
+ }, \
+ { EXCHG_DEST_DOC_MAILADDRESSFIELD, \
+ aEXCHG_DEST_DOC_MAILADDRESSFIELD_Def, \
+ aEmptyArr, \
+ aEXCHG_DEST_DOC_MAILADDRESSFIELD_Copy, \
+ aEmptyArr \
+ }, \
+ { 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_SUBSCR_BOX, \
+ aEXCHG_DEST_SUBSCR_BOX_Def, \
+ aEXCHG_DEST_SUBSCR_BOX_Move, \
+ aEXCHG_DEST_SUBSCR_BOX_Copy, \
+ aEXCHG_DEST_SUBSCR_BOX_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 \
+ }, \
+ { EXCHG_DEST_SFX_GROUPVIEW, \
+ aEXCHG_DEST_GROUPVIEW_Def, \
+ aEXCHG_DEST_GROUPVIEW_Move, \
+ aEXCHG_DEST_GROUPVIEW_Copy, \
+ aEXCHG_DEST_GROUPVIEW_Link \
+ }, \
+ { \
+ 0xffff \
+ } \
+};
+
+static BOOL CheckContext_Impl( const SotDataObject& rData,
+ const SotAction_Impl& rEntry )
+{
+ BOOL bRet = TRUE;
+ switch( rEntry.nFormatId )
+ {
+ case SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR:
+#ifdef WNT
+ switch( rEntry.nContextCheckId )
+ {
+ case FILEGRPDSC_ONLY_URL:
+ {
+ bRet = FALSE;
+ SvData aData( rEntry.nFormatId, MEDIUM_ALL );
+ if( rData.GetTypeList().Get( SOT_FORMATSTR_ID_FILECONTENT ) &&
+ ((SotDataObject&)rData).GetData( &aData ))
+ {
+ // dann als FileGroupDescriptor bereitstellen
+ void *pData;
+ aData.GetData( &pData, TRANSFER_REFERENCE );
+ FILEGROUPDESCRIPTOR* pFDesc = (FILEGROUPDESCRIPTOR*)pData;
+ // read only URL-Files
+ if( pFDesc->cItems )
+ {
+ ByteString sDesc( pFDesc->fgd[0].cFileName );
+ bRet = 4 < sDesc.Len() && sDesc.Copy( sDesc.Len()-4 ).
+ EqualsIgnoreCaseAscii( ".URL" );
+ }
+ }
+ }
+ break;
+ }
+#endif
+ break;
+ }
+ return bRet;
+}
+
+static USHORT GetAction_Impl(const SotDataObject& rData,const SotAction_Impl* pArray,
+ ULONG& rFormat )
+{
+ const SvDataTypeList& rTypeList = rData.GetTypeList();
+ const SotAction_Impl* pArrayStart = pArray;
+ ULONG nId = pArray->nFormatId;
+ while( nId != 0xffff )
+ {
+ rFormat = nId;
+ if( 0 != rTypeList.Get( SotExchange::RegisterSotFormatName( nId ) ) &&
+ ( !pArray->nContextCheckId ||
+ CheckContext_Impl( rData, *pArray ) ))
+ {
+ if( SOT_FORMAT_FILE_LIST == rFormat &&
+ 0 != rTypeList.Get( SotExchange::RegisterSotFormatName(
+ SOT_FORMAT_FILE ) ) )
+ {
+ SvData aData( SOT_FORMAT_FILE_LIST );
+ ((SotDataObject&)rData).GetData( &aData );
+ FileList aFileList;
+ FileList* pFileList = &aFileList;
+ aData.GetData( (SvDataCopyStream**)&pFileList, pFileList->Type() );
+ // FileList mit einem Eintrag matcht auf FORMAT_FILE!
+ if( aFileList.Count() == 1 )
+ {
+ // Eintrag fuer FORMAT_FILE suchen
+ 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;
+ }
+ return EXCHG_INOUT_ACTION_NONE;
+}
+
+USHORT SotExchange::GetExchangeAction(
+ const SotDataObject& rData, USHORT nDestination, USHORT nSourceOptions,
+ USHORT nUserAction, ULONG& rFormat, USHORT& rDefaultAction )
+{
+ // 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 = GetAction_Impl(rData, pEntry->aDefaultActions,rFormat);
+ // Unterstuetzt die Quelle die Aktion?
+ if( !(nUserAction & nSourceOptions ))
+ {
+ // Nein -> Alle Aktionen der Quelle checken
+ rDefaultAction = (EXCHG_IN_ACTION_COPY & nSourceOptions);
+ if( rDefaultAction && (nUserAction=GetAction_Impl(rData,pEntry->aCopyActions,rFormat)))
+ return nUserAction;
+ rDefaultAction = (EXCHG_IN_ACTION_LINK & nSourceOptions);
+ if( rDefaultAction && (nUserAction=GetAction_Impl(rData,pEntry->aLinkActions,rFormat)))
+ return nUserAction;
+ rDefaultAction = (EXCHG_IN_ACTION_MOVE & nSourceOptions);
+ if( rDefaultAction && (nUserAction=GetAction_Impl(rData,pEntry->aMoveActions,rFormat)))
+ return nUserAction;
+ rDefaultAction = 0;
+ return 0;
+ }
+ rDefaultAction = nUserAction;
+ }
+ else
+ rDefaultAction = nUserAction;
+
+ switch( nUserAction )
+ {
+ case EXCHG_IN_ACTION_MOVE:
+ nUserAction = GetAction_Impl(rData, pEntry->aMoveActions, rFormat);
+ break;
+
+ case EXCHG_IN_ACTION_COPY:
+ nUserAction = GetAction_Impl(rData, pEntry->aCopyActions, rFormat);
+ break;
+
+ case EXCHG_IN_ACTION_LINK:
+ nUserAction = GetAction_Impl(rData, pEntry->aLinkActions, rFormat);
+ break;
+
+ default:
+ nUserAction = EXCHG_INOUT_ACTION_NONE;
+ }
+ return nUserAction;
+}
+
+
+
+#if SUPD <= 397
+
+USHORT SotExchange::GetExchangeAction(
+ const SotDataObject& rData, USHORT nDestination, USHORT nSourceOptions,
+ USHORT nUserAction, ULONG& rFormat, USHORT& rDefaultAction )
+{
+ USHORT nFmt = 0,
+ nRet = GetExchangeAction( rData, nDestination, nSourceOptions,
+ nUserAction, nFmt , rDefaultAction );
+ rFormat = RegisterSotFormatName( nFmt );
+ return nRet;
+}
+
+#endif
+
diff --git a/sot/source/base/makefile.mk b/sot/source/base/makefile.mk
new file mode 100644
index 000000000000..21b3a55f75bb
--- /dev/null
+++ b/sot/source/base/makefile.mk
@@ -0,0 +1,109 @@
+#*************************************************************************
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.1.1.1 $
+#
+# last change: $Author: hr $ $Date: 2000-09-18 16:56:51 $
+#
+# The Contents of this file are made available subject to the terms of
+# either of the following licenses
+#
+# - GNU Lesser General Public License Version 2.1
+# - Sun Industry Standards Source License Version 1.1
+#
+# Sun Microsystems Inc., October, 2000
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2000 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#
+# Sun Industry Standards Source License Version 1.1
+# =================================================
+# The contents of this file are subject to the Sun Industry Standards
+# Source License Version 1.1 (the "License"); You may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at http://www.openoffice.org/license.html.
+#
+# Software provided under this License is provided on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+# See the License for the specific provisions governing your rights and
+# obligations concerning the Software.
+#
+# The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+# Copyright: 2000 by Sun Microsystems, Inc.
+#
+# All Rights Reserved.
+#
+# Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=sot
+TARGET=base
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+.IF "$(COM)"=="GCC"
+NOOPTFILES=\
+ $(SLO)$/dtrans.obj\
+ $(SLO)$/exchange.obj
+.ENDIF
+
+# --- Settings -----------------------------------------------------
+.INCLUDE : svpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sv.mk
+
+
+# --- Files --------------------------------------------------------
+
+CXXFILES= factory.cxx \
+ object.cxx \
+ dtrans.cxx \
+ exchange.cxx \
+ filelist.cxx \
+ formats.cxx \
+ $(PROJECTPCHSOURCE).cxx
+
+SLOFILES= \
+ $(SLO)$/factory.obj \
+ $(SLO)$/object.obj \
+ $(SLO)$/dtrans.obj \
+ $(SLO)$/exchange.obj \
+ $(SLO)$/filelist.obj \
+ $(SLO)$/formats.obj
+
+.IF "$(OS)"=="NETBSD"
+SLOFILES += $(SLO)$/netbsd.obj
+.ENDIF
+
+
+# --- Targets -------------------------------------------------------
+
+
+.INCLUDE : target.mk
+
+.INCLUDE : $(PRJ)$/util$/target.pmk
diff --git a/sot/source/base/object.cxx b/sot/source/base/object.cxx
new file mode 100644
index 000000000000..aa757a6eb364
--- /dev/null
+++ b/sot/source/base/object.cxx
@@ -0,0 +1,510 @@
+/*************************************************************************
+ *
+ * $RCSfile: object.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:56:51 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SOT_OBJECT_CXX
+
+#include <tools/debug.hxx>
+#include <object.hxx>
+#include <factory.hxx>
+#include <agg.hxx>
+#pragma hdrstop
+
+/************** 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()
+ : nStrongLockCount( 0 )
+ , nOwnerLockCount( 0 )
+ , pAggList ( NULL )
+ , 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
+ SvAggregate & rEle = pAggList->GetObject( i );
+ DBG_ASSERT( !rEle.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" )
+ for( ULONG 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( 0 == --nOwnerLockCount )
+ DoClose();
+ ReleaseRef();
+ }
+}
+
+//=========================================================================
+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..47f2e4fa9815
--- /dev/null
+++ b/sot/source/sdstor/makefile.mk
@@ -0,0 +1,114 @@
+#*************************************************************************
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.1.1.1 $
+#
+# last change: $Author: hr $ $Date: 2000-09-18 16:56:51 $
+#
+# The Contents of this file are made available subject to the terms of
+# either of the following licenses
+#
+# - GNU Lesser General Public License Version 2.1
+# - Sun Industry Standards Source License Version 1.1
+#
+# Sun Microsystems Inc., October, 2000
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2000 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#
+# Sun Industry Standards Source License Version 1.1
+# =================================================
+# The contents of this file are subject to the Sun Industry Standards
+# Source License Version 1.1 (the "License"); You may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at http://www.openoffice.org/license.html.
+#
+# Software provided under this License is provided on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+# See the License for the specific provisions governing your rights and
+# obligations concerning the Software.
+#
+# The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+# Copyright: 2000 by Sun Microsystems, Inc.
+#
+# All Rights Reserved.
+#
+# Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=sot
+TARGET=sdstor
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : svpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sv.mk
+
+# --- Files --------------------------------------------------------
+
+CXXFILES = \
+ stg.cxx \
+ stgcache.cxx \
+ stgstrms.cxx \
+ stgelem.cxx \
+ stgio.cxx \
+ stgole.cxx \
+ stgdir.cxx \
+ stgavl.cxx \
+ storinfo.cxx \
+ storage.cxx \
+ $(PROJECTPCHSOURCE).cxx
+
+SLOFILES = \
+ $(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
+
+# NETBSD: somewhere we have to instantiate the static data members.
+# NETBSD-1.2.1 doesn't know about weak symbols so the default mechanism for GCC won't work.
+# SCO and MACOSX: the linker does know about weak symbols, but we can't ignore multiple defined symbols
+.IF "$(OS)"=="NETBSD" || "$(OS)"=="SCO" || "$(OS)$(COM)"=="OS2GCC" || "$(OS)"=="MACOSX"
+SLOFILES+=$(SLO)$/staticmb.obj
+.ENDIF
+
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
+.INCLUDE : $(PRJ)$/util$/target.pmk
diff --git a/sot/source/sdstor/sdintern.hdb b/sot/source/sdstor/sdintern.hdb
new file mode 100644
index 000000000000..4dfbc69be013
--- /dev/null
+++ b/sot/source/sdstor/sdintern.hdb
@@ -0,0 +1,22 @@
+write "/*************************************************************************"
+write "* SDINTERN.HXX"
+write "* __DATE__"
+write "* (c) 1992-1995 STAR DIVISION"
+write "*************************************************************************/"
+write "#ifndef _SDINTERN_HXX"
+write "#define _SDINTERN_HXX"
+write "#ifndef _SOLAR_H"
+write "#include <tools/solar.h>"
+write "#endif"
+write "#ifndef _STREAM_HXX"
+write "#include <tools/stream.hxx>"
+write "#endif"
+file stg.hxx
+file stgelem.hxx
+file stgcache.hxx
+file stgio.hxx
+file stgstrms.hxx
+file stgavl.hxx
+file stgdir.hxx
+write "#endif"
+
diff --git a/sot/source/sdstor/stg.cxx b/sot/source/sdstor/stg.cxx
new file mode 100644
index 000000000000..4696b6a8c4d6
--- /dev/null
+++ b/sot/source/sdstor/stg.cxx
@@ -0,0 +1,925 @@
+/*************************************************************************
+ *
+ * $RCSfile: stg.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:56:51 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <storinfo.hxx>
+#ifndef _TOOLS_OWNLIST_HXX
+#include <tools/ownlist.hxx>
+#endif
+#ifndef _TOOLS_STRING_HXX
+#include <tools/string.hxx>
+#endif
+#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"
+#pragma hdrstop
+
+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 //////////////////////////////
+
+StorageBase::StorageBase( StgIo* p, StgDirEntry* pe )
+ : bAutoCommit( FALSE ), pIo( p ), pEntry( pe )
+{
+ nMode = STREAM_READ;
+ nError = SVSTREAM_OK;
+ p->IncRef();
+ if( pe )
+ pe->nRefCnt++;
+}
+
+StorageBase::~StorageBase()
+{
+ 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 StorageBase::Validate( BOOL bWrite ) const
+{
+ if( pEntry
+ && !pEntry->bInvalid
+ && ( !bWrite || !pEntry->bDirect || ( nMode & STREAM_WRITE ) ) )
+ return TRUE;
+ SetError( SVSTREAM_ACCESS_DENIED );
+ return FALSE;
+}
+
+// Check the given share flags against the current flags
+
+BOOL StorageBase::ValidateMode( 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;
+ }
+ SetError( SVSTREAM_ACCESS_DENIED );
+ return FALSE;
+}
+
+// The following three methods are declared as const, since they
+// may be called from within a const method.
+
+ULONG StorageBase::GetError() const
+{
+ ULONG n = nError;
+ ((StorageBase*) this)->nError = SVSTREAM_OK;
+ return n;
+}
+
+void StorageBase::SetError( ULONG n ) const
+{
+ if( !nError )
+ ((StorageBase*) this)->nError = n;
+}
+
+void StorageBase::ResetError() const
+{
+ ((StorageBase*) this)->nError = SVSTREAM_OK;
+}
+
+// Retrieve the underlying SvStream for info purposes
+
+const SvStream* StorageBase::GetSvStream() const
+{
+ return pIo ? pIo->GetStrm() : NULL;
+}
+
+//////////////////////// class StorageStream /////////////////////////////
+
+StorageStream::StorageStream( StgIo* p, StgDirEntry* q, StreamMode m )
+ : StorageBase( p, q ), 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;
+ nMode = m;
+}
+
+StorageStream::~StorageStream()
+{
+ // Do an auto-commit if the entry is open in direct mode
+ if( bAutoCommit )
+ Commit();
+ if( pEntry && pEntry->nRefCnt && pEntry->bDirect && (nMode & STREAM_WRITE) )
+ pEntry->Commit();
+}
+
+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( !( 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( StorageStream* pDest )
+{
+ if( !Validate() || !pDest->Validate( TRUE ) || pEntry == pDest->pEntry )
+ return FALSE;
+ pEntry->Copy( *pDest->pEntry );
+ pDest->Commit();
+ pIo->MoveError( *this );
+ SetError( pDest->GetError() );
+ return BOOL( Good() && pDest->Good() );
+}
+
+///////////////////////// 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;
+}
+
+// Open the storage file. If writing is permitted and the file is not
+// a storage file, initialize it.
+
+Storage::Storage( const String& rFile, StreamMode m, BOOL bDirect )
+ : StorageBase( new StgIo, NULL ), aName( rFile ), bIsRoot( FALSE )
+{
+ BOOL bTemp = FALSE;
+ if( !aName.Len() )
+ {
+ // no name = temporary name!
+ DirEntry aEntry;
+ aName = aEntry.TempName().GetFull();
+ bTemp = TRUE;
+ }
+ // the root storage creates the I/O system
+ 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 )
+ : StorageBase( new StgIo, NULL ), bIsRoot( FALSE )
+{
+ nMode = STREAM_READ;
+ if( r.IsWritable() )
+ 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 = nMode;
+ }
+ pIo->MoveError( *this );
+ }
+ else
+ {
+ SetError( r.GetError() );
+ pEntry = NULL;
+ }
+}
+
+// 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 )
+ : StorageBase( p, q ), bIsRoot( FALSE )
+{
+ if( q )
+ q->aEntry.GetName( aName );
+ else
+ m &= ~STREAM_READWRITE;
+ bIsRoot = FALSE;
+ nMode = m;
+ if( q && q->nRefCnt == 1 )
+ q->nMode = m;
+}
+
+Storage::~Storage()
+{
+ // Invalidate all open substorages
+ if( bAutoCommit )
+ Commit();
+ if( pEntry )
+ {
+ // Do an auto-commit if the entry is open in direct mode
+ if( pEntry->nRefCnt && pEntry->bDirect && (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 )
+ {
+ DirEntry aEntry( GetName() );
+ FSysError nErr = aEntry.Kill();
+ DBG_ASSERT( nErr == FSYS_ERR_OK, "cannot delete temp-file" )
+ }
+}
+
+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
+
+Storage* Storage::OpenStorage( const String& rName, StreamMode m, BOOL bDirect )
+{
+ if( !Validate() || !ValidateMode( m, NULL ) )
+ 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;
+ }
+ // Dont check direct conflict if opening readonly
+ if( p && (m & STREAM_WRITE ))
+ {
+ // Either direct or transacted mode is supported
+ if( pEntry->nRefCnt == 1 )
+ p->bDirect = bDirect;
+ if( p->bDirect != bDirect )
+ SetError( SVSTREAM_ACCESS_DENIED );
+ }
+ Storage* pStg = new Storage( pIo, p, m );
+ pIo->MoveError( *pStg );
+ if( m & STREAM_WRITE ) pStg->bAutoCommit = TRUE;
+ return pStg;
+}
+
+// Open a stream
+
+StorageStream* Storage::OpenStream( const String& rName, StreamMode m, BOOL )
+{
+ if( !Validate() || !ValidateMode( m, NULL ) )
+ 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->bAutoCommit = 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, Storage* 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
+ Storage* p1 = OpenStorage( rElem, INTERNAL_MODE );
+ Storage* p2 = pDest->OpenStorage
+ ( rNew, STREAM_WRITE | STREAM_SHARE_DENYALL, pEntry->bDirect );
+ p2->pEntry->aEntry.SetClassId( p1->pEntry->aEntry.GetClassId() );
+ p1->CopyTo( p2 );
+ SetError( p1->GetError() );
+ if( p2->GetError() )
+ pDest->SetError( p2->GetError() );
+ else
+ p2->Commit();
+ delete p1;
+ delete p2;
+ return BOOL( Good() && pDest->Good() );
+ }
+ else
+ {
+ // stream copy
+ StorageStream* p1 = OpenStream( rElem, INTERNAL_MODE );
+ StorageStream* p2 = pDest->OpenStream
+ ( rNew, STREAM_WRITE | STREAM_SHARE_DENYALL, pEntry->bDirect );
+ p1->CopyTo( p2 );
+ SetError( p1->GetError() );
+ if( p2->GetError() )
+ pDest->SetError( p2->GetError() );
+ else
+ p2->Commit();
+ delete p1;
+ delete p2;
+ return BOOL( Good() && pDest->Good() );
+ }
+ }
+ SetError( SVSTREAM_FILE_NOT_FOUND );
+ return FALSE;
+}
+
+BOOL Storage::CopyTo( Storage* pDest ) const
+{
+ if( !Validate() || !pDest || !pDest->Validate( TRUE )
+ || pDest->pEntry == pEntry )
+ {
+ SetError( SVSTREAM_ACCESS_DENIED );
+ return FALSE;
+ }
+ Storage* pThis = (Storage*) this;
+ /*
+ if( !pThis->pEntry->IsContained( pDest->pEntry ) )
+ {
+ SetError( SVSTREAM_ACCESS_DENIED );
+ return FALSE;
+ }
+ */
+ pDest->pEntry->aEntry.SetClassId( pEntry->aEntry.GetClassId() );
+ pDest->pEntry->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, Storage* pDest, const String& rNew )
+{
+ if( !Validate() || !pDest || !pDest->Validate( TRUE )
+ || pDest->pEntry == pEntry )
+ {
+ 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;
+ if( pIo == pDest->pIo && rElem == rNew )
+ {
+ 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, pDest, 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( !( 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();
+ 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;
+}
+
diff --git a/sot/source/sdstor/stgavl.cxx b/sot/source/sdstor/stgavl.cxx
new file mode 100644
index 000000000000..bd78852eb8e2
--- /dev/null
+++ b/sot/source/sdstor/stgavl.cxx
@@ -0,0 +1,451 @@
+/*************************************************************************
+ *
+ * $RCSfile: stgavl.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:56:51 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+
+#include "stgavl.hxx"
+#pragma hdrstop
+
+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;
+ 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 += 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 ? ( pCur == pDel ) : 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::Enum( short& n )
+{
+ if( this )
+ {
+ if( pLeft )
+ pLeft->Enum( n );
+ nId = n++;
+ if( pRight )
+ pRight->Enum( 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->Enum( 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..e9ab60dcea4f
--- /dev/null
+++ b/sot/source/sdstor/stgavl.hxx
@@ -0,0 +1,113 @@
+/*************************************************************************
+ *
+ * $RCSfile: stgavl.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:56:51 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _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 Enum( 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..c5381f69a540
--- /dev/null
+++ b/sot/source/sdstor/stgcache.cxx
@@ -0,0 +1,535 @@
+/*************************************************************************
+ *
+ * $RCSfile: stgcache.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:56:51 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#if defined(_MSC_VER) && (_MSC_VER<1200)
+#include <tools/presys.h>
+#endif
+#if STLPORT_VERSION<321
+#include <hash_map.h>
+#else
+#include <hash_map>
+#endif
+#if defined(_MSC_VER) && (_MSC_VER<1200)
+#include <tools/postsys.h>
+#endif
+#include <vos/macros.hxx>
+
+#include <string.h>
+
+#ifndef _TOOLS_STRING_HXX
+#include <tools/string.hxx>
+#endif
+
+#include "stg.hxx"
+#include "stgelem.hxx"
+#include "stgcache.hxx"
+#include "stgstrms.hxx"
+#include "stgdir.hxx"
+#include "stgio.hxx"
+#pragma hdrstop
+
+/*************************************************************************/
+//-----------------------------------------------------------------------------
+typedef NAMESPACE_STD(hash_map)
+//typedef hash_map
+<
+ INT32,
+ StgPage *,
+ NAMESPACE_STD(hash)< INT32 >,
+ NAMESPACE_STD(equal_to)< INT32 >
+> UsrStgPagePtr_Impl;
+#ifdef WNT
+#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 __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.
+
+StgCache::StgCache()
+{
+ nRef = 0;
+ pStrm = NULL;
+ pCur = pElem1 = NULL;
+ nPageSize = 512;
+ nError = SVSTREAM_OK;
+ bMyStream = FALSE;
+ bFile = FALSE;
+ pLRUCache = 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 = ( nFileSize >= 512 ) ? ( nFileSize - 512 ) / nPageSize : 0;
+ 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( bMyStream )
+ delete pStrm;
+ pStrm = p;
+ bMyStream = bMy;
+}
+
+// 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 = ( nFileSize >= 512 ) ? ( nFileSize - 512 ) / nPageSize : 0;
+ 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() )
+ {
+ 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 )
+ {
+ ULONG nPhysPos = pStrm->Seek( nPos );
+#ifdef CHECK_DIRTY
+ if( nPhysPos != nPos )
+ ErrorBox( NULL, WB_OK, String("SO2: Seek failed") ).Execute();
+#endif
+ }
+ pStrm->Read( pBuf, nBytes );
+ 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 )
+ {
+ ULONG nPhysPos = pStrm->Seek( nPos );
+#ifdef CHECK_DIRTY
+ if( nPhysPos != nPos )
+ 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..c9a3bf032a3a
--- /dev/null
+++ b/sot/source/sdstor/stgcache.hxx
@@ -0,0 +1,164 @@
+/*************************************************************************
+ *
+ * $RCSfile: stgcache.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:56:51 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _STGCACHE_HXX
+#define _STGCACHE_HXX
+
+#ifndef _TOOLS_SOLAR_H
+#include <tools/solar.h>
+#endif
+#ifndef _TOOLS_STREAM_HXX
+#include <tools/stream.hxx>
+#endif
+
+#ifndef _STGELEM_HXX
+#include "stgelem.hxx"
+#endif
+
+
+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
+ 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 );
+ 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 #
+ void* 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 __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..c5f4db205021
--- /dev/null
+++ b/sot/source/sdstor/stgdir.cxx
@@ -0,0 +1,1032 @@
+/*************************************************************************
+ *
+ * $RCSfile: stgdir.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:56:51 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <string.h> // memcpy()
+
+#include "stg.hxx"
+#include "stgelem.hxx"
+#include "stgcache.hxx"
+#include "stgstrms.hxx"
+#include "stgdir.hxx"
+#include "stgio.hxx"
+#pragma hdrstop
+
+//////////////////////////// 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 )
+{
+ short nThreshold = (USHORT) rIo.aHdr.GetThreshold();
+ delete pStgStrm;
+ if( !bForceBig && aEntry.GetSize() < (INT32) 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( !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();
+ short nThreshold = (USHORT) 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 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;
+ // enlarge?
+ if( nNew > nSize )
+ {
+ if( !SetSize( nNew ) )
+ 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 )
+ 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 )
+ {
+ void* p = new BYTE[ 4096 ];
+ 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;
+ }
+ delete p;
+ }
+}
+
+// Commit this entry
+
+BOOL StgDirEntry::Commit()
+{
+ 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 aIter( *this );
+ StgDirEntry* p = aIter.First();
+ while( p )
+ {
+ p->aEntry = p->aSave;
+ p->bDirty = FALSE;
+ bSomeRenamed = BOOL( bSomeRenamed | p->bRenamed );
+ // Remove any new entries
+ if( p->bCreated )
+ {
+ p->bCreated = FALSE;
+ p->Close();
+ p->bInvalid = TRUE;
+ }
+ // Reactivate any removed entries
+ else if( p->bRemoved )
+ p->bRemoved = p->bInvalid = p->bTemp = FALSE;
+ p = aIter.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;
+ }
+ }
+ 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 )
+ {
+ void* p = new BYTE[ 4096 ];
+ 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;
+ }
+ delete p;
+ 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 ) )
+ {
+ void* p = new BYTE[ 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;
+ }
+ delete p;
+ 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;
+ }
+ }
+}
+
+///////////////////////////// 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;
+ 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 != 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..44b1614a590f
--- /dev/null
+++ b/sot/source/sdstor/stgdir.hxx
@@ -0,0 +1,170 @@
+/*************************************************************************
+ *
+ * $RCSfile: stgdir.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:56:51 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _STGDIR_HXX
+#define _STGDIR_HXX
+
+#ifndef _STGAVL_HXX
+#include "stgavl.hxx"
+#endif
+#ifndef _STGELEM_HXX
+#include "stgelem.hxx"
+#endif
+#ifndef _STGSTRMS_HXX
+#include "stgstrms.hxx"
+#endif
+
+class StgIo;
+class StgEntry;
+class StgDirEntry;
+class StgDirStrm;
+
+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& );
+};
+
+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..ef568aca861f
--- /dev/null
+++ b/sot/source/sdstor/stgelem.cxx
@@ -0,0 +1,433 @@
+/*************************************************************************
+ *
+ * $RCSfile: stgelem.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:56:51 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <string.h> // memset(), memcpy()
+#include <tools/intn.hxx>
+#include "stg.hxx"
+#include "stgelem.hxx"
+#include "stgcache.hxx"
+#include "stgstrms.hxx"
+#include "stgdir.hxx"
+#include "stgio.hxx"
+
+#pragma hdrstop
+
+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();
+ 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 rIo.Good();
+}
+
+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 );
+}
+
+// Perform thorough checks also on unknown variables
+
+BOOL StgHeader::Check()
+{
+ return BOOL( memcmp( cSignature, cStgSignature, 8 ) == 0
+ && (short) ( nVersion >> 16 ) == 3 );
+}
+
+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 International* pInter = 0;
+
+inline International& GetInternational()
+{
+ return pInter ? *pInter : *(pInter = new International);
+}
+
+BOOL StgEntry::SetName( const String& rName )
+{
+ const International& aInter = GetInternational();
+ // make upper case character in current language
+ aName = rName;
+ aName.Erase( 31 );
+ aInter.ToUpper( aName );
+ //ToUnicode_Impl( aNameStr );
+
+ int i;
+ for( i = 0; i < aName.Len() && i < 32; i++ )
+ nName[ i ] = rName.GetChar( 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 )
+ return FALSE;
+
+ aName = String( nName, n );
+ const International& aInter = GetInternational();
+ aInter.ToUpper( aName );
+ 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..8273eb35b991
--- /dev/null
+++ b/sot/source/sdstor/stgelem.hxx
@@ -0,0 +1,204 @@
+/*************************************************************************
+ *
+ * $RCSfile: stgelem.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:56:51 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+// 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
+
+class StgIo;
+class SvStream;
+class String;
+
+struct ClsId
+{
+ INT32 n1;
+ INT16 n2, n3;
+ UINT8 n4, n5, n6, n7, n8, n9, n10, n11;
+};
+
+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 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..6b5e3e47758a
--- /dev/null
+++ b/sot/source/sdstor/stgio.cxx
@@ -0,0 +1,416 @@
+/*************************************************************************
+ *
+ * $RCSfile: stgio.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:56:52 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include "stg.hxx"
+#include "stgelem.hxx"
+#include "stgcache.hxx"
+#include "stgstrms.hxx"
+#include "stgdir.hxx"
+#include "stgio.hxx"
+#pragma hdrstop
+
+///////////////////////////// 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;
+ 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( ( 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( 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;
+}
+
+Link StgIo::aErrorLink;
+
+void StgIo::SetErrorLink( const Link& rLink )
+{
+ aErrorLink = rLink;
+}
+
+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;
+ aErrorLink.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..3418cd013415
--- /dev/null
+++ b/sot/source/sdstor/stgio.hxx
@@ -0,0 +1,121 @@
+/*************************************************************************
+ *
+ * $RCSfile: stgio.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:56:52 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _STGIO_HXX
+#define _STGIO_HXX
+
+#ifndef _STGCACHE_HXX
+#include <stgcache.hxx>
+#endif
+#ifndef _STGELEM_HXX
+#include <stgelem.hxx>
+#endif
+#ifndef _TOOLS_STRING_HXX
+#include <tools/string.hxx>
+#endif
+
+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 Link aErrorLink;
+ static void SetErrorLink( const Link& );
+ static const Link& GetErrorLink() { return aErrorLink; }
+ ULONG ValidateFATs( );
+};
+
+#endif
diff --git a/sot/source/sdstor/stgole.cxx b/sot/source/sdstor/stgole.cxx
new file mode 100644
index 000000000000..6551754d3c00
--- /dev/null
+++ b/sot/source/sdstor/stgole.cxx
@@ -0,0 +1,255 @@
+/*************************************************************************
+ *
+ * $RCSfile: stgole.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:56:52 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include "rtl/string.h"
+#include "rtl/string.h"
+#include "stgole.hxx"
+#include "storinfo.hxx" // Read/WriteClipboardFormat()
+#pragma hdrstop
+
+///////////////////////// class StgInternalStream ////////////////////////
+
+StgInternalStream::StgInternalStream
+ ( Storage& 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( Storage& 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;
+ sal_Char* p = new sal_Char[ (USHORT) nLen1 ];
+ if( Read( p, nLen1 ) == (ULONG) nLen1 )
+ {
+ aUserName = String( p, gsl_getSystemTextEncoding() );
+/* // 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 )
+ 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) 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( Storage& 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 nVersion = 0;
+ Seek( 0L );
+ *this >> nVersion >> 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..7356bccff445
--- /dev/null
+++ b/sot/source/sdstor/stgole.hxx
@@ -0,0 +1,111 @@
+/*************************************************************************
+ *
+ * $RCSfile: stgole.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:56:52 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _SDSTOR_STGOLE_HXX
+#define _SDSTOR_STGOLE_HXX
+
+#include <string.h> // memset()
+
+#include "stg.hxx"
+#include "stgelem.hxx"
+
+class StgInternalStream : public SvStream
+{
+ StorageStream* 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( Storage&, const String&, BOOL );
+ ~StgInternalStream();
+ void Commit();
+};
+
+// standard stream "\1CompObj"
+
+class StgCompObjStream : public StgInternalStream
+{
+ ClsId aClsId;
+ String aUserName;
+ ULONG nCbFormat;
+public:
+ StgCompObjStream( Storage&, BOOL );
+ ClsId& GetClsId() { return aClsId; }
+ String& GetUserName() { return aUserName; }
+ ULONG& GetCbFormat() { return nCbFormat; }
+ BOOL Load();
+ BOOL Store();
+};
+
+// standard stream "\1Ole"
+
+class StgOleStream : public StgInternalStream
+{
+ ULONG nFlags;
+public:
+ StgOleStream( Storage&, BOOL );
+ ULONG& 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..e295edc92ac6
--- /dev/null
+++ b/sot/source/sdstor/stgstrms.cxx
@@ -0,0 +1,1268 @@
+/*************************************************************************
+ *
+ * $RCSfile: stgstrms.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:56:52 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <string.h> // memcpy()
+
+#ifndef _TOOLS_FSYS_HXX
+#include <tools/fsys.hxx>
+#endif
+#include <tools/debug.hxx>
+
+#include "stg.hxx"
+#include "stgelem.hxx"
+#include "stgcache.hxx"
+#include "stgstrms.hxx"
+#include "stgdir.hxx"
+#include "stgio.hxx"
+#pragma hdrstop
+
+#if defined(W31)
+ #include <tools/svwin.h>
+ #define memcpy hmemcpy
+ #define __HUGE _huge
+#else
+ #define __HUGE
+#endif
+
+///////////////////////////// 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;
+ 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, 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 );
+ 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 -= 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 );
+ 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 );
+ 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 -= 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 );
+ 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 );
+ 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* pPg = rIo.Get( nPage, TRUE );
+ if( !pPg )
+ return FALSE;
+ pPg->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 nPos, BOOL bForce, BOOL bDirty )
+{
+ if( Pos2Page( nPos ) )
+ {
+ 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( ( 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 += 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 += 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 += nRes;
+ nPos += nRes;
+ n -= nRes;
+ 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 += nRes;
+ nPos += nRes;
+ n -= nRes;
+ 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 )
+ {
+ void* 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();
+ DirEntry aEntry( aName );
+ aEntry.Kill();
+ delete pStrm;
+ }
+}
+
+ULONG StgTmpStrm::GetSize()
+{
+ 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 )
+ {
+ DirEntry aEntry;
+ aEntry = aEntry.TempName();
+ aName = aEntry.GetFull();
+ SvFileStream* s = new SvFileStream( aName, STREAM_READWRITE );
+ ULONG nCur = Tell();
+ ULONG i = nEndOfData;
+ if( i )
+ {
+ void* 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..a63d664d6967
--- /dev/null
+++ b/sot/source/sdstor/stgstrms.hxx
@@ -0,0 +1,201 @@
+/*************************************************************************
+ *
+ * $RCSfile: stgstrms.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:56:52 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _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:
+ ~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& );
+ 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;
+ 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();
+};
+
+#endif
diff --git a/sot/source/sdstor/storage.cxx b/sot/source/sdstor/storage.cxx
new file mode 100644
index 000000000000..c47f107b30ca
--- /dev/null
+++ b/sot/source/sdstor/storage.cxx
@@ -0,0 +1,948 @@
+/*************************************************************************
+ *
+ * $RCSfile: storage.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:56:52 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <stg.hxx>
+#include <storinfo.hxx>
+#include <storage.hxx>
+
+#ifndef _TOOLS_FSYS_HXX
+#include <tools/fsys.hxx>
+#endif
+#ifndef _CACHESTR_HXX //autogen
+#include <tools/cachestr.hxx>
+#endif
+#include <tools/debug.hxx>
+#pragma hdrstop
+
+/************** 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 nStorageMode)
+ : SvStream( MakeLockBytes_Impl( rName, nMode ) )
+ , pOwnStm( NULL )
+{
+ if( nMode & STREAM_WRITE )
+ bIsWritable = TRUE;
+ else
+ bIsWritable = FALSE;
+
+ DBG_ASSERT( !nStorageMode,"StorageModes ignored" )
+}
+
+SotStorageStream::SotStorageStream( StorageStream * pStm )
+{
+ if( STREAM_WRITE & pStm->GetMode() )
+ bIsWritable = TRUE;
+ else
+ bIsWritable = FALSE;
+
+ pOwnStm = pStm;
+ SetError( pStm->GetError() );
+ pStm->ResetError();
+}
+
+SotStorageStream::SotStorageStream()
+ : pOwnStm( NULL )
+{
+ // ??? wenn Init virtuell ist, entsprechen setzen
+ bIsWritable = TRUE;
+}
+
+/************************************************************************
+|* SotStorageStream::~SotStorageStream()
+|*
+|* Beschreibung
+*************************************************************************/
+SotStorageStream::~SotStorageStream()
+{
+
+ SetBufferSize( 0 );
+ // Hack, wegen Fehler in den SD-Storages
+ // Commit();
+ 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
+ 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 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;
+}
+
+/************** 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() \
+ : nError( SVSTREAM_OK ) \
+ , bIsRoot( FALSE ) \
+ , bDelStm( FALSE ) \
+ , nVersion( SOFFICE_FILEFORMAT_NOW ) \
+ , pTmpStg( NULL ) \
+ , pOwnStg( NULL ) \
+ , pStorStm( NULL )
+
+SotStorage::SotStorage()
+ INIT_SotStorage()
+{
+}
+
+#define ERASEMASK ( STREAM_TRUNC | STREAM_WRITE | STREAM_SHARE_DENYALL )
+
+SotStorage::SotStorage( const String & rName, StreamMode nMode,
+ StorageMode nStorageMode )
+ INIT_SotStorage()
+{
+ aName = rName; // Namen merken
+ // Sicherheitshalber wird die Storage File geloescht, wenn
+ // sie neu erzeugt werden soll
+ if( aName.Len() && ( ( nMode & ERASEMASK ) == ERASEMASK ) )
+ {
+ DirEntry aFile( rName );
+ aFile.Kill();
+ }
+
+ pTmpStg = new Storage( aName, nMode,
+ (nStorageMode & STORAGE_TRANSACTED) ? FALSE : TRUE );
+ pOwnStg = pTmpStg;
+ if( !aName.Len() )
+ aName = pOwnStg->GetName();
+ ULONG nErr = pOwnStg->GetError();
+ SetError( nErr );
+}
+
+SotStorage::SotStorage( Storage * pStor )
+ INIT_SotStorage()
+{
+ aName = pStor->GetName(); // Namen merken
+ SignAsRoot( pStor->IsRoot() );
+ SetError( pStor->GetError() );
+ pOwnStg = pStor;
+ ULONG nErr = pOwnStg->GetError();
+ SetError( nErr );
+}
+
+SotStorage::SotStorage( SvStream & rStm )
+ INIT_SotStorage()
+{
+ SetError( rStm.GetError() );
+ pOwnStg = new Storage( rStm, FALSE );
+}
+
+SotStorage::SotStorage( SvStream * pStm, BOOL bDelete )
+ INIT_SotStorage()
+{
+ SetError( pStm->GetError() );
+ pOwnStg = new Storage( *pStm, FALSE );
+
+ ULONG nError = pOwnStg->GetError();
+ if ( nError != SVSTREAM_OK )
+ SetError( nError );
+
+ pStorStm = pStm;
+ bDelStm = bDelete;
+}
+
+/*************************************************************************
+|* SotStorage::~SotStorage()
+|*
+|* Beschreibung
+*************************************************************************/
+SotStorage::~SotStorage()
+{
+ delete pOwnStg;
+ if( bDelStm )
+ delete pStorStm;
+}
+
+
+/*************************************************************************
+|* 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;
+ }
+ return pStm;
+}
+
+/*************************************************************************
+|* SotStorage::GetStorage()
+|*
+|* Beschreibung
+*************************************************************************/
+BOOL SotStorage::IsStorageFile( const String & rFileName )
+{
+ return Storage::IsStorageFile( rFileName );
+}
+
+/*************************************************************************
+|* SotStorage::GetStorage()
+|*
+|* Beschreibung
+*************************************************************************/
+const String & SotStorage::GetName() const
+{
+ if( !aName.Len() )
+ {
+ DBG_ASSERT( Owner(), "must be owner" )
+ if( pOwnStg )
+ ((SotStorage *)this)->aName = pOwnStg->GetName();
+ }
+ return 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!" );
+ aName = rName;
+}
+
+/*************************************************************************
+|* SotStorage::ResetError()
+|*
+|* Beschreibung
+*************************************************************************/
+void SotStorage::ResetError()
+{
+ nError = SVSTREAM_OK;
+ if( pOwnStg )
+ 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( pOwnStg )
+ 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( pOwnStg )
+ 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( pOwnStg )
+ aGN = pOwnStg->GetClassName();
+ else
+ SetError( SVSTREAM_GENERALERROR );
+ return aGN;
+}
+
+ULONG SotStorage::GetFormat()
+{
+ ULONG nFormat = 0;
+ DBG_ASSERT( Owner(), "must be owner" )
+ if( pOwnStg )
+ nFormat = pOwnStg->GetFormat();
+ else
+ SetError( SVSTREAM_GENERALERROR );
+ return nFormat;
+}
+
+String SotStorage::GetUserName()
+{
+ String aName;
+ DBG_ASSERT( Owner(), "must be owner" )
+ if( pOwnStg )
+ aName = pOwnStg->GetUserName();
+ else
+ SetError( SVSTREAM_GENERALERROR );
+ return aName;
+}
+
+BOOL SotStorage::ShouldConvert()
+{
+ DBG_ASSERT( Owner(), "must be owner" )
+ if( pOwnStg )
+ return pOwnStg->ShouldConvert();
+ else
+ SetError( SVSTREAM_GENERALERROR );
+ return FALSE;
+}
+
+/*************************************************************************
+|* SotStorage::FillInfoList()
+|*
+|* Beschreibung
+*************************************************************************/
+void SotStorage::FillInfoList( SvStorageInfoList * pFillList ) const
+{
+ DBG_ASSERT( Owner(), "must be owner" )
+ if( pOwnStg )
+ 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( pOwnStg && pDestStg->pOwnStg )
+ {
+ pOwnStg->CopyTo( pDestStg->pOwnStg );
+ SetError( pOwnStg->GetError() );
+ pDestStg->aKey = aKey;
+ pDestStg->nVersion = nVersion;
+ }
+ else
+ SetError( SVSTREAM_GENERALERROR );
+ return SVSTREAM_OK == GetError();
+}
+
+/*************************************************************************
+|* SotStorage::Commit()
+|*
+|* Beschreibung
+*************************************************************************/
+BOOL SotStorage::Commit()
+{
+ DBG_ASSERT( Owner(), "must be owner" )
+ if( pOwnStg )
+ {
+ if( !pOwnStg->Commit() )
+ SetError( pOwnStg->GetError() );
+ }
+ else
+ SetError( SVSTREAM_GENERALERROR );
+ return SVSTREAM_OK == GetError();
+}
+
+/*************************************************************************
+|* SotStorage::Revert()
+|*
+|* Beschreibung
+*************************************************************************/
+BOOL SotStorage::Revert()
+{
+ DBG_ASSERT( Owner(), "must be owner" )
+ if( pOwnStg )
+ {
+ if( !pOwnStg->Revert() )
+ SetError( pOwnStg->GetError() );
+ }
+ else
+ SetError( SVSTREAM_GENERALERROR );
+ return SVSTREAM_OK == GetError();
+}
+
+/*************************************************************************
+|* SotStorage::OpenStream()
+|*
+|* Beschreibung
+*************************************************************************/
+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( pOwnStg )
+ {
+ // volle Ole-Patches einschalten
+ // egal was kommt, nur exclusiv gestattet
+ nMode |= STREAM_SHARE_DENYALL;
+ ErrCode nE = pOwnStg->GetError();
+ StorageStream * p = pOwnStg->OpenStream( rEleName, nMode,
+ (nStorageMode & STORAGE_TRANSACTED) ? FALSE : TRUE );
+ pStm = new SotStorageStream( p );
+ if( !nE )
+ 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( pOwnStg )
+ {
+ nMode |= STREAM_SHARE_DENYALL;
+ ErrCode nE = pOwnStg->GetError();
+ Storage * p = pOwnStg->OpenStorage( rEleName, nMode,
+ (nStorageMode & STORAGE_TRANSACTED) ? FALSE : TRUE );
+ pStor = new SotStorage( p );
+ if( !nE )
+ 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( pOwnStg )
+ return pOwnStg->IsStorage( rEleName );
+ return FALSE;
+}
+
+BOOL SotStorage::IsStream( const String & rEleName ) const
+{
+ DBG_ASSERT( Owner(), "must be owner" )
+ // ein bisschen schneller
+ if( pOwnStg )
+ return pOwnStg->IsStream( rEleName );
+ return FALSE;
+}
+
+BOOL SotStorage::IsContained( const String & rEleName ) const
+{
+ DBG_ASSERT( Owner(), "must be owner" )
+ // ein bisschen schneller
+ if( pOwnStg )
+ return pOwnStg->IsContained( rEleName );
+ return FALSE;
+}
+
+/*************************************************************************
+|* SotStorage::Remove()
+|*
+|* Beschreibung
+*************************************************************************/
+BOOL SotStorage::Remove( const String & rEleName )
+{
+ DBG_ASSERT( Owner(), "must be owner" )
+ if( pOwnStg )
+ {
+ pOwnStg->Remove( rEleName );
+ SetError( 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( pOwnStg )
+ {
+ pOwnStg->Rename( rEleName, rNewName );
+ SetError( 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( pOwnStg )
+ {
+ pOwnStg->CopyTo( rEleName, pNewSt->pOwnStg, rNewName );
+ SetError( 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( pOwnStg )
+ {
+ pOwnStg->MoveTo( rEleName, pNewSt->pOwnStg, rNewName );
+ SetError( 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( pOwnStg )
+ pResult = pOwnStg->GetSvStream();
+ return pResult;
+}
+
+SvStream* SotStorage::GetTargetSvStream() const
+{
+ SvStream* pResult = 0;
+ DBG_ASSERT( Owner(), "must be owner" )
+ if( pOwnStg )
+ pResult = (SvStream*)(pOwnStg->GetSvStream());
+ return pResult;
+}
+
+
+BOOL SotStorage::Validate()
+{
+ DBG_ASSERT( bIsRoot, "Validate nur an Rootstorage" );
+ if( pOwnStg )
+ return pOwnStg->ValidateFAT();
+ else
+ return TRUE;
+}
+
+
diff --git a/sot/source/sdstor/storinfo.cxx b/sot/source/sdstor/storinfo.cxx
new file mode 100644
index 000000000000..04aef46f9bab
--- /dev/null
+++ b/sot/source/sdstor/storinfo.cxx
@@ -0,0 +1,143 @@
+/*************************************************************************
+ *
+ * $RCSfile: storinfo.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:56:52 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <stg.hxx>
+#include <storinfo.hxx>
+#include <exchange.hxx>
+#pragma hdrstop
+
+
+/************** 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 )
+{
+ ULONG 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, 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
+}
+
+