summaryrefslogtreecommitdiff
path: root/binfilter/bf_basic
diff options
context:
space:
mode:
Diffstat (limited to 'binfilter/bf_basic')
-rw-r--r--binfilter/bf_basic/source/basmgr/basmgr.cxx2668
-rw-r--r--binfilter/bf_basic/source/basmgr/makefile.mk49
-rw-r--r--binfilter/bf_basic/source/classes/image.cxx450
-rw-r--r--binfilter/bf_basic/source/classes/makefile.mk59
-rw-r--r--binfilter/bf_basic/source/classes/sb.cxx1416
-rw-r--r--binfilter/bf_basic/source/classes/sbintern.cxx79
-rw-r--r--binfilter/bf_basic/source/classes/sbunoobj.cxx2710
-rw-r--r--binfilter/bf_basic/source/classes/sbxmod.cxx1447
-rw-r--r--binfilter/bf_basic/source/comp/buffer.cxx173
-rw-r--r--binfilter/bf_basic/source/comp/codegen.cxx232
-rw-r--r--binfilter/bf_basic/source/comp/makefile.mk64
-rw-r--r--binfilter/bf_basic/source/comp/parser.cxx872
-rw-r--r--binfilter/bf_basic/source/comp/sbcomp.cxx113
-rw-r--r--binfilter/bf_basic/source/comp/scanner.cxx559
-rw-r--r--binfilter/bf_basic/source/comp/token.cxx575
-rw-r--r--binfilter/bf_basic/source/inc/buffer.hxx66
-rw-r--r--binfilter/bf_basic/source/inc/codegen.hxx96
-rw-r--r--binfilter/bf_basic/source/inc/filefmt.hxx185
-rw-r--r--binfilter/bf_basic/source/inc/image.hxx109
-rw-r--r--binfilter/bf_basic/source/inc/opcodes.hxx168
-rw-r--r--binfilter/bf_basic/source/inc/sbintern.hxx141
-rw-r--r--binfilter/bf_basic/source/inc/sbjsmeth.hxx60
-rw-r--r--binfilter/bf_basic/source/inc/sbjsmod.hxx54
-rw-r--r--binfilter/bf_basic/source/inc/sbunoobj.hxx250
-rw-r--r--binfilter/bf_basic/source/inc/scanner.hxx147
-rw-r--r--binfilter/bf_basic/source/inc/token.hxx159
-rw-r--r--binfilter/bf_basic/source/runtime/basrdll.cxx92
-rw-r--r--binfilter/bf_basic/source/runtime/makefile.mk82
-rw-r--r--binfilter/bf_basic/source/sbx/makefile.mk77
-rw-r--r--binfilter/bf_basic/source/sbx/sbxarray.cxx784
-rw-r--r--binfilter/bf_basic/source/sbx/sbxbase.cxx426
-rw-r--r--binfilter/bf_basic/source/sbx/sbxbool.cxx251
-rw-r--r--binfilter/bf_basic/source/sbx/sbxbyte.cxx333
-rw-r--r--binfilter/bf_basic/source/sbx/sbxchar.cxx323
-rw-r--r--binfilter/bf_basic/source/sbx/sbxcoll.cxx303
-rw-r--r--binfilter/bf_basic/source/sbx/sbxconv.hxx158
-rw-r--r--binfilter/bf_basic/source/sbx/sbxcurr.cxx399
-rw-r--r--binfilter/bf_basic/source/sbx/sbxdate.cxx416
-rw-r--r--binfilter/bf_basic/source/sbx/sbxdbl.cxx301
-rw-r--r--binfilter/bf_basic/source/sbx/sbxdec.cxx742
-rw-r--r--binfilter/bf_basic/source/sbx/sbxdec.hxx127
-rw-r--r--binfilter/bf_basic/source/sbx/sbxexec.cxx402
-rw-r--r--binfilter/bf_basic/source/sbx/sbxint.cxx970
-rw-r--r--binfilter/bf_basic/source/sbx/sbxlng.cxx345
-rw-r--r--binfilter/bf_basic/source/sbx/sbxobj.cxx926
-rw-r--r--binfilter/bf_basic/source/sbx/sbxres.cxx94
-rw-r--r--binfilter/bf_basic/source/sbx/sbxres.hxx93
-rw-r--r--binfilter/bf_basic/source/sbx/sbxscan.cxx517
-rw-r--r--binfilter/bf_basic/source/sbx/sbxsng.cxx363
-rw-r--r--binfilter/bf_basic/source/sbx/sbxstr.cxx246
-rw-r--r--binfilter/bf_basic/source/sbx/sbxuint.cxx335
-rw-r--r--binfilter/bf_basic/source/sbx/sbxulng.cxx325
-rw-r--r--binfilter/bf_basic/source/sbx/sbxvalue.cxx1710
-rw-r--r--binfilter/bf_basic/source/sbx/sbxvar.cxx565
-rw-r--r--binfilter/bf_basic/util/makefile.mk88
55 files changed, 24694 insertions, 0 deletions
diff --git a/binfilter/bf_basic/source/basmgr/basmgr.cxx b/binfilter/bf_basic/source/basmgr/basmgr.cxx
new file mode 100644
index 000000000000..cc1b0e1f7da4
--- /dev/null
+++ b/binfilter/bf_basic/source/basmgr/basmgr.cxx
@@ -0,0 +1,2668 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <tools/stream.hxx>
+#include <sot/storage.hxx>
+#include <tools/urlobj.hxx>
+#include <bf_svtools/smplhint.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/window.hxx>
+#include <vcl/wrkwin.hxx>
+#include <vcl/msgbox.hxx>
+#include <sbx.hxx>
+#include <sot/storinfo.hxx>
+#include <bf_svtools/pathoptions.hxx>
+#include <tools/debug.hxx>
+
+#include <sbmod.hxx>
+
+#include "basmgr.hxx"
+#include "sbintern.hxx"
+
+
+#define LIB_SEP 0x01
+#define LIBINFO_SEP 0x02
+#define LIBINFO_ID 0x1491
+#define PASSWORD_MARKER 0x31452134
+
+
+// Library API, implemented for XML import/export
+
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/container/XContainer.hpp>
+#include <com/sun/star/script/XStarBasicAccess.hpp>
+#include <com/sun/star/script/XStarBasicModuleInfo.hpp>
+#include <com/sun/star/script/XStarBasicDialogInfo.hpp>
+#include <com/sun/star/script/XStarBasicLibraryInfo.hpp>
+
+#include <cppuhelper/implbase1.hxx>
+
+namespace binfilter {
+
+using namespace com::sun::star::container;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::script;
+using namespace cppu;
+using namespace rtl;
+
+typedef WeakImplHelper1< XNameContainer > NameContainerHelper;
+typedef WeakImplHelper1< XStarBasicModuleInfo > ModuleInfoHelper;
+typedef WeakImplHelper1< XStarBasicDialogInfo > DialogInfoHelper;
+typedef WeakImplHelper1< XStarBasicLibraryInfo > LibraryInfoHelper;
+typedef WeakImplHelper1< XStarBasicAccess > StarBasicAccessHelper;
+
+
+#define CURR_VER 2
+
+// Version 1
+// ULONG nEndPos
+// USHORT nId
+// USHORT nVer
+// BOOL bDoLoad
+// String LibName
+// String AbsStorageName
+// String RelStorageName
+// Version 2
+// + BOOL bReference
+
+static const char szStdLibName[] = "Standard";
+static const char szBasicStorage[] = "StarBASIC";
+static const char szOldManagerStream[] = "BasicManager";
+static const char szManagerStream[] = "BasicManager2";
+static const char szImbedded[] = "LIBIMBEDDED";
+static const char szCryptingKey[] = "CryptedBasic";
+static const char szScriptLanguage[] = "StarBasic";
+
+static const String BasicStreamName( RTL_CONSTASCII_USTRINGPARAM(szBasicStorage) );
+static const String ManagerStreamName( RTL_CONSTASCII_USTRINGPARAM(szManagerStream) );
+
+#define DEFINE_CONST_UNICODE(CONSTASCII) UniString(RTL_CONSTASCII_USTRINGPARAM(CONSTASCII))
+
+
+TYPEINIT1( BasicManager, SfxBroadcaster );
+DBG_NAME( BasicManager );
+
+StreamMode eStreamReadMode = STREAM_READ | STREAM_NOCREATE | STREAM_SHARE_DENYALL;
+StreamMode eStorageReadMode = STREAM_READ | STREAM_SHARE_DENYWRITE;
+
+DECLARE_LIST( BasErrorLst, BasicError* )
+
+
+//----------------------------------------------------------------------------
+// BasicManager impl data
+struct BasicManagerImpl
+{
+ LibraryContainerInfo* mpInfo;
+
+ // Save stream data
+ SvMemoryStream* mpManagerStream;
+ SvMemoryStream** mppLibStreams;
+ sal_Int32 mnLibStreamCount;
+ sal_Bool mbModifiedByLibraryContainer;
+ sal_Bool mbError;
+
+ BasicManagerImpl( void )
+ : mpInfo( NULL )
+ , mpManagerStream( NULL )
+ , mppLibStreams( NULL )
+ , mnLibStreamCount( 0 )
+ , mbModifiedByLibraryContainer( sal_False )
+ , mbError( sal_False )
+ {}
+ ~BasicManagerImpl();
+};
+
+BasicManagerImpl::~BasicManagerImpl()
+{
+ delete mpInfo;
+ delete mpManagerStream;
+ if( mppLibStreams )
+ {
+ for( sal_Int32 i = 0 ; i < mnLibStreamCount ; i++ )
+ delete mppLibStreams[i];
+ delete[] mppLibStreams;
+ }
+}
+
+//============================================================================
+// BasMgrContainerListenerImpl
+//============================================================================
+
+typedef ::cppu::WeakImplHelper1< ::com::sun::star::container::XContainerListener > ContainerListenerHelper;
+
+class BasMgrContainerListenerImpl: public ContainerListenerHelper
+{
+ BasicManager* mpMgr;
+ OUString maLibName; // empty -> no lib, but lib container
+
+public:
+ BasMgrContainerListenerImpl( BasicManager* pMgr, OUString aLibName )
+ : mpMgr( pMgr )
+ , maLibName( aLibName ) {}
+
+ static void insertLibraryImpl( const Reference< XLibraryContainer >& xScriptCont, BasicManager* pMgr,
+ Any aLibAny, OUString aLibName );
+ static void addLibraryModulesImpl( BasicManager* pMgr, Reference< XNameAccess > xLibNameAccess,
+ OUString aLibName );
+
+
+ // XEventListener
+ virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source )
+ throw(::com::sun::star::uno::RuntimeException);
+
+ // XContainerListener
+ virtual void SAL_CALL elementInserted( const ::com::sun::star::container::ContainerEvent& Event )
+ throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL elementReplaced( const ::com::sun::star::container::ContainerEvent& Event )
+ throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL elementRemoved( const ::com::sun::star::container::ContainerEvent& Event )
+ throw(::com::sun::star::uno::RuntimeException);
+};
+
+
+//============================================================================
+// BasMgrContainerListenerImpl
+//============================================================================
+
+void BasMgrContainerListenerImpl::insertLibraryImpl( const Reference< XLibraryContainer >& xScriptCont,
+ BasicManager* pMgr, Any aLibAny, OUString aLibName )
+{
+ Reference< XNameAccess > xLibNameAccess;
+ aLibAny >>= xLibNameAccess;
+
+ if( !pMgr->GetLib( aLibName ) )
+ {
+ BasicManager* pBasMgr = static_cast< BasicManager* >( pMgr );
+#ifdef DBG_UTIL
+ StarBASIC* pLib =
+#endif
+ pBasMgr->CreateLibForLibContainer( aLibName, xScriptCont );
+ DBG_ASSERT( pLib, "XML Import: Basic library could not be created");
+ }
+
+ Reference< XContainer> xLibContainer( xLibNameAccess, UNO_QUERY );
+ if( xLibContainer.is() )
+ {
+ // Register listener for library
+ Reference< XContainerListener > xLibraryListener
+ = static_cast< XContainerListener* >
+ ( new BasMgrContainerListenerImpl( pMgr, aLibName ) );
+ xLibContainer->addContainerListener( xLibraryListener );
+ }
+
+ if( xScriptCont->isLibraryLoaded( aLibName ) )
+ {
+ addLibraryModulesImpl( pMgr, xLibNameAccess, aLibName );
+ }
+}
+
+
+void BasMgrContainerListenerImpl::addLibraryModulesImpl( BasicManager* pMgr,
+ Reference< XNameAccess > xLibNameAccess, OUString aLibName )
+{
+ OUString aScriptLanguage = DEFINE_CONST_UNICODE( szScriptLanguage );
+ Sequence< OUString > aModuleNames = xLibNameAccess->getElementNames();
+ sal_Int32 nModuleCount = aModuleNames.getLength();
+
+ StarBASIC* pLib = pMgr->GetLib( aLibName );
+ DBG_ASSERT( pLib, "BasMgrContainerListenerImpl::addLibraryModulesImpl: Unknown lib!");
+ if( pLib )
+ {
+ const OUString* pNames = aModuleNames.getConstArray();
+ for( sal_Int32 j = 0 ; j < nModuleCount ; j++ )
+ {
+ OUString aModuleName = pNames[ j ];
+ Any aElement = xLibNameAccess->getByName( aModuleName );
+ OUString aMod;
+ aElement >>= aMod;
+ pLib->MakeModule32( aModuleName, aMod );
+ }
+ }
+
+ pLib->SetModified( FALSE );
+}
+
+
+
+// XEventListener
+//----------------------------------------------------------------------------
+
+void SAL_CALL BasMgrContainerListenerImpl::disposing( const EventObject& Source )
+ throw( RuntimeException )
+{
+ (void)Source;
+}
+
+// XContainerListener
+//----------------------------------------------------------------------------
+
+void SAL_CALL BasMgrContainerListenerImpl::elementInserted( const ContainerEvent& Event )
+ throw( RuntimeException )
+{
+ sal_Bool bLibContainer = ( maLibName.getLength() == 0 );
+ OUString aName;
+ Event.Accessor >>= aName;
+
+ mpMgr->mpImpl->mbModifiedByLibraryContainer = sal_True;
+
+ if( bLibContainer )
+ {
+ Reference< XLibraryContainer > xScriptCont( Event.Source, UNO_QUERY );
+ insertLibraryImpl( xScriptCont, mpMgr, Event.Element, aName );
+ }
+ else
+ {
+ OUString aScriptLanguage = DEFINE_CONST_UNICODE( szScriptLanguage );
+ OUString aMod;
+ Event.Element >>= aMod;
+
+ StarBASIC* pLib = mpMgr->GetLib( maLibName );
+ DBG_ASSERT( pLib, "BasMgrContainerListenerImpl::elementInserted: Unknown lib!");
+ if( pLib )
+ {
+ SbModule* pMod = pLib->FindModule( aName );
+ if( !pMod )
+ {
+ pLib->MakeModule32( aName, aMod );
+ pLib->SetModified( FALSE );
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+
+void SAL_CALL BasMgrContainerListenerImpl::elementReplaced( const ContainerEvent& Event )
+ throw( RuntimeException )
+{
+ OUString aName;
+ Event.Accessor >>= aName;
+
+ mpMgr->mpImpl->mbModifiedByLibraryContainer = sal_True;
+
+ // Replace not possible for library container
+#ifdef DBG_UTIL
+ sal_Bool bLibContainer = ( maLibName.getLength() == 0 );
+#endif
+ DBG_ASSERT( !bLibContainer, "library container fired elementReplaced()");
+
+ StarBASIC* pLib = mpMgr->GetLib( maLibName );
+ if( pLib )
+ {
+ SbModule* pMod = pLib->FindModule( aName );
+ OUString aMod;
+ Event.Element >>= aMod;
+ if( pMod )
+ pMod->SetSource32( aMod );
+ else
+ pLib->MakeModule32( aName, aMod );
+
+ pLib->SetModified( FALSE );
+ }
+}
+
+//----------------------------------------------------------------------------
+
+void SAL_CALL BasMgrContainerListenerImpl::elementRemoved( const ContainerEvent& Event )
+ throw( RuntimeException )
+{
+ OUString aName;
+ Event.Accessor >>= aName;
+
+ mpMgr->mpImpl->mbModifiedByLibraryContainer = sal_True;
+
+ sal_Bool bLibContainer = ( maLibName.getLength() == 0 );
+ if( bLibContainer )
+ {
+ StarBASIC* pLib = mpMgr->GetLib( aName );
+ if( pLib )
+ {
+ USHORT nLibId = mpMgr->GetLibId( aName );
+ mpMgr->RemoveLib( nLibId, FALSE );
+ }
+ }
+ else
+ {
+ StarBASIC* pLib = mpMgr->GetLib( maLibName );
+ SbModule* pMod = pLib ? pLib->FindModule( aName ) : NULL;
+ if( pMod )
+ {
+ pLib->Remove( pMod );
+ pLib->SetModified( FALSE );
+ }
+ }
+}
+
+
+//=====================================================================
+
+class BasicErrorManager
+{
+private:
+ BasErrorLst aErrorList;
+
+public:
+ ~BasicErrorManager();
+
+ void Reset();
+ void InsertError( const BasicError& rError );
+
+ BOOL HasErrors() { return (BOOL)aErrorList.Count(); }
+ BasicError* GetFirstError() { return aErrorList.First(); }
+ BasicError* GetNextError() { return aErrorList.Next(); }
+};
+
+
+BasicErrorManager::~BasicErrorManager()
+{
+ Reset();
+}
+
+void BasicErrorManager::Reset()
+{
+ BasicError* pError = (BasicError*)aErrorList.First();
+ while ( pError )
+ {
+ delete pError;
+ pError = (BasicError*)aErrorList.Next();
+ }
+ aErrorList.Clear();
+}
+
+void BasicErrorManager::InsertError( const BasicError& rError )
+{
+ aErrorList.Insert( new BasicError( rError ), LIST_APPEND );
+}
+
+BasicError::BasicError( ULONG nId, USHORT nR, const String& rErrStr ) :
+ aErrStr( rErrStr )
+{
+ nErrorId = nId;
+ nReason = nR;
+}
+
+BasicError::BasicError( const BasicError& rErr ) :
+ aErrStr( rErr.aErrStr )
+{
+ nErrorId = rErr.nErrorId;
+ nReason = rErr.nReason;
+}
+
+
+class BasicLibInfo
+{
+private:
+ StarBASICRef xLib;
+ String aLibName;
+ String aStorageName; // String reicht, da zur Laufzeit eindeutig.
+ String aRelStorageName;
+ String aPassword;
+
+ BOOL bDoLoad;
+ BOOL bReference;
+ BOOL bPasswordVerified;
+ BOOL bFoundInPath; // Darf dann nicht neu relativiert werden!
+
+ // Lib represents library in new UNO library container
+ Reference< XLibraryContainer > mxScriptCont;
+
+public:
+ BasicLibInfo();
+
+ BOOL IsReference() const { return bReference; }
+ BOOL& IsReference() { return bReference; }
+
+ BOOL IsExtern() const { return ! aStorageName.EqualsAscii(szImbedded); }
+
+ void SetStorageName( const String& rName ) { aStorageName = rName; }
+ const String& GetStorageName() const { return aStorageName; }
+
+ void SetRelStorageName( const String& rN ) { aRelStorageName = rN; }
+ const String& GetRelStorageName() const { return aRelStorageName; }
+ void CalcRelStorageName( const String& rMgrStorageName );
+
+ StarBASICRef GetLib() const
+ {
+ if( mxScriptCont.is() && mxScriptCont->hasByName( aLibName ) &&
+ !mxScriptCont->isLibraryLoaded( aLibName ) )
+ return StarBASICRef();
+ return xLib;
+ }
+ StarBASICRef& GetLibRef() { return xLib; }
+ void SetLib( StarBASIC* pBasic ) { xLib = pBasic; }
+
+ const String& GetLibName() const { return aLibName; }
+ void SetLibName( const String& rName ) { aLibName = rName; }
+
+ // Nur temporaer fuer Laden/Speichern....
+ BOOL DoLoad() { return bDoLoad; }
+
+ BOOL HasPassword() const { return aPassword.Len() != 0; }
+ const String& GetPassword() const { return aPassword; }
+ void SetPassword( const String& rNewPassword )
+ { aPassword = rNewPassword; }
+ BOOL IsPasswordVerified() const { return bPasswordVerified; }
+ void SetPasswordVerified() { bPasswordVerified = TRUE; }
+
+ BOOL IsFoundInPath() const { return bFoundInPath; }
+ void SetFoundInPath( BOOL bInPath ) { bFoundInPath = bInPath; }
+
+ void Store( SotStorageStream& rSStream, const String& rBasMgrStorageName, BOOL bUseOldReloadInfo );
+ static BasicLibInfo* Create( SotStorageStream& rSStream );
+
+ Reference< XLibraryContainer > GetLibraryContainer( void )
+ { return mxScriptCont; }
+ void SetLibraryContainer( const Reference< XLibraryContainer >& xScriptCont )
+ { mxScriptCont = xScriptCont; }
+};
+
+DECLARE_LIST( BasicLibsBase, BasicLibInfo* )
+
+class BasicLibs : public BasicLibsBase
+{
+public:
+ String aBasicLibPath; // soll eigentlich Member vom Manager werden, aber jetzt nicht inkompatibel!
+};
+
+BasicLibInfo::BasicLibInfo()
+{
+ bReference = FALSE;
+ bPasswordVerified = FALSE;
+ bDoLoad = FALSE;
+ bFoundInPath = FALSE;
+ mxScriptCont = NULL;
+ aStorageName = String::CreateFromAscii(szImbedded);
+ aRelStorageName = String::CreateFromAscii(szImbedded);
+}
+
+void BasicLibInfo::Store( SotStorageStream& rSStream, const String& rBasMgrStorageName, BOOL bUseOldReloadInfo )
+{
+ ULONG nStartPos = rSStream.Tell();
+ sal_uInt32 nEndPos = 0;
+
+ USHORT nId = LIBINFO_ID;
+ USHORT nVer = CURR_VER;
+
+ rSStream << nEndPos;
+ rSStream << nId;
+ rSStream << nVer;
+
+ String aCurStorageName = INetURLObject(rBasMgrStorageName, INET_PROT_FILE).GetMainURL( INetURLObject::NO_DECODE );
+ DBG_ASSERT(aCurStorageName.Len() != 0, "Bad storage name");
+
+ // Falls nicht gesetzt, StorageName initialisieren
+ if ( aStorageName.Len() == 0 )
+ aStorageName = aCurStorageName;
+
+ // Wieder laden?
+ BOOL bDoLoad_ = xLib.Is();
+ if ( bUseOldReloadInfo )
+ bDoLoad_ = DoLoad();
+ rSStream << bDoLoad_;
+
+ // Den Namen der Lib...
+ rSStream.WriteByteString(GetLibName());
+
+ // Absoluter Pfad....
+ if ( ! GetStorageName().EqualsAscii(szImbedded) )
+ {
+ String aSName = INetURLObject( GetStorageName(), INET_PROT_FILE).GetMainURL( INetURLObject::NO_DECODE );
+ DBG_ASSERT(aSName.Len() != 0, "Bad storage name");
+ rSStream.WriteByteString( aSName );
+ }
+ else
+ rSStream.WriteByteString( szImbedded );
+
+ // Relativer Pfad...
+ if ( ( aStorageName == aCurStorageName ) || ( aStorageName.EqualsAscii(szImbedded) ) )
+ rSStream.WriteByteString( szImbedded );
+ else
+ {
+ // Nicht den relativen Pfad ermitteln, wenn die Datei nur im Pfad
+ // gefunden wurde: Dann andert sich der relative Pfad und nach einem
+ // verschieben der Libs in einen anderen Pfad werden sie nicht gefunden.
+ if ( !IsFoundInPath() )
+ CalcRelStorageName( aCurStorageName );
+ rSStream.WriteByteString(aRelStorageName);
+ }
+
+ // ------------------------------
+ // Version 2
+ // ------------------------------
+
+ // Referenz...
+ rSStream << bReference;
+
+ // ------------------------------
+ // Schluss
+ // ------------------------------
+
+ nEndPos = rSStream.Tell();
+ rSStream.Seek( nStartPos );
+ rSStream << nEndPos;
+ rSStream.Seek( nEndPos );
+}
+
+BasicLibInfo* BasicLibInfo::Create( SotStorageStream& rSStream )
+{
+ BasicLibInfo* pInfo = new BasicLibInfo;
+
+ sal_uInt32 nEndPos;
+ USHORT nId;
+ USHORT nVer;
+
+ rSStream >> nEndPos;
+ rSStream >> nId;
+ rSStream >> nVer;
+
+ DBG_ASSERT( nId == LIBINFO_ID, "Keine BasicLibInfo !?" );
+ if( nId == LIBINFO_ID )
+ {
+ // Wieder laden?
+ BOOL bDoLoad;
+ rSStream >> bDoLoad;
+ pInfo->bDoLoad = bDoLoad;
+
+ // Den Namen der Lib...
+ String aName;
+ rSStream.ReadByteString(aName);
+ pInfo->SetLibName( aName );
+
+ // Absoluter Pfad....
+ String aStorageName;
+ rSStream.ReadByteString(aStorageName);
+ pInfo->SetStorageName( aStorageName );
+
+ // Relativer Pfad...
+ String aRelStorageName;
+ rSStream.ReadByteString(aRelStorageName);
+ pInfo->SetRelStorageName( aRelStorageName );
+
+ if ( nVer >= 2 )
+ {
+ BOOL bReferenz;
+ rSStream >> bReferenz;
+ pInfo->IsReference() = bReferenz;
+ }
+
+ rSStream.Seek( nEndPos );
+ }
+ return pInfo;
+}
+
+void BasicLibInfo::CalcRelStorageName( const String& rMgrStorageName )
+{
+ if ( rMgrStorageName.Len() )
+ {
+ INetURLObject aAbsURLObj( rMgrStorageName );
+ aAbsURLObj.removeSegment();
+ String aPath = aAbsURLObj.GetMainURL( INetURLObject::NO_DECODE );
+ UniString aRelURL = INetURLObject::GetRelURL( aPath, GetStorageName() );
+ SetRelStorageName( aRelURL );
+ }
+ else
+ SetRelStorageName( String() );
+}
+
+BasicManager::BasicManager( SotStorage& rStorage, const String& rBaseURL, StarBASIC* pParentFromStdLib, String* pLibPath )
+{
+ DBG_CTOR( BasicManager, 0 );
+
+ Init();
+
+ if( pLibPath )
+ pLibs->aBasicLibPath = *pLibPath;
+
+ String aStorName( rStorage.GetName() );
+ maStorageName = INetURLObject(aStorName, INET_PROT_FILE).GetMainURL( INetURLObject::NO_DECODE );
+
+ // #91251: Storage name not longer available for documents < 5.0
+ // Should be no real problem, because only relative storage names
+ // (links) can be affected.
+ // DBG_ASSERT( aStorName.Len(), "No Storage Name!" );
+ // DBG_ASSERT(aStorageName.Len() != 0, "Bad storage name");
+
+ // Wenn es den Manager-Stream nicht gibt, sind keine weiteren
+ // Aktionen noetig.
+ if ( rStorage.IsStream( ManagerStreamName ) )
+ {
+ LoadBasicManager( rStorage, rBaseURL );
+ // StdLib erhaelt gewuenschten Parent:
+ StarBASIC* pStdLib = GetStdLib();
+ DBG_ASSERT( pStdLib, "Standard-Lib nicht geladen?" );
+ if ( !pStdLib )
+ {
+ // Sollte eigentlich nie passieren, aber dann wenigstens nicht abstuerzen...
+ pStdLib = new StarBASIC;
+ BasicLibInfo* pStdLibInfo = pLibs->GetObject( 0 );
+ if ( !pStdLibInfo )
+ pStdLibInfo = CreateLibInfo();
+ pStdLibInfo->SetLib( pStdLib );
+ StarBASICRef xStdLib = pStdLibInfo->GetLib();
+ xStdLib->SetName( String::CreateFromAscii(szStdLibName) );
+ pStdLibInfo->SetLibName( String::CreateFromAscii(szStdLibName) );
+ xStdLib->SetFlag( SBX_DONTSTORE | SBX_EXTSEARCH );
+ xStdLib->SetModified( FALSE );
+ }
+ else
+ {
+ pStdLib->SetParent( pParentFromStdLib );
+ // Die anderen erhalten die StdLib als Parent:
+ for ( USHORT nBasic = 1; nBasic < GetLibCount(); nBasic++ )
+ {
+ StarBASIC* pBasic = GetLib( nBasic );
+ if ( pBasic )
+ {
+// pBasic->SetParent( pStdLib );
+ pStdLib->Insert( pBasic );
+ pBasic->SetFlag( SBX_EXTSEARCH );
+ }
+ }
+ // Durch das Insert modified:
+ pStdLib->SetModified( FALSE );
+ }
+
+ // #91626 Save all stream data to save it unmodified if basic isn't modified
+ // in an 6.0+ office. So also the old basic dialogs can be saved.
+ SotStorageStreamRef xManagerStream = rStorage.OpenSotStream
+ ( ManagerStreamName, eStreamReadMode );
+ mpImpl->mpManagerStream = new SvMemoryStream();
+ *static_cast<SvStream*>(&xManagerStream) >> *mpImpl->mpManagerStream;
+
+ SotStorageRef xBasicStorage = rStorage.OpenSotStorage
+ ( BasicStreamName, eStorageReadMode, FALSE );
+ if( xBasicStorage.Is() && !xBasicStorage->GetError() )
+ {
+ USHORT nLibs = GetLibCount();
+ mpImpl->mppLibStreams = new SvMemoryStream*[ nLibs ];
+ for( USHORT nL = 0; nL < nLibs; nL++ )
+ {
+ BasicLibInfo* pInfo = pLibs->GetObject( nL );
+ DBG_ASSERT( pInfo, "pInfo?!" );
+ SotStorageStreamRef xBasicStream = xBasicStorage->OpenSotStream( pInfo->GetLibName(), eStreamReadMode );
+ mpImpl->mppLibStreams[nL] = new SvMemoryStream();
+ *static_cast<SvStream*>(&xBasicStream) >> *( mpImpl->mppLibStreams[nL] );
+ }
+ }
+ else
+ mpImpl->mbError = sal_True;
+ }
+ else
+ {
+ ImpCreateStdLib( pParentFromStdLib );
+ if ( rStorage.IsStream( String::CreateFromAscii(szOldManagerStream) ) )
+ LoadOldBasicManager( rStorage );
+ }
+
+ bBasMgrModified = FALSE;
+}
+
+
+void copyToLibraryContainer( StarBASIC* pBasic, LibraryContainerInfo* pInfo )
+{
+ Reference< XLibraryContainer > xScriptCont;
+ String aLibName = pBasic->GetName();
+ if( pInfo && (xScriptCont = pInfo->mxScriptCont).is() )
+ {
+ if( !xScriptCont->hasByName( aLibName ) )
+ xScriptCont->createLibrary( aLibName );
+
+ Any aLibAny = xScriptCont->getByName( aLibName );
+ Reference< XNameContainer > xLib;
+ aLibAny >>= xLib;
+ if( xLib.is() )
+ {
+ USHORT nModCount = pBasic->GetModules()->Count();
+ for ( USHORT nMod = 0 ; nMod < nModCount ; nMod++ )
+ {
+ SbModule* pModule = (SbModule*)pBasic->GetModules()->Get( nMod );
+ DBG_ASSERT( pModule, "Modul nicht erhalten!" );
+
+ String aModName = pModule->GetName();
+ if( !xLib->hasByName( aModName ) )
+ {
+ OUString aSource = pModule->GetSource32();
+ Any aSourceAny;
+ aSourceAny <<= aSource;
+ xLib->insertByName( aModName, aSourceAny );
+ }
+ }
+ }
+ }
+}
+
+void BasicManager::SetLibraryContainerInfo( LibraryContainerInfo* pInfo )
+{
+ if( !pInfo )
+ return;
+ mpImpl->mpInfo = pInfo;
+
+ Reference< XLibraryContainer > xScriptCont;
+ StarBASIC* pStdLib = GetStdLib();
+ String aLibName = pStdLib->GetName();
+ if( mpImpl->mpInfo && (xScriptCont = mpImpl->mpInfo->mxScriptCont).is() )
+ {
+ OUString aScriptLanguage = DEFINE_CONST_UNICODE( "StarBasic" );
+
+ // Register listener for lib container
+ OUString aEmptyLibName;
+ Reference< XContainerListener > xLibContainerListener
+ = static_cast< XContainerListener* >
+ ( new BasMgrContainerListenerImpl( this, aEmptyLibName ) );
+
+ Reference< XContainer> xLibContainer( xScriptCont, UNO_QUERY );
+ xLibContainer->addContainerListener( xLibContainerListener );
+
+ Sequence< OUString > aNames = xScriptCont->getElementNames();
+ const OUString* pNames = aNames.getConstArray();
+ sal_Int32 i, nNameCount = aNames.getLength();
+
+ if( nNameCount )
+ {
+ for( i = 0 ; i < nNameCount ; i++ )
+ {
+ OUString aLibName2 = pNames[ i ];
+ Any aLibAny = xScriptCont->getByName( aLibName2 );
+
+ if( String( aLibName2 ).EqualsAscii( "Standard" ) )
+ xScriptCont->loadLibrary( aLibName2 );
+
+ BasMgrContainerListenerImpl::insertLibraryImpl
+ ( xScriptCont, this, aLibAny, aLibName2 );
+ }
+ }
+ else
+ {
+ // No libs? Maybe an 5.2 document already loaded
+ USHORT nLibs = GetLibCount();
+ for( USHORT nL = 0; nL < nLibs; nL++ )
+ {
+ BasicLibInfo* pBasLibInfo = pLibs->GetObject( nL );
+ StarBASIC* pLib = pBasLibInfo->GetLib();
+ if( !pLib )
+ {
+ BOOL bLoaded = ImpLoadLibary( pBasLibInfo, NULL, FALSE );
+ if( bLoaded )
+ pLib = pBasLibInfo->GetLib();
+ }
+ if( pLib )
+ {
+ copyToLibraryContainer( pLib, mpImpl->mpInfo );
+ if( pBasLibInfo->HasPassword() )
+ {
+ OldBasicPassword* pOldBasicPassword =
+ mpImpl->mpInfo->mpOldBasicPassword;
+ if( pOldBasicPassword )
+ {
+ pOldBasicPassword->setLibraryPassword
+ ( pLib->GetName(), pBasLibInfo->GetPassword() );
+ pBasLibInfo->SetPasswordVerified();
+ }
+ }
+ }
+ }
+
+ mpImpl->mbModifiedByLibraryContainer = sal_False;
+ }
+ }
+}
+
+BasicManager::BasicManager( StarBASIC* pSLib, String* pLibPath )
+{
+ DBG_CTOR( BasicManager, 0 );
+ Init();
+ DBG_ASSERT( pSLib, "BasicManager kann nicht mit einem NULL-Pointer erzeugt werden!" );
+
+ if( pLibPath )
+ pLibs->aBasicLibPath = *pLibPath;
+
+ BasicLibInfo* pStdLibInfo = CreateLibInfo();
+ pStdLibInfo->SetLib( pSLib );
+ StarBASICRef xStdLib = pStdLibInfo->GetLib();
+ xStdLib->SetName( String::CreateFromAscii(szStdLibName));
+ pStdLibInfo->SetLibName( String::CreateFromAscii(szStdLibName) );
+ pSLib->SetFlag( SBX_DONTSTORE | SBX_EXTSEARCH );
+
+ // Speichern lohnt sich nur, wenn sich das Basic aendert.
+ xStdLib->SetModified( FALSE );
+ bBasMgrModified = FALSE;
+}
+
+BasicManager::BasicManager()
+{
+ DBG_CTOR( BasicManager, 0 );
+ // Diese CTOR darf nur verwendet werden um bei 'Speichern unter'
+ // die relativen Pfade anzupassen, das gibt kein AppBasic und somit
+ // duerfen auch keine Libs geladen werden...
+ Init();
+}
+
+BOOL BasicManager::HasBasicWithModules( const SotStorage& rStorage, const String& rBaseURL )
+{
+ if( !rStorage.IsStream( ManagerStreamName ) )
+ return FALSE;
+
+ StarBASIC* pDummyParentBasic = new StarBASIC();
+ BasicManager* pBasMgr = new BasicManager( (SotStorage&)rStorage, rBaseURL, pDummyParentBasic );
+ BOOL bRet = FALSE;
+
+ USHORT nLibs = pBasMgr->GetLibCount();
+ for( USHORT nL = 0; nL < nLibs; nL++ )
+ {
+ BasicLibInfo* pInfo = pBasMgr->pLibs->GetObject( nL );
+ StarBASIC* pLib = pInfo->GetLib();
+ if( !pLib )
+ {
+ BOOL bLoaded = pBasMgr->ImpLoadLibary( pInfo, NULL, FALSE );
+ if( bLoaded )
+ pLib = pInfo->GetLib();
+ }
+ if( pLib )
+ {
+ SbxArray* pModules = pLib->GetModules();
+ if( pModules->Count() )
+ {
+ bRet = TRUE;
+ break;
+ }
+ }
+ }
+
+ delete pBasMgr;
+ return bRet;
+}
+
+void BasicManager::ImpMgrNotLoaded( const String& rStorageName )
+{
+ // pErrInf wird nur zerstoert, wenn der Fehler von einem ErrorHandler
+ // gehandelt wird!
+// String aErrorText( BasicResId( IDS_SBERR_MGROPEN ) );
+// aErrorText.SearchAndReplace( "XX", rStorageName );
+ StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_MGROPEN, rStorageName, ERRCODE_BUTTON_OK );
+ pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_OPENMGRSTREAM, rStorageName ) );
+
+ // Eine STD-Lib erzeugen, sonst macht es Peng!
+ BasicLibInfo* pStdLibInfo = CreateLibInfo();
+ pStdLibInfo->SetLib( new StarBASIC );
+ StarBASICRef xStdLib = pStdLibInfo->GetLib();
+ xStdLib->SetName( String::CreateFromAscii(szStdLibName) );
+ pStdLibInfo->SetLibName( String::CreateFromAscii(szStdLibName) );
+ xStdLib->SetFlag( SBX_DONTSTORE | SBX_EXTSEARCH );
+ xStdLib->SetModified( FALSE );
+}
+
+
+void BasicManager::ImpCreateStdLib( StarBASIC* pParentFromStdLib )
+{
+ BasicLibInfo* pStdLibInfo = CreateLibInfo();
+ StarBASIC* pStdLib = new StarBASIC( pParentFromStdLib );
+ pStdLibInfo->SetLib( pStdLib );
+ pStdLib->SetName( String::CreateFromAscii(szStdLibName) );
+ pStdLibInfo->SetLibName( String::CreateFromAscii(szStdLibName) );
+ pStdLib->SetFlag( SBX_DONTSTORE | SBX_EXTSEARCH );
+}
+
+
+void BasicManager::LoadBasicManager( SotStorage& rStorage, const String& rBaseURL, BOOL bLoadLibs )
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+
+// StreamMode eStreamMode = STREAM_READ | STREAM_NOCREATE | STREAM_SHARE_DENYWRITE;
+
+ SotStorageStreamRef xManagerStream = rStorage.OpenSotStream
+ ( ManagerStreamName, eStreamReadMode );
+
+ String aStorName( rStorage.GetName() );
+ // #i13114 removed, DBG_ASSERT( aStorName.Len(), "No Storage Name!" );
+
+ if ( !xManagerStream.Is() || xManagerStream->GetError() || ( xManagerStream->Seek( STREAM_SEEK_TO_END ) == 0 ) )
+ {
+ ImpMgrNotLoaded( aStorName );
+ return;
+ }
+
+ maStorageName = INetURLObject(aStorName, INET_PROT_FILE).GetMainURL( INetURLObject::NO_DECODE );
+ // #i13114 removed, DBG_ASSERT(aStorageName.Len() != 0, "Bad storage name");
+
+ String aRealStorageName = maStorageName; // fuer relative Pfade, kann durch BaseURL umgebogen werden.
+
+ // Wenn aus Vorlagen geladen wird, gilt nur die BaseURL:
+ //String aBaseURL = INetURLObject::GetBaseURL();
+ if ( rBaseURL.Len() )
+ {
+ INetURLObject aObj( rBaseURL );
+ if ( aObj.GetProtocol() == INET_PROT_FILE )
+ aRealStorageName = aObj.PathToFileName();
+ }
+
+ xManagerStream->SetBufferSize( 1024 );
+ xManagerStream->Seek( STREAM_SEEK_TO_BEGIN );
+
+ sal_uInt32 nEndPos;
+ *xManagerStream >> nEndPos;
+
+ USHORT nLibs;
+ *xManagerStream >> nLibs;
+ // Plausi!
+ if( nLibs & 0xF000 )
+ {
+ DBG_ASSERT( !this, "BasicManager-Stream defekt!" );
+ return;
+ }
+ for ( USHORT nL = 0; nL < nLibs; nL++ )
+ {
+ BasicLibInfo* pInfo = BasicLibInfo::Create( *xManagerStream );
+
+ // ggf. absoluten Pfad-Namen korrigieren, wenn rel. existiert
+ // Immer erst den relativen versuchen, falls zwei Staende auf der Platte
+ if ( pInfo->GetRelStorageName().Len() && ( ! pInfo->GetRelStorageName().EqualsAscii(szImbedded) ) )
+ {
+ INetURLObject aObj( aRealStorageName, INET_PROT_FILE );
+ aObj.removeSegment();
+ bool bWasAbsolute = FALSE;
+ aObj = aObj.smartRel2Abs( pInfo->GetRelStorageName(), bWasAbsolute );
+
+ //*** TODO: Replace if still necessary
+ /* if ( SfxContentHelper::Exists( aObj.GetMainURL() ) )
+ pInfo->SetStorageName( aObj.GetMainURL() );
+ else */
+ //*** TODO-End
+ if ( pLibs->aBasicLibPath.Len() )
+ {
+ // Lib im Pfad suchen...
+ String aSearchFile = pInfo->GetRelStorageName();
+ SvtPathOptions aPathCFG;
+ if( aPathCFG.SearchFile( aSearchFile, SvtPathOptions::PATH_BASIC ) )
+ {
+ pInfo->SetStorageName( aSearchFile );
+ pInfo->SetFoundInPath( TRUE );
+ }
+ }
+ }
+
+ pLibs->Insert( pInfo, LIST_APPEND );
+ // Libs aus externen Dateien sollen erst bei Bedarf geladen werden.
+ // Aber Referenzen werden gleich geladen, sonst bekommen die Grosskunden
+ // vielleicht Probleme...
+ if ( bLoadLibs && pInfo->DoLoad() &&
+ ( ( !pInfo->IsExtern() ) || ( pInfo->IsReference() ) ) )
+ {
+ ImpLoadLibary( pInfo, &rStorage );
+ }
+ }
+
+ xManagerStream->Seek( nEndPos );
+ xManagerStream->SetBufferSize( 0 );
+ xManagerStream.Clear();
+}
+
+void BasicManager::LoadOldBasicManager( SotStorage& rStorage )
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+
+// StreamMode eStreamMode = STREAM_READ | STREAM_NOCREATE | STREAM_SHARE_DENYWRITE;
+
+ SotStorageStreamRef xManagerStream = rStorage.OpenSotStream
+ ( String::CreateFromAscii(szOldManagerStream), eStreamReadMode );
+
+ String aStorName( rStorage.GetName() );
+ DBG_ASSERT( aStorName.Len(), "No Storage Name!" );
+
+ if ( !xManagerStream.Is() || xManagerStream->GetError() || ( xManagerStream->Seek( STREAM_SEEK_TO_END ) == 0 ) )
+ {
+ ImpMgrNotLoaded( aStorName );
+ return;
+ }
+
+ xManagerStream->SetBufferSize( 1024 );
+ xManagerStream->Seek( STREAM_SEEK_TO_BEGIN );
+ sal_uInt32 nBasicStartOff, nBasicEndOff;
+ *xManagerStream >> nBasicStartOff;
+ *xManagerStream >> nBasicEndOff;
+
+ DBG_ASSERT( !xManagerStream->GetError(), "Ungueltiger Manager-Stream!" );
+
+ xManagerStream->Seek( nBasicStartOff );
+ if( !ImplLoadBasic( *xManagerStream, pLibs->GetObject(0)->GetLibRef() ) )
+ {
+// String aErrorText( BasicResId( IDS_SBERR_MGROPEN ) );
+// aErrorText.SearchAndReplace( "XX", aStorName );
+ StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_MGROPEN, aStorName, ERRCODE_BUTTON_OK );
+ pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_OPENMGRSTREAM, aStorName ) );
+ // und es geht weiter...
+ }
+ xManagerStream->Seek( nBasicEndOff+1 ); // +1: 0x00 als Trenner
+ String aLibs;
+ xManagerStream->ReadByteString(aLibs);
+ xManagerStream->SetBufferSize( 0 );
+ xManagerStream.Clear(); // Sream schliessen
+
+ if ( aLibs.Len() )
+ {
+ String aCurStorageName( aStorName );
+ INetURLObject aCurStorage( aCurStorageName, INET_PROT_FILE );
+ USHORT nLibs = aLibs.GetTokenCount( LIB_SEP );
+ for ( USHORT nLib = 0; nLib < nLibs; nLib++ )
+ {
+ String aLibInfo( aLibs.GetToken( nLib, LIB_SEP ) );
+ // == 2 soll irgendwann weg!
+ DBG_ASSERT( ( aLibInfo.GetTokenCount( LIBINFO_SEP ) == 2 ) || ( aLibInfo.GetTokenCount( LIBINFO_SEP ) == 3 ), "Ungueltige Lib-Info!" );
+ String aLibName( aLibInfo.GetToken( 0, LIBINFO_SEP ) );
+ String aLibAbsStorageName( aLibInfo.GetToken( 1, LIBINFO_SEP ) );
+ String aLibRelStorageName( aLibInfo.GetToken( 2, LIBINFO_SEP ) );
+ INetURLObject aLibAbsStorage( aLibAbsStorageName, INET_PROT_FILE );
+
+ INetURLObject aLibRelStorage( aStorName );
+ aLibRelStorage.removeSegment();
+ bool bWasAbsolute = FALSE;
+ aLibRelStorage = aLibRelStorage.smartRel2Abs( aLibRelStorageName, bWasAbsolute);
+ DBG_ASSERT(!bWasAbsolute, "RelStorageName was absolute!" );
+
+ SotStorageRef xStorageRef;
+ if ( ( aLibAbsStorage == aCurStorage ) || ( aLibRelStorageName.EqualsAscii(szImbedded) ) )
+ xStorageRef = &rStorage;
+ else
+ {
+ xStorageRef = new SotStorage( FALSE, aLibAbsStorage.GetMainURL
+ ( INetURLObject::NO_DECODE ), eStorageReadMode, TRUE );
+ if ( xStorageRef->GetError() != ERRCODE_NONE )
+ xStorageRef = new SotStorage( FALSE, aLibRelStorage.
+ GetMainURL( INetURLObject::NO_DECODE ), eStorageReadMode, TRUE );
+ }
+ if ( xStorageRef.Is() )
+ AddLib( *xStorageRef, aLibName, FALSE );
+ else
+ {
+// String aErrorText( BasicResId( IDS_SBERR_LIBLOAD ) );
+// aErrorText.SearchAndReplace( "XX", aLibName );
+ StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_LIBLOAD, aStorName, ERRCODE_BUTTON_OK );
+ pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_STORAGENOTFOUND, aStorName ) );
+ }
+ }
+ }
+}
+
+BasicManager::~BasicManager()
+{
+ DBG_DTOR( BasicManager, 0 );
+
+ // Listener benachrichtigen, falls noch etwas zu Speichern...
+ Broadcast( SfxSimpleHint( SFX_HINT_DYING) );
+
+ // Basic-Infos zerstoeren...
+ // In umgekehrter Reihenfolge, weil die StdLib Referenzen haelt, die
+ // anderen nur die StdLib als Parent haben.
+ BasicLibInfo* pInf = pLibs->Last();
+ while ( pInf )
+ {
+ delete pInf;
+ pInf = pLibs->Prev();
+ }
+ pLibs->Clear();
+ delete pLibs;
+ delete pErrorMgr;
+ delete mpImpl;
+}
+
+void BasicManager::LegacyDeleteBasicManager( BasicManager*& _rpManager )
+{
+ delete _rpManager;
+ _rpManager = NULL;
+}
+
+void BasicManager::Init()
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+
+ bBasMgrModified = FALSE;
+ pErrorMgr = new BasicErrorManager;
+ pLibs = new BasicLibs;
+ mpImpl = new BasicManagerImpl();
+}
+
+BasicLibInfo* BasicManager::CreateLibInfo()
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+
+ BasicLibInfo* pInf = new BasicLibInfo;
+ pLibs->Insert( pInf, LIST_APPEND );
+ return pInf;
+}
+
+BOOL BasicManager::CopyBasicData( SotStorage* pStorFrom, const String& rSourceURL, const String& rBaseURL, SotStorage* pStorTo )
+{
+ /*-----------------------------------------------------------------
+ Diese Methode wird vom SXF gerufen bei 'Datei speichern unter',
+ damit die Basic-Storages kopiert werden.
+ Neu: ggf. muessen relative Pfade angepasst werden!
+ ------------------------------------------------------------------*/
+ BOOL bOk = TRUE;
+
+ // bei remote Dokumenten identische Storage
+ if ( pStorFrom != pStorTo )
+ {
+ if( pStorFrom->IsStorage( BasicStreamName ) )
+ bOk = pStorFrom->CopyTo( BasicStreamName, pStorTo, BasicStreamName );
+ if( bOk && pStorFrom->IsStream( ManagerStreamName ) )
+ {
+ // bOk = pStorFrom->CopyTo( szManagerStream, pStorTo, szManagerStream );
+ BasicManager aBasMgr;
+ // Die aktuelle Base-URL ist die vom speichern...
+ String aStorName( pStorFrom->GetName() );
+ DBG_ASSERT( aStorName.Len(), "No Storage Name!" );
+
+ aBasMgr.LoadBasicManager( *pStorFrom, rSourceURL, FALSE );
+ aBasMgr.Store( *pStorTo, rBaseURL, FALSE );
+ }
+ }
+
+ return bOk;
+}
+
+void BasicManager::Store( SotStorage& rStorage, const String& rBaseURL )
+{
+ Store( rStorage, rBaseURL, TRUE );
+}
+
+void BasicManager::Store( SotStorage& rStorage, const String& rBaseURL, BOOL bStoreLibs )
+{
+ // #91626
+ sal_Bool bModified = mpImpl->mbModifiedByLibraryContainer || mpImpl->mbError;
+
+ // #92172 Password handling
+ OldBasicPassword* pOldBasicPassword = NULL;
+ USHORT nLibs = GetLibCount();
+ if( mpImpl->mpInfo )
+ pOldBasicPassword = mpImpl->mpInfo->mpOldBasicPassword;
+ if( pOldBasicPassword )
+ {
+ Reference< XLibraryContainer > xScriptCont = mpImpl->mpInfo->mxScriptCont;
+ for( USHORT nL = 0; nL < nLibs; nL++ )
+ {
+ BasicLibInfo* pInfo = pLibs->GetObject( nL );
+ DBG_ASSERT( pInfo, "pInfo?!" );
+
+ String aLibName = pInfo->GetLibName();
+ sal_Bool bPassword = pOldBasicPassword->hasLibraryPassword( aLibName );
+ String aPassword = pOldBasicPassword->getLibraryPassword( aLibName );
+ if( pInfo->GetPassword() != aPassword )
+ bModified = sal_True;
+
+ if( xScriptCont.is() && xScriptCont->hasByName( aLibName ) )
+ xScriptCont->loadLibrary( aLibName );
+
+ if( bPassword && aPassword.Len() == 0 )
+ {
+ String aDummySource( String::CreateFromAscii(
+ "REM This module belonged to a password protected library that was exported without\n"
+ "REM verifying the password. So the original module source could not be exported!\n"
+ "sub main\n"
+ "end sub\n" ) );
+ Any aDummySourceAny;
+ aDummySourceAny <<= OUString( aDummySource );
+
+ if( xScriptCont.is() && xScriptCont->hasByName( aLibName ) )
+ {
+ // Now the library isn't password protected any more
+ // but the modules don't contain any source
+ pOldBasicPassword->clearLibraryPassword( aLibName );
+
+ Any aLibAny = xScriptCont->getByName( aLibName );
+ Reference< XNameContainer > xLib;
+ aLibAny >>= xLib;
+
+ Sequence< OUString > aNames = xLib->getElementNames();
+ sal_Int32 nNameCount = aNames.getLength();
+ const OUString* pNames = aNames.getConstArray();
+ for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
+ {
+ OUString aElementName = pNames[ i ];
+ xLib->replaceByName( aElementName, aDummySourceAny );
+ }
+ }
+
+ StarBASIC* pBasic = GetLib( aLibName );
+ if( pBasic )
+ {
+ SbxArray* pModules = pBasic->GetModules();
+ USHORT nModCount = pModules->Count();
+ for( USHORT j = 0; j < nModCount ; j++ )
+ {
+ SbModule* pMod = (SbModule*)pModules->Get( j );
+ pMod->SetSource32( aDummySource );
+ pMod->Compile();
+ }
+ }
+
+ bModified = sal_True;
+ }
+ else
+ {
+ if( pInfo->GetPassword().Len() != 0 )
+ bModified = sal_True;
+ pInfo->SetPassword( aPassword );
+ }
+ }
+ }
+
+ // #91626
+ if( !bModified && bStoreLibs && mpImpl->mpManagerStream )
+ {
+ // Store saved streams
+ SotStorageStreamRef xManagerStream = rStorage.OpenSotStream(
+ ManagerStreamName, STREAM_STD_READWRITE | STREAM_TRUNC );
+ //ManagerStreamName, STREAM_STD_READWRITE /* | STREAM_TRUNC */ );
+ // STREAM_TRUNC buggy??!!! Then
+ // xManagerStream->Seek( 0 );
+ mpImpl->mpManagerStream->Seek( 0 );
+ *static_cast<SvStream*>(&xManagerStream) << *mpImpl->mpManagerStream;
+
+ SotStorageRef xBasicStorage = rStorage.OpenSotStorage
+ ( BasicStreamName, STREAM_STD_READWRITE, FALSE );
+
+ if ( xBasicStorage.Is() && !xBasicStorage->GetError() )
+ {
+ for( USHORT nL = 0; nL < nLibs; nL++ )
+ {
+ BasicLibInfo* pInfo = pLibs->GetObject( nL );
+ DBG_ASSERT( pInfo, "pInfo?!" );
+ SotStorageStreamRef xBasicStream = xBasicStorage->OpenSotStream( pInfo->GetLibName(), STREAM_STD_READWRITE );
+ mpImpl->mppLibStreams[nL]->Seek( 0 );
+ *static_cast<SvStream*>(&xBasicStream) << *( mpImpl->mppLibStreams[nL] );
+ }
+
+ xBasicStorage->Commit();
+ }
+ return;
+ }
+
+
+ DBG_CHKTHIS( BasicManager, 0 );
+ // Neue Bibliotheken sind nicht unbedingt modified, muessen aber trotzdem
+ // gespeichert werden.
+ BOOL bStoreAll = FALSE;
+ if ( bStoreLibs && !rStorage.IsStorage( BasicStreamName ) )
+ bStoreAll = TRUE;
+
+ SotStorageStreamRef xManagerStream = rStorage.OpenSotStream( ManagerStreamName, STREAM_STD_READWRITE /* | STREAM_TRUNC */ );
+ // Assertion, weil es eigentlich nie vorkommen darf.
+ DBG_ASSERT( xManagerStream.Is(), "Kein ManagerStream!");
+
+ ClearErrors();
+
+ String aStorName( rStorage.GetName() );
+ DBG_ASSERT( aStorName.Len(), "No Storage Name!" );
+
+ if ( !xManagerStream.Is() || xManagerStream->GetError() )
+ {
+// String aErrorText( BasicResId( IDS_SBERR_MGRSAVE ) );
+// aErrorText.SearchAndReplace( "XX", aStorName );
+ StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_MGRSAVE, aStorName, ERRCODE_BUTTON_OK );
+ ((BasicManager*)this)->pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_OPENMGRSTREAM, aStorName ) );
+ }
+ else
+ {
+ maStorageName = aStorName;
+
+ // Funktioniert nicht, auber auch OPEN_TRUNC nicht (UAE in OLE32)
+ // => Erst mal den alten Schrott stehen lassen!
+// xManagerStream->SetSize( 0 );
+ xManagerStream->SetBufferSize( 1024 );
+ xManagerStream->Seek( 0 );
+
+ ULONG nStartPos = 0;
+ sal_uInt32 nEndPos = 0;
+ *xManagerStream << nEndPos;
+
+ // Fehlerabfrage, falls schreiben nicht moeglich ?
+ DBG_ASSERT( !xManagerStream->GetError(), "Unerwarteter Fehler beim Schreiben des Manager-Streams" );
+
+
+ // Die Namen der Libs und der Storages...
+// DirEntry aCurStorage( aStorName() );
+// aCurStorage.ToAbs();
+ String aLibInfo;
+ *xManagerStream << nLibs;
+ for ( USHORT nL = 0; nL < nLibs; nL++ )
+ {
+ BasicLibInfo* pInfo = pLibs->GetObject( nL );
+ DBG_ASSERT( pInfo, "pInfo?!" );
+
+ String aStrgName = GetStorageName();
+
+ // Falls ins Temp-Verzeichniss gesichert wird, sollte der richtige
+ // Storage-Name an der globalen URL haengen...
+ //String aBaseURL = INetURLObject::GetBaseURL();
+ if ( rBaseURL.Len() )
+ {
+ INetURLObject aObj( rBaseURL );
+ if ( aObj.GetProtocol() == INET_PROT_FILE )
+ aStrgName = aObj.PathToFileName();
+ }
+
+ pInfo->Store( *xManagerStream, aStrgName, !bStoreLibs );
+ }
+
+ nEndPos = xManagerStream->Tell();
+ xManagerStream->Seek( nStartPos );
+ *xManagerStream << nEndPos;
+ xManagerStream->Seek( nEndPos );
+ xManagerStream->SetBufferSize( 0 );
+ xManagerStream.Clear();
+ }
+
+ // Und dann die Libs in den entsprechenden Storages...
+ if ( bStoreLibs )
+ {
+ String aCurStorage( aStorName );
+ for ( USHORT nL = 0; nL < nLibs; nL++ )
+ {
+ BasicLibInfo* pInfo = pLibs->GetObject( nL );
+ DBG_ASSERT( pInfo, "Info?!" );
+ StarBASIC* pLib = pInfo->GetLib();
+ if ( pLib && ( pLib->IsModified() || bStoreAll ) ) // 0, wenn nicht geladen...
+ {
+ if ( pInfo->IsReference() )
+ {
+ // Vielleicht nicht modified, aber bStoreAll.
+ // Fehlermeldung nicht, wenn Macro lauft
+ // (also speichern durch Macro)
+ if ( pLib->IsModified() && !StarBASIC::IsRunning() )
+ {
+ String sTemp( String::CreateFromAscii( "Reference will not be saved: " ) );
+ sTemp += pLib->GetName();
+ WarningBox( NULL, WB_OK, sTemp ).Execute();
+ // Einmal meckern reicht.
+ pLib->SetModified( FALSE );
+ }
+ }
+ else
+ {
+ SotStorageRef xStorage;
+ if ( ( pInfo->GetStorageName() != aCurStorage ) && ( !pInfo->GetStorageName().EqualsAscii(szImbedded) ) )
+ xStorage = new SotStorage( FALSE, pInfo->GetStorageName() );
+ else
+ xStorage = &rStorage;
+ ImpStoreLibary( pLib, *xStorage );
+ }
+ }
+ }
+ }
+
+ if ( !HasErrors() )
+ bBasMgrModified = FALSE;
+}
+
+
+BOOL BasicManager::ImpStoreLibary( StarBASIC* pLib, SotStorage& rStorage ) const
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+ DBG_ASSERT( pLib, "pLib = 0 (ImpStorageLibary)" );
+
+ SotStorageRef xBasicStorage = rStorage.OpenSotStorage
+ ( BasicStreamName, STREAM_STD_READWRITE, FALSE );
+
+ String aStorName( rStorage.GetName() );
+ DBG_ASSERT( aStorName.Len(), "No Storage Name!" );
+ if ( !xBasicStorage.Is() || xBasicStorage->GetError() )
+ {
+// String aErrorText( BasicResId( IDS_SBERR_MGRSAVE ) );
+// aErrorText.SearchAndReplace( "XX", aStorName );
+ StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_MGRSAVE, aStorName, ERRCODE_BUTTON_OK );
+ ((BasicManager*)this)->pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_OPENLIBSTORAGE, pLib->GetName() ) );
+ }
+ else
+ {
+ // In dem Basic-Storage liegt jede Lib in einem Stream...
+ SotStorageStreamRef xBasicStream = xBasicStorage->OpenSotStream( pLib->GetName(), STREAM_STD_READWRITE );
+ if ( !xBasicStream.Is() || xBasicStream->GetError() )
+ {
+// String aErrorText( BasicResId( IDS_SBERR_LIBSAVE ) );
+// aErrorText.SearchAndReplace( "XX", pLib->GetName() );
+ StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_LIBSAVE, pLib->GetName(), ERRCODE_BUTTON_OK );
+ ((BasicManager*)this)->pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_OPENLIBSTREAM, pLib->GetName() ) );
+ }
+ else
+ {
+ BasicLibInfo* pLibInfo = FindLibInfo( pLib );
+ DBG_ASSERT( pLibInfo, "ImpStoreLibary: LibInfo?!" );
+
+ xBasicStream->SetSize( 0 );
+ xBasicStream->SetBufferSize( 1024 );
+
+ // SBX_DONTSTORE, damit Child-Basics nicht gespeichert werden
+ SetFlagToAllLibs( SBX_DONTSTORE, TRUE );
+ // Aber das hier will ich jetzt speichern:
+ pLib->ResetFlag( SBX_DONTSTORE );
+ if ( pLibInfo->HasPassword() )
+ xBasicStream->SetKey( szCryptingKey );
+ BOOL bDone = pLib->Store( *xBasicStream );
+ xBasicStream->SetBufferSize( 0 );
+ if ( bDone )
+ {
+ // Diese Informationen immer verschluesseln...
+ xBasicStream->SetBufferSize( 1024 );
+ xBasicStream->SetKey( szCryptingKey );
+ *xBasicStream << static_cast<sal_uInt32>(PASSWORD_MARKER);
+ String aTmpPassword = pLibInfo->GetPassword();
+ xBasicStream->WriteByteString( aTmpPassword, RTL_TEXTENCODING_MS_1252 );
+ xBasicStream->SetBufferSize( 0 );
+ }
+ // Vorsichtshalber alle Dont't Store lassen...
+ pLib->SetFlag( SBX_DONTSTORE );
+// SetFlagToAllLibs( SBX_DONTSTORE, FALSE );
+ pLib->SetModified( FALSE );
+ if( !xBasicStorage->Commit() )
+ bDone = FALSE;
+ xBasicStream->SetKey( ByteString() );
+ DBG_ASSERT( bDone, "Warum geht Basic::Store() nicht ?" );
+ return bDone;
+ }
+ }
+ return FALSE;
+}
+
+BOOL BasicManager::ImpLoadLibary( BasicLibInfo* pLibInfo, SotStorage* pCurStorage, BOOL bInfosOnly ) const
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+
+ DBG_ASSERT( pLibInfo, "LibInfo!?" );
+
+ String aStorageName( pLibInfo->GetStorageName() );
+ if ( !aStorageName.Len() || ( aStorageName.EqualsAscii(szImbedded) ) )
+ aStorageName = GetStorageName();
+
+ SotStorageRef xStorage;
+ // Der aktuelle darf nicht nochmal geoffnet werden...
+ if ( pCurStorage )
+ {
+ String aStorName( pCurStorage->GetName() );
+ // #i13114 removed, DBG_ASSERT( aStorName.Len(), "No Storage Name!" );
+
+ INetURLObject aCurStorageEntry(aStorName, INET_PROT_FILE);
+ // #i13114 removed, DBG_ASSERT(aCurStorageEntry.GetMainURL( INetURLObject::NO_DECODE ).Len() != 0, "Bad storage name");
+
+ INetURLObject aStorageEntry(aStorageName, INET_PROT_FILE);
+ // #i13114 removed, DBG_ASSERT(aCurStorageEntry.GetMainURL( INetURLObject::NO_DECODE ).Len() != 0, "Bad storage name");
+
+ if ( aCurStorageEntry == aStorageEntry )
+ xStorage = pCurStorage;
+ }
+
+ if ( !xStorage.Is() )
+ xStorage = new SotStorage( FALSE, aStorageName, eStorageReadMode );
+
+ SotStorageRef xBasicStorage = xStorage->OpenSotStorage
+ ( BasicStreamName, eStorageReadMode, FALSE );
+
+ if ( !xBasicStorage.Is() || xBasicStorage->GetError() )
+ {
+ StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_MGROPEN, xStorage->GetName(), ERRCODE_BUTTON_OK );
+ pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_OPENLIBSTORAGE, pLibInfo->GetLibName() ) );
+ }
+ else
+ {
+ // In dem Basic-Storage liegt jede Lib in einem Stream...
+ SotStorageStreamRef xBasicStream = xBasicStorage->OpenSotStream( pLibInfo->GetLibName(), eStreamReadMode );
+ if ( !xBasicStream.Is() || xBasicStream->GetError() )
+ {
+ StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_LIBLOAD , pLibInfo->GetLibName(), ERRCODE_BUTTON_OK );
+ pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_OPENLIBSTREAM, pLibInfo->GetLibName() ) );
+ }
+ else
+ {
+ BOOL bLoaded = FALSE;
+ if ( xBasicStream->Seek( STREAM_SEEK_TO_END ) != 0 )
+ {
+ if ( !bInfosOnly )
+ {
+ if ( !pLibInfo->GetLib().Is() )
+ pLibInfo->SetLib( new StarBASIC( GetStdLib() ) );
+ xBasicStream->SetBufferSize( 1024 );
+ xBasicStream->Seek( STREAM_SEEK_TO_BEGIN );
+ bLoaded = ImplLoadBasic( *xBasicStream, pLibInfo->GetLibRef() );
+ xBasicStream->SetBufferSize( 0 );
+ StarBASICRef xStdLib = pLibInfo->GetLib();
+ xStdLib->SetName( pLibInfo->GetLibName() );
+ xStdLib->SetModified( FALSE );
+ xStdLib->SetFlag( SBX_DONTSTORE );
+ }
+ else
+ {
+ // Das Basic skippen...
+ xBasicStream->Seek( STREAM_SEEK_TO_BEGIN );
+ ImplEncryptStream( *xBasicStream );
+ SbxBase::Skip( *xBasicStream );
+ bLoaded = TRUE;
+ }
+ }
+ if ( !bLoaded )
+ {
+ StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_LIBLOAD, pLibInfo->GetLibName(), ERRCODE_BUTTON_OK );
+ pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_BASICLOADERROR, pLibInfo->GetLibName() ) );
+ }
+ else
+ {
+ // Ggf. stehen weitere Informationen im Stream...
+ xBasicStream->SetKey( szCryptingKey );
+ xBasicStream->RefreshBuffer();
+ sal_uInt32 nPasswordMarker = 0;
+ *xBasicStream >> nPasswordMarker;
+ if ( ( nPasswordMarker == PASSWORD_MARKER ) && !xBasicStream->IsEof() )
+ {
+ String aPassword;
+ xBasicStream->ReadByteString(aPassword);
+ pLibInfo->SetPassword( aPassword );
+ }
+ xBasicStream->SetKey( ByteString() );
+ CheckModules( pLibInfo->GetLib(), pLibInfo->IsReference() );
+ }
+// bBasMgrModified = TRUE; // Warum?
+ return bLoaded;
+ }
+ }
+ return FALSE;
+}
+
+BOOL BasicManager::ImplEncryptStream( SvStream& rStrm ) const
+{
+ ULONG nPos = rStrm.Tell();
+ UINT32 nCreator;
+ rStrm >> nCreator;
+ rStrm.Seek( nPos );
+ BOOL bProtected = FALSE;
+ if ( nCreator != SBXCR_SBX )
+ {
+ // sollte nur bei verschluesselten Streams nicht stimmen.
+ bProtected = TRUE;
+ rStrm.SetKey( szCryptingKey );
+ rStrm.RefreshBuffer();
+ }
+ return bProtected;
+}
+
+
+// Dieser Code ist notwendig, um das BASIC der Beta 1 laden zu koennen
+BOOL BasicManager::ImplLoadBasic( SvStream& rStrm, StarBASICRef& rOldBasic ) const
+{
+ BOOL bProtected = ImplEncryptStream( rStrm );
+ SbxBaseRef xNew = SbxBase::Load( rStrm );
+ BOOL bLoaded = FALSE;
+ if( xNew.Is() )
+ {
+ if( xNew->IsA( TYPE(StarBASIC) ) )
+ {
+ StarBASIC* pNew = (StarBASIC*)(SbxBase*) xNew;
+ // Den Parent des alten BASICs uebernehmen
+ if( rOldBasic.Is() )
+ {
+ pNew->SetParent( rOldBasic->GetParent() );
+ if( pNew->GetParent() )
+ pNew->GetParent()->Insert( pNew );
+ pNew->SetFlag( SBX_EXTSEARCH );
+ }
+ rOldBasic = pNew;
+
+ // Fill new libray container (5.2 -> 6.0)
+ copyToLibraryContainer( pNew, mpImpl->mpInfo );
+
+/*
+ if( rOldBasic->GetParent() )
+ {
+ rOldBasic->GetParent()->Insert( rOldBasic );
+ rOldBasic->SetFlag( SBX_EXTSEARCH );
+ }
+*/
+ pNew->SetModified( FALSE );
+ bLoaded = TRUE;
+ }
+ }
+ if ( bProtected )
+ rStrm.SetKey( ByteString() );
+ return bLoaded;
+}
+
+void BasicManager::CheckModules( StarBASIC* pLib, BOOL bReference ) const
+{
+ if ( !pLib )
+ return;
+
+ BOOL bModified = pLib->IsModified();
+
+/*?*/ // for ( USHORT nMod = 0; nMod < pLib->GetModules()->Count(); nMod++ )
+/*?*/ // {
+/*?*/ // SbModule* pModule = (SbModule*)pLib->GetModules()->Get( nMod );
+/*?*/ // DBG_ASSERT( pModule, "Modul nicht erhalten!" );
+/*?*/ // if ( !pModule->IsCompiled() && !StarBASIC::GetErrorCode() )
+/*?*/ // pLib->Compile( pModule );
+/*?*/ // }
+
+ // #67477, AB 8.12.99 On demand Compilieren bei referenzierten
+ // Libraries sollte nicht zu modified fuehren
+ if( !bModified && bReference )
+ {
+ DBG_ERROR( "Per Reference eingebundene Basic-Library ist nicht compiliert!" );
+ pLib->SetModified( FALSE );
+ }
+}
+
+
+StarBASIC* BasicManager::AddLib( SotStorage& rStorage, const String& rLibName, BOOL bReference )
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+
+ String aStorName( rStorage.GetName() );
+ DBG_ASSERT( aStorName.Len(), "No Storage Name!" );
+
+ String aStorageName = INetURLObject(aStorName, INET_PROT_FILE).GetMainURL( INetURLObject::NO_DECODE );
+ DBG_ASSERT(aStorageName.Len() != 0, "Bad storage name");
+
+ String aNewLibName( rLibName );
+ while ( HasLib( aNewLibName ) )
+ aNewLibName += '_';
+
+ BasicLibInfo* pLibInfo = CreateLibInfo();
+ // Erstmal mit dem Original-Namen, da sonst ImpLoadLibary nicht geht...
+ pLibInfo->SetLibName( rLibName );
+ // Funktioniert so aber nicht, wenn Name doppelt
+// USHORT nLibId = GetLibId( rLibName );
+ USHORT nLibId = (USHORT) pLibs->GetPos( pLibInfo );
+
+ // Vorm Laden StorageNamen setzen, da er mit pCurStorage verglichen wird.
+ pLibInfo->SetStorageName( aStorageName );
+ BOOL bLoaded = ImpLoadLibary( pLibInfo, &rStorage );
+
+ if ( bLoaded )
+ {
+ if ( aNewLibName != rLibName )
+ SetLibName( nLibId, aNewLibName );
+
+ if ( bReference )
+ {
+ pLibInfo->GetLib()->SetModified( FALSE ); // Dann nicht speichern
+ pLibInfo->SetRelStorageName( String() );
+// pLibInfo->CalcRelStorageName( GetStorageName() );
+ pLibInfo->IsReference() = TRUE;
+ }
+ else
+ {
+ pLibInfo->GetLib()->SetModified( TRUE ); // Muss nach Add gespeichert werden!
+ pLibInfo->SetStorageName( String::CreateFromAscii(szImbedded) ); // Im BasicManager-Storage speichern
+ }
+ bBasMgrModified = TRUE;
+ }
+ else
+ {
+ RemoveLib( nLibId, FALSE );
+ pLibInfo = 0;
+ }
+
+ if( pLibInfo )
+ return &*pLibInfo->GetLib() ;
+ else
+ return 0;
+}
+BOOL BasicManager::IsReference( USHORT nLib )
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+
+ BasicLibInfo* pLibInfo = pLibs->GetObject( nLib );
+ DBG_ASSERT( pLibInfo, "Lib?!" );
+ if ( pLibInfo )
+ return pLibInfo->IsReference();
+
+ return FALSE;
+}
+
+BOOL BasicManager::RemoveLib( USHORT nLib )
+{
+ // Nur physikalisch loeschen, wenn keine Referenz.
+ return RemoveLib( nLib, !IsReference( nLib ) );
+}
+
+BOOL BasicManager::RemoveLib( USHORT nLib, BOOL bDelBasicFromStorage )
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+ DBG_ASSERT( nLib, "Standard-Lib kann nicht entfernt werden!" );
+
+ BasicLibInfo* pLibInfo = pLibs->GetObject( nLib );
+ DBG_ASSERT( pLibInfo, "Lib nicht gefunden!" );
+
+ if ( !pLibInfo || !nLib )
+ {
+// String aErrorText( BasicResId( IDS_SBERR_REMOVELIB ) );
+ StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_REMOVELIB, String(), ERRCODE_BUTTON_OK );
+ pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_STDLIB, pLibInfo->GetLibName() ) );
+ return FALSE;
+ }
+
+ // Wenn einer der Streams nicht geoeffnet werden kann, ist es kein
+ // Fehler, es gibt halt noch nichts zum loeschen, weil das Basic noch
+ // nie geschrieben wurde...
+ if ( bDelBasicFromStorage && !pLibInfo->IsReference() &&
+ ( !pLibInfo->IsExtern() || SotStorage::IsStorageFile( pLibInfo->GetStorageName() ) ) )
+ {
+ SotStorageRef xStorage;
+ if ( !pLibInfo->IsExtern() )
+ xStorage = new SotStorage( FALSE, GetStorageName() );
+ else
+ xStorage = new SotStorage( FALSE, pLibInfo->GetStorageName() );
+
+ if ( xStorage->IsStorage( BasicStreamName ) )
+ {
+ SotStorageRef xBasicStorage = xStorage->OpenSotStorage
+ ( BasicStreamName, STREAM_STD_READWRITE, FALSE );
+
+ if ( !xBasicStorage.Is() || xBasicStorage->GetError() )
+ {
+// String aErrorText( BasicResId( IDS_SBERR_REMOVELIB ) );
+ StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_REMOVELIB, String(), ERRCODE_BUTTON_OK );
+ pErrorMgr->InsertError( BasicError( *pErrInf, BASERR_REASON_OPENLIBSTORAGE, pLibInfo->GetLibName() ) );
+ }
+ else if ( xBasicStorage->IsStream( pLibInfo->GetLibName() ) )
+ {
+ xBasicStorage->Remove( pLibInfo->GetLibName() );
+ xBasicStorage->Commit();
+
+ // Wenn kein weiterer Stream vorhanden,
+ // dann auch den SubStorage loeschen.
+ SvStorageInfoList aInfoList( 0, 4 );
+ xBasicStorage->FillInfoList( &aInfoList );
+ if ( !aInfoList.Count() )
+ {
+ xBasicStorage.Clear();
+ xStorage->Remove( BasicStreamName );
+ xStorage->Commit();
+ // Wenn kein weiterer Streams oder SubStorages vorhanden,
+ // dann auch den Storage loeschen.
+ aInfoList.Clear();
+ xStorage->FillInfoList( &aInfoList );
+ if ( !aInfoList.Count() )
+ {
+ String aName_( xStorage->GetName() );
+ xStorage.Clear();
+ //*** TODO: Replace if still necessary
+ //SfxContentHelper::Kill( aName );
+ //*** TODO-End
+ }
+ }
+ }
+ }
+ }
+ bBasMgrModified = TRUE;
+ if ( pLibInfo->GetLib().Is() )
+ GetStdLib()->Remove( pLibInfo->GetLib() );
+ delete pLibs->Remove( pLibInfo );
+ return TRUE; // Remove hat geklappt, Del unwichtig.
+}
+
+USHORT BasicManager::GetLibCount() const
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+ return (USHORT)pLibs->Count();
+}
+
+StarBASIC* BasicManager::GetLib( USHORT nLib ) const
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+ BasicLibInfo* pInf = pLibs->GetObject( nLib );
+ DBG_ASSERT( pInf, "Lib existiert nicht!" );
+ if ( pInf )
+ return pInf->GetLib();
+ return 0;
+}
+
+StarBASIC* BasicManager::GetStdLib() const
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+ StarBASIC* pLib = GetLib( 0 );
+ return pLib;
+}
+
+StarBASIC* BasicManager::GetLib( const String& rName ) const
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+
+ BasicLibInfo* pInf = pLibs->First();
+ while ( pInf )
+ {
+ if ( pInf->GetLibName().CompareIgnoreCaseToAscii( rName ) == COMPARE_EQUAL ) // prueffen, ob vorhanden...
+ return pInf->GetLib();
+
+ pInf = pLibs->Next();
+ }
+ return 0;
+}
+
+USHORT BasicManager::GetLibId( const String& rName ) const
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+
+ BasicLibInfo* pInf = pLibs->First();
+ while ( pInf )
+ {
+ if ( pInf->GetLibName().CompareIgnoreCaseToAscii( rName ) == COMPARE_EQUAL )
+ return (USHORT)pLibs->GetCurPos();
+
+ pInf = pLibs->Next();
+ }
+ return LIB_NOTFOUND;
+}
+
+BOOL BasicManager::HasLib( const String& rName ) const
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+
+ BasicLibInfo* pInf = pLibs->First();
+ while ( pInf )
+ {
+ if ( pInf->GetLibName().CompareIgnoreCaseToAscii( rName ) == COMPARE_EQUAL )
+ return TRUE;
+
+ pInf = pLibs->Next();
+ }
+ return FALSE;
+}
+
+BOOL BasicManager::SetLibName( USHORT nLib, const String& rName )
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+
+ BasicLibInfo* pLibInfo = pLibs->GetObject( nLib );
+ DBG_ASSERT( pLibInfo, "Lib?!" );
+ if ( pLibInfo )
+ {
+ pLibInfo->SetLibName( rName );
+ if ( pLibInfo->GetLib().Is() )
+ {
+ StarBASICRef xStdLib = pLibInfo->GetLib();
+ xStdLib->SetName( rName );
+ xStdLib->SetModified( TRUE );
+ }
+ bBasMgrModified = TRUE;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+String BasicManager::GetLibName( USHORT nLib )
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+
+ BasicLibInfo* pLibInfo = pLibs->GetObject( nLib );
+ DBG_ASSERT( pLibInfo, "Lib?!" );
+ if ( pLibInfo )
+ return pLibInfo->GetLibName();
+ return String();
+}
+
+StarBASIC* BasicManager::CreateLib( const String& rLibName )
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+ if ( GetLib( rLibName ) )
+ return 0;
+
+ BasicLibInfo* pLibInfo = CreateLibInfo();
+ StarBASIC* pNew = new StarBASIC( GetStdLib() );
+ GetStdLib()->Insert( pNew );
+ pNew->SetFlag( SBX_EXTSEARCH | SBX_DONTSTORE );
+ pLibInfo->SetLib( pNew );
+ pLibInfo->SetLibName( rLibName );
+ pLibInfo->GetLib()->SetName( rLibName );
+ return pLibInfo->GetLib();
+}
+
+// For XML import/export:
+StarBASIC* BasicManager::CreateLib
+ ( const String& rLibName, const String& Password, const String& LinkTargetURL )
+{
+ // Ask if lib exists because standard lib is always there
+ StarBASIC* pLib = GetLib( rLibName );
+ if( !pLib )
+ {
+ if( LinkTargetURL.Len() != 0 )
+ {
+ SotStorageRef xStorage = new SotStorage( FALSE, LinkTargetURL, STREAM_READ | STREAM_SHARE_DENYWRITE );
+ if( !xStorage->GetError() )
+ {
+ pLib = AddLib( *xStorage, rLibName, TRUE );
+
+ //if( !pLibInfo )
+ //pLibInfo = FindLibInfo( pLib );
+ //pLibInfo->SetStorageName( LinkTargetURL );
+ //pLibInfo->GetLib()->SetModified( FALSE ); // Dann nicht speichern
+ //pLibInfo->SetRelStorageName( String() );
+ //pLibInfo->IsReference() = TRUE;
+ }
+ //else
+ //Message?
+
+ DBG_ASSERT( pLib, "XML Import: Linked basic library could not be loaded");
+ }
+ else
+ {
+ pLib = CreateLib( rLibName );
+ if( Password.Len() != 0 )
+ {
+ BasicLibInfo* pLibInfo = FindLibInfo( pLib );
+ pLibInfo ->SetPassword( Password );
+ }
+ }
+ //ExternalSourceURL ?
+ }
+ return pLib;
+}
+
+StarBASIC* BasicManager::CreateLibForLibContainer( const String& rLibName,
+ const Reference< XLibraryContainer >& xScriptCont )
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+ if ( GetLib( rLibName ) )
+ return 0;
+
+ BasicLibInfo* pLibInfo = CreateLibInfo();
+ StarBASIC* pNew = new StarBASIC( GetStdLib() );
+ GetStdLib()->Insert( pNew );
+ pNew->SetFlag( SBX_EXTSEARCH | SBX_DONTSTORE );
+ pLibInfo->SetLib( pNew );
+ pLibInfo->SetLibName( rLibName );
+ pLibInfo->GetLib()->SetName( rLibName );
+ pLibInfo->SetLibraryContainer( xScriptCont );
+ return pNew;
+}
+
+
+BasicLibInfo* BasicManager::FindLibInfo( StarBASIC* pBasic ) const
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+
+ BasicLibInfo* pInf = ((BasicManager*)this)->pLibs->First();
+ while ( pInf )
+ {
+ if ( pInf->GetLib() == pBasic )
+ return pInf;
+
+ pInf = ((BasicManager*)this)->pLibs->Next();
+ }
+ return 0;
+}
+
+void BasicManager::SetFlagToAllLibs( short nFlag, BOOL bSet ) const
+{
+ USHORT nLibs = GetLibCount();
+ for ( USHORT nL = 0; nL < nLibs; nL++ )
+ {
+ BasicLibInfo* pInfo = pLibs->GetObject( nL );
+ DBG_ASSERT( pInfo, "Info?!" );
+ StarBASIC* pLib = pInfo->GetLib();
+ if ( pLib )
+ {
+ if ( bSet )
+ pLib->SetFlag( nFlag );
+ else
+ pLib->ResetFlag( nFlag );
+ }
+ }
+}
+
+BOOL BasicManager::HasErrors()
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+ return pErrorMgr->HasErrors();
+}
+
+void BasicManager::ClearErrors()
+{
+ DBG_CHKTHIS( BasicManager, 0 );
+ pErrorMgr->Reset();
+}
+
+//=====================================================================
+
+class ModuleInfo_Impl : public ModuleInfoHelper
+{
+ OUString maName;
+ OUString maLanguage;
+ OUString maSource;
+
+public:
+ ModuleInfo_Impl( const OUString& aName, const OUString& aLanguage, const OUString& aSource )
+ : maName( aName ), maLanguage( aLanguage), maSource( aSource ) {}
+
+ // Methods XStarBasicModuleInfo
+ virtual OUString SAL_CALL getName() throw(RuntimeException)
+ { return maName; }
+ virtual OUString SAL_CALL getLanguage() throw(RuntimeException)
+ { return maLanguage; }
+ virtual OUString SAL_CALL getSource() throw(RuntimeException)
+ { return maSource; }
+};
+
+
+//=====================================================================
+
+class DialogInfo_Impl : public DialogInfoHelper
+{
+ OUString maName;
+ Sequence< sal_Int8 > mData;
+
+public:
+ DialogInfo_Impl( const OUString& aName, Sequence< sal_Int8 > Data )
+ : maName( aName ), mData( Data ) {}
+
+ // Methods XStarBasicDialogInfo
+ virtual OUString SAL_CALL getName() throw(RuntimeException)
+ { return maName; }
+ virtual Sequence< sal_Int8 > SAL_CALL getData() throw(RuntimeException)
+ { return mData; }
+};
+
+
+//=====================================================================
+
+class LibraryInfo_Impl : public LibraryInfoHelper
+{
+ OUString maName;
+ Reference< XNameContainer > mxModuleContainer;
+ Reference< XNameContainer > mxDialogContainer;
+ OUString maPassword;
+ OUString maExternaleSourceURL;
+ OUString maLinkTargetURL;
+
+public:
+ LibraryInfo_Impl
+ (
+ const OUString& aName,
+ Reference< XNameContainer > xModuleContainer,
+ Reference< XNameContainer > xDialogContainer,
+ const OUString& aPassword,
+ const OUString& aExternaleSourceURL,
+ const OUString& aLinkTargetURL
+ )
+ : maName( aName )
+ , mxModuleContainer( xModuleContainer )
+ , mxDialogContainer( xDialogContainer )
+ , maPassword( aPassword )
+ , maExternaleSourceURL( aExternaleSourceURL )
+ , maLinkTargetURL( aLinkTargetURL )
+ {}
+
+ // Methods XStarBasicLibraryInfo
+ virtual OUString SAL_CALL getName() throw(RuntimeException)
+ { return maName; }
+ virtual Reference< XNameContainer > SAL_CALL getModuleContainer() throw(RuntimeException)
+ { return mxModuleContainer; }
+ virtual Reference< XNameContainer > SAL_CALL getDialogContainer() throw(RuntimeException)
+ { return mxDialogContainer; }
+ virtual OUString SAL_CALL getPassword() throw(RuntimeException)
+ { return maPassword; }
+ virtual OUString SAL_CALL getExternalSourceURL() throw(RuntimeException)
+ { return maExternaleSourceURL; }
+ virtual OUString SAL_CALL getLinkTargetURL() throw(RuntimeException)
+ { return maLinkTargetURL; }
+};
+
+//=====================================================================
+
+class ModuleContainer_Impl : public NameContainerHelper
+{
+ StarBASIC* mpLib;
+
+public:
+ ModuleContainer_Impl( StarBASIC* pLib )
+ :mpLib( pLib ) {}
+
+ // Methods XElementAccess
+ virtual Type SAL_CALL getElementType()
+ throw(RuntimeException);
+ virtual sal_Bool SAL_CALL hasElements()
+ throw(RuntimeException);
+
+ // Methods XNameAccess
+ virtual Any SAL_CALL getByName( const OUString& aName )
+ throw(NoSuchElementException, WrappedTargetException, RuntimeException);
+ virtual Sequence< OUString > SAL_CALL getElementNames()
+ throw(RuntimeException);
+ virtual sal_Bool SAL_CALL hasByName( const OUString& aName )
+ throw(RuntimeException);
+
+ // Methods XNameReplace
+ virtual void SAL_CALL replaceByName( const OUString& aName, const Any& aElement )
+ throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException);
+
+ // Methods XNameContainer
+ virtual void SAL_CALL insertByName( const OUString& aName, const Any& aElement )
+ throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException);
+ virtual void SAL_CALL removeByName( const OUString& Name )
+ throw(NoSuchElementException, WrappedTargetException, RuntimeException);
+};
+
+// Methods XElementAccess
+Type ModuleContainer_Impl::getElementType()
+ throw(RuntimeException)
+{
+ Type aModuleType = ::getCppuType( (const Reference< XStarBasicModuleInfo > *)0 );
+ return aModuleType;
+}
+
+sal_Bool ModuleContainer_Impl::hasElements()
+ throw(RuntimeException)
+{
+ SbxArray* pMods = mpLib ? mpLib->GetModules() : NULL;
+ return pMods && pMods->Count() > 0;
+}
+
+// Methods XNameAccess
+Any ModuleContainer_Impl::getByName( const OUString& aName )
+ throw(NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ SbModule* pMod = mpLib ? mpLib->FindModule( aName ) : NULL;
+ if( !pMod )
+ throw NoSuchElementException();
+ Reference< XStarBasicModuleInfo > xMod = (XStarBasicModuleInfo*)new ModuleInfo_Impl
+ ( aName, OUString::createFromAscii( "StarBasic" ), pMod->GetSource32() );
+ Any aRetAny;
+ aRetAny <<= xMod;
+ return aRetAny;
+}
+
+Sequence< OUString > ModuleContainer_Impl::getElementNames()
+ throw(RuntimeException)
+{
+ SbxArray* pMods = mpLib ? mpLib->GetModules() : NULL;
+ USHORT nMods = pMods ? pMods->Count() : 0;
+ Sequence< OUString > aRetSeq( nMods );
+ OUString* pRetSeq = aRetSeq.getArray();
+ for( USHORT i = 0 ; i < nMods ; i++ )
+ {
+ SbxVariable* pMod = pMods->Get( i );
+ pRetSeq[i] = OUString( pMod->GetName() );
+ }
+ return aRetSeq;
+}
+
+sal_Bool ModuleContainer_Impl::hasByName( const OUString& aName )
+ throw(RuntimeException)
+{
+ SbModule* pMod = mpLib ? mpLib->FindModule( aName ) : NULL;
+ sal_Bool bRet = (pMod != NULL);
+ return bRet;
+}
+
+
+// Methods XNameReplace
+void ModuleContainer_Impl::replaceByName( const OUString& aName, const Any& aElement )
+ throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ removeByName( aName );
+ insertByName( aName, aElement );
+}
+
+
+// Methods XNameContainer
+void ModuleContainer_Impl::insertByName( const OUString& aName, const Any& aElement )
+ throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
+{
+ Type aModuleType = ::getCppuType( (const Reference< XStarBasicModuleInfo > *)0 );
+ Type aAnyType = aElement.getValueType();
+ if( aModuleType != aAnyType )
+ throw IllegalArgumentException();
+ Reference< XStarBasicModuleInfo > xMod;
+ aElement >>= xMod;
+ mpLib->MakeModule32( aName, xMod->getSource() );
+}
+
+void ModuleContainer_Impl::removeByName( const OUString& Name )
+ throw(NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ SbModule* pMod = mpLib ? mpLib->FindModule( Name ) : NULL;
+ if( !pMod )
+ throw NoSuchElementException();
+ mpLib->Remove( pMod );
+}
+
+
+//=====================================================================
+
+Sequence< sal_Int8 > implGetDialogData( SbxObject* pDialog )
+{
+ SvMemoryStream aMemStream;
+ pDialog->Store( aMemStream );
+ sal_Int32 nLen = aMemStream.Tell();
+ Sequence< sal_Int8 > aData( nLen );
+ sal_Int8* pDestData = aData.getArray();
+ const sal_Int8* pSrcData = (const sal_Int8*)aMemStream.GetData();
+ rtl_copyMemory( pDestData, pSrcData, nLen );
+ return aData;
+}
+
+SbxObject* implCreateDialog( Sequence< sal_Int8 > aData )
+{
+ sal_Int8* pData = aData.getArray();
+ SvMemoryStream aMemStream( pData, aData.getLength(), STREAM_READ );
+ SbxObject* pDialog = (SbxObject*)SbxBase::Load( aMemStream );
+ return pDialog;
+}
+
+// HACK! Because this value is defined in basctl/inc/vcsbxdef.hxx
+// which we can't include here, we have to use the value directly
+#define SBXID_DIALOG 101
+
+
+class DialogContainer_Impl : public NameContainerHelper
+{
+ StarBASIC* mpLib;
+
+public:
+ DialogContainer_Impl( StarBASIC* pLib )
+ :mpLib( pLib ) {}
+
+ // Methods XElementAccess
+ virtual Type SAL_CALL getElementType()
+ throw(RuntimeException);
+ virtual sal_Bool SAL_CALL hasElements()
+ throw(RuntimeException);
+
+ // Methods XNameAccess
+ virtual Any SAL_CALL getByName( const OUString& aName )
+ throw(NoSuchElementException, WrappedTargetException, RuntimeException);
+ virtual Sequence< OUString > SAL_CALL getElementNames()
+ throw(RuntimeException);
+ virtual sal_Bool SAL_CALL hasByName( const OUString& aName )
+ throw(RuntimeException);
+
+ // Methods XNameReplace
+ virtual void SAL_CALL replaceByName( const OUString& aName, const Any& aElement )
+ throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException);
+
+ // Methods XNameContainer
+ virtual void SAL_CALL insertByName( const OUString& aName, const Any& aElement )
+ throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException);
+ virtual void SAL_CALL removeByName( const OUString& Name )
+ throw(NoSuchElementException, WrappedTargetException, RuntimeException);
+};
+
+// Methods XElementAccess
+Type DialogContainer_Impl::getElementType()
+ throw(RuntimeException)
+{
+ Type aModuleType = ::getCppuType( (const Reference< XStarBasicDialogInfo > *)0 );
+ return aModuleType;
+}
+
+sal_Bool DialogContainer_Impl::hasElements()
+ throw(RuntimeException)
+{
+ sal_Bool bRet = sal_False;
+
+ mpLib->GetAll( SbxCLASS_OBJECT );
+ sal_Int16 nCount = mpLib->GetObjects()->Count();
+ for( sal_Int16 nObj = 0; nObj < nCount ; nObj++ )
+ {
+ SbxVariable* pVar = mpLib->GetObjects()->Get( nObj );
+ if ( pVar->ISA( SbxObject ) && ( ((SbxObject*)pVar)->GetSbxId() == SBXID_DIALOG ) )
+ {
+ bRet = sal_True;
+ break;
+ }
+ }
+ return bRet;
+}
+
+// Methods XNameAccess
+Any DialogContainer_Impl::getByName( const OUString& aName )
+ throw(NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ SbxVariable* pVar = mpLib->GetObjects()->Find( aName, SbxCLASS_DONTCARE );
+ if( !( pVar && pVar->ISA( SbxObject ) &&
+ ( ((SbxObject*)pVar)->GetSbxId() == SBXID_DIALOG ) ) )
+ {
+ throw NoSuchElementException();
+ }
+
+ Reference< XStarBasicDialogInfo > xDialog =
+ (XStarBasicDialogInfo*)new DialogInfo_Impl
+ ( aName, implGetDialogData( (SbxObject*)pVar ) );
+
+ Any aRetAny;
+ aRetAny <<= xDialog;
+ return aRetAny;
+}
+
+Sequence< OUString > DialogContainer_Impl::getElementNames()
+ throw(RuntimeException)
+{
+ mpLib->GetAll( SbxCLASS_OBJECT );
+ sal_Int16 nCount = mpLib->GetObjects()->Count();
+ Sequence< OUString > aRetSeq( nCount );
+ OUString* pRetSeq = aRetSeq.getArray();
+ sal_Int32 nDialogCounter = 0;
+
+ for( sal_Int16 nObj = 0; nObj < nCount ; nObj++ )
+ {
+ SbxVariable* pVar = mpLib->GetObjects()->Get( nObj );
+ if ( pVar->ISA( SbxObject ) && ( ((SbxObject*)pVar)->GetSbxId() == SBXID_DIALOG ) )
+ {
+ pRetSeq[ nDialogCounter ] = OUString( pVar->GetName() );
+ nDialogCounter++;
+ }
+ }
+ aRetSeq.realloc( nDialogCounter );
+ return aRetSeq;
+}
+
+sal_Bool DialogContainer_Impl::hasByName( const OUString& aName )
+ throw(RuntimeException)
+{
+ sal_Bool bRet = sal_False;
+ SbxVariable* pVar = mpLib->GetObjects()->Find( aName, SbxCLASS_DONTCARE );
+ if( pVar && pVar->ISA( SbxObject ) &&
+ ( ((SbxObject*)pVar)->GetSbxId() == SBXID_DIALOG ) )
+ {
+ bRet = sal_True;
+ }
+ return bRet;
+}
+
+
+// Methods XNameReplace
+void DialogContainer_Impl::replaceByName( const OUString& aName, const Any& aElement )
+ throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ removeByName( aName );
+ insertByName( aName, aElement );
+}
+
+
+// Methods XNameContainer
+void DialogContainer_Impl::insertByName( const OUString& aName, const Any& aElement )
+ throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
+{
+ (void)aName;
+ Type aModuleType = ::getCppuType( (const Reference< XStarBasicDialogInfo > *)0 );
+ Type aAnyType = aElement.getValueType();
+ if( aModuleType != aAnyType )
+ throw IllegalArgumentException();
+ Reference< XStarBasicDialogInfo > xMod;
+ aElement >>= xMod;
+ SbxObjectRef xDialog = implCreateDialog( xMod->getData() );
+ mpLib->Insert( xDialog );
+}
+
+void DialogContainer_Impl::removeByName( const OUString& Name )
+ throw(NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ (void)Name;
+ SbxVariable* pVar = mpLib->GetObjects()->Find( Name, SbxCLASS_DONTCARE );
+ if( !( pVar && pVar->ISA( SbxObject ) &&
+ ( ((SbxObject*)pVar)->GetSbxId() == SBXID_DIALOG ) ) )
+ {
+ throw NoSuchElementException();
+ }
+ mpLib->Remove( pVar );
+}
+
+
+//=====================================================================
+
+
+class LibraryContainer_Impl : public NameContainerHelper
+{
+ BasicManager* mpMgr;
+
+public:
+ LibraryContainer_Impl( BasicManager* pMgr )
+ :mpMgr( pMgr ) {}
+
+ // Methods XElementAccess
+ virtual Type SAL_CALL getElementType()
+ throw(RuntimeException);
+ virtual sal_Bool SAL_CALL hasElements()
+ throw(RuntimeException);
+
+ // Methods XNameAccess
+ virtual Any SAL_CALL getByName( const OUString& aName )
+ throw(NoSuchElementException, WrappedTargetException, RuntimeException);
+ virtual Sequence< OUString > SAL_CALL getElementNames()
+ throw(RuntimeException);
+ virtual sal_Bool SAL_CALL hasByName( const OUString& aName )
+ throw(RuntimeException);
+
+ // Methods XNameReplace
+ virtual void SAL_CALL replaceByName( const OUString& aName, const Any& aElement )
+ throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException);
+
+ // Methods XNameContainer
+ virtual void SAL_CALL insertByName( const OUString& aName, const Any& aElement )
+ throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException);
+ virtual void SAL_CALL removeByName( const OUString& Name )
+ throw(NoSuchElementException, WrappedTargetException, RuntimeException);
+};
+
+
+// Methods XElementAccess
+Type LibraryContainer_Impl::getElementType()
+ throw(RuntimeException)
+{
+ Type aType = ::getCppuType( (const Reference< XStarBasicLibraryInfo > *)0 );
+ return aType;
+}
+
+sal_Bool LibraryContainer_Impl::hasElements()
+ throw(RuntimeException)
+{
+ sal_Int32 nLibs = mpMgr->GetLibCount();
+ sal_Bool bRet = (nLibs > 0);
+ return bRet;
+}
+
+// Methods XNameAccess
+Any LibraryContainer_Impl::getByName( const OUString& aName )
+ throw(NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ Any aRetAny;
+ if( !mpMgr->HasLib( aName ) )
+ throw NoSuchElementException();
+ StarBASIC* pLib = mpMgr->GetLib( aName );
+
+ Reference< XNameContainer > xModuleContainer =
+ (XNameContainer*)new ModuleContainer_Impl( pLib );
+
+ Reference< XNameContainer > xDialogContainer;
+ (XNameContainer*)new DialogContainer_Impl( pLib );
+
+ BasicLibInfo* pLibInfo = mpMgr->FindLibInfo( pLib );
+
+ OUString aPassword = pLibInfo->GetPassword();
+
+ // TODO Nur extern-Info liefern!
+ OUString aExternaleSourceURL;
+ OUString aLinkTargetURL;
+ if( pLibInfo->IsReference() )
+ aLinkTargetURL = pLibInfo->GetStorageName();
+ else if( pLibInfo->IsExtern() )
+ aExternaleSourceURL = pLibInfo->GetStorageName();
+
+ Reference< XStarBasicLibraryInfo > xLibInfo = new LibraryInfo_Impl
+ (
+ aName,
+ xModuleContainer,
+ xDialogContainer,
+ aPassword,
+ aExternaleSourceURL,
+ aLinkTargetURL
+ );
+
+ aRetAny <<= xLibInfo;
+ return aRetAny;
+}
+
+Sequence< OUString > LibraryContainer_Impl::getElementNames()
+ throw(RuntimeException)
+{
+ USHORT nLibs = mpMgr->GetLibCount();
+ Sequence< OUString > aRetSeq( nLibs );
+ OUString* pRetSeq = aRetSeq.getArray();
+ for( USHORT i = 0 ; i < nLibs ; i++ )
+ {
+ pRetSeq[i] = OUString( mpMgr->GetLibName( i ) );
+ }
+ return aRetSeq;
+}
+
+sal_Bool LibraryContainer_Impl::hasByName( const OUString& aName )
+ throw(RuntimeException)
+{
+ sal_Bool bRet = mpMgr->HasLib( aName );
+ return bRet;
+}
+
+// Methods XNameReplace
+void LibraryContainer_Impl::replaceByName( const OUString& aName, const Any& aElement )
+ throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ removeByName( aName );
+ insertByName( aName, aElement );
+}
+
+// Methods XNameContainer
+void LibraryContainer_Impl::insertByName( const OUString& aName, const Any& aElement )
+ throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
+{
+ (void)aName;
+ (void)aElement;
+ // TODO: Insert a complete Library?!
+}
+
+void LibraryContainer_Impl::removeByName( const OUString& Name )
+ throw(NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ StarBASIC* pLib = mpMgr->GetLib( Name );
+ if( !pLib )
+ throw NoSuchElementException();
+ USHORT nLibId = mpMgr->GetLibId( Name );
+ mpMgr->RemoveLib( nLibId );
+}
+
+//=====================================================================
+
+typedef WeakImplHelper1< XStarBasicAccess > StarBasicAccessHelper;
+
+
+class StarBasicAccess_Impl : public StarBasicAccessHelper
+{
+ BasicManager* mpMgr;
+ Reference< XNameContainer > mxLibContainer;
+
+public:
+ StarBasicAccess_Impl( BasicManager* pMgr )
+ :mpMgr( pMgr ) {}
+
+public:
+
+ // Methods
+ virtual Reference< XNameContainer > SAL_CALL getLibraryContainer()
+ throw(RuntimeException);
+ virtual void SAL_CALL createLibrary( const OUString& LibName, const OUString& Password,
+ const OUString& ExternalSourceURL, const OUString& LinkTargetURL )
+ throw(ElementExistException, RuntimeException);
+ virtual void SAL_CALL addModule( const OUString& LibraryName, const OUString& ModuleName,
+ const OUString& Language, const OUString& Source )
+ throw(NoSuchElementException, RuntimeException);
+ virtual void SAL_CALL addDialog( const OUString& LibraryName, const OUString& DialogName,
+ const Sequence< sal_Int8 >& Data )
+ throw(NoSuchElementException, RuntimeException);
+
+};
+
+Reference< XNameContainer > SAL_CALL StarBasicAccess_Impl::getLibraryContainer()
+ throw(RuntimeException)
+{
+ if( !mxLibContainer.is() )
+ mxLibContainer = (XNameContainer*)new LibraryContainer_Impl( mpMgr );
+ return mxLibContainer;
+}
+
+void SAL_CALL StarBasicAccess_Impl::createLibrary
+(
+ const OUString& LibName,
+ const OUString& Password,
+ const OUString& ExternalSourceURL,
+ const OUString& LinkTargetURL
+)
+ throw(ElementExistException, RuntimeException)
+{
+ (void)ExternalSourceURL;
+#ifdef DBG_UTIL
+ StarBASIC* pLib =
+#endif
+ mpMgr->CreateLib( LibName, Password, LinkTargetURL );
+ DBG_ASSERT( pLib, "XML Import: Basic library could not be created");
+}
+
+void SAL_CALL StarBasicAccess_Impl::addModule
+(
+ const OUString& LibraryName,
+ const OUString& ModuleName,
+ const OUString& Language,
+ const OUString& Source
+)
+ throw(NoSuchElementException, RuntimeException)
+{
+ (void)Language;
+ StarBASIC* pLib = mpMgr->GetLib( LibraryName );
+ DBG_ASSERT( pLib, "XML Import: Lib for module unknown");
+ if( pLib )
+ pLib->MakeModule32( ModuleName, Source );
+}
+
+void SAL_CALL StarBasicAccess_Impl::addDialog
+(
+ const OUString& LibraryName,
+ const OUString& DialogName,
+ const Sequence< sal_Int8 >& Data
+)
+ throw(NoSuchElementException, RuntimeException)
+{
+ (void)LibraryName;
+ (void)DialogName;
+ (void)Data;
+}
+
+// Basic XML Import/Export
+Reference< XStarBasicAccess > getStarBasicAccess( BasicManager* pMgr )
+{
+ Reference< XStarBasicAccess > xRet =
+ new StarBasicAccess_Impl( (BasicManager*)pMgr );
+ return xRet;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/basmgr/makefile.mk b/binfilter/bf_basic/source/basmgr/makefile.mk
new file mode 100644
index 000000000000..bfa54fc07b4d
--- /dev/null
+++ b/binfilter/bf_basic/source/basmgr/makefile.mk
@@ -0,0 +1,49 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=binfilter
+TARGET=basic_basicmgr
+ENABLE_EXCEPTIONS=TRUE
+
+NO_HIDS=TRUE
+
+# --- Settings -----------------------------------------------------------
+
+.INCLUDE : settings.mk
+
+INC+= -I$(PRJ)$/inc$/bf_basic
+
+# --- Allgemein -----------------------------------------------------------
+
+SLOFILES= \
+ $(SLO)$/basmgr.obj
+
+# --- Targets -------------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/binfilter/bf_basic/source/classes/image.cxx b/binfilter/bf_basic/source/classes/image.cxx
new file mode 100644
index 000000000000..65cb44c939aa
--- /dev/null
+++ b/binfilter/bf_basic/source/classes/image.cxx
@@ -0,0 +1,450 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <tools/stream.hxx>
+#include <tools/tenccvt.hxx>
+#include "sbx.hxx"
+#include "sb.hxx"
+#include <string.h> // memset() etc
+#include "image.hxx"
+#include "codegen.hxx"
+
+namespace binfilter {
+
+SbiImage::SbiImage()
+{
+ pStringOff = NULL;
+ pStrings = NULL;
+ pCode = NULL;
+ pLegacyPCode = NULL;
+ nFlags = 0;
+ nStrings = 0;
+ nStringSize= 0;
+ nCodeSize = 0;
+ nLegacyCodeSize =
+ nDimBase = 0;
+ bInit =
+ bError = FALSE;
+ bFirstInit = TRUE;
+ eCharSet = gsl_getSystemTextEncoding();
+}
+
+SbiImage::~SbiImage()
+{
+ Clear();
+}
+
+void SbiImage::Clear()
+{
+ delete[] pStringOff;
+ delete[] pStrings;
+ delete[] pCode;
+ ReleaseLegacyBuffer();
+ pStringOff = NULL;
+ pStrings = NULL;
+ pCode = NULL;
+ nFlags = 0;
+ nStrings = 0;
+ nStringSize= 0;
+ nLegacyCodeSize = 0;
+ nCodeSize = 0;
+ eCharSet = gsl_getSystemTextEncoding();
+ nDimBase = 0;
+ bError = FALSE;
+}
+
+/**************************************************************************
+*
+* Service-Routinen fuer das Laden und Speichern
+*
+**************************************************************************/
+
+BOOL SbiGood( SvStream& r )
+{
+ return BOOL( !r.IsEof() && r.GetError() == SVSTREAM_OK );
+}
+
+// Oeffnen eines Records
+
+ULONG SbiOpenRecord( SvStream& r, UINT16 nSignature, UINT16 nElem )
+{
+ ULONG nPos = r.Tell();
+ r << nSignature << (INT32) 0 << nElem;
+ return nPos;
+}
+
+// Schliessen eines Records
+
+void SbiCloseRecord( SvStream& r, ULONG nOff )
+{
+ ULONG nPos = r.Tell();
+ r.Seek( nOff + 2 );
+ r << (INT32) ( nPos - nOff - 8 );
+ r.Seek( nPos );
+}
+
+/**************************************************************************
+*
+* Laden und Speichern
+*
+**************************************************************************/
+
+// Falls die Versionsnummer nicht passt, werden die binaeren Teile
+// nicht geladen, wohl aber Source, Kommentar und Name.
+
+BOOL SbiImage::Load( SvStream& r, UINT32& nVersion )
+{
+
+ UINT16 nSign, nCount;
+ UINT32 nLen, nOff;
+
+ Clear();
+ // Master-Record einlesen
+ r >> nSign >> nLen >> nCount;
+ ULONG nLast = r.Tell() + nLen;
+ UINT32 nCharSet; // System-Zeichensatz
+ UINT32 lDimBase;
+ UINT16 nReserved1;
+ UINT32 nReserved2;
+ UINT32 nReserved3;
+ BOOL bBadVer = FALSE;
+ if( nSign == B_MODULE )
+ {
+ r >> nVersion >> nCharSet >> lDimBase
+ >> nFlags >> nReserved1 >> nReserved2 >> nReserved3;
+ eCharSet = (CharSet) nCharSet;
+ eCharSet = GetSOLoadTextEncoding( eCharSet );
+ bBadVer = BOOL( nVersion > B_CURVERSION );
+ nDimBase = (USHORT) lDimBase;
+ }
+
+ bool bLegacy = ( nVersion < B_EXT_IMG_VERSION );
+
+ ULONG nNext;
+ while( ( nNext = r.Tell() ) < nLast )
+ {
+ short i;
+
+ r >> nSign >> nLen >> nCount;
+ nNext += nLen + 8;
+ if( r.GetError() == SVSTREAM_OK )
+ switch( nSign )
+ {
+ case B_NAME:
+ r.ReadByteString( aName, eCharSet );
+ //r >> aName;
+ break;
+ case B_COMMENT:
+ r.ReadByteString( aComment, eCharSet );
+ //r >> aComment;
+ break;
+ case B_SOURCE:
+ {
+ String aTmp;
+ r.ReadByteString( aTmp, eCharSet );
+ aOUSource = aTmp;
+ //r >> aSource;
+ break;
+ }
+#ifdef EXTENDED_BINARY_MODULES
+ case B_EXTSOURCE:
+ {
+ for( UINT16 j = 0 ; j < nCount ; j++ )
+ {
+ String aTmp;
+ r.ReadByteString( aTmp, eCharSet );
+ aOUSource += aTmp;
+ }
+ break;
+ }
+#endif
+ case B_PCODE:
+ if( bBadVer ) break;
+ pCode = new char[ nLen ];
+ nCodeSize = nLen;
+ r.Read( pCode, nCodeSize );
+ if ( bLegacy )
+ {
+ ReleaseLegacyBuffer(); // release any previously held buffer
+ nLegacyCodeSize = (UINT16) nCodeSize;
+ pLegacyPCode = pCode;
+
+ PCodeBuffConvertor< UINT16, UINT32 > aLegacyToNew( (BYTE*)pLegacyPCode, nLegacyCodeSize );
+ aLegacyToNew.convert();
+ pCode = (char*)aLegacyToNew.GetBuffer();
+ nCodeSize = aLegacyToNew.GetSize();
+ // we don't release the legacy buffer
+ // right now, thats because the module
+ // needs it to fix up the method
+ // nStart members. When that is done
+ // the module can release the buffer
+ // or it can wait until this routine
+ // is called again or when this class // destructs all of which will trigger
+ // release of the buffer.
+ }
+ break;
+ case B_PUBLICS:
+ case B_POOLDIR:
+ case B_SYMPOOL:
+ case B_LINERANGES:
+ break;
+ case B_STRINGPOOL:
+ if( bBadVer ) break;
+ MakeStrings( nCount );
+ for( i = 0; i < nStrings && SbiGood( r ); i++ )
+ {
+ r >> nOff;
+ pStringOff[ i ] = (USHORT) nOff;
+ }
+ r >> nLen;
+ if( SbiGood( r ) )
+ {
+ delete [] pStrings;
+ pStrings = new sal_Unicode[ nLen ];
+ nStringSize = (USHORT) nLen;
+
+ char* pByteStrings = new char[ nLen ];
+ r.Read( pByteStrings, nStringSize );
+ for( short j = 0; j < nStrings; j++ )
+ {
+ USHORT nOff2 = (USHORT) pStringOff[ j ];
+ String aStr( pByteStrings + nOff2, eCharSet );
+ memcpy( pStrings + nOff2, aStr.GetBuffer(), (aStr.Len() + 1) * sizeof( sal_Unicode ) );
+ }
+ delete[] pByteStrings;
+ } break;
+ case B_MODEND:
+ goto done;
+ default:
+ break;
+ }
+ else
+ break;
+ r.Seek( nNext );
+ }
+done:
+ r.Seek( nLast );
+ //if( eCharSet != ::GetSystemCharSet() )
+ //ConvertStrings();
+ if( !SbiGood( r ) )
+ bError = TRUE;
+ return BOOL( !bError );
+}
+
+BOOL SbiImage::Save( SvStream& r, UINT32 nVer )
+{
+ bool bLegacy = ( nVer < B_EXT_IMG_VERSION );
+
+ // detect if old code exceeds legacy limits
+ // if so, then disallow save
+ if ( bLegacy && ExceedsLegacyLimits() )
+ {
+ SbiImage aEmptyImg;
+ aEmptyImg.aName = aName;
+ aEmptyImg.Save( r, B_LEGACYVERSION );
+ return TRUE;
+ }
+ // Erst mal der Header:
+ ULONG nStart = SbiOpenRecord( r, B_MODULE, 1 );
+ ULONG nPos;
+
+ eCharSet = GetSOStoreTextEncoding( eCharSet );
+ if ( bLegacy )
+ r << (INT32) B_LEGACYVERSION;
+ else
+ r << (INT32) B_CURVERSION;
+ r << (INT32) eCharSet
+ << (INT32) nDimBase
+ << (INT16) nFlags
+ << (INT16) 0
+ << (INT32) 0
+ << (INT32) 0;
+
+ // Name?
+ if( aName.Len() && SbiGood( r ) )
+ {
+ nPos = SbiOpenRecord( r, B_NAME, 1 );
+ r.WriteByteString( aName, eCharSet );
+ //r << aName;
+ SbiCloseRecord( r, nPos );
+ }
+ // Kommentar?
+ if( aComment.Len() && SbiGood( r ) )
+ {
+ nPos = SbiOpenRecord( r, B_COMMENT, 1 );
+ r.WriteByteString( aComment, eCharSet );
+ //r << aComment;
+ SbiCloseRecord( r, nPos );
+ }
+ // Source?
+ if( aOUSource.getLength() && SbiGood( r ) )
+ {
+ nPos = SbiOpenRecord( r, B_SOURCE, 1 );
+ String aTmp;
+ sal_Int32 nLen = aOUSource.getLength();
+ const sal_Int32 nMaxUnitSize = STRING_MAXLEN - 1;
+ if( nLen > STRING_MAXLEN )
+ aTmp = aOUSource.copy( 0, nMaxUnitSize );
+ else
+ aTmp = aOUSource;
+ r.WriteByteString( aTmp, eCharSet );
+ //r << aSource;
+ SbiCloseRecord( r, nPos );
+
+#ifdef EXTENDED_BINARY_MODULES
+ if( nLen > STRING_MAXLEN )
+ {
+ sal_Int32 nRemainingLen = nLen - nMaxUnitSize;
+ UINT16 nUnitCount = UINT16( (nRemainingLen + nMaxUnitSize - 1) / nMaxUnitSize );
+ nPos = SbiOpenRecord( r, B_EXTSOURCE, nUnitCount );
+ for( UINT16 i = 0 ; i < nUnitCount ; i++ )
+ {
+ sal_Int32 nCopyLen =
+ (nRemainingLen > nMaxUnitSize) ? nMaxUnitSize : nRemainingLen;
+ String aTmp2 = aOUSource.copy( (i+1) * nMaxUnitSize, nCopyLen );
+ nRemainingLen -= nCopyLen;
+ r.WriteByteString( aTmp2, eCharSet );
+ }
+ SbiCloseRecord( r, nPos );
+ }
+#endif
+ }
+ // Binaere Daten?
+ if( pCode && SbiGood( r ) )
+ {
+ nPos = SbiOpenRecord( r, B_PCODE, 1 );
+ if ( bLegacy )
+ {
+ ReleaseLegacyBuffer(); // release any previously held buffer
+ PCodeBuffConvertor< UINT32, UINT16 > aNewToLegacy( (BYTE*)pCode, nCodeSize );
+ aNewToLegacy.convert();
+ pLegacyPCode = (char*)aNewToLegacy.GetBuffer();
+ nLegacyCodeSize = aNewToLegacy.GetSize();
+ r.Write( pLegacyPCode, nLegacyCodeSize );
+ }
+ else
+ r.Write( pCode, nCodeSize );
+ SbiCloseRecord( r, nPos );
+ }
+ // String-Pool?
+ if( nStrings )
+ {
+ nPos = SbiOpenRecord( r, B_STRINGPOOL, nStrings );
+ // Fuer jeden String:
+ // UINT32 Offset des Strings im Stringblock
+ short i;
+
+ for( i = 0; i < nStrings && SbiGood( r ); i++ )
+ r << (UINT32) pStringOff[ i ];
+
+ // Danach der String-Block
+ char* pByteStrings = new char[ nStringSize ];
+ for( i = 0; i < nStrings; i++ )
+ {
+ USHORT nOff = (USHORT) pStringOff[ i ];
+ ByteString aStr( pStrings + nOff, eCharSet );
+ memcpy( pByteStrings + nOff, aStr.GetBuffer(), (aStr.Len() + 1) * sizeof( char ) );
+ }
+ r << (UINT32) nStringSize;
+ r.Write( pByteStrings, nStringSize );
+
+ delete[] pByteStrings;
+ SbiCloseRecord( r, nPos );
+ }
+ // Und die Gesamtlaenge setzen
+ SbiCloseRecord( r, nStart );
+ if( !SbiGood( r ) )
+ bError = TRUE;
+ return BOOL( !bError );
+}
+
+/**************************************************************************
+*
+* Routinen, die auch vom Compiler gerufen werden
+*
+**************************************************************************/
+
+void SbiImage::MakeStrings( short nSize )
+{
+ nStrings = 0;
+ nStringIdx = 0;
+ nStringOff = 0;
+ nStringSize = 1024;
+ pStrings = new sal_Unicode[ nStringSize ];
+ pStringOff = new UINT32[ nSize ];
+ if( pStrings && pStringOff )
+ {
+ nStrings = nSize;
+ memset( pStringOff, 0, nSize * sizeof( UINT32 ) );
+ memset( pStrings, 0, nStringSize * sizeof( sal_Unicode ) );
+ }
+ else
+ bError = TRUE;
+}
+
+/**************************************************************************
+*
+* Zugriffe auf das Image
+*
+**************************************************************************/
+
+const SbxObject* SbiImage::FindType (String aTypeName) const
+{
+ return rTypes.Is() ? (SbxObject*)rTypes->Find(aTypeName,SbxCLASS_OBJECT) : NULL;
+}
+
+UINT16
+SbiImage::CalcLegacyOffset( INT32 nOffset )
+{
+ return SbiCodeGen::calcLegacyOffSet( (BYTE*)pCode, nOffset ) ;
+}
+UINT32
+SbiImage::CalcNewOffset( INT16 nOffset )
+{
+ return SbiCodeGen::calcNewOffSet( (BYTE*)pLegacyPCode, nOffset ) ;
+}
+
+void
+SbiImage::ReleaseLegacyBuffer()
+{
+ delete[] pLegacyPCode;
+ pLegacyPCode = NULL;
+ nLegacyCodeSize = 0;
+}
+
+BOOL
+SbiImage::ExceedsLegacyLimits()
+{
+ if ( ( nStringSize > 0xFF00L ) || ( CalcLegacyOffset( nCodeSize ) > 0xFF00L ) )
+ return TRUE;
+ return FALSE;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/classes/makefile.mk b/binfilter/bf_basic/source/classes/makefile.mk
new file mode 100644
index 000000000000..51a6dc023dbc
--- /dev/null
+++ b/binfilter/bf_basic/source/classes/makefile.mk
@@ -0,0 +1,59 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=binfilter
+TARGET=basic_classes
+
+NO_HIDS=TRUE
+
+# --- Settings -----------------------------------------------------------
+
+ENABLE_EXCEPTIONS=TRUE
+
+.INCLUDE : settings.mk
+
+INC+= -I$(PRJ)$/inc$/bf_basic
+
+# --- Allgemein -----------------------------------------------------------
+
+SLOFILES=\
+ $(SLO)$/sb.obj \
+ $(SLO)$/sbxmod.obj \
+ $(SLO)$/sbunoobj.obj \
+ $(SLO)$/image.obj \
+ $(SLO)$/sbintern.obj \
+
+# $(SLO)$/propacc.obj \
+ $(SLO)$/disas.obj \
+ $(SLO)$/eventatt.obj
+
+# --- Targets -------------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/binfilter/bf_basic/source/classes/sb.cxx b/binfilter/bf_basic/source/classes/sb.cxx
new file mode 100644
index 000000000000..df3f3f4dc784
--- /dev/null
+++ b/binfilter/bf_basic/source/classes/sb.cxx
@@ -0,0 +1,1416 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <stdio.h>
+
+#include "sb.hxx"
+#include <tools/rcid.h>
+#include <tools/config.hxx>
+
+#include <tools/stream.hxx>
+#ifndef __RSC //autogen
+#include <tools/errinf.hxx>
+#endif
+#include <sbx.hxx>
+#include <tools/list.hxx>
+#include <tools/rc.hxx>
+#include <vcl/svapp.hxx>
+#include "sbunoobj.hxx"
+#include "sbjsmeth.hxx"
+#include "sbjsmod.hxx"
+#include "sbintern.hxx"
+#include "image.hxx"
+#include "filefmt.hxx"
+
+#include <osl/mutex.hxx>
+
+namespace binfilter {
+
+// #pragma SW_SEGMENT_CLASS( SBASIC, SBASIC_CODE )
+
+TYPEINIT1(StarBASIC,SbxObject)
+
+#define RTLNAME "@SBRTL"
+
+
+//========================================================================
+// Array zur Umrechnung SFX <-> VB-Fehlercodes anlegen
+
+struct SFX_VB_ErrorItem
+{
+ USHORT nErrorVB;
+ SbError nErrorSFX;
+};
+
+const SFX_VB_ErrorItem __FAR_DATA SFX_VB_ErrorTab[] =
+{
+ { 1, SbERR_BASIC_EXCEPTION }, // #87844 Map exception to error code 1
+ { 2, SbERR_SYNTAX },
+ { 3, SbERR_NO_GOSUB },
+ { 4, SbERR_REDO_FROM_START },
+ { 5, SbERR_BAD_ARGUMENT },
+ { 6, SbERR_MATH_OVERFLOW },
+ { 7, SbERR_NO_MEMORY },
+ { 8, SbERR_ALREADY_DIM },
+ { 9, SbERR_OUT_OF_RANGE },
+ { 10, SbERR_DUPLICATE_DEF },
+ { 11, SbERR_ZERODIV },
+ { 12, SbERR_VAR_UNDEFINED },
+ { 13, SbERR_CONVERSION },
+ { 14, SbERR_BAD_PARAMETER },
+ { 18, SbERR_USER_ABORT },
+ { 20, SbERR_BAD_RESUME },
+ { 28, SbERR_STACK_OVERFLOW },
+ { 35, SbERR_PROC_UNDEFINED },
+ { 48, SbERR_BAD_DLL_LOAD },
+ { 49, SbERR_BAD_DLL_CALL },
+ { 51, SbERR_INTERNAL_ERROR },
+ { 52, SbERR_BAD_CHANNEL },
+ { 53, SbERR_FILE_NOT_FOUND },
+ { 54, SbERR_BAD_FILE_MODE },
+ { 55, SbERR_FILE_ALREADY_OPEN },
+ { 57, SbERR_IO_ERROR },
+ { 58, SbERR_FILE_EXISTS },
+ { 59, SbERR_BAD_RECORD_LENGTH },
+ { 61, SbERR_DISK_FULL },
+ { 62, SbERR_READ_PAST_EOF },
+ { 63, SbERR_BAD_RECORD_NUMBER },
+ { 67, SbERR_TOO_MANY_FILES },
+ { 68, SbERR_NO_DEVICE },
+ { 70, SbERR_ACCESS_DENIED },
+ { 71, SbERR_NOT_READY },
+ { 73, SbERR_NOT_IMPLEMENTED },
+ { 74, SbERR_DIFFERENT_DRIVE },
+ { 75, SbERR_ACCESS_ERROR },
+ { 76, SbERR_PATH_NOT_FOUND },
+ { 91, SbERR_NO_OBJECT },
+ { 93, SbERR_BAD_PATTERN },
+ { 94, SBERR_IS_NULL },
+ { 250, SbERR_DDE_ERROR },
+ { 280, SbERR_DDE_WAITINGACK },
+ { 281, SbERR_DDE_OUTOFCHANNELS },
+ { 282, SbERR_DDE_NO_RESPONSE },
+ { 283, SbERR_DDE_MULT_RESPONSES },
+ { 284, SbERR_DDE_CHANNEL_LOCKED },
+ { 285, SbERR_DDE_NOTPROCESSED },
+ { 286, SbERR_DDE_TIMEOUT },
+ { 287, SbERR_DDE_USER_INTERRUPT },
+ { 288, SbERR_DDE_BUSY },
+ { 289, SbERR_DDE_NO_DATA },
+ { 290, SbERR_DDE_WRONG_DATA_FORMAT },
+ { 291, SbERR_DDE_PARTNER_QUIT },
+ { 292, SbERR_DDE_CONV_CLOSED },
+ { 293, SbERR_DDE_NO_CHANNEL },
+ { 294, SbERR_DDE_INVALID_LINK },
+ { 295, SbERR_DDE_QUEUE_OVERFLOW },
+ { 296, SbERR_DDE_LINK_ALREADY_EST },
+ { 297, SbERR_DDE_LINK_INV_TOPIC },
+ { 298, SbERR_DDE_DLL_NOT_FOUND },
+ { 323, SbERR_CANNOT_LOAD },
+ { 341, SbERR_BAD_INDEX },
+ { 366, SbERR_NO_ACTIVE_OBJECT },
+ { 380, SbERR_BAD_PROP_VALUE },
+ { 382, SbERR_PROP_READONLY },
+ { 394, SbERR_PROP_WRITEONLY },
+ { 420, SbERR_INVALID_OBJECT },
+ { 423, SbERR_NO_METHOD },
+ { 424, SbERR_NEEDS_OBJECT },
+ { 425, SbERR_INVALID_USAGE_OBJECT },
+ { 430, SbERR_NO_OLE },
+ { 438, SbERR_BAD_METHOD },
+ { 440, SbERR_OLE_ERROR },
+ { 445, SbERR_BAD_ACTION },
+ { 446, SbERR_NO_NAMED_ARGS },
+ { 447, SbERR_BAD_LOCALE },
+ { 448, SbERR_NAMED_NOT_FOUND },
+ { 449, SbERR_NOT_OPTIONAL },
+ { 450, SbERR_WRONG_ARGS },
+ { 451, SbERR_NOT_A_COLL },
+ { 452, SbERR_BAD_ORDINAL },
+ { 453, SbERR_DLLPROC_NOT_FOUND },
+ { 460, SbERR_BAD_CLIPBD_FORMAT },
+ { 951, SbERR_UNEXPECTED },
+ { 952, SbERR_EXPECTED },
+ { 953, SbERR_SYMBOL_EXPECTED },
+ { 954, SbERR_VAR_EXPECTED },
+ { 955, SbERR_LABEL_EXPECTED },
+ { 956, SbERR_LVALUE_EXPECTED },
+ { 957, SbERR_VAR_DEFINED },
+ { 958, SbERR_PROC_DEFINED },
+ { 959, SbERR_LABEL_DEFINED },
+ { 960, SbERR_UNDEF_VAR },
+ { 961, SbERR_UNDEF_ARRAY },
+ { 962, SbERR_UNDEF_PROC },
+ { 963, SbERR_UNDEF_LABEL },
+ { 964, SbERR_UNDEF_TYPE },
+ { 965, SbERR_BAD_EXIT },
+ { 966, SbERR_BAD_BLOCK },
+ { 967, SbERR_BAD_BRACKETS },
+ { 968, SbERR_BAD_DECLARATION },
+ { 969, SbERR_BAD_PARAMETERS },
+ { 970, SbERR_BAD_CHAR_IN_NUMBER },
+ { 971, SbERR_MUST_HAVE_DIMS },
+ { 972, SbERR_NO_IF },
+ { 973, SbERR_NOT_IN_SUBR },
+ { 974, SbERR_NOT_IN_MAIN },
+ { 975, SbERR_WRONG_DIMS },
+ { 976, SbERR_BAD_OPTION },
+ { 977, SbERR_CONSTANT_REDECLARED },
+ { 978, SbERR_PROG_TOO_LARGE },
+ { 979, SbERR_NO_STRINGS_ARRAYS },
+ { 1000, SbERR_PROPERTY_NOT_FOUND },
+ { 1001, SbERR_METHOD_NOT_FOUND },
+ { 1002, SbERR_ARG_MISSING },
+ { 1003, SbERR_BAD_NUMBER_OF_ARGS },
+ { 1004, SbERR_METHOD_FAILED },
+ { 1005, SbERR_SETPROP_FAILED },
+ { 1006, SbERR_GETPROP_FAILED },
+ { 0xFFFF, 0xFFFFFFFFL } // End-Marke
+};
+
+
+////////////////////////////////////////////////////////////////////////////
+
+// Die StarBASIC-Factory hat einen Hack. Wenn ein SbModule eingerichtet wird,
+// wird der Pointer gespeichert und an nachfolgende SbProperties/SbMethods
+// uebergeben. Dadurch wird die Modul-Relationship wiederhergestellt. Das
+// klappt aber nur, wenn ein Modul geladen wird. Fuer getrennt geladene
+// Properties kann es Probleme geben!
+
+SbxBase* SbiFactory::Create( UINT16 nSbxId, UINT32 nCreator )
+{
+ if( nCreator == SBXCR_SBX )
+ {
+ String aEmpty;
+ switch( nSbxId )
+ {
+ case SBXID_BASIC:
+ return new StarBASIC( NULL );
+ case SBXID_BASICMOD:
+ return new SbModule( aEmpty );
+ case SBXID_BASICPROP:
+ return new SbProperty( aEmpty, SbxVARIANT, NULL );
+ case SBXID_BASICMETHOD:
+ return new SbMethod( aEmpty, SbxVARIANT, NULL );
+ case SBXID_JSCRIPTMOD:
+ return new SbJScriptModule( aEmpty );
+ case SBXID_JSCRIPTMETH:
+ return new SbJScriptMethod( aEmpty, SbxVARIANT, NULL );
+ }
+ }
+ return NULL;
+}
+
+SbxObject* SbiFactory::CreateObject( const String& rClass )
+{
+ if( rClass.EqualsIgnoreCaseAscii( "StarBASIC" ) )
+ return new StarBASIC( NULL );
+ else
+ if( rClass.EqualsIgnoreCaseAscii( "StarBASICModule" ) )
+ {
+ String aEmpty;
+ return new SbModule( aEmpty );
+ }
+ else
+ if( rClass.EqualsIgnoreCaseAscii( "Collection" ) )
+ {
+ String aCollectionName( RTL_CONSTASCII_USTRINGPARAM("Collection") );
+ return new BasicCollection( aCollectionName );
+ }
+ else
+ return NULL;
+}
+
+
+// Factory class to create OLE objects
+class SbOLEFactory : public SbxFactory
+{
+public:
+ virtual SbxBase* Create( UINT16 nSbxId, UINT32 = SBXCR_SBX );
+ virtual SbxObject* CreateObject( const String& );
+};
+
+SbxBase* SbOLEFactory::Create( UINT16, UINT32 )
+{
+ // Not supported
+ return NULL;
+}
+
+SbUnoObject* createOLEObject_Impl( const String& aType ); // sbunoobj.cxx
+
+SbxObject* SbOLEFactory::CreateObject( const String& rClassName )
+{
+ SbxObject* pRet = createOLEObject_Impl( rClassName );
+ return pRet;
+}
+
+
+// Factory class to create user defined objects (type command)
+class SbTypeFactory : public SbxFactory
+{
+ SbxObject* cloneTypeObjectImpl( const SbxObject& rTypeObj );
+
+public:
+ virtual SbxBase* Create( UINT16 nSbxId, UINT32 = SBXCR_SBX );
+ virtual SbxObject* CreateObject( const String& );
+};
+
+SbxBase* SbTypeFactory::Create( UINT16, UINT32 )
+{
+ // Not supported
+ return NULL;
+}
+
+SbxObject* SbTypeFactory::cloneTypeObjectImpl( const SbxObject& rTypeObj )
+{
+ SbxObject* pRet = new SbxObject( rTypeObj );
+ pRet->PutObject( pRet );
+
+ // Copy the properties, not only the reference to them
+ SbxArray* pProps = pRet->GetProperties();
+ UINT32 nCount = pProps->Count32();
+ for( UINT32 i = 0 ; i < nCount ; i++ )
+ {
+ SbxVariable* pVar = pProps->Get32( i );
+ SbxProperty* pProp = PTR_CAST( SbxProperty, pVar );
+ if( pProp )
+ {
+ SbxProperty* pNewProp = new SbxProperty( *pProp );
+ pProps->PutDirect( pNewProp, i );
+ }
+ }
+ return pRet;
+}
+
+SbxObject* SbTypeFactory::CreateObject( const String& rClassName )
+{
+ SbxObject* pRet = NULL;
+ SbModule* pMod = pMOD;
+ if( pMod )
+ {
+ const SbxObject* pObj = pMod->FindType( rClassName );
+ if( pObj )
+ pRet = cloneTypeObjectImpl( *pObj );
+ }
+ return pRet;
+}
+
+TYPEINIT1(SbClassModuleObject,SbModule)
+
+SbClassModuleObject::SbClassModuleObject( SbModule* pClassModule )
+ : SbModule( pClassModule->GetName() )
+ , mpClassModule( pClassModule )
+ , mbInitializeEventDone( false )
+{
+ aOUSource = pClassModule->aOUSource;
+ aComment = pClassModule->aComment;
+ pImage = pClassModule->pImage;
+
+ SetClassName( pClassModule->GetName() );
+
+ // Allow search only internally
+ ResetFlag( SBX_GBLSEARCH );
+
+ // Copy the methods from original class module
+ SbxArray* pClassMethods = pClassModule->GetMethods();
+ UINT32 nMethodCount = pClassMethods->Count32();
+ UINT32 i;
+ for( i = 0 ; i < nMethodCount ; i++ )
+ {
+ SbxVariable* pVar = pClassMethods->Get32( i );
+
+ // Exclude SbIfaceMapperMethod to copy them in a second step
+ SbIfaceMapperMethod* pIfaceMethod = PTR_CAST( SbIfaceMapperMethod, pVar );
+ if( !pIfaceMethod )
+ {
+ SbMethod* pMethod = PTR_CAST(SbMethod, pVar );
+ if( pMethod )
+ {
+ USHORT nFlags_ = pMethod->GetFlags();
+ pMethod->SetFlag( SBX_NO_BROADCAST );
+ SbMethod* pNewMethod = new SbMethod( *pMethod );
+ pNewMethod->ResetFlag( SBX_NO_BROADCAST );
+ pMethod->SetFlags( nFlags_ );
+ pNewMethod->pMod = this;
+ pNewMethod->SetParent( this );
+ pMethods->PutDirect( pNewMethod, i );
+ StartListening( pNewMethod->GetBroadcaster(), TRUE );
+ }
+ }
+ }
+
+ // Copy SbIfaceMapperMethod in a second step to ensure that
+ // the corresponding base methods have already been copied
+ for( i = 0 ; i < nMethodCount ; i++ )
+ {
+ SbxVariable* pVar = pClassMethods->Get32( i );
+
+ SbIfaceMapperMethod* pIfaceMethod = PTR_CAST( SbIfaceMapperMethod, pVar );
+ if( pIfaceMethod )
+ {
+ SbMethod* pImplMethod = pIfaceMethod->getImplMethod();
+ if( !pImplMethod )
+ {
+ DBG_ERROR( "No ImplMethod" );
+ continue;
+ }
+
+ // Search for own copy of ImplMethod
+ String aImplMethodName = pImplMethod->GetName();
+ SbxVariable* p = pMethods->Find( aImplMethodName, SbxCLASS_METHOD );
+ SbMethod* pImplMethodCopy = p ? PTR_CAST(SbMethod,p) : NULL;
+ if( !pImplMethodCopy )
+ {
+ DBG_ERROR( "Found no ImplMethod copy" );
+ continue;
+ }
+ SbIfaceMapperMethod* pNewIfaceMethod =
+ new SbIfaceMapperMethod( pIfaceMethod->GetName(), pImplMethodCopy );
+ pMethods->PutDirect( pNewIfaceMethod, i );
+ }
+ }
+
+ // Copy the properties from original class module
+ SbxArray* pClassProps = pClassModule->GetProperties();
+ UINT32 nPropertyCount = pClassProps->Count32();
+ for( i = 0 ; i < nPropertyCount ; i++ )
+ {
+ SbxVariable* pVar = pClassProps->Get32( i );
+ SbProcedureProperty* pProcedureProp = PTR_CAST( SbProcedureProperty, pVar );
+ if( pProcedureProp )
+ {
+ USHORT nFlags_ = pProcedureProp->GetFlags();
+ pProcedureProp->SetFlag( SBX_NO_BROADCAST );
+ SbProcedureProperty* pNewProp = new SbProcedureProperty
+ ( pProcedureProp->GetName(), pProcedureProp->GetType() );
+ // ( pProcedureProp->GetName(), pProcedureProp->GetType(), this );
+ pNewProp->ResetFlag( SBX_NO_BROADCAST );
+ pProcedureProp->SetFlags( nFlags_ );
+ pProps->PutDirect( pNewProp, i );
+ StartListening( pNewProp->GetBroadcaster(), TRUE );
+ }
+ else
+ {
+ SbxProperty* pProp = PTR_CAST( SbxProperty, pVar );
+ if( pProp )
+ {
+ USHORT nFlags_ = pProp->GetFlags();
+ pProp->SetFlag( SBX_NO_BROADCAST );
+ SbxProperty* pNewProp = new SbxProperty( *pProp );
+ pNewProp->ResetFlag( SBX_NO_BROADCAST );
+ pNewProp->SetParent( this );
+ pProps->PutDirect( pNewProp, i );
+ pProp->SetFlags( nFlags_ );
+ }
+ }
+ }
+}
+
+SbClassModuleObject::~SbClassModuleObject()
+{
+ triggerTerminateEvent();
+
+ // Must be deleted by base class dtor because this data
+ // is not owned by the SbClassModuleObject object
+ pImage = NULL;
+}
+
+void SbClassModuleObject::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
+ const SfxHint& rHint, const TypeId& rHintType )
+{
+ bool bDone = false;
+
+ const SbxHint* pHint = PTR_CAST(SbxHint,&rHint);
+ if( pHint )
+ {
+ SbxVariable* pVar = pHint->GetVar();
+ SbProcedureProperty* pProcProperty = PTR_CAST( SbProcedureProperty, pVar );
+ if( pProcProperty )
+ {
+ bDone = true;
+
+ if( pHint->GetId() == SBX_HINT_DATAWANTED )
+ {
+ String aProcName;
+ aProcName.AppendAscii( "Property Get " );
+ aProcName += pProcProperty->GetName();
+
+ SbxVariable* pMeth = Find( aProcName, SbxCLASS_METHOD );
+ if( pMeth )
+ {
+ SbxValues aVals;
+ aVals.eType = SbxVARIANT;
+ pMeth->Get( aVals );
+ pVar->Put( aVals );
+ }
+ }
+ else if( pHint->GetId() == SBX_HINT_DATACHANGED )
+ {
+ SbxVariable* pMeth = NULL;
+
+ bool bSet = pProcProperty->isSet();
+ if( bSet )
+ {
+ pProcProperty->setSet( false );
+
+ String aProcName;
+ aProcName.AppendAscii( "Property Set " );
+ aProcName += pProcProperty->GetName();
+ pMeth = Find( aProcName, SbxCLASS_METHOD );
+ }
+ if( !pMeth ) // Let
+ {
+ String aProcName;
+ aProcName.AppendAscii( "Property Let " );
+ aProcName += pProcProperty->GetName();
+ pMeth = Find( aProcName, SbxCLASS_METHOD );
+ }
+
+ if( pMeth )
+ {
+ // Setup parameters
+ SbxArrayRef xArray = new SbxArray;
+ xArray->Put( pMeth, 0 ); // Method as parameter 0
+ xArray->Put( pVar, 1 );
+ pMeth->SetParameters( xArray );
+
+ SbxValues aVals;
+ pMeth->Get( aVals );
+ pMeth->SetParameters( NULL );
+ }
+ }
+ }
+ }
+
+ if( !bDone )
+ SbModule::SFX_NOTIFY( rBC, rBCType, rHint, rHintType );
+}
+
+SbxVariable* SbClassModuleObject::Find( const XubString& rName, SbxClassType t )
+{
+ SbxVariable* pRes = SbxObject::Find( rName, t );
+ if( pRes )
+ {
+ triggerInitializeEvent();
+
+ SbIfaceMapperMethod* pIfaceMapperMethod = PTR_CAST(SbIfaceMapperMethod,pRes);
+ if( pIfaceMapperMethod )
+ {
+ pRes = pIfaceMapperMethod->getImplMethod();
+ pRes->SetFlag( SBX_EXTFOUND );
+ }
+ }
+ return pRes;
+}
+
+void SbClassModuleObject::triggerInitializeEvent( void )
+{
+ static String aInitMethodName( RTL_CONSTASCII_USTRINGPARAM("Class_Initialize") );
+
+ if( mbInitializeEventDone )
+ return;
+
+ mbInitializeEventDone = true;
+
+ // Search method
+ SbxVariable* pMeth = SbxObject::Find( aInitMethodName, SbxCLASS_METHOD );
+ if( pMeth )
+ {
+ SbxValues aVals;
+ pMeth->Get( aVals );
+ }
+}
+
+void SbClassModuleObject::triggerTerminateEvent( void )
+{
+ static String aTermMethodName( RTL_CONSTASCII_USTRINGPARAM("Class_Terminate") );
+
+ if( !mbInitializeEventDone || GetSbData()->bRunInit )
+ return;
+
+ // Search method
+ SbxVariable* pMeth = SbxObject::Find( aTermMethodName, SbxCLASS_METHOD );
+ if( pMeth )
+ {
+ SbxValues aVals;
+ pMeth->Get( aVals );
+ }
+}
+
+
+void SbClassData::clear( void )
+{
+ mxIfaces->Clear();
+}
+
+SbClassFactory::SbClassFactory( void )
+{
+ String aDummyName;
+ xClassModules = new SbxObject( aDummyName );
+}
+
+SbClassFactory::~SbClassFactory()
+{}
+
+SbxBase* SbClassFactory::Create( UINT16, UINT32 )
+{
+ // Not supported
+ return NULL;
+}
+
+SbxObject* SbClassFactory::CreateObject( const String& rClassName )
+{
+ SbxVariable* pVar = xClassModules->Find( rClassName, SbxCLASS_DONTCARE );
+ SbxObject* pRet = NULL;
+ if( pVar )
+ {
+ SbModule* pMod = (SbModule*)pVar;
+ pRet = new SbClassModuleObject( pMod );
+ }
+ return pRet;
+}
+
+////////////////////////////////////////////////////////////////////////////
+
+StarBASIC::StarBASIC( StarBASIC* p )
+ : SbxObject( String( RTL_CONSTASCII_USTRINGPARAM("StarBASIC") ) )
+{
+ SetParent( p );
+ pLibInfo = NULL;
+ bNoRtl = bBreak = FALSE;
+ pModules = new SbxArray;
+
+ if( !GetSbData()->nInst++ )
+ {
+ pSBFAC = new SbiFactory;
+ AddFactory( pSBFAC );
+ pUNOFAC = new SbUnoFactory;
+ AddFactory( pUNOFAC );
+ pTYPEFAC = new SbTypeFactory;
+ AddFactory( pTYPEFAC );
+ pCLASSFAC = new SbClassFactory;
+ AddFactory( pCLASSFAC );
+ pOLEFAC = new SbOLEFactory;
+ AddFactory( pOLEFAC );
+ }
+// pRtl = new SbiStdObject( String( RTL_CONSTASCII_USTRINGPARAM(RTLNAME) ), this );
+ // Suche ueber StarBASIC ist immer global
+ SetFlag( SBX_GBLSEARCH );
+}
+
+// #51727 SetModified ueberladen, damit der Modified-
+// Zustand nicht an den Parent weitergegeben wird.
+void StarBASIC::SetModified( BOOL b )
+{
+ SbxBase::SetModified( b );
+}
+
+//***
+
+StarBASIC::~StarBASIC()
+{
+ if( !--GetSbData()->nInst )
+ {
+ RemoveFactory( pSBFAC );
+ pSBFAC = NULL;
+ RemoveFactory( pUNOFAC );
+ pUNOFAC = NULL;
+ RemoveFactory( pTYPEFAC );
+ pTYPEFAC = NULL;
+ RemoveFactory( pCLASSFAC );
+ pCLASSFAC = NULL;
+ RemoveFactory( pOLEFAC );
+ pOLEFAC = NULL;
+ }
+
+ // #100326 Set Parent NULL in registered listeners
+ if( xUnoListeners.Is() )
+ {
+ USHORT uCount = xUnoListeners->Count();
+ for( USHORT i = 0 ; i < uCount ; i++ )
+ {
+ SbxVariable* pListenerObj = xUnoListeners->Get( i );
+ pListenerObj->SetParent( NULL );
+ }
+ xUnoListeners = NULL;
+ }
+}
+
+// operator new() wird hier versenkt, damit jeder eine Instanz
+// anlegen kann, ohne neu zu bilden.
+
+void* StarBASIC::operator new( size_t n )
+{
+ if( n < sizeof( StarBASIC ) )
+ {
+// DBG_ASSERT( FALSE, "Warnung: inkompatibler BASIC-Stand!" );
+ n = sizeof( StarBASIC );
+ }
+ return ::operator new( n );
+}
+
+void StarBASIC::operator delete( void* p )
+{
+ ::operator delete( p );
+}
+
+/**************************************************************************
+*
+* Erzeugen/Verwalten von Modulen
+*
+**************************************************************************/
+
+SbModule* StarBASIC::MakeModule32( const String& rName, const ::rtl::OUString& rSrc )
+{
+ SbModule* p = new SbModule( rName );
+ p->SetSource32( rSrc );
+ p->SetParent( this );
+ pModules->Insert( p, pModules->Count() );
+ SetModified( TRUE );
+ return p;
+}
+
+void StarBASIC::Insert( SbxVariable* pVar )
+{
+ if( pVar->IsA( TYPE(SbModule) ) )
+ {
+ pModules->Insert( pVar, pModules->Count() );
+ pVar->SetParent( this );
+ StartListening( pVar->GetBroadcaster(), TRUE );
+ }
+ else
+ {
+ BOOL bWasModified = IsModified();
+ SbxObject::Insert( pVar );
+ if( !bWasModified && pVar->IsSet( SBX_DONTSTORE ) )
+ SetModified( FALSE );
+ }
+}
+
+void StarBASIC::Remove( SbxVariable* pVar )
+{
+ if( pVar->IsA( TYPE(SbModule) ) )
+ {
+ // #87540 Can be last reference!
+ SbxVariableRef xVar = pVar;
+ pModules->Remove( pVar );
+ pVar->SetParent( 0 );
+ EndListening( pVar->GetBroadcaster() );
+ }
+ else
+ SbxObject::Remove( pVar );
+}
+
+void StarBASIC::Clear()
+{
+ while( pModules->Count() )
+ pModules->Remove( pModules->Count() - 1 );
+}
+
+SbModule* StarBASIC::FindModule( const String& rName )
+{
+ for( USHORT i = 0; i < pModules->Count(); i++ )
+ {
+ SbModule* p = (SbModule*) pModules->Get( i );
+ if( p->GetName().EqualsIgnoreCaseAscii( rName ) )
+ return p;
+ }
+ return NULL;
+}
+
+// Init-Code aller Module ausfuehren (auch in inserteten Bibliotheken)
+void StarBASIC::InitAllModules( StarBASIC* pBasicNotToInit )
+{
+ // Eigene Module initialisieren
+/*?*/ // for ( USHORT nMod = 0; nMod < pModules->Count(); nMod++ )
+/*?*/ // {
+/*?*/ // SbModule* pModule = (SbModule*)pModules->Get( nMod );
+/*?*/ // if( !pModule->IsCompiled() )
+/*?*/ // pModule->Compile();
+/*?*/ // pModule->RunInit();
+/*?*/ // }
+ DBG_ERROR( "StarBASIC::InitAllModules: dead code!" );
+ // Alle Objekte ueberpruefen, ob es sich um ein Basic handelt
+ // Wenn ja, auch dort initialisieren
+ for ( USHORT nObj = 0; nObj < pObjs->Count(); nObj++ )
+ {
+ SbxVariable* pVar = pObjs->Get( nObj );
+ StarBASIC* pBasic = PTR_CAST(StarBASIC,pVar);
+ if( pBasic && pBasic != pBasicNotToInit )
+ pBasic->InitAllModules();
+ }
+}
+
+// #88329 Put modules back to not initialised state to
+// force reinitialisation at next start
+void StarBASIC::DeInitAllModules( void )
+{
+ // Eigene Module initialisieren
+ for ( USHORT nMod = 0; nMod < pModules->Count(); nMod++ )
+ {
+ SbModule* pModule = (SbModule*)pModules->Get( nMod );
+ if( pModule->pImage )
+ pModule->pImage->bInit = false;
+ }
+ // Alle Objekte ueberpruefen, ob es sich um ein Basic handelt
+ // Wenn ja, auch dort initialisieren
+ for ( USHORT nObj = 0; nObj < pObjs->Count(); nObj++ )
+ {
+ SbxVariable* pVar = pObjs->Get( nObj );
+ StarBASIC* pBasic = PTR_CAST(StarBASIC,pVar);
+ if( pBasic )
+ pBasic->DeInitAllModules();
+ }
+}
+
+// Diese Implementation sucht erst innerhalb der Runtime-Library, dann
+// nach einem Element innerhalb eines Moduls. Dieses Element kann eine
+// Public-Variable oder ein Entrypoint sein. Wenn nicht gefunden, wird,
+// falls nach einer Methode gesucht wird und ein Modul mit dem angege-
+// benen Namen gefunden wurde, der Entrypoint "Main" gesucht. Wenn das
+// auch nicht klappt, laeuft die traditionelle Suche ueber Objekte an.
+
+SbxVariable* StarBASIC::Find( const String& rName, SbxClassType t )
+{
+ static String aMainStr( RTL_CONSTASCII_USTRINGPARAM("Main") );
+
+ SbxVariable* pRes = NULL;
+ SbModule* pNamed = NULL;
+ // "Extended" search in Runtime Lib
+ // aber nur, wenn SbiRuntime nicht das Flag gesetzt hat
+ if( !bNoRtl )
+ {
+ if( t == SbxCLASS_DONTCARE || t == SbxCLASS_OBJECT )
+ {
+ if( rName.EqualsIgnoreCaseAscii( RTLNAME ) )
+ pRes = pRtl;
+ }
+/*?*/ // if( !pRes )
+/*?*/ // pRes = ((SbiStdObject*) (SbxObject*) pRtl)->Find( rName, t );
+ if( pRes )
+ pRes->SetFlag( SBX_EXTFOUND );
+ }
+ // Module durchsuchen
+ if( !pRes )
+ for( USHORT i = 0; i < pModules->Count(); i++ )
+ {
+ SbModule* p = (SbModule*) pModules->Get( i );
+ if( p->IsVisible() )
+ {
+ // Modul merken fuer Main()-Aufruf
+ // oder stimmt etwa der Name ueberein?!?
+ if( p->GetName().EqualsIgnoreCaseAscii( rName ) )
+ {
+ if( t == SbxCLASS_OBJECT || t == SbxCLASS_DONTCARE )
+ {
+ pRes = p; break;
+ }
+ pNamed = p;
+ }
+ // Sonst testen, ob das Element vorhanden ist
+ // GBLSEARCH-Flag rausnehmen (wg. Rekursion)
+ USHORT nGblFlag = p->GetFlags() & SBX_GBLSEARCH;
+ p->ResetFlag( SBX_GBLSEARCH );
+ pRes = p->Find( rName, t );
+ p->SetFlag( nGblFlag );
+ if( pRes )
+ break;
+ }
+ }
+ if( !pRes && pNamed && ( t == SbxCLASS_METHOD || t == SbxCLASS_DONTCARE ) &&
+ !pNamed->GetName().EqualsIgnoreCaseAscii( aMainStr ) )
+ pRes = pNamed->Find( aMainStr, SbxCLASS_METHOD );
+ if( !pRes )
+ pRes = SbxObject::Find( rName, t );
+ return pRes;
+}
+
+BOOL StarBASIC::Call( const String& rName, SbxArray* pParam )
+{
+ BOOL bRes = SbxObject::Call( rName, pParam );
+ if( !bRes )
+ {
+ SbxError eErr = SbxBase::GetError();
+ SbxBase::ResetError();
+ if( eErr != SbxERR_OK )
+ RTError( (SbError)eErr, 0, 0, 0 );
+ }
+ return bRes;
+}
+
+void StarBASIC::Stop()
+{
+/*?*/ // SbiInstance* p = pINST;
+/*?*/ // while( p )
+/*?*/ // {
+/*?*/ // p->Stop();
+/*?*/ // p = p->pNext;
+/*?*/ // }
+}
+
+BOOL StarBASIC::IsRunning()
+{
+ return BOOL( pINST != NULL );
+}
+
+/**************************************************************************
+*
+* Debugging und Fehlerbehandlung
+*
+**************************************************************************/
+
+USHORT __EXPORT StarBASIC::BreakHdl()
+{
+ return (USHORT) ( aBreakHdl.IsSet()
+ ? aBreakHdl.Call( this ) : SbDEBUG_CONTINUE );
+}
+
+// AB: 29.3.96
+// Das Mapping zwischen alten und neuen Fehlercodes erfolgt, indem die Tabelle
+// SFX_VB_ErrorTab[] durchsucht wird. Dies ist zwar nicht besonders performant,
+// verbraucht aber viel weniger Speicher als entsprechende switch-Bloecke.
+// Die Umrechnung von Fehlercodes muss nicht schnell sein, daher auch keine
+// binaere Suche bei VB-Error -> SFX-Error.
+
+// Neue Fehler-Codes auf alte, Sbx-Kompatible zurueckmappen
+USHORT StarBASIC::GetVBErrorCode( SbError nError )
+{
+ USHORT nRet = 0;
+
+ // Suchschleife
+ const SFX_VB_ErrorItem* pErrItem;
+ USHORT nIndex = 0;
+ do
+ {
+ pErrItem = SFX_VB_ErrorTab + nIndex;
+ if( pErrItem->nErrorSFX == nError )
+ {
+ nRet = pErrItem->nErrorVB;
+ break;
+ }
+ nIndex++;
+ }
+ while( pErrItem->nErrorVB != 0xFFFF ); // bis End-Marke
+ return nRet;
+}
+
+SbError StarBASIC::GetSfxFromVBError( USHORT nError )
+{
+ SbError nRet = 0L;
+
+ // Suchschleife
+ const SFX_VB_ErrorItem* pErrItem;
+ USHORT nIndex = 0;
+ do
+ {
+ pErrItem = SFX_VB_ErrorTab + nIndex;
+ if( pErrItem->nErrorVB == nError )
+ {
+ nRet = pErrItem->nErrorSFX;
+ break;
+ }
+ else if( pErrItem->nErrorVB > nError )
+ break; // kann nicht mehr gefunden werden
+
+ nIndex++;
+ }
+ while( pErrItem->nErrorVB != 0xFFFF ); // bis End-Marke
+ return nRet;
+}
+
+// Error- / Break-Daten setzen
+void StarBASIC::SetErrorData
+( SbError nCode, USHORT nLine, USHORT nCol1, USHORT nCol2 )
+{
+ SbiGlobals& aGlobals = *GetSbData();
+ aGlobals.nCode = nCode;
+ aGlobals.nLine = nLine;
+ aGlobals.nCol1 = nCol1;
+ aGlobals.nCol2 = nCol2;
+}
+
+//----------------------------------------------------------------
+// Hilfsklasse zum Zugriff auf String SubResourcen einer Resource.
+// Quelle: sfx2\source\doc\docfile.cxx (TLX)
+struct BasicStringList_Impl : private Resource
+{
+ ResId aResId;
+
+ BasicStringList_Impl( ResId& rErrIdP, USHORT nId)
+ : Resource( rErrIdP ),aResId(nId,*rErrIdP.GetResMgr()){}
+ ~BasicStringList_Impl() { FreeResource(); }
+
+ String GetString(){ return String( aResId ); }
+ BOOL IsErrorTextAvailable( void )
+ { return IsAvailableRes(aResId.SetRT(RSC_STRING)); }
+};
+//----------------------------------------------------------------
+
+// #60175 Flag, das bei Basic-Fehlern das Anziehen der SFX-Resourcen verhindert
+static BOOL bStaticSuppressSfxResource = FALSE;
+
+void StarBASIC::MakeErrorText( SbError nId, const String& /*aMsg*/ )
+{
+ SolarMutexGuard aSolarGuard;
+
+ if( bStaticSuppressSfxResource )
+ {
+ GetSbData()->aErrMsg = String( RTL_CONSTASCII_USTRINGPARAM("No resource: Error message not available") );
+ return;
+ }
+
+ USHORT nOldID = GetVBErrorCode( nId );
+
+ // Hilfsklasse instanzieren
+/*?*/ // BasicResId aId( RID_BASIC_START );
+/*?*/ // BasicStringList_Impl aMyStringList( aId, USHORT(nId & ERRCODE_RES_MASK) );
+
+/*?*/ // if( aMyStringList.IsErrorTextAvailable() )
+/*?*/ ///*?*/ // {
+/*?*/ // // Merge Message mit Zusatztext
+/*?*/ // String aMsg1 = aMyStringList.GetString();
+/*?*/ // // Argument-Platzhalter durch %s ersetzen
+/*?*/ // String aSrgStr( RTL_CONSTASCII_USTRINGPARAM("$(ARG1)") );
+/*?*/ // USHORT nResult = aMsg1.Search( aSrgStr );
+/*?*/ //
+/*?*/ // if( nResult != STRING_NOTFOUND )
+/*?*/ // {
+/*?*/ // aMsg1.Erase( nResult, aSrgStr.Len() );
+/*?*/ // aMsg1.Insert( aMsg, nResult );
+/*?*/ // }
+/*?*/ // GetSbData()->aErrMsg = aMsg1;
+/*?*/ // }
+/*?*/ // else if( nOldID != 0 )
+ if( nOldID != 0 )
+ {
+ String aStdMsg( RTL_CONSTASCII_USTRINGPARAM("error ") );
+ aStdMsg += String::CreateFromInt32( nOldID);
+ aStdMsg += String( RTL_CONSTASCII_USTRINGPARAM(": no error message available!") );
+ GetSbData()->aErrMsg = aStdMsg;
+ }
+ else
+ GetSbData()->aErrMsg = String::EmptyString();
+}
+
+BOOL StarBASIC::CError
+ ( SbError code, const String& rMsg, USHORT l, USHORT c1, USHORT c2 )
+{
+ SolarMutexGuard aSolarGuard;
+
+ // Compiler-Fehler waehrend der Laufzeit -> Programm anhalten
+ if( IsRunning() )
+ {
+ // #109018 Check if running Basic is affected
+/*?*/ // StarBASIC* pStartedBasic = pINST->GetBasic();
+/*?*/ // if( pStartedBasic != this )
+/*?*/ // return FALSE;
+
+ Stop();
+ }
+
+ // Flag setzen, damit GlobalRunInit den Fehler mitbekommt
+ GetSbData()->bGlobalInitErr = TRUE;
+
+ // Fehlertext basteln
+ MakeErrorText( code, rMsg );
+
+ // Umsetzung des Codes fuer String-Transport in SFX-Error
+ if( rMsg.Len() )
+ code = (ULONG)*new StringErrorInfo( code, String(rMsg) );
+
+ SetErrorData( code, l, c1, c2 );
+ GetSbData()->bCompiler = TRUE;
+ BOOL bRet;
+ if( GetSbData()->aErrHdl.IsSet() )
+ bRet = (BOOL) GetSbData()->aErrHdl.Call( this );
+ else
+ bRet = ErrorHdl();
+ GetSbData()->bCompiler = FALSE; // nur TRUE fuer Error-Handler
+ return bRet;
+}
+
+BOOL StarBASIC::RTError
+ ( SbError code, USHORT l, USHORT c1, USHORT c2 )
+{
+ return RTError( code, String(), l, c1, c2 );
+}
+
+BOOL StarBASIC::RTError( SbError code, const String& rMsg, USHORT l, USHORT c1, USHORT c2 )
+{
+ SolarMutexGuard aSolarGuard;
+
+ SbError c = code;
+ if( (c & ERRCODE_CLASS_MASK) == ERRCODE_CLASS_COMPILER )
+ c = 0;
+ MakeErrorText( c, rMsg );
+
+ // Umsetzung des Codes fuer String-Transport in SFX-Error
+ if( rMsg.Len() )
+ code = (ULONG)*new StringErrorInfo( code, String(rMsg) );
+
+ SetErrorData( code, l, c1, c2 );
+ if( GetSbData()->aErrHdl.IsSet() )
+ return (BOOL) GetSbData()->aErrHdl.Call( this );
+ else
+ return ErrorHdl();
+}
+
+void StarBASIC::Error( SbError n )
+{
+ Error( n, String() );
+}
+
+void StarBASIC::Error( SbError /*n*/, const String& /*rMsg*/ )
+{
+/*?*/ // if( pINST )
+/*?*/ // pINST->Error( n, rMsg );
+}
+
+void StarBASIC::FatalError( SbError /*n*/ )
+{
+/*?*/ // if( pINST )
+/*?*/ // pINST->FatalError( n );
+}
+
+BOOL __EXPORT StarBASIC::ErrorHdl()
+{
+ return (BOOL) ( aErrorHdl.IsSet()
+ ? aErrorHdl.Call( this ) : FALSE );
+}
+
+/**************************************************************************
+*
+* Laden und Speichern
+*
+**************************************************************************/
+
+BOOL StarBASIC::LoadData( SvStream& r, USHORT nVer )
+{
+ if( !SbxObject::LoadData( r, nVer ) )
+ return FALSE;
+
+ // #95459 Delete dialogs, otherwise endless recursion
+ // in SbxVarable::GetType() if dialogs are accessed
+ USHORT nObjCount = pObjs->Count();
+ SbxVariable** ppDeleteTab = new SbxVariable*[ nObjCount ];
+ USHORT nObj;
+
+ for( nObj = 0 ; nObj < nObjCount ; nObj++ )
+ {
+ SbxVariable* pVar = pObjs->Get( nObj );
+ StarBASIC* pBasic = PTR_CAST( StarBASIC, pVar );
+ ppDeleteTab[nObj] = pBasic ? NULL : pVar;
+ }
+ for( nObj = 0 ; nObj < nObjCount ; nObj++ )
+ {
+ SbxVariable* pVar = ppDeleteTab[nObj];
+ if( pVar )
+ pObjs->Remove( pVar );
+ }
+ delete[] ppDeleteTab;
+
+ UINT16 nMod;
+ pModules->Clear();
+ r >> nMod;
+ for( USHORT i = 0; i < nMod; i++ )
+ {
+ SbModule* pMod = (SbModule*) SbxBase::Load( r );
+ if( !pMod )
+ return FALSE;
+ else if( pMod->ISA(SbJScriptModule) )
+ {
+ // Ref zuweisen, damit pMod deleted wird
+ SbModuleRef xRef = pMod;
+ }
+ else
+ {
+ pMod->SetParent( this );
+ pModules->Put( pMod, i );
+ }
+ }
+ // HACK fuer SFX-Mist!
+ SbxVariable* p = Find( String( RTL_CONSTASCII_USTRINGPARAM("FALSE") ), SbxCLASS_PROPERTY );
+ if( p )
+ Remove( p );
+ p = Find( String( RTL_CONSTASCII_USTRINGPARAM("TRUE") ), SbxCLASS_PROPERTY );
+ if( p )
+ Remove( p );
+ // Ende des Hacks!
+ // Suche ueber StarBASIC ist immer global
+ DBG_ASSERT( IsSet( SBX_GBLSEARCH ), "Basic ohne GBLSEARCH geladen" );
+ SetFlag( SBX_GBLSEARCH );
+ return TRUE;
+}
+
+BOOL StarBASIC::StoreData( SvStream& r ) const
+{
+ if( !SbxObject::StoreData( r ) )
+ return FALSE;
+ r << (UINT16) pModules->Count();
+ for( USHORT i = 0; i < pModules->Count(); i++ )
+ {
+ SbModule* p = (SbModule*) pModules->Get( i );
+ if( !p->Store( r ) )
+ return FALSE;
+ }
+ return TRUE;
+}
+
+//========================================================================
+// #118116 Implementation Collection object
+
+TYPEINIT1(BasicCollection,SbxObject)
+
+static const char pCountStr[] = "Count";
+static const char pAddStr[] = "Add";
+static const char pItemStr[] = "Item";
+static const char pRemoveStr[] = "Remove";
+static USHORT nCountHash = 0, nAddHash, nItemHash, nRemoveHash;
+
+BasicCollection::BasicCollection( const XubString& rClass )
+ : SbxObject( rClass )
+{
+ if( !nCountHash )
+ {
+ nCountHash = MakeHashCode( String::CreateFromAscii( pCountStr ) );
+ nAddHash = MakeHashCode( String::CreateFromAscii( pAddStr ) );
+ nItemHash = MakeHashCode( String::CreateFromAscii( pItemStr ) );
+ nRemoveHash = MakeHashCode( String::CreateFromAscii( pRemoveStr ) );
+ }
+ Initialize();
+}
+
+BasicCollection::~BasicCollection()
+{}
+
+void BasicCollection::Clear()
+{
+ SbxObject::Clear();
+ Initialize();
+}
+
+void BasicCollection::Initialize()
+{
+ xItemArray = new SbxArray();
+ SetType( SbxOBJECT );
+ SetFlag( SBX_FIXED );
+ ResetFlag( SBX_WRITE );
+ SbxVariable* p;
+ p = Make( String::CreateFromAscii( pCountStr ), SbxCLASS_PROPERTY, SbxINTEGER );
+ p->ResetFlag( SBX_WRITE );
+ p->SetFlag( SBX_DONTSTORE );
+ p = Make( String::CreateFromAscii( pAddStr ), SbxCLASS_METHOD, SbxEMPTY );
+ p->SetFlag( SBX_DONTSTORE );
+ p = Make( String::CreateFromAscii( pItemStr ), SbxCLASS_METHOD, SbxVARIANT );
+ p->SetFlag( SBX_DONTSTORE );
+ p = Make( String::CreateFromAscii( pRemoveStr ), SbxCLASS_METHOD, SbxEMPTY );
+ p->SetFlag( SBX_DONTSTORE );
+}
+
+SbxVariable* BasicCollection::Find( const XubString& rName, SbxClassType t )
+{
+ SbxVariable* pFind = SbxObject::Find( rName, t );
+ return pFind;
+}
+
+void BasicCollection::SFX_NOTIFY( SfxBroadcaster& rCst, const TypeId& rId1,
+ const SfxHint& rHint, const TypeId& rId2 )
+{
+ const SbxHint* p = PTR_CAST(SbxHint,&rHint);
+ if( p )
+ {
+ ULONG nId = p->GetId();
+ BOOL bRead = BOOL( nId == SBX_HINT_DATAWANTED );
+ BOOL bWrite = BOOL( nId == SBX_HINT_DATACHANGED );
+ SbxVariable* pVar = p->GetVar();
+ SbxArray* pArg = pVar->GetParameters();
+ if( bRead || bWrite )
+ {
+ XubString aVarName( pVar->GetName() );
+ if( pVar->GetHashCode() == nCountHash
+ && aVarName.EqualsIgnoreCaseAscii( pCountStr ) )
+ pVar->PutLong( xItemArray->Count32() );
+ else if( pVar->GetHashCode() == nAddHash
+ && aVarName.EqualsIgnoreCaseAscii( pAddStr ) )
+ CollAdd( pArg );
+ else if( pVar->GetHashCode() == nItemHash
+ && aVarName.EqualsIgnoreCaseAscii( pItemStr ) )
+ CollItem( pArg );
+ else if( pVar->GetHashCode() == nRemoveHash
+ && aVarName.EqualsIgnoreCaseAscii( pRemoveStr ) )
+ CollRemove( pArg );
+ else
+ SbxObject::SFX_NOTIFY( rCst, rId1, rHint, rId2 );
+ return;
+ }
+ }
+ SbxObject::SFX_NOTIFY( rCst, rId1, rHint, rId2 );
+}
+
+INT32 BasicCollection::implGetIndex( SbxVariable* pIndexVar )
+{
+ INT32 nIndex = -1;
+ if( pIndexVar->GetType() == SbxSTRING )
+ nIndex = implGetIndexForName( pIndexVar->GetString() );
+ else
+ nIndex = pIndexVar->GetLong() - 1;
+ return nIndex;
+}
+
+INT32 BasicCollection::implGetIndexForName( const String& rName )
+{
+ INT32 nIndex = -1;
+ INT32 nCount = xItemArray->Count32();
+ INT32 nNameHash = MakeHashCode( rName );
+ for( INT32 i = 0 ; i < nCount ; i++ )
+ {
+ SbxVariable* pVar = xItemArray->Get32( i );
+ if( pVar->GetHashCode() == nNameHash &&
+ pVar->GetName().EqualsIgnoreCaseAscii( rName ) )
+ {
+ nIndex = i;
+ break;
+ }
+ }
+ return nIndex;
+}
+
+void BasicCollection::CollAdd( SbxArray* pPar_ )
+{
+ USHORT nCount = pPar_->Count();
+ if( nCount < 2 || nCount > 5 )
+ {
+ SetError( SbxERR_WRONG_ARGS );
+ return;
+ }
+
+ SbxVariable* pItem = pPar_->Get(1);
+ if( pItem )
+ {
+ int nNextIndex;
+ if( nCount < 4 )
+ {
+ nNextIndex = xItemArray->Count();
+ }
+ else
+ {
+ SbxVariable* pBefore = pPar_->Get(3);
+ if( nCount == 5 )
+ {
+ if( !pBefore->IsErr() )
+ {
+ SetError( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ SbxVariable* pAfter = pPar_->Get(4);
+ INT32 nAfterIndex = implGetIndex( pAfter );
+ if( nAfterIndex == -1 )
+ {
+ SetError( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ nNextIndex = nAfterIndex + 1;
+ }
+ else // if( nCount == 4 )
+ {
+ INT32 nBeforeIndex = implGetIndex( pBefore );
+ if( nBeforeIndex == -1 )
+ {
+ SetError( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ nNextIndex = nBeforeIndex;
+ }
+ }
+
+ SbxVariableRef pNewItem = new SbxVariable( *pItem );
+ if( nCount >= 3 )
+ {
+ SbxVariable* pKey = pPar_->Get(2);
+ if( !pKey->IsErr() )
+ {
+ if( pKey->GetType() != SbxSTRING )
+ {
+ SetError( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ String aKey = pKey->GetString();
+ if( implGetIndexForName( aKey ) != -1 )
+ {
+ SetError( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ pNewItem->SetName( aKey );
+ }
+ }
+ pNewItem->SetFlag( SBX_READWRITE );
+ xItemArray->Insert32( pNewItem, nNextIndex );
+ }
+ else
+ {
+ SetError( SbERR_BAD_ARGUMENT );
+ return;
+ }
+}
+
+void BasicCollection::CollItem( SbxArray* pPar_ )
+{
+ if( pPar_->Count() != 2 )
+ {
+ SetError( SbxERR_WRONG_ARGS );
+ return;
+ }
+ SbxVariable* pRes = NULL;
+ SbxVariable* p = pPar_->Get( 1 );
+ INT32 nIndex = implGetIndex( p );
+ if( nIndex >= 0 && nIndex < (INT32)xItemArray->Count32() )
+ pRes = xItemArray->Get32( nIndex );
+ if( !pRes )
+ SetError( SbxERR_BAD_INDEX );
+ *(pPar_->Get(0)) = *pRes;
+}
+
+void BasicCollection::CollRemove( SbxArray* pPar_ )
+{
+ if( pPar_ == NULL || pPar_->Count() != 2 )
+ {
+ SetError( SbxERR_WRONG_ARGS );
+ return;
+ }
+
+ SbxVariable* p = pPar_->Get( 1 );
+ INT32 nIndex = implGetIndex( p );
+ if( nIndex >= 0 && nIndex < (INT32)xItemArray->Count32() )
+ xItemArray->Remove32( nIndex );
+ else
+ SetError( SbxERR_BAD_INDEX );
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/classes/sbintern.cxx b/binfilter/bf_basic/source/classes/sbintern.cxx
new file mode 100644
index 000000000000..1fdb6f5c1cde
--- /dev/null
+++ b/binfilter/bf_basic/source/classes/sbintern.cxx
@@ -0,0 +1,79 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "sbintern.hxx"
+#include "sbunoobj.hxx"
+#include "token.hxx" // Tokenizer
+#include "codegen.hxx" // Code-Generator
+#include "basmgr.hxx"
+
+namespace binfilter {
+
+SV_IMPL_PTRARR(SbErrorStack, SbErrorStackEntry*)
+
+SbiGlobals* GetSbData()
+{
+ DBG_TESTSOLARMUTEX();
+ static SbiGlobals* s_pGlobals = new SbiGlobals;
+ return s_pGlobals;
+}
+
+SbiGlobals::SbiGlobals()
+{
+ pInst = NULL;
+ pMod = NULL;
+ pSbFac= NULL;
+ pUnoFac = NULL;
+ pTypeFac = NULL;
+ pOLEFac = NULL;
+ pCompMod = NULL; // JSM
+ nInst = 0;
+ nCode = 0;
+ nLine = 0;
+ nCol1 = nCol2 = 0;
+ bCompiler = FALSE;
+ bGlobalInitErr = FALSE;
+ bRunInit = FALSE;
+ eLanguageMode = SB_LANG_BASIC;
+ pErrStack = NULL;
+ pTransliterationWrapper = NULL;
+ bBlockCompilerError = FALSE;
+ pAppBasMgr = NULL;
+}
+
+SbiGlobals::~SbiGlobals()
+{
+ delete pErrStack;
+ delete pSbFac;
+ delete pUnoFac;
+ delete pTransliterationWrapper;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/classes/sbunoobj.cxx b/binfilter/bf_basic/source/classes/sbunoobj.cxx
new file mode 100644
index 000000000000..4853691c678d
--- /dev/null
+++ b/binfilter/bf_basic/source/classes/sbunoobj.cxx
@@ -0,0 +1,2710 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <osl/mutex.hxx>
+#include <vcl/svapp.hxx>
+#include <tools/errcode.hxx>
+#include <bf_svtools/hint.hxx>
+
+#include <cppuhelper/implbase1.hxx>
+#include <cppuhelper/typeprovider.hxx>
+#include <cppuhelper/extract.hxx>
+
+#include <comphelper/processfactory.hxx>
+
+#include <rtl/ustrbuf.hxx>
+#include <rtl/strbuf.hxx>
+
+#include <com/sun/star/script/ArrayWrapper.hpp>
+
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/uno/DeploymentException.hpp>
+#include <com/sun/star/lang/XTypeProvider.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/PropertyConcept.hpp>
+#include <com/sun/star/beans/MethodConcept.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/script/BasicErrorException.hpp>
+#include <com/sun/star/script/XAllListener.hpp>
+#include <com/sun/star/script/XInvocationAdapterFactory.hpp>
+#include <com/sun/star/script/XTypeConverter.hpp>
+#include <com/sun/star/script/XDefaultProperty.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/reflection/XIdlArray.hpp>
+#include <com/sun/star/reflection/XIdlReflection.hpp>
+#include <com/sun/star/reflection/XIdlClassProvider.hpp>
+#include <com/sun/star/reflection/XTypeDescription.hpp>
+#include <com/sun/star/bridge/oleautomation/NamedArgument.hpp>
+#include <com/sun/star/bridge/oleautomation/Date.hpp>
+#include <com/sun/star/bridge/oleautomation/Decimal.hpp>
+#include <com/sun/star/bridge/oleautomation/Currency.hpp>
+
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::reflection;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::script;
+using namespace com::sun::star::container;
+using namespace com::sun::star::bridge;
+using namespace cppu;
+using namespace rtl;
+
+
+#include "sbstar.hxx"
+#include "sberrors.hxx"
+#include "sbunoobj.hxx"
+#include "sbjsmod.hxx"
+#include "basmgr.hxx"
+#include "sbintern.hxx"
+
+#include<math.h>
+
+namespace binfilter {
+
+TYPEINIT1(SbUnoMethod,SbxMethod)
+TYPEINIT1(SbUnoProperty,SbxProperty)
+TYPEINIT1(SbUnoObject,SbxObject)
+TYPEINIT1(SbUnoClass,SbxObject)
+
+typedef WeakImplHelper1< XAllListener > BasicAllListenerHelper;
+
+// Flag, um immer ueber Invocation zu gehen
+//#define INVOCATION_ONLY
+
+
+// Identifier fuer die dbg_-Properies als Strings anlegen
+static String ID_DBG_SUPPORTEDINTERFACES( RTL_CONSTASCII_USTRINGPARAM("Dbg_SupportedInterfaces") );
+static String ID_DBG_PROPERTIES( RTL_CONSTASCII_USTRINGPARAM("Dbg_Properties") );
+static String ID_DBG_METHODS( RTL_CONSTASCII_USTRINGPARAM("Dbg_Methods") );
+
+static String aIllegalArgumentExceptionName
+ ( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.lang.IllegalArgumentException" ) );
+static OUString aSeqLevelStr( RTL_CONSTASCII_USTRINGPARAM("[]") );
+
+Reference< XComponentContext > getComponentContext_Impl( void )
+{
+ static Reference< XComponentContext > xContext;
+
+ // Haben wir schon CoreReflection, sonst besorgen
+ if( !xContext.is() )
+ {
+ Reference< XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory();
+ Reference< XPropertySet > xProps( xFactory, UNO_QUERY );
+ OSL_ASSERT( xProps.is() );
+ if (xProps.is())
+ {
+ xProps->getPropertyValue(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= xContext;
+ OSL_ASSERT( xContext.is() );
+ }
+ }
+ return xContext;
+}
+
+// CoreReflection statisch speichern
+Reference< XIdlReflection > getCoreReflection_Impl( void )
+{
+ static Reference< XIdlReflection > xCoreReflection;
+
+ // Haben wir schon CoreReflection, sonst besorgen
+ if( !xCoreReflection.is() )
+ {
+ Reference< XComponentContext > xContext = getComponentContext_Impl();
+ if( xContext.is() )
+ {
+ xContext->getValueByName(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("/singletons/com.sun.star.reflection.theCoreReflection") ) )
+ >>= xCoreReflection;
+ OSL_ENSURE( xCoreReflection.is(), "### CoreReflection singleton not accessable!?" );
+ }
+ if( !xCoreReflection.is() )
+ {
+ throw DeploymentException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("/singletons/com.sun.star.reflection.theCoreReflection singleton not accessable") ),
+ Reference< XInterface >() );
+ }
+ }
+ return xCoreReflection;
+}
+
+// CoreReflection statisch speichern
+Reference< XHierarchicalNameAccess > getCoreReflection_HierarchicalNameAccess_Impl( void )
+{
+ static Reference< XHierarchicalNameAccess > xCoreReflection_HierarchicalNameAccess;
+
+ if( !xCoreReflection_HierarchicalNameAccess.is() )
+ {
+ Reference< XIdlReflection > xCoreReflection = getCoreReflection_Impl();
+ if( xCoreReflection.is() )
+ {
+ xCoreReflection_HierarchicalNameAccess =
+ Reference< XHierarchicalNameAccess >( xCoreReflection, UNO_QUERY );
+ }
+ }
+ return xCoreReflection_HierarchicalNameAccess;
+}
+
+// Hold TypeProvider statically
+Reference< XHierarchicalNameAccess > getTypeProvider_Impl( void )
+{
+ static Reference< XHierarchicalNameAccess > xAccess;
+
+ // Haben wir schon CoreReflection, sonst besorgen
+ if( !xAccess.is() )
+ {
+ Reference< XComponentContext > xContext = getComponentContext_Impl();
+ if( xContext.is() )
+ {
+ xContext->getValueByName(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("/singletons/com.sun.star.reflection.theTypeDescriptionManager") ) )
+ >>= xAccess;
+ OSL_ENSURE( xAccess.is(), "### TypeDescriptionManager singleton not accessable!?" );
+ }
+ if( !xAccess.is() )
+ {
+ throw DeploymentException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM
+ ("/singletons/com.sun.star.reflection.theTypeDescriptionManager singleton not accessable") ),
+ Reference< XInterface >() );
+ }
+ }
+ return xAccess;
+}
+
+// #111851 factory function to create an OLE object
+SbUnoObject* createOLEObject_Impl( const String& aType )
+{
+ static Reference< XMultiServiceFactory > xOLEFactory;
+ static bool bNeedsInit = true;
+
+ if( bNeedsInit )
+ {
+ bNeedsInit = false;
+
+ Reference< XComponentContext > xContext = getComponentContext_Impl();
+ if( xContext.is() )
+ {
+ Reference<XMultiComponentFactory> xSMgr = xContext->getServiceManager();
+ xOLEFactory = Reference<XMultiServiceFactory>(
+ xSMgr->createInstanceWithContext(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.bridge.OleObjectFactory")),
+ xContext ), UNO_QUERY );
+ }
+ }
+
+ SbUnoObject* pUnoObj = NULL;
+ if( xOLEFactory.is() )
+ {
+ Reference< XInterface > xOLEObject = xOLEFactory->createInstance( aType );
+ if( xOLEObject.is() )
+ {
+ Any aAny;
+ aAny <<= xOLEObject;
+ pUnoObj = new SbUnoObject( aType, aAny );
+ }
+ }
+ return pUnoObj;
+}
+
+
+String implGetExceptionMsg( Exception& e, const String& aExceptionType_ );
+
+// #105565 Special Object to wrap a strongly typed Uno Any
+TYPEINIT1(SbUnoAnyObject,SbxObject)
+
+// TODO: Spaeter auslagern
+Reference<XIdlClass> TypeToIdlClass( const Type& rType )
+{
+ // void als Default-Klasse eintragen
+ Reference<XIdlClass> xRetClass;
+ typelib_TypeDescription * pTD = 0;
+ rType.getDescription( &pTD );
+
+ if( pTD )
+ {
+ OUString sOWName( pTD->pTypeName );
+ Reference< XIdlReflection > xRefl = getCoreReflection_Impl();
+ xRetClass = xRefl->forName( sOWName );
+ }
+ return xRetClass;
+}
+
+// Fehlermeldungs-Message bei Exception zusammenbauen
+String implGetExceptionMsg( Exception& e, const String& aExceptionType_ )
+{
+ String aExceptionType = aExceptionType_;
+ if( aExceptionType.Len() == 0 )
+ aExceptionType = String( RTL_CONSTASCII_USTRINGPARAM("Unknown" ) );
+
+ String aTypeLine( RTL_CONSTASCII_USTRINGPARAM("\nType: " ) );
+ aTypeLine += aExceptionType;
+
+ String aMessageLine( RTL_CONSTASCII_USTRINGPARAM("\nMessage: " ) );
+ aMessageLine += String( e.Message );
+
+ String aMsg = aTypeLine;
+ aMsg += aMessageLine;
+ return aMsg;
+}
+
+// Exception type unknown
+String implGetExceptionMsg( Exception& e )
+{
+ String aMsg = implGetExceptionMsg( e, String() );
+ return aMsg;
+}
+
+// Error-Message fuer WrappedTargetExceptions
+String implGetWrappedMsg( WrappedTargetException& e )
+{
+ String aMsg;
+ Any aWrappedAny = e.TargetException;
+ Type aExceptionType = aWrappedAny.getValueType();
+
+ // Really an Exception?
+ if( aExceptionType.getTypeClass() == TypeClass_EXCEPTION )
+ {
+ RuntimeException& e_ = *( (RuntimeException*)aWrappedAny.getValue() );
+ aMsg = implGetExceptionMsg( e_, String( aExceptionType.getTypeName() ) );
+ }
+ // Otherwise use WrappedTargetException itself
+ else
+ {
+ aMsg = implGetExceptionMsg( e );
+ }
+
+ return aMsg;
+}
+
+void implHandleBasicErrorException( BasicErrorException& e )
+{
+ SbError nError = StarBASIC::GetSfxFromVBError( (USHORT)e.ErrorCode );
+ StarBASIC::Error( nError, e.ErrorMessageArgument );
+}
+
+void implHandleWrappedTargetException( WrappedTargetException& e )
+{
+ SbError nError;
+ String aMessage;
+ Any aWrappedAny = e.TargetException;
+ if ( aWrappedAny.getValueType() == ::getCppuType( (BasicErrorException*)NULL ) )
+ {
+ BasicErrorException& be = *( (BasicErrorException*)aWrappedAny.getValue() );
+ nError = StarBASIC::GetSfxFromVBError( (USHORT)be.ErrorCode );
+ aMessage = be.ErrorMessageArgument;
+ }
+ else
+ {
+ nError = ERRCODE_BASIC_EXCEPTION;
+ aMessage = implGetWrappedMsg( e );
+ }
+ StarBASIC::Error( nError, aMessage );
+}
+
+// Von Uno nach Sbx wandeln
+SbxDataType unoToSbxType( TypeClass eType )
+{
+ SbxDataType eRetType = SbxVOID;
+
+ switch( eType )
+ {
+ case TypeClass_INTERFACE:
+ case TypeClass_TYPE:
+ case TypeClass_STRUCT:
+ case TypeClass_EXCEPTION: eRetType = SbxOBJECT; break;
+
+ /* folgende Typen lassen wir erstmal weg
+ case TypeClass_SERVICE: break;
+ case TypeClass_CLASS: break;
+ case TypeClass_TYPEDEF: break;
+ case TypeClass_UNION: break;
+ case TypeClass_ARRAY: break;
+ */
+ case TypeClass_ENUM: eRetType = SbxLONG; break;
+ case TypeClass_SEQUENCE:
+ eRetType = (SbxDataType) ( SbxOBJECT | SbxARRAY );
+ break;
+
+ /*
+ case TypeClass_VOID: break;
+ case TypeClass_UNKNOWN: break;
+ */
+
+ case TypeClass_ANY: eRetType = SbxVARIANT; break;
+ case TypeClass_BOOLEAN: eRetType = SbxBOOL; break;
+ case TypeClass_CHAR: eRetType = SbxCHAR; break;
+ case TypeClass_STRING: eRetType = SbxSTRING; break;
+ case TypeClass_FLOAT: eRetType = SbxSINGLE; break;
+ case TypeClass_DOUBLE: eRetType = SbxDOUBLE; break;
+ //case TypeClass_OCTET: break;
+ case TypeClass_BYTE: eRetType = SbxINTEGER; break;
+ //case TypeClass_INT: eRetType = SbxINT; break;
+ case TypeClass_SHORT: eRetType = SbxINTEGER; break;
+ case TypeClass_LONG: eRetType = SbxLONG; break;
+ case TypeClass_HYPER: eRetType = SbxSALINT64; break;
+ //case TypeClass_UNSIGNED_OCTET: break;
+ case TypeClass_UNSIGNED_SHORT: eRetType = SbxUSHORT; break;
+ case TypeClass_UNSIGNED_LONG: eRetType = SbxULONG; break;
+ case TypeClass_UNSIGNED_HYPER: eRetType = SbxSALUINT64;break;
+ //case TypeClass_UNSIGNED_INT: eRetType = SbxUINT; break;
+ //case TypeClass_UNSIGNED_BYTE: eRetType = SbxUSHORT; break;
+ default: break;
+ }
+ return eRetType;
+}
+
+SbxDataType unoToSbxType( const Reference< XIdlClass >& xIdlClass )
+{
+ SbxDataType eRetType = SbxVOID;
+ if( xIdlClass.is() )
+ {
+ TypeClass eType = xIdlClass->getTypeClass();
+ eRetType = unoToSbxType( eType );
+ }
+ return eRetType;
+}
+void unoToSbxValue( SbxVariable* pVar, const Any& aValue );
+static void implSequenceToMultiDimArray( SbxDimArray*& pArray, Sequence< sal_Int32 >& indices, Sequence< sal_Int32 >& sizes, const Any& aValue, sal_Int32& dimension, sal_Bool bIsZeroIndex )
+{
+ Type aType = aValue.getValueType();
+ TypeClass eTypeClass = aType.getTypeClass();
+
+ sal_Int32 indicesIndex = indices.getLength() -1;
+ sal_Int32 dimCopy = dimension;
+
+ if ( eTypeClass == TypeClass_SEQUENCE )
+ {
+ Reference< XIdlClass > xIdlTargetClass = TypeToIdlClass( aType );
+ Reference< XIdlArray > xIdlArray = xIdlTargetClass->getArray();
+ sal_Int32 nLen = xIdlArray->getLen( aValue );
+ for ( sal_Int32 index = 0; index < nLen; ++index )
+ {
+ Any aElementAny = xIdlArray->get( aValue, (UINT32)index );
+ // This detects the dimension were currently processing
+ if ( dimCopy == dimension )
+ {
+ ++dimCopy;
+ if ( sizes.getLength() < dimCopy )
+ {
+ sizes.realloc( sizes.getLength() + 1 );
+ sizes[ sizes.getLength() - 1 ] = nLen;
+ indices.realloc( indices.getLength() + 1 );
+ indicesIndex = indices.getLength() - 1;
+ }
+ }
+
+ if ( bIsZeroIndex )
+ indices[ dimCopy - 1 ] = index;
+ else
+ indices[ dimCopy - 1] = index + 1;
+
+ implSequenceToMultiDimArray( pArray, indices, sizes, aElementAny, dimCopy, bIsZeroIndex );
+ }
+
+ }
+ else
+ {
+ if ( indices.getLength() < 1 )
+ {
+ // Should never ever get here ( indices.getLength()
+ // should equal number of dimensions in the array )
+ // And that should at least be 1 !
+ // #QUESTION is there a better error?
+ StarBASIC::Error( SbERR_INVALID_OBJECT );
+ return;
+ }
+
+ if ( !pArray )
+ {
+ SbxDataType eSbxElementType = unoToSbxType( aValue.getValueTypeClass() );
+ pArray = new SbxDimArray( eSbxElementType );
+ sal_Int32 nIndexLen = indices.getLength();
+
+ // Dimension the array
+ for ( sal_Int32 index = 0; index < nIndexLen; ++index )
+ {
+ if ( bIsZeroIndex )
+ pArray->unoAddDim32( 0, sizes[ index ] - 1);
+ else
+ pArray->unoAddDim32( 1, sizes[ index ] );
+
+ }
+ }
+
+ if ( pArray )
+ {
+ SbxDataType eSbxElementType = unoToSbxType( aValue.getValueTypeClass() );
+ SbxVariableRef xVar = new SbxVariable( eSbxElementType );
+ unoToSbxValue( (SbxVariable*)xVar, aValue );
+
+ sal_Int32* pIndices = indices.getArray();
+ pArray->Put32( (SbxVariable*)xVar, pIndices );
+
+ }
+ }
+}
+
+void unoToSbxValue( SbxVariable* pVar, const Any& aValue )
+{
+ Type aType = aValue.getValueType();
+ TypeClass eTypeClass = aType.getTypeClass();
+ switch( eTypeClass )
+ {
+ case TypeClass_TYPE:
+ {
+ // Map Type to IdlClass
+ Type aType_;
+ aValue >>= aType_;
+ Reference<XIdlClass> xClass = TypeToIdlClass( aType_ );
+ Any aClassAny;
+ aClassAny <<= xClass;
+
+ // SbUnoObject instanzieren
+ String aName;
+ SbUnoObject* pSbUnoObject = new SbUnoObject( aName, aClassAny );
+ SbxObjectRef xWrapper = (SbxObject*)pSbUnoObject;
+
+ // #51475 Wenn das Objekt ungueltig ist null liefern
+ if( pSbUnoObject->getUnoAny().getValueType().getTypeClass() == TypeClass_VOID )
+ {
+ pVar->PutObject( NULL );
+ }
+ else
+ {
+ pVar->PutObject( xWrapper );
+ }
+ }
+ break;
+ // Interfaces und Structs muessen in ein SbUnoObject gewrappt werden
+ case TypeClass_INTERFACE:
+ case TypeClass_STRUCT:
+ case TypeClass_EXCEPTION:
+ {
+ if( eTypeClass == TypeClass_STRUCT )
+ {
+ ArrayWrapper aWrap;
+ if ( (aValue >>= aWrap) )
+ {
+ SbxDimArray* pArray = NULL;
+ Sequence< sal_Int32 > indices;
+ Sequence< sal_Int32 > sizes;
+ sal_Int32 dimension = 0;
+ implSequenceToMultiDimArray( pArray, indices, sizes, aWrap.Array, dimension, aWrap.IsZeroIndex );
+ if ( pArray )
+ {
+ SbxDimArrayRef xArray = pArray;
+ USHORT nFlags = pVar->GetFlags();
+ pVar->ResetFlag( SBX_FIXED );
+ pVar->PutObject( (SbxDimArray*)xArray );
+ pVar->SetFlags( nFlags );
+ }
+ else
+ pVar->PutEmpty();
+ break;
+ }
+ }
+ // SbUnoObject instanzieren
+ String aName;
+ SbUnoObject* pSbUnoObject = new SbUnoObject( aName, aValue );
+ SbxObjectRef xWrapper = (SbxObject*)pSbUnoObject;
+
+ // #51475 Wenn das Objekt ungueltig ist null liefern
+ if( pSbUnoObject->getUnoAny().getValueType().getTypeClass() == TypeClass_VOID )
+ {
+ pVar->PutObject( NULL );
+ }
+ else
+ {
+ pVar->PutObject( xWrapper );
+ }
+ }
+ break;
+
+ /* folgende Typen lassen wir erstmal weg
+ case TypeClass_SERVICE: break;
+ case TypeClass_CLASS: break;
+ case TypeClass_TYPEDEF: break;
+ case TypeClass_UNION: break;
+ case TypeClass_ENUM: break;
+ case TypeClass_ARRAY: break;
+ */
+
+ case TypeClass_ENUM:
+ {
+ sal_Int32 nEnum = 0;
+ enum2int( nEnum, aValue );
+ pVar->PutLong( nEnum );
+ }
+ break;
+
+ case TypeClass_SEQUENCE:
+ {
+ Reference< XIdlClass > xIdlTargetClass = TypeToIdlClass( aType );
+ Reference< XIdlArray > xIdlArray = xIdlTargetClass->getArray();
+ sal_Int32 i, nLen = xIdlArray->getLen( aValue );
+
+ typelib_TypeDescription * pTD = 0;
+ aType.getDescription( &pTD );
+ OSL_ASSERT( pTD && pTD->eTypeClass == typelib_TypeClass_SEQUENCE );
+ Type aElementType( ((typelib_IndirectTypeDescription *)pTD)->pType );
+ ::typelib_typedescription_release( pTD );
+
+ // In Basic Array anlegen
+ SbxDimArrayRef xArray;
+ SbxDataType eSbxElementType = unoToSbxType( aElementType.getTypeClass() );
+ xArray = new SbxDimArray( eSbxElementType );
+ if( nLen > 0 )
+ {
+ xArray->unoAddDim32( 0, nLen - 1 );
+
+ // Elemente als Variablen eintragen
+ for( i = 0 ; i < nLen ; i++ )
+ {
+ // Elemente wandeln
+ Any aElementAny = xIdlArray->get( aValue, (UINT32)i );
+ SbxVariableRef xVar = new SbxVariable( eSbxElementType );
+ unoToSbxValue( (SbxVariable*)xVar, aElementAny );
+
+ // Ins Array braten
+ xArray->Put32( (SbxVariable*)xVar, &i );
+ }
+ }
+ else
+ {
+ xArray->unoAddDim( 0, -1 );
+ }
+
+ // Array zurueckliefern
+ USHORT nFlags = pVar->GetFlags();
+ pVar->ResetFlag( SBX_FIXED );
+ pVar->PutObject( (SbxDimArray*)xArray );
+ pVar->SetFlags( nFlags );
+
+ // #54548, Die Parameter duerfen hier nicht weggehauen werden
+ //pVar->SetParameters( NULL );
+ }
+ break;
+
+ /*
+ case TypeClass_VOID: break;
+ case TypeClass_UNKNOWN: break;
+
+ case TypeClass_ANY:
+ {
+ // Any rausholen und konvertieren
+ //Any* pAny = (Any*)aValue.get();
+ //if( pAny )
+ //unoToSbxValue( pVar, *pAny );
+ }
+ break;
+ */
+
+ case TypeClass_BOOLEAN: pVar->PutBool( *(sal_Bool*)aValue.getValue() ); break;
+ case TypeClass_CHAR:
+ {
+ pVar->PutChar( *(sal_Unicode*)aValue.getValue() );
+ break;
+ }
+ case TypeClass_STRING: { OUString val; aValue >>= val; pVar->PutString( String( val ) ); } break;
+ case TypeClass_FLOAT: { float val = 0; aValue >>= val; pVar->PutSingle( val ); } break;
+ case TypeClass_DOUBLE: { double val = 0; aValue >>= val; pVar->PutDouble( val ); } break;
+ //case TypeClass_OCTET: break;
+ case TypeClass_BYTE: { sal_Int8 val = 0; aValue >>= val; pVar->PutInteger( val ); } break;
+ //case TypeClass_INT: break;
+ case TypeClass_SHORT: { sal_Int16 val = 0; aValue >>= val; pVar->PutInteger( val ); } break;
+ case TypeClass_LONG: { sal_Int32 val = 0; aValue >>= val; pVar->PutLong( val ); } break;
+ case TypeClass_HYPER: { sal_Int64 val = 0; aValue >>= val; pVar->PutInt64( val ); } break;
+ //case TypeClass_UNSIGNED_OCTET:break;
+ case TypeClass_UNSIGNED_SHORT: { sal_uInt16 val = 0; aValue >>= val; pVar->PutUShort( val ); } break;
+ case TypeClass_UNSIGNED_LONG: { sal_uInt32 val = 0; aValue >>= val; pVar->PutULong( val ); } break;
+ case TypeClass_UNSIGNED_HYPER: { sal_uInt64 val = 0; aValue >>= val; pVar->PutUInt64( val ); } break;
+ //case TypeClass_UNSIGNED_INT: break;
+ //case TypeClass_UNSIGNED_BYTE: break;
+ default: pVar->PutEmpty(); break;
+ }
+}
+
+// Reflection fuer Sbx-Typen liefern
+Type getUnoTypeForSbxBaseType( SbxDataType eType )
+{
+ Type aRetType = getCppuVoidType();
+ switch( eType )
+ {
+ //case SbxEMPTY: eRet = TypeClass_VOID; break;
+ case SbxNULL: aRetType = ::getCppuType( (const Reference< XInterface > *)0 ); break;
+ case SbxINTEGER: aRetType = ::getCppuType( (sal_Int16*)0 ); break;
+ case SbxLONG: aRetType = ::getCppuType( (sal_Int32*)0 ); break;
+ case SbxSINGLE: aRetType = ::getCppuType( (float*)0 ); break;
+ case SbxDOUBLE: aRetType = ::getCppuType( (double*)0 ); break;
+ case SbxCURRENCY: aRetType = ::getCppuType( (oleautomation::Currency*)0 ); break;
+ case SbxDECIMAL: aRetType = ::getCppuType( (oleautomation::Decimal*)0 ); break;
+ case SbxDATE: {
+/*?*/ // SbiInstance* pInst = pINST;
+/*?*/ // if( pInst && pInst->IsCompatibility() )
+/*?*/ // aRetType = ::getCppuType( (double*)0 );
+/*?*/ // else
+ aRetType = ::getCppuType( (oleautomation::Date*)0 );
+ }
+ break;
+ // case SbxDATE: aRetType = ::getCppuType( (double*)0 ); break;
+ case SbxSTRING: aRetType = ::getCppuType( (OUString*)0 ); break;
+ //case SbxOBJECT: break;
+ //case SbxERROR: break;
+ case SbxBOOL: aRetType = ::getCppuType( (sal_Bool*)0 ); break;
+ case SbxVARIANT: aRetType = ::getCppuType( (Any*)0 ); break;
+ //case SbxDATAOBJECT: break;
+ case SbxCHAR: aRetType = ::getCppuType( (sal_Unicode*)0 ); break;
+ case SbxBYTE: aRetType = ::getCppuType( (sal_Int16*)0 ); break;
+ case SbxUSHORT: aRetType = ::getCppuType( (sal_uInt16*)0 ); break;
+ case SbxULONG: aRetType = ::getCppuType( (sal_uInt32*)0 ); break;
+ //case SbxLONG64: break;
+ //case SbxULONG64: break;
+ // Maschinenabhaengige zur Sicherheit auf Hyper abbilden
+ case SbxINT: aRetType = ::getCppuType( (sal_Int32*)0 ); break;
+ case SbxUINT: aRetType = ::getCppuType( (sal_uInt32*)0 ); break;
+ //case SbxVOID: break;
+ //case SbxHRESULT: break;
+ //case SbxPOINTER: break;
+ //case SbxDIMARRAY: break;
+ //case SbxCARRAY: break;
+ //case SbxUSERDEF: break;
+ //case SbxLPSTR: break;
+ //case SbxLPWSTR: break;
+ //case SbxCoreSTRING: break;
+ default: break;
+ }
+ return aRetType;
+}
+
+// Konvertierung von Sbx nach Uno ohne bekannte Zielklasse fuer TypeClass_ANY
+Type getUnoTypeForSbxValue( SbxValue* pVal )
+{
+ Type aRetType = getCppuVoidType();
+ if( !pVal )
+ return aRetType;
+
+ // SbxType nach Uno wandeln
+ SbxDataType eBaseType = pVal->SbxValue::GetType();
+ if( eBaseType == SbxOBJECT )
+ {
+ SbxBaseRef xObj = (SbxBase*)pVal->GetObject();
+ if( !xObj )
+ {
+ // #109936 No error any more
+ // StarBASIC::Error( SbERR_INVALID_OBJECT );
+ aRetType = getCppuType( static_cast<Reference<XInterface> *>(0) );
+ return aRetType;
+ }
+
+ if( xObj->ISA(SbxDimArray) )
+ {
+ SbxBase* pObj = (SbxBase*)xObj;
+ SbxDimArray* pArray = (SbxDimArray*)pObj;
+
+ short nDims = pArray->GetDims();
+ Type aElementType = getUnoTypeForSbxBaseType( (SbxDataType)(pArray->GetType() & 0xfff) );
+ TypeClass eElementTypeClass = aElementType.getTypeClass();
+
+ // Normal case: One dimensional array
+ sal_Int32 nLower, nUpper;
+ if( nDims == 1 && pArray->GetDim32( 1, nLower, nUpper ) )
+ {
+ if( eElementTypeClass == TypeClass_VOID || eElementTypeClass == TypeClass_ANY )
+ {
+ // Wenn alle Elemente des Arrays vom gleichen Typ sind, wird
+ // der genommen, sonst wird das ganze als Any-Sequence betrachtet
+ sal_Bool bNeedsInit = sal_True;
+
+ INT32 nSize = nUpper - nLower + 1;
+ INT32 nIdx = nLower;
+ for( INT32 i = 0 ; i < nSize ; i++,nIdx++ )
+ {
+ SbxVariableRef xVar = pArray->Get32( &nIdx );
+ Type aType = getUnoTypeForSbxValue( (SbxVariable*)xVar );
+ if( bNeedsInit )
+ {
+ if( aType.getTypeClass() == TypeClass_VOID )
+ {
+ // #88522
+ // if only first element is void: different types -> []any
+ // if all elements are void: []void is not allowed -> []any
+ aElementType = getCppuType( (Any*)0 );
+ break;
+ }
+ aElementType = aType;
+ bNeedsInit = sal_False;
+ }
+ else if( aElementType != aType )
+ {
+ // Verschiedene Typen -> AnySequence
+ aElementType = getCppuType( (Any*)0 );
+ break;
+ }
+ }
+ }
+
+ OUString aSeqTypeName( aSeqLevelStr );
+ aSeqTypeName += aElementType.getTypeName();
+ aRetType = Type( TypeClass_SEQUENCE, aSeqTypeName );
+ }
+ // #i33795 Map also multi dimensional arrays to corresponding sequences
+ else if( nDims > 1 )
+ {
+ if( eElementTypeClass == TypeClass_VOID || eElementTypeClass == TypeClass_ANY )
+ {
+ // For this check the array's dim structure does not matter
+ UINT32 nFlatArraySize = pArray->Count32();
+
+ sal_Bool bNeedsInit = sal_True;
+ for( UINT32 i = 0 ; i < nFlatArraySize ; i++ )
+ {
+ SbxVariableRef xVar = pArray->SbxArray::Get32( i );
+ Type aType = getUnoTypeForSbxValue( (SbxVariable*)xVar );
+ if( bNeedsInit )
+ {
+ if( aType.getTypeClass() == TypeClass_VOID )
+ {
+ // if only first element is void: different types -> []any
+ // if all elements are void: []void is not allowed -> []any
+ aElementType = getCppuType( (Any*)0 );
+ break;
+ }
+ aElementType = aType;
+ bNeedsInit = sal_False;
+ }
+ else if( aElementType != aType )
+ {
+ // Verschiedene Typen -> AnySequence
+ aElementType = getCppuType( (Any*)0 );
+ break;
+ }
+ }
+ }
+
+ OUString aSeqTypeName;
+ for( short iDim = 0 ; iDim < nDims ; iDim++ )
+ aSeqTypeName += aSeqLevelStr;
+ aSeqTypeName += aElementType.getTypeName();
+ aRetType = Type( TypeClass_SEQUENCE, aSeqTypeName );
+ }
+ }
+ // Kein Array, sondern...
+ else if( xObj->ISA(SbUnoObject) )
+ {
+ aRetType = ((SbUnoObject*)(SbxBase*)xObj)->getUnoAny().getValueType();
+ }
+ // SbUnoAnyObject?
+ else if( xObj->ISA(SbUnoAnyObject) )
+ {
+ aRetType = ((SbUnoAnyObject*)(SbxBase*)xObj)->getValue().getValueType();
+ }
+ // Sonst ist es ein Nicht-Uno-Basic-Objekt -> default==void liefern
+ }
+ // Kein Objekt, Basistyp konvertieren
+ else
+ {
+ aRetType = getUnoTypeForSbxBaseType( eBaseType );
+ }
+ return aRetType;
+}
+
+// Deklaration Konvertierung von Sbx nach Uno mit bekannter Zielklasse
+Any sbxToUnoValue( SbxVariable* pVar, const Type& rType, Property* pUnoProperty = NULL );
+
+// Konvertierung von Sbx nach Uno ohne bekannte Zielklasse fuer TypeClass_ANY
+Any sbxToUnoValueImpl( SbxVariable* pVar, bool bBlockConversionToSmallestType = false )
+{
+ SbxDataType eBaseType = pVar->SbxValue::GetType();
+ if( eBaseType == SbxOBJECT )
+ {
+ SbxBaseRef xObj = (SbxBase*)pVar->GetObject();
+ if( xObj.Is() && xObj->ISA(SbUnoAnyObject) )
+ return ((SbUnoAnyObject*)(SbxBase*)xObj)->getValue();
+ }
+
+ Type aType = getUnoTypeForSbxValue( pVar );
+ TypeClass eType = aType.getTypeClass();
+
+ if( !bBlockConversionToSmallestType )
+ {
+ // #79615 Choose "smallest" represention for int values
+ // because up cast is allowed, downcast not
+ switch( eType )
+ {
+ case TypeClass_FLOAT:
+ case TypeClass_DOUBLE:
+ {
+ double d = pVar->GetDouble();
+ if( d == floor( d ) )
+ {
+ if( d >= -128 && d <= 127 )
+ aType = ::getCppuType( (sal_Int8*)0 );
+ else if( d >= SbxMININT && d <= SbxMAXINT )
+ aType = ::getCppuType( (sal_Int16*)0 );
+ else if( d >= -SbxMAXLNG && d <= SbxMAXLNG )
+ aType = ::getCppuType( (sal_Int32*)0 );
+ }
+ break;
+ }
+ case TypeClass_SHORT:
+ {
+ sal_Int16 n = pVar->GetInteger();
+ if( n >= -128 && n <= 127 )
+ aType = ::getCppuType( (sal_Int8*)0 );
+ break;
+ }
+ case TypeClass_LONG:
+ {
+ sal_Int32 n = pVar->GetLong();
+ if( n >= -128 && n <= 127 )
+ aType = ::getCppuType( (sal_Int8*)0 );
+ else if( n >= SbxMININT && n <= SbxMAXINT )
+ aType = ::getCppuType( (sal_Int16*)0 );
+ break;
+ }
+ case TypeClass_UNSIGNED_SHORT:
+ {
+ sal_uInt16 n = pVar->GetUShort();
+ if( n <= 255 )
+ aType = ::getCppuType( (sal_uInt8*)0 );
+ break;
+ }
+ case TypeClass_UNSIGNED_LONG:
+ {
+ sal_uInt32 n = pVar->GetLong();
+ if( n <= 255 )
+ aType = ::getCppuType( (sal_uInt8*)0 );
+ else if( n <= SbxMAXUINT )
+ aType = ::getCppuType( (sal_uInt16*)0 );
+ break;
+ }
+ default: break;
+ }
+ }
+
+ return sbxToUnoValue( pVar, aType );
+}
+
+
+
+// Helper function for StepREDIMP
+static Any implRekMultiDimArrayToSequence( SbxDimArray* pArray,
+ const Type& aElemType, short nMaxDimIndex, short nActualDim,
+ sal_Int32* pActualIndices, sal_Int32* pLowerBounds, sal_Int32* pUpperBounds )
+{
+ sal_Int32 nSeqLevel = nMaxDimIndex - nActualDim + 1;
+ OUString aSeqTypeName;
+ sal_Int32 i;
+ for( i = 0 ; i < nSeqLevel ; i++ )
+ aSeqTypeName += aSeqLevelStr;
+
+ aSeqTypeName += aElemType.getTypeName();
+ Type aSeqType( TypeClass_SEQUENCE, aSeqTypeName );
+
+ // Create Sequence instance
+ Any aRetVal;
+ Reference< XIdlClass > xIdlTargetClass = TypeToIdlClass( aSeqType );
+ xIdlTargetClass->createObject( aRetVal );
+
+ // Alloc sequence according to array bounds
+ sal_Int32 nUpper = pUpperBounds[nActualDim];
+ sal_Int32 nLower = pLowerBounds[nActualDim];
+ sal_Int32 nSeqSize = nUpper - nLower + 1;
+ Reference< XIdlArray > xArray = xIdlTargetClass->getArray();
+ xArray->realloc( aRetVal, nSeqSize );
+
+ sal_Int32& ri = pActualIndices[nActualDim];
+
+ for( ri = nLower,i = 0 ; ri <= nUpper ; ri++,i++ )
+ {
+ Any aElementVal;
+
+ if( nActualDim < nMaxDimIndex )
+ {
+ aElementVal = implRekMultiDimArrayToSequence( pArray, aElemType,
+ nMaxDimIndex, nActualDim + 1, pActualIndices, pLowerBounds, pUpperBounds );
+ }
+ else
+ {
+ SbxVariable* pSource = pArray->Get32( pActualIndices );
+ aElementVal = sbxToUnoValue( pSource, aElemType );
+ }
+
+ try
+ {
+ // In die Sequence uebernehmen
+ xArray->set( aRetVal, i, aElementVal );
+ }
+ catch( IllegalArgumentException& e1 )
+ {
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION,
+ implGetExceptionMsg( e1, aIllegalArgumentExceptionName ) );
+ }
+ catch (IndexOutOfBoundsException&)
+ {
+ StarBASIC::Error( SbERR_OUT_OF_RANGE );
+ }
+ }
+ return aRetVal;
+}
+
+// Konvertierung von Sbx nach Uno mit bekannter Zielklasse
+Any sbxToUnoValue( SbxVariable* pVar, const Type& rType, Property* pUnoProperty )
+{
+ Any aRetVal;
+
+ // #94560 No conversion of empty/void for MAYBE_VOID properties
+ if( pUnoProperty && pUnoProperty->Attributes & PropertyAttribute::MAYBEVOID )
+ {
+ if( pVar->IsEmpty() )
+ return aRetVal;
+ }
+
+ SbxDataType eBaseType = pVar->SbxValue::GetType();
+ if( eBaseType == SbxOBJECT )
+ {
+ SbxBaseRef xObj = (SbxBase*)pVar->GetObject();
+ if( xObj.Is() && xObj->ISA(SbUnoAnyObject) )
+ {
+ return ((SbUnoAnyObject*)(SbxBase*)xObj)->getValue();
+ }
+ }
+
+ TypeClass eType = rType.getTypeClass();
+ switch( eType )
+ {
+ case TypeClass_INTERFACE:
+ case TypeClass_STRUCT:
+ case TypeClass_EXCEPTION:
+ {
+ Reference< XIdlClass > xIdlTargetClass = TypeToIdlClass( rType );
+
+ // Null-Referenz?
+ if( pVar->IsNull() && eType == TypeClass_INTERFACE )
+ {
+ Reference< XInterface > xRef;
+ OUString aClassName = xIdlTargetClass->getName();
+ Type aClassType( xIdlTargetClass->getTypeClass(), aClassName.getStr() );
+ aRetVal.setValue( &xRef, aClassType );
+ }
+ }
+ break;
+
+ /* folgende Typen lassen wir erstmal weg
+ case TypeClass_SERVICE: break;
+ case TypeClass_CLASS: break;
+ case TypeClass_TYPEDEF: break;
+ case TypeClass_UNION: break;
+ case TypeClass_ENUM: break;
+ case TypeClass_ARRAY: break;
+ */
+
+ // Array -> Sequence
+ case TypeClass_ENUM:
+ {
+ aRetVal = int2enum( pVar->GetLong(), rType );
+ }
+ break;
+
+ case TypeClass_SEQUENCE:
+ {
+ SbxBaseRef xObj = (SbxBase*)pVar->GetObject();
+ if( xObj && xObj->ISA(SbxDimArray) )
+ {
+ SbxBase* pObj = (SbxBase*)xObj;
+ SbxDimArray* pArray = (SbxDimArray*)pObj;
+
+ short nDims = pArray->GetDims();
+
+ // Normal case: One dimensional array
+ sal_Int32 nLower, nUpper;
+ if( nDims == 1 && pArray->GetDim32( 1, nLower, nUpper ) )
+ {
+ sal_Int32 nSeqSize = nUpper - nLower + 1;
+
+ // Instanz der geforderten Sequence erzeugen
+ Reference< XIdlClass > xIdlTargetClass = TypeToIdlClass( rType );
+ xIdlTargetClass->createObject( aRetVal );
+ Reference< XIdlArray > xArray = xIdlTargetClass->getArray();
+ xArray->realloc( aRetVal, nSeqSize );
+
+ // Element-Type
+ OUString aClassName = xIdlTargetClass->getName();
+ typelib_TypeDescription * pSeqTD = 0;
+ typelib_typedescription_getByName( &pSeqTD, aClassName.pData );
+ OSL_ASSERT( pSeqTD );
+ Type aElemType( ((typelib_IndirectTypeDescription *)pSeqTD)->pType );
+ // Reference< XIdlClass > xElementClass = TypeToIdlClass( aElemType );
+
+ // Alle Array-Member umwandeln und eintragen
+ sal_Int32 nIdx = nLower;
+ for( sal_Int32 i = 0 ; i < nSeqSize ; i++,nIdx++ )
+ {
+ SbxVariableRef xVar = pArray->Get32( &nIdx );
+
+ // Wert von Sbx nach Uno wandeln
+ Any aAnyValue = sbxToUnoValue( (SbxVariable*)xVar, aElemType );
+
+ try
+ {
+ // In die Sequence uebernehmen
+ xArray->set( aRetVal, i, aAnyValue );
+ }
+ catch( IllegalArgumentException& e1 )
+ {
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION,
+ implGetExceptionMsg( e1, aIllegalArgumentExceptionName ) );
+ }
+ catch (IndexOutOfBoundsException&)
+ {
+ StarBASIC::Error( SbERR_OUT_OF_RANGE );
+ }
+ }
+ }
+ // #i33795 Map also multi dimensional arrays to corresponding sequences
+ else if( nDims > 1 )
+ {
+ // Element-Type
+ typelib_TypeDescription * pSeqTD = 0;
+ Type aCurType( rType );
+ sal_Int32 nSeqLevel = 0;
+ Type aElemType;
+ do
+ {
+ OUString aTypeName = aCurType.getTypeName();
+ typelib_typedescription_getByName( &pSeqTD, aTypeName.pData );
+ OSL_ASSERT( pSeqTD );
+ if( pSeqTD->eTypeClass == typelib_TypeClass_SEQUENCE )
+ {
+ aCurType = Type( ((typelib_IndirectTypeDescription *)pSeqTD)->pType );
+ nSeqLevel++;
+ }
+ else
+ {
+ aElemType = aCurType;
+ break;
+ }
+ }
+ while( true );
+
+ if( nSeqLevel == nDims )
+ {
+ sal_Int32* pLowerBounds = new sal_Int32[nDims];
+ sal_Int32* pUpperBounds = new sal_Int32[nDims];
+ sal_Int32* pActualIndices = new sal_Int32[nDims];
+ for( short i = 1 ; i <= nDims ; i++ )
+ {
+ sal_Int32 lBound, uBound;
+ pArray->GetDim32( i, lBound, uBound );
+
+ short j = i - 1;
+ pActualIndices[j] = pLowerBounds[j] = lBound;
+ pUpperBounds[j] = uBound;
+ }
+
+ aRetVal = implRekMultiDimArrayToSequence( pArray, aElemType,
+ nDims - 1, 0, pActualIndices, pLowerBounds, pUpperBounds );
+
+ delete[] pUpperBounds;
+ delete[] pLowerBounds;
+ delete[] pActualIndices;
+ }
+ }
+ }
+ }
+ break;
+
+ /*
+ case TypeClass_VOID: break;
+ case TypeClass_UNKNOWN: break;
+ */
+
+ // Bei Any die Klassen-unabhaengige Konvertierungs-Routine nutzen
+ case TypeClass_ANY:
+ {
+ aRetVal = sbxToUnoValueImpl( pVar );
+ }
+ break;
+
+ case TypeClass_BOOLEAN:
+ {
+ sal_Bool b = pVar->GetBool();
+ aRetVal.setValue( &b, getBooleanCppuType() );
+ break;
+ }
+ case TypeClass_CHAR:
+ {
+ sal_Unicode c = pVar->GetChar();
+ aRetVal.setValue( &c , getCharCppuType() );
+ break;
+ }
+ case TypeClass_STRING: aRetVal <<= OUString( pVar->GetString() ); break;
+ case TypeClass_FLOAT: aRetVal <<= pVar->GetSingle(); break;
+ case TypeClass_DOUBLE: aRetVal <<= pVar->GetDouble(); break;
+ //case TypeClass_OCTET: break;
+
+ case TypeClass_BYTE:
+ {
+ sal_Int16 nVal = pVar->GetInteger();
+ sal_Bool bOverflow = sal_False;
+ if( nVal < -128 )
+ {
+ bOverflow = sal_True;
+ nVal = -128;
+ }
+ else if( nVal > 127 )
+ {
+ bOverflow = sal_True;
+ nVal = 127;
+ }
+ if( bOverflow )
+ StarBASIC::Error( ERRCODE_BASIC_MATH_OVERFLOW );
+
+ sal_Int8 nByteVal = (sal_Int8)nVal;
+ aRetVal <<= nByteVal;
+ break;
+ }
+ //case TypeClass_INT: break;
+ case TypeClass_SHORT: aRetVal <<= (sal_Int16)( pVar->GetInteger() ); break;
+ case TypeClass_LONG: aRetVal <<= (sal_Int32)( pVar->GetLong() ); break;
+ case TypeClass_HYPER: aRetVal <<= (sal_Int64)( pVar->GetInt64() ); break;
+ //case TypeClass_UNSIGNED_OCTET:break;
+ case TypeClass_UNSIGNED_SHORT: aRetVal <<= (sal_uInt16)( pVar->GetUShort() ); break;
+ case TypeClass_UNSIGNED_LONG: aRetVal <<= (sal_uInt32)( pVar->GetULong() ); break;
+ case TypeClass_UNSIGNED_HYPER: aRetVal <<= (sal_uInt64)( pVar->GetUInt64() ); break;
+ //case TypeClass_UNSIGNED_INT: break;
+ //case TypeClass_UNSIGNED_BYTE: break;
+ default: break;
+ }
+
+ return aRetVal;
+}
+
+// Dbg-Hilfsmethode zum Auslesen der in einem Object implementierten Interfaces
+String Impl_GetInterfaceInfo( const Reference< XInterface >& x, const Reference< XIdlClass >& xClass, USHORT nRekLevel )
+{
+ Type aIfaceType = ::getCppuType( (const Reference< XInterface > *)0 );
+ static Reference< XIdlClass > xIfaceClass = TypeToIdlClass( aIfaceType );
+
+ String aRetStr;
+ for( USHORT i = 0 ; i < nRekLevel ; i++ )
+ aRetStr.AppendAscii( " " );
+ aRetStr += String( xClass->getName() );
+ OUString aClassName = xClass->getName();
+ Type aClassType( xClass->getTypeClass(), aClassName.getStr() );
+
+ // Pruefen, ob das Interface wirklich unterstuetzt wird
+ if( !x->queryInterface( aClassType ).hasValue() )
+ {
+ aRetStr.AppendAscii( " (ERROR: Not really supported!)\n" );
+ }
+ // Gibt es Super-Interfaces
+ else
+ {
+ aRetStr.AppendAscii( "\n" );
+
+ // Super-Interfaces holen
+ Sequence< Reference< XIdlClass > > aSuperClassSeq = xClass->getSuperclasses();
+ const Reference< XIdlClass >* pClasses = aSuperClassSeq.getConstArray();
+ UINT32 nSuperIfaceCount = aSuperClassSeq.getLength();
+ for( UINT32 j = 0 ; j < nSuperIfaceCount ; j++ )
+ {
+ const Reference< XIdlClass >& rxIfaceClass = pClasses[j];
+ if( !rxIfaceClass->equals( xIfaceClass ) )
+ aRetStr += Impl_GetInterfaceInfo( x, rxIfaceClass, nRekLevel + 1 );
+ }
+ }
+ return aRetStr;
+}
+
+String getDbgObjectNameImpl( SbUnoObject* pUnoObj )
+{
+ String aName;
+ if( pUnoObj )
+ {
+ aName = pUnoObj->GetClassName();
+ if( !aName.Len() )
+ {
+ Any aToInspectObj = pUnoObj->getUnoAny();
+ TypeClass eType = aToInspectObj.getValueType().getTypeClass();
+ Reference< XInterface > xObj;
+ if( eType == TypeClass_INTERFACE )
+ xObj = *(Reference< XInterface >*)aToInspectObj.getValue();
+ if( xObj.is() )
+ {
+ Reference< XServiceInfo > xServiceInfo( xObj, UNO_QUERY );
+ if( xServiceInfo.is() )
+ aName = xServiceInfo->getImplementationName();
+ }
+ }
+ }
+ return aName;
+}
+
+String getDbgObjectName( SbUnoObject* pUnoObj )
+{
+ String aName = getDbgObjectNameImpl( pUnoObj );
+ if( !aName.Len() )
+ aName.AppendAscii( "Unknown" );
+
+ String aRet;
+ if( aName.Len() > 20 )
+ aRet.AppendAscii( "\n" );
+ aRet.AppendAscii( "\"" );
+ aRet += aName;
+ aRet.AppendAscii( "\":" );
+ return aRet;
+}
+
+// Dbg-Hilfsmethode zum Auslesen der in einem Object implementierten Interfaces
+String Impl_GetSupportedInterfaces( SbUnoObject* pUnoObj )
+{
+ Any aToInspectObj = pUnoObj->getUnoAny();
+
+ // #54898: Nur TypeClass Interface zulasssen
+ TypeClass eType = aToInspectObj.getValueType().getTypeClass();
+ String aRet;
+ if( eType != TypeClass_INTERFACE )
+ {
+ aRet += ID_DBG_SUPPORTEDINTERFACES;
+ aRet.AppendAscii( " not available.\n(TypeClass is not TypeClass_INTERFACE)\n" );
+ }
+ else
+ {
+ // Interface aus dem Any besorgen
+ const Reference< XInterface > x = *(Reference< XInterface >*)aToInspectObj.getValue();
+
+ // XIdlClassProvider-Interface ansprechen
+ Reference< XIdlClassProvider > xClassProvider( x, UNO_QUERY );
+ Reference< XTypeProvider > xTypeProvider( x, UNO_QUERY );
+
+ aRet.AssignAscii( "Supported interfaces by object " );
+ String aObjName = getDbgObjectName( pUnoObj );
+ aRet += aObjName;
+ aRet.AppendAscii( "\n" );
+ if( xTypeProvider.is() )
+ {
+ // Interfaces der Implementation holen
+ Sequence< Type > aTypeSeq = xTypeProvider->getTypes();
+ const Type* pTypeArray = aTypeSeq.getConstArray();
+ UINT32 nIfaceCount = aTypeSeq.getLength();
+ for( UINT32 j = 0 ; j < nIfaceCount ; j++ )
+ {
+ const Type& rType = pTypeArray[j];
+
+ Reference<XIdlClass> xClass = TypeToIdlClass( rType );
+ if( xClass.is() )
+ {
+ aRet += Impl_GetInterfaceInfo( x, xClass, 1 );
+ }
+ else
+ {
+ typelib_TypeDescription * pTD = 0;
+ rType.getDescription( &pTD );
+ String TypeName( OUString( pTD->pTypeName ) );
+
+ aRet.AppendAscii( "*** ERROR: No IdlClass for type \"" );
+ aRet += TypeName;
+ aRet.AppendAscii( "\"\n*** Please check type library\n" );
+ }
+ }
+ }
+ else if( xClassProvider.is() )
+ {
+
+ DBG_ERROR( "XClassProvider not supported in UNO3" );
+ }
+ }
+ return aRet;
+}
+
+
+
+// Dbg-Hilfsmethode SbxDataType -> String
+String Dbg_SbxDataType2String( SbxDataType eType )
+{
+ String aRet( RTL_CONSTASCII_USTRINGPARAM("Unknown Sbx-Type!") );
+ switch( +eType )
+ {
+ case SbxEMPTY: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxEMPTY") ); break;
+ case SbxNULL: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxNULL") ); break;
+ case SbxINTEGER: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxINTEGER") ); break;
+ case SbxLONG: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxLONG") ); break;
+ case SbxSINGLE: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxSINGLE") ); break;
+ case SbxDOUBLE: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxDOUBLE") ); break;
+ case SbxCURRENCY: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxCURRENCY") ); break;
+ case SbxDECIMAL: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxDECIMAL") ); break;
+ case SbxDATE: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxDATE") ); break;
+ case SbxSTRING: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxSTRING") ); break;
+ case SbxOBJECT: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxOBJECT") ); break;
+ case SbxERROR: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxERROR") ); break;
+ case SbxBOOL: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxBOOL") ); break;
+ case SbxVARIANT: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxVARIANT") ); break;
+ case SbxDATAOBJECT: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxDATAOBJECT") ); break;
+ case SbxCHAR: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxCHAR") ); break;
+ case SbxBYTE: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxBYTE") ); break;
+ case SbxUSHORT: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxUSHORT") ); break;
+ case SbxULONG: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxULONG") ); break;
+ case SbxLONG64: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxLONG64") ); break;
+ case SbxULONG64: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxULONG64") ); break;
+ case SbxSALINT64: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxINT64") ); break;
+ case SbxSALUINT64: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxUINT64") ); break;
+ case SbxINT: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxINT") ); break;
+ case SbxUINT: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxUINT") ); break;
+ case SbxVOID: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxVOID") ); break;
+ case SbxHRESULT: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxHRESULT") ); break;
+ case SbxPOINTER: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxPOINTER") ); break;
+ case SbxDIMARRAY: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxDIMARRAY") ); break;
+ case SbxCARRAY: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxCARRAY") ); break;
+ case SbxUSERDEF: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxUSERDEF") ); break;
+ case SbxLPSTR: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxLPSTR") ); break;
+ case SbxLPWSTR: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxLPWSTR") ); break;
+ case SbxCoreSTRING: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxCoreSTRING" ) ); break;
+ case SbxOBJECT | SbxARRAY: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxARRAY") ); break;
+ default: break;
+ }
+ return aRet;
+}
+
+// Dbg-Hilfsmethode zum Anzeigen der Properties eines SbUnoObjects
+String Impl_DumpProperties( SbUnoObject* pUnoObj )
+{
+ String aRet( RTL_CONSTASCII_USTRINGPARAM("Properties of object ") );
+ String aObjName = getDbgObjectName( pUnoObj );
+ aRet += aObjName;
+
+ // Uno-Infos auswerten, um Arrays zu erkennen
+ Reference< XIntrospectionAccess > xAccess = pUnoObj->getIntrospectionAccess();
+ if( !xAccess.is() )
+ {
+ Reference< XInvocation > xInvok = pUnoObj->getInvocation();
+ if( xInvok.is() )
+ xAccess = xInvok->getIntrospection();
+ }
+ if( !xAccess.is() )
+ {
+ aRet.AppendAscii( "\nUnknown, no introspection available\n" );
+ return aRet;
+ }
+
+ Sequence<Property> props = xAccess->getProperties( PropertyConcept::ALL - PropertyConcept::DANGEROUS );
+ UINT32 nUnoPropCount = props.getLength();
+ const Property* pUnoProps = props.getConstArray();
+
+ SbxArray* pProps = pUnoObj->GetProperties();
+ USHORT nPropCount = pProps->Count();
+ USHORT nPropsPerLine = 1 + nPropCount / 30;
+ for( USHORT i = 0; i < nPropCount; i++ )
+ {
+ SbxVariable* pVar = pProps->Get( i );
+ if( pVar )
+ {
+ String aPropStr;
+ if( (i % nPropsPerLine) == 0 )
+ aPropStr.AppendAscii( "\n" );
+
+ // Typ und Namen ausgeben
+ // Ist es in Uno eine Sequence?
+ SbxDataType eType = pVar->GetFullType();
+
+ BOOL bMaybeVoid = FALSE;
+ if( i < nUnoPropCount )
+ {
+ const Property& rProp = pUnoProps[ i ];
+
+ // #63133: Bei MAYBEVOID Typ aus Uno neu konvertieren,
+ // damit nicht immer nur SbxEMPTY ausgegben wird.
+ if( rProp.Attributes & PropertyAttribute::MAYBEVOID )
+ {
+ eType = unoToSbxType( rProp.Type.getTypeClass() );
+ bMaybeVoid = TRUE;
+ }
+ if( eType == SbxOBJECT )
+ {
+ Type aType = rProp.Type;
+ if( aType.getTypeClass() == TypeClass_SEQUENCE )
+ eType = (SbxDataType) ( SbxOBJECT | SbxARRAY );
+ }
+ }
+ aPropStr += Dbg_SbxDataType2String( eType );
+ if( bMaybeVoid )
+ aPropStr.AppendAscii( "/void" );
+ aPropStr.AppendAscii( " " );
+ aPropStr += pVar->GetName();
+
+ if( i == nPropCount - 1 )
+ aPropStr.AppendAscii( "\n" );
+ else
+ aPropStr.AppendAscii( "; " );
+
+ aRet += aPropStr;
+ }
+ }
+ return aRet;
+}
+
+// Dbg-Hilfsmethode zum Anzeigen der Methoden eines SbUnoObjects
+String Impl_DumpMethods( SbUnoObject* pUnoObj )
+{
+ String aRet( RTL_CONSTASCII_USTRINGPARAM("Methods of object ") );
+ String aObjName = getDbgObjectName( pUnoObj );
+ aRet += aObjName;
+
+ // XIntrospectionAccess, um die Typen der Parameter auch ausgeben zu koennen
+ Reference< XIntrospectionAccess > xAccess = pUnoObj->getIntrospectionAccess();
+ if( !xAccess.is() )
+ {
+ Reference< XInvocation > xInvok = pUnoObj->getInvocation();
+ if( xInvok.is() )
+ xAccess = xInvok->getIntrospection();
+ }
+ if( !xAccess.is() )
+ {
+ aRet.AppendAscii( "\nUnknown, no introspection available\n" );
+ return aRet;
+ }
+ Sequence< Reference< XIdlMethod > > methods = xAccess->getMethods
+ ( MethodConcept::ALL - MethodConcept::DANGEROUS );
+ const Reference< XIdlMethod >* pUnoMethods = methods.getConstArray();
+
+ SbxArray* pMethods = pUnoObj->GetMethods();
+ USHORT nMethodCount = pMethods->Count();
+ if( !nMethodCount )
+ {
+ aRet.AppendAscii( "\nNo methods found\n" );
+ return aRet;
+ }
+ USHORT nPropsPerLine = 1 + nMethodCount / 30;
+ for( USHORT i = 0; i < nMethodCount; i++ )
+ {
+ SbxVariable* pVar = pMethods->Get( i );
+ if( pVar )
+ {
+ String aPropStr;
+ if( (i % nPropsPerLine) == 0 )
+ aPropStr.AppendAscii( "\n" );
+
+ // Methode ansprechen
+ const Reference< XIdlMethod >& rxMethod = pUnoMethods[i];
+
+ // Ist es in Uno eine Sequence?
+ SbxDataType eType = pVar->GetFullType();
+ if( eType == SbxOBJECT )
+ {
+ Reference< XIdlClass > xClass = rxMethod->getReturnType();
+ if( xClass.is() && xClass->getTypeClass() == TypeClass_SEQUENCE )
+ eType = (SbxDataType) ( SbxOBJECT | SbxARRAY );
+ }
+ // Name und Typ ausgeben
+ aPropStr += Dbg_SbxDataType2String( eType );
+ aPropStr.AppendAscii( " " );
+ aPropStr += pVar->GetName();
+ aPropStr.AppendAscii( " ( " );
+
+ // get-Methode darf keinen Parameter haben
+ Sequence< Reference< XIdlClass > > aParamsSeq = rxMethod->getParameterTypes();
+ UINT32 nParamCount = aParamsSeq.getLength();
+ const Reference< XIdlClass >* pParams = aParamsSeq.getConstArray();
+
+ if( nParamCount > 0 )
+ {
+ for( USHORT j = 0; j < nParamCount; j++ )
+ {
+ String aTypeStr = Dbg_SbxDataType2String( unoToSbxType( pParams[ j ] ) );
+ aPropStr += aTypeStr;
+
+ if( j < nParamCount - 1 )
+ aPropStr.AppendAscii( ", " );
+ }
+ }
+ else
+ aPropStr.AppendAscii( "void" );
+
+ aPropStr.AppendAscii( " ) " );
+
+ if( i == nMethodCount - 1 )
+ aPropStr.AppendAscii( "\n" );
+ else
+ aPropStr.AppendAscii( "; " );
+
+ aRet += aPropStr;
+ }
+ }
+ return aRet;
+}
+
+TYPEINIT1(AutomationNamedArgsSbxArray,SbxArray)
+
+// Implementation SbUnoObject
+void SbUnoObject::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
+ const SfxHint& rHint, const TypeId& rHintType )
+{
+ if( bNeedIntrospection )
+ doIntrospection();
+
+ const SbxHint* pHint = PTR_CAST(SbxHint,&rHint);
+ if( pHint )
+ {
+ SbxVariable* pVar = pHint->GetVar();
+ SbxArray* pParams = pVar->GetParameters();
+ SbUnoProperty* pProp = PTR_CAST(SbUnoProperty,pVar);
+ SbUnoMethod* pMeth = PTR_CAST(SbUnoMethod,pVar);
+ if( pProp )
+ {
+ bool bInvocation = pProp->isInvocationBased();
+ if( pHint->GetId() == SBX_HINT_DATAWANTED )
+ {
+ // Test-Properties
+ INT32 nId = pProp->nId;
+ if( nId < 0 )
+ {
+ // Id == -1: Implementierte Interfaces gemaess ClassProvider anzeigen
+ if( nId == -1 ) // Property ID_DBG_SUPPORTEDINTERFACES"
+ {
+ String aRetStr = Impl_GetSupportedInterfaces( this );
+ pVar->PutString( aRetStr );
+ }
+ // Id == -2: Properties ausgeben
+ else if( nId == -2 ) // Property ID_DBG_PROPERTIES
+ {
+ // Jetzt muessen alle Properties angelegt werden
+ implCreateAll();
+ String aRetStr = Impl_DumpProperties( this );
+ pVar->PutString( aRetStr );
+ }
+ // Id == -3: Methoden ausgeben
+ else if( nId == -3 ) // Property ID_DBG_METHODS
+ {
+ // Jetzt muessen alle Properties angelegt werden
+ implCreateAll();
+ String aRetStr = Impl_DumpMethods( this );
+ pVar->PutString( aRetStr );
+ }
+ return;
+ }
+
+ if( !bInvocation && mxUnoAccess.is() )
+ {
+ try
+ {
+ // Wert holen
+ Reference< XPropertySet > xPropSet( mxUnoAccess->queryAdapter( ::getCppuType( (const Reference< XPropertySet > *)0 ) ), UNO_QUERY );
+ Any aRetAny = xPropSet->getPropertyValue( pProp->GetName() );
+ // Die Nutzung von getPropertyValue (statt ueber den Index zu gehen) ist
+ // nicht optimal, aber die Umstellung auf XInvocation steht ja ohnehin an
+ // Ansonsten kann auch FastPropertySet genutzt werden
+
+ // Wert von Uno nach Sbx uebernehmen
+ unoToSbxValue( pVar, aRetAny );
+ }
+ catch( BasicErrorException& e0 )
+ {
+ implHandleBasicErrorException( e0 );
+ }
+ catch( WrappedTargetException& e1 )
+ {
+ implHandleWrappedTargetException( e1 );
+ }
+ catch( RuntimeException& e2 )
+ {
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION, implGetExceptionMsg( e2 ) );
+ }
+ catch( Exception& e3 )
+ {
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION, implGetExceptionMsg( e3 ) );
+ }
+ }
+ else if( bInvocation && mxInvocation.is() )
+ {
+ try
+ {
+ // Wert holen
+ Any aRetAny = mxInvocation->getValue( pProp->GetName() );
+
+ // Wert von Uno nach Sbx uebernehmen
+ unoToSbxValue( pVar, aRetAny );
+ }
+ catch( BasicErrorException& e0 )
+ {
+ implHandleBasicErrorException( e0 );
+ }
+ catch( WrappedTargetException& e1 )
+ {
+ implHandleWrappedTargetException( e1 );
+ }
+ catch( RuntimeException& e2 )
+ {
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION, implGetExceptionMsg( e2 ) );
+ }
+ catch( Exception& e3 )
+ {
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION, implGetExceptionMsg( e3 ) );
+ }
+ }
+ }
+ else if( pHint->GetId() == SBX_HINT_DATACHANGED )
+ {
+ if( !bInvocation && mxUnoAccess.is() )
+ {
+ if( pProp->aUnoProp.Attributes & PropertyAttribute::READONLY )
+ {
+ StarBASIC::Error( SbERR_PROP_READONLY );
+ return;
+ }
+
+ // Wert von Uno nach Sbx uebernehmen
+ Any aAnyValue = sbxToUnoValue( pVar, pProp->aUnoProp.Type, &pProp->aUnoProp );
+ try
+ {
+ // Wert setzen
+ Reference< XPropertySet > xPropSet( mxUnoAccess->queryAdapter( ::getCppuType( (const Reference< XPropertySet > *)0 ) ), UNO_QUERY );
+ xPropSet->setPropertyValue( pProp->GetName(), aAnyValue );
+ // Die Nutzung von getPropertyValue (statt ueber den Index zu gehen) ist
+ // nicht optimal, aber die Umstellung auf XInvocation steht ja ohnehin an
+ // Ansonsten kann auch FastPropertySet genutzt werden
+ }
+ catch( BasicErrorException& e0 )
+ {
+ implHandleBasicErrorException( e0 );
+ }
+ catch( WrappedTargetException& e1 )
+ {
+ implHandleWrappedTargetException( e1 );
+ }
+ catch( IllegalArgumentException& e2 )
+ {
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION,
+ implGetExceptionMsg( e2, aIllegalArgumentExceptionName ) );
+ }
+ catch( RuntimeException& e3 )
+ {
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION, implGetExceptionMsg( e3 ) );
+ }
+ catch( Exception& e4 )
+ {
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION, implGetExceptionMsg( e4 ) );
+ }
+ }
+ else if( bInvocation && mxInvocation.is() )
+ {
+ // Wert von Uno nach Sbx uebernehmen
+ Any aAnyValue = sbxToUnoValueImpl( pVar );
+ try
+ {
+ // Wert setzen
+ mxInvocation->setValue( pProp->GetName(), aAnyValue );
+ }
+ catch( BasicErrorException& e0 )
+ {
+ implHandleBasicErrorException( e0 );
+ }
+ catch( WrappedTargetException& e1 )
+ {
+ implHandleWrappedTargetException( e1 );
+ }
+ catch( RuntimeException& e2 )
+ {
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION, implGetExceptionMsg( e2 ) );
+ }
+ catch( Exception& e3 )
+ {
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION, implGetExceptionMsg( e3 ) );
+ }
+ }
+ }
+ }
+ else if( pMeth )
+ {
+ bool bInvocation = pMeth->isInvocationBased();
+ if( pHint->GetId() == SBX_HINT_DATAWANTED )
+ {
+ // Anzahl Parameter -1 wegen Param0 == this
+ UINT32 nParamCount = pParams ? ((UINT32)pParams->Count() - 1) : 0;
+ Sequence<Any> args;
+ BOOL bOutParams = FALSE;
+ UINT32 i;
+
+ if( !bInvocation && mxUnoAccess.is() )
+ {
+ // Infos holen
+ const Sequence<ParamInfo>& rInfoSeq = pMeth->getParamInfos();
+ const ParamInfo* pParamInfos = rInfoSeq.getConstArray();
+ UINT32 nUnoParamCount = rInfoSeq.getLength();
+ UINT32 nAllocParamCount = nParamCount;
+
+ // Ueberschuessige Parameter ignorieren, Alternative: Error schmeissen
+ if( nParamCount > nUnoParamCount )
+ {
+ nParamCount = nUnoParamCount;
+ nAllocParamCount = nParamCount;
+ }
+ else if( nParamCount < nUnoParamCount )
+ {
+/*?*/ // SbiInstance* pInst = pINST;
+/*?*/ // if( pInst && pInst->IsCompatibility() )
+/*?*/ // {
+/*?*/ // // Check types
+/*?*/ // bool bError = false;
+/*?*/ // for( i = nParamCount ; i < nUnoParamCount ; i++ )
+/*?*/ // {
+/*?*/ // const ParamInfo& rInfo = pParamInfos[i];
+/*?*/ // const Reference< XIdlClass >& rxClass = rInfo.aType;
+/*?*/ // if( rxClass->getTypeClass() != TypeClass_ANY )
+/*?*/ // {
+/*?*/ // bError = true;
+/*?*/ // StarBASIC::Error( SbERR_NOT_OPTIONAL );
+/*?*/ // }
+/*?*/ // }
+/*?*/ // if( !bError )
+/*?*/ // nAllocParamCount = nUnoParamCount;
+/*?*/ // }
+ }
+
+ if( nAllocParamCount > 0 )
+ {
+ args.realloc( nAllocParamCount );
+ Any* pAnyArgs = args.getArray();
+ for( i = 0 ; i < nParamCount ; i++ )
+ {
+ const ParamInfo& rInfo = pParamInfos[i];
+ const Reference< XIdlClass >& rxClass = rInfo.aType;
+ //const XIdlClassRef& rxClass = pUnoParams[i];
+
+ com::sun::star::uno::Type aType( rxClass->getTypeClass(), rxClass->getName() );
+
+ // ACHTUNG: Bei den Sbx-Parametern den Offset nicht vergessen!
+ pAnyArgs[i] = sbxToUnoValue( pParams->Get( (USHORT)(i+1) ), aType );
+
+ // Wenn es nicht schon feststeht pruefen, ob Out-Parameter vorliegen
+ if( !bOutParams )
+ {
+ ParamMode aParamMode = rInfo.aMode;
+ if( aParamMode != ParamMode_IN )
+ bOutParams = TRUE;
+ }
+ }
+ }
+ }
+ else if( bInvocation && pParams && mxInvocation.is() )
+ {
+ bool bOLEAutomation = true;
+ // TODO: bOLEAutomation = xOLEAutomation.is()
+
+ AutomationNamedArgsSbxArray* pArgNamesArray = NULL;
+ if( bOLEAutomation )
+ pArgNamesArray = PTR_CAST(AutomationNamedArgsSbxArray,pParams);
+
+ args.realloc( nParamCount );
+ Any* pAnyArgs = args.getArray();
+ bool bBlockConversionToSmallestType( false );
+/*?*/ // bool bBlockConversionToSmallestType = pINST->IsCompatibility();
+ if( pArgNamesArray )
+ {
+ Sequence< OUString >& rNameSeq = pArgNamesArray->getNames();
+ OUString* pNames = rNameSeq.getArray();
+
+ Any aValAny;
+ for( i = 0 ; i < nParamCount ; i++ )
+ {
+ USHORT iSbx = (USHORT)(i+1);
+
+ // ACHTUNG: Bei den Sbx-Parametern den Offset nicht vergessen!
+ aValAny = sbxToUnoValueImpl( pParams->Get( iSbx ),
+ bBlockConversionToSmallestType );
+
+ OUString aParamName = pNames[iSbx];
+ if( aParamName.getLength() )
+ {
+ oleautomation::NamedArgument aNamedArgument;
+ aNamedArgument.Name = aParamName;
+ aNamedArgument.Value = aValAny;
+ pAnyArgs[i] <<= aNamedArgument;
+ }
+ else
+ {
+ pAnyArgs[i] = aValAny;
+ }
+ }
+ }
+ else
+ {
+ for( i = 0 ; i < nParamCount ; i++ )
+ {
+ // ACHTUNG: Bei den Sbx-Parametern den Offset nicht vergessen!
+ pAnyArgs[i] = sbxToUnoValueImpl( pParams->Get( (USHORT)(i+1) ),
+ bBlockConversionToSmallestType );
+ }
+ }
+ }
+
+ // Methode callen
+ GetSbData()->bBlockCompilerError = TRUE; // #106433 Block compiler errors for API calls
+ try
+ {
+ if( !bInvocation && mxUnoAccess.is() )
+ {
+ Any aRetAny = pMeth->m_xUnoMethod->invoke( getUnoAny(), args );
+
+ // Wert von Uno nach Sbx uebernehmen
+ unoToSbxValue( pVar, aRetAny );
+
+ // Muessen wir Out-Parameter zurueckkopieren?
+ if( bOutParams )
+ {
+ const Any* pAnyArgs = args.getConstArray();
+
+ // Infos holen
+ const Sequence<ParamInfo>& rInfoSeq = pMeth->getParamInfos();
+ const ParamInfo* pParamInfos = rInfoSeq.getConstArray();
+
+ UINT32 j;
+ for( j = 0 ; j < nParamCount ; j++ )
+ {
+ const ParamInfo& rInfo = pParamInfos[j];
+ ParamMode aParamMode = rInfo.aMode;
+ if( aParamMode != ParamMode_IN )
+ unoToSbxValue( (SbxVariable*)pParams->Get( (USHORT)(j+1) ), pAnyArgs[ j ] );
+ }
+ }
+ }
+ else if( bInvocation && mxInvocation.is() )
+ {
+ Sequence< INT16 > OutParamIndex;
+ Sequence< Any > OutParam;
+ Any aRetAny = mxInvocation->invoke( pMeth->GetName(), args, OutParamIndex, OutParam );
+
+ // Wert von Uno nach Sbx uebernehmen
+ unoToSbxValue( pVar, aRetAny );
+
+ const INT16* pIndices = OutParamIndex.getConstArray();
+ UINT32 nLen = OutParamIndex.getLength();
+ if( nLen )
+ {
+ const Any* pNewValues = OutParam.getConstArray();
+ for( UINT32 j = 0 ; j < nLen ; j++ )
+ {
+ INT16 iTarget = pIndices[ j ];
+ if( iTarget >= (INT16)nParamCount )
+ break;
+ unoToSbxValue( (SbxVariable*)pParams->Get( (USHORT)(j+1) ), pNewValues[ j ] );
+ }
+ }
+ }
+
+ // #55460, Parameter hier weghauen, da das in unoToSbxValue()
+ // bei Arrays wegen #54548 nicht mehr gemacht wird
+ if( pParams )
+ pVar->SetParameters( NULL );
+ }
+ catch( BasicErrorException& e0 )
+ {
+ implHandleBasicErrorException( e0 );
+ }
+ catch( WrappedTargetException& e1 )
+ {
+ implHandleWrappedTargetException( e1 );
+ }
+ catch( RuntimeException& e2 )
+ {
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION, implGetExceptionMsg( e2 ) );
+ }
+ catch( IllegalArgumentException& e3)
+ {
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION,
+ implGetExceptionMsg( e3, aIllegalArgumentExceptionName ) );
+ }
+ catch( Exception& e4 )
+ {
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION, implGetExceptionMsg( e4 ) );
+ }
+ /*
+ catch( NullPointerException& e1 )
+ {
+ }
+ catch( InvocationTargetException& e2 )
+ {
+ }
+ */
+ GetSbData()->bBlockCompilerError = FALSE; // #106433 Unblock compiler errors
+ }
+ }
+ else
+ SbxObject::SFX_NOTIFY( rBC, rBCType, rHint, rHintType );
+ }
+}
+
+
+#ifdef INVOCATION_ONLY
+// Aus USR
+Reference< XInvocation > createDynamicInvocationFor( const Any& aAny );
+#endif
+
+SbUnoObject::SbUnoObject( const String& aName_, const Any& aUnoObj_ )
+ : SbxObject( aName_ )
+{
+ static Reference< XIntrospection > xIntrospection;
+
+ // Default-Properties von Sbx wieder rauspruegeln
+ Remove( XubString( RTL_CONSTASCII_USTRINGPARAM("Name") ), SbxCLASS_DONTCARE );
+ Remove( XubString( RTL_CONSTASCII_USTRINGPARAM("Parent") ), SbxCLASS_DONTCARE );
+
+ // Typ des Objekts pruefen
+ TypeClass eType = aUnoObj_.getValueType().getTypeClass();
+ Reference< XInterface > x;
+ if( eType == TypeClass_INTERFACE )
+ {
+ // Interface aus dem Any besorgen
+ x = *(Reference< XInterface >*)aUnoObj_.getValue();
+ if( !x.is() )
+ return;
+ }
+
+ Reference< XTypeProvider > xTypeProvider;
+#ifdef INVOCATION_ONLY
+ // Invocation besorgen
+ mxInvocation = createDynamicInvocationFor( aUnoObj_ );
+#else
+ // Hat das Object selbst eine Invocation?
+ mxInvocation = Reference< XInvocation >( x, UNO_QUERY );
+
+ xTypeProvider = Reference< XTypeProvider >( x, UNO_QUERY );
+#endif
+
+ if( mxInvocation.is() )
+ {
+ // #94670: This is WRONG because then the MaterialHolder doesn't refer
+ // to the object implementing XInvocation but to the object passed to
+ // the invocation service!!!
+ // mxMaterialHolder = Reference< XMaterialHolder >::query( mxInvocation );
+
+ // ExactName holen
+ mxExactNameInvocation = Reference< XExactName >::query( mxInvocation );
+
+ // Rest bezieht sich nur auf Introspection
+ if( !xTypeProvider.is() )
+ {
+ bNeedIntrospection = FALSE;
+ return;
+ }
+ }
+
+ // Introspection-Flag
+ bNeedIntrospection = TRUE;
+ maTmpUnoObj = aUnoObj_;
+
+
+ //*** Namen bestimmen ***
+ BOOL bFatalError = TRUE;
+
+ // Ist es ein Interface oder eine struct?
+ BOOL bSetClassName = FALSE;
+ String aClassName_;
+ if( eType == TypeClass_STRUCT || eType == TypeClass_EXCEPTION )
+ {
+ // Struct ist Ok
+ bFatalError = FALSE;
+
+ // #67173 Echten Klassen-Namen eintragen
+ if( aName_.Len() == 0 )
+ {
+ aClassName_ = String( aUnoObj_.getValueType().getTypeName() );
+ bSetClassName = TRUE;
+ }
+ }
+ else if( eType == TypeClass_INTERFACE )
+ {
+ // #70197 Interface geht immer durch Typ im Any
+ bFatalError = FALSE;
+
+ // Nach XIdlClassProvider-Interface fragen
+ Reference< XIdlClassProvider > xClassProvider( x, UNO_QUERY );
+ if( xClassProvider.is() )
+ {
+ // #67173 Echten Klassen-Namen eintragen
+ if( aName_.Len() == 0 )
+ {
+ Sequence< Reference< XIdlClass > > szClasses = xClassProvider->getIdlClasses();
+ UINT32 nLen = szClasses.getLength();
+ if( nLen )
+ {
+ const Reference< XIdlClass > xImplClass = szClasses.getConstArray()[ 0 ];
+ if( xImplClass.is() )
+ {
+ aClassName_ = String( xImplClass->getName() );
+ bSetClassName = TRUE;
+ }
+ }
+ }
+ }
+ }
+ if( bSetClassName )
+ SetClassName( aClassName_ );
+
+ // Weder Interface noch Struct -> FatalError
+ if( bFatalError )
+ {
+ StarBASIC::FatalError( ERRCODE_BASIC_EXCEPTION );
+ return;
+ }
+
+ // #67781 Introspection erst on demand durchfuehren
+}
+
+SbUnoObject::~SbUnoObject()
+{
+}
+
+
+// #76470 Introspection on Demand durchfuehren
+void SbUnoObject::doIntrospection( void )
+{
+ static Reference< XIntrospection > xIntrospection;
+
+ if( !bNeedIntrospection )
+ return;
+ bNeedIntrospection = FALSE;
+
+ if( !xIntrospection.is() )
+ {
+ // Introspection-Service holen
+ Reference< XMultiServiceFactory > xFactory( comphelper::getProcessServiceFactory() );
+ if ( xFactory.is() )
+ {
+ Reference< XInterface > xI = xFactory->createInstance( rtl::OUString::createFromAscii("com.sun.star.beans.Introspection") );
+ if (xI.is())
+ xIntrospection = Reference< XIntrospection >::query( xI );
+ //xI->queryInterface( ::getCppuType( (const Reference< XIntrospection > *)0 ), xIntrospection );
+ }
+ }
+ if( !xIntrospection.is() )
+ {
+ StarBASIC::FatalError( ERRCODE_BASIC_EXCEPTION );
+ return;
+ }
+
+ // Introspection durchfuehren
+ try
+ {
+ mxUnoAccess = xIntrospection->inspect( maTmpUnoObj );
+ }
+ catch( RuntimeException& e )
+ {
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION, implGetExceptionMsg( e ) );
+ }
+
+ if( !mxUnoAccess.is() )
+ {
+ // #51475 Ungueltiges Objekt kennzeichnen (kein mxMaterialHolder)
+ return;
+ }
+
+ // MaterialHolder vom Access holen
+ mxMaterialHolder = Reference< XMaterialHolder >::query( mxUnoAccess );
+
+ // ExactName vom Access holen
+ mxExactName = Reference< XExactName >::query( mxUnoAccess );
+}
+
+
+
+
+// #67781 Start einer Liste aller SbUnoMethod-Instanzen
+static SbUnoMethod* pFirst = NULL;
+
+SbUnoMethod::SbUnoMethod
+(
+ const String& aName_,
+ SbxDataType eSbxType,
+ Reference< XIdlMethod > xUnoMethod_,
+ bool bInvocation
+)
+ : SbxMethod( aName_, eSbxType )
+ , mbInvocation( bInvocation )
+{
+ m_xUnoMethod = xUnoMethod_;
+ pParamInfoSeq = NULL;
+
+ // #67781 Methode in Liste eintragen
+ pNext = pFirst;
+ pPrev = NULL;
+ pFirst = this;
+ if( pNext )
+ pNext->pPrev = this;
+}
+
+SbUnoMethod::~SbUnoMethod()
+{
+ delete pParamInfoSeq;
+
+ if( this == pFirst )
+ pFirst = pNext;
+ else if( pPrev )
+ pPrev->pNext = pNext;
+ if( pNext )
+ pNext->pPrev = pPrev;
+}
+
+SbxInfo* SbUnoMethod::GetInfo()
+{
+/*?*/ // if( !pInfo && m_xUnoMethod.is() )
+/*?*/ // {
+/*?*/ // SbiInstance* pInst = pINST;
+/*?*/ // if( pInst && pInst->IsCompatibility() )
+/*?*/ // {
+/*?*/ // pInfo = new SbxInfo();
+/*?*/ //
+/*?*/ // const Sequence<ParamInfo>& rInfoSeq = getParamInfos();
+/*?*/ // const ParamInfo* pParamInfos = rInfoSeq.getConstArray();
+/*?*/ // UINT32 nParamCount = rInfoSeq.getLength();
+/*?*/ //
+/*?*/ // for( UINT32 i = 0 ; i < nParamCount ; i++ )
+/*?*/ // {
+/*?*/ // const ParamInfo& rInfo = pParamInfos[i];
+/*?*/ // OUString aParamName = rInfo.aName;
+/*?*/ //
+/*?*/ // // const Reference< XIdlClass >& rxClass = rInfo.aType;
+/*?*/ // SbxDataType t = SbxVARIANT;
+/*?*/ // USHORT nFlags_ = SBX_READ;
+/*?*/ // pInfo->AddParam( aParamName, t, nFlags_ );
+/*?*/ // }
+/*?*/ // }
+/*?*/ // }
+ return pInfo;
+}
+
+const Sequence<ParamInfo>& SbUnoMethod::getParamInfos( void )
+{
+ if( !pParamInfoSeq && m_xUnoMethod.is() )
+ {
+ Sequence<ParamInfo> aTmp = m_xUnoMethod->getParameterInfos() ;
+ pParamInfoSeq = new Sequence<ParamInfo>( aTmp );
+ }
+ return *pParamInfoSeq;
+}
+
+SbUnoProperty::SbUnoProperty
+(
+ const String& aName_,
+ SbxDataType eSbxType,
+ const Property& aUnoProp_,
+ INT32 nId_,
+ bool bInvocation
+)
+ : SbxProperty( aName_, eSbxType )
+ , aUnoProp( aUnoProp_ )
+ , nId( nId_ )
+ , mbInvocation( bInvocation )
+{
+ // #54548, bei bedarf Dummy-Array einsetzen, damit SbiRuntime::CheckArray() geht
+ static SbxArrayRef xDummyArray = new SbxArray( SbxVARIANT );
+ if( eSbxType & SbxARRAY )
+ PutObject( xDummyArray );
+}
+
+SbUnoProperty::~SbUnoProperty()
+{}
+
+
+/*?*/ // // #72732 Spezielle SbxVariable, die beim put/get prueft,
+/*?*/ // // ob der Kontext fuer eine UnoClass sinnvoll ist. Sonst
+/*?*/ // // liegt eventuell ein Schreibfehler im Basic-Source vor.
+/*?*/ // BOOL UnoClassMemberVariable::Get( SbxValues& rRes ) const
+/*?*/ // {
+/*?*/ // // Zugriff auf den Member einer UnoClass mit Parametern ist unsinnig
+/*?*/ // if( GetParameters() )
+/*?*/ // {
+/*?*/ // if( mpRuntime )
+/*?*/ // mpRuntime->Error( SbERR_NO_METHOD );
+/*?*/ // }
+/*?*/ // return SbxVariable::Get( rRes );
+/*?*/ // }
+/*?*/ //
+/*?*/ // BOOL UnoClassMemberVariable::Put( const SbxValues& rRes )
+/*?*/ // {
+/*?*/ // if( bInternalUse )
+/*?*/ // {
+/*?*/ // return SbxVariable::Put( rRes );
+/*?*/ // }
+/*?*/ // // Schreibzugriff auf den Member einer UnoClass ist immer falsch
+/*?*/ // mpRuntime->Error( SbERR_NO_METHOD );
+/*?*/ // return FALSE;
+/*?*/ // }
+/*?*/ //
+/*?*/ // TYPEINIT1(UnoClassMemberVariable,SbxVariable)
+
+SbxVariable* SbUnoObject::Find( const XubString& rName, SbxClassType t )
+{
+ static Reference< XIdlMethod > xDummyMethod;
+ static Property aDummyProp;
+
+ SbxVariable* pRes = SbxObject::Find( rName, t );
+
+ if( bNeedIntrospection )
+ doIntrospection();
+
+ // Neu 4.3.1999: Properties on Demand anlegen, daher jetzt perIntrospectionAccess
+ // suchen, ob doch eine Property oder Methode des geforderten Namens existiert
+ if( !pRes )
+ {
+ OUString aUName( rName );
+ if( mxUnoAccess.is() )
+ {
+ if( mxExactName.is() )
+ {
+ OUString aUExactName = mxExactName->getExactName( aUName );
+ if( aUExactName.getLength() )
+ aUName = aUExactName;
+ }
+ if( mxUnoAccess->hasProperty( aUName, PropertyConcept::ALL - PropertyConcept::DANGEROUS ) )
+ {
+ const Property& rProp = mxUnoAccess->
+ getProperty( aUName, PropertyConcept::ALL - PropertyConcept::DANGEROUS );
+
+ // #58455 Wenn die Property void sein kann, muss als Typ Variant gesetzt werden
+ SbxDataType eSbxType;
+ if( rProp.Attributes & PropertyAttribute::MAYBEVOID )
+ eSbxType = SbxVARIANT;
+ else
+ eSbxType = unoToSbxType( rProp.Type.getTypeClass() );
+
+ // Property anlegen und reinbraten
+ SbxVariableRef xVarRef = new SbUnoProperty( rProp.Name, eSbxType, rProp, 0, false );
+ QuickInsert( (SbxVariable*)xVarRef );
+ pRes = xVarRef;
+ }
+ else if( mxUnoAccess->hasMethod( aUName,
+ MethodConcept::ALL - MethodConcept::DANGEROUS ) )
+ {
+ // Methode ansprechen
+ const Reference< XIdlMethod >& rxMethod = mxUnoAccess->
+ getMethod( aUName, MethodConcept::ALL - MethodConcept::DANGEROUS );
+
+ // SbUnoMethode anlegen und reinbraten
+ SbxVariableRef xMethRef = new SbUnoMethod( rxMethod->getName(),
+ unoToSbxType( rxMethod->getReturnType() ), rxMethod, false );
+ QuickInsert( (SbxVariable*)xMethRef );
+ pRes = xMethRef;
+ }
+
+ // Wenn immer noch nichts gefunden wurde, muss geprueft werden, ob NameAccess vorliegt
+ if( !pRes )
+ {
+ try
+ {
+ Reference< XNameAccess > xNameAccess( mxUnoAccess->queryAdapter( ::getCppuType( (const Reference< XPropertySet > *)0 ) ), UNO_QUERY );
+ OUString aUName2( rName );
+
+ if( xNameAccess.is() && xNameAccess->hasByName( aUName2 ) )
+ {
+ Any aAny = xNameAccess->getByName( aUName2 );
+
+ // ACHTUNG: Die hier erzeugte Variable darf wegen bei XNameAccess
+ // nicht als feste Property in das Object aufgenommen werden und
+ // wird daher nirgendwo gehalten.
+ // Wenn das Probleme gibt, muss das kuenstlich gemacht werden oder
+ // es muss eine Klasse SbUnoNameAccessProperty geschaffen werden,
+ // bei der die Existenz staendig neu ueberprueft und die ggf. weg-
+ // geworfen wird, wenn der Name nicht mehr gefunden wird.
+ pRes = new SbxVariable( SbxVARIANT );
+ unoToSbxValue( pRes, aAny );
+ }
+ }
+ catch( NoSuchElementException& e )
+ {
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION, implGetExceptionMsg( e ) );
+ }
+ catch( BasicErrorException& e0 )
+ {
+ // Anlegen, damit der Exception-Fehler nicht ueberschrieben wird
+ if( !pRes )
+ pRes = new SbxVariable( SbxVARIANT );
+
+ implHandleBasicErrorException( e0 );
+ }
+ catch( WrappedTargetException& e1 )
+ {
+ // Anlegen, damit der Exception-Fehler nicht ueberschrieben wird
+ if( !pRes )
+ pRes = new SbxVariable( SbxVARIANT );
+
+ implHandleWrappedTargetException( e1 );
+ }
+ catch( RuntimeException& e2 )
+ {
+ // Anlegen, damit der Exception-Fehler nicht ueberschrieben wird
+ if( !pRes )
+ pRes = new SbxVariable( SbxVARIANT );
+
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION, implGetExceptionMsg( e2 ) );
+ }
+ }
+ }
+ if( !pRes && mxInvocation.is() )
+ {
+ if( mxExactNameInvocation.is() )
+ {
+ OUString aUExactName = mxExactNameInvocation->getExactName( aUName );
+ if( aUExactName.getLength() )
+ aUName = aUExactName;
+ }
+
+ try
+ {
+ if( mxInvocation->hasProperty( aUName ) )
+ {
+ // Property anlegen und reinbraten
+ SbxVariableRef xVarRef = new SbUnoProperty( aUName, SbxVARIANT, aDummyProp, 0, true );
+ QuickInsert( (SbxVariable*)xVarRef );
+ pRes = xVarRef;
+ }
+ else if( mxInvocation->hasMethod( aUName ) )
+ {
+ // SbUnoMethode anlegen und reinbraten
+ SbxVariableRef xMethRef = new SbUnoMethod( aUName, SbxVARIANT, xDummyMethod, true );
+ QuickInsert( (SbxVariable*)xMethRef );
+ pRes = xMethRef;
+ }
+ }
+ catch( RuntimeException& e )
+ {
+ // Anlegen, damit der Exception-Fehler nicht ueberschrieben wird
+ if( !pRes )
+ pRes = new SbxVariable( SbxVARIANT );
+
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION, implGetExceptionMsg( e ) );
+ }
+ }
+ }
+
+ // Ganz am Schluss noch pruefen, ob die Dbg_-Properties gemeint sind
+
+ if( !pRes )
+ {
+ if( rName.EqualsIgnoreCaseAscii( ID_DBG_SUPPORTEDINTERFACES ) ||
+ rName.EqualsIgnoreCaseAscii( ID_DBG_PROPERTIES ) ||
+ rName.EqualsIgnoreCaseAscii( ID_DBG_METHODS ) )
+ {
+ // Anlegen
+ implCreateDbgProperties();
+
+ // Jetzt muessen sie regulaer gefunden werden
+ pRes = SbxObject::Find( rName, SbxCLASS_DONTCARE );
+ }
+ }
+ return pRes;
+}
+
+
+// Hilfs-Methode zum Anlegen der dbg_-Properties
+void SbUnoObject::implCreateDbgProperties( void )
+{
+ Property aProp;
+
+ // Id == -1: Implementierte Interfaces gemaess ClassProvider anzeigen
+ SbxVariableRef xVarRef = new SbUnoProperty( ID_DBG_SUPPORTEDINTERFACES, SbxSTRING, aProp, -1, false );
+ QuickInsert( (SbxVariable*)xVarRef );
+
+ // Id == -2: Properties ausgeben
+ xVarRef = new SbUnoProperty( ID_DBG_PROPERTIES, SbxSTRING, aProp, -2, false );
+ QuickInsert( (SbxVariable*)xVarRef );
+
+ // Id == -3: Methoden ausgeben
+ xVarRef = new SbUnoProperty( ID_DBG_METHODS, SbxSTRING, aProp, -3, false );
+ QuickInsert( (SbxVariable*)xVarRef );
+}
+
+void SbUnoObject::implCreateAll( void )
+{
+ // Bestehende Methoden und Properties alle wieder wegwerfen
+ pMethods = new SbxArray;
+ pProps = new SbxArray;
+
+ if( bNeedIntrospection ) doIntrospection();
+
+ // Instrospection besorgen
+ Reference< XIntrospectionAccess > xAccess = mxUnoAccess;
+ if( !xAccess.is() )
+ {
+ if( mxInvocation.is() )
+ xAccess = mxInvocation->getIntrospection();
+ }
+ if( !xAccess.is() )
+ return;
+
+ // Properties anlegen
+ Sequence<Property> props = xAccess->getProperties( PropertyConcept::ALL - PropertyConcept::DANGEROUS );
+ UINT32 nPropCount = props.getLength();
+ const Property* pProps_ = props.getConstArray();
+
+ UINT32 i;
+ for( i = 0 ; i < nPropCount ; i++ )
+ {
+ const Property& rProp = pProps_[ i ];
+
+ // #58455 Wenn die Property void sein kann, muss als Typ Variant gesetzt werden
+ SbxDataType eSbxType;
+ if( rProp.Attributes & PropertyAttribute::MAYBEVOID )
+ eSbxType = SbxVARIANT;
+ else
+ eSbxType = unoToSbxType( rProp.Type.getTypeClass() );
+
+ // Property anlegen und reinbraten
+ SbxVariableRef xVarRef = new SbUnoProperty( rProp.Name, eSbxType, rProp, i, false );
+ QuickInsert( (SbxVariable*)xVarRef );
+ }
+
+ // Dbg_-Properties anlegen
+ implCreateDbgProperties();
+
+ // Methoden anlegen
+ Sequence< Reference< XIdlMethod > > aMethodSeq = xAccess->getMethods
+ ( MethodConcept::ALL - MethodConcept::DANGEROUS );
+ UINT32 nMethCount = aMethodSeq.getLength();
+ const Reference< XIdlMethod >* pMethods_ = aMethodSeq.getConstArray();
+ for( i = 0 ; i < nMethCount ; i++ )
+ {
+ // Methode ansprechen
+ const Reference< XIdlMethod >& rxMethod = pMethods_[i];
+
+ // SbUnoMethode anlegen und reinbraten
+ SbxVariableRef xMethRef = new SbUnoMethod
+ ( rxMethod->getName(), unoToSbxType( rxMethod->getReturnType() ), rxMethod, false );
+ QuickInsert( (SbxVariable*)xMethRef );
+ }
+}
+
+
+// Wert rausgeben
+Any SbUnoObject::getUnoAny( void )
+{
+ Any aRetAny;
+ if( bNeedIntrospection ) doIntrospection();
+ if( mxMaterialHolder.is() )
+ aRetAny = mxMaterialHolder->getMaterial();
+ else if( mxInvocation.is() )
+ aRetAny <<= mxInvocation;
+ return aRetAny;
+}
+
+// Hilfsmethode zum Anlegen einer Uno-Struct per CoreReflection
+SbUnoObject* Impl_CreateUnoStruct( const String& aClassName )
+{
+ // CoreReflection holen
+ Reference< XIdlReflection > xCoreReflection = getCoreReflection_Impl();
+ if( !xCoreReflection.is() )
+ return NULL;
+
+ // Klasse suchen
+ Reference< XIdlClass > xClass;
+ Reference< XHierarchicalNameAccess > xHarryName =
+ getCoreReflection_HierarchicalNameAccess_Impl();
+ if( xHarryName.is() && xHarryName->hasByHierarchicalName( aClassName ) )
+ xClass = xCoreReflection->forName( aClassName );
+ if( !xClass.is() )
+ return NULL;
+
+ // Ist es ueberhaupt ein struct?
+ TypeClass eType = xClass->getTypeClass();
+ if( eType != TypeClass_STRUCT )
+ return NULL;
+
+ // Instanz erzeugen
+ Any aNewAny;
+ xClass->createObject( aNewAny );
+
+ // SbUnoObject daraus basteln
+ SbUnoObject* pUnoObj = new SbUnoObject( aClassName, aNewAny );
+ return pUnoObj;
+}
+
+
+// Factory-Klasse fuer das Anlegen von Uno-Structs per DIM AS NEW
+SbxBase* SbUnoFactory::Create( UINT16, UINT32 )
+{
+ // Ueber SbxId laeuft in Uno nix
+ return NULL;
+}
+
+SbxObject* SbUnoFactory::CreateObject( const String& rClassName )
+{
+ return Impl_CreateUnoStruct( rClassName );
+}
+
+// Funktion, um einen globalen Bezeichner im
+// UnoScope zu suchen und fuer Sbx zu wrappen
+SbxVariable* findUnoClass( const String& rName )
+{
+ // #105550 Check if module exists
+ SbUnoClass* pUnoClass = NULL;
+
+ Reference< XHierarchicalNameAccess > xTypeAccess = getTypeProvider_Impl();
+ Reference< XTypeDescription > xTypeDesc;
+ if( xTypeAccess->hasByHierarchicalName( rName ) )
+ {
+ Any aRet = xTypeAccess->getByHierarchicalName( rName );
+ aRet >>= xTypeDesc;
+
+ if( xTypeDesc.is() )
+ {
+ TypeClass eTypeClass = xTypeDesc->getTypeClass();
+ if( eTypeClass == TypeClass_MODULE || eTypeClass == TypeClass_CONSTANTS )
+ pUnoClass = new SbUnoClass( rName );
+ }
+ }
+ return pUnoClass;
+}
+
+SbxVariable* SbUnoClass::Find( const XubString& rName, SbxClassType t )
+{
+ (void)t;
+
+ SbxVariable* pRes = SbxObject::Find( rName, SbxCLASS_VARIABLE );
+
+ // Wenn nichts gefunden wird, ist das Sub-Modul noch nicht bekannt
+ if( !pRes )
+ {
+ // Wenn es schon eine Klasse ist, nach einen Feld fragen
+ if( m_xClass.is() )
+ {
+ // Ist es ein Field
+ OUString aUStr( rName );
+ Reference< XIdlField > xField = m_xClass->getField( aUStr );
+ Reference< XIdlClass > xClass;
+ if( xField.is() )
+ {
+ try
+ {
+ Any aAny;
+ aAny = xField->get( aAny );
+
+ // Nach Sbx wandeln
+ pRes = new SbxVariable( SbxVARIANT );
+ pRes->SetName( rName );
+ unoToSbxValue( pRes, aAny );
+ }
+ catch( BasicErrorException& e0 )
+ {
+ implHandleBasicErrorException( e0 );
+ }
+ catch( WrappedTargetException& e1 )
+ {
+ implHandleWrappedTargetException( e1 );
+ }
+ catch( RuntimeException& e2 )
+ {
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION, implGetExceptionMsg( e2 ) );
+ }
+ catch( IllegalArgumentException& e3 )
+ {
+ StarBASIC::Error( ERRCODE_BASIC_EXCEPTION,
+ implGetExceptionMsg( e3, aIllegalArgumentExceptionName ) );
+ }
+ }
+ }
+ else
+ {
+ // Vollqualifizierten Namen erweitern
+ String aNewName = GetName();
+ aNewName.AppendAscii( "." );
+ aNewName += rName;
+
+ // CoreReflection holen
+ Reference< XIdlReflection > xCoreReflection = getCoreReflection_Impl();
+ if( xCoreReflection.is() )
+ {
+ // Ist es eine Konstante?
+ Reference< XHierarchicalNameAccess > xHarryName( xCoreReflection, UNO_QUERY );
+ if( xHarryName.is() )
+ {
+ try
+ {
+ Any aValue = xHarryName->getByHierarchicalName( aNewName );
+ TypeClass eType = aValue.getValueType().getTypeClass();
+
+ // Interface gefunden? Dann ist es eine Klasse
+ if( eType == TypeClass_INTERFACE )
+ {
+ Reference< XInterface > xIface = *(Reference< XInterface >*)aValue.getValue();
+ Reference< XIdlClass > xClass( xIface, UNO_QUERY );
+ if( xClass.is() )
+ {
+ pRes = new SbxVariable( SbxVARIANT );
+ SbxObjectRef xWrapper = (SbxObject*)new SbUnoClass( aNewName, xClass );
+ pRes->PutObject( xWrapper );
+
+ }
+ }
+ else
+ {
+ pRes = new SbxVariable( SbxVARIANT );
+ unoToSbxValue( pRes, aValue );
+ }
+ }
+ catch( NoSuchElementException& e1 )
+ {
+ String aMsg = implGetExceptionMsg( e1 );
+ }
+ }
+
+ // Sonst wieder als Klasse annehmen
+ if( !pRes )
+ {
+ SbxVariable* pNewClass = findUnoClass( aNewName );
+ if( pNewClass )
+ {
+ Reference< XIdlClass > xClass;
+ pRes = new SbxVariable( SbxVARIANT );
+ SbxObjectRef xWrapper = (SbxObject*)pNewClass;
+ pRes->PutObject( xWrapper );
+ }
+ }
+ }
+ }
+
+ if( pRes )
+ {
+ pRes->SetName( rName );
+
+ // Variable einfuegen, damit sie spaeter im Find gefunden wird
+ QuickInsert( pRes );
+
+ // Uns selbst gleich wieder als Listener rausnehmen,
+ // die Werte sind alle konstant
+ if( pRes->IsBroadcaster() )
+ EndListening( pRes->GetBroadcaster(), TRUE );
+ }
+ }
+ return pRes;
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/classes/sbxmod.cxx b/binfilter/bf_basic/source/classes/sbxmod.cxx
new file mode 100644
index 000000000000..4f954d25de5e
--- /dev/null
+++ b/binfilter/bf_basic/source/classes/sbxmod.cxx
@@ -0,0 +1,1447 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <list>
+
+#include <vcl/svapp.hxx>
+
+#include <tools/stream.hxx>
+#include <bf_svtools/brdcst.hxx>
+#include <sbx.hxx>
+#include "sb.hxx"
+#include <sbjsmeth.hxx>
+#include "sbjsmod.hxx"
+#include "sbintern.hxx"
+#include "image.hxx"
+#include "token.hxx"
+#include "sbunoobj.hxx"
+#include "basrdll.hxx"
+
+#include <osl/mutex.hxx>
+#include <rtl/ustring.hxx>
+
+// for the bsearch
+#ifdef WNT
+#define CDECL _cdecl
+#endif
+#if defined(UNX)
+#define CDECL
+#endif
+#ifdef UNX
+#include <sys/resource.h>
+#endif
+
+#include <stdio.h>
+
+
+namespace binfilter {
+
+using ::rtl::OUString;
+
+TYPEINIT1(SbModule,SbxObject)
+TYPEINIT1(SbMethod,SbxMethod)
+TYPEINIT1(SbProperty,SbxProperty)
+TYPEINIT1(SbProcedureProperty,SbxProperty)
+TYPEINIT1(SbJScriptModule,SbModule)
+TYPEINIT1(SbJScriptMethod,SbMethod)
+
+/////////////////////////////////////////////////////////////////////////////
+
+// Ein BASIC-Modul hat EXTSEARCH gesetzt, damit die im Modul enthaltenen
+// Elemente von anderen Modulen aus gefunden werden koennen.
+
+SbModule::SbModule( const String& rName )
+ : SbxObject( String( RTL_CONSTASCII_USTRINGPARAM("StarBASICModule") ) ),
+ pImage( NULL ), pClassData( NULL )
+{
+ SetName( rName );
+ SetFlag( SBX_EXTSEARCH | SBX_GBLSEARCH );
+}
+
+SbModule::~SbModule()
+{
+ if( pImage )
+ delete pImage;
+ if( pClassData )
+ delete pClassData;
+}
+
+BOOL SbModule::IsCompiled() const
+{
+ return BOOL( pImage != 0 );
+}
+
+const SbxObject* SbModule::FindType( String aTypeName ) const
+{
+ return pImage ? pImage->FindType( aTypeName ) : NULL;
+}
+
+
+// Aus dem Codegenerator: Loeschen des Images und Invalidieren der Entries
+
+void SbModule::StartDefinitions()
+{
+ delete pImage; pImage = NULL;
+ if( pClassData )
+ pClassData->clear();
+
+ // Methoden und Properties bleiben erhalten, sind jedoch ungueltig
+ // schliesslich sind ja u.U. die Infos belegt
+ USHORT i;
+ for( i = 0; i < pMethods->Count(); i++ )
+ {
+ SbMethod* p = PTR_CAST(SbMethod,pMethods->Get( i ) );
+ if( p )
+ p->bInvalid = TRUE;
+ }
+ for( i = 0; i < pProps->Count(); )
+ {
+ SbProperty* p = PTR_CAST(SbProperty,pProps->Get( i ) );
+ if( p )
+ pProps->Remove( i );
+ else
+ i++;
+ }
+}
+
+// Methode anfordern/anlegen
+
+SbMethod* SbModule::GetMethod( const String& rName, SbxDataType t )
+{
+ SbxVariable* p = pMethods->Find( rName, SbxCLASS_METHOD );
+ SbMethod* pMeth = p ? PTR_CAST(SbMethod,p) : NULL;
+ if( p && !pMeth )
+ pMethods->Remove( p );
+ if( !pMeth )
+ {
+ pMeth = new SbMethod( rName, t, this );
+ pMeth->SetParent( this );
+ pMeth->SetFlags( SBX_READ );
+ pMethods->Put( pMeth, pMethods->Count() );
+ StartListening( pMeth->GetBroadcaster(), TRUE );
+ }
+ // Per Default ist die Methode GUELTIG, da sie auch vom Compiler
+ // (Codegenerator) erzeugt werden kann
+ pMeth->bInvalid = FALSE;
+ pMeth->ResetFlag( SBX_FIXED );
+ pMeth->SetFlag( SBX_WRITE );
+ pMeth->SetType( t );
+ pMeth->ResetFlag( SBX_WRITE );
+ if( t != SbxVARIANT )
+ pMeth->SetFlag( SBX_FIXED );
+ return pMeth;
+}
+
+// Property anfordern/anlegen
+
+SbIfaceMapperMethod::~SbIfaceMapperMethod()
+{
+}
+
+TYPEINIT1(SbIfaceMapperMethod,SbMethod)
+
+
+// Aus dem Codegenerator: Ungueltige Eintraege entfernen
+
+void SbModule::EndDefinitions( BOOL bNewState )
+{
+ for( USHORT i = 0; i < pMethods->Count(); )
+ {
+ SbMethod* p = PTR_CAST(SbMethod,pMethods->Get( i ) );
+ if( p )
+ {
+ if( p->bInvalid )
+ pMethods->Remove( p );
+ else
+ {
+ p->bInvalid = bNewState;
+ i++;
+ }
+ }
+ else
+ i++;
+ }
+ SetModified( TRUE );
+}
+
+void SbModule::Clear()
+{
+ delete pImage; pImage = NULL;
+ if( pClassData )
+ pClassData->clear();
+ SbxObject::Clear();
+}
+
+
+SbxVariable* SbModule::Find( const XubString& rName, SbxClassType t )
+{
+ SbxVariable* pRes = SbxObject::Find( rName, t );
+/*?*/ // if( !pRes && pImage )
+/*?*/ // {
+/*?*/ // SbiInstance* pInst = pINST;
+/*?*/ // if( pInst && pInst->IsCompatibility() )
+/*?*/ // {
+/*?*/ // // Put enum types as objects into module,
+/*?*/ // // allows MyEnum.First notation
+/*?*/ // SbxArrayRef xArray = pImage->GetEnums();
+/*?*/ // if( xArray.Is() )
+/*?*/ // {
+/*?*/ // SbxVariable* pEnumVar = xArray->Find( rName, SbxCLASS_DONTCARE );
+/*?*/ // SbxObject* pEnumObject = PTR_CAST( SbxObject, pEnumVar );
+/*?*/ // if( pEnumObject )
+/*?*/ // {
+/*?*/ // bool bPrivate = pEnumObject->IsSet( SBX_PRIVATE );
+/*?*/ // String aEnumName = pEnumObject->GetName();
+/*?*/ //
+/*?*/ // pRes = new SbxVariable( SbxOBJECT );
+/*?*/ // pRes->SetName( aEnumName );
+/*?*/ // pRes->SetParent( this );
+/*?*/ // pRes->SetFlag( SBX_READ );
+/*?*/ // if( bPrivate )
+/*?*/ // pRes->SetFlag( SBX_PRIVATE );
+/*?*/ // pRes->PutObject( pEnumObject );
+/*?*/ // }
+/*?*/ // }
+/*?*/ // }
+/*?*/ // }
+ return pRes;
+}
+
+const ::rtl::OUString& SbModule::GetSource32() const
+{
+ return aOUSource;
+}
+
+const String& SbModule::GetSource() const
+{
+ static String aRetStr;
+ aRetStr = aOUSource;
+ return aRetStr;
+}
+
+// Parent und BASIC sind eins!
+
+void SbModule::SetParent( SbxObject* p )
+{
+ // #118083: Assertion is not valid any more
+ // DBG_ASSERT( !p || p->IsA( TYPE(StarBASIC) ), "SbModules nur in BASIC eintragen" );
+ pParent = p;
+}
+
+void SbModule::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
+ const SfxHint& rHint, const TypeId& rHintType )
+{
+ const SbxHint* pHint = PTR_CAST(SbxHint,&rHint);
+ if( pHint )
+ {
+ SbxVariable* pVar = pHint->GetVar();
+ SbProperty* pProp = PTR_CAST(SbProperty,pVar);
+ SbMethod* pMeth = PTR_CAST(SbMethod,pVar);
+ if( pProp )
+ {
+ if( pProp->GetModule() != this )
+ SetError( SbxERR_BAD_ACTION );
+ }
+ else if( pMeth )
+ {
+ if( pHint->GetId() == SBX_HINT_DATAWANTED )
+ {
+ if( pMeth->bInvalid && !Compile() )
+ // Auto-Compile hat nicht geklappt!
+ StarBASIC::Error( SbERR_BAD_PROP_VALUE );
+ else
+ {
+ // Aufruf eines Unterprogramms
+ SbModule* pOld = pMOD;
+ pMOD = this;
+ Run( (SbMethod*) pVar );
+ pMOD = pOld;
+ }
+ }
+ }
+ else
+ SbxObject::SFX_NOTIFY( rBC, rBCType, rHint, rHintType );
+ }
+}
+
+// Das Setzen der Source macht das Image ungueltig
+// und scant die Methoden-Definitionen neu ein
+
+void SbModule::SetSource( const String& r )
+{
+ SetSource32( r );
+}
+
+void SbModule::SetSource32( const ::rtl::OUString& r )
+{
+ aOUSource = r;
+ StartDefinitions();
+ SbiTokenizer aTok( r );
+ while( !aTok.IsEof() )
+ {
+ SbiToken eEndTok = NIL;
+
+ // Suchen nach SUB oder FUNCTION
+ SbiToken eLastTok = NIL;
+ while( !aTok.IsEof() )
+ {
+ // #32385: Nicht bei declare
+ SbiToken eCurTok = aTok.Next();
+ if( eLastTok != DECLARE )
+ {
+ if( eCurTok == SUB )
+ {
+ eEndTok = ENDSUB; break;
+ }
+ if( eCurTok == FUNCTION )
+ {
+ eEndTok = ENDFUNC; break;
+ }
+ if( eCurTok == PROPERTY )
+ {
+ eEndTok = ENDPROPERTY; break;
+ }
+ if( eCurTok == OPTION )
+ {
+ eCurTok = aTok.Next();
+ if( eCurTok == COMPATIBLE )
+ aTok.SetCompatible( true );
+ }
+ }
+ eLastTok = eCurTok;
+ }
+ // Definition der Methode
+ SbMethod* pMeth = NULL;
+ if( eEndTok != NIL )
+ {
+ USHORT nLine1 = aTok.GetLine();
+ if( aTok.Next() == SYMBOL )
+ {
+ String aName_( aTok.GetSym() );
+ SbxDataType t = aTok.GetType();
+ if( t == SbxVARIANT && eEndTok == ENDSUB )
+ t = SbxVOID;
+ pMeth = GetMethod( aName_, t );
+ pMeth->nLine1 = pMeth->nLine2 = nLine1;
+ // Die Methode ist erst mal GUELTIG
+ pMeth->bInvalid = FALSE;
+ }
+ else
+ eEndTok = NIL;
+ }
+ // Skip bis END SUB/END FUNCTION
+ if( eEndTok != NIL )
+ {
+ while( !aTok.IsEof() )
+ {
+ if( aTok.Next() == eEndTok )
+ {
+ pMeth->nLine2 = aTok.GetLine();
+ break;
+ }
+ }
+ if( aTok.IsEof() )
+ pMeth->nLine2 = aTok.GetLine();
+ }
+ }
+ EndDefinitions( TRUE );
+}
+
+SbMethod* SbModule::GetFunctionForLine( USHORT nLine )
+{
+ for( USHORT i = 0; i < pMethods->Count(); i++ )
+ {
+ SbMethod* p = (SbMethod*) pMethods->Get( i );
+ if( p->GetSbxId() == SBXID_BASICMETHOD )
+ {
+ if( nLine >= p->nLine1 && nLine <= p->nLine2 )
+ return p;
+ }
+ }
+ return NULL;
+}
+
+// Ausstrahlen eines Hints an alle Basics
+
+static void _SendHint( SbxObject* pObj, ULONG nId, SbMethod* p )
+{
+ // Selbst ein BASIC?
+ if( pObj->IsA( TYPE(StarBASIC) ) && pObj->IsBroadcaster() )
+ pObj->GetBroadcaster().Broadcast( SbxHint( nId, p ) );
+ // Dann die Unterobjekte fragen
+ SbxArray* pObjs = pObj->GetObjects();
+ for( USHORT i = 0; i < pObjs->Count(); i++ )
+ {
+ SbxVariable* pVar = pObjs->Get( i );
+ if( pVar->IsA( TYPE(SbxObject) ) )
+ _SendHint( PTR_CAST(SbxObject,pVar), nId, p );
+ }
+}
+
+/*?*/ // static void SendHint( SbxObject* pObj, ULONG nId, SbMethod* p )
+/*?*/ // {
+/*?*/ // while( pObj->GetParent() )
+/*?*/ // pObj = pObj->GetParent();
+/*?*/ // _SendHint( pObj, nId, p );
+/*?*/ // }
+
+// #57841 Uno-Objekte, die in RTL-Funktionen gehalten werden,
+// beim Programm-Ende freigeben, damit nichts gehalten wird.
+void ClearUnoObjectsInRTL_Impl_Rek( StarBASIC* pBasic )
+{
+ // return-Wert von CreateUnoService loeschen
+ static String aName( RTL_CONSTASCII_USTRINGPARAM("CreateUnoService") );
+ SbxVariable* pVar = pBasic->GetRtl()->Find( aName, SbxCLASS_METHOD );
+ if( pVar )
+ pVar->SbxValue::Clear();
+
+ // return-Wert von CreateUnoDialog loeschen
+ static String aName2( RTL_CONSTASCII_USTRINGPARAM("CreateUnoDialog") );
+ pVar = pBasic->GetRtl()->Find( aName2, SbxCLASS_METHOD );
+ if( pVar )
+ pVar->SbxValue::Clear();
+
+ // return-Wert von CDec loeschen
+ static String aName3( RTL_CONSTASCII_USTRINGPARAM("CDec") );
+ pVar = pBasic->GetRtl()->Find( aName3, SbxCLASS_METHOD );
+ if( pVar )
+ pVar->SbxValue::Clear();
+
+ // return-Wert von CreateObject loeschen
+ static String aName4( RTL_CONSTASCII_USTRINGPARAM("CreateObject") );
+ pVar = pBasic->GetRtl()->Find( aName4, SbxCLASS_METHOD );
+ if( pVar )
+ pVar->SbxValue::Clear();
+
+ // Ueber alle Sub-Basics gehen
+ SbxArray* pObjs = pBasic->GetObjects();
+ USHORT nCount = pObjs->Count();
+ for( USHORT i = 0 ; i < nCount ; i++ )
+ {
+ SbxVariable* pObjVar = pObjs->Get( i );
+ StarBASIC* pSubBasic = PTR_CAST( StarBASIC, pObjVar );
+ if( pSubBasic )
+ ClearUnoObjectsInRTL_Impl_Rek( pSubBasic );
+ }
+}
+
+// Ausfuehren eines BASIC-Unterprogramms
+USHORT SbModule::Run( SbMethod* /*pMeth*/ )
+{
+ DBG_ERROR( "SbModule::Run: dead code!" );
+ return 0;
+}
+
+// Suche nach dem naechsten STMNT-Befehl im Code. Wird vom STMNT-
+// Opcode verwendet, um die Endspalte zu setzen.
+
+const BYTE* SbModule::FindNextStmnt( const BYTE* p, USHORT& nLine, USHORT& nCol ) const
+{
+ return FindNextStmnt( p, nLine, nCol, FALSE );
+}
+
+const BYTE* SbModule::FindNextStmnt( const BYTE* /*p*/, USHORT& /*nLine*/, USHORT& /*nCol*/,
+ BOOL /*bFollowJumps*/, const SbiImage* /*pImg*/ ) const
+{
+ DBG_ERROR( "SbModule::FindNextStmnt: dead code!" );
+/*?*/ // UINT32 nPC = (UINT32) ( p - (const BYTE*) pImage->GetCode() );
+/*?*/ // while( nPC < pImage->GetCodeSize() )
+/*?*/ // {
+/*?*/ // SbiOpcode eOp = (SbiOpcode ) ( *p++ );
+/*?*/ // nPC++;
+/*?*/ // if( bFollowJumps && eOp == _JUMP && pImg )
+/*?*/ // {
+/*?*/ // DBG_ASSERT( pImg, "FindNextStmnt: pImg==NULL with FollowJumps option" );
+/*?*/ // UINT32 nOp1 = *p++; nOp1 |= *p++ << 8;
+/*?*/ // nOp1 |= *p++ << 16; nOp1 |= *p++ << 24;
+/*?*/ // p = (const BYTE*) pImg->GetCode() + nOp1;
+/*?*/ // }
+/*?*/ // else if( eOp >= SbOP1_START && eOp <= SbOP1_END )
+/*?*/ // p += 4, nPC += 4;
+/*?*/ // else if( eOp == _STMNT )
+/*?*/ // {
+/*?*/ // UINT32 nl, nc;
+/*?*/ // nl = *p++; nl |= *p++ << 8;
+/*?*/ // nl |= *p++ << 16 ; nl |= *p++ << 24;
+/*?*/ // nc = *p++; nc |= *p++ << 8;
+/*?*/ // nc |= *p++ << 16 ; nc |= *p++ << 24;
+/*?*/ // nLine = (USHORT)nl; nCol = (USHORT)nc;
+/*?*/ // return p;
+/*?*/ // }
+/*?*/ // else if( eOp >= SbOP2_START && eOp <= SbOP2_END )
+/*?*/ // p += 8, nPC += 8;
+/*?*/ // else if( !( eOp >= SbOP0_START && eOp <= SbOP0_END ) )
+/*?*/ // {
+/*?*/ // StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
+/*?*/ // break;
+/*?*/ // }
+/*?*/ // }
+ return NULL;
+}
+
+// Testen, ob eine Zeile STMNT-Opcodes enthaelt
+
+BOOL SbModule::IsBreakable( USHORT nLine ) const
+{
+ if( !pImage )
+ return FALSE;
+ const BYTE* p = (const BYTE* ) pImage->GetCode();
+ USHORT nl, nc;
+ while( ( p = FindNextStmnt( p, nl, nc ) ) != NULL )
+ if( nl == nLine )
+ return TRUE;
+ return FALSE;
+}
+
+USHORT SbModule::GetBPCount() const
+{
+ return 0;
+}
+
+USHORT SbModule::GetBP( USHORT ) const
+{
+ return 0;
+}
+
+BOOL SbModule::IsBP( USHORT ) const
+{
+ return FALSE;
+}
+
+BOOL SbModule::SetBP( USHORT /*nLine*/ )
+{
+ DBG_ERROR( "SbModule::SetBP: dead code!" );
+ return FALSE;
+}
+
+BOOL SbModule::ClearBP( USHORT )
+{
+ return FALSE;
+}
+
+void SbModule::ClearAllBP()
+{
+}
+
+void
+SbModule::fixUpMethodStart( bool bCvtToLegacy, SbiImage* pImg ) const
+{
+ if ( !pImg )
+ pImg = pImage;
+ for( UINT32 i = 0; i < pMethods->Count(); i++ )
+ {
+ SbMethod* pMeth = PTR_CAST(SbMethod,pMethods->Get( (USHORT)i ) );
+ if( pMeth )
+ {
+ //fixup method start positions
+ if ( bCvtToLegacy )
+ pMeth->nStart = pImg->CalcLegacyOffset( pMeth->nStart );
+ else
+ pMeth->nStart = pImg->CalcNewOffset( (USHORT)pMeth->nStart );
+ }
+ }
+
+}
+
+BOOL SbModule::LoadData( SvStream& rStrm, USHORT nVer )
+{
+ Clear();
+ if( !SbxObject::LoadData( rStrm, 1 ) )
+ return FALSE;
+ // Sicherheitshalber...
+ SetFlag( SBX_EXTSEARCH | SBX_GBLSEARCH );
+ BYTE bImage;
+ rStrm >> bImage;
+ if( bImage )
+ {
+ SbiImage* p = new SbiImage;
+ UINT32 nImgVer = 0;
+
+ if( !p->Load( rStrm, nImgVer ) )
+ {
+ delete p;
+ return FALSE;
+ }
+ // If the image is in old format, we fix up the method start offsets
+ if ( nImgVer < B_EXT_IMG_VERSION )
+ {
+ fixUpMethodStart( false, p );
+ p->ReleaseLegacyBuffer();
+ }
+ aComment = p->aComment;
+ SetName( p->aName );
+ if( p->GetCodeSize() )
+ {
+ aOUSource = p->aOUSource;
+ // Alte Version: Image weg
+ if( nVer == 1 )
+ {
+ SetSource32( p->aOUSource );
+ delete p;
+ }
+ else
+ pImage = p;
+ }
+ else
+ {
+ SetSource32( p->aOUSource );
+ delete p;
+ }
+ }
+ return TRUE;
+}
+
+BOOL SbModule::StoreData( SvStream& rStrm ) const
+{
+ BOOL bFixup = ( pImage && !pImage->ExceedsLegacyLimits() );
+ if ( bFixup )
+ fixUpMethodStart( true );
+ BOOL bRet = SbxObject::StoreData( rStrm );
+ if ( !bRet )
+ return FALSE;
+
+ if( pImage )
+ {
+ pImage->aOUSource = aOUSource;
+ pImage->aComment = aComment;
+ pImage->aName = GetName();
+ rStrm << (BYTE) 1;
+ // # PCode is saved only for legacy formats only
+ // It should be noted that it probably isn't necessary
+ // It would be better not to store the image ( more flexible with
+ // formats )
+ bool bRes = pImage->Save( rStrm, B_LEGACYVERSION );
+ if ( bFixup )
+ fixUpMethodStart( false ); // restore method starts
+ return bRes;
+
+ }
+ else
+ {
+ SbiImage aImg;
+ aImg.aOUSource = aOUSource;
+ aImg.aComment = aComment;
+ aImg.aName = GetName();
+ rStrm << (BYTE) 1;
+ return aImg.Save( rStrm );
+ }
+}
+
+// Called for >= OO 1.0 passwd protected libraries only
+//
+
+BOOL SbModule::LoadCompleted()
+{
+ SbxArray* p = GetMethods();
+ USHORT i;
+ for( i = 0; i < p->Count(); i++ )
+ {
+ SbMethod* q = PTR_CAST(SbMethod,p->Get( i ) );
+ if( q )
+ q->pMod = this;
+ }
+ p = GetProperties();
+ for( i = 0; i < p->Count(); i++ )
+ {
+ SbProperty* q = PTR_CAST(SbProperty,p->Get( i ) );
+ if( q )
+ q->pMod = this;
+ }
+ return TRUE;
+}
+
+
+/////////////////////////////////////////////////////////////////////////
+// Hilfsklasse zur Untersuchung von JavaScript-Modulen, zunaechst zum
+// Heraussuchen der Funktionen, spaeter auch zum Syntax-Highlighting verwenden
+
+// Flags fuer Zeichen-Eigenschaften
+#define CHAR_START_IDENTIFIER 0x0001
+#define CHAR_IN_IDENTIFIER 0x0002
+#define CHAR_START_NUMBER 0x0004
+#define CHAR_IN_NUMBER 0x0008
+#define CHAR_IN_HEX_NUMBER 0x0010
+#define CHAR_IN_OCT_NUMBER 0x0020
+#define CHAR_START_STRING 0x0040
+#define CHAR_OPERATOR 0x0080
+#define CHAR_SPACE 0x0100
+#define CHAR_EOL 0x0200
+
+#define CHAR_EOF 0x00
+
+
+/*?*/ // class SimpleTokenizer_Impl
+/*?*/ // {
+/*?*/ // // Zeichen-Info-Tabelle
+/*?*/ // USHORT aCharTypeTab[256];
+/*?*/ //
+/*?*/ // const sal_Unicode* mpStringBegin;
+/*?*/ // const sal_Unicode* mpActualPos;
+/*?*/ //
+/*?*/ // // Zeile und Spalte
+/*?*/ // UINT32 nLine;
+/*?*/ // UINT32 nCol;
+/*?*/ //
+/*?*/ // sal_Unicode peekChar( void ) { return *mpActualPos; }
+/*?*/ // sal_Unicode getChar( void ) { nCol++; return *mpActualPos++; }
+/*?*/ //
+/*?*/ // // Hilfsfunktion: Zeichen-Flag Testen
+/*?*/ // BOOL testCharFlags( sal_Unicode c, USHORT nTestFlags );
+/*?*/ //
+/*?*/ // // Neues Token holen, Leerstring == nix mehr da
+/*?*/ // BOOL getNextToken( /*out*/TokenTypes& reType,
+/*?*/ // /*out*/const sal_Unicode*& rpStartPos, /*out*/const sal_Unicode*& rpEndPos );
+/*?*/ //
+/*?*/ // String getTokStr( /*out*/const sal_Unicode* pStartPos, /*out*/const sal_Unicode* pEndPos );
+/*?*/ //
+/*?*/ // #ifdef DBG_UTIL
+/*?*/ // // TEST: Token ausgeben
+/*?*/ // String getFullTokenStr( /*out*/TokenTypes eType,
+/*?*/ // /*out*/const sal_Unicode* pStartPos, /*out*/const sal_Unicode* pEndPos );
+/*?*/ // #endif
+/*?*/ //
+/*?*/ // const char** ppListKeyWords;
+/*?*/ // UINT16 nKeyWordCount;
+/*?*/ //
+/*?*/ // public:
+/*?*/ // SimpleTokenizer_Impl( void );
+/*?*/ // ~SimpleTokenizer_Impl( void );
+/*?*/ //
+/*?*/ // UINT16 parseLine( UINT32 nLine, const String* aSource );
+/*?*/ // void getHighlightPortions( UINT32 nParseLine, const String& rLine,
+/*?*/ // /*out*/HighlightPortions& portions );
+/*?*/ // void setKeyWords( const char** ppKeyWords, UINT16 nCount );
+/*?*/ // };
+
+/*?*/ // // Hilfsfunktion: Zeichen-Flag Testen
+/*?*/ // BOOL SimpleTokenizer_Impl::testCharFlags( sal_Unicode c, USHORT nTestFlags )
+/*?*/ // {
+/*?*/ // bool bRet = false;
+/*?*/ // if( c != 0 && c <= 255 )
+/*?*/ // {
+/*?*/ // bRet = ( (aCharTypeTab[c] & nTestFlags) != 0 );
+/*?*/ // }
+/*?*/ // else if( c > 255 )
+/*?*/ // {
+/*?*/ // bRet = (( CHAR_START_IDENTIFIER | CHAR_IN_IDENTIFIER ) & nTestFlags) != 0
+/*?*/ // ? BasicSimpleCharClass::isAlpha( c, true ) : false;
+/*?*/ // }
+/*?*/ // return bRet;
+/*?*/ // }
+/*?*/ //
+/*?*/ // void SimpleTokenizer_Impl::setKeyWords( const char** ppKeyWords, UINT16 nCount )
+/*?*/ // {
+/*?*/ // ppListKeyWords = ppKeyWords;
+/*?*/ // nKeyWordCount = nCount;
+/*?*/ // }
+/*?*/ //
+/*?*/ // // Neues Token holen
+/*?*/ // BOOL SimpleTokenizer_Impl::getNextToken( /*out*/TokenTypes& reType,
+/*?*/ // /*out*/const sal_Unicode*& rpStartPos, /*out*/const sal_Unicode*& rpEndPos )
+/*?*/ // {
+/*?*/ // reType = TT_UNKNOWN;
+/*?*/ //
+/*?*/ // // Position merken
+/*?*/ // rpStartPos = mpActualPos;
+/*?*/ //
+/*?*/ // // Zeichen untersuchen
+/*?*/ // sal_Unicode c = peekChar();
+/*?*/ // if( c == CHAR_EOF )
+/*?*/ // return FALSE;
+/*?*/ //
+/*?*/ // // Zeichen lesen
+/*?*/ // getChar();
+/*?*/ //
+/*?*/ // //*** Alle Moeglichkeiten durchgehen ***
+/*?*/ // // Space?
+/*?*/ // if ( (testCharFlags( c, CHAR_SPACE ) == TRUE) )
+/*?*/ // {
+/*?*/ // while( testCharFlags( peekChar(), CHAR_SPACE ) == TRUE )
+/*?*/ // getChar();
+/*?*/ //
+/*?*/ // reType = TT_WHITESPACE;
+/*?*/ // }
+/*?*/ //
+/*?*/ // // Identifier?
+/*?*/ // else if ( (testCharFlags( c, CHAR_START_IDENTIFIER ) == TRUE) )
+/*?*/ // {
+/*?*/ // BOOL bIdentifierChar;
+/*?*/ // do
+/*?*/ // {
+/*?*/ // // Naechstes Zeichen holen
+/*?*/ // c = peekChar();
+/*?*/ // bIdentifierChar = testCharFlags( c, CHAR_IN_IDENTIFIER );
+/*?*/ // if( bIdentifierChar )
+/*?*/ // getChar();
+/*?*/ // }
+/*?*/ // while( bIdentifierChar );
+/*?*/ //
+/*?*/ // reType = TT_IDENTIFIER;
+/*?*/ //
+/*?*/ // // Schluesselwort-Tabelle
+/*?*/ // if (ppListKeyWords != NULL)
+/*?*/ // {
+/*?*/ // int nCount = mpActualPos - rpStartPos;
+/*?*/ //
+/*?*/ // // No keyword if string contains char > 255
+/*?*/ // bool bCanBeKeyword = true;
+/*?*/ // for( int i = 0 ; i < nCount ; i++ )
+/*?*/ // {
+/*?*/ // if( rpStartPos[i] > 255 )
+/*?*/ // {
+/*?*/ // bCanBeKeyword = false;
+/*?*/ // break;
+/*?*/ // }
+/*?*/ // }
+/*?*/ //
+/*?*/ // if( bCanBeKeyword )
+/*?*/ // {
+/*?*/ // String aKWString(
+/*?*/ // rpStartPos, sal::static_int_cast< xub_StrLen >(nCount) );
+/*?*/ // ByteString aByteStr( aKWString, RTL_TEXTENCODING_ASCII_US );
+/*?*/ // aByteStr.ToLowerAscii();
+/*?*/ // if ( bsearch( aByteStr.GetBuffer(), ppListKeyWords, nKeyWordCount, sizeof( char* ),
+/*?*/ // compare_strings ) )
+/*?*/ // {
+/*?*/ // reType = TT_KEYWORD;
+/*?*/ //
+/*?*/ // if ( aByteStr.Equals( "rem" ) )
+/*?*/ // {
+/*?*/ // // Alle Zeichen bis Zeilen-Ende oder EOF entfernen
+/*?*/ // sal_Unicode cPeek = peekChar();
+/*?*/ // while( cPeek != CHAR_EOF && testCharFlags( cPeek, CHAR_EOL ) == FALSE )
+/*?*/ // {
+/*?*/ // c = getChar();
+/*?*/ // cPeek = peekChar();
+/*?*/ // }
+/*?*/ //
+/*?*/ // reType = TT_COMMENT;
+/*?*/ // }
+/*?*/ // }
+/*?*/ // }
+/*?*/ // }
+/*?*/ // }
+/*?*/ //
+/*?*/ // // Operator?
+/*?*/ // else if ( testCharFlags( c, CHAR_OPERATOR ) == TRUE || c == '\'' )
+/*?*/ // {
+/*?*/ // // Kommentar ?
+/*?*/ // if ( c == '\'' )
+/*?*/ // {
+/*?*/ // c = getChar(); // '/' entfernen
+/*?*/ //
+/*?*/ // // Alle Zeichen bis Zeilen-Ende oder EOF entfernen
+/*?*/ // sal_Unicode cPeek = peekChar();
+/*?*/ // while( cPeek != CHAR_EOF && testCharFlags( cPeek, CHAR_EOL ) == FALSE )
+/*?*/ // {
+/*?*/ // getChar();
+/*?*/ // cPeek = peekChar();
+/*?*/ // }
+/*?*/ //
+/*?*/ // reType = TT_COMMENT;
+/*?*/ // }
+/*?*/ //
+/*?*/ // // Echter Operator, kann hier einfach behandelt werden,
+/*?*/ // // da nicht der wirkliche Operator, wie z.B. += interessiert,
+/*?*/ // // sondern nur die Tatsache, dass es sich um einen handelt.
+/*?*/ // if( reType != TT_COMMENT )
+/*?*/ // {
+/*?*/ // reType = TT_OPERATOR;
+/*?*/ // }
+/*?*/ // }
+/*?*/ //
+/*?*/ // // Objekt-Trenner? Muss vor Number abgehandelt werden
+/*?*/ // else if( c == '.' && ( peekChar() < '0' || peekChar() > '9' ) )
+/*?*/ // {
+/*?*/ // reType = TT_OPERATOR;
+/*?*/ // }
+/*?*/ //
+/*?*/ // // Zahl?
+/*?*/ // else if( testCharFlags( c, CHAR_START_NUMBER ) == TRUE )
+/*?*/ // {
+/*?*/ // reType = TT_NUMBER;
+/*?*/ //
+/*?*/ // // Zahlensystem, 10 = normal, wird bei Oct/Hex geaendert
+/*?*/ // int nRadix = 10;
+/*?*/ //
+/*?*/ // // Ist es eine Hex- oder Oct-Zahl?
+/*?*/ // if( c == '&' )
+/*?*/ // {
+/*?*/ // // Octal?
+/*?*/ // if( peekChar() == 'o' || peekChar() == 'O' )
+/*?*/ // {
+/*?*/ // // o entfernen
+/*?*/ // getChar();
+/*?*/ // nRadix = 8; // Octal-Basis
+/*?*/ //
+/*?*/ // // Alle Ziffern einlesen
+/*?*/ // while( testCharFlags( peekChar(), CHAR_IN_OCT_NUMBER ) )
+/*?*/ // c = getChar();
+/*?*/ // }
+/*?*/ // // Hex?
+/*?*/ // else if( peekChar() == 'h' || peekChar() == 'H' )
+/*?*/ // {
+/*?*/ // // x entfernen
+/*?*/ // getChar();
+/*?*/ // nRadix = 16; // Hex-Basis
+/*?*/ //
+/*?*/ // // Alle Ziffern einlesen und puffern
+/*?*/ // while( testCharFlags( peekChar(), CHAR_IN_HEX_NUMBER ) )
+/*?*/ // c = getChar();
+/*?*/ // }
+/*?*/ // else
+/*?*/ // {
+/*?*/ // reType = TT_OPERATOR;
+/*?*/ // }
+/*?*/ // }
+/*?*/ //
+/*?*/ // // Wenn nicht Oct oder Hex als double ansehen
+/*?*/ // if( reType == TT_NUMBER && nRadix == 10 )
+/*?*/ // {
+/*?*/ // // Flag, ob das letzte Zeichen ein Exponent war
+/*?*/ // BOOL bAfterExpChar = FALSE;
+/*?*/ //
+/*?*/ // // Alle Ziffern einlesen
+/*?*/ // while( testCharFlags( peekChar(), CHAR_IN_NUMBER ) ||
+/*?*/ // (bAfterExpChar && peekChar() == '+' ) ||
+/*?*/ // (bAfterExpChar && peekChar() == '-' ) )
+/*?*/ // // Nach Exponent auch +/- OK
+/*?*/ // {
+/*?*/ // c = getChar(); // Zeichen lesen
+/*?*/ // bAfterExpChar = ( c == 'e' || c == 'E' );
+/*?*/ // }
+/*?*/ // }
+/*?*/ //
+/*?*/ // // reType = TT_NUMBER;
+/*?*/ // }
+/*?*/ //
+/*?*/ // // String?
+/*?*/ // else if( testCharFlags( c, CHAR_START_STRING ) == TRUE )
+/*?*/ // {
+/*?*/ // // Merken, welches Zeichen den String eroeffnet hat
+/*?*/ // sal_Unicode cEndString = c;
+/*?*/ // if( c == '[' )
+/*?*/ // cEndString = ']';
+/*?*/ //
+/*?*/ // // Alle Ziffern einlesen und puffern
+/*?*/ // while( peekChar() != cEndString )
+/*?*/ // {
+/*?*/ // // #58846 EOF vor getChar() abfangen, damit EOF micht verloren geht
+/*?*/ // if( peekChar() == CHAR_EOF )
+/*?*/ // {
+/*?*/ // // ERROR: unterminated string literal
+/*?*/ // reType = TT_ERROR;
+/*?*/ // break;
+/*?*/ // }
+/*?*/ // c = getChar();
+/*?*/ // if( testCharFlags( c, CHAR_EOL ) == TRUE )
+/*?*/ // {
+/*?*/ // // ERROR: unterminated string literal
+/*?*/ // reType = TT_ERROR;
+/*?*/ // break;
+/*?*/ // }
+/*?*/ // }
+/*?*/ //
+/*?*/ // // Zeichen lesen
+/*?*/ // if( reType != TT_ERROR )
+/*?*/ // {
+/*?*/ // getChar();
+/*?*/ // if( cEndString == ']' )
+/*?*/ // reType = TT_IDENTIFIER;
+/*?*/ // else
+/*?*/ // reType = TT_STRING;
+/*?*/ // }
+/*?*/ // }
+/*?*/ //
+/*?*/ // // Zeilenende?
+/*?*/ // else if( testCharFlags( c, CHAR_EOL ) == TRUE )
+/*?*/ // {
+/*?*/ // // Falls ein weiteres anderes EOL-Char folgt, weg damit
+/*?*/ // sal_Unicode cNext = peekChar();
+/*?*/ // if( cNext != c && testCharFlags( cNext, CHAR_EOL ) == TRUE )
+/*?*/ // getChar();
+/*?*/ //
+/*?*/ // // Positions-Daten auf Zeilen-Beginn setzen
+/*?*/ // nCol = 0;
+/*?*/ // nLine++;
+/*?*/ //
+/*?*/ // reType = TT_EOL;
+/*?*/ // }
+/*?*/ //
+/*?*/ // // Alles andere bleibt TT_UNKNOWN
+/*?*/ //
+/*?*/ //
+/*?*/ // // End-Position eintragen
+/*?*/ // rpEndPos = mpActualPos;
+/*?*/ // return TRUE;
+/*?*/ // }
+/*?*/ //
+/*?*/ // String SimpleTokenizer_Impl::getTokStr
+/*?*/ // ( /*out*/const sal_Unicode* pStartPos, /*out*/const sal_Unicode* pEndPos )
+/*?*/ // {
+/*?*/ // return String( pStartPos, (USHORT)( pEndPos - pStartPos ) );
+/*?*/ // }
+/*?*/ //
+/*?*/ // #ifdef DBG_UTIL
+/*?*/ // // TEST: Token ausgeben
+/*?*/ // String SimpleTokenizer_Impl::getFullTokenStr( /*out*/TokenTypes eType,
+/*?*/ // /*out*/const sal_Unicode* pStartPos, /*out*/const sal_Unicode* pEndPos )
+/*?*/ // {
+/*?*/ // String aOut;
+/*?*/ // switch( eType )
+/*?*/ // {
+/*?*/ // case TT_UNKNOWN: aOut = String( RTL_CONSTASCII_USTRINGPARAM("TT_UNKNOWN:") ); break;
+/*?*/ // case TT_IDENTIFIER: aOut = String( RTL_CONSTASCII_USTRINGPARAM("TT_IDENTIFIER:") ); break;
+/*?*/ // case TT_WHITESPACE: aOut = String( RTL_CONSTASCII_USTRINGPARAM("TT_WHITESPACE:") ); break;
+/*?*/ // case TT_NUMBER: aOut = String( RTL_CONSTASCII_USTRINGPARAM("TT_NUMBER:") ); break;
+/*?*/ // case TT_STRING: aOut = String( RTL_CONSTASCII_USTRINGPARAM("TT_STRING:") ); break;
+/*?*/ // case TT_EOL: aOut = String( RTL_CONSTASCII_USTRINGPARAM("TT_EOL:") ); break;
+/*?*/ // case TT_COMMENT: aOut = String( RTL_CONSTASCII_USTRINGPARAM("TT_COMMENT:") ); break;
+/*?*/ // case TT_ERROR: aOut = String( RTL_CONSTASCII_USTRINGPARAM("TT_ERROR:") ); break;
+/*?*/ // case TT_OPERATOR: aOut = String( RTL_CONSTASCII_USTRINGPARAM("TT_OPERATOR:") ); break;
+/*?*/ // case TT_KEYWORD: aOut = String( RTL_CONSTASCII_USTRINGPARAM("TT_KEYWORD:") ); break;
+/*?*/ // }
+/*?*/ // if( eType != TT_EOL )
+/*?*/ // {
+/*?*/ // aOut += String( pStartPos, (USHORT)( pEndPos - pStartPos ) );
+/*?*/ // }
+/*?*/ // aOut += String( RTL_CONSTASCII_USTRINGPARAM("\n") );
+/*?*/ // return aOut;
+/*?*/ // }
+/*?*/ // #endif
+/*?*/ //
+/*?*/ // SimpleTokenizer_Impl::SimpleTokenizer_Impl( void )
+/*?*/ // {
+/*?*/ // memset( aCharTypeTab, 0, sizeof( aCharTypeTab ) );
+/*?*/ //
+/*?*/ // // Zeichen-Tabelle fuellen
+/*?*/ // USHORT i;
+/*?*/ //
+/*?*/ // // Zulaessige Zeichen fuer Identifier
+/*?*/ // USHORT nHelpMask = (USHORT)( CHAR_START_IDENTIFIER | CHAR_IN_IDENTIFIER );
+/*?*/ // for( i = 'a' ; i <= 'z' ; i++ )
+/*?*/ // aCharTypeTab[i] |= nHelpMask;
+/*?*/ // for( i = 'A' ; i <= 'Z' ; i++ )
+/*?*/ // aCharTypeTab[i] |= nHelpMask;
+/*?*/ // // '_' extra eintragen
+/*?*/ // aCharTypeTab[(int)'_'] |= nHelpMask;
+/*?*/ // // AB 23.6.97: '$' ist auch erlaubt
+/*?*/ // aCharTypeTab[(int)'$'] |= nHelpMask;
+/*?*/ //
+/*?*/ // // Ziffern (Identifier und Number ist moeglich)
+/*?*/ // nHelpMask = (USHORT)( CHAR_IN_IDENTIFIER | CHAR_START_NUMBER |
+/*?*/ // CHAR_IN_NUMBER | CHAR_IN_HEX_NUMBER );
+/*?*/ // for( i = '0' ; i <= '9' ; i++ )
+/*?*/ // aCharTypeTab[i] |= nHelpMask;
+/*?*/ //
+/*?*/ // // e und E sowie . von Hand ergaenzen
+/*?*/ // aCharTypeTab[(int)'e'] |= CHAR_IN_NUMBER;
+/*?*/ // aCharTypeTab[(int)'E'] |= CHAR_IN_NUMBER;
+/*?*/ // aCharTypeTab[(int)'.'] |= (USHORT)( CHAR_IN_NUMBER | CHAR_START_NUMBER );
+/*?*/ // aCharTypeTab[(int)'&'] |= CHAR_START_NUMBER;
+/*?*/ //
+/*?*/ // // Hex-Ziffern
+/*?*/ // for( i = 'a' ; i <= 'f' ; i++ )
+/*?*/ // aCharTypeTab[i] |= CHAR_IN_HEX_NUMBER;
+/*?*/ // for( i = 'A' ; i <= 'F' ; i++ )
+/*?*/ // aCharTypeTab[i] |= CHAR_IN_HEX_NUMBER;
+/*?*/ //
+/*?*/ // // Oct-Ziffern
+/*?*/ // for( i = '0' ; i <= '7' ; i++ )
+/*?*/ // aCharTypeTab[i] |= CHAR_IN_OCT_NUMBER;
+/*?*/ //
+/*?*/ // // String-Beginn/End-Zeichen
+/*?*/ // aCharTypeTab[(int)'\''] |= CHAR_START_STRING;
+/*?*/ // aCharTypeTab[(int)'\"'] |= CHAR_START_STRING;
+/*?*/ // aCharTypeTab[(int)'['] |= CHAR_START_STRING;
+/*?*/ //
+/*?*/ // // Operator-Zeichen
+/*?*/ // aCharTypeTab[(int)'!'] |= CHAR_OPERATOR;
+/*?*/ // aCharTypeTab[(int)'%'] |= CHAR_OPERATOR;
+/*?*/ // // aCharTypeTab[(int)'&'] |= CHAR_OPERATOR; Removed because of #i14140
+/*?*/ // aCharTypeTab[(int)'('] |= CHAR_OPERATOR;
+/*?*/ // aCharTypeTab[(int)')'] |= CHAR_OPERATOR;
+/*?*/ // aCharTypeTab[(int)'*'] |= CHAR_OPERATOR;
+/*?*/ // aCharTypeTab[(int)'+'] |= CHAR_OPERATOR;
+/*?*/ // aCharTypeTab[(int)','] |= CHAR_OPERATOR;
+/*?*/ // aCharTypeTab[(int)'-'] |= CHAR_OPERATOR;
+/*?*/ // aCharTypeTab[(int)'/'] |= CHAR_OPERATOR;
+/*?*/ // aCharTypeTab[(int)':'] |= CHAR_OPERATOR;
+/*?*/ // aCharTypeTab[(int)'<'] |= CHAR_OPERATOR;
+/*?*/ // aCharTypeTab[(int)'='] |= CHAR_OPERATOR;
+/*?*/ // aCharTypeTab[(int)'>'] |= CHAR_OPERATOR;
+/*?*/ // aCharTypeTab[(int)'?'] |= CHAR_OPERATOR;
+/*?*/ // aCharTypeTab[(int)'^'] |= CHAR_OPERATOR;
+/*?*/ // aCharTypeTab[(int)'|'] |= CHAR_OPERATOR;
+/*?*/ // aCharTypeTab[(int)'~'] |= CHAR_OPERATOR;
+/*?*/ // aCharTypeTab[(int)'{'] |= CHAR_OPERATOR;
+/*?*/ // aCharTypeTab[(int)'}'] |= CHAR_OPERATOR;
+/*?*/ // // aCharTypeTab[(int)'['] |= CHAR_OPERATOR; Removed because of #i17826
+/*?*/ // aCharTypeTab[(int)']'] |= CHAR_OPERATOR;
+/*?*/ // aCharTypeTab[(int)';'] |= CHAR_OPERATOR;
+/*?*/ //
+/*?*/ // // Space
+/*?*/ // aCharTypeTab[(int)' ' ] |= CHAR_SPACE;
+/*?*/ // aCharTypeTab[(int)'\t'] |= CHAR_SPACE;
+/*?*/ //
+/*?*/ // // Zeilen-Ende-Zeichen
+/*?*/ // aCharTypeTab[(int)'\r'] |= CHAR_EOL;
+/*?*/ // aCharTypeTab[(int)'\n'] |= CHAR_EOL;
+/*?*/ //
+/*?*/ // ppListKeyWords = NULL;
+/*?*/ // }
+/*?*/ //
+/*?*/ // SimpleTokenizer_Impl::~SimpleTokenizer_Impl( void )
+/*?*/ // {
+/*?*/ // }
+/*?*/ //
+/*?*/ // SimpleTokenizer_Impl* getSimpleTokenizer( void )
+/*?*/ // {
+/*?*/ // static SimpleTokenizer_Impl* pSimpleTokenizer = NULL;
+/*?*/ // if( !pSimpleTokenizer )
+/*?*/ // pSimpleTokenizer = new SimpleTokenizer_Impl();
+/*?*/ // return pSimpleTokenizer;
+/*?*/ // }
+/*?*/ //
+/*?*/ // // Heraussuchen der jeweils naechsten Funktion aus einem JavaScript-Modul
+/*?*/ // UINT16 SimpleTokenizer_Impl::parseLine( UINT32 nParseLine, const String* aSource )
+/*?*/ // {
+/*?*/ // // Position auf den Anfang des Source-Strings setzen
+/*?*/ // mpStringBegin = mpActualPos = aSource->GetBuffer();
+/*?*/ //
+/*?*/ // // Zeile und Spalte initialisieren
+/*?*/ // nLine = nParseLine;
+/*?*/ // nCol = 0L;
+/*?*/ //
+/*?*/ // // Variablen fuer die Out-Parameter
+/*?*/ // TokenTypes eType;
+/*?*/ // const sal_Unicode* pStartPos;
+/*?*/ // const sal_Unicode* pEndPos;
+/*?*/ //
+/*?*/ // // Schleife ueber alle Tokens
+/*?*/ // UINT16 nTokenCount = 0;
+/*?*/ // while( getNextToken( eType, pStartPos, pEndPos ) )
+/*?*/ // nTokenCount++;
+/*?*/ //
+/*?*/ // return nTokenCount;
+/*?*/ // }
+/*?*/ //
+/*?*/ // void SimpleTokenizer_Impl::getHighlightPortions( UINT32 nParseLine, const String& rLine,
+/*?*/ // /*out*/HighlightPortions& portions )
+/*?*/ // {
+/*?*/ // // Position auf den Anfang des Source-Strings setzen
+/*?*/ // mpStringBegin = mpActualPos = rLine.GetBuffer();
+/*?*/ //
+/*?*/ // // Zeile und Spalte initialisieren
+/*?*/ // nLine = nParseLine;
+/*?*/ // nCol = 0L;
+/*?*/ //
+/*?*/ // // Variablen fuer die Out-Parameter
+/*?*/ // TokenTypes eType;
+/*?*/ // const sal_Unicode* pStartPos;
+/*?*/ // const sal_Unicode* pEndPos;
+/*?*/ //
+/*?*/ // // Schleife ueber alle Tokens
+/*?*/ // while( getNextToken( eType, pStartPos, pEndPos ) )
+/*?*/ // {
+/*?*/ // HighlightPortion portion;
+/*?*/ //
+/*?*/ // portion.nBegin = (UINT16)(pStartPos - mpStringBegin);
+/*?*/ // portion.nEnd = (UINT16)(pEndPos - mpStringBegin);
+/*?*/ // portion.tokenType = eType;
+/*?*/ //
+/*?*/ // portions.Insert(portion, portions.Count());
+/*?*/ // }
+/*?*/ // }
+
+
+/*?*/ // //////////////////////////////////////////////////////////////////////////
+/*?*/ // // Implementierung des SyntaxHighlighter
+/*?*/ //
+/*?*/ // SyntaxHighlighter::SyntaxHighlighter()
+/*?*/ // {
+/*?*/ // m_pSimpleTokenizer = new SimpleTokenizer_Impl();
+/*?*/ // m_pKeyWords = NULL;
+/*?*/ // m_nKeyWordCount = 0;
+/*?*/ // }
+/*?*/ //
+/*?*/ // SyntaxHighlighter::~SyntaxHighlighter()
+/*?*/ // {
+/*?*/ // delete(m_pSimpleTokenizer);
+/*?*/ // delete(m_pKeyWords);
+/*?*/ // }
+/*?*/ //
+/*?*/ // void SyntaxHighlighter::initialize( HighlighterLanguage eLanguage_ )
+/*?*/ // {
+/*?*/ // eLanguage = eLanguage_;
+/*?*/ // delete(m_pSimpleTokenizer);
+/*?*/ // m_pSimpleTokenizer = new SimpleTokenizer_Impl();
+/*?*/ //
+/*?*/ // if (eLanguage == HIGHLIGHT_BASIC)
+/*?*/ // {
+/*?*/ // m_pSimpleTokenizer->setKeyWords( strListBasicKeyWords,
+/*?*/ // sizeof( strListBasicKeyWords ) / sizeof( char* ));
+/*?*/ // }
+/*?*/ // else
+/*?*/ // {
+/*?*/ // m_pSimpleTokenizer->setKeyWords( NULL, 0 );
+/*?*/ // }
+/*?*/ // }
+/*?*/ //
+/*?*/ // const Range SyntaxHighlighter::notifyChange( UINT32 nLine, INT32 nLineCountDifference,
+/*?*/ // const String* pChangedLines, UINT32 nArrayLength)
+/*?*/ // {
+/*?*/ // (void)nLineCountDifference;
+/*?*/ //
+/*?*/ // for( UINT32 i=0 ; i < nArrayLength ; i++ )
+/*?*/ // m_pSimpleTokenizer->parseLine(nLine+i, &pChangedLines[i]);
+/*?*/ //
+/*?*/ // return Range( nLine, nLine + nArrayLength-1 );
+/*?*/ // }
+/*?*/ //
+/*?*/ // void SyntaxHighlighter::getHighlightPortions( UINT32 nLine, const String& rLine,
+/*?*/ // /*out*/HighlightPortions& portions )
+/*?*/ // {
+/*?*/ // m_pSimpleTokenizer->getHighlightPortions( nLine, rLine, portions );
+/*?*/ // }
+
+
+/////////////////////////////////////////////////////////////////////////
+// Implementation SbJScriptModule (Basic-Modul fuer JavaScript-Sourcen)
+SbJScriptModule::SbJScriptModule( const String& rName )
+ :SbModule( rName )
+{
+}
+
+BOOL SbJScriptModule::LoadData( SvStream& rStrm, USHORT nVer )
+{
+ (void)nVer;
+
+ Clear();
+ if( !SbxObject::LoadData( rStrm, 1 ) )
+ return FALSE;
+
+ // Source-String holen
+ String aTmp;
+ rStrm.ReadByteString( aTmp, gsl_getSystemTextEncoding() );
+ aOUSource = aTmp;
+ //rStrm >> aSource;
+ return TRUE;
+}
+
+BOOL SbJScriptModule::StoreData( SvStream& rStrm ) const
+{
+ if( !SbxObject::StoreData( rStrm ) )
+ return FALSE;
+
+ // Source-String schreiben
+ String aTmp = aOUSource;
+ rStrm.WriteByteString( aTmp, gsl_getSystemTextEncoding() );
+ //rStrm << aSource;
+ return TRUE;
+}
+
+
+/////////////////////////////////////////////////////////////////////////
+
+SbMethod::SbMethod( const String& r, SbxDataType t, SbModule* p )
+ : SbxMethod( r, t ), pMod( p )
+{
+ bInvalid = TRUE;
+ nStart =
+ nDebugFlags =
+ nLine1 =
+ nLine2 = 0;
+ // AB: 2.7.1996: HACK wegen 'Referenz kann nicht gesichert werden'
+ SetFlag( SBX_NO_MODIFY );
+}
+
+SbMethod::SbMethod( const SbMethod& r )
+ : SvRefBase( r ), SbxMethod( r )
+{
+ pMod = r.pMod;
+ bInvalid = r.bInvalid;
+ nStart = r.nStart;
+ nDebugFlags = r.nDebugFlags;
+ nLine1 = r.nLine1;
+ nLine2 = r.nLine2;
+ SetFlag( SBX_NO_MODIFY );
+}
+
+SbMethod::~SbMethod()
+{
+}
+
+BOOL SbMethod::LoadData( SvStream& rStrm, USHORT nVer )
+{
+ if( !SbxMethod::LoadData( rStrm, 1 ) )
+ return FALSE;
+ INT16 n;
+ rStrm >> n;
+ INT16 nTempStart = (INT16)nStart;
+ // nDebugFlags = n; // AB 16.1.96: Nicht mehr uebernehmen
+ if( nVer == 2 )
+ rStrm >> nLine1 >> nLine2 >> nTempStart >> bInvalid;
+ // AB: 2.7.1996: HACK wegen 'Referenz kann nicht gesichert werden'
+ SetFlag( SBX_NO_MODIFY );
+ nStart = nTempStart;
+ return TRUE;
+}
+
+BOOL SbMethod::StoreData( SvStream& rStrm ) const
+{
+ if( !SbxMethod::StoreData( rStrm ) )
+ return FALSE;
+ rStrm << (INT16) nDebugFlags
+ << (INT16) nLine1
+ << (INT16) nLine2
+ << (INT16) nStart
+ << (BYTE) bInvalid;
+ return TRUE;
+}
+
+// Kann spaeter mal weg
+
+SbxInfo* SbMethod::GetInfo()
+{
+ return pInfo;
+}
+
+// Schnittstelle zum Ausfuehren einer Methode aus den Applikationen
+// #34191# Mit speziellem RefCounting, damit das Basic nicht durch CloseDocument()
+// abgeschossen werden kann. Rueckgabewert wird als String geliefert.
+ErrCode SbMethod::Call( SbxValue* /*pRet*/ )
+{
+ DBG_ERROR( "SbMethod::Call: dead code!" );
+/*?*/ // // RefCount vom Modul hochzaehlen
+/*?*/ // SbModule* pMod_ = (SbModule*)GetParent();
+/*?*/ // pMod_->AddRef();
+/*?*/ //
+/*?*/ // // RefCount vom Basic hochzaehlen
+/*?*/ // StarBASIC* pBasic = (StarBASIC*)pMod_->GetParent();
+/*?*/ // pBasic->AddRef();
+/*?*/ //
+/*?*/ // // Values anlegen, um Return-Wert zu erhalten
+/*?*/ // SbxValues aVals;
+/*?*/ // aVals.eType = SbxVARIANT;
+/*?*/ //
+/*?*/ // // #104083: Compile BEFORE get
+/*?*/ // if( bInvalid && !pMod_->Compile() )
+/*?*/ // StarBASIC::Error( SbERR_BAD_PROP_VALUE );
+/*?*/ //
+/*?*/ // Get( aVals );
+/*?*/ // if ( pRet )
+/*?*/ // pRet->Put( aVals );
+/*?*/ //
+/*?*/ // // Gab es einen Error
+/*?*/ // ErrCode nErr = SbxBase::GetError();
+/*?*/ // SbxBase::ResetError();
+/*?*/ //
+/*?*/ // // Objekte freigeben
+/*?*/ // pMod_->ReleaseRef();
+/*?*/ // pBasic->ReleaseRef();
+/*?*/ //
+/*?*/ // return nErr;
+ return SbERR_NO_METHOD;
+}
+
+
+// #100883 Own Broadcast for SbMethod
+void SbMethod::Broadcast( ULONG nHintId )
+{
+ if( pCst && !IsSet( SBX_NO_BROADCAST ) && StaticIsEnabledBroadcasting() )
+ {
+ // Da die Methode von aussen aufrufbar ist, hier noch einmal
+ // die Berechtigung testen
+ if( nHintId & SBX_HINT_DATAWANTED )
+ if( !CanRead() )
+ return;
+ if( nHintId & SBX_HINT_DATACHANGED )
+ if( !CanWrite() )
+ return;
+
+ if( pMod && !pMod->IsCompiled() )
+ pMod->Compile();
+
+ // Block broadcasts while creating new method
+ SfxBroadcaster* pSave = pCst;
+ pCst = NULL;
+ SbMethod* pThisCopy = new SbMethod( *this );
+ SbMethodRef xHolder = pThisCopy;
+ if( mpPar.Is() )
+ {
+ // this, als Element 0 eintragen, aber den Parent nicht umsetzen!
+ mpPar->PutDirect( pThisCopy, 0 );
+ SetParameters( NULL );
+ }
+
+ pCst = pSave;
+ pSave->Broadcast( SbxHint( nHintId, pThisCopy ) );
+
+ USHORT nSaveFlags = GetFlags();
+ SetFlag( SBX_READWRITE );
+ pCst = NULL;
+ Put( pThisCopy->GetValues_Impl() );
+ pCst = pSave;
+ SetFlags( nSaveFlags );
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+// Implementation SbJScriptMethod (Method-Klasse als Wrapper fuer JavaScript-Funktionen)
+
+SbJScriptMethod::SbJScriptMethod( const String& r, SbxDataType t, SbModule* p )
+ : SbMethod( r, t, p )
+{
+}
+
+SbJScriptMethod::~SbJScriptMethod()
+{}
+
+
+/////////////////////////////////////////////////////////////////////////
+
+SbProperty::SbProperty( const String& r, SbxDataType t, SbModule* p )
+ : SbxProperty( r, t ), pMod( p )
+{
+ bInvalid = FALSE;
+}
+
+SbProperty::~SbProperty()
+{}
+
+/////////////////////////////////////////////////////////////////////////
+
+SbProcedureProperty::~SbProcedureProperty()
+{}
+
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/comp/buffer.cxx b/binfilter/bf_basic/source/comp/buffer.cxx
new file mode 100644
index 000000000000..7a2a65c845fb
--- /dev/null
+++ b/binfilter/bf_basic/source/comp/buffer.cxx
@@ -0,0 +1,173 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "buffer.hxx"
+#include <string.h>
+
+namespace binfilter {
+
+const static UINT32 UP_LIMIT=0xFFFFFF00L;
+
+// Der SbiBuffer wird in Inkrements von mindestens 16 Bytes erweitert.
+// Dies ist notwendig, da viele Klassen von einer Pufferlaenge
+// von x*16 Bytes ausgehen.
+
+SbiBuffer::SbiBuffer( SbiParser* p, short n )
+{
+ pParser = p;
+ n = ( (n + 15 ) / 16 ) * 16;
+ if( !n ) n = 16;
+ pBuf = NULL;
+ pCur = NULL;
+ nInc = n;
+ nSize =
+ nOff = 0;
+}
+
+SbiBuffer::~SbiBuffer()
+{
+ delete[] pBuf;
+}
+
+// Rausreichen des Puffers
+// Dies fuehrt zur Loeschung des Puffers!
+
+char* SbiBuffer::GetBuffer()
+{
+ char* p = pBuf;
+ pBuf = NULL;
+ pCur = NULL;
+ return p;
+}
+
+// Test, ob der Puffer n Bytes aufnehmen kann.
+// Im Zweifelsfall wird er vergroessert
+
+BOOL SbiBuffer::Check( USHORT n )
+{
+ if( !n ) return TRUE;
+ if( ( static_cast<UINT32>( nOff )+ n ) > static_cast<UINT32>( nSize ) )
+ {
+ if( nInc == 0 )
+ return FALSE;
+ USHORT nn = 0;
+ while( nn < n ) nn = nn + nInc;
+ char* p;
+ if( ( static_cast<UINT32>( nSize ) + nn ) > UP_LIMIT ) p = NULL;
+ else p = new char [nSize + nn];
+ if( !p )
+ {
+/*?*/ // pParser->Error( SbERR_PROG_TOO_LARGE );
+ nInc = 0;
+ delete[] pBuf; pBuf = NULL;
+ return FALSE;
+ }
+ else
+ {
+ if( nSize ) memcpy( p, pBuf, nSize );
+ delete[] pBuf;
+ pBuf = p;
+ pCur = pBuf + nOff;
+ nSize = nSize + nn;
+ }
+ }
+ return TRUE;
+}
+
+BOOL SbiBuffer::operator +=( INT8 n )
+{
+ if( Check( 1 ) )
+ {
+ *pCur++ = (char) n; nOff++; return TRUE;
+ } else return FALSE;
+}
+
+BOOL SbiBuffer::operator +=( UINT8 n )
+{
+ if( Check( 1 ) )
+ {
+ *pCur++ = (char) n; nOff++; return TRUE;
+ } else return FALSE;
+}
+
+BOOL SbiBuffer::operator +=( INT16 n )
+{
+ if( Check( 2 ) )
+ {
+ *pCur++ = (char) ( n & 0xFF );
+ *pCur++ = (char) ( n >> 8 );
+ nOff += 2; return TRUE;
+ } else return FALSE;
+}
+
+BOOL SbiBuffer::operator +=( UINT16 n )
+{
+ if( Check( 2 ) )
+ {
+ *pCur++ = (char) ( n & 0xFF );
+ *pCur++ = (char) ( n >> 8 );
+ nOff += 2; return TRUE;
+ } else return FALSE;
+}
+
+BOOL SbiBuffer::operator +=( UINT32 n )
+{
+ if( Check( 4 ) )
+ {
+ UINT16 n1 = static_cast<UINT16>( n & 0xFFFF );
+ UINT16 n2 = static_cast<UINT16>( n >> 16 );
+ if ( operator +=( n1 ) && operator +=( n2 ) )
+ return TRUE;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+BOOL SbiBuffer::operator +=( INT32 n )
+{
+ return operator +=( (UINT32) n );
+}
+
+
+BOOL SbiBuffer::operator +=( const String& n )
+{
+ USHORT l = n.Len() + 1;
+ if( Check( l ) )
+ {
+ ByteString aByteStr( n, gsl_getSystemTextEncoding() );
+ memcpy( pCur, aByteStr.GetBuffer(), l );
+ pCur += l;
+ nOff = nOff + l;
+ return TRUE;
+ }
+ else return FALSE;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/comp/codegen.cxx b/binfilter/bf_basic/source/comp/codegen.cxx
new file mode 100644
index 000000000000..7016206b345a
--- /dev/null
+++ b/binfilter/bf_basic/source/comp/codegen.cxx
@@ -0,0 +1,232 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "sbx.hxx"
+#include "image.hxx"
+#include "buffer.hxx"
+#include "opcodes.hxx"
+#include "codegen.hxx"
+#include <limits>
+
+namespace binfilter {
+
+template < class T >
+class PCodeVisitor
+{
+public:
+ virtual ~PCodeVisitor();
+
+ virtual void start( BYTE* pStart ) = 0;
+ virtual void processOpCode0( SbiOpcode eOp ) = 0;
+ virtual void processOpCode1( SbiOpcode eOp, T nOp1 ) = 0;
+ virtual void processOpCode2( SbiOpcode eOp, T nOp1, T nOp2 ) = 0;
+ virtual bool processParams() = 0;
+ virtual void end() = 0;
+};
+
+template <class T> PCodeVisitor< T >::~PCodeVisitor()
+{}
+
+template <class T>
+class PCodeBufferWalker
+{
+private:
+ T m_nBytes;
+ BYTE* m_pCode;
+ T readParam( BYTE*& pCode )
+ {
+ short nBytes = sizeof( T );
+ T nOp1=0;
+ for ( int i=0; i<nBytes; ++i )
+ nOp1 |= *pCode++ << ( i * 8);
+ return nOp1;
+ }
+public:
+ PCodeBufferWalker( BYTE* pCode, T nBytes ): m_nBytes( nBytes ), m_pCode( pCode )
+ {
+ }
+ void visitBuffer( PCodeVisitor< T >& visitor )
+ {
+ BYTE* pCode = m_pCode;
+ if ( !pCode )
+ return;
+ BYTE* pEnd = pCode + m_nBytes;
+ visitor.start( m_pCode );
+ T nOp1 = 0, nOp2 = 0;
+ for( ; pCode < pEnd; )
+ {
+ SbiOpcode eOp = (SbiOpcode)(*pCode++);
+
+ if ( eOp <= SbOP0_END )
+ visitor.processOpCode0( eOp );
+ else if( eOp >= SbOP1_START && eOp <= SbOP1_END )
+ {
+ if ( visitor.processParams() )
+ nOp1 = readParam( pCode );
+ else
+ pCode += sizeof( T );
+ visitor.processOpCode1( eOp, nOp1 );
+ }
+ else if( eOp >= SbOP2_START && eOp <= SbOP2_END )
+ {
+ if ( visitor.processParams() )
+ {
+ nOp1 = readParam( pCode );
+ nOp2 = readParam( pCode );
+ }
+ else
+ pCode += ( sizeof( T ) * 2 );
+ visitor.processOpCode2( eOp, nOp1, nOp2 );
+ }
+ }
+ visitor.end();
+ }
+};
+
+template < class T, class S >
+class OffSetAccumulator : public PCodeVisitor< T >
+{
+ T m_nNumOp0;
+ T m_nNumSingleParams;
+ T m_nNumDoubleParams;
+public:
+
+ OffSetAccumulator() : m_nNumOp0(0), m_nNumSingleParams(0), m_nNumDoubleParams(0){}
+ virtual void start( BYTE* /*pStart*/ ){}
+ virtual void processOpCode0( SbiOpcode /*eOp*/ ){ ++m_nNumOp0; }
+ virtual void processOpCode1( SbiOpcode /*eOp*/, T /*nOp1*/ ){ ++m_nNumSingleParams; }
+ virtual void processOpCode2( SbiOpcode /*eOp*/, T /*nOp1*/, T /*nOp2*/ ) { ++m_nNumDoubleParams; }
+ virtual void end(){}
+ S offset()
+ {
+ T result = 0 ;
+ static const S max = std::numeric_limits< S >::max();
+ result = m_nNumOp0 + ( ( sizeof(S) + 1 ) * m_nNumSingleParams ) + ( (( sizeof(S) * 2 )+ 1 ) * m_nNumDoubleParams );
+ if ( result > max )
+ return max;
+
+ return static_cast<S>(result);
+ }
+ virtual bool processParams(){ return false; }
+};
+
+template < class T, class S >
+class BufferTransformer : public PCodeVisitor< T >
+{
+ BYTE* m_pStart;
+ SbiBuffer m_ConvertedBuf;
+public:
+ BufferTransformer():m_pStart(NULL), m_ConvertedBuf( NULL, 1024 ) {}
+ virtual void start( BYTE* pStart ){ m_pStart = pStart; }
+ virtual void processOpCode0( SbiOpcode eOp )
+ {
+ m_ConvertedBuf += (UINT8)eOp;
+ }
+ virtual void processOpCode1( SbiOpcode eOp, T nOp1 )
+ {
+ m_ConvertedBuf += (UINT8)eOp;
+ switch( eOp )
+ {
+ case _JUMP:
+ case _JUMPT:
+ case _JUMPF:
+ case _GOSUB:
+ case _CASEIS:
+ case _RETURN:
+ case _ERRHDL:
+ case _TESTFOR:
+ nOp1 = static_cast<T>( convertBufferOffSet(m_pStart, nOp1) );
+ break;
+ case _RESUME:
+ if ( nOp1 > 1 )
+ nOp1 = static_cast<T>( convertBufferOffSet(m_pStart, nOp1) );
+ break;
+ default:
+ break; //
+
+ }
+ m_ConvertedBuf += (S)nOp1;
+ }
+ virtual void processOpCode2( SbiOpcode eOp, T nOp1, T nOp2 )
+ {
+ m_ConvertedBuf += (UINT8)eOp;
+ if ( eOp == _CASEIS )
+ if ( nOp1 )
+ nOp1 = static_cast<T>( convertBufferOffSet(m_pStart, nOp1) );
+ m_ConvertedBuf += (S)nOp1;
+ m_ConvertedBuf += (S)nOp2;
+
+ }
+ virtual bool processParams(){ return true; }
+ virtual void end() {}
+ // yeuch, careful here, you can only call
+ // GetBuffer on the returned SbiBuffer once, also
+ // you (as the caller) get to own the memory
+ SbiBuffer& buffer()
+ {
+ return m_ConvertedBuf;
+ }
+ static S convertBufferOffSet( BYTE* pStart, T nOp1 )
+ {
+ PCodeBufferWalker< T > aBuff( pStart, nOp1);
+ OffSetAccumulator< T, S > aVisitor;
+ aBuff.visitBuffer( aVisitor );
+ return aVisitor.offset();
+ }
+};
+
+UINT32
+SbiCodeGen::calcNewOffSet( BYTE* pCode, UINT16 nOffset )
+{
+ return BufferTransformer< UINT16, UINT32 >::convertBufferOffSet( pCode, nOffset );
+}
+
+UINT16
+SbiCodeGen::calcLegacyOffSet( BYTE* pCode, UINT32 nOffset )
+{
+ return BufferTransformer< UINT32, UINT16 >::convertBufferOffSet( pCode, nOffset );
+}
+
+template <class T, class S>
+void
+PCodeBuffConvertor<T,S>::convert()
+{
+ PCodeBufferWalker< T > aBuf( m_pStart, m_nSize );
+ BufferTransformer< T, S > aTrnsfrmer;
+ aBuf.visitBuffer( aTrnsfrmer );
+ m_pCnvtdBuf = (BYTE*)aTrnsfrmer.buffer().GetBuffer();
+ m_nCnvtdSize = static_cast<S>( aTrnsfrmer.buffer().GetSize() );
+}
+
+// instantiate for types needed in SbiImage::Load and SbiImage::Save
+template class PCodeBuffConvertor<UINT16, UINT32 >;
+template class PCodeBuffConvertor<UINT32, UINT16>;
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/comp/makefile.mk b/binfilter/bf_basic/source/comp/makefile.mk
new file mode 100644
index 000000000000..3e7377cdd8f4
--- /dev/null
+++ b/binfilter/bf_basic/source/comp/makefile.mk
@@ -0,0 +1,64 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=binfilter
+TARGET=basic_comp
+
+NO_HIDS=TRUE
+
+# --- Settings ------------------------------------------------------------
+
+.INCLUDE : settings.mk
+
+INC+= -I$(PRJ)$/inc$/bf_basic
+
+# --- Allgemein -----------------------------------------------------------
+
+EXCEPTIONSFILES=
+#EXCEPTIONSFILES=$(SLO)$/parser.obj
+
+SLOFILES= \
+ $(EXCEPTIONSFILES) \
+ $(SLO)$/codegen.obj \
+ $(SLO)$/token.obj \
+ $(SLO)$/scanner.obj \
+ $(SLO)$/buffer.obj \
+ $(SLO)$/sbcomp.obj \
+
+# $(SLO)$/dim.obj \
+ $(SLO)$/exprtree.obj \
+ $(SLO)$/exprnode.obj \
+ $(SLO)$/exprgen.obj \
+ $(SLO)$/io.obj \
+ $(SLO)$/loops.obj \
+ $(SLO)$/symtbl.obj \
+
+# --- Targets --------------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/binfilter/bf_basic/source/comp/parser.cxx b/binfilter/bf_basic/source/comp/parser.cxx
new file mode 100644
index 000000000000..e68ad6467b3a
--- /dev/null
+++ b/binfilter/bf_basic/source/comp/parser.cxx
@@ -0,0 +1,872 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_basic.hxx"
+
+#include <sbx.hxx>
+#include "sbcomp.hxx"
+
+struct SbiParseStack { // "Stack" fuer Statement-Blocks
+ SbiParseStack* pNext; // Chain
+ SbiExprNode* pWithVar; // Variable fuer WITH
+ SbiToken eExitTok; // Exit-Token
+ UINT32 nChain; // JUMP-Chain
+};
+
+struct SbiStatement {
+ SbiToken eTok;
+ void( SbiParser::*Func )(); // Verarbeitungsroutine
+ BOOL bMain; // TRUE: ausserhalb SUBs OK
+ BOOL bSubr; // TRUE: in SUBs OK
+};
+
+#define Y TRUE
+#define N FALSE
+
+static SbiStatement StmntTable [] = {
+{ CALL, &SbiParser::Call, N, Y, }, // CALL
+{ CLOSE, &SbiParser::Close, N, Y, }, // CLOSE
+{ _CONST_, &SbiParser::Dim, Y, Y, }, // CONST
+{ DECLARE, &SbiParser::Declare, Y, N, }, // DECLARE
+{ DEFBOOL, &SbiParser::DefXXX, Y, N, }, // DEFBOOL
+{ DEFCUR, &SbiParser::DefXXX, Y, N, }, // DEFCUR
+{ DEFDATE, &SbiParser::DefXXX, Y, N, }, // DEFDATE
+{ DEFDBL, &SbiParser::DefXXX, Y, N, }, // DEFDBL
+{ DEFERR, &SbiParser::DefXXX, Y, N, }, // DEFERR
+{ DEFINT, &SbiParser::DefXXX, Y, N, }, // DEFINT
+{ DEFLNG, &SbiParser::DefXXX, Y, N, }, // DEFLNG
+{ DEFOBJ, &SbiParser::DefXXX, Y, N, }, // DEFOBJ
+{ DEFSNG, &SbiParser::DefXXX, Y, N, }, // DEFSNG
+{ DEFSTR, &SbiParser::DefXXX, Y, N, }, // DEFSTR
+{ DEFVAR, &SbiParser::DefXXX, Y, N, }, // DEFVAR
+{ DIM, &SbiParser::Dim, Y, Y, }, // DIM
+{ DO, &SbiParser::DoLoop, N, Y, }, // DO
+{ ELSE, &SbiParser::NoIf, N, Y, }, // ELSE
+{ ELSEIF, &SbiParser::NoIf, N, Y, }, // ELSEIF
+{ ENDIF, &SbiParser::NoIf, N, Y, }, // ENDIF
+{ END, &SbiParser::Stop, N, Y, }, // END
+{ ENUM, &SbiParser::Enum, Y, N, }, // TYPE
+{ ERASE, &SbiParser::Erase, N, Y, }, // ERASE
+{ _ERROR_, &SbiParser::ErrorStmnt, N, Y, }, // ERROR
+{ EXIT, &SbiParser::Exit, N, Y, }, // EXIT
+{ FOR, &SbiParser::For, N, Y, }, // FOR
+{ FUNCTION, &SbiParser::SubFunc, Y, N, }, // FUNCTION
+{ GOSUB, &SbiParser::Goto, N, Y, }, // GOSUB
+{ GLOBAL, &SbiParser::Dim, Y, N, }, // GLOBAL
+{ GOTO, &SbiParser::Goto, N, Y, }, // GOTO
+{ IF, &SbiParser::If, N, Y, }, // IF
+{ IMPLEMENTS, &SbiParser::Implements, Y, N, }, // IMPLEMENTS
+{ INPUT, &SbiParser::Input, N, Y, }, // INPUT
+{ LET, &SbiParser::Assign, N, Y, }, // LET
+{ LINEINPUT,&SbiParser::LineInput, N, Y, }, // LINE INPUT
+{ LOOP, &SbiParser::BadBlock, N, Y, }, // LOOP
+{ LSET, &SbiParser::LSet, N, Y, }, // LSET
+{ NAME, &SbiParser::Name, N, Y, }, // NAME
+{ NEXT, &SbiParser::BadBlock, N, Y, }, // NEXT
+{ ON, &SbiParser::On, N, Y, }, // ON
+{ OPEN, &SbiParser::Open, N, Y, }, // OPEN
+{ OPTION, &SbiParser::Option, Y, N, }, // OPTION
+{ PRINT, &SbiParser::Print, N, Y, }, // PRINT
+{ PRIVATE, &SbiParser::Dim, Y, N, }, // PRIVATE
+{ PROPERTY, &SbiParser::SubFunc, Y, N, }, // FUNCTION
+{ PUBLIC, &SbiParser::Dim, Y, N, }, // PUBLIC
+{ REDIM, &SbiParser::ReDim, N, Y, }, // DIM
+{ RESUME, &SbiParser::Resume, N, Y, }, // RESUME
+{ RETURN, &SbiParser::Return, N, Y, }, // RETURN
+{ RSET, &SbiParser::RSet, N, Y, }, // RSET
+{ SELECT, &SbiParser::Select, N, Y, }, // SELECT
+{ SET, &SbiParser::Set, N, Y, }, // SET
+{ STATIC, &SbiParser::Static, Y, Y, }, // STATIC
+{ STOP, &SbiParser::Stop, N, Y, }, // STOP
+{ SUB, &SbiParser::SubFunc, Y, N, }, // SUB
+{ TYPE, &SbiParser::Type, Y, N, }, // TYPE
+{ UNTIL, &SbiParser::BadBlock, N, Y, }, // UNTIL
+{ WHILE, &SbiParser::While, N, Y, }, // WHILE
+{ WEND, &SbiParser::BadBlock, N, Y, }, // WEND
+{ WITH, &SbiParser::With, N, Y, }, // WITH
+{ WRITE, &SbiParser::Write, N, Y, }, // WRITE
+
+{ NIL, NULL, N, N }
+};
+
+
+#ifdef MSC
+// 'this' : used in base member initializer list
+#pragma warning( disable: 4355 )
+#endif
+
+SbiParser::SbiParser( StarBASIC* pb, SbModule* pm )
+ : SbiTokenizer( pm->GetSource32(), pb ),
+ aGblStrings( this ),
+ aLclStrings( this ),
+ aGlobals( aGblStrings, SbGLOBAL ),
+ aPublics( aGblStrings, SbPUBLIC ),
+ aRtlSyms( aGblStrings, SbRTL ),
+ aGen( *pm, this, 1024 )
+{
+ pBasic = pb;
+ eCurExpr = SbSYMBOL;
+ eEndTok = NIL;
+ pProc = NULL;
+ pStack = NULL;
+ pWithVar = NULL;
+ nBase = 0;
+ bText =
+ bGblDefs =
+ bNewGblDefs =
+ bSingleLineIf =
+ bExplicit = FALSE;
+ bClassModule = FALSE;
+ bVBASupportOn = FALSE;
+ pPool = &aPublics;
+ for( short i = 0; i < 26; i++ )
+ eDefTypes[ i ] = SbxVARIANT; // Kein expliziter Defaulttyp
+
+ aPublics.SetParent( &aGlobals );
+ aGlobals.SetParent( &aRtlSyms );
+
+ // Die globale Chainkette faengt bei Adresse 0 an:
+ nGblChain = aGen.Gen( _JUMP, 0 );
+
+ rTypeArray = new SbxArray; // Array fuer Benutzerdefinierte Typen
+ rEnumArray = new SbxArray; // Array for Enum types
+}
+
+
+// Ist Teil der Runtime-Library?
+SbiSymDef* SbiParser::CheckRTLForSym( const String& rSym, SbxDataType eType )
+{
+ SbxVariable* pVar = GetBasic()->GetRtl()->Find( rSym, SbxCLASS_DONTCARE );
+ SbiSymDef* pDef = NULL;
+ if( pVar )
+ {
+ if( pVar->IsA( TYPE(SbxMethod) ) )
+ {
+ SbiProcDef* pProc_ = aRtlSyms.AddProc( rSym );
+ pProc_->SetType( pVar->GetType() );
+ pDef = pProc_;
+ }
+ else
+ {
+ pDef = aRtlSyms.AddSym( rSym );
+ pDef->SetType( eType );
+ }
+ }
+ return pDef;
+}
+
+// Globale Chainkette schliessen
+
+BOOL SbiParser::HasGlobalCode()
+{
+ if( bGblDefs && nGblChain )
+ {
+ aGen.BackChain( nGblChain );
+ aGen.Gen( _LEAVE );
+ // aGen.Gen( _STOP );
+ nGblChain = 0;
+ }
+ return bGblDefs;
+}
+
+void SbiParser::OpenBlock( SbiToken eTok, SbiExprNode* pVar )
+{
+ SbiParseStack* p = new SbiParseStack;
+ p->eExitTok = eTok;
+ p->nChain = 0;
+ p->pWithVar = pWithVar;
+ p->pNext = pStack;
+ pStack = p;
+ pWithVar = pVar;
+
+ // #29955 for-Schleifen-Ebene pflegen
+ if( eTok == FOR )
+ aGen.IncForLevel();
+}
+
+void SbiParser::CloseBlock()
+{
+ if( pStack )
+ {
+ SbiParseStack* p = pStack;
+
+ // #29955 for-Schleifen-Ebene pflegen
+ if( p->eExitTok == FOR )
+ aGen.DecForLevel();
+
+ aGen.BackChain( p->nChain );
+ pStack = p->pNext;
+ pWithVar = p->pWithVar;
+ delete p;
+ }
+}
+
+// EXIT ...
+
+void SbiParser::Exit()
+{
+ SbiToken eTok = Next();
+ for( SbiParseStack* p = pStack; p; p = p->pNext )
+ {
+ if( eTok == p->eExitTok )
+ {
+ p->nChain = aGen.Gen( _JUMP, p->nChain );
+ return;
+ }
+ }
+ if( pStack )
+ Error( SbERR_EXPECTED, pStack->eExitTok );
+ else
+ Error( SbERR_BAD_EXIT );
+}
+
+BOOL SbiParser::TestSymbol( BOOL bKwdOk )
+{
+ Peek();
+ if( eCurTok == SYMBOL || ( bKwdOk && IsKwd( eCurTok ) ) )
+ {
+ Next(); return TRUE;
+ }
+ Error( SbERR_SYMBOL_EXPECTED );
+ return FALSE;
+}
+
+// Testen auf ein bestimmtes Token
+
+BOOL SbiParser::TestToken( SbiToken t )
+{
+ if( Peek() == t )
+ {
+ Next(); return TRUE;
+ }
+ else
+ {
+ Error( SbERR_EXPECTED, t );
+ return FALSE;
+ }
+}
+
+// Testen auf Komma oder EOLN
+
+BOOL SbiParser::TestComma()
+{
+ SbiToken eTok = Peek();
+ if( IsEoln( eTok ) )
+ {
+ Next();
+ return FALSE;
+ }
+ else if( eTok != COMMA )
+ {
+ Error( SbERR_EXPECTED, COMMA );
+ return FALSE;
+ }
+ Next();
+ return TRUE;
+}
+
+// Testen, ob EOLN vorliegt
+
+void SbiParser::TestEoln()
+{
+ if( !IsEoln( Next() ) )
+ {
+ Error( SbERR_EXPECTED, EOLN );
+ while( !IsEoln( Next() ) ) {}
+ }
+}
+
+// Parsing eines Statement-Blocks
+// Das Parsing laeuft bis zum Ende-Token.
+
+void SbiParser::StmntBlock( SbiToken eEnd )
+{
+ SbiToken xe = eEndTok;
+ eEndTok = eEnd;
+ while( !bAbort && Parse() ) {}
+ eEndTok = xe;
+ if( IsEof() )
+ {
+ Error( SbERR_BAD_BLOCK, eEnd );
+ bAbort = TRUE;
+ }
+}
+
+// Die Hauptroutine. Durch wiederholten Aufrufs dieser Routine wird
+// die Quelle geparst. Returnwert FALSE bei Ende/Fehlern.
+
+BOOL SbiParser::Parse()
+{
+ if( bAbort ) return FALSE;
+
+ EnableErrors();
+
+ bErrorIsSymbol = false;
+ Peek();
+ bErrorIsSymbol = true;
+ // Dateiende?
+ if( IsEof() )
+ {
+ // AB #33133: Falls keine Sub angelegt wurde, muss hier
+ // der globale Chain abgeschlossen werden!
+ // AB #40689: Durch die neue static-Behandlung kann noch
+ // ein nGblChain vorhanden sein, daher vorher abfragen
+ if( bNewGblDefs && nGblChain == 0 )
+ nGblChain = aGen.Gen( _JUMP, 0 );
+ return FALSE;
+ }
+
+ // Leerstatement?
+ if( IsEoln( eCurTok ) )
+ {
+ Next(); return TRUE;
+ }
+
+ if( !bSingleLineIf && MayBeLabel( TRUE ) )
+ {
+ // Ist ein Label
+ if( !pProc )
+ Error( SbERR_NOT_IN_MAIN, aSym );
+ else
+ pProc->GetLabels().Define( aSym );
+ Next(); Peek();
+ // Leerstatement?
+ if( IsEoln( eCurTok ) )
+ {
+ Next(); return TRUE;
+ }
+ }
+
+ // Ende des Parsings?
+ if( eCurTok == eEndTok )
+ {
+ Next();
+ if( eCurTok != NIL )
+ aGen.Statement();
+ return FALSE;
+ }
+
+ // Kommentar?
+ if( eCurTok == REM )
+ {
+ Next(); return TRUE;
+ }
+
+ // Kommt ein Symbol, ist es entweder eine Variable( LET )
+ // oder eine SUB-Prozedur( CALL ohne Klammern )
+ // DOT fuer Zuweisungen im WITH-Block: .A=5
+ if( eCurTok == SYMBOL || eCurTok == DOT )
+ {
+ if( !pProc )
+ Error( SbERR_EXPECTED, SUB );
+ else
+ {
+ // Damit Zeile & Spalte stimmen...
+ Next();
+ Push( eCurTok );
+ aGen.Statement();
+ Symbol();
+ }
+ }
+ else
+ {
+ Next();
+
+ // Hier folgen nun die Statement-Parser.
+
+ SbiStatement* p;
+ for( p = StmntTable; p->eTok != NIL; p++ )
+ if( p->eTok == eCurTok )
+ break;
+ if( p->eTok != NIL )
+ {
+ if( !pProc && !p->bMain )
+ Error( SbERR_NOT_IN_MAIN, eCurTok );
+ else if( pProc && !p->bSubr )
+ Error( SbERR_NOT_IN_SUBR, eCurTok );
+ else
+ {
+ // globalen Chain pflegen
+ // AB #41606/#40689: Durch die neue static-Behandlung kann noch
+ // ein nGblChain vorhanden sein, daher vorher abfragen
+ if( bNewGblDefs && nGblChain == 0 &&
+ ( eCurTok == SUB || eCurTok == FUNCTION || eCurTok == PROPERTY ) )
+ {
+ nGblChain = aGen.Gen( _JUMP, 0 );
+ bNewGblDefs = FALSE;
+ }
+ // Statement-Opcode bitte auch am Anfang einer Sub
+ if( ( p->bSubr && (eCurTok != STATIC || Peek() == SUB || Peek() == FUNCTION ) ) ||
+ eCurTok == SUB || eCurTok == FUNCTION )
+ aGen.Statement();
+ (this->*( p->Func ) )();
+ SbxError nSbxErr = SbxBase::GetError();
+ if( nSbxErr )
+ SbxBase::ResetError(), Error( (SbError)nSbxErr );
+ }
+ }
+ else
+ Error( SbERR_UNEXPECTED, eCurTok );
+ }
+
+ // Test auf Ende des Statements:
+ // Kann auch ein ELSE sein, da vor dem ELSE kein : stehen muss!
+
+ if( !IsEos() )
+ {
+ Peek();
+ if( !IsEos() && eCurTok != ELSE )
+ {
+ // falls das Parsing abgebrochen wurde, bis zum ":" vorgehen:
+ Error( SbERR_UNEXPECTED, eCurTok );
+ while( !IsEos() ) Next();
+ }
+ }
+ // Der Parser bricht am Ende ab, das naechste Token ist noch nicht
+ // geholt!
+ return TRUE;
+}
+
+// Innerste With-Variable liefern
+SbiExprNode* SbiParser::GetWithVar()
+{
+ if( pWithVar )
+ return pWithVar;
+
+ // Sonst im Stack suchen
+ SbiParseStack* p = pStack;
+ while( p )
+ {
+ // LoopVar kann zur Zeit nur fuer with sein
+ if( p->pWithVar )
+ return p->pWithVar;
+ p = p->pNext;
+ }
+ return NULL;
+}
+
+
+// Zuweisung oder Subroutine Call
+
+void SbiParser::Symbol()
+{
+ SbiExpression aVar( this, SbSYMBOL );
+
+ bool bEQ = ( Peek() == EQ );
+ RecursiveMode eRecMode = ( bEQ ? PREVENT_CALL : FORCE_CALL );
+ bool bSpecialMidHandling = false;
+ SbiSymDef* pDef = aVar.GetRealVar();
+ if( bEQ && pDef && pDef->GetScope() == SbRTL )
+ {
+ String aRtlName = pDef->GetName();
+ if( aRtlName.EqualsIgnoreCaseAscii("Mid") )
+ {
+ SbiExprNode* pExprNode = aVar.GetExprNode();
+ // SbiNodeType eNodeType;
+ if( pExprNode && pExprNode->GetNodeType() == SbxVARVAL )
+ {
+ SbiExprList* pPar = pExprNode->GetParameters();
+ short nParCount = pPar ? pPar->GetSize() : 0;
+ if( nParCount == 2 || nParCount == 3 )
+ {
+ if( nParCount == 2 )
+ pPar->addExpression( new SbiExpression( this, -1, SbxLONG ) );
+
+ TestToken( EQ );
+ pPar->addExpression( new SbiExpression( this ) );
+
+ bSpecialMidHandling = true;
+ }
+ }
+ }
+ }
+ aVar.Gen( eRecMode );
+ if( !bSpecialMidHandling )
+ {
+ if( !bEQ )
+ {
+ aGen.Gen( _GET );
+ }
+ else
+ {
+ // Dann muss es eine Zuweisung sein. Was anderes gibts nicht!
+ if( !aVar.IsLvalue() )
+ Error( SbERR_LVALUE_EXPECTED );
+ TestToken( EQ );
+ SbiExpression aExpr( this );
+ aExpr.Gen();
+ SbiOpcode eOp = _PUT;
+ // SbiSymDef* pDef = aVar.GetRealVar();
+ if( pDef )
+ {
+ if( pDef->GetConstDef() )
+ Error( SbERR_DUPLICATE_DEF, pDef->GetName() );
+ if( pDef->GetType() == SbxOBJECT )
+ {
+ eOp = _SET;
+ if( pDef->GetTypeId() )
+ {
+ aGen.Gen( _SETCLASS, pDef->GetTypeId() );
+ return;
+ }
+ }
+ }
+ aGen.Gen( eOp );
+ }
+ }
+}
+
+// Zuweisungen
+
+void SbiParser::Assign()
+{
+ SbiExpression aLvalue( this, SbLVALUE );
+ TestToken( EQ );
+ SbiExpression aExpr( this );
+ aLvalue.Gen();
+ aExpr.Gen();
+ USHORT nLen = 0;
+ SbiSymDef* pDef = aLvalue.GetRealVar();
+ {
+ if( pDef->GetConstDef() )
+ Error( SbERR_DUPLICATE_DEF, pDef->GetName() );
+ nLen = aLvalue.GetRealVar()->GetLen();
+ }
+ if( nLen )
+ aGen.Gen( _PAD, nLen );
+ aGen.Gen( _PUT );
+}
+
+// Zuweisungen einer Objektvariablen
+
+void SbiParser::Set()
+{
+ SbiExpression aLvalue( this, SbLVALUE );
+ SbxDataType eType = aLvalue.GetType();
+ if( eType != SbxOBJECT && eType != SbxEMPTY && eType != SbxVARIANT )
+ Error( SbERR_INVALID_OBJECT );
+ TestToken( EQ );
+ SbiSymDef* pDef = aLvalue.GetRealVar();
+ if( pDef && pDef->GetConstDef() )
+ Error( SbERR_DUPLICATE_DEF, pDef->GetName() );
+
+ SbiToken eTok = Peek();
+ if( eTok == NEW )
+ {
+ Next();
+ String aStr;
+ SbiSymDef* pTypeDef = new SbiSymDef( aStr );
+ TypeDecl( *pTypeDef, TRUE );
+
+ aLvalue.Gen();
+ // aGen.Gen( _CLASS, pDef->GetTypeId() | 0x8000 );
+ aGen.Gen( _CREATE, pDef->GetId(), pTypeDef->GetTypeId() );
+ aGen.Gen( _SETCLASS, pDef->GetTypeId() );
+ }
+ else
+ {
+ SbiExpression aExpr( this );
+ aLvalue.Gen();
+ aExpr.Gen();
+ // Its a good idea to distinguish between
+ // set someting = another &
+ // someting = another
+ // ( its necessary for vba objects where set is object
+ // specific and also doesn't involve processing default params )
+ if( pDef->GetTypeId() )
+ aGen.Gen( _SETCLASS, pDef->GetTypeId() );
+ else
+ {
+ if ( bVBASupportOn )
+ aGen.Gen( _VBASET );
+ else
+ aGen.Gen( _SET );
+ }
+ }
+ // aGen.Gen( _SET );
+}
+
+// JSM 07.10.95
+void SbiParser::LSet()
+{
+ SbiExpression aLvalue( this, SbLVALUE );
+ if( aLvalue.GetType() != SbxSTRING )
+ Error( SbERR_INVALID_OBJECT );
+ TestToken( EQ );
+ SbiSymDef* pDef = aLvalue.GetRealVar();
+ if( pDef && pDef->GetConstDef() )
+ Error( SbERR_DUPLICATE_DEF, pDef->GetName() );
+ SbiExpression aExpr( this );
+ aLvalue.Gen();
+ aExpr.Gen();
+ aGen.Gen( _LSET );
+}
+
+// JSM 07.10.95
+void SbiParser::RSet()
+{
+ SbiExpression aLvalue( this, SbLVALUE );
+ if( aLvalue.GetType() != SbxSTRING )
+ Error( SbERR_INVALID_OBJECT );
+ TestToken( EQ );
+ SbiSymDef* pDef = aLvalue.GetRealVar();
+ if( pDef && pDef->GetConstDef() )
+ Error( SbERR_DUPLICATE_DEF, pDef->GetName() );
+ SbiExpression aExpr( this );
+ aLvalue.Gen();
+ aExpr.Gen();
+ aGen.Gen( _RSET );
+}
+
+// DEFINT, DEFLNG, DEFSNG, DEFDBL, DEFSTR und so weiter
+
+void SbiParser::DefXXX()
+{
+ sal_Unicode ch1, ch2;
+ SbxDataType t = SbxDataType( eCurTok - DEFINT + SbxINTEGER );
+
+ while( !bAbort )
+ {
+ if( Next() != SYMBOL ) break;
+ ch1 = aSym.ToUpperAscii().GetBuffer()[0];
+ ch2 = 0;
+ if( Peek() == MINUS )
+ {
+ Next();
+ if( Next() != SYMBOL ) Error( SbERR_SYMBOL_EXPECTED );
+ else
+ {
+ ch2 = aSym.ToUpperAscii().GetBuffer()[0];
+ //ch2 = aSym.Upper();
+ if( ch2 < ch1 ) Error( SbERR_SYNTAX ), ch2 = 0;
+ }
+ }
+ if (!ch2) ch2 = ch1;
+ ch1 -= 'A'; ch2 -= 'A';
+ for (; ch1 <= ch2; ch1++) eDefTypes[ ch1 ] = t;
+ if( !TestComma() ) break;
+ }
+}
+
+// STOP/SYSTEM
+
+void SbiParser::Stop()
+{
+ aGen.Gen( _STOP );
+ Peek(); // #35694: Nur Peek(), damit EOL in Single-Line-If erkannt wird
+}
+
+// IMPLEMENTS
+
+void SbiParser::Implements()
+{
+ if( !bClassModule )
+ {
+ Error( SbERR_UNEXPECTED, IMPLEMENTS );
+ return;
+ }
+
+ if( TestSymbol() )
+ {
+ String aImplementedIface = GetSym();
+ aIfaceVector.push_back( aImplementedIface );
+ }
+}
+
+void SbiParser::EnableCompatibility()
+{
+ if( !bCompatible )
+ AddConstants();
+ bCompatible = TRUE;
+}
+
+// OPTION
+
+void SbiParser::Option()
+{
+ switch( Next() )
+ {
+ case EXPLICIT:
+ bExplicit = TRUE; break;
+ case BASE:
+ if( Next() == NUMBER )
+ {
+ if( nVal == 0 || nVal == 1 )
+ {
+ nBase = (short) nVal;
+ break;
+ }
+ }
+ Error( SbERR_EXPECTED, "0/1" );
+ break;
+ case PRIVATE:
+ {
+ String aString = SbiTokenizer::Symbol(Next());
+ if( !aString.EqualsIgnoreCaseAscii("Module") )
+ Error( SbERR_EXPECTED, "Module" );
+ break;
+ }
+ case COMPARE:
+ switch( Next() )
+ {
+ case TEXT: bText = TRUE; return;
+ case BINARY: bText = FALSE; return;
+ default:;
+ } // Fall thru!
+ case COMPATIBLE:
+ EnableCompatibility();
+ break;
+
+ case CLASSMODULE:
+ bClassModule = TRUE;
+ break;
+ case VBASUPPORT:
+ if( Next() == NUMBER )
+ {
+ if ( nVal == 1 || nVal == 0 )
+ {
+ bVBASupportOn = ( nVal == 1 );
+ if ( bVBASupportOn )
+ EnableCompatibility();
+ break;
+ }
+ }
+ Error( SbERR_EXPECTED, "0/1" );
+ break;
+ default:
+ Error( SbERR_BAD_OPTION, eCurTok );
+ }
+}
+
+void addStringConst( SbiSymPool& rPool, const char* pSym, const String& rStr )
+{
+ SbiConstDef* pConst = new SbiConstDef( String::CreateFromAscii( pSym ) );
+ pConst->SetType( SbxSTRING );
+ pConst->Set( rStr );
+ rPool.Add( pConst );
+}
+
+inline void addStringConst( SbiSymPool& rPool, const char* pSym, const char* pStr )
+{
+ addStringConst( rPool, pSym, String::CreateFromAscii( pStr ) );
+}
+
+void SbiParser::AddConstants( void )
+{
+ // #113063 Create constant RTL symbols
+ addStringConst( aPublics, "vbCr", "\x0D" );
+ addStringConst( aPublics, "vbCrLf", "\x0D\x0A" );
+ addStringConst( aPublics, "vbFormFeed", "\x0C" );
+ addStringConst( aPublics, "vbLf", "\x0A" );
+#if defined(UNX)
+ addStringConst( aPublics, "vbNewLine", "\x0A" );
+#else
+ addStringConst( aPublics, "vbNewLine", "\x0D\x0A" );
+#endif
+ addStringConst( aPublics, "vbNullString", "" );
+ addStringConst( aPublics, "vbTab", "\x09" );
+ addStringConst( aPublics, "vbVerticalTab", "\x0B" );
+
+ // Force length 1 and make char 0 afterwards
+ String aNullCharStr( String::CreateFromAscii( " " ) );
+ aNullCharStr.SetChar( 0, 0 );
+ addStringConst( aPublics, "vbNullChar", aNullCharStr );
+}
+
+// ERROR n
+
+void SbiParser::ErrorStmnt()
+{
+ SbiExpression aPar( this );
+ aPar.Gen();
+ aGen.Gen( _ERROR );
+}
+
+
+// AB 22.5.1996
+// JavaScript-Parsing zunaechst provisorisch hier implementiert
+void SbiParser::OpenJavaBlock( SbiToken, SbiExprNode* )
+{
+}
+
+void SbiParser::CloseJavaBlock()
+{
+}
+
+void SbiParser::JavaStmntBlock( SbiToken )
+{
+}
+
+void SbiParser::JavaBreak()
+{
+}
+
+void SbiParser::JavaContinue()
+{
+}
+
+void SbiParser::JavaFor()
+{
+}
+
+void SbiParser::JavaFunction()
+{
+}
+
+void SbiParser::JavaIf()
+{
+}
+
+void SbiParser::JavaNew()
+{
+}
+
+void SbiParser::JavaReturn()
+{
+}
+
+void SbiParser::JavaThis()
+{
+}
+
+void SbiParser::JavaVar()
+{
+}
+
+void SbiParser::JavaWhile()
+{
+}
+
+void SbiParser::JavaWith()
+{
+}
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/comp/sbcomp.cxx b/binfilter/bf_basic/source/comp/sbcomp.cxx
new file mode 100644
index 000000000000..1d703baceac7
--- /dev/null
+++ b/binfilter/bf_basic/source/comp/sbcomp.cxx
@@ -0,0 +1,113 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "sbx.hxx"
+#include "image.hxx"
+
+
+// For debugging only
+// #define DBG_SAVE_DISASSEMBLY
+
+#include <comphelper/processfactory.hxx>
+
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/ucb/XSimpleFileAccess3.hpp>
+#include <com/sun/star/io/XTextOutputStream.hpp>
+#include <com/sun/star/io/XActiveDataSource.hpp>
+
+namespace binfilter {
+
+/*?*/ // #ifdef DBG_SAVE_DISASSEMBLY
+/*?*/ // static bool dbg_bDisassemble = true;
+/*?*/ //
+/*?*/ // using namespace comphelper;
+/*?*/ // using namespace rtl;
+/*?*/ // using namespace com::sun::star::uno;
+/*?*/ // using namespace com::sun::star::lang;
+/*?*/ // using namespace com::sun::star::ucb;
+/*?*/ // using namespace com::sun::star::io;
+/*?*/ //
+/*?*/ // void dbg_SaveDisassembly( SbModule* pModule )
+/*?*/ // {
+/*?*/ // bool bDisassemble = dbg_bDisassemble;
+/*?*/ // if( bDisassemble )
+/*?*/ // {
+/*?*/ // Reference< XSimpleFileAccess3 > xSFI;
+/*?*/ // Reference< XTextOutputStream > xTextOut;
+/*?*/ // Reference< XOutputStream > xOut;
+/*?*/ // Reference< XMultiServiceFactory > xSMgr = getProcessServiceFactory();
+/*?*/ // if( xSMgr.is() )
+/*?*/ // {
+/*?*/ // Reference< XSimpleFileAccess3 > xSFI = Reference< XSimpleFileAccess3 >( xSMgr->createInstance
+/*?*/ // ( OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY );
+/*?*/ // if( xSFI.is() )
+/*?*/ // {
+/*?*/ // String aFile( RTL_CONSTASCII_USTRINGPARAM("file:///d:/BasicAsm_") );
+/*?*/ // StarBASIC* pBasic = (StarBASIC*)pModule->GetParent();
+/*?*/ // if( pBasic )
+/*?*/ // {
+/*?*/ // aFile += pBasic->GetName();
+/*?*/ // aFile.AppendAscii( "_" );
+/*?*/ // }
+/*?*/ // aFile += pModule->GetName();
+/*?*/ // aFile.AppendAscii( ".txt" );
+/*?*/ //
+/*?*/ // // String aFile( RTL_CONSTASCII_USTRINGPARAM("file:///d:/BasicAsm.txt") );
+/*?*/ // if( xSFI->exists( aFile ) )
+/*?*/ // xSFI->kill( aFile );
+/*?*/ // xOut = xSFI->openFileWrite( aFile );
+/*?*/ // Reference< XInterface > x = xSMgr->createInstance( OUString::createFromAscii( "com.sun.star.io.TextOutputStream" ) );
+/*?*/ // Reference< XActiveDataSource > xADS( x, UNO_QUERY );
+/*?*/ // xADS->setOutputStream( xOut );
+/*?*/ // xTextOut = Reference< XTextOutputStream >( x, UNO_QUERY );
+/*?*/ // }
+/*?*/ // }
+/*?*/ //
+/*?*/ // if( xTextOut.is() )
+/*?*/ // {
+/*?*/ // String aDisassemblyStr;
+/*?*/ // pModule->Disassemble( aDisassemblyStr );
+/*?*/ // xTextOut->writeString( aDisassemblyStr );
+/*?*/ // }
+/*?*/ // xOut->closeOutput();
+/*?*/ // }
+/*?*/ // }
+/*?*/ // #endif
+
+// Diese Routine ist hier definiert, damit der Compiler als eigenes Segment
+// geladen werden kann.
+
+BOOL SbModule::Compile()
+{
+ DBG_ERROR( "SbModule::Compile: dead code!" );
+ return FALSE;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/comp/scanner.cxx b/binfilter/bf_basic/source/comp/scanner.cxx
new file mode 100644
index 000000000000..069c22b703ed
--- /dev/null
+++ b/binfilter/bf_basic/source/comp/scanner.cxx
@@ -0,0 +1,559 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "scanner.hxx"
+#include "sbintern.hxx"
+#include "token.hxx"
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#if defined UNX
+#include <stdlib.h>
+#else
+#include <math.h> // atof()
+#endif
+#include <rtl/math.hxx>
+#include <vcl/svapp.hxx>
+#include <unotools/charclass.hxx>
+
+namespace binfilter {
+
+SbiScanner::SbiScanner( const ::rtl::OUString& rBuf, StarBASIC* p ) : aBuf( rBuf )
+{
+ pBasic = p;
+ pLine = NULL;
+ nVal = 0;
+ eScanType = SbxVARIANT;
+ nErrors = 0;
+ nBufPos = 0;
+ nCurCol1 = 0;
+ nSavedCol1 = 0;
+ nColLock = 0;
+ nLine = 0;
+ nCol1 = 0;
+ nCol2 = 0;
+ nCol = 0;
+ bError =
+ bAbort =
+ bSpaces =
+ bNumber =
+ bSymbol =
+ bUsedForHilite =
+ bCompatible =
+ bPrevLineExtentsComment = FALSE;
+ bHash =
+ bErrors = TRUE;
+}
+
+SbiScanner::~SbiScanner()
+{}
+
+/*?*/ // void SbiScanner::LockColumn()
+/*?*/ // {
+/*?*/ // if( !nColLock++ )
+/*?*/ // nSavedCol1 = nCol1;
+/*?*/ // }
+/*?*/ //
+/*?*/ // void SbiScanner::UnlockColumn()
+/*?*/ // {
+/*?*/ // if( nColLock )
+/*?*/ // nColLock--;
+/*?*/ // }
+/*?*/ //
+void SbiScanner::GenError( SbError code )
+{
+ if( GetSbData()->bBlockCompilerError )
+ {
+ bAbort = TRUE;
+ return;
+ }
+ if( !bError && bErrors )
+ {
+ BOOL bRes = TRUE;
+ // Nur einen Fehler pro Statement reporten
+ bError = TRUE;
+ if( pBasic )
+ {
+ // Falls EXPECTED oder UNEXPECTED kommen sollte, bezieht es sich
+ // immer auf das letzte Token, also die Col1 uebernehmen
+ USHORT nc = nColLock ? nSavedCol1 : nCol1;
+ switch( code )
+ {
+ case SbERR_EXPECTED:
+ case SbERR_UNEXPECTED:
+ case SbERR_SYMBOL_EXPECTED:
+ case SbERR_LABEL_EXPECTED:
+ nc = nCol1;
+ if( nc > nCol2 ) nCol2 = nc;
+ break;
+ }
+ bRes = pBasic->CError( code, aError, nLine, nc, nCol2 );
+ }
+ bAbort |= !bRes |
+ ( code == SbERR_NO_MEMORY || code == SbERR_PROG_TOO_LARGE );
+ }
+ if( bErrors )
+ nErrors++;
+}
+
+// Testen auf ein legales Suffix
+
+static SbxDataType GetSuffixType( sal_Unicode c )
+{
+ static String aSuffixesStr = String::CreateFromAscii( "%&!#@ $" );
+ if( c )
+ {
+ sal_uInt32 n = aSuffixesStr.Search( c );
+ if( STRING_NOTFOUND != n && c != ' ' )
+ return SbxDataType( (USHORT) n + SbxINTEGER );
+ }
+ return SbxVARIANT;
+}
+
+// Einlesen des naechsten Symbols in die Variablen aSym, nVal und eType
+// Returnwert ist FALSE bei EOF oder Fehlern
+#define BUF_SIZE 80
+
+BOOL SbiScanner::NextSym()
+{
+ // Fuer den EOLN-Fall merken
+ USHORT nOldLine = nLine;
+ USHORT nOldCol1 = nCol1;
+ USHORT nOldCol2 = nCol2;
+ sal_Unicode buf[ BUF_SIZE ], *p = buf;
+ bHash = FALSE;
+
+ eScanType = SbxVARIANT;
+ aSym.Erase();
+ bSymbol =
+ bNumber = bSpaces = FALSE;
+
+ // Zeile einlesen?
+ if( !pLine )
+ {
+ INT32 n = nBufPos;
+ INT32 nLen = aBuf.getLength();
+ if( nBufPos >= nLen )
+ return FALSE;
+ const sal_Unicode* p2 = aBuf.getStr();
+ p2 += n;
+ while( ( n < nLen ) && ( *p2 != '\n' ) && ( *p2 != '\r' ) )
+ p2++, n++;
+ aLine = aBuf.copy( nBufPos, n - nBufPos );
+ if( n < nLen )
+ {
+ if( *p2 == '\r' && *( p2+1 ) == '\n' )
+ n += 2;
+ else
+ n++;
+ }
+ nBufPos = n;
+ pLine = aLine.getStr();
+ nOldLine = ++nLine;
+ nCol = nCol1 = nCol2 = nOldCol1 = nOldCol2 = 0;
+ nColLock = 0;
+ }
+
+ // Leerstellen weg:
+ while( *pLine && (( *pLine == ' ' ) || ( *pLine == '\t' ) || ( *pLine == '\f' )) )
+ pLine++, nCol++, bSpaces = TRUE;
+
+ nCol1 = nCol;
+
+ // nur Leerzeile?
+ if( !*pLine )
+ goto eoln;
+
+ if( bPrevLineExtentsComment )
+ goto PrevLineCommentLbl;
+
+ if( *pLine == '#' )
+ {
+ pLine++;
+ nCol++;
+ bHash = TRUE;
+ }
+
+ // Symbol? Dann Zeichen kopieren.
+ if( BasicSimpleCharClass::isAlpha( *pLine, bCompatible ) || *pLine == '_' )
+ {
+ // Wenn nach '_' nichts kommt, ist es ein Zeilenabschluss!
+ if( *pLine == '_' && !*(pLine+1) )
+ { pLine++;
+ goto eoln; }
+ bSymbol = TRUE;
+ short n = nCol;
+ for ( ; (BasicSimpleCharClass::isAlphaNumeric( *pLine, bCompatible ) || ( *pLine == '_' ) ); pLine++ )
+ nCol++;
+ aSym = aLine.copy( n, nCol - n );
+ // Abschliessendes '_' durch Space ersetzen, wenn Zeilenende folgt
+ // (sonst falsche Zeilenfortsetzung)
+ if( !bUsedForHilite && !*pLine && *(pLine-1) == '_' )
+ {
+ aSym.GetBufferAccess(); // #109693 force copy if necessary
+ *((sal_Unicode*)(pLine-1)) = ' '; // cast wegen const
+ }
+ // Typkennung?
+ // Das Ausrufezeichen bitte nicht testen, wenn
+ // danach noch ein Symbol anschliesst
+ else if( *pLine != '!' || !BasicSimpleCharClass::isAlpha( pLine[ 1 ], bCompatible ) )
+ {
+ SbxDataType t = GetSuffixType( *pLine );
+ if( t != SbxVARIANT )
+ {
+ eScanType = t;
+ pLine++;
+ nCol++;
+ }
+ }
+ }
+
+ // Zahl? Dann einlesen und konvertieren.
+ else if( BasicSimpleCharClass::isDigit( *pLine & 0xFF )
+ || ( *pLine == '.' && BasicSimpleCharClass::isDigit( *(pLine+1) & 0xFF ) ) )
+ {
+ short exp = 0;
+ short comma = 0;
+ short ndig = 0;
+ short ncdig = 0;
+ eScanType = SbxDOUBLE;
+ BOOL bBufOverflow = FALSE;
+ while( strchr( "0123456789.DEde", *pLine ) && *pLine )
+ {
+ // AB 4.1.1996: Buffer voll? -> leer weiter scannen
+ if( (p-buf) == (BUF_SIZE-1) )
+ {
+ bBufOverflow = TRUE;
+ pLine++, nCol++;
+ continue;
+ }
+ // Komma oder Exponent?
+ if( *pLine == '.' )
+ {
+ if( ++comma > 1 )
+ {
+ pLine++; nCol++; continue;
+ }
+ else *p++ = *pLine++, nCol++;
+ }
+ else if( strchr( "DdEe", *pLine ) )
+ {
+ if (++exp > 1)
+ {
+ pLine++; nCol++; continue;
+ }
+// if( toupper( *pLine ) == 'D' )
+// eScanType = SbxDOUBLE;
+ *p++ = 'E'; pLine++; nCol++;
+ // Vorzeichen hinter Exponent?
+ if( *pLine == '+' )
+ pLine++, nCol++;
+ else
+ if( *pLine == '-' )
+ *p++ = *pLine++, nCol++;
+ }
+ else
+ {
+ *p++ = *pLine++, nCol++;
+ if( comma && !exp ) ncdig++;
+ }
+ if (!exp) ndig++;
+ }
+ *p = 0;
+ aSym = p; bNumber = TRUE;
+ // Komma, Exponent mehrfach vorhanden?
+ if( comma > 1 || exp > 1 )
+ { aError = '.';
+ GenError( SbERR_BAD_CHAR_IN_NUMBER ); }
+
+ // #57844 Lokalisierte Funktion benutzen
+ nVal = rtl_math_uStringToDouble( buf, buf+(p-buf), '.', ',', NULL, NULL );
+ // ALT: nVal = atof( buf );
+
+ ndig = ndig - comma;
+ if( !comma && !exp )
+ {
+ if( nVal >= SbxMININT && nVal <= SbxMAXINT )
+ eScanType = SbxINTEGER;
+ else
+ if( nVal >= SbxMINLNG && nVal <= SbxMAXLNG )
+ eScanType = SbxLONG;
+ }
+ if( bBufOverflow )
+ GenError( SbERR_MATH_OVERFLOW );
+ // zu viele Zahlen fuer SINGLE?
+// if (ndig > 15 || ncdig > 6)
+// eScanType = SbxDOUBLE;
+// else
+// if( nVal > SbxMAXSNG || nVal < SbxMINSNG )
+// eScanType = SbxDOUBLE;
+
+ // Typkennung?
+ SbxDataType t = GetSuffixType( *pLine );
+ if( t != SbxVARIANT )
+ {
+ eScanType = t;
+ pLine++;
+ nCol++;
+ }
+ }
+
+ // Hex/Oktalzahl? Einlesen und konvertieren:
+ else if( *pLine == '&' )
+ {
+ pLine++; nCol++;
+ sal_Unicode cmp1[] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F', 0 };
+ sal_Unicode cmp2[] = { '0', '1', '2', '3', '4', '5', '6', '7', 0 };
+ sal_Unicode *cmp = cmp1;
+ //char *cmp = "0123456789ABCDEF";
+ sal_Unicode base = 16;
+ sal_Unicode ndig = 8;
+ sal_Unicode xch = *pLine++ & 0xFF; nCol++;
+ switch( toupper( xch ) )
+ {
+ case 'O':
+ cmp = cmp2; base = 8; ndig = 11; break;
+ //cmp = "01234567"; base = 8; ndig = 11; break;
+ case 'H':
+ break;
+ default :
+ // Wird als Operator angesehen
+ pLine--; nCol--; nCol1 = nCol-1; aSym = '&'; return SYMBOL;
+ }
+ bNumber = TRUE;
+ long l = 0;
+ int i;
+ BOOL bBufOverflow = FALSE;
+ while( BasicSimpleCharClass::isAlphaNumeric( *pLine & 0xFF, bCompatible ) )
+ {
+ sal_Unicode ch = sal::static_int_cast< sal_Unicode >(
+ toupper( *pLine & 0xFF ) );
+ pLine++; nCol++;
+ // AB 4.1.1996: Buffer voll, leer weiter scannen
+ if( (p-buf) == (BUF_SIZE-1) )
+ bBufOverflow = TRUE;
+ else if( String( cmp ).Search( ch ) != STRING_NOTFOUND )
+ //else if( strchr( cmp, ch ) )
+ *p++ = ch;
+ else
+ {
+ aError = ch;
+ GenError( SbERR_BAD_CHAR_IN_NUMBER );
+ }
+ }
+ *p = 0;
+ for( p = buf; *p; p++ )
+ {
+ i = (*p & 0xFF) - '0';
+ if( i > 9 ) i -= 7;
+ l = ( l * base ) + i;
+ if( !ndig-- )
+ {
+ GenError( SbERR_MATH_OVERFLOW ); break;
+ }
+ }
+ if( *pLine == '&' ) pLine++, nCol++;
+ nVal = (double) l;
+ eScanType = ( l >= SbxMININT && l <= SbxMAXINT ) ? SbxINTEGER : SbxLONG;
+ if( bBufOverflow )
+ GenError( SbERR_MATH_OVERFLOW );
+ }
+
+ // Strings:
+ else if( *pLine == '"' || *pLine == '[' )
+ {
+ sal_Unicode cSep = *pLine;
+ if( cSep == '[' )
+ bSymbol = TRUE, cSep = ']';
+ short n = nCol+1;
+ while( *pLine )
+ {
+ do pLine++, nCol++;
+ while( *pLine && ( *pLine != cSep ) );
+ if( *pLine == cSep )
+ {
+ pLine++; nCol++;
+ if( *pLine != cSep || cSep == ']' ) break;
+ } else aError = cSep, GenError( SbERR_EXPECTED );
+ }
+ aSym = aLine.copy( n, nCol - n - 1 );
+ // Doppelte Stringbegrenzer raus
+ String s( cSep );
+ s += cSep;
+ USHORT nIdx = 0;
+ do
+ {
+ nIdx = aSym.Search( s, nIdx );
+ if( nIdx == STRING_NOTFOUND )
+ break;
+ aSym.Erase( nIdx, 1 );
+ nIdx++;
+ }
+ while( true );
+ if( cSep != ']' )
+ eScanType = ( cSep == '#' ) ? SbxDATE : SbxSTRING;
+ }
+ // ungueltige Zeichen:
+ else if( ( *pLine & 0xFF ) >= 0x7F )
+ {
+ GenError( SbERR_SYNTAX ); pLine++; nCol++;
+ }
+ // andere Gruppen:
+ else
+ {
+ short n = 1;
+ switch( *pLine++ )
+ {
+ case '<': if( *pLine == '>' || *pLine == '=' ) n = 2; break;
+ case '>': if( *pLine == '=' ) n = 2; break;
+ case ':': if( *pLine == '=' ) n = 2; break;
+ }
+ aSym = aLine.copy( nCol, n );
+ pLine += n-1; nCol = nCol + n;
+ }
+
+ nCol2 = nCol-1;
+
+PrevLineCommentLbl:
+ // Kommentar?
+ if( bPrevLineExtentsComment || (eScanType != SbxSTRING &&
+ ( aSym.GetBuffer()[0] == '\'' || aSym.EqualsIgnoreCaseAscii( "REM" ) ) ) )
+ {
+ bPrevLineExtentsComment = FALSE;
+ aSym = String::CreateFromAscii( "REM" );
+ USHORT nLen = String( pLine ).Len();
+ if( bCompatible && pLine[ nLen - 1 ] == '_' && pLine[ nLen - 2 ] == ' ' )
+ bPrevLineExtentsComment = TRUE;
+ nCol2 = nCol2 + nLen;
+ pLine = NULL;
+ }
+ return TRUE;
+
+ // Sonst Zeilen-Ende: aber bitte auf '_' testen, ob die
+ // Zeile nicht weitergeht!
+eoln:
+ if( nCol && *--pLine == '_' )
+ {
+ pLine = NULL; return NextSym();
+ }
+ else
+ {
+ pLine = NULL;
+ nLine = nOldLine;
+ nCol1 = nOldCol1;
+ nCol2 = nOldCol2;
+ aSym = '\n';
+ nColLock = 0;
+ return TRUE;
+ }
+}
+
+LetterTable BasicSimpleCharClass::aLetterTable;
+
+LetterTable::LetterTable( void )
+{
+ for( int i = 0 ; i < 256 ; ++i )
+ IsLetterTab[i] = false;
+
+ IsLetterTab[0xC0] = true; // À , CAPITAL LETTER A WITH GRAVE ACCENT
+ IsLetterTab[0xC1] = true; // Á , CAPITAL LETTER A WITH ACUTE ACCENT
+ IsLetterTab[0xC2] = true; // Â , CAPITAL LETTER A WITH CIRCUMFLEX ACCENT
+ IsLetterTab[0xC3] = true; // Ã , CAPITAL LETTER A WITH TILDE
+ IsLetterTab[0xC4] = true; // Ä , CAPITAL LETTER A WITH DIAERESIS
+ IsLetterTab[0xC5] = true; // Å , CAPITAL LETTER A WITH RING ABOVE
+ IsLetterTab[0xC6] = true; // Æ , CAPITAL LIGATURE AE
+ IsLetterTab[0xC7] = true; // Ç , CAPITAL LETTER C WITH CEDILLA
+ IsLetterTab[0xC8] = true; // È , CAPITAL LETTER E WITH GRAVE ACCENT
+ IsLetterTab[0xC9] = true; // É , CAPITAL LETTER E WITH ACUTE ACCENT
+ IsLetterTab[0xCA] = true; // Ê , CAPITAL LETTER E WITH CIRCUMFLEX ACCENT
+ IsLetterTab[0xCB] = true; // Ë , CAPITAL LETTER E WITH DIAERESIS
+ IsLetterTab[0xCC] = true; // Ì , CAPITAL LETTER I WITH GRAVE ACCENT
+ IsLetterTab[0xCD] = true; // Í , CAPITAL LETTER I WITH ACUTE ACCENT
+ IsLetterTab[0xCE] = true; // Î , CAPITAL LETTER I WITH CIRCUMFLEX ACCENT
+ IsLetterTab[0xCF] = true; // Ï , CAPITAL LETTER I WITH DIAERESIS
+ IsLetterTab[0xD0] = true; // Ð , CAPITAL LETTER ETH
+ IsLetterTab[0xD1] = true; // Ñ , CAPITAL LETTER N WITH TILDE
+ IsLetterTab[0xD2] = true; // Ò , CAPITAL LETTER O WITH GRAVE ACCENT
+ IsLetterTab[0xD3] = true; // Ó , CAPITAL LETTER O WITH ACUTE ACCENT
+ IsLetterTab[0xD4] = true; // Ô , CAPITAL LETTER O WITH CIRCUMFLEX ACCENT
+ IsLetterTab[0xD5] = true; // Õ , CAPITAL LETTER O WITH TILDE
+ IsLetterTab[0xD6] = true; // Ö , CAPITAL LETTER O WITH DIAERESIS
+ IsLetterTab[0xD8] = true; // Ø , CAPITAL LETTER O WITH STROKE
+ IsLetterTab[0xD9] = true; // Ù , CAPITAL LETTER U WITH GRAVE ACCENT
+ IsLetterTab[0xDA] = true; // Ú , CAPITAL LETTER U WITH ACUTE ACCENT
+ IsLetterTab[0xDB] = true; // Û , CAPITAL LETTER U WITH CIRCUMFLEX ACCENT
+ IsLetterTab[0xDC] = true; // Ü , CAPITAL LETTER U WITH DIAERESIS
+ IsLetterTab[0xDD] = true; // Ý , CAPITAL LETTER Y WITH ACUTE ACCENT
+ IsLetterTab[0xDE] = true; // Þ , CAPITAL LETTER THORN
+ IsLetterTab[0xDF] = true; // ß , SMALL LETTER SHARP S
+ IsLetterTab[0xE0] = true; // à , SMALL LETTER A WITH GRAVE ACCENT
+ IsLetterTab[0xE1] = true; // á , SMALL LETTER A WITH ACUTE ACCENT
+ IsLetterTab[0xE2] = true; // â , SMALL LETTER A WITH CIRCUMFLEX ACCENT
+ IsLetterTab[0xE3] = true; // ã , SMALL LETTER A WITH TILDE
+ IsLetterTab[0xE4] = true; // ä , SMALL LETTER A WITH DIAERESIS
+ IsLetterTab[0xE5] = true; // å , SMALL LETTER A WITH RING ABOVE
+ IsLetterTab[0xE6] = true; // æ , SMALL LIGATURE AE
+ IsLetterTab[0xE7] = true; // ç , SMALL LETTER C WITH CEDILLA
+ IsLetterTab[0xE8] = true; // è , SMALL LETTER E WITH GRAVE ACCENT
+ IsLetterTab[0xE9] = true; // é , SMALL LETTER E WITH ACUTE ACCENT
+ IsLetterTab[0xEA] = true; // ê , SMALL LETTER E WITH CIRCUMFLEX ACCENT
+ IsLetterTab[0xEB] = true; // ë , SMALL LETTER E WITH DIAERESIS
+ IsLetterTab[0xEC] = true; // ì , SMALL LETTER I WITH GRAVE ACCENT
+ IsLetterTab[0xED] = true; // í , SMALL LETTER I WITH ACUTE ACCENT
+ IsLetterTab[0xEE] = true; // î , SMALL LETTER I WITH CIRCUMFLEX ACCENT
+ IsLetterTab[0xEF] = true; // ï , SMALL LETTER I WITH DIAERESIS
+ IsLetterTab[0xF0] = true; // ð , SMALL LETTER ETH
+ IsLetterTab[0xF1] = true; // ñ , SMALL LETTER N WITH TILDE
+ IsLetterTab[0xF2] = true; // ò , SMALL LETTER O WITH GRAVE ACCENT
+ IsLetterTab[0xF3] = true; // ó , SMALL LETTER O WITH ACUTE ACCENT
+ IsLetterTab[0xF4] = true; // ô , SMALL LETTER O WITH CIRCUMFLEX ACCENT
+ IsLetterTab[0xF5] = true; // õ , SMALL LETTER O WITH TILDE
+ IsLetterTab[0xF6] = true; // ö , SMALL LETTER O WITH DIAERESIS
+ IsLetterTab[0xF8] = true; // ø , SMALL LETTER O WITH OBLIQUE BAR
+ IsLetterTab[0xF9] = true; // ù , SMALL LETTER U WITH GRAVE ACCENT
+ IsLetterTab[0xFA] = true; // ú , SMALL LETTER U WITH ACUTE ACCENT
+ IsLetterTab[0xFB] = true; // û , SMALL LETTER U WITH CIRCUMFLEX ACCENT
+ IsLetterTab[0xFC] = true; // ü , SMALL LETTER U WITH DIAERESIS
+ IsLetterTab[0xFD] = true; // ý , SMALL LETTER Y WITH ACUTE ACCENT
+ IsLetterTab[0xFE] = true; // þ , SMALL LETTER THORN
+ IsLetterTab[0xFF] = true; // ÿ , SMALL LETTER Y WITH DIAERESIS
+}
+
+bool LetterTable::isLetterUnicode( sal_Unicode c )
+{
+ static CharClass* pCharClass = NULL;
+ if( pCharClass == NULL )
+ pCharClass = new CharClass( Application::GetSettings().GetLocale() );
+ String aStr( c );
+ bool bRet = pCharClass->isLetter( aStr, 0 );
+ return bRet;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/comp/token.cxx b/binfilter/bf_basic/source/comp/token.cxx
new file mode 100644
index 000000000000..f26f2b750d5c
--- /dev/null
+++ b/binfilter/bf_basic/source/comp/token.cxx
@@ -0,0 +1,575 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <ctype.h>
+#include "token.hxx"
+
+namespace binfilter {
+
+struct TokenTable { SbiToken t; const char *s; };
+
+static short nToken; // Anzahl der Tokens
+
+static TokenTable* pTokTable;
+
+static TokenTable aTokTable_Basic [] = { // Token-Tabelle:
+
+ { CAT, "&" },
+ { MUL, "*" },
+ { PLUS, "+" },
+ { MINUS, "-" },
+ { DIV, "/" },
+ { EOS, ":" },
+ { ASSIGN, ":=" },
+ { LT, "<" },
+ { LE, "<=" },
+ { NE, "<>" },
+ { EQ, "=" },
+ { GT, ">" },
+ { GE, ">=" },
+ { ACCESS, "Access" },
+ { ALIAS, "Alias" },
+ { AND, "And" },
+ { ANY, "Any" },
+ { APPEND, "Append" },
+ { AS, "As" },
+ { BASE, "Base" },
+ { BINARY, "Binary" },
+ { TBOOLEAN, "Boolean" },
+ { BYREF, "ByRef", },
+ { TBYTE, "Byte", },
+ { BYVAL, "ByVal", },
+ { CALL, "Call" },
+ { CASE, "Case" },
+ { _CDECL_, "Cdecl" },
+ { CLASSMODULE, "ClassModule" },
+ { CLOSE, "Close" },
+ { COMPARE, "Compare" },
+ { COMPATIBLE,"Compatible" },
+ { _CONST_, "Const" },
+ { TCURRENCY,"Currency" },
+ { TDATE, "Date" },
+ { DECLARE, "Declare" },
+ { DEFBOOL, "DefBool" },
+ { DEFCUR, "DefCur" },
+ { DEFDATE, "DefDate" },
+ { DEFDBL, "DefDbl" },
+ { DEFERR, "DefErr" },
+ { DEFINT, "DefInt" },
+ { DEFLNG, "DefLng" },
+ { DEFOBJ, "DefObj" },
+ { DEFSNG, "DefSng" },
+ { DEFSTR, "DefStr" },
+ { DEFVAR, "DefVar" },
+ { DIM, "Dim" },
+ { DO, "Do" },
+ { TDOUBLE, "Double" },
+ { EACH, "Each" },
+ { ELSE, "Else" },
+ { ELSEIF, "ElseIf" },
+ { END, "End" },
+ { ENDENUM, "End Enum" },
+ { ENDFUNC, "End Function" },
+ { ENDIF, "End If" },
+ { ENDPROPERTY, "End Property" },
+ { ENDSELECT,"End Select" },
+ { ENDSUB, "End Sub" },
+ { ENDTYPE, "End Type" },
+ { ENDIF, "EndIf" },
+ { ENUM, "Enum" },
+ { EQV, "Eqv" },
+ { ERASE, "Erase" },
+ { _ERROR_, "Error" },
+ { EXIT, "Exit" },
+ { EXPLICIT, "Explicit" },
+ { FOR, "For" },
+ { FUNCTION, "Function" },
+ { GET, "Get" },
+ { GLOBAL, "Global" },
+ { GOSUB, "GoSub" },
+ { GOTO, "GoTo" },
+ { IF, "If" },
+ { IMP, "Imp" },
+ { IMPLEMENTS, "Implements" },
+ { _IN_, "In" },
+ { INPUT, "Input" }, // auch INPUT #
+ { TINTEGER, "Integer" },
+ { IS, "Is" },
+ { LET, "Let" },
+ { LIB, "Lib" },
+ { LINE, "Line" },
+ { LINEINPUT,"Line Input" },
+ { LOCAL, "Local" },
+ { LOCK, "Lock" },
+ { TLONG, "Long" },
+ { LOOP, "Loop" },
+ { LPRINT, "LPrint" },
+ { LSET, "LSet" }, // JSM
+ { MOD, "Mod" },
+ { NAME, "Name" },
+ { NEW, "New" },
+ { NEXT, "Next" },
+ { NOT, "Not" },
+ { TOBJECT, "Object" },
+ { ON, "On" },
+ { OPEN, "Open" },
+ { OPTION, "Option" },
+ { _OPTIONAL_, "Optional" },
+ { OR, "Or" },
+ { OUTPUT, "Output" },
+ { PARAMARRAY, "ParamArray" },
+ { PRESERVE, "Preserve" },
+ { PRINT, "Print" },
+ { PRIVATE, "Private" },
+ { PROPERTY, "Property" },
+ { PUBLIC, "Public" },
+ { RANDOM, "Random" },
+ { READ, "Read" },
+ { REDIM, "ReDim" },
+ { REM, "Rem" },
+ { RESUME, "Resume" },
+ { RETURN, "Return" },
+ { RSET, "RSet" }, // JSM
+ { SELECT, "Select" },
+ { SET, "Set" },
+#ifdef SHARED
+#undef SHARED
+#define tmpSHARED
+#endif
+ { SHARED, "Shared" },
+#ifdef tmpSHARED
+#define SHARED
+#undef tmpSHARED
+#endif
+ { TSINGLE, "Single" },
+ { STATIC, "Static" },
+ { STEP, "Step" },
+ { STOP, "Stop" },
+ { TSTRING, "String" },
+ { SUB, "Sub" },
+ { STOP, "System" },
+ { TEXT, "Text" },
+ { THEN, "Then" },
+ { TO, "To", },
+ { TYPE, "Type" },
+ { TYPEOF, "TypeOf" },
+ { UNTIL, "Until" },
+ { TVARIANT, "Variant" },
+ { VBASUPPORT, "VbaSupport" },
+ { WEND, "Wend" },
+ { WHILE, "While" },
+ { WITH, "With" },
+ { WRITE, "Write" }, // auch WRITE #
+ { XOR, "Xor" },
+ { NIL, "" }
+};
+
+/*
+TokenTable aTokTable_Java [] = { // Token-Tabelle:
+
+ { JS_LOG_NOT, "!" },
+ { JS_NE, "!=" },
+ { JS_MOD, "%" },
+ { JS_ASS_MOD, "%=" },
+ { JS_BIT_AND, "&" },
+ { JS_LOG_AND, "&&" },
+ { JS_ASS_AND, "&=" },
+ { JS_LPAREN, "(" },
+ { JS_RPAREN, ")" },
+ { JS_MUL, "*" },
+ { JS_ASS_MUL, "*=" },
+ { JS_PLUS, "+" },
+ { JS_INC, "++" },
+ { JS_ASS_PLUS, "+=" },
+ { JS_COMMA, "," },
+ { JS_MINUS, "-" },
+ { JS_DEC, "--" },
+ { JS_ASS_MINUS, "-=" },
+ { JS_DIV, "/" },
+ { JS_ASS_DIV, "/=" },
+ { JS_COND_SEL, ":" },
+ { JS_LT, "<" },
+ { JS_LSHIFT, "<<" },
+ { JS_ASS_LSHIFT,"<<=" },
+ { JS_LE, "<=" },
+ { JS_NE, "<>" },
+ { JS_ASSIGNMENT,"=" },
+ { JS_EQ, "==" },
+ { JS_GT, ">" },
+ { JS_RSHIFT, ">>" },
+ { JS_ASS_RSHIFT,">>=" },
+ { JS_RSHIFT_Z, ">>>" },
+ { JS_ASS_RSHIFT_Z,">>>=" },
+ { JS_GE, ">=" },
+ { JS_COND_QUEST,"?" },
+ { ACCESS, "Access" },
+ { ALIAS, "Alias" },
+ { AND, "And" },
+ { ANY, "Any" },
+ { APPEND, "Append" },
+ { AS, "As" },
+ { BASE, "Base" },
+ { BINARY, "Binary" },
+ { TBOOLEAN, "Boolean" },
+ { BYVAL, "ByVal", },
+ { CALL, "Call" },
+ { CASE, "Case" },
+ { _CDECL_, "Cdecl" },
+ { CLOSE, "Close" },
+ { COMPARE, "Compare" },
+ { _CONST_, "Const" },
+ { TCURRENCY,"Currency" },
+ { TDATE, "Date" },
+ { DECLARE, "Declare" },
+ { DEFBOOL, "DefBool" },
+ { DEFCUR, "DefCur" },
+ { DEFDATE, "DefDate" },
+ { DEFDBL, "DefDbl" },
+ { DEFERR, "DefErr" },
+ { DEFINT, "DefInt" },
+ { DEFLNG, "DefLng" },
+ { DEFOBJ, "DefObj" },
+ { DEFSNG, "DefSng" },
+ { DEFSTR, "DefStr" },
+ { DEFVAR, "DefVar" },
+ { DIM, "Dim" },
+ { DO, "Do" },
+ { TDOUBLE, "Double" },
+ { EACH, "Each" },
+ { ELSE, "Else" },
+ { ELSEIF, "ElseIf" },
+ { END, "End" },
+ { ENDFUNC, "End Function" },
+ { ENDIF, "End If" },
+ { ENDSELECT,"End Select" },
+ { ENDSUB, "End Sub" },
+ { ENDTYPE, "End Type" },
+ { ENDIF, "EndIf" },
+ { EQV, "Eqv" },
+ { ERASE, "Erase" },
+ { _ERROR_, "Error" },
+ { EXIT, "Exit" },
+ { EXPLICIT, "Explicit" },
+ { FOR, "For" },
+ { FUNCTION, "Function" },
+ { GLOBAL, "Global" },
+ { GOSUB, "GoSub" },
+ { GOTO, "GoTo" },
+ { IF, "If" },
+ { IMP, "Imp" },
+ { _IN_, "In" },
+ { INPUT, "Input" }, // auch INPUT #
+ { TINTEGER, "Integer" },
+ { IS, "Is" },
+ { LET, "Let" },
+ { LIB, "Lib" },
+ { LINE, "Line" },
+ { LINEINPUT,"Line Input" },
+ { LOCAL, "Local" },
+ { LOCK, "Lock" },
+ { TLONG, "Long" },
+ { LOOP, "Loop" },
+ { LPRINT, "LPrint" },
+ { LSET, "LSet" }, // JSM
+ { MOD, "Mod" },
+ { NAME, "Name" },
+ { NEW, "New" },
+ { NEXT, "Next" },
+ { NOT, "Not" },
+ { TOBJECT, "Object" },
+ { ON, "On" },
+ { OPEN, "Open" },
+ { OPTION, "Option" },
+ { _OPTIONAL_, "Optional" },
+ { OR, "Or" },
+ { OUTPUT, "Output" },
+ { PRESERVE, "Preserve" },
+ { PRINT, "Print" },
+ { PRIVATE, "Private" },
+ { PUBLIC, "Public" },
+ { RANDOM, "Random" },
+ { READ, "Read" },
+ { REDIM, "ReDim" },
+ { REM, "Rem" },
+ { RESUME, "Resume" },
+ { RETURN, "Return" },
+ { RSET, "RSet" }, // JSM
+ { SELECT, "Select" },
+ { SET, "Set" },
+ { SHARED, "Shared" },
+ { TSINGLE, "Single" },
+ { STATIC, "Static" },
+ { STEP, "Step" },
+ { STOP, "Stop" },
+ { TSTRING, "String" },
+ { SUB, "Sub" },
+ { STOP, "System" },
+ { TEXT, "Text" },
+ { THEN, "Then" },
+ { TO, "To", },
+ { TYPE, "Type" },
+ { UNTIL, "Until" },
+ { TVARIANT, "Variant" },
+ { WEND, "Wend" },
+ { WHILE, "While" },
+ { WITH, "With" },
+ { WRITE, "Write" }, // auch WRITE #
+ { XOR, "Xor" },
+ { JS_LINDEX, "[" },
+ { JS_RINDEX, "]" },
+ { JS_BIT_XOR, "^" },
+ { JS_ASS_XOR, "^=" },
+ { JS_BIT_OR, "|" },
+ { JS_ASS_OR, "|=" },
+ { JS_LOG_OR, "||" },
+ { JS_BIT_NOT, "~" },
+ { NIL }
+};
+*/
+
+// Der Konstruktor ermittelt die Laenge der Token-Tabelle.
+
+SbiTokenizer::SbiTokenizer( const ::rtl::OUString& rSrc, StarBASIC* pb )
+ : SbiScanner( rSrc, pb )
+{
+ pTokTable = aTokTable_Basic;
+ //if( StarBASIC::GetGlobalLanguageMode() == SB_LANG_JAVASCRIPT )
+ // pTokTable = aTokTable_Java;
+ TokenTable *tp;
+ bEof = bAs = FALSE;
+ eCurTok = NIL;
+ ePush = NIL;
+ bEos = bKeywords = bErrorIsSymbol = TRUE;
+ if( !nToken )
+ for( nToken = 0, tp = pTokTable; tp->t; nToken++, tp++ ) {}
+}
+
+SbiTokenizer::~SbiTokenizer()
+{}
+
+// Einlesen des naechsten Tokens, ohne dass das Token geschluckt wird
+
+SbiToken SbiTokenizer::Peek()
+{
+ if( ePush == NIL )
+ {
+ USHORT nOldLine = nLine;
+ USHORT nOldCol1 = nCol1;
+ USHORT nOldCol2 = nCol2;
+ ePush = Next();
+ nPLine = nLine; nLine = nOldLine;
+ nPCol1 = nCol1; nCol1 = nOldCol1;
+ nPCol2 = nCol2; nCol2 = nOldCol2;
+ }
+ return eCurTok = ePush;
+}
+
+// Einlesen des naechsten Tokens und Ablage desselben
+// Tokens, die nicht in der Token-Tabelle vorkommen, werden
+// direkt als Zeichen zurueckgeliefert.
+// Einige Worte werden gesondert behandelt.
+
+SbiToken SbiTokenizer::Next()
+{
+ if (bEof) return EOLN;
+ // Schon eines eingelesen?
+ if( ePush != NIL )
+ {
+ eCurTok = ePush;
+ ePush = NIL;
+ nLine = nPLine;
+ nCol1 = nPCol1;
+ nCol2 = nPCol2;
+ bEos = IsEoln( eCurTok );
+ return eCurTok;
+ }
+ TokenTable *tp;
+
+ // Sonst einlesen:
+ if( !NextSym() )
+ {
+ bEof = bEos = TRUE;
+ return eCurTok = EOLN;
+ }
+ // Zeilenende?
+ if( aSym.GetBuffer()[0] == '\n' )
+ {
+ bEos = TRUE; return eCurTok = EOLN;
+ }
+ bEos = FALSE;
+
+ // Zahl?
+ if( bNumber )
+ return eCurTok = NUMBER;
+
+ // String?
+ else if( ( eScanType == SbxDATE || eScanType == SbxSTRING ) && !bSymbol )
+ return eCurTok = FIXSTRING;
+ // Sonderfaelle von Zeichen, die zwischen "Z" und "a" liegen. ICompare()
+ // wertet die Position dieser Zeichen unterschiedlich aus.
+ else if( aSym.GetBuffer()[0] == '^' )
+ return eCurTok = EXPON;
+ else if( aSym.GetBuffer()[0] == '\\' )
+ return eCurTok = IDIV;
+ else
+ {
+ // Mit Typkennung oder ein Symbol und keine Keyword-Erkennung?
+ // Dann kein Token-Test
+ if( eScanType != SbxVARIANT
+ || ( !bKeywords && bSymbol ) )
+ return eCurTok = SYMBOL;
+ // Gueltiges Token?
+ short lb = 0;
+ short ub = nToken-1;
+ short delta;
+ do
+ {
+ delta = (ub - lb) >> 1;
+ tp = &pTokTable[ lb + delta ];
+ StringCompare res = aSym.CompareIgnoreCaseToAscii( tp->s );
+ // Gefunden?
+ if( res == COMPARE_EQUAL ) goto special;
+ // Groesser? Dann untere Haelfte
+ if( res == COMPARE_LESS )
+ {
+ if ((ub - lb) == 2) ub = lb;
+ else ub = ub - delta;
+ }
+ // Kleiner? Dann obere Haelfte
+ else
+ {
+ if ((ub -lb) == 2) lb = ub;
+ else lb = lb + delta;
+ }
+ } while( delta );
+ // Symbol? Wenn nicht >= Token
+ sal_Unicode ch = aSym.GetBuffer()[0];
+ if( !BasicSimpleCharClass::isAlpha( ch, bCompatible ) && !bSymbol )
+ return eCurTok = (SbiToken) (ch & 0x00FF);
+ return eCurTok = SYMBOL;
+ }
+special:
+ // LINE INPUT
+ if( tp->t == LINE )
+ {
+ short nC1 = nCol1;
+ String aOldSym = aSym;
+ eCurTok = Peek();
+ if( eCurTok == INPUT )
+ {
+ Next();
+ nCol1 = nC1;
+ return eCurTok = LINEINPUT;
+ }
+ else
+ {
+ aSym = aOldSym;
+ return eCurTok = LINE;
+ }
+ }
+ // END IF, CASE, SUB, DEF, FUNCTION, TYPE, CLASS, WITH
+ if( tp->t == END )
+ {
+ // AB, 15.3.96, Spezialbehandlung fuer END, beim Peek() geht die
+ // aktuelle Zeile verloren, daher alles merken und danach restaurieren
+ USHORT nOldLine = nLine;
+ USHORT nOldCol = nCol;
+ USHORT nOldCol1 = nCol1;
+ USHORT nOldCol2 = nCol2;
+ String aOldSym = aSym;
+ SaveLine(); // pLine im Scanner sichern
+
+ eCurTok = Peek();
+ switch( eCurTok )
+ {
+ case IF: Next(); eCurTok = ENDIF; break;
+ case SELECT: Next(); eCurTok = ENDSELECT; break;
+ case SUB: Next(); eCurTok = ENDSUB; break;
+ case FUNCTION: Next(); eCurTok = ENDFUNC; break;
+ case PROPERTY: Next(); eCurTok = ENDPROPERTY; break;
+ case TYPE: Next(); eCurTok = ENDTYPE; break;
+ case ENUM: Next(); eCurTok = ENDENUM; break;
+ case WITH: Next(); eCurTok = ENDWITH; break;
+ default : eCurTok = END;
+ }
+ nCol1 = nOldCol1;
+ if( eCurTok == END )
+ {
+ // Alles zuruecksetzen, damit Token nach END ganz neu gelesen wird
+ ePush = NIL;
+ nLine = nOldLine;
+ nCol = nOldCol;
+ nCol2 = nOldCol2;
+ aSym = aOldSym;
+ RestoreLine(); // pLine im Scanner restaurieren
+ }
+ return eCurTok;
+ }
+ // Sind Datentypen Keywords?
+ // Nur nach AS, sonst sind es Symbole!
+ // Es gibt ja ERROR(), DATA(), STRING() etc.
+ eCurTok = tp->t;
+ // AS: Datentypen sind Keywords
+ if( tp->t == AS )
+ bAs = TRUE;
+ else
+ {
+ if( bAs )
+ bAs = FALSE;
+ else if( eCurTok >= DATATYPE1 && eCurTok <= DATATYPE2 && (bErrorIsSymbol || eCurTok != _ERROR_) )
+ eCurTok = SYMBOL;
+ }
+
+ // CLASSMODULE, PROPERTY, GET, ENUM token only visible in compatible mode
+ SbiToken eTok = tp->t;
+ if( bCompatible )
+ {
+ // #129904 Suppress system
+ if( eTok == STOP && aSym.CompareIgnoreCaseToAscii( "system" ) == COMPARE_EQUAL )
+ eCurTok = SYMBOL;
+ }
+ else
+ {
+ if( eTok == CLASSMODULE ||
+ eTok == IMPLEMENTS ||
+ eTok == PARAMARRAY ||
+ eTok == ENUM ||
+ eTok == PROPERTY ||
+ eTok == GET ||
+ eTok == TYPEOF )
+ {
+ eCurTok = SYMBOL;
+ }
+ }
+
+ bEos = IsEoln( eCurTok );
+ return eCurTok;
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/inc/buffer.hxx b/binfilter/bf_basic/source/inc/buffer.hxx
new file mode 100644
index 000000000000..bd232febdc3c
--- /dev/null
+++ b/binfilter/bf_basic/source/inc/buffer.hxx
@@ -0,0 +1,66 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _BUFFER_HXX
+#define _BUFFER_HXX
+
+#include <tools/solar.h>
+#include <tools/string.hxx>
+
+namespace binfilter {
+
+class SbiParser;
+
+class SbiBuffer { // Code/Konstanten-Puffer:
+ SbiParser* pParser; // fuer Fehlermeldungen
+ char* pBuf; // Puffer-Pointer
+ char* pCur; // aktueller Puffer-Pointer
+ UINT32 nOff; // aktuelles Offset
+ UINT32 nSize; // aktuelle Groesse
+ short nInc; // Inkrement
+ BOOL Check( USHORT ); // Buffergroesse testen
+public:
+ SbiBuffer( SbiParser*, short ); // Inkrement
+ ~SbiBuffer();
+ BOOL operator += (const String&);// Basic-String speichern
+ BOOL operator += (INT8); // Zeichen speichern
+ BOOL operator += (INT16); // Integer speichern
+ BOOL operator += (UINT8); // Zeichen speichern
+ BOOL operator += (UINT16); // Integer speichern
+ BOOL operator += (UINT32); // Integer speichern
+ BOOL operator += (INT32); // Integer speichern
+ char* GetBuffer(); // Puffer rausgeben (selbst loeschen!)
+ char* GetBufferPtr(){ return pBuf; }
+ UINT32 GetSize() { return nOff; }
+};
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/inc/codegen.hxx b/binfilter/bf_basic/source/inc/codegen.hxx
new file mode 100644
index 000000000000..290c5a999f6c
--- /dev/null
+++ b/binfilter/bf_basic/source/inc/codegen.hxx
@@ -0,0 +1,96 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _CODEGEN_HXX
+#define _CODEGEN_HXX
+
+namespace binfilter {
+
+class SbiImage;
+class SbiParser;
+class SbModule;
+
+class SbiCodeGen { // Code-Erzeugung:
+/*?*/ // SbiParser* pParser; // fuer Fehlermeldungen, Line, Column etc.
+/*?*/ // SbModule& rMod; // aktuelles Modul
+/*?*/ // SbiBuffer aCode; // Code-Puffer
+/*?*/ // short nLine, nCol; // Zeile, Spalte fuer Stmnt-Befehl
+/*?*/ // short nForLevel; // #29955 for-Schleifen-Ebene
+/*?*/ // BOOL bStmnt; // TRUE: Statement-Opcode liegt an
+public:
+/*?*/ // SbiCodeGen( SbModule&, SbiParser*, short );
+/*?*/ // SbiParser* GetParser() { return pParser; }
+/*?*/ // UINT32 Gen( SbiOpcode );
+/*?*/ // UINT32 Gen( SbiOpcode, UINT32 );
+/*?*/ // UINT32 Gen( SbiOpcode, UINT32, UINT32 );
+/*?*/ // void Patch( UINT32 o, UINT32 v ){ aCode.Patch( o, v ); }
+/*?*/ // void BackChain( UINT32 off ) { aCode.Chain( off ); }
+/*?*/ // void Statement();
+/*?*/ // void GenStmnt(); // evtl. Statement-Opcode erzeugen
+/*?*/ // UINT32 GetPC();
+/*?*/ // UINT32 GetOffset() { return GetPC() + 1; }
+/*?*/ // void Save();
+/*?*/ //
+/*?*/ // // #29955 for-Schleifen-Ebene pflegen
+/*?*/ // void IncForLevel( void ) { nForLevel++; }
+/*?*/ // void DecForLevel( void ) { nForLevel--; }
+/*?*/ //
+ static UINT32 calcNewOffSet( BYTE* pCode, UINT16 nOffset );
+ static UINT16 calcLegacyOffSet( BYTE* pCode, UINT32 nOffset );
+/*?*/ //
+};
+
+template < class T, class S >
+class PCodeBuffConvertor
+{
+ T m_nSize; //
+ BYTE* m_pStart;
+ BYTE* m_pCnvtdBuf;
+ S m_nCnvtdSize; //
+
+ // Disable usual copying symantics and bodgy default ctor
+ PCodeBuffConvertor();
+ PCodeBuffConvertor(const PCodeBuffConvertor& );
+ PCodeBuffConvertor& operator = ( const PCodeBuffConvertor& );
+public:
+ PCodeBuffConvertor( BYTE* pCode, T nSize ): m_nSize( nSize ), m_pStart( pCode ), m_pCnvtdBuf( NULL ), m_nCnvtdSize( 0 ){ convert(); }
+ S GetSize(){ return m_nCnvtdSize; }
+ void convert();
+ // Caller owns the buffer returned
+ BYTE* GetBuffer() { return m_pCnvtdBuf; }
+};
+
+// #111897 PARAM_INFO flags start at 0x00010000 to not
+// conflict with DefaultId in SbxParamInfo::nUserData
+#define PARAM_INFO_PARAMARRAY 0x0010000
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/inc/filefmt.hxx b/binfilter/bf_basic/source/inc/filefmt.hxx
new file mode 100644
index 000000000000..8805d0253a01
--- /dev/null
+++ b/binfilter/bf_basic/source/inc/filefmt.hxx
@@ -0,0 +1,185 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SB_FILEFMT_HXX
+#define _SB_FILEFMT_HXX
+
+#include <tools/solar.h>
+
+class SvStream;
+
+namespace binfilter {
+
+// Version 2: Datentyp des Returnwerts fuer Publics
+// Version 3: neue Opcodes
+// Version 4: neue Opcodes
+// Version 5: Bug (Ansprung von STATIC-Variablen im Init-Code)
+// Version 6: Neue Opcodes und Bug (Globals anlegen, ohne BASIC zu beenden)
+// Version 7: Korrektur im WITH-Parsing
+// Version 8: Korrektur im IF-Parsing
+// Version 9: Init-Code auch mit LEAVE beenden, wenn keine SUB/FUNCTION folgt
+// Version A: #36374 Bei DIM AS NEW... auch Variablen anlegen
+// Version B: #40689 Static umgestellt
+// Version C: #41606 Bug bei Static
+// Version D: #42678 Bug bei RTL-Function spc
+// Version E: #56204 DCREATE, um auch bei DIM AS NEW Arrays anzulegen
+// Version F: #57844 Einfuehrung von SvNumberformat::StringToDouble
+// Version 10: #29955 For-Schleifen-Level in Statement-PCodes generieren
+// Version 11: #29955 Wegen Build-Inkonsistenzen Neu-Compilieren erzwingen
+
+#define B_LEGACYVERSION 0x00000011L
+#define B_CURVERSION 0x00000012L
+#define B_EXT_IMG_VERSION 0x00000012L
+
+// Eine Datei enthaelt entweder einen Modul- oder einen Library-Record.
+// Diese Records enthalten wiederum weitere Records. Jeder Record hat
+// den folgenden Header:
+
+// UINT16 Kennung
+// UINT32 Laenge des Records ohne Header
+// UINT16 Anzahl Unterelemente
+
+// Alle Datei-Offsets in Records sind relativ zum Start des Moduls!
+
+#define B_LIBRARY 0x4C42 // BL Library Record
+#define B_MODULE 0x4D42 // BM Module Record
+#define B_NAME 0x4E4D // MN module name
+#define B_COMMENT 0x434D // MC comment
+#define B_SOURCE 0x4353 // SC source code
+#define B_PCODE 0x4350 // PC p-code
+#define B_OLDPUBLICS 0x7550 // Pu publics
+#define B_PUBLICS 0x5550 // PU publics
+#define B_POOLDIR 0x4450 // PD symbol pool directory
+#define B_SYMPOOL 0x5953 // SY symbol pool
+#define B_STRINGPOOL 0x5453 // ST symbol pool
+#define B_LINERANGES 0x524C // LR line ranges for publics
+#define B_MODEND 0x454D // ME module end
+#define B_SBXOBJECTS 0x5853 // SX SBX objects
+
+#define EXTENDED_BINARY_MODULES
+#ifdef EXTENDED_BINARY_MODULES
+#define B_EXTSOURCE 0x5345 // ES extended source
+#endif
+
+// Ein Library Record enthaelt nur Module Records
+// UINT16 Kennung BL
+// UINT32 Laenge des Records
+// UINT16 Anzahl Module
+
+// Ein Modul-Record enthaelt alle anderen Recordtypen
+// UINT16 Kennung BM
+// UINT32 Laenge des Records
+// UINT16 1
+// Daten:
+// UINT32 Versionsnummer
+// UINT32 Zeichensatz
+// UINT32 Startadresse Initialisierungscode
+// UINT32 Startadresse Sub Main
+// UINT32 Reserviert
+// UINT32 Reserviert
+
+// Modulname, Kommentar und Quellcode:
+// UINT16 Kennung MN, MC oder SC
+// UINT32 Laenge des Records
+// UINT16 1
+// Daten:
+// String-Instanz
+
+// P-Code:
+// UINT16 Kennung PC
+// UINT32 Laenge des Records
+// UINT16 1
+// Daten:
+// Der P-Code als Bytesack
+
+// Alle Symbole und Strings werden in einem String-Pool gehalten.
+// Verweise auf diese Strings sind in Form eines Indexes in diesen Pool.
+
+// Liste aller Publics:
+// UINT16 Kennung PU oder Pu
+// UINT32 Laenge des Records
+// UINT16 Anzahl der Publics
+// Daten fuer jeden Public-Eintrag:
+// UINT16 String-Index
+// UINT32 Startadresse im P-Code-Image (UINT16 fuer alte Publics)
+// UINT16 Datentyp des Returnwertes (ab Version 2)
+
+// Verzeichnis der Symbol-Tabellen:
+// UINT16 Kennung SP
+// UINT32 Laenge des Records
+// UINT16 Anzahl der Symboltabellen
+// Daten fuer jede Symboltabelle:
+// UINT16 Stringindex des Namens
+// UINT16 Anzahl Symbole
+// UINT16 Scope-Kennung
+
+// Symboltabelle:
+// UINT16 Kennung SY
+// UINT32 Laenge des Records
+// UINT16 Anzahl der Symbole
+// Daten:
+// UINT16 Stringindex des Namens
+// UINT16 Anzahl Symbole
+// Daten fuer jedes Symbol:
+// UINT16 Stringindex des Namens
+// UINT16 Datentyp
+// UINT16 Laenge bei STRING*n-Symbolen (0x8000: STATIC-Variable)
+
+// Stringpool:
+// UINT16 Kennung ST
+// UINT32 Laenge des Records
+// UINT16 Anzahl der Strings
+// Daten fuer jeden String:
+// UINT32 Offset in den Block aller Strings
+// Danach folgt der Block aller Strings, die dort als ASCIIZ-Strings liegen.
+
+// Line Ranges:
+// UINT16 Kennung LR
+// UINT32 Laenge des Records
+// UINT16 Anzahl der Strings
+// Daten fuer jedes Public:
+// UINT16 1. Zeile (Sub XXX)
+// UINT16 2. Zeile (End Sub)
+
+// SBX-Objekte:
+// UINT16 Anzahl Objekte
+// .... Objektdaten
+
+////////////////////////////////////////////////////////////////////////////
+
+// Service-Routinen (in IMAGE.CXX)
+
+BOOL SbGood( SvStream& r );
+ULONG SbOpenRecord( SvStream&, UINT16 nSignature, UINT16 nElem );
+void SbCloseRecord( SvStream&, ULONG );
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/inc/image.hxx b/binfilter/bf_basic/source/inc/image.hxx
new file mode 100644
index 000000000000..cc317931978d
--- /dev/null
+++ b/binfilter/bf_basic/source/inc/image.hxx
@@ -0,0 +1,109 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SBIMAGE_HXX
+#define _SBIMAGE_HXX
+
+#include "sbintern.hxx"
+#include <rtl/ustring.hxx>
+#include "filefmt.hxx"
+
+// Diese Klasse liest das vom Compiler erzeugte Image ein und verwaltet
+// den Zugriff auf die einzelnen Elemente.
+
+namespace binfilter {
+
+struct SbPublicEntry;
+
+class SbiImage {
+ friend class SbiCodeGen; // Compiler-Klassen, die die private-
+
+ SbxArrayRef rTypes; // User defined types
+ SbxArrayRef rEnums; // Enum types
+ UINT32* pStringOff; // StringId-Offsets
+ sal_Unicode* pStrings; // StringPool
+ char* pCode; // Code-Image
+ char* pLegacyPCode; // Code-Image
+ BOOL bError; // TRUE: Fehler
+ USHORT nFlags; // Flags (s.u.)
+ short nStrings; // Anzahl Strings
+ UINT32 nStringSize; // Groesse des String-Puffers
+ UINT32 nCodeSize; // Groesse des Code-Blocks
+ UINT16 nLegacyCodeSize; // Groesse des Code-Blocks
+ UINT16 nDimBase; // OPTION BASE-Wert
+ rtl_TextEncoding eCharSet; // Zeichensatz fuer Strings
+ // temporaere Verwaltungs-Variable:
+ short nStringIdx; // aktueller String-Index
+ UINT32 nStringOff; // aktuelle Pos im Stringpuffer
+ // Routinen fuer Compiler:
+ void MakeStrings( short ); // StringPool einrichten
+
+public:
+ String aName; // Makroname
+ ::rtl::OUString aOUSource; // Quellcode
+ String aComment; // Kommentar
+ BOOL bInit; // TRUE: Init-Code ist gelaufen
+ BOOL bFirstInit; // TRUE, wenn das Image das erste mal nach
+ // dem Compilieren initialisiert wird.
+ SbiImage();
+ ~SbiImage();
+ void Clear(); // Inhalt loeschen
+ BOOL Load( SvStream&, UINT32& nVer ); // Loads image from stream
+ // nVer is set to version
+ // of image
+ BOOL Save( SvStream&, UINT32 = B_CURVERSION );
+ BOOL IsError() { return bError; }
+
+ const char* GetCode() const { return pCode; }
+ UINT32 GetCodeSize() const { return nCodeSize; }
+ ::rtl::OUString& GetSource32() { return aOUSource; }
+ USHORT GetBase() const { return nDimBase; }
+ const SbxObject* FindType (String aTypeName) const;
+
+ SbxArrayRef GetEnums() { return rEnums; }
+
+ void SetFlag( USHORT n ) { nFlags |= n; }
+ USHORT GetFlag( USHORT n ) const { return nFlags & n; }
+ UINT16 CalcLegacyOffset( INT32 nOffset );
+ UINT32 CalcNewOffset( INT16 nOffset );
+ void ReleaseLegacyBuffer();
+ BOOL ExceedsLegacyLimits();
+
+};
+
+#define SBIMG_EXPLICIT 0x0001 // OPTION EXPLICIT ist aktiv
+#define SBIMG_COMPARETEXT 0x0002 // OPTION COMPARE TEXT ist aktiv
+#define SBIMG_INITCODE 0x0004 // Init-Code vorhanden
+#define SBIMG_CLASSMODULE 0x0008 // OPTION ClassModule is active
+#define SBIMG_VBASUPPORT 0x0020 // OPTION VBASupport is 1
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/inc/opcodes.hxx b/binfilter/bf_basic/source/inc/opcodes.hxx
new file mode 100644
index 000000000000..a670ed029639
--- /dev/null
+++ b/binfilter/bf_basic/source/inc/opcodes.hxx
@@ -0,0 +1,168 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _OPCODES_HXX
+#define _OPCODES_HXX
+
+#include "sbintern.hxx"
+
+#ifdef MTW
+#undef _NUMBER
+#endif
+
+// Ein Opcode ist entweder 1, 3 oder 5 Bytes lang, je nach numerischen
+// Wert des Opcodes (s.u.).
+
+enum SbiOpcode {
+ // Alle Opcodes ohne Operanden
+ _NOP = 0,
+
+ SbOP0_START = _NOP,
+
+ // Operatoren
+ // die folgenden Operatoren sind genauso angeordnet
+ // wie der enum SbxVarOp
+ _EXP, _MUL, _DIV, _MOD, _PLUS, _MINUS, _NEG,
+ _EQ, _NE, _LT, _GT, _LE, _GE,
+ _IDIV, _AND, _OR, _XOR, _EQV, _IMP, _NOT,
+ _CAT,
+ // Ende enum SbxVarOp
+ _LIKE, _IS,
+ // Laden/speichern
+ _ARGC, // neuen Argv einrichten
+ _ARGV, // TOS ==> aktueller Argv
+ _INPUT, // Input ==> TOS
+ _LINPUT, // Line Input ==> TOS
+ _GET, // TOS anfassen
+ _SET, // Speichern Objekt TOS ==> TOS-1
+ _PUT, // TOS ==> TOS-1
+ _PUTC, // TOS ==> TOS-1, dann ReadOnly
+ _DIM, // DIM
+ _REDIM, // REDIM
+ _REDIMP, // REDIM PRESERVE
+ _ERASE, // TOS loeschen
+ // Verzweigen
+ _STOP, // Programmende
+ _INITFOR, // FOR-Variable initialisieren
+ _NEXT, // FOR-Variable inkrementieren
+ _CASE, // Anfang CASE
+ _ENDCASE, // Ende CASE
+ _STDERROR, // Standard-Fehlerbehandlung
+ _NOERROR, // keine Fehlerbehandlung
+ _LEAVE, // UP verlassen
+ // E/A
+ _CHANNEL, // TOS = Kanalnummer
+ _BPRINT, // print TOS
+ _PRINTF, // print TOS in field
+ _BWRITE, // write TOS
+ _RENAME, // Rename Tos+1 to Tos
+ _PROMPT, // TOS = Prompt for Input
+ _RESTART, // Restartpunkt definieren
+ _CHAN0, // I/O-Kanal 0
+ // Sonstiges
+ _EMPTY, // Leeren Ausdruck auf Stack
+ _ERROR, // TOS = Fehlercode
+ _LSET, // Speichern Objekt TOS ==> TOS-1
+ _RSET, // Speichern Objekt TOS ==> TOS-1
+ _REDIMP_ERASE, // Copies array to be later used by REDIM PRESERVE before erasing it
+ _INITFOREACH,
+ _VBASET, // VBA-like Set
+ SbOP0_END,
+
+ // Alle Opcodes mit einem Operanden
+
+ _NUMBER = 0x40, // Laden einer numerischen Konstanten (+ID)
+
+ SbOP1_START = _NUMBER,
+
+ _SCONST, // Laden einer Stringkonstanten (+ID)
+ _CONST, // Immediate Load (+Wert)
+ _ARGN, // Speichern eines named Args in Argv (+StringID)
+ _PAD, // String auf feste Laenge bringen (+Laenge)
+ // Verzweigungen
+ _JUMP, // Sprung (+Target)
+ _JUMPT, // TOS auswerten, bedingter Sprung (+Target)
+ _JUMPF, // TOS auswerten, bedingter Sprung (+Target)
+ _ONJUMP, // TOS auswerten, Sprung in JUMP-Tabelle (+MaxVal)
+ _GOSUB, // UP-Aufruf (+Target)
+ _RETURN, // UP-Return (+0 oder Target)
+ _TESTFOR, // FOR-Variable testen, inkrementieren (+Endlabel)
+ _CASETO, // Tos+1 <= Case <= Tos, 2xremove (+Target)
+ _ERRHDL, // Fehler-Handler (+Offset)
+ _RESUME, // Resume nach Fehlern (+0 or 1 or Label)
+ // E/A
+ _CLOSE, // (+Kanal/0)
+ _PRCHAR, // (+char)
+ // Verwaltung
+ _SETCLASS, // Set + Klassennamen testen (+StringId)
+ _TESTCLASS, // Check TOS class (+StringId)
+ _LIB, // Libnamen fuer Declare-Procs setzen (+StringId)
+ _BASED, // TOS wird um BASE erhoeht, BASE davor gepusht (+base)
+ // Typanpassung im Argv
+ _ARGTYP, // Letzten Parameter in Argv konvertieren (+Typ)
+ SbOP1_END,
+
+ // Alle Opcodes mit zwei Operanden
+
+ _RTL = 0x80, // Laden aus RTL (+StringID+Typ)
+
+ SbOP2_START = _RTL,
+
+ _FIND, // Laden (+StringID+Typ)
+ _ELEM, // Laden Element (+StringID+Typ)
+ _PARAM, // Parameter (+Offset+Typ)
+ // Verzweigen
+ _CALL, // DECLARE-Methode rufen (+StringID+Typ)
+ _CALLC, // Cdecl-DECLARE-Methode rufen (+StringID+Typ)
+ _CASEIS, // Case-Test (+Test-Opcode+True-Target)
+ // Verwaltung
+ _STMNT, // Beginn eines Statements (+Line+Col)
+ // E/A
+ _OPEN, // (+SvStreamFlags+Flags)
+ // Objekte
+ _LOCAL, // Lokale Variable definieren (+StringID+Typ)
+ _PUBLIC, // Modulglobale Variable (+StringID+Typ)
+ _GLOBAL, // Globale Variable definieren, public-Anweisung (+StringID+Typ)
+ _CREATE, // Objekt kreieren (+StringId+StringID)
+ _STATIC, // Statische Variabl (+StringID+Typ) JSM
+ _TCREATE, // User Defined Objekt kreieren
+ _DCREATE, // Objekt-Array kreieren (+StringId+StringID)
+ _GLOBAL_P, // Globale Variable definieren, die beim Neustart von Basic
+ // nicht ueberschrieben wird, P=PERSIST (+StringID+Typ)
+ _FIND_G, // Sucht globale Variable mit Spezialbehandlung wegen _GLOBAL_P
+ _DCREATE_REDIMP, // Objekt-Array redimensionieren (+StringId+StringID)
+ _FIND_CM, // Search inside a class module (CM) to enable global search in time
+ SbOP2_END
+
+};
+
+
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/inc/sbintern.hxx b/binfilter/bf_basic/source/inc/sbintern.hxx
new file mode 100644
index 000000000000..01ec2fea482d
--- /dev/null
+++ b/binfilter/bf_basic/source/inc/sbintern.hxx
@@ -0,0 +1,141 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SB_INTERN_HXX
+#define _SB_INTERN_HXX
+
+#include <sbxfac.hxx>
+#include <unotools/transliterationwrapper.hxx>
+#include "sb.hxx"
+
+namespace
+{
+ class TransliterationWrapper;
+}
+
+namespace binfilter {
+
+class SbUnoFactory;
+class SbTypeFactory;
+class SbOLEFactory;
+class SbiInstance;
+class SbModule;
+
+class SbiFactory : public SbxFactory
+{
+public:
+ virtual SbxBase* Create( UINT16 nSbxId, UINT32 = SBXCR_SBX );
+ virtual SbxObject* CreateObject( const String& );
+};
+
+struct SbClassData
+{
+ SbxArrayRef mxIfaces;
+
+ ~SbClassData( void )
+ { clear(); }
+ void clear( void );
+};
+
+// #115824: Factory class to create class objects (type command)
+// Implementation: sb.cxx
+class SbClassFactory : public SbxFactory
+{
+ SbxObjectRef xClassModules;
+
+public:
+ SbClassFactory( void );
+ virtual ~SbClassFactory();
+
+ virtual SbxBase* Create( UINT16 nSbxId, UINT32 = SBXCR_SBX );
+ virtual SbxObject* CreateObject( const String& );
+};
+
+// Stack fuer die im Fehlerfall abgebaute SbiRuntime Kette
+class SbErrorStackEntry
+{
+public:
+ SbErrorStackEntry(SbMethodRef aM, xub_StrLen nL, xub_StrLen nC1, xub_StrLen nC2)
+ : aMethod(aM), nLine(nL), nCol1(nC1), nCol2(nC2) {}
+ SbMethodRef aMethod;
+ xub_StrLen nLine;
+ xub_StrLen nCol1, nCol2;
+};
+
+SV_DECL_PTRARR_DEL(SbErrorStack, SbErrorStackEntry*, 1, 1)
+
+
+
+struct SbiGlobals
+{
+ SbiInstance* pInst; // alle aktiven Runtime-Instanzen
+ SbiFactory* pSbFac; // StarBASIC-Factory
+ SbUnoFactory* pUnoFac; // Factory fuer Uno-Structs bei DIM AS NEW
+ SbTypeFactory* pTypeFac; // Factory for user defined types
+ SbClassFactory* pClassFac; // Factory for user defined classes (based on class modules)
+ SbOLEFactory* pOLEFac; // Factory for OLE types
+ SbModule* pMod; // aktuell aktives Modul
+ SbModule* pCompMod; // aktuell compiliertes Modul
+ short nInst; // Anzahl BASICs
+ Link aErrHdl; // globaler Error-Handler
+ Link aBreakHdl; // globaler Break-Handler
+ SbError nCode; // aktueller Fehlercode
+ xub_StrLen nLine; // aktuelle Zeile
+ xub_StrLen nCol1,nCol2; // aktuelle Spalten (von,bis)
+ BOOL bCompiler; // Flag fuer Compiler-Error
+ BOOL bGlobalInitErr; // Beim GlobalInit trat ein Compiler-Fehler auf
+ BOOL bRunInit; // TRUE, wenn RunInit vom Basic aktiv ist
+ String aErrMsg; // Puffer fuer GetErrorText()
+ SbLanguageMode eLanguageMode; // Flag fuer Visual-Basic-Script-Modus
+ SbErrorStack* pErrStack; // Stack fuer die im Fehlerfall abgebaute SbiRuntime Kette
+ ::utl::TransliterationWrapper* pTransliterationWrapper; // For StrComp
+ BOOL bBlockCompilerError;
+ BasicManager* pAppBasMgr;
+
+ SbiGlobals();
+ ~SbiGlobals();
+};
+
+// Utility-Makros und -Routinen
+
+SbiGlobals* GetSbData();
+
+#define pINST GetSbData()->pInst
+#define pMOD GetSbData()->pMod
+#define pCMOD GetSbData()->pCompMod
+#define pSBFAC GetSbData()->pSbFac
+#define pUNOFAC GetSbData()->pUnoFac
+#define pTYPEFAC GetSbData()->pTypeFac
+#define pCLASSFAC GetSbData()->pClassFac
+#define pOLEFAC GetSbData()->pOLEFac
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/inc/sbjsmeth.hxx b/binfilter/bf_basic/source/inc/sbjsmeth.hxx
new file mode 100644
index 000000000000..dfd9c85c5a88
--- /dev/null
+++ b/binfilter/bf_basic/source/inc/sbjsmeth.hxx
@@ -0,0 +1,60 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef _SB_SBJSMETH_HXX
+#define _SB_SBJSMETH_HXX
+
+#include "sbmeth.hxx"
+
+namespace binfilter {
+
+// Basic-Modul fuer JavaScript-Sourcen.
+// Alle Basic-spezifischen Methoden muessen virtuell ueberladen und deaktiviert
+// werden. Die Unterscheidung von normalen Modulen erfolgt uebr RTTI.
+
+class SbJScriptMethod : public SbMethod
+{
+public:
+ SbJScriptMethod( const String&, SbxDataType, SbModule* );
+ virtual ~SbJScriptMethod();
+
+ SBX_DECL_PERSIST_NODATA(SBXCR_SBX,SBXID_JSCRIPTMETH,2);
+ TYPEINFO();
+};
+
+#ifndef __SB_SBJSCRIPTMETHODREF_HXX
+#define __SB_SBJSCRIPTMETHODREF_HXX
+SV_DECL_IMPL_REF(SbJScriptMethod)
+#endif
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/inc/sbjsmod.hxx b/binfilter/bf_basic/source/inc/sbjsmod.hxx
new file mode 100644
index 000000000000..835f23a72fb0
--- /dev/null
+++ b/binfilter/bf_basic/source/inc/sbjsmod.hxx
@@ -0,0 +1,54 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SB_SBJSMOD_HXX
+#define _SB_SBJSMOD_HXX
+
+#include "sbmod.hxx"
+
+namespace binfilter {
+
+// Basic-Modul fuer JavaScript-Sourcen.
+// Alle Basic-spezifischen Methoden muessen virtuell ueberladen und deaktiviert
+// werden. Die Unterscheidung von normalen Modulen erfolgt uebr RTTI.
+
+class SbJScriptModule : public SbModule
+{
+ virtual BOOL LoadData( SvStream&, USHORT );
+ virtual BOOL StoreData( SvStream& ) const;
+public:
+ SBX_DECL_PERSIST_NODATA(SBXCR_SBX,SBXID_JSCRIPTMOD,1);
+ TYPEINFO();
+ SbJScriptModule( const String& ); // DURCHREICHEN
+};
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/inc/sbunoobj.hxx b/binfilter/bf_basic/source/inc/sbunoobj.hxx
new file mode 100644
index 000000000000..47e93dab804a
--- /dev/null
+++ b/binfilter/bf_basic/source/inc/sbunoobj.hxx
@@ -0,0 +1,250 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SB_UNO_OBJ
+#define SB_UNO_OBJ
+
+#include "sbxobj.hxx"
+#include "sbxmeth.hxx"
+#include "sbxprop.hxx"
+#include "sbxfac.hxx"
+#include "sbx.hxx"
+
+#include <com/sun/star/beans/XMaterialHolder.hpp>
+#include <com/sun/star/beans/XExactName.hpp>
+#include <com/sun/star/beans/XIntrospectionAccess.hpp>
+#include <com/sun/star/beans/XIntrospection.hpp>
+#include <com/sun/star/script/XInvocation.hpp>
+#include <com/sun/star/reflection/XIdlClass.hpp>
+#ifndef _RTL_USTRING_
+#include <rtl/ustring.hxx>
+#endif
+
+namespace binfilter {
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::script;
+using namespace com::sun::star::reflection;
+
+class SbUnoObject: public SbxObject
+{
+ Reference< XIntrospectionAccess > mxUnoAccess;
+ Reference< XMaterialHolder > mxMaterialHolder;
+ Reference< XInvocation > mxInvocation;
+ Reference< XExactName > mxExactName;
+ Reference< XExactName > mxExactNameInvocation;
+ BOOL bNeedIntrospection;
+ Any maTmpUnoObj; // Only to save obj for doIntrospection!
+
+ // Hilfs-Methode zum Anlegen der dbg_-Properties
+ void implCreateDbgProperties( void );
+
+ // Hilfs-Methode zum Anlegen aller Properties und Methoden
+ // (Beim on-demand-Mechanismus erforderlich fuer die dbg_-Properties)
+ void implCreateAll( void );
+
+public:
+ TYPEINFO();
+ SbUnoObject( const String& aName_, const Any& aUnoObj_ );
+ ~SbUnoObject();
+
+ // #76470 Introspection on Demand durchfuehren
+ void doIntrospection( void );
+
+ // Find ueberladen, um z.B. NameAccess zu unterstuetzen
+ virtual SbxVariable* Find( const String&, SbxClassType );
+
+ // Force creation of all properties for debugging
+ void createAllProperties( void )
+ { implCreateAll(); }
+
+ // Wert rausgeben
+ Any getUnoAny( void );
+ Reference< XIntrospectionAccess > getIntrospectionAccess( void ) { return mxUnoAccess; }
+ Reference< XInvocation > getInvocation( void ) { return mxInvocation; }
+
+ void SFX_NOTIFY( SfxBroadcaster&, const TypeId&, const SfxHint& rHint, const TypeId& );
+};
+SV_DECL_IMPL_REF(SbUnoObject);
+
+
+class SbUnoMethod : public SbxMethod
+{
+ friend class SbUnoObject;
+
+ Reference< XIdlMethod > m_xUnoMethod;
+ Sequence<ParamInfo>* pParamInfoSeq;
+
+ // #67781 Verweis auf vorige und naechste Methode in der Methoden-Liste
+ SbUnoMethod* pPrev;
+ SbUnoMethod* pNext;
+
+ bool mbInvocation; // Method is based on invocation
+
+public:
+ TYPEINFO();
+
+ SbUnoMethod( const String& aName_, SbxDataType eSbxType, Reference< XIdlMethod > xUnoMethod_,
+ bool bInvocation );
+ virtual ~SbUnoMethod();
+ virtual SbxInfo* GetInfo();
+
+ const Sequence<ParamInfo>& getParamInfos( void );
+
+ bool isInvocationBased( void )
+ { return mbInvocation; }
+};
+
+
+class SbUnoProperty : public SbxProperty
+{
+ friend class SbUnoObject;
+
+ // Daten der Uno-Property
+ Property aUnoProp;
+ INT32 nId;
+
+ bool mbInvocation; // Property is based on invocation
+
+ virtual ~SbUnoProperty();
+public:
+ TYPEINFO();
+ SbUnoProperty( const String& aName_, SbxDataType eSbxType,
+ const Property& aUnoProp_, INT32 nId_, bool bInvocation );
+
+ bool isInvocationBased( void )
+ { return mbInvocation; }
+};
+
+// Factory-Klasse fuer das Anlegen von Uno-Structs per DIM AS NEW
+class SbUnoFactory : public SbxFactory
+{
+public:
+ virtual SbxBase* Create( UINT16 nSbxId, UINT32 = SBXCR_SBX );
+ virtual SbxObject* CreateObject( const String& );
+};
+
+// Wrapper fuer eine Uno-Klasse
+class SbUnoClass: public SbxObject
+{
+ const Reference< XIdlClass > m_xClass;
+
+public:
+ TYPEINFO();
+ SbUnoClass( const String& aName_ )
+ : SbxObject( aName_ )
+ {}
+ SbUnoClass( const String& aName_, const Reference< XIdlClass >& xClass_ )
+ : SbxObject( aName_ )
+ , m_xClass( xClass_ )
+ {}
+ //~SbUnoClass();
+
+ // Find ueberladen, um Elemente on Demand anzulegen
+ virtual SbxVariable* Find( const String&, SbxClassType );
+
+ // Wert rausgeben
+ const Reference< XIdlClass >& getUnoClass( void ) { return m_xClass; }
+
+ //void SFX_NOTIFY( SfxBroadcaster&, const TypeId&, const SfxHint& rHint, const TypeId& );
+};
+SV_DECL_IMPL_REF(SbUnoClass);
+
+
+// Funktion, um einen globalen Bezeichner im
+// UnoScope zu suchen und fuer Sbx zu wrappen
+SbxVariable* findUnoClass( const String& rName );
+
+
+// #105565 Special Object to wrap a strongly typed Uno Any
+class SbUnoAnyObject: public SbxObject
+{
+ Any mVal;
+
+public:
+ SbUnoAnyObject( const Any& rVal )
+ : SbxObject( String() )
+ , mVal( rVal )
+ {}
+
+ const Any& getValue( void )
+ { return mVal; }
+
+ TYPEINFO();
+};
+
+
+// #112509 Special SbxArray to transport named parameters for calls
+// to OLEAutomation objects through the UNO OLE automation bridge
+
+class AutomationNamedArgsSbxArray : public SbxArray
+{
+ Sequence< ::rtl::OUString > maNameSeq;
+public:
+ TYPEINFO();
+ AutomationNamedArgsSbxArray( sal_Int32 nSeqSize )
+ : maNameSeq( nSeqSize )
+ {}
+
+ Sequence< ::rtl::OUString >& getNames( void )
+ { return maNameSeq; }
+};
+
+
+class StarBASIC;
+
+//========================================================================
+// #118116 Collection object
+
+class BasicCollection : public SbxObject
+{
+ friend class SbiRuntime;
+ SbxArrayRef xItemArray;
+
+ void Initialize();
+ virtual ~BasicCollection();
+ virtual void SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
+ const SfxHint& rHint, const TypeId& rHintType );
+ INT32 implGetIndex( SbxVariable* pIndexVar );
+ INT32 implGetIndexForName( const String& rName );
+ void CollAdd( SbxArray* pPar_ );
+ void CollItem( SbxArray* pPar_ );
+ void CollRemove( SbxArray* pPar_ );
+
+public:
+ TYPEINFO();
+ BasicCollection( const String& rClassname );
+ virtual SbxVariable* Find( const String&, SbxClassType );
+ virtual void Clear();
+};
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/inc/scanner.hxx b/binfilter/bf_basic/source/inc/scanner.hxx
new file mode 100644
index 000000000000..068cb627bbb7
--- /dev/null
+++ b/binfilter/bf_basic/source/inc/scanner.hxx
@@ -0,0 +1,147 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SCANNER_HXX
+#define _SCANNER_HXX
+
+#include <tools/string.hxx>
+#include "sberrors.hxx"
+
+namespace binfilter {
+
+// Der Scanner ist stand-alone, d.h. er kann von ueberallher verwendet
+// werden. Eine BASIC-Instanz ist fuer Fehlermeldungen notwendig. Ohne
+// BASIC werden die Fehler nur gezaehlt. Auch ist Basic notwendig, wenn
+// eine erweiterte SBX-Variable zur Erkennung von Datentypen etc. verwendet
+// werden soll.
+
+class StarBASIC;
+
+class SbiScanner
+{
+ ::rtl::OUString aBuf; // Input-Puffer
+ ::rtl::OUString aLine; // aktuelle Zeile
+ const sal_Unicode* pLine; // Pointer
+ const sal_Unicode* pSaveLine; // Merker fuer Line
+protected:
+ String aSym; // Symbolpuffer
+ String aError; // Fehler-String
+ SbxDataType eScanType; // evtl. Datentyp
+ StarBASIC* pBasic; // Instanz fuer Fehler-Callbacks
+ double nVal; // numerischer Wert
+ short nCurCol1; // aktuelle Spalte 1
+ short nSavedCol1; // gerettete Spalte 1
+ short nCol; // aktuelle Spaltennummer
+ short nErrors; // Anzahl Fehler
+ short nColLock; // Lock-Zaehler fuer Col1
+ INT32 nBufPos; // aktuelle Buffer-Pos
+ USHORT nLine; // aktuelle Zeile
+ USHORT nCol1, nCol2; // aktuelle 1. und 2. Spalte
+ BOOL bSymbol; // TRUE: Symbol gescannt
+ BOOL bNumber; // TRUE: Zahl gescannt
+ BOOL bSpaces; // TRUE: Whitespace vor Token
+ BOOL bErrors; // TRUE: Fehler generieren
+ BOOL bAbort; // TRUE: abbrechen
+ BOOL bHash; // TRUE: # eingelesen
+ BOOL bError; // TRUE: Fehler generieren
+ BOOL bUsedForHilite; // TRUE: Nutzung fuer Highlighting
+ BOOL bCompatible; // TRUE: OPTION Compatible
+ BOOL bPrevLineExtentsComment; // TRUE: Previous line is comment and ends on "... _"
+
+ void GenError( SbError );
+public:
+ SbiScanner( const ::rtl::OUString&, StarBASIC* = NULL );
+ ~SbiScanner();
+
+ void EnableErrors() { bError = FALSE; }
+ BOOL IsHash() { return bHash; }
+ BOOL IsCompatible() { return bCompatible; }
+ void SetCompatible( bool b ) { bCompatible = b; } // #118206
+ BOOL WhiteSpace() { return bSpaces; }
+ short GetErrors() { return nErrors; }
+ short GetLine() { return nLine; }
+ short GetCol1() { return nCol1; }
+ short GetCol2() { return nCol2; }
+ void SetCol1( short n ) { nCol1 = n; }
+ StarBASIC* GetBasic() { return pBasic; }
+ void SaveLine(void) { pSaveLine = pLine; }
+ void RestoreLine(void) { pLine = pSaveLine; }
+ void LockColumn();
+ void UnlockColumn();
+
+ BOOL NextSym(); // naechstes Symbol lesen
+ const String& GetSym() { return aSym; }
+ SbxDataType GetType() { return eScanType; }
+ double GetDbl() { return nVal; }
+};
+
+class LetterTable
+{
+ bool IsLetterTab[256];
+
+public:
+ LetterTable( void );
+
+ inline bool isLetter( sal_Unicode c )
+ {
+ bool bRet = (c < 256) ? IsLetterTab[c] : isLetterUnicode( c );
+ return bRet;
+ }
+ bool isLetterUnicode( sal_Unicode c );
+};
+
+class BasicSimpleCharClass
+{
+ static LetterTable aLetterTable;
+
+public:
+ static BOOL isAlpha( sal_Unicode c, bool bCompatible )
+ {
+ BOOL bRet = (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
+ || (bCompatible && aLetterTable.isLetter( c ));
+ return bRet;
+ }
+
+ static BOOL isDigit( sal_Unicode c )
+ {
+ BOOL bRet = (c >= '0' && c <= '9');
+ return bRet;
+ }
+
+ static BOOL isAlphaNumeric( sal_Unicode c, bool bCompatible )
+ {
+ BOOL bRet = isDigit( c ) || isAlpha( c, bCompatible );
+ return bRet;
+ }
+};
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/inc/token.hxx b/binfilter/bf_basic/source/inc/token.hxx
new file mode 100644
index 000000000000..6b6196741a74
--- /dev/null
+++ b/binfilter/bf_basic/source/inc/token.hxx
@@ -0,0 +1,159 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _TOKEN_HXX
+#define _TOKEN_HXX
+
+#include "scanner.hxx"
+#include "sbdef.hxx"
+
+#if defined( SHARED )
+#define SbiTokenSHAREDTMPUNDEF
+#undef SHARED
+#endif
+
+namespace binfilter {
+
+// Der Tokenizer ist stand-alone, d.h. er kann von ueberallher verwendet
+// werden. Eine BASIC-Instanz ist fuer Fehlermeldungen notwendig. Ohne
+// BASIC werden die Fehler nur gezaehlt. Auch ist Basic notwendig, wenn
+// eine erweiterte SBX-Variable zur Erkennung von Datentypen etc. verwendet
+// werden soll.
+
+enum SbiToken {
+ NIL = 0,
+ // Token zwischen 0x20 und 0x3F sind Literale:
+ LPAREN = '(', RPAREN = ')', COMMA = ',', DOT = '.', EXCLAM = '!',
+ HASH = '#', SEMICOLON = ';',
+
+ // Anweisungen:
+ FIRSTKWD = 0x40,
+ AS = FIRSTKWD, ALIAS, ASSIGN,
+ CALL, CASE, CLOSE, COMPARE, _CONST_,
+ DECLARE, DIM, DO,
+
+ // in der Reihenfolge der Datentyp-Enums!
+ DEFINT, DEFLNG, DEFSNG, DEFDBL, DEFCUR, DEFDATE, DEFSTR, DEFOBJ,
+ DEFERR, DEFBOOL, DEFVAR,
+ // in der Reihenfolge der Datentyp-Enums!
+ DATATYPE1,
+ TINTEGER = DATATYPE1,
+ TLONG, TSINGLE, TDOUBLE, TCURRENCY, TDATE, TSTRING, TOBJECT,
+ _ERROR_, TBOOLEAN, TVARIANT, TBYTE,
+ DATATYPE2 = TBYTE,
+
+ EACH, ELSE, ELSEIF, END, ERASE, EXIT,
+ FOR, FUNCTION,
+ GET, GLOBAL, GOSUB, GOTO,
+ IF, _IN_, INPUT,
+ LET, LINE, LINEINPUT, LOCAL, LOOP, LPRINT, LSET,
+ NAME, NEW, NEXT,
+ ON, OPEN, OPTION, IMPLEMENTS,
+ PRINT, PRIVATE, PROPERTY, PUBLIC,
+ REDIM, REM, RESUME, RETURN, RSET,
+ SELECT, SET, SHARED, STATIC, STEP, STOP, SUB,
+ TEXT, THEN, TO, TYPE, ENUM,
+ UNTIL,
+ WEND, WHILE, WITH, WRITE,
+ ENDENUM, ENDIF, ENDFUNC, ENDPROPERTY, ENDSUB, ENDTYPE, ENDSELECT, ENDWITH,
+ // Ende aller Keywords
+ LASTKWD = ENDWITH,
+ // Statement-Ende
+ EOS, EOLN,
+ // Operatoren:
+ EXPON, NEG, MUL,
+ DIV, IDIV, MOD, PLUS, MINUS,
+ EQ, NE, LT, GT, LE, GE,
+ NOT, AND, OR, XOR, EQV,
+ IMP, CAT, LIKE, IS, TYPEOF,
+ // Sonstiges:
+ FIRSTEXTRA,
+ NUMBER=FIRSTEXTRA, FIXSTRING, SYMBOL, _CDECL_, BYVAL, BYREF,
+ OUTPUT, RANDOM, APPEND, BINARY, ACCESS,
+ LOCK, READ, PRESERVE, BASE, ANY, LIB, _OPTIONAL_,
+ EXPLICIT, COMPATIBLE, CLASSMODULE, PARAMARRAY,
+
+ // Ab hier kommen JavaScript-Tokens (gleiches enum, damit gleicher Typ)
+ FIRSTJAVA,
+ JS_BREAK=FIRSTJAVA, JS_CONTINUE, JS_FOR, JS_FUNCTION, JS_IF, JS_NEW,
+ JS_RETURN, JS_THIS, JS_VAR, JS_WHILE, JS_WITH,
+
+ // JavaScript-Operatoren
+ // _ASS_ = Assignment
+ JS_COMMA, JS_ASSIGNMENT, JS_ASS_PLUS, JS_ASS_MINUS, JS_ASS_MUL,
+ JS_ASS_DIV, JS_ASS_MOD, JS_ASS_LSHIFT, JS_ASS_RSHIFT, JS_ASS_RSHIFT_Z,
+ JS_ASS_AND, JS_ASS_XOR, JS_ASS_OR,
+ JS_COND_QUEST, JS_COND_SEL, JS_LOG_OR, JS_LOG_AND, JS_BIT_OR,
+ JS_BIT_XOR, JS_BIT_AND, JS_EQ, JS_NE, JS_LT, JS_LE,
+ JS_GT, JS_GE, JS_LSHIFT, JS_RSHIFT, JS_RSHIFT_Z,
+ JS_PLUS, JS_MINUS, JS_MUL, JS_DIV, JS_MOD, JS_LOG_NOT, JS_BIT_NOT,
+ JS_INC, JS_DEC, JS_LPAREN, JS_RPAREN, JS_LINDEX, JS_RINDEX
+ , VBASUPPORT
+};
+
+#ifdef SbiTokenSHAREDTMPUNDEF
+#define SHARED
+#undef SbiTokenSHAREDTMPUNDEF
+#endif
+
+class SbiTokenizer : public SbiScanner {
+protected:
+ SbiToken eCurTok; // aktuelles Token
+ SbiToken ePush; // Pushback-Token
+ USHORT nPLine, nPCol1, nPCol2; // Pushback-Location
+ BOOL bEof; // TRUE bei Dateiende
+ BOOL bEos; // TRUE bei Statement-Ende
+ BOOL bKeywords; // TRUE, falls Keywords geparst werden
+ BOOL bAs; // letztes Keyword war AS
+ BOOL bErrorIsSymbol; // Handle Error token as Symbol, not keyword
+public:
+ SbiTokenizer( const ::rtl::OUString&, StarBASIC* = NULL );
+ ~SbiTokenizer();
+
+ inline BOOL IsEof() { return bEof; }
+ inline BOOL IsEos() { return bEos; }
+
+ SbiToken Peek(); // das naechste Token lesen
+ SbiToken Next(); // Ein Token lesen
+ void Error( SbError c ) { GenError( c ); }
+
+ void Keywords( BOOL b ) { bKeywords = b; }
+
+ static BOOL IsEoln( SbiToken t )
+ { return BOOL( t == EOS || t == EOLN || t == REM ); }
+ static BOOL IsKwd( SbiToken t )
+ { return BOOL( t >= FIRSTKWD && t <= LASTKWD ); }
+ static BOOL IsExtra( SbiToken t )
+ { return BOOL( t >= FIRSTEXTRA ); }
+};
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/runtime/basrdll.cxx b/binfilter/bf_basic/source/runtime/basrdll.cxx
new file mode 100644
index 000000000000..a2efc14d8b5f
--- /dev/null
+++ b/binfilter/bf_basic/source/runtime/basrdll.cxx
@@ -0,0 +1,92 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "basrdll.hxx"
+
+namespace binfilter {
+
+/*?*/ // BasicResId::BasicResId( USHORT nId ):
+/*?*/ // ResId( nId, (*(BasicDLL**)GetAppData(SHL_BASIC))->GetResMgr() )
+/*?*/ // {
+/*?*/ // }
+
+BasicDLL::BasicDLL()
+{
+/*?*/ // *(BasicDLL**)GetAppData(SHL_BASIC) = this;
+/*?*/ // ::com::sun::star::lang::Locale aLocale = Application::GetSettings().GetUILocale();
+/*?*/ // pResMgr = ResMgr::CreateResMgr(CREATEVERSIONRESMGR_NAME(ofa), aLocale );
+ bDebugMode = FALSE;
+ bBreakEnabled = TRUE;
+}
+
+BasicDLL::~BasicDLL()
+{
+/*?*/ // delete pResMgr;
+}
+
+/*?*/ // void BasicDLL::EnableBreak( BOOL bEnable )
+/*?*/ // {
+/*?*/ // BasicDLL* pThis = *(BasicDLL**)GetAppData(SHL_BASIC);
+/*?*/ // DBG_ASSERT( pThis, "BasicDLL::EnableBreak: Noch keine Instanz!" );
+/*?*/ // if ( pThis )
+/*?*/ // pThis->bBreakEnabled = bEnable;
+/*?*/ // }
+/*?*/ //
+/*?*/ // void BasicDLL::SetDebugMode( BOOL bDebugMode )
+/*?*/ // {
+/*?*/ // BasicDLL* pThis = *(BasicDLL**)GetAppData(SHL_BASIC);
+/*?*/ // DBG_ASSERT( pThis, "BasicDLL::EnableBreak: Noch keine Instanz!" );
+/*?*/ // if ( pThis )
+/*?*/ // pThis->bDebugMode = bDebugMode;
+/*?*/ // }
+/*?*/ //
+/*?*/ //
+/*?*/ // void BasicDLL::BasicBreak()
+/*?*/ // {
+/*?*/ // //bJustStopping: Wenn jemand wie wild x-mal STOP drueckt, aber das Basic
+/*?*/ // // nicht schnell genug anhaelt, kommt die Box ggf. oefters...
+/*?*/ // static BOOL bJustStopping = FALSE;
+/*?*/ //
+/*?*/ // BasicDLL* pThis = *(BasicDLL**)GetAppData(SHL_BASIC);
+/*?*/ // DBG_ASSERT( pThis, "BasicDLL::EnableBreak: Noch keine Instanz!" );
+/*?*/ // if ( pThis )
+/*?*/ // {
+/*?*/ // if ( StarBASIC::IsRunning() && !bJustStopping && ( pThis->bBreakEnabled || pThis->bDebugMode ) )
+/*?*/ // {
+/*?*/ // bJustStopping = TRUE;
+/*?*/ // StarBASIC::Stop();
+/*?*/ // String aMessageStr( BasicResId( IDS_SBERR_TERMINATED ) );
+/*?*/ // InfoBox( 0, aMessageStr ).Execute();
+/*?*/ // bJustStopping = FALSE;
+/*?*/ // }
+/*?*/ // }
+/*?*/ // }
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/runtime/makefile.mk b/binfilter/bf_basic/source/runtime/makefile.mk
new file mode 100644
index 000000000000..f2553b1e47ca
--- /dev/null
+++ b/binfilter/bf_basic/source/runtime/makefile.mk
@@ -0,0 +1,82 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=binfilter
+TARGET=basic_runtime
+
+NO_HIDS=TRUE
+
+# --- Settings -----------------------------------------------------------
+
+.INCLUDE : settings.mk
+
+INC+= -I$(PRJ)$/inc$/bf_basic
+
+# --- Allgemein -----------------------------------------------------------
+
+SLOFILES= \
+ $(SLO)$/basrdll.obj \
+
+# $(SLO)$/inputbox.obj \
+ $(SLO)$/runtime.obj \
+ $(SLO)$/step0.obj \
+ $(SLO)$/step1.obj \
+ $(SLO)$/step2.obj \
+ $(SLO)$/iosys.obj \
+ $(SLO)$/stdobj.obj \
+ $(SLO)$/stdobj1.obj \
+ $(SLO)$/methods.obj \
+ $(SLO)$/methods1.obj \
+ $(SLO)$/props.obj \
+ $(SLO)$/ddectrl.obj \
+ $(SLO)$/dllmgr.obj
+
+.IF "$(GUI)$(CPU)" == "WINI"
+#SLOFILES+= $(SLO)$/win.obj
+.ENDIF
+
+.IF "$(GUI)$(CPU)" == "WNTI"
+#SLOFILES+= $(SLO)$/wnt.obj
+.ENDIF
+
+.IF "$(GUI)$(CPU)" == "OS2I"
+#SLOFILES+= $(SLO)$/os2.obj
+.ENDIF
+
+#EXCEPTIONSFILES=$(SLO)$/step0.obj \
+ $(SLO)$/step2.obj \
+ $(SLO)$/methods.obj \
+ $(SLO)$/methods1.obj \
+ $(SLO)$/iosys.obj \
+ $(SLO)$/runtime.obj
+
+# --- Targets -------------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/binfilter/bf_basic/source/sbx/makefile.mk b/binfilter/bf_basic/source/sbx/makefile.mk
new file mode 100644
index 000000000000..33335d8eb054
--- /dev/null
+++ b/binfilter/bf_basic/source/sbx/makefile.mk
@@ -0,0 +1,77 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=binfilter
+TARGET=basic_sbx
+
+NO_HIDS=TRUE
+
+# --- Settings -----------------------------------------------------------
+
+.INCLUDE : settings.mk
+
+INC+= -I$(PRJ)$/inc$/bf_basic
+
+# --- Allgemein -----------------------------------------------------------
+
+EXCEPTIONSFILES=$(SLO)$/sbxarray.obj
+
+SLOFILES= \
+ $(EXCEPTIONSFILES) \
+ $(SLO)$/sbxbase.obj \
+ $(SLO)$/sbxvar.obj \
+ $(SLO)$/sbxvalue.obj \
+ $(SLO)$/sbxdec.obj \
+ $(SLO)$/sbxint.obj \
+ $(SLO)$/sbxcurr.obj \
+ $(SLO)$/sbxstr.obj \
+ $(SLO)$/sbxbool.obj \
+ $(SLO)$/sbxdbl.obj \
+ $(SLO)$/sbxdate.obj \
+ $(SLO)$/sbxsng.obj \
+ $(SLO)$/sbxlng.obj \
+ $(SLO)$/sbxobj.obj \
+ $(SLO)$/sbxscan.obj \
+ $(SLO)$/sbxbyte.obj \
+ $(SLO)$/sbxchar.obj \
+ $(SLO)$/sbxulng.obj \
+ $(SLO)$/sbxuint.obj \
+ $(SLO)$/sbxcoll.obj \
+ $(SLO)$/sbxres.obj \
+ $(SLO)$/sbxexec.obj \
+
+# $(SLO)$/sbxvals.obj \
+ $(SLO)$/sbxmstrm.obj \
+
+
+# --- Targets -------------------------------------------------------------
+
+.INCLUDE : target.mk
+
+
diff --git a/binfilter/bf_basic/source/sbx/sbxarray.cxx b/binfilter/bf_basic/source/sbx/sbxarray.cxx
new file mode 100644
index 000000000000..74301330e258
--- /dev/null
+++ b/binfilter/bf_basic/source/sbx/sbxarray.cxx
@@ -0,0 +1,784 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <tools/stream.hxx>
+#include "sbx.hxx"
+#include <vector>
+using namespace std;
+
+namespace binfilter {
+
+struct SbxDim { // eine Array-Dimension:
+ SbxDim* pNext; // Link
+ INT32 nLbound, nUbound; // Begrenzungen
+ INT32 nSize; // Anzahl Elemente
+};
+
+class SbxVarEntry : public SbxVariableRef {
+public:
+ XubString* pAlias;
+ SbxVarEntry() : SbxVariableRef(), pAlias( NULL ) {}
+ ~SbxVarEntry() { delete pAlias; }
+};
+
+typedef SbxVarEntry* SbxVarEntryPtr;
+typedef vector< SbxVarEntryPtr > SbxVarEntryPtrVector;
+class SbxVarRefs : public SbxVarEntryPtrVector
+{
+public:
+ SbxVarRefs( void ) {}
+};
+
+
+TYPEINIT1(SbxArray,SbxBase)
+TYPEINIT1(SbxDimArray,SbxArray)
+
+//////////////////////////////////////////////////////////////////////////
+//
+// SbxArray
+//
+//////////////////////////////////////////////////////////////////////////
+
+SbxArray::SbxArray( SbxDataType t ) : SbxBase()
+{
+ pData = new SbxVarRefs;
+ eType = t;
+ if( t != SbxVARIANT )
+ SetFlag( SBX_FIXED );
+}
+
+SbxArray::SbxArray( const SbxArray& rArray ) :
+ SvRefBase( rArray ), SbxBase()
+{
+ pData = new SbxVarRefs;
+ if( rArray.eType != SbxVARIANT )
+ SetFlag( SBX_FIXED );
+ *this = rArray;
+}
+
+SbxArray& SbxArray::operator=( const SbxArray& rArray )
+{
+ if( &rArray != this )
+ {
+ eType = rArray.eType;
+ Clear();
+ SbxVarRefs* pSrc = rArray.pData;
+ for( UINT32 i = 0; i < pSrc->size(); i++ )
+ {
+ SbxVarEntryPtr pSrcRef = (*pSrc)[i];
+ SbxVarEntryPtr pDstRef = new SbxVarEntry;
+ *((SbxVariableRef*) pDstRef) = *((SbxVariableRef*) pSrcRef);
+ if( pSrcRef->pAlias )
+ pDstRef->pAlias = new XubString( *pSrcRef->pAlias );
+ const SbxVariable* pSrc_ = *pSrcRef;
+ if( pSrc_ )
+ {
+ if( eType != SbxVARIANT )
+ // Keine Objekte konvertieren
+ if( eType != SbxOBJECT || pSrc_->GetClass() != SbxCLASS_OBJECT )
+ ((SbxVariable*) pSrc_)->Convert( eType );
+ pData->push_back( pDstRef );
+ }
+ }
+ }
+ return *this;
+}
+
+SbxArray::~SbxArray()
+{
+ Clear();
+ delete pData;
+}
+
+SbxDataType SbxArray::GetType() const
+{
+ return (SbxDataType) ( eType | SbxARRAY );
+}
+
+SbxClassType SbxArray::GetClass() const
+{
+ return SbxCLASS_ARRAY;
+}
+
+void SbxArray::Clear()
+{
+ UINT32 nSize = pData->size();
+ for( UINT32 i = 0 ; i < nSize ; i++ )
+ {
+ SbxVarEntry* pEntry = (*pData)[i];
+ delete pEntry;
+ }
+ pData->clear();
+}
+
+UINT32 SbxArray::Count32() const
+{
+ return pData->size();
+}
+
+USHORT SbxArray::Count() const
+{
+ UINT32 nCount = pData->size();
+ DBG_ASSERT( nCount <= SBX_MAXINDEX, "SBX: Array-Index > SBX_MAXINDEX" );
+ return (USHORT)nCount;
+}
+
+SbxVariableRef& SbxArray::GetRef32( UINT32 nIdx )
+{
+ // Array ggf. vergroessern
+ DBG_ASSERT( nIdx <= SBX_MAXINDEX32, "SBX: Array-Index > SBX_MAXINDEX32" );
+ // Very Hot Fix
+ if( nIdx > SBX_MAXINDEX32 )
+ {
+ SetError( SbxERR_BOUNDS );
+ nIdx = 0;
+ }
+ while( pData->size() <= nIdx )
+ {
+ const SbxVarEntryPtr p = new SbxVarEntry;
+ pData->push_back( p );
+ }
+ return *((*pData)[nIdx]);
+}
+
+SbxVariableRef& SbxArray::GetRef( USHORT nIdx )
+{
+ // Array ggf. vergroessern
+ DBG_ASSERT( nIdx <= SBX_MAXINDEX, "SBX: Array-Index > SBX_MAXINDEX" );
+ // Very Hot Fix
+ if( nIdx > SBX_MAXINDEX )
+ {
+ SetError( SbxERR_BOUNDS );
+ nIdx = 0;
+ }
+ while( pData->size() <= nIdx )
+ {
+ const SbxVarEntryPtr p = new SbxVarEntry;
+ pData->push_back( p );
+ }
+ return *((*pData)[nIdx]);
+}
+
+SbxVariable* SbxArray::Get32( UINT32 nIdx )
+{
+ if( !CanRead() )
+ {
+ SetError( SbxERR_PROP_WRITEONLY );
+ return NULL;
+ }
+ SbxVariableRef& rRef = GetRef32( nIdx );
+
+ if ( !rRef.Is() )
+ rRef = new SbxVariable( eType );
+
+ return rRef;
+}
+
+SbxVariable* SbxArray::Get( USHORT nIdx )
+{
+ if( !CanRead() )
+ {
+ SetError( SbxERR_PROP_WRITEONLY );
+ return NULL;
+ }
+ SbxVariableRef& rRef = GetRef( nIdx );
+
+ if ( !rRef.Is() )
+ rRef = new SbxVariable( eType );
+
+ return rRef;
+}
+
+void SbxArray::Put32( SbxVariable* pVar, UINT32 nIdx )
+{
+ if( !CanWrite() )
+ SetError( SbxERR_PROP_READONLY );
+ else
+ {
+ if( pVar )
+ if( eType != SbxVARIANT )
+ // Keine Objekte konvertieren
+ if( eType != SbxOBJECT || pVar->GetClass() != SbxCLASS_OBJECT )
+ pVar->Convert( eType );
+ SbxVariableRef& rRef = GetRef32( nIdx );
+ if( (SbxVariable*) rRef != pVar )
+ {
+ rRef = pVar;
+ SetFlag( SBX_MODIFIED );
+ }
+ }
+}
+
+void SbxArray::Put( SbxVariable* pVar, USHORT nIdx )
+{
+ if( !CanWrite() )
+ SetError( SbxERR_PROP_READONLY );
+ else
+ {
+ if( pVar )
+ if( eType != SbxVARIANT )
+ // Keine Objekte konvertieren
+ if( eType != SbxOBJECT || pVar->GetClass() != SbxCLASS_OBJECT )
+ pVar->Convert( eType );
+ SbxVariableRef& rRef = GetRef( nIdx );
+ if( (SbxVariable*) rRef != pVar )
+ {
+ rRef = pVar;
+ SetFlag( SBX_MODIFIED );
+ }
+ }
+}
+
+void SbxArray::Insert32( SbxVariable* pVar, UINT32 nIdx )
+{
+ DBG_ASSERT( pData->size() <= SBX_MAXINDEX32, "SBX: Array wird zu gross" );
+ if( pData->size() > SBX_MAXINDEX32 )
+ return;
+ SbxVarEntryPtr p = new SbxVarEntry;
+ *((SbxVariableRef*) p) = pVar;
+ SbxVarEntryPtrVector::size_type nSize = pData->size();
+ if( nIdx > nSize )
+ nIdx = nSize;
+ if( eType != SbxVARIANT && pVar )
+ (*p)->Convert( eType );
+ if( nIdx == nSize )
+ {
+ pData->push_back( p );
+ }
+ else
+ {
+ pData->insert( pData->begin() + nIdx, p );
+ }
+ SetFlag( SBX_MODIFIED );
+}
+
+void SbxArray::Insert( SbxVariable* pVar, USHORT nIdx )
+{
+ DBG_ASSERT( pData->size() <= 0x3FF0, "SBX: Array wird zu gross" );
+ if( pData->size() > 0x3FF0 )
+ return;
+ Insert32( pVar, nIdx );
+}
+
+void SbxArray::Remove32( UINT32 nIdx )
+{
+ if( nIdx < pData->size() )
+ {
+ SbxVariableRef* pRef = (*pData)[nIdx];
+ pData->erase( pData->begin() + nIdx );
+ delete pRef;
+ SetFlag( SBX_MODIFIED );
+ }
+}
+
+void SbxArray::Remove( USHORT nIdx )
+{
+ if( nIdx < pData->size() )
+ {
+ SbxVariableRef* pRef = (*pData)[nIdx];
+ pData->erase( pData->begin() + nIdx );
+ delete pRef;
+ SetFlag( SBX_MODIFIED );
+ }
+}
+
+void SbxArray::Remove( SbxVariable* pVar )
+{
+ if( pVar )
+ {
+ for( UINT32 i = 0; i < pData->size(); i++ )
+ {
+ SbxVariableRef* pRef = (*pData)[i];
+ // SbxVariableRef* pRef = pData->GetObject( i );
+ if( *pRef == pVar )
+ {
+ Remove32( i ); break;
+ }
+ }
+ }
+}
+
+// Uebernahme der Daten aus dem uebergebenen Array, wobei
+// gleichnamige Variable ueberschrieben werden.
+
+void SbxArray::Merge( SbxArray* p )
+{
+ if( p )
+ {
+ UINT32 nSize = p->Count();
+ for( UINT32 i = 0; i < nSize; i++ )
+ {
+ SbxVarEntryPtr pRef1 = (*(p->pData))[i];
+ // Ist das Element by name schon drin?
+ // Dann ueberschreiben!
+ SbxVariable* pVar = *pRef1;
+ if( pVar )
+ {
+ XubString aName = pVar->GetName();
+ USHORT nHash = pVar->GetHashCode();
+ for( UINT32 j = 0; j < pData->size(); j++ )
+ {
+ SbxVariableRef* pRef2 = (*pData)[j];
+ if( (*pRef2)->GetHashCode() == nHash
+ && (*pRef2)->GetName().EqualsIgnoreCaseAscii( aName ) )
+ {
+ *pRef2 = pVar; pRef1 = NULL;
+ break;
+ }
+ }
+ if( pRef1 )
+ {
+ SbxVarEntryPtr pRef = new SbxVarEntry;
+ const SbxVarEntryPtr pTemp = pRef;
+ pData->push_back( pTemp );
+ *((SbxVariableRef*) pRef) = *((SbxVariableRef*) pRef1);
+ if( pRef1->pAlias )
+ pRef->pAlias = new XubString( *pRef1->pAlias );
+ }
+ }
+ }
+ }
+}
+
+// Suchen eines Elements ueber die Userdaten. Falls ein Element
+// ein Objekt ist, wird dieses ebenfalls durchsucht.
+
+SbxVariable* SbxArray::FindUserData( UINT32 nData )
+{
+ SbxVariable* p = NULL;
+ for( UINT32 i = 0; i < pData->size(); i++ )
+ {
+ SbxVariableRef* pRef = (*pData)[i];
+ SbxVariable* pVar = *pRef;
+ if( pVar )
+ {
+ if( pVar->IsVisible() && pVar->GetUserData() == nData )
+ {
+ p = pVar;
+ p->ResetFlag( SBX_EXTFOUND );
+ break; // JSM 06.10.95
+ }
+ // Haben wir ein Array/Objekt mit Extended Search?
+ else if( pVar->IsSet( SBX_EXTSEARCH ) )
+ {
+ switch( pVar->GetClass() )
+ {
+ case SbxCLASS_OBJECT:
+ {
+ // Objekte duerfen ihren Parent nicht durchsuchen
+ USHORT nOld = pVar->GetFlags();
+ pVar->ResetFlag( SBX_GBLSEARCH );
+ p = ((SbxObject*) pVar)->FindUserData( nData );
+ pVar->SetFlags( nOld );
+ break;
+ }
+ case SbxCLASS_ARRAY:
+ p = ((SbxArray*) pVar)->FindUserData( nData );
+ break;
+ default: break;
+ }
+ if( p )
+ {
+ p->SetFlag( SBX_EXTFOUND );
+ break;
+ }
+ }
+ }
+ }
+ return p;
+}
+
+// Suchen eines Elements ueber den Namen und den Typ. Falls ein Element
+// ein Objekt ist, wird dieses ebenfalls durchsucht.
+
+SbxVariable* SbxArray::Find( const XubString& rName, SbxClassType t )
+{
+ SbxVariable* p = NULL;
+ UINT32 nCount = pData->size();
+ if( !nCount )
+ return NULL;
+ BOOL bExtSearch = IsSet( SBX_EXTSEARCH );
+ USHORT nHash = SbxVariable::MakeHashCode( rName );
+ for( UINT32 i = 0; i < nCount; i++ )
+ {
+ SbxVariableRef* pRef = (*pData)[i];
+ SbxVariable* pVar = *pRef;
+ if( pVar && pVar->IsVisible() )
+ {
+ // Die ganz sichere Suche klappt auch, wenn es
+ // keinen Hascode gibt!
+ USHORT nVarHash = pVar->GetHashCode();
+ if( ( !nVarHash || nVarHash == nHash )
+ && ( t == SbxCLASS_DONTCARE || pVar->GetClass() == t )
+ && ( pVar->GetName().EqualsIgnoreCaseAscii( rName ) ) )
+ {
+ p = pVar;
+ p->ResetFlag( SBX_EXTFOUND );
+ break;
+ }
+ // Haben wir ein Array/Objekt mit Extended Search?
+ else if( bExtSearch && pVar->IsSet( SBX_EXTSEARCH ) )
+ {
+ switch( pVar->GetClass() )
+ {
+ case SbxCLASS_OBJECT:
+ {
+ // Objekte duerfen ihren Parent nicht durchsuchen
+ USHORT nOld = pVar->GetFlags();
+ pVar->ResetFlag( SBX_GBLSEARCH );
+ p = ((SbxObject*) pVar)->Find( rName, t );
+ pVar->SetFlags( nOld );
+ break;
+ }
+ case SbxCLASS_ARRAY:
+ p = ((SbxArray*) pVar)->Find( rName, t );
+ break;
+ default: break;
+ }
+ if( p )
+ {
+ p->SetFlag( SBX_EXTFOUND );
+ break;
+ }
+ }
+ }
+ }
+ return p;
+}
+
+BOOL SbxArray::LoadData( SvStream& rStrm, USHORT nVer )
+{
+ UINT16 nElem;
+ Clear();
+ BOOL bRes = TRUE;
+ USHORT f = nFlags;
+ nFlags |= SBX_WRITE;
+ rStrm >> nElem;
+ nElem &= 0x7FFF;
+ for( UINT32 n = 0; n < nElem; n++ )
+ {
+ UINT16 nIdx;
+ rStrm >> nIdx;
+ SbxVariable* pVar = (SbxVariable*) Load( rStrm );
+ if( pVar )
+ {
+ SbxVariableRef& rRef = GetRef( nIdx );
+ rRef = pVar;
+ }
+ else
+ {
+ bRes = FALSE; break;
+ }
+ }
+ if( bRes )
+ bRes = LoadPrivateData( rStrm, nVer );
+ nFlags = f;
+ return bRes;
+}
+
+BOOL SbxArray::StoreData( SvStream& rStrm ) const
+{
+ UINT32 nElem = 0;
+ UINT32 n;
+ // Welche Elemente sind ueberhaupt definiert?
+ for( n = 0; n < pData->size(); n++ )
+ {
+ SbxVariableRef* pRef = (*pData)[n];
+ SbxVariable* p = *pRef;
+ if( p && !( p->GetFlags() & SBX_DONTSTORE ) )
+ nElem++;
+ }
+ rStrm << (UINT16) nElem;
+ for( n = 0; n < pData->size(); n++ )
+ {
+ SbxVariableRef* pRef = (*pData)[n];
+ SbxVariable* p = *pRef;
+ if( p && !( p->GetFlags() & SBX_DONTSTORE ) )
+ {
+ rStrm << (UINT16) n;
+ if( !p->Store( rStrm ) )
+ return FALSE;
+ }
+ }
+ return StorePrivateData( rStrm );
+}
+
+// #100883 Method to set method directly to parameter array
+void SbxArray::PutDirect( SbxVariable* pVar, UINT32 nIdx )
+{
+ SbxVariableRef& rRef = GetRef32( nIdx );
+ rRef = pVar;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+//
+// SbxArray
+//
+//////////////////////////////////////////////////////////////////////////
+
+SbxDimArray::SbxDimArray( SbxDataType t ) : SbxArray( t )
+{
+ pFirst = pLast = NULL;
+ nDim = 0;
+}
+
+SbxDimArray::SbxDimArray( const SbxDimArray& rArray )
+ : SvRefBase( rArray ), SbxArray( rArray.eType )
+{
+ pFirst = pLast = NULL;
+ nDim = 0;
+ *this = rArray;
+}
+
+SbxDimArray& SbxDimArray::operator=( const SbxDimArray& rArray )
+{
+ if( &rArray != this )
+ {
+ SbxArray::operator=( (const SbxArray&) rArray );
+ SbxDim* p = rArray.pFirst;
+ while( p )
+ {
+ AddDim32( p->nLbound, p->nUbound );
+ p = p->pNext;
+ }
+ }
+ return *this;
+}
+
+SbxDimArray::~SbxDimArray()
+{
+ Clear();
+}
+
+void SbxDimArray::Clear()
+{
+ SbxDim* p = pFirst;
+ while( p )
+ {
+ SbxDim* q = p->pNext;
+ delete p;
+ p = q;
+ }
+ pFirst = pLast = NULL;
+ nDim = 0;
+}
+
+// Dimension hinzufuegen
+
+void SbxDimArray::AddDimImpl32( INT32 lb, INT32 ub, BOOL bAllowSize0 )
+{
+ SbxError eRes = SbxERR_OK;
+ if( ub < lb && !bAllowSize0 )
+ {
+ eRes = SbxERR_BOUNDS;
+ ub = lb;
+ }
+ SbxDim* p = new SbxDim;
+ p->nLbound = lb;
+ p->nUbound = ub;
+ p->nSize = ub - lb + 1;
+ p->pNext = NULL;
+ if( !pFirst )
+ pFirst = pLast = p;
+ else
+ pLast->pNext = p, pLast = p;
+ nDim++;
+ if( eRes )
+ SetError( eRes );
+}
+
+void SbxDimArray::AddDim( short lb, short ub )
+{
+ AddDimImpl32( lb, ub, FALSE );
+}
+
+void SbxDimArray::unoAddDim( short lb, short ub )
+{
+ AddDimImpl32( lb, ub, TRUE );
+}
+
+void SbxDimArray::AddDim32( INT32 lb, INT32 ub )
+{
+ AddDimImpl32( lb, ub, FALSE );
+}
+
+void SbxDimArray::unoAddDim32( INT32 lb, INT32 ub )
+{
+ AddDimImpl32( lb, ub, TRUE );
+}
+
+
+// Dimensionsdaten auslesen
+
+BOOL SbxDimArray::GetDim32( INT32 n, INT32& rlb, INT32& rub ) const
+{
+ if( n < 1 || n > nDim )
+ {
+ SetError( SbxERR_BOUNDS ); rub = rlb = 0; return FALSE;
+ }
+ SbxDim* p = pFirst;
+ while( --n )
+ p = p->pNext;
+ rub = p->nUbound;
+ rlb = p->nLbound;
+ return TRUE;
+}
+
+BOOL SbxDimArray::GetDim( short n, short& rlb, short& rub ) const
+{
+ INT32 rlb32, rub32;
+ BOOL bRet = GetDim32( n, rlb32, rub32 );
+ if( bRet )
+ {
+ if( rlb32 < -SBX_MAXINDEX || rub32 > SBX_MAXINDEX )
+ {
+ SetError( SbxERR_BOUNDS );
+ return FALSE;
+ }
+ rub = (short)rub32;
+ rlb = (short)rlb32;
+ }
+ return bRet;
+}
+
+// Element-Ptr anhand einer Index-Liste
+
+UINT32 SbxDimArray::Offset32( const INT32* pIdx )
+{
+ UINT32 nPos = 0;
+ for( SbxDim* p = pFirst; p; p = p->pNext )
+ {
+ INT32 nIdx = *pIdx++;
+ if( nIdx < p->nLbound || nIdx > p->nUbound )
+ {
+ nPos = (UINT32)SBX_MAXINDEX32 + 1; break;
+ }
+ nPos = nPos * p->nSize + nIdx - p->nLbound;
+ }
+ if( nDim == 0 || nPos > SBX_MAXINDEX32 )
+ {
+ SetError( SbxERR_BOUNDS ); nPos = 0;
+ }
+ return nPos;
+}
+
+USHORT SbxDimArray::Offset( const short* pIdx )
+{
+ long nPos = 0;
+ for( SbxDim* p = pFirst; p; p = p->pNext )
+ {
+ short nIdx = *pIdx++;
+ if( nIdx < p->nLbound || nIdx > p->nUbound )
+ {
+ nPos = SBX_MAXINDEX + 1; break;
+ }
+ nPos = nPos * p->nSize + nIdx - p->nLbound;
+ }
+ if( nDim == 0 || nPos > SBX_MAXINDEX )
+ {
+ SetError( SbxERR_BOUNDS ); nPos = 0;
+ }
+ return (USHORT) nPos;
+}
+
+SbxVariable* SbxDimArray::Get( const short* pIdx )
+{
+ return SbxArray::Get( Offset( pIdx ) );
+}
+
+SbxVariable* SbxDimArray::Get32( const INT32* pIdx )
+{
+ return SbxArray::Get32( Offset32( pIdx ) );
+}
+
+void SbxDimArray::Put32( SbxVariable* p, const INT32* pIdx )
+{
+ SbxArray::Put32( p, Offset32( pIdx ) );
+}
+
+
+// Element-Nr anhand eines Parameter-Arrays
+
+UINT32 SbxDimArray::Offset32( SbxArray* pPar )
+{
+ if( nDim == 0 || !pPar )
+ {
+ SetError( SbxERR_BOUNDS ); return 0;
+ }
+ UINT32 nPos = 0;
+ USHORT nOff = 1; // Nicht Element 0!
+ for( SbxDim* p = pFirst; p && !IsError(); p = p->pNext )
+ {
+ INT32 nIdx = pPar->Get( nOff++ )->GetLong();
+ if( nIdx < p->nLbound || nIdx > p->nUbound )
+ {
+ nPos = (UINT32) SBX_MAXINDEX32+1; break;
+ }
+ nPos = nPos * p->nSize + nIdx - p->nLbound;
+ }
+ if( nPos > (UINT32) SBX_MAXINDEX32 )
+ {
+ SetError( SbxERR_BOUNDS ); nPos = 0;
+ }
+ return nPos;
+}
+
+SbxVariable* SbxDimArray::Get( SbxArray* pPar )
+{
+ return SbxArray::Get32( Offset32( pPar ) );
+}
+
+BOOL SbxDimArray::LoadData( SvStream& rStrm, USHORT nVer )
+{
+ short nDimension;
+ rStrm >> nDimension;
+ for( short i = 0; i < nDimension && rStrm.GetError() == SVSTREAM_OK; i++ )
+ {
+ INT16 lb, ub;
+ rStrm >> lb >> ub;
+ AddDim( lb, ub );
+ }
+ return SbxArray::LoadData( rStrm, nVer );
+}
+
+BOOL SbxDimArray::StoreData( SvStream& rStrm ) const
+{
+ rStrm << (INT16) nDim;
+ for( short i = 0; i < nDim; i++ )
+ {
+ short lb, ub;
+ GetDim( i, lb, ub );
+ rStrm << (INT16) lb << (INT16) ub;
+ }
+ return SbxArray::StoreData( rStrm );
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/sbx/sbxbase.cxx b/binfilter/bf_basic/source/sbx/sbxbase.cxx
new file mode 100644
index 000000000000..3a367fef54b7
--- /dev/null
+++ b/binfilter/bf_basic/source/sbx/sbxbase.cxx
@@ -0,0 +1,426 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <tools/stream.hxx>
+
+#include "sbx.hxx"
+#include "sbxfac.hxx"
+#include "sbxbase.hxx"
+
+namespace binfilter {
+
+// AppData-Struktur fuer SBX:
+
+SV_IMPL_PTRARR(SbxParams,SbxParamInfo*);
+SV_IMPL_PTRARR(SbxFacs,SbxFactory*);
+
+TYPEINIT0(SbxBase)
+
+// SBX-Daten anfordern oder ggf. anlegen
+// wir legen den Bereich einfach an und verzichten auf die Freigabe!
+
+SbxAppData* GetSbxData_Impl()
+{
+ DBG_TESTSOLARMUTEX();
+ static SbxAppData* pAppData = new SbxAppData;
+ return pAppData;
+}
+
+//////////////////////////////// SbxBase /////////////////////////////////
+
+DBG_NAME(SbxBase);
+
+SbxBase::SbxBase()
+{
+ DBG_CTOR( SbxBase, 0 );
+ nFlags = SBX_READWRITE;
+}
+
+SbxBase::SbxBase( const SbxBase& r )
+ : SvRefBase( r )
+{
+ DBG_CTOR( SbxBase, 0 );
+ nFlags = r.nFlags;
+}
+
+SbxBase::~SbxBase()
+{
+ DBG_DTOR(SbxBase,0);
+}
+
+SbxBase& SbxBase::operator=( const SbxBase& r )
+{
+ DBG_CHKTHIS( SbxBase, 0 );
+ nFlags = r.nFlags;
+ return *this;
+}
+
+SbxDataType SbxBase::GetType() const
+{
+ DBG_CHKTHIS( SbxBase, 0 );
+ return SbxEMPTY;
+}
+
+SbxClassType SbxBase::GetClass() const
+{
+ DBG_CHKTHIS( SbxBase, 0 );
+ return SbxCLASS_DONTCARE;
+}
+
+void SbxBase::Clear()
+{
+ DBG_CHKTHIS( SbxBase, 0 );
+}
+
+BOOL SbxBase::IsFixed() const
+{
+ DBG_CHKTHIS( SbxBase, 0 );
+ return IsSet( SBX_FIXED );
+}
+
+void SbxBase::SetModified( BOOL b )
+{
+ DBG_CHKTHIS( SbxBase, 0 );
+ if( IsSet( SBX_NO_MODIFY ) )
+ return;
+ if( b )
+ SetFlag( SBX_MODIFIED );
+ else
+ ResetFlag( SBX_MODIFIED );
+}
+
+SbxError SbxBase::GetError()
+{
+ return GetSbxData_Impl()->eSbxError;
+}
+
+void SbxBase::SetError( SbxError e )
+{
+ SbxAppData* p = GetSbxData_Impl();
+ if( e && p->eSbxError == SbxERR_OK )
+ p->eSbxError = e;
+}
+
+BOOL SbxBase::IsError()
+{
+ return BOOL( GetSbxData_Impl()->eSbxError != SbxERR_OK );
+}
+
+void SbxBase::ResetError()
+{
+ GetSbxData_Impl()->eSbxError = SbxERR_OK;
+}
+
+void SbxBase::AddFactory( SbxFactory* pFac )
+{
+ SbxAppData* p = GetSbxData_Impl();
+ const SbxFactory* pTemp = pFac;
+
+ // AB, 6.3.96: HandleLast-Flag beruecksichtigen
+ USHORT nPos = p->aFacs.Count(); // Einfuege-Position
+ if( !pFac->IsHandleLast() ) // Nur, wenn nicht selbst HandleLast
+ {
+ // Neue Factory vor Factories mit HandleLast einordnen
+ while( nPos > 0 &&
+ (static_cast<SbxFactory*>(p->aFacs.GetObject( nPos-1 )))->IsHandleLast() )
+ nPos--;
+ }
+ p->aFacs.Insert( pTemp, nPos );
+}
+
+void SbxBase::RemoveFactory( SbxFactory* pFac )
+{
+ SbxAppData* p = GetSbxData_Impl();
+ for( USHORT i = 0; i < p->aFacs.Count(); i++ )
+ {
+ if( p->aFacs.GetObject( i ) == pFac )
+ {
+ p->aFacs.Remove( i, 1 ); break;
+ }
+ }
+}
+
+
+SbxBase* SbxBase::Create( UINT16 nSbxId, UINT32 nCreator )
+{
+ // #91626: Hack to skip old Basic dialogs
+ // Problem: There does not exist a factory any more,
+ // so we have to create a dummy SbxVariable instead
+ if( nSbxId == 0x65 ) // Dialog Id
+ return new SbxVariable;
+
+ XubString aEmptyStr;
+ if( nCreator == SBXCR_SBX )
+ switch( nSbxId )
+ {
+ case SBXID_VALUE: return new SbxValue;
+ case SBXID_VARIABLE: return new SbxVariable;
+ case SBXID_ARRAY: return new SbxArray;
+ case SBXID_DIMARRAY: return new SbxDimArray;
+ case SBXID_OBJECT: return new SbxObject( aEmptyStr );
+ case SBXID_COLLECTION: return new SbxCollection( aEmptyStr );
+ case SBXID_FIXCOLLECTION:
+ return new SbxStdCollection( aEmptyStr, aEmptyStr );
+ case SBXID_METHOD: return new SbxMethod( aEmptyStr, SbxEMPTY );
+ case SBXID_PROPERTY: return new SbxProperty( aEmptyStr, SbxEMPTY );
+ }
+ // Unbekanter Typ: ber die Factories gehen!
+ SbxAppData* p = GetSbxData_Impl();
+ SbxBase* pNew = NULL;
+ for( USHORT i = 0; i < p->aFacs.Count(); i++ )
+ {
+ SbxFactory* pFac = p->aFacs.GetObject( i );
+ pNew = pFac->Create( nSbxId, nCreator );
+ if( pNew )
+ break;
+ }
+#ifdef DBG_UTIL
+ if( !pNew )
+ {
+ ByteString aMsg( "SBX: Keine Factory fuer SBX-ID " );
+ aMsg += ByteString::CreateFromInt32(nSbxId);
+ DbgError( aMsg.GetBuffer() );
+ }
+#endif
+ return pNew;
+}
+
+SbxObject* SbxBase::CreateObject( const XubString& rClass )
+{
+ SbxAppData* p = GetSbxData_Impl();
+ SbxObject* pNew = NULL;
+ for( USHORT i = 0; i < p->aFacs.Count(); i++ )
+ {
+ pNew = p->aFacs.GetObject( i )->CreateObject( rClass );
+ if( pNew )
+ break;
+ }
+#ifdef DBG_UTIL
+ if( !pNew )
+ {
+ ByteString aMsg( "SBX: Keine Factory fuer Objektklasse " );
+ ByteString aClassStr( (const UniString&)rClass, RTL_TEXTENCODING_ASCII_US );
+ aMsg += aClassStr;
+ DbgError( (const char*)aMsg.GetBuffer() );
+ }
+#endif
+ return pNew;
+}
+
+static BOOL bStaticEnableBroadcasting = TRUE;
+
+// Sbx-Loesung als Ersatz fuer SfxBroadcaster::Enable()
+BOOL SbxBase::StaticIsEnabledBroadcasting( void )
+{
+ return bStaticEnableBroadcasting;
+}
+
+SbxBase* SbxBase::Load( SvStream& rStrm )
+{
+ UINT16 nSbxId, nFlags, nVer;
+ UINT32 nCreator, nSize;
+ rStrm >> nCreator >> nSbxId >> nFlags >> nVer;
+
+ // Eine Dummheit meinerseits korrigieren:
+ if( nFlags & SBX_RESERVED )
+ nFlags = ( nFlags & ~SBX_RESERVED ) | SBX_GBLSEARCH;
+
+ ULONG nOldPos = rStrm.Tell();
+ rStrm >> nSize;
+ SbxBase* p = Create( nSbxId, nCreator );
+ if( p )
+ {
+ p->nFlags = nFlags;
+ if( p->LoadData( rStrm, nVer ) )
+ {
+ ULONG nNewPos = rStrm.Tell();
+ nOldPos += nSize;
+ DBG_ASSERT( nOldPos >= nNewPos, "SBX: Zu viele Daten eingelesen" );
+ if( nOldPos != nNewPos )
+ rStrm.Seek( nOldPos );
+ if( !p->LoadCompleted() )
+ {
+ // Loeschen des Objekts
+ SbxBaseRef aRef( p );
+ p = NULL;
+ }
+ }
+ else
+ {
+ rStrm.SetError( SVSTREAM_FILEFORMAT_ERROR );
+ // Loeschen des Objekts
+ SbxBaseRef aRef( p );
+ p = NULL;
+ }
+ }
+ else
+ rStrm.SetError( SVSTREAM_FILEFORMAT_ERROR );
+ return p;
+}
+
+// Sbx-Objekt im Stream ueberspringen
+void SbxBase::Skip( SvStream& rStrm )
+{
+ UINT16 nSbxId, nFlags, nVer;
+ UINT32 nCreator, nSize;
+ rStrm >> nCreator >> nSbxId >> nFlags >> nVer;
+
+ ULONG nStartPos = rStrm.Tell();
+ rStrm >> nSize;
+
+ rStrm.Seek( nStartPos + nSize );
+}
+
+BOOL SbxBase::Store( SvStream& rStrm )
+{
+ DBG_CHKTHIS( SbxBase, 0 );
+ if( !( nFlags & SBX_DONTSTORE ) )
+ {
+ rStrm << (UINT32) GetCreator()
+ << (UINT16) GetSbxId()
+ << (UINT16) GetFlags()
+ << (UINT16) GetVersion();
+ ULONG nOldPos = rStrm.Tell();
+ rStrm << (UINT32) 0L;
+ BOOL bRes = StoreData( rStrm );
+ ULONG nNewPos = rStrm.Tell();
+ rStrm.Seek( nOldPos );
+ rStrm << (UINT32) ( nNewPos - nOldPos );
+ rStrm.Seek( nNewPos );
+ if( rStrm.GetError() != SVSTREAM_OK )
+ bRes = FALSE;
+ if( bRes )
+ bRes = StoreCompleted();
+ return bRes;
+ }
+ else
+ return TRUE;
+}
+
+BOOL SbxBase::LoadData( SvStream&, USHORT )
+{
+ DBG_CHKTHIS( SbxBase, 0 );
+ return FALSE;
+}
+
+BOOL SbxBase::StoreData( SvStream& ) const
+{
+ DBG_CHKTHIS( SbxBase, 0 );
+ return FALSE;
+}
+
+BOOL SbxBase::LoadPrivateData( SvStream&, USHORT )
+{
+ DBG_CHKTHIS( SbxBase, 0 );
+ return TRUE;
+}
+
+BOOL SbxBase::StorePrivateData( SvStream& ) const
+{
+ DBG_CHKTHIS( SbxBase, 0 );
+ return TRUE;
+}
+
+BOOL SbxBase::LoadCompleted()
+{
+ DBG_CHKTHIS( SbxBase, 0 );
+ return TRUE;
+}
+
+BOOL SbxBase::StoreCompleted()
+{
+ DBG_CHKTHIS( SbxBase, 0 );
+ return TRUE;
+}
+
+//////////////////////////////// SbxFactory ////////////////////////////////
+
+SbxBase* SbxFactory::Create( UINT16, UINT32 )
+{
+ return NULL;
+}
+
+SbxObject* SbxFactory::CreateObject( const XubString& )
+{
+ return NULL;
+}
+
+///////////////////////////////// SbxInfo //////////////////////////////////
+
+SbxInfo::~SbxInfo()
+{}
+
+void SbxInfo::AddParam
+ ( const XubString& rName, SbxDataType eType, USHORT nFlags )
+{
+ const SbxParamInfo* p = new SbxParamInfo( rName, eType, nFlags );
+ aParams.Insert( p, aParams.Count() );
+}
+
+BOOL SbxInfo::LoadData( SvStream& rStrm, USHORT nVer )
+{
+ aParams.Remove( 0, aParams.Count() );
+ UINT16 nParam;
+ rStrm.ReadByteString( aComment, RTL_TEXTENCODING_ASCII_US );
+ rStrm.ReadByteString( aHelpFile, RTL_TEXTENCODING_ASCII_US );
+ rStrm >> nHelpId >> nParam;
+ while( nParam-- )
+ {
+ XubString aName;
+ UINT16 nType, nFlags;
+ UINT32 nUserData = 0;
+ rStrm.ReadByteString( aName, RTL_TEXTENCODING_ASCII_US );
+ rStrm >> nType >> nFlags;
+ if( nVer > 1 )
+ rStrm >> nUserData;
+ AddParam( aName, (SbxDataType) nType, nFlags );
+ SbxParamInfo* p = aParams.GetObject( aParams.Count() - 1 );
+ p->nUserData = nUserData;
+ }
+ return TRUE;
+}
+
+BOOL SbxInfo::StoreData( SvStream& rStrm ) const
+{
+ rStrm.WriteByteString( aComment, RTL_TEXTENCODING_ASCII_US );
+ rStrm.WriteByteString( aHelpFile, RTL_TEXTENCODING_ASCII_US );
+ rStrm << nHelpId << aParams.Count();
+ for( USHORT i = 0; i < aParams.Count(); i++ )
+ {
+ SbxParamInfo* p = aParams.GetObject( i );
+ rStrm.WriteByteString( p->aName, RTL_TEXTENCODING_ASCII_US );
+ rStrm << (UINT16) p->eType
+ << (UINT16) p->nFlags
+ << (UINT32) p->nUserData;
+ }
+ return TRUE;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/sbx/sbxbool.cxx b/binfilter/bf_basic/source/sbx/sbxbool.cxx
new file mode 100644
index 000000000000..6fabf540c7f5
--- /dev/null
+++ b/binfilter/bf_basic/source/sbx/sbxbool.cxx
@@ -0,0 +1,251 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <tools/errcode.hxx>
+#include "sbx.hxx"
+#include "sbxconv.hxx"
+#include "sbxres.hxx"
+
+namespace binfilter {
+
+enum SbxBOOL ImpGetBool( const SbxValues* p )
+{
+ enum SbxBOOL nRes;
+ switch( +p->eType )
+ {
+ case SbxNULL:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ case SbxEMPTY:
+ nRes = SbxFALSE; break;
+ case SbxCHAR:
+ nRes = p->nChar ? SbxTRUE : SbxFALSE; break;
+ case SbxBYTE:
+ nRes = p->nByte ? SbxTRUE : SbxFALSE; break;
+ case SbxINTEGER:
+ case SbxBOOL:
+ nRes = p->nInteger ? SbxTRUE : SbxFALSE; break;
+ case SbxERROR:
+ case SbxUSHORT:
+ nRes = p->nUShort ? SbxTRUE : SbxFALSE; break;
+ case SbxLONG:
+ nRes = p->nLong ? SbxTRUE : SbxFALSE; break;
+ case SbxULONG:
+ nRes = p->nULong ? SbxTRUE : SbxFALSE; break;
+ case SbxSINGLE:
+ nRes = p->nSingle ? SbxTRUE : SbxFALSE; break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ nRes = p->nDouble ? SbxTRUE : SbxFALSE; break;
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ {
+ double dVal = 0.0;
+ if( p->pDecimal )
+ p->pDecimal->getDouble( dVal );
+ nRes = dVal ? SbxTRUE : SbxFALSE;
+ }
+ break;
+ case SbxSALINT64:
+ nRes = p->nInt64 ? SbxTRUE : SbxFALSE; break;
+ case SbxSALUINT64:
+ nRes = p->uInt64 ? SbxTRUE : SbxFALSE; break;
+ case SbxULONG64:
+ nRes = !!p->nULong64 ? SbxTRUE : SbxFALSE; break;
+ case SbxLONG64:
+ case SbxCURRENCY:
+ nRes = !!p->nLong64 ? SbxTRUE : SbxFALSE; break;
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ nRes = SbxFALSE;
+ if( p->pString )
+ {
+ if( p->pString->EqualsIgnoreCaseAscii( SbxRes( STRING_TRUE ) ) )
+ nRes = SbxTRUE;
+ else if( !p->pString->EqualsIgnoreCaseAscii( SbxRes( STRING_FALSE ) ) )
+ {
+ // Jetzt kann es noch in eine Zahl konvertierbar sein
+ BOOL bError = TRUE;
+ double n;
+ SbxDataType t;
+ USHORT nLen = 0;
+ String s( *p->pString );
+ if( ImpScan( s, n, t, &nLen ) == SbxERR_OK )
+ {
+ if( nLen == s.Len() )
+ {
+ bError = FALSE;
+ if( n != 0.0 )
+ nRes = SbxTRUE;
+ }
+ }
+ if( bError )
+ SbxBase::SetError( SbxERR_CONVERSION );
+ }
+ }
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ nRes = pVal->GetBool() ? SbxTRUE : SbxFALSE;
+ else
+ {
+ SbxBase::SetError( SbxERR_NO_OBJECT ); nRes = SbxFALSE;
+ }
+ break;
+ }
+
+ case SbxBYREF | SbxCHAR:
+ nRes = *p->pChar ? SbxTRUE : SbxFALSE; break;
+ case SbxBYREF | SbxBYTE:
+ nRes = *p->pByte ? SbxTRUE : SbxFALSE; break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ nRes = *p->pInteger ? SbxTRUE : SbxFALSE; break;
+ case SbxBYREF | SbxLONG:
+ nRes = *p->pLong ? SbxTRUE : SbxFALSE; break;
+ case SbxBYREF | SbxULONG:
+ nRes = *p->pULong ? SbxTRUE : SbxFALSE; break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ nRes = *p->pUShort ? SbxTRUE : SbxFALSE; break;
+ case SbxBYREF | SbxSINGLE:
+ nRes = ( *p->pSingle != 0 ) ? SbxTRUE : SbxFALSE; break;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ nRes = ( *p->pDouble != 0 ) ? SbxTRUE : SbxFALSE; break;
+ case SbxBYREF | SbxSALINT64:
+ nRes = ( *p->pnInt64 ) ? SbxTRUE : SbxFALSE; break;
+ case SbxBYREF | SbxSALUINT64:
+ nRes = ( *p->puInt64 ) ? SbxTRUE : SbxFALSE; break;
+ case SbxBYREF | SbxULONG64:
+ nRes = !!*p->pULong64 ? SbxTRUE : SbxFALSE; break;
+ case SbxBYREF | SbxLONG64:
+ case SbxBYREF | SbxCURRENCY:
+ nRes = !!*p->pLong64 ? SbxTRUE : SbxFALSE; break;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION ); nRes = SbxFALSE;
+ }
+ return nRes;
+}
+
+void ImpPutBool( SbxValues* p, INT16 n )
+{
+ if( n )
+ n = SbxTRUE;
+ switch( +p->eType )
+ {
+ case SbxCHAR:
+ p->nChar = (xub_Unicode) n; break;
+ case SbxUINT:
+ p->nByte = (BYTE) n; break;
+ case SbxINTEGER:
+ case SbxBOOL:
+ p->nInteger = n; break;
+ case SbxLONG:
+ p->nLong = n; break;
+ case SbxULONG:
+ p->nULong = (UINT32) n; break;
+ case SbxERROR:
+ case SbxUSHORT:
+ p->nUShort = (UINT16) n; break;
+ case SbxSINGLE:
+ p->nSingle = n; break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ p->nDouble = n; break;
+ case SbxSALINT64:
+ p->nInt64 = n; break;
+ case SbxSALUINT64:
+ p->uInt64 = n; break;
+ case SbxULONG64:
+ p->nULong64.Set( (UINT32)n ); break;
+ case SbxLONG64:
+ case SbxCURRENCY:
+ p->nLong64.Set( (INT32)n ); break;
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ ImpCreateDecimal( p )->setInt( (INT16)n );
+ break;
+
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ if( !p->pString )
+ p->pString = new XubString;
+ *p->pString = SbxRes( n ? STRING_TRUE : STRING_FALSE );
+ break;
+
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ pVal->PutBool( BOOL( n != 0 ) );
+ else
+ SbxBase::SetError( SbxERR_NO_OBJECT );
+ break;
+ }
+ case SbxBYREF | SbxCHAR:
+ *p->pChar = (xub_Unicode) n; break;
+ case SbxBYREF | SbxBYTE:
+ *p->pByte = (BYTE) n; break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ *p->pInteger = (INT16) n; break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ *p->pUShort = (UINT16) n; break;
+ case SbxBYREF | SbxLONG:
+ *p->pLong = n; break;
+ case SbxBYREF | SbxULONG:
+ *p->pULong = (UINT32) n; break;
+ case SbxBYREF | SbxSINGLE:
+ *p->pSingle = n; break;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ *p->pDouble = n; break;
+ case SbxBYREF | SbxSALINT64:
+ *p->pnInt64 = n; break;
+ case SbxBYREF | SbxSALUINT64:
+ *p->puInt64 = n; break;
+ case SbxBYREF | SbxULONG64:
+ p->pULong64->Set( (UINT32)n ); break;
+ case SbxBYREF | SbxLONG64:
+ case SbxBYREF | SbxCURRENCY:
+ p->pLong64->Set( (INT32)n ); break;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/sbx/sbxbyte.cxx b/binfilter/bf_basic/source/sbx/sbxbyte.cxx
new file mode 100644
index 000000000000..6f19626042b0
--- /dev/null
+++ b/binfilter/bf_basic/source/sbx/sbxbyte.cxx
@@ -0,0 +1,333 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <tools/errcode.hxx>
+#include "sbx.hxx"
+#include "sbxconv.hxx"
+
+namespace binfilter {
+
+BYTE ImpGetByte( const SbxValues* p )
+{
+ SbxValues aTmp;
+ BYTE nRes;
+start:
+ switch( +p->eType )
+ {
+ case SbxNULL:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ case SbxEMPTY:
+ nRes = 0; break;
+ case SbxCHAR:
+ if( p->nChar > SbxMAXBYTE )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
+ }
+ else
+ nRes = (BYTE) p->nChar;
+ break;
+ case SbxBYTE:
+ nRes = (BYTE) p->nByte; break;
+ case SbxINTEGER:
+ case SbxBOOL:
+ if( p->nInteger > SbxMAXBYTE )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXBYTE;
+ }
+ else if( p->nInteger < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
+ }
+ else
+ nRes = (BYTE) p->nInteger;
+ break;
+ case SbxERROR:
+ case SbxUSHORT:
+ if( p->nUShort > (USHORT) SbxMAXBYTE )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXBYTE;
+ }
+ else
+ nRes = (BYTE) p->nUShort;
+ break;
+ case SbxLONG:
+ if( p->nLong > SbxMAXBYTE )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXBYTE;
+ }
+ else if( p->nLong < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
+ }
+ else
+ nRes = (BYTE) p->nLong;
+ break;
+ case SbxULONG:
+ if( p->nULong > SbxMAXBYTE )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXBYTE;
+ }
+ else
+ nRes = (BYTE) p->nULong;
+ break;
+ case SbxSALINT64:
+ if( p->nInt64 > SbxMAXBYTE )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXBYTE;
+ }
+ else if( p->nInt64 < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
+ }
+ else
+ nRes = (BYTE) p->nInt64;
+ break;
+ case SbxSALUINT64:
+ if( p->uInt64 > SbxMAXBYTE )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXBYTE;
+ }
+ else
+ nRes = (BYTE) p->uInt64;
+ break;
+ case SbxSINGLE:
+ if( p->nSingle > SbxMAXBYTE )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXBYTE;
+ }
+ else if( p->nSingle < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
+ }
+ else
+ nRes = (BYTE) ImpRound( p->nSingle );
+ break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ case SbxLONG64:
+ case SbxULONG64:
+ case SbxCURRENCY:
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ {
+ double dVal;
+ if( p->eType == SbxCURRENCY )
+ dVal = ImpCurrencyToDouble( p->nLong64 );
+ else if( p->eType == SbxLONG64 )
+ dVal = ImpINT64ToDouble( p->nLong64 );
+ else if( p->eType == SbxULONG64 )
+ dVal = ImpUINT64ToDouble( p->nULong64 );
+ else if( p->eType == SbxDECIMAL )
+ {
+ dVal = 0.0;
+ if( p->pDecimal )
+ p->pDecimal->getDouble( dVal );
+ }
+ else
+ dVal = p->nDouble;
+
+ if( dVal > SbxMAXBYTE )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXBYTE;
+ }
+ else if( dVal < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
+ }
+ else
+ nRes = (BYTE) ImpRound( dVal );
+ break;
+ }
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ if( !p->pString )
+ nRes = 0;
+ else
+ {
+ double d;
+ SbxDataType t;
+ if( ImpScan( *p->pString, d, t, NULL ) != SbxERR_OK )
+ nRes = 0;
+ else if( d > SbxMAXBYTE )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXBYTE;
+ }
+ else if( d < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
+ }
+ else
+ nRes = (BYTE) ( d + 0.5 );
+ }
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ nRes = pVal->GetByte();
+ else
+ {
+ SbxBase::SetError( SbxERR_NO_OBJECT ); nRes = 0;
+ }
+ break;
+ }
+
+ case SbxBYREF | SbxBYTE:
+ nRes = p->nByte; break;
+
+ // ab hier wird getestet
+ case SbxBYREF | SbxCHAR:
+ aTmp.nChar = *p->pChar; goto ref;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ aTmp.nInteger = *p->pInteger; goto ref;
+ case SbxBYREF | SbxLONG:
+ aTmp.nLong = *p->pLong; goto ref;
+ case SbxBYREF | SbxULONG:
+ aTmp.nULong = *p->pULong; goto ref;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ aTmp.nUShort = *p->pUShort; goto ref;
+ case SbxBYREF | SbxSINGLE:
+ aTmp.nSingle = *p->pSingle; goto ref;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ aTmp.nDouble = *p->pDouble; goto ref;
+ case SbxBYREF | SbxULONG64:
+ aTmp.nULong64 = *p->pULong64; goto ref;
+ case SbxBYREF | SbxLONG64:
+ case SbxBYREF | SbxCURRENCY:
+ aTmp.nLong64 = *p->pLong64; goto ref;
+ case SbxBYREF | SbxSALINT64:
+ aTmp.nInt64 = *p->pnInt64; goto ref;
+ case SbxBYREF | SbxSALUINT64:
+ aTmp.uInt64 = *p->puInt64; goto ref;
+ ref:
+ aTmp.eType = SbxDataType( p->eType & 0x0FFF );
+ p = &aTmp; goto start;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
+ }
+ return nRes;
+}
+
+void ImpPutByte( SbxValues* p, BYTE n )
+{
+ switch( +p->eType )
+ {
+ case SbxBYTE:
+ p->nByte = n; break;
+ case SbxINTEGER:
+ case SbxBOOL:
+ p->nInteger = n; break;
+ case SbxERROR:
+ case SbxUSHORT:
+ p->nUShort = n; break;
+ case SbxLONG:
+ p->nLong = n; break;
+ case SbxULONG:
+ p->nULong = n; break;
+ case SbxSINGLE:
+ p->nSingle = n; break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ p->nDouble = n; break;
+ case SbxSALINT64:
+ p->nInt64 = n; break;
+ case SbxSALUINT64:
+ p->uInt64 = n; break;
+ case SbxULONG64:
+ p->nULong64 = ImpDoubleToUINT64( (double)n ); break;
+ case SbxLONG64:
+ p->nLong64 = ImpDoubleToINT64( (double)n ); break;
+ case SbxCURRENCY:
+ p->nLong64 = ImpDoubleToCurrency( (double)n ); break;
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ ImpCreateDecimal( p )->setByte( n );
+ break;
+
+ case SbxCHAR:
+ p->nChar = (xub_Unicode) n; break;
+
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ if( !p->pString )
+ p->pString = new XubString;
+ ImpCvtNum( (double) n, 0, *p->pString );
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ pVal->PutByte( n );
+ else
+ SbxBase::SetError( SbxERR_NO_OBJECT );
+ break;
+ }
+ case SbxBYREF | SbxCHAR:
+ *p->pChar = (xub_Unicode) n; break;
+ case SbxBYREF | SbxBYTE:
+ *p->pByte = n; break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ *p->pInteger = n; break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ *p->pUShort = n; break;
+ case SbxBYREF | SbxLONG:
+ *p->pLong = n; break;
+ case SbxBYREF | SbxULONG:
+ *p->pULong = n; break;
+ case SbxBYREF | SbxSINGLE:
+ *p->pSingle = n; break;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ *p->pDouble = n; break;
+ case SbxBYREF | SbxULONG64:
+ *p->pULong64 = ImpDoubleToUINT64( (double)n ); break;
+ case SbxBYREF | SbxLONG64:
+ *p->pLong64 = ImpDoubleToINT64( (double)n ); break;
+ case SbxBYREF | SbxSALINT64:
+ *p->pnInt64 = n; break;
+ case SbxBYREF | SbxSALUINT64:
+ *p->puInt64 = n; break;
+ case SbxBYREF | SbxCURRENCY:
+ *p->pLong64 = ImpDoubleToCurrency( (double)n ); break;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/sbx/sbxchar.cxx b/binfilter/bf_basic/source/sbx/sbxchar.cxx
new file mode 100644
index 000000000000..a34549217cd8
--- /dev/null
+++ b/binfilter/bf_basic/source/sbx/sbxchar.cxx
@@ -0,0 +1,323 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <tools/errcode.hxx>
+#include "sbx.hxx"
+#include "sbxconv.hxx"
+
+namespace binfilter {
+
+xub_Unicode ImpGetChar( const SbxValues* p )
+{
+ SbxValues aTmp;
+ xub_Unicode nRes;
+start:
+ switch( +p->eType )
+ {
+ case SbxNULL:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ case SbxEMPTY:
+ nRes = 0; break;
+ case SbxCHAR:
+ nRes = p->nChar; break;
+ case SbxBYTE:
+ nRes = (xub_Unicode) p->nByte;
+ break;
+ case SbxINTEGER:
+ case SbxBOOL:
+ if( p->nInteger < SbxMINCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMINCHAR;
+ }
+ else
+ nRes = (xub_Unicode) p->nInteger;
+ break;
+ case SbxERROR:
+ case SbxUSHORT:
+ nRes = (xub_Unicode) p->nUShort;
+ break;
+ case SbxLONG:
+ if( p->nLong > SbxMAXCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXCHAR;
+ }
+ else if( p->nLong < SbxMINCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMINCHAR;
+ }
+ else
+ nRes = (xub_Unicode) p->nLong;
+ break;
+ case SbxULONG:
+ if( p->nULong > SbxMAXCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXCHAR;
+ }
+ else
+ nRes = (xub_Unicode) p->nULong;
+ break;
+ case SbxSALINT64:
+ if( p->nInt64 > SbxMAXCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXCHAR;
+ }
+ else if( p->nInt64 < SbxMINCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMINCHAR;
+ }
+ else
+ nRes = (xub_Unicode) p->nInt64;
+ break;
+ case SbxSALUINT64:
+ if( p->uInt64 > SbxMAXCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXCHAR;
+ }
+ else
+ nRes = (xub_Unicode) p->uInt64;
+ break;
+ case SbxSINGLE:
+ if( p->nSingle > SbxMAXCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXCHAR;
+ }
+ else if( p->nSingle < SbxMINCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMINCHAR;
+ }
+ else
+ nRes = (xub_Unicode) ImpRound( p->nSingle );
+ break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ case SbxLONG64:
+ case SbxULONG64:
+ case SbxCURRENCY:
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ {
+ double dVal;
+ if( p->eType == SbxCURRENCY )
+ dVal = ImpCurrencyToDouble( p->nLong64 );
+ else if( p->eType == SbxLONG64 )
+ dVal = ImpINT64ToDouble( p->nLong64 );
+ else if( p->eType == SbxULONG64 )
+ dVal = ImpUINT64ToDouble( p->nULong64 );
+ else if( p->eType == SbxDECIMAL )
+ {
+ dVal = 0.0;
+ if( p->pDecimal )
+ p->pDecimal->getDouble( dVal );
+ }
+ else
+ dVal = p->nDouble;
+
+ if( dVal > SbxMAXCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXCHAR;
+ }
+ else if( dVal < SbxMINCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMINCHAR;
+ }
+ else
+ nRes = (BYTE) ImpRound( dVal );
+ break;
+ }
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ if( !p->pString )
+ nRes = 0;
+ else
+ {
+ double d;
+ SbxDataType t;
+ if( ImpScan( *p->pString, d, t, NULL ) != SbxERR_OK )
+ nRes = 0;
+ else if( d > SbxMAXCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXCHAR;
+ }
+ else if( d < SbxMINCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMINCHAR;
+ }
+ else
+ nRes = (xub_Unicode) ImpRound( d );
+ }
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ nRes = pVal->GetChar();
+ else
+ {
+ SbxBase::SetError( SbxERR_NO_OBJECT ); nRes = 0;
+ }
+ break;
+ }
+
+ case SbxBYREF | SbxCHAR:
+ nRes = *p->pChar; break;
+ // ab hier wird getestet
+ case SbxBYREF | SbxBYTE:
+ aTmp.nByte = *p->pByte; goto ref;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ aTmp.nInteger = *p->pInteger; goto ref;
+ case SbxBYREF | SbxLONG:
+ aTmp.nLong = *p->pLong; goto ref;
+ case SbxBYREF | SbxULONG:
+ aTmp.nULong = *p->pULong; goto ref;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ aTmp.nUShort = *p->pUShort; goto ref;
+ case SbxBYREF | SbxSINGLE:
+ aTmp.nSingle = *p->pSingle; goto ref;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ aTmp.nDouble = *p->pDouble; goto ref;
+ case SbxBYREF | SbxULONG64:
+ aTmp.nULong64 = *p->pULong64; goto ref;
+ case SbxBYREF | SbxLONG64:
+ case SbxBYREF | SbxCURRENCY:
+ aTmp.nLong64 = *p->pLong64; goto ref;
+ case SbxBYREF | SbxSALINT64:
+ aTmp.nInt64 = *p->pnInt64; goto ref;
+ case SbxBYREF | SbxSALUINT64:
+ aTmp.uInt64 = *p->puInt64; goto ref;
+ ref:
+ aTmp.eType = SbxDataType( p->eType & 0x0FFF );
+ p = &aTmp; goto start;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
+ }
+ return nRes;
+}
+
+void ImpPutChar( SbxValues* p, xub_Unicode n )
+{
+ SbxValues aTmp;
+start:
+ switch( +p->eType )
+ {
+ case SbxCHAR:
+ p->nChar = n; break;
+ case SbxINTEGER:
+ case SbxBOOL:
+ p->nInteger = n; break;
+ case SbxLONG:
+ p->nLong = n; break;
+ case SbxSINGLE:
+ p->nSingle = n; break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ p->nDouble = n; break;
+ case SbxSALINT64:
+ p->nInt64 = n; break;
+ case SbxSALUINT64:
+ p->uInt64 = n; break;
+ case SbxULONG64:
+ p->nULong64 = ImpDoubleToUINT64( (double)n ); break;
+ case SbxLONG64:
+ p->nLong64 = ImpDoubleToINT64( (double)n ); break;
+ case SbxCURRENCY:
+ p->nLong64 = ImpDoubleToCurrency( (double)n ); break;
+ case SbxBYREF | SbxDECIMAL:
+ ImpCreateDecimal( p )->setChar( n );
+ break;
+
+ // ab hier wird getestet
+ case SbxBYTE:
+ aTmp.pByte = &p->nByte; goto direct;
+ case SbxULONG:
+ aTmp.pULong = &p->nULong; goto direct;
+ case SbxERROR:
+ case SbxUSHORT:
+ aTmp.pUShort = &p->nUShort; goto direct;
+ direct:
+ aTmp.eType = SbxDataType( p->eType | SbxBYREF );
+ p = &aTmp; goto start;
+
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ if( !p->pString )
+ p->pString = new XubString;
+ *p->pString = n;
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ pVal->PutChar( n );
+ else
+ SbxBase::SetError( SbxERR_NO_OBJECT );
+ break;
+ }
+ case SbxBYREF | SbxCHAR:
+ *p->pChar = n; break;
+ case SbxBYREF | SbxBYTE:
+ *p->pByte = (BYTE) n; break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ *p->pInteger = n; break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ *p->pUShort = (UINT16) n; break;
+ case SbxBYREF | SbxLONG:
+ *p->pLong = (INT32) n; break;
+ case SbxBYREF | SbxULONG:
+ *p->pULong = (UINT32) n; break;
+ case SbxBYREF | SbxSINGLE:
+ *p->pSingle = (float) n; break;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ *p->pDouble = (double) n; break;
+ case SbxBYREF | SbxSALINT64:
+ *p->pnInt64 = n; break;
+ case SbxBYREF | SbxSALUINT64:
+ *p->puInt64 = n; break;
+ case SbxBYREF | SbxULONG64:
+ *p->pULong64 = ImpDoubleToUINT64( (double)n ); break;
+ case SbxBYREF | SbxLONG64:
+ *p->pLong64 = ImpDoubleToINT64( (double)n ); break;
+ case SbxBYREF | SbxCURRENCY:
+ *p->pLong64 = ImpDoubleToCurrency( (double)n ); break;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/sbx/sbxcoll.cxx b/binfilter/bf_basic/source/sbx/sbxcoll.cxx
new file mode 100644
index 000000000000..23c42ae7fd23
--- /dev/null
+++ b/binfilter/bf_basic/source/sbx/sbxcoll.cxx
@@ -0,0 +1,303 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <tools/stream.hxx>
+
+#include "sbx.hxx"
+#include "sbxres.hxx"
+
+namespace binfilter {
+
+TYPEINIT1(SbxCollection,SbxObject)
+TYPEINIT1(SbxStdCollection,SbxCollection)
+
+static const char* pCount;
+static const char* pAdd;
+static const char* pItem;
+static const char* pRemove;
+static USHORT nCountHash = 0, nAddHash, nItemHash, nRemoveHash;
+
+/////////////////////////////////////////////////////////////////////////
+
+SbxCollection::SbxCollection( const XubString& rClass )
+ : SbxObject( rClass )
+{
+ if( !nCountHash )
+ {
+ pCount = GetSbxRes( STRING_COUNTPROP );
+ pAdd = GetSbxRes( STRING_ADDMETH );
+ pItem = GetSbxRes( STRING_ITEMMETH );
+ pRemove = GetSbxRes( STRING_REMOVEMETH );
+ nCountHash = MakeHashCode( String::CreateFromAscii( pCount ) );
+ nAddHash = MakeHashCode( String::CreateFromAscii( pAdd ) );
+ nItemHash = MakeHashCode( String::CreateFromAscii( pItem ) );
+ nRemoveHash = MakeHashCode( String::CreateFromAscii( pRemove ) );
+ }
+ Initialize();
+ // Fuer Zugriffe auf sich selbst
+ StartListening( GetBroadcaster(), TRUE );
+}
+
+SbxCollection::SbxCollection( const SbxCollection& rColl )
+ : SvRefBase( rColl ), SbxObject( rColl )
+{}
+
+SbxCollection& SbxCollection::operator=( const SbxCollection& r )
+{
+ if( &r != this )
+ SbxObject::operator=( r );
+ return *this;
+}
+
+SbxCollection::~SbxCollection()
+{}
+
+void SbxCollection::Clear()
+{
+ SbxObject::Clear();
+ Initialize();
+}
+
+void SbxCollection::Initialize()
+{
+ SetType( SbxOBJECT );
+ SetFlag( SBX_FIXED );
+ ResetFlag( SBX_WRITE );
+ SbxVariable* p;
+ p = Make( String::CreateFromAscii( pCount ), SbxCLASS_PROPERTY, SbxINTEGER );
+ p->ResetFlag( SBX_WRITE );
+ p->SetFlag( SBX_DONTSTORE );
+ p = Make( String::CreateFromAscii( pAdd ), SbxCLASS_METHOD, SbxEMPTY );
+ p->SetFlag( SBX_DONTSTORE );
+ p = Make( String::CreateFromAscii( pItem ), SbxCLASS_METHOD, SbxOBJECT );
+ p->SetFlag( SBX_DONTSTORE );
+ p = Make( String::CreateFromAscii( pRemove ), SbxCLASS_METHOD, SbxEMPTY );
+ p->SetFlag( SBX_DONTSTORE );
+}
+
+SbxVariable* SbxCollection::FindUserData( UINT32 nData )
+{
+ if( GetParameters() )
+ {
+ SbxObject* pObj = (SbxObject*) GetObject();
+ return pObj ? pObj->FindUserData( nData ) : NULL;
+ }
+ else
+ return SbxObject::FindUserData( nData );
+}
+
+SbxVariable* SbxCollection::Find( const XubString& rName, SbxClassType t )
+{
+ if( GetParameters() )
+ {
+ SbxObject* pObj = (SbxObject*) GetObject();
+ return pObj ? pObj->Find( rName, t ) : NULL;
+ }
+ else
+ return SbxObject::Find( rName, t );
+}
+
+void SbxCollection::SFX_NOTIFY( SfxBroadcaster& rCst, const TypeId& rId1,
+ const SfxHint& rHint, const TypeId& rId2 )
+{
+ const SbxHint* p = PTR_CAST(SbxHint,&rHint);
+ if( p )
+ {
+ ULONG nId = p->GetId();
+ BOOL bRead = BOOL( nId == SBX_HINT_DATAWANTED );
+ BOOL bWrite = BOOL( nId == SBX_HINT_DATACHANGED );
+ SbxVariable* pVar = p->GetVar();
+ SbxArray* pArg = pVar->GetParameters();
+ if( bRead || bWrite )
+ {
+ XubString aVarName( pVar->GetName() );
+ if( pVar == this )
+ CollItem( pArg );
+ else if( pVar->GetHashCode() == nCountHash
+ && aVarName.EqualsIgnoreCaseAscii( pCount ) )
+ pVar->PutLong( pObjs->Count() );
+ else if( pVar->GetHashCode() == nAddHash
+ && aVarName.EqualsIgnoreCaseAscii( pAdd ) )
+ CollAdd( pArg );
+ else if( pVar->GetHashCode() == nItemHash
+ && aVarName.EqualsIgnoreCaseAscii( pItem ) )
+ CollItem( pArg );
+ else if( pVar->GetHashCode() == nRemoveHash
+ && aVarName.EqualsIgnoreCaseAscii( pRemove ) )
+ CollRemove( pArg );
+ else
+ SbxObject::SFX_NOTIFY( rCst, rId1, rHint, rId2 );
+ return;
+ }
+ }
+ SbxObject::SFX_NOTIFY( rCst, rId1, rHint, rId2 );
+}
+
+// Default: Argument ist Objekt
+
+void SbxCollection::CollAdd( SbxArray* pPar_ )
+{
+ if( pPar_->Count() != 2 )
+ SetError( SbxERR_WRONG_ARGS );
+ else
+ {
+ SbxBase* pObj = pPar_->Get( 1 )->GetObject();
+ if( !pObj || !( pObj->ISA(SbxObject) ) )
+ SetError( SbxERR_NOTIMP );
+ else
+ Insert( (SbxObject*) pObj );
+ }
+}
+
+// Default: Index ab 1 oder der Objektname
+
+void SbxCollection::CollItem( SbxArray* pPar_ )
+{
+ if( pPar_->Count() != 2 )
+ SetError( SbxERR_WRONG_ARGS );
+ else
+ {
+ SbxVariable* pRes = NULL;
+ SbxVariable* p = pPar_->Get( 1 );
+ if( p->GetType() == SbxSTRING )
+ pRes = Find( p->GetString(), SbxCLASS_OBJECT );
+ else
+ {
+ short n = p->GetInteger();
+ if( n >= 1 && n <= (short) pObjs->Count() )
+ pRes = pObjs->Get( (USHORT) n - 1 );
+ }
+ if( !pRes )
+ SetError( SbxERR_BAD_INDEX );
+ pPar_->Get( 0 )->PutObject( pRes );
+ }
+}
+
+// Default: Index ab 1
+
+void SbxCollection::CollRemove( SbxArray* pPar_ )
+{
+ if( pPar_->Count() != 2 )
+ SetError( SbxERR_WRONG_ARGS );
+ else
+ {
+ short n = pPar_->Get( 1 )->GetInteger();
+ if( n < 1 || n > (short) pObjs->Count() )
+ SetError( SbxERR_BAD_INDEX );
+ else
+ Remove( pObjs->Get( (USHORT) n - 1 ) );
+ }
+}
+
+BOOL SbxCollection::LoadData( SvStream& rStrm, USHORT nVer )
+{
+ BOOL bRes = SbxObject::LoadData( rStrm, nVer );
+ Initialize();
+ return bRes;
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+SbxStdCollection::SbxStdCollection
+ ( const XubString& rClass, const XubString& rElem, BOOL b )
+ : SbxCollection( rClass ), aElemClass( rElem ),
+ bAddRemoveOk( b )
+{}
+
+SbxStdCollection::SbxStdCollection( const SbxStdCollection& r )
+ : SvRefBase( r ), SbxCollection( r ),
+ aElemClass( r.aElemClass ), bAddRemoveOk( r.bAddRemoveOk )
+{}
+
+SbxStdCollection& SbxStdCollection::operator=( const SbxStdCollection& r )
+{
+ if( &r != this )
+ {
+ if( !r.aElemClass.EqualsIgnoreCaseAscii( aElemClass ) )
+ SetError( SbxERR_CONVERSION );
+ else
+ SbxCollection::operator=( r );
+ }
+ return *this;
+}
+
+SbxStdCollection::~SbxStdCollection()
+{}
+
+// Default: Fehler, wenn falsches Objekt
+
+void SbxStdCollection::Insert( SbxVariable* p )
+{
+ SbxObject* pObj = PTR_CAST(SbxObject,p);
+ if( pObj && !pObj->IsClass( aElemClass ) )
+ SetError( SbxERR_BAD_ACTION );
+ else
+ SbxCollection::Insert( p );
+}
+
+void SbxStdCollection::CollAdd( SbxArray* pPar_ )
+{
+ if( !bAddRemoveOk )
+ SetError( SbxERR_BAD_ACTION );
+ else
+ SbxCollection::CollAdd( pPar_ );
+}
+
+void SbxStdCollection::CollRemove( SbxArray* pPar_ )
+{
+ if( !bAddRemoveOk )
+ SetError( SbxERR_BAD_ACTION );
+ else
+ SbxCollection::CollRemove( pPar_ );
+}
+
+BOOL SbxStdCollection::LoadData( SvStream& rStrm, USHORT nVer )
+{
+ BOOL bRes = SbxCollection::LoadData( rStrm, nVer );
+ if( bRes )
+ {
+ rStrm.ReadByteString( aElemClass, RTL_TEXTENCODING_ASCII_US );
+ rStrm >> bAddRemoveOk;
+ }
+ return bRes;
+}
+
+BOOL SbxStdCollection::StoreData( SvStream& rStrm ) const
+{
+ BOOL bRes = SbxCollection::StoreData( rStrm );
+ if( bRes )
+ {
+ rStrm.WriteByteString( aElemClass, RTL_TEXTENCODING_ASCII_US );
+ rStrm << bAddRemoveOk;
+ }
+ return bRes;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/sbx/sbxconv.hxx b/binfilter/bf_basic/source/sbx/sbxconv.hxx
new file mode 100644
index 000000000000..03a523cf5832
--- /dev/null
+++ b/binfilter/bf_basic/source/sbx/sbxconv.hxx
@@ -0,0 +1,158 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SBXCONV_HXX
+#define _SBXCONV_HXX
+
+#include "sbxdec.hxx"
+
+namespace binfilter {
+
+class SbxINT64Converter
+{
+public:
+ static BigInt SbxINT64_2_BigInt( const SbxINT64 &r );
+ static BOOL BigInt_2_SbxINT64( const BigInt& b, SbxINT64 *p );
+ static BigInt SbxUINT64_2_BigInt( const SbxUINT64 &r );
+ static BOOL BigInt_2_SbxUINT64( const BigInt& b, SbxUINT64 *p );
+};
+
+// SBXSCAN.CXX
+extern void ImpCvtNum( double nNum, short nPrec, String& rRes, BOOL bCoreString=FALSE );
+extern SbxError ImpScan
+ ( const String& rSrc, double& nVal, SbxDataType& rType, USHORT* pLen,
+ BOOL bAllowIntntl=FALSE, BOOL bOnlyIntntl=FALSE );
+
+// SBXINT.CXX
+
+double ImpRound( double );
+INT16 ImpGetInteger( const SbxValues* );
+void ImpPutInteger( SbxValues*, INT16 );
+sal_Int64 ImpGetInt64( const SbxValues* );
+void ImpPutInt64( SbxValues*, sal_Int64 );
+sal_uInt64 ImpGetUInt64( const SbxValues* );
+void ImpPutUInt64( SbxValues*, sal_uInt64 );
+
+sal_Int64 ImpDoubleToSalInt64( double d );
+sal_uInt64 ImpDoubleToSalUInt64( double d );
+double ImpSalUInt64ToDouble( sal_uInt64 n );
+
+// SBXLNG.CXX
+
+INT32 ImpGetLong( const SbxValues* );
+void ImpPutLong( SbxValues*, INT32 );
+
+// SBXSNG.CXX
+
+float ImpGetSingle( const SbxValues* );
+void ImpPutSingle( SbxValues*, float );
+
+// SBXDBL.CXX
+
+double ImpGetDouble( const SbxValues* );
+void ImpPutDouble( SbxValues*, double, BOOL bCoreString=FALSE );
+
+#if FALSE
+// SBX64.CXX
+
+SbxINT64 ImpGetINT64( const SbxValues* );
+void ImpPutINT64( SbxValues*, const SbxINT64& );
+SbxUINT64 ImpGetUINT64( const SbxValues* );
+void ImpPutUINT64( SbxValues*, const SbxUINT64& );
+#endif
+
+// SBXCURR.CXX
+
+SbxUINT64 ImpDoubleToUINT64( double );
+double ImpUINT64ToDouble( const SbxUINT64& );
+SbxINT64 ImpDoubleToINT64( double );
+double ImpINT64ToDouble( const SbxINT64& );
+
+#if TRUE
+INT32 ImpGetCurrLong( const SbxValues* );
+void ImpPutCurrLong( SbxValues*, INT32 );
+INT32 ImpDoubleToCurrLong( double );
+double ImpCurrLongToDouble( INT32 );
+#endif
+
+SbxINT64 ImpGetCurrency( const SbxValues* );
+void ImpPutCurrency( SbxValues*, const SbxINT64& );
+inline
+SbxINT64 ImpDoubleToCurrency( double d )
+ { return ImpDoubleToINT64( d * CURRENCY_FACTOR ); }
+inline
+double ImpCurrencyToDouble( const SbxINT64 &r )
+ { return ImpINT64ToDouble( r ) / CURRENCY_FACTOR; }
+
+
+// SBXDEC.CXX
+
+SbxDecimal* ImpCreateDecimal( SbxValues* p );
+SbxDecimal* ImpGetDecimal( const SbxValues* p );
+void ImpPutDecimal( SbxValues* p, SbxDecimal* pDec );
+
+// SBXDATE.CXX
+
+double ImpGetDate( const SbxValues* );
+void ImpPutDate( SbxValues*, double );
+
+// SBXSTR.CXX
+
+String ImpGetString( const SbxValues* );
+String ImpGetCoreString( const SbxValues* );
+void ImpPutString( SbxValues*, const String* );
+
+// SBXCHAR.CXX
+
+sal_Unicode ImpGetChar( const SbxValues* );
+void ImpPutChar( SbxValues*, sal_Unicode );
+
+// SBXBYTE.CXX
+BYTE ImpGetByte( const SbxValues* );
+void ImpPutByte( SbxValues*, BYTE );
+
+// SBXUINT.CXX
+
+UINT16 ImpGetUShort( const SbxValues* );
+void ImpPutUShort( SbxValues*, UINT16 );
+
+// SBXULNG.CXX
+
+UINT32 ImpGetULong( const SbxValues* );
+void ImpPutULong( SbxValues*, UINT32 );
+
+// SBXBOOL.CXX
+
+enum SbxBOOL ImpGetBool( const SbxValues* );
+void ImpPutBool( SbxValues*, INT16 );
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/sbx/sbxcurr.cxx b/binfilter/bf_basic/source/sbx/sbxcurr.cxx
new file mode 100644
index 000000000000..5e273496bd83
--- /dev/null
+++ b/binfilter/bf_basic/source/sbx/sbxcurr.cxx
@@ -0,0 +1,399 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "sbx.hxx"
+
+#include <tools/errcode.hxx>
+
+#define _TLBIGINT_INT64
+#include <tools/bigint.hxx>
+
+#include "sbxvar.hxx"
+#include "sbxconv.hxx"
+
+namespace binfilter {
+
+static String ImpCurrencyToString( const SbxINT64& );
+static SbxINT64 ImpStringToCurrency( const String& );
+
+SbxINT64 ImpGetCurrency( const SbxValues* p )
+{
+ SbxValues aTmp;
+ SbxINT64 nRes;
+start:
+ switch( +p->eType )
+ {
+ case SbxNULL:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ case SbxEMPTY:
+ nRes.SetNull(); break;
+ case SbxCHAR:
+ nRes = ImpDoubleToCurrency( (double)p->nChar ); break;
+ case SbxBYTE:
+ nRes = ImpDoubleToCurrency( (double)p->nByte ); break;
+ case SbxINTEGER:
+ case SbxBOOL:
+ nRes = ImpDoubleToCurrency( (double)p->nInteger ); break;
+ case SbxERROR:
+ case SbxUSHORT:
+ nRes = ImpDoubleToCurrency( (double)p->nUShort ); break;
+ case SbxCURRENCY:
+ nRes = p->nLong64; break;
+ case SbxLONG:
+ nRes = ImpDoubleToCurrency( (double)p->nLong );
+ break;
+ case SbxULONG:
+ nRes = ImpDoubleToCurrency( (double)p->nULong );
+ break;
+ case SbxSALINT64:
+ nRes = ImpDoubleToCurrency( (double)p->nInt64 );
+ break;
+ case SbxSALUINT64:
+ nRes = ImpDoubleToCurrency( ImpSalUInt64ToDouble( p->uInt64 ) );
+ break;
+ case SbxSINGLE:
+ if( p->nSingle > SbxMAXCURR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes.SetMax();
+ }
+ else if( p->nSingle < SbxMINCURR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes.SetMin();
+ }
+ else
+ nRes = ImpDoubleToCurrency( (double)p->nSingle );
+ break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ if( p->nDouble > SbxMAXCURR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes.SetMax();
+ }
+ else if( p->nDouble < SbxMINCURR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes.SetMin();
+ }
+ else
+ nRes = ImpDoubleToCurrency( p->nDouble );
+ break;
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ {
+ double d = 0.0;
+ if( p->pDecimal )
+ p->pDecimal->getDouble( d );
+ if( d > SbxMAXCURR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes.SetMax();
+ }
+ else if( d < SbxMINCURR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes.SetMin();
+ }
+ else
+ nRes = ImpDoubleToCurrency( d );
+ break;
+ }
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ if( !p->pString )
+ nRes.SetNull();
+ else
+ nRes = ImpStringToCurrency( *p->pString );
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ nRes = pVal->GetCurrency();
+ else
+ {
+ SbxBase::SetError( SbxERR_NO_OBJECT ); nRes.SetNull();
+ }
+ break;
+ }
+
+ case SbxBYREF | SbxCHAR:
+ nRes = ImpDoubleToCurrency( (double)*p->pChar ); break;
+ case SbxBYREF | SbxBYTE:
+ nRes = ImpDoubleToCurrency( (double)*p->pByte ); break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ nRes = ImpDoubleToCurrency( (double)*p->pInteger ); break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ nRes = ImpDoubleToCurrency( (double)*p->pUShort ); break;
+ case SbxBYREF | SbxCURRENCY:
+ nRes = *p->pLong64; break;
+
+ // ab hier muss getestet werden
+ case SbxBYREF | SbxLONG:
+ aTmp.nLong = *p->pLong; goto ref;
+ case SbxBYREF | SbxULONG:
+ aTmp.nULong = *p->pULong; goto ref;
+ case SbxBYREF | SbxSINGLE:
+ aTmp.nSingle = *p->pSingle; goto ref;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ aTmp.nDouble = *p->pDouble; goto ref;
+ case SbxBYREF | SbxSALINT64:
+ aTmp.nInt64 = *p->pnInt64; goto ref;
+ case SbxBYREF | SbxSALUINT64:
+ aTmp.uInt64 = *p->puInt64; goto ref;
+ ref:
+ aTmp.eType = SbxDataType( p->eType & 0x0FFF );
+ p = &aTmp; goto start;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION ); nRes.SetNull();
+ }
+ return nRes;
+}
+
+void ImpPutCurrency( SbxValues* p, const SbxINT64 &r )
+{
+ double dVal = ImpCurrencyToDouble( r );
+ SbxValues aTmp;
+start:
+ switch( +p->eType )
+ {
+ // Hier sind Tests notwendig
+ case SbxCHAR:
+ aTmp.pChar = &p->nChar; goto direct;
+ case SbxBYTE:
+ aTmp.pByte = &p->nByte; goto direct;
+ case SbxINTEGER:
+ case SbxBOOL:
+ aTmp.pInteger = &p->nInteger; goto direct;
+ case SbxLONG:
+ aTmp.pLong = &p->nLong; goto direct;
+ case SbxULONG:
+ aTmp.pULong = &p->nULong; goto direct;
+ case SbxERROR:
+ case SbxUSHORT:
+ aTmp.pUShort = &p->nUShort; goto direct;
+ direct:
+ aTmp.eType = SbxDataType( p->eType | SbxBYREF );
+ p = &aTmp; goto start;
+
+ // ab hier nicht mehr
+ case SbxSINGLE:
+ p->nSingle = (float)dVal; break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ p->nDouble = dVal; break;
+ case SbxSALINT64:
+ p->nInt64 = ImpDoubleToSalInt64( dVal ); break;
+ case SbxSALUINT64:
+ p->uInt64 = ImpDoubleToSalUInt64( dVal ); break;
+ case SbxCURRENCY:
+ p->nLong64 = r; break;
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ {
+ SbxDecimal* pDec = ImpCreateDecimal( p );
+ if( !pDec->setDouble( dVal ) )
+ SbxBase::SetError( SbxERR_OVERFLOW );
+ break;
+ }
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ if( !p->pString )
+ p->pString = new XubString;
+
+ *p->pString = ImpCurrencyToString( r );
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ pVal->PutCurrency( r );
+ else
+ SbxBase::SetError( SbxERR_NO_OBJECT );
+ break;
+ }
+ case SbxBYREF | SbxCHAR:
+ if( dVal > SbxMAXCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); dVal = SbxMAXCHAR;
+ }
+ else if( dVal < SbxMINCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); dVal = SbxMINCHAR;
+ }
+ *p->pChar = (xub_Unicode) dVal; break;
+ case SbxBYREF | SbxBYTE:
+ if( dVal > SbxMAXBYTE )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); dVal = SbxMAXBYTE;
+ }
+ else if( dVal < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); dVal = 0;
+ }
+ *p->pByte = (BYTE) dVal; break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ if( dVal > SbxMAXINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); dVal = SbxMAXINT;
+ }
+ else if( dVal < SbxMININT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); dVal = SbxMININT;
+ }
+ *p->pInteger = (INT16) dVal; break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ if( dVal > SbxMAXUINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); dVal = SbxMAXUINT;
+ }
+ else if( dVal < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); dVal = 0;
+ }
+ *p->pUShort = (UINT16) dVal; break;
+ case SbxBYREF | SbxLONG:
+ if( dVal > SbxMAXLNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); dVal = SbxMAXLNG;
+ }
+ else if( dVal < SbxMINLNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); dVal = SbxMINLNG;
+ }
+ *p->pLong = (INT32) dVal; break;
+ case SbxBYREF | SbxULONG:
+ if( dVal > SbxMAXULNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); dVal = SbxMAXULNG;
+ }
+ else if( dVal < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); dVal = 0;
+ }
+ *p->pULong = (UINT32) dVal; break;
+ case SbxBYREF | SbxSALINT64:
+ *p->pnInt64 = ImpDoubleToSalInt64( dVal ); break;
+ case SbxBYREF | SbxSALUINT64:
+ *p->puInt64 = ImpDoubleToSalUInt64( dVal ); break;
+ case SbxBYREF | SbxSINGLE:
+ *p->pSingle = (float) dVal; break;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ *p->pDouble = (double) dVal; break;
+ case SbxBYREF | SbxCURRENCY:
+ *p->pLong64 = r; break;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ }
+}
+
+// Hilfs-Funktionen zur Wandlung
+
+static String ImpCurrencyToString( const SbxINT64 &r )
+{
+ BigInt a10000 = 10000;
+
+ //return GetpApp()->GetAppInternational().GetCurr( BigInt( r ), 4 );
+ BigInt aInt( SbxINT64Converter::SbxINT64_2_BigInt( r ) );
+ aInt.Abs();
+ BigInt aFrac = aInt;
+ aInt /= a10000;
+ aFrac %= a10000;
+ aFrac += a10000;
+
+ String aString;
+ if( r.nHigh < 0 )
+ aString = '-';
+ aString += aInt.GetString();
+ aString += '.';
+ aString += aFrac.GetString().GetBuffer()+1;
+ return aString;
+}
+
+static SbxINT64 ImpStringToCurrency( const String &r )
+{
+ int nDec = 4;
+ String aStr;
+ const sal_Unicode* p = r.GetBuffer();
+
+ if( *p == '-' )
+ aStr += *p++;
+
+ while( *p >= '0' && *p <= '9' ) {
+ aStr += *p++;
+ if( *p == ',' )
+ p++;
+ }
+
+ if( *p == '.' ) {
+ p++;
+ while( nDec && *p >= '0' && *p <= '9' ) {
+ aStr += *p++;
+ nDec--;
+ }
+ }
+ while( nDec ) {
+ aStr += '0';
+ nDec--;
+ }
+
+ BigInt aBig( aStr );
+ SbxINT64 nRes;
+ SbxINT64Converter::BigInt_2_SbxINT64( aBig, &nRes );
+ return nRes;
+}
+
+double ImpINT64ToDouble( const SbxINT64 &r )
+{ return (double)r.nHigh*(double)4294967296.0 + (double)r.nLow; }
+
+SbxINT64 ImpDoubleToINT64( double d )
+{
+ SbxINT64 nRes;
+ nRes.Set( d );
+ return nRes;
+}
+
+double ImpUINT64ToDouble( const SbxUINT64 &r )
+{ return (double)r.nHigh*(double)4294967296.0 + (double)r.nLow; }
+
+SbxUINT64 ImpDoubleToUINT64( double d )
+{
+ SbxUINT64 nRes;
+ nRes.Set( d );
+ return nRes;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/sbx/sbxdate.cxx b/binfilter/bf_basic/source/sbx/sbxdate.cxx
new file mode 100644
index 000000000000..d936c719333b
--- /dev/null
+++ b/binfilter/bf_basic/source/sbx/sbxdate.cxx
@@ -0,0 +1,416 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <vcl/svapp.hxx>
+#include <bf_svtools/zforlist.hxx>
+#include <tools/errcode.hxx>
+#include <tools/color.hxx>
+#include <i18npool/lang.h>
+#include "sbx.hxx"
+#include "sbxconv.hxx"
+#include "math.h"
+
+#include <comphelper/processfactory.hxx>
+
+namespace binfilter {
+
+double ImpGetDate( const SbxValues* p )
+{
+ double nRes;
+ switch( +p->eType )
+ {
+ case SbxNULL:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ case SbxEMPTY:
+ nRes = 0; break;
+ case SbxCHAR:
+ nRes = p->nChar; break;
+ case SbxBYTE:
+ nRes = p->nByte; break;
+ case SbxINTEGER:
+ case SbxBOOL:
+ nRes = p->nInteger; break;
+ case SbxERROR:
+ case SbxUSHORT:
+ nRes = p->nUShort; break;
+ case SbxLONG:
+ nRes = (double) p->nLong; break;
+ case SbxULONG:
+ nRes = (double) p->nULong; break;
+ case SbxSINGLE:
+ nRes = p->nSingle; break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ nRes = p->nDouble; break;
+ case SbxULONG64:
+ nRes = ImpUINT64ToDouble( p->nULong64 ); break;
+ case SbxLONG64:
+ nRes = ImpINT64ToDouble( p->nLong64 ); break;
+ case SbxCURRENCY:
+ nRes = ImpCurrencyToDouble( p->nLong64 ); break;
+ case SbxSALINT64:
+ nRes = static_cast< double >(p->nInt64); break;
+ case SbxSALUINT64:
+ nRes = ImpSalUInt64ToDouble( p->uInt64 ); break;
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ if( p->pDecimal )
+ p->pDecimal->getDouble( nRes );
+ else
+ nRes = 0.0;
+ break;
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ if( !p->pString )
+ nRes = 0;
+ else
+ {
+#ifndef DOS
+ LanguageType eLangType = GetpApp()->GetSettings().GetLanguage();
+
+ SvNumberFormatter* pFormatter;
+ com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >
+ xFactory = comphelper::getProcessServiceFactory();
+ pFormatter = new SvNumberFormatter( xFactory, eLangType );
+
+ sal_uInt32 nIndex;
+ xub_StrLen nCheckPos = 0;
+ short nType = 127;
+
+ // Standard-Vorlagen des Formatters haben nur zweistellige
+ // Jahreszahl. Deshalb eigenes Format registrieren
+
+ // HACK, da der Numberformatter in PutandConvertEntry die Platzhalter
+ // fuer Monat, Tag, Jahr nicht entsprechend der Systemeinstellung
+ // austauscht. Problem: Print Year(Date) unter engl. BS
+ // siehe auch basic\source\runtime\runtime.cxx
+
+ SvtSysLocale aSysLocale;
+ DateFormat eDate = aSysLocale.GetLocaleData().getDateFormat();
+ String aDateStr;
+ switch( eDate )
+ {
+ case MDY: aDateStr.AssignAscii( "MM.TT.JJJJ" ); break;
+ case DMY: aDateStr.AssignAscii( "TT.MM.JJJJ" ); break;
+ case YMD: aDateStr.AssignAscii( "JJJJ.MM.TT" ); break;
+ default: aDateStr.AssignAscii( "MM.TT.JJJJ" );
+ }
+
+ String aStr( aDateStr );
+ aStr.AppendAscii( " HH:MM:SS" );
+
+ pFormatter->PutandConvertEntry( aStr, nCheckPos, nType,
+ nIndex, LANGUAGE_GERMAN, eLangType );
+ BOOL bSuccess = pFormatter->IsNumberFormat( *p->pString, nIndex, nRes );
+ if ( bSuccess )
+ {
+ short nType_ = pFormatter->GetType( nIndex );
+ if(!(nType_ & ( NUMBERFORMAT_DATETIME | NUMBERFORMAT_DATE |
+ NUMBERFORMAT_TIME | NUMBERFORMAT_DEFINED )))
+ bSuccess = FALSE;
+ }
+
+ if ( !bSuccess )
+ {
+ SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
+ }
+
+ delete pFormatter;
+#else
+ SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
+#endif
+ }
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ nRes = pVal->GetDate();
+ else
+ {
+ SbxBase::SetError( SbxERR_NO_OBJECT ); nRes = 0;
+ }
+ break;
+ }
+
+ case SbxBYREF | SbxCHAR:
+ nRes = *p->pChar; break;
+ case SbxBYREF | SbxBYTE:
+ nRes = *p->pByte; break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ nRes = *p->pInteger; break;
+ case SbxBYREF | SbxLONG:
+ nRes = *p->pLong; break;
+ case SbxBYREF | SbxULONG:
+ nRes = *p->pULong; break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ nRes = *p->pUShort; break;
+ case SbxBYREF | SbxSINGLE:
+ nRes = *p->pSingle; break;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ nRes = *p->pDouble; break;
+ case SbxBYREF | SbxULONG64:
+ nRes = ImpUINT64ToDouble( *p->pULong64 ); break;
+ case SbxBYREF | SbxLONG64:
+ nRes = ImpINT64ToDouble( *p->pLong64 ); break;
+ case SbxBYREF | SbxCURRENCY:
+ nRes = ImpCurrencyToDouble( *p->pLong64 ); break;
+ case SbxBYREF | SbxSALINT64:
+ nRes = static_cast< double >(*p->pnInt64); break;
+ case SbxBYREF | SbxSALUINT64:
+ nRes = ImpSalUInt64ToDouble( *p->puInt64 ); break;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
+ }
+ return nRes;
+}
+
+void ImpPutDate( SbxValues* p, double n )
+{
+ SbxValues aTmp;
+
+start:
+ switch( +p->eType )
+ {
+ case SbxDATE:
+ case SbxDOUBLE:
+ p->nDouble = n; break;
+
+ // ab hier wird getestet
+ case SbxCHAR:
+ aTmp.pChar = &p->nChar; goto direct;
+ case SbxBYTE:
+ aTmp.pByte = &p->nByte; goto direct;
+ case SbxINTEGER:
+ case SbxBOOL:
+ aTmp.pInteger = &p->nInteger; goto direct;
+ case SbxLONG:
+ aTmp.pLong = &p->nLong; goto direct;
+ case SbxULONG:
+ aTmp.pULong = &p->nULong; goto direct;
+ case SbxERROR:
+ case SbxUSHORT:
+ aTmp.pUShort = &p->nUShort; goto direct;
+ case SbxSINGLE:
+ aTmp.pSingle = &p->nSingle; goto direct;
+ case SbxULONG64:
+ aTmp.pULong64 = &p->nULong64; goto direct;
+ case SbxLONG64:
+ case SbxCURRENCY:
+ aTmp.pLong64 = &p->nLong64; goto direct;
+ case SbxSALINT64:
+ aTmp.pnInt64 = &p->nInt64; goto direct;
+ case SbxSALUINT64:
+ aTmp.puInt64 = &p->uInt64; goto direct;
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ {
+ SbxDecimal* pDec = ImpCreateDecimal( p );
+ if( !pDec->setDouble( n ) )
+ SbxBase::SetError( SbxERR_OVERFLOW );
+ break;
+ }
+ direct:
+ aTmp.eType = SbxDataType( p->eType | SbxBYREF );
+ p = &aTmp; goto start;
+
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+#ifndef DOS
+ {
+ if( !p->pString )
+ p->pString = new XubString;
+ Color* pColor;
+
+ LanguageType eLangType = GetpApp()->GetSettings().GetLanguage();
+ SvNumberFormatter* pFormatter;
+ com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >
+ xFactory = comphelper::getProcessServiceFactory();
+ pFormatter = new SvNumberFormatter( xFactory, eLangType );
+
+ sal_uInt32 nIndex;
+ xub_StrLen nCheckPos = 0;
+ short nType;
+
+ SvtSysLocale aSysLocale;
+ DateFormat eDate = aSysLocale.GetLocaleData().getDateFormat();
+ String aStr;
+ // ist der ganzzahlige Teil 0, wollen wir kein Jahr!
+ if( n <= -1.0 || n >= 1.0 )
+ {
+ // Time only if != 00:00:00
+ if( floor( n ) == n )
+ {
+ switch( eDate )
+ {
+ case MDY: aStr.AssignAscii( "MM.TT.JJJJ" ); break;
+ case DMY: aStr.AssignAscii( "TT.MM.JJJJ" ); break;
+ case YMD: aStr.AssignAscii( "JJJJ.MM.TT" ); break;
+ default: aStr.AssignAscii( "MM.TT.JJJJ" );
+ }
+ }
+ else
+ {
+ switch( eDate )
+ {
+ case MDY: aStr.AssignAscii( "MM.TT.JJJJ HH:MM:SS" ); break;
+ case DMY: aStr.AssignAscii( "TT.MM.JJJJ HH:MM:SS" ); break;
+ case YMD: aStr.AssignAscii( "JJJJ.MM.TT HH:MM:SS" ); break;
+ default: aStr.AssignAscii( "MM.TT.JJJJ HH:MM:SS" );
+ }
+ }
+ }
+ else
+ aStr.AppendAscii( "HH:MM:SS" );
+
+ pFormatter->PutandConvertEntry( aStr,
+ nCheckPos,
+ nType,
+ nIndex,
+ LANGUAGE_GERMAN,
+ eLangType );
+ pFormatter->GetOutputString( n, nIndex, *p->pString, &pColor );
+ delete pFormatter;
+#endif
+ break;
+#ifndef DOS
+ }
+#endif
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ pVal->PutDate( n );
+ else
+ SbxBase::SetError( SbxERR_NO_OBJECT );
+ break;
+ }
+ case SbxBYREF | SbxCHAR:
+ if( n > SbxMAXCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXCHAR;
+ }
+ else if( n < SbxMINCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINCHAR;
+ }
+ *p->pChar = (xub_Unicode) n; break;
+ case SbxBYREF | SbxBYTE:
+ if( n > SbxMAXBYTE )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXBYTE;
+ }
+ else if( n < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
+ }
+ *p->pByte = (BYTE) n; break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ if( n > SbxMAXINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXINT;
+ }
+ else if( n < SbxMININT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMININT;
+ }
+ *p->pInteger = (INT16) n; break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ if( n > SbxMAXUINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXUINT;
+ }
+ else if( n < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
+ }
+ *p->pUShort = (UINT16) n; break;
+ case SbxBYREF | SbxLONG:
+ if( n > SbxMAXLNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXLNG;
+ }
+ else if( n < SbxMINLNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINLNG;
+ }
+ *p->pLong = (INT32) n; break;
+ case SbxBYREF | SbxULONG:
+ if( n > SbxMAXULNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXULNG;
+ }
+ else if( n < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
+ }
+ *p->pULong = (UINT32) n; break;
+ case SbxBYREF | SbxSINGLE:
+ if( n > SbxMAXSNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXSNG;
+ }
+ else if( n < SbxMINSNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINSNG;
+ }
+ *p->pSingle = (float) n; break;
+ case SbxBYREF | SbxSALINT64:
+ *p->pnInt64 = ImpDoubleToSalInt64( n ); break;
+ case SbxBYREF | SbxSALUINT64:
+ *p->puInt64 = ImpDoubleToSalUInt64( n ); break;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ *p->pDouble = (double) n; break;
+ case SbxBYREF | SbxCURRENCY:
+ if( n > SbxMAXCURR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXCURR;
+ }
+ else if( n < SbxMINCURR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINCURR;
+ }
+ *p->pLong64 = ImpDoubleToCurrency( n ); break;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/sbx/sbxdbl.cxx b/binfilter/bf_basic/source/sbx/sbxdbl.cxx
new file mode 100644
index 000000000000..25815cee7482
--- /dev/null
+++ b/binfilter/bf_basic/source/sbx/sbxdbl.cxx
@@ -0,0 +1,301 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <tools/errcode.hxx>
+#include "sbx.hxx"
+#include "sbxconv.hxx"
+
+namespace binfilter {
+
+double ImpGetDouble( const SbxValues* p )
+{
+ double nRes;
+ switch( +p->eType )
+ {
+ case SbxNULL:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ case SbxEMPTY:
+ nRes = 0; break;
+ case SbxCHAR:
+ nRes = p->nChar; break;
+ case SbxBYTE:
+ nRes = p->nByte; break;
+ case SbxINTEGER:
+ case SbxBOOL:
+ nRes = p->nInteger; break;
+ case SbxERROR:
+ case SbxUSHORT:
+ nRes = p->nUShort; break;
+ case SbxLONG:
+ nRes = p->nLong; break;
+ case SbxULONG:
+ nRes = p->nULong; break;
+ case SbxSINGLE:
+ nRes = p->nSingle; break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ nRes = p->nDouble; break;
+ case SbxCURRENCY:
+ nRes = ImpCurrencyToDouble( p->nLong64 ); break;
+ case SbxSALINT64:
+ nRes = static_cast< double >(p->nInt64); break;
+ case SbxSALUINT64:
+ nRes = ImpSalUInt64ToDouble( p->uInt64 ); break;
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ if( p->pDecimal )
+ p->pDecimal->getDouble( nRes );
+ else
+ nRes = 0.0;
+ break;
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ if( !p->pString )
+ nRes = 0;
+ else
+ {
+ double d;
+ SbxDataType t;
+ if( ImpScan( *p->pString, d, t, NULL ) != SbxERR_OK )
+ nRes = 0;
+ else
+ nRes = d;
+ }
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ nRes = pVal->GetDouble();
+ else
+ {
+ SbxBase::SetError( SbxERR_NO_OBJECT ); nRes = 0;
+ }
+ break;
+ }
+
+ case SbxBYREF | SbxCHAR:
+ nRes = *p->pChar; break;
+ case SbxBYREF | SbxBYTE:
+ nRes = *p->pByte; break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ nRes = *p->pInteger; break;
+ case SbxBYREF | SbxLONG:
+ nRes = *p->pLong; break;
+ case SbxBYREF | SbxULONG:
+ nRes = *p->pULong; break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ nRes = *p->pUShort; break;
+ case SbxBYREF | SbxSINGLE:
+ nRes = *p->pSingle; break;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ nRes = *p->pDouble; break;
+ case SbxBYREF | SbxCURRENCY:
+ nRes = ImpCurrencyToDouble( *p->pLong64 ); break;
+ case SbxBYREF | SbxSALINT64:
+ nRes = static_cast< double >(*p->pnInt64); break;
+ case SbxBYREF | SbxSALUINT64:
+ nRes = ImpSalUInt64ToDouble( *p->puInt64 ); break;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
+ }
+ return nRes;
+}
+
+void ImpPutDouble( SbxValues* p, double n, BOOL bCoreString )
+{
+ SbxValues aTmp;
+start:
+ switch( +p->eType )
+ {
+ // Hier sind Tests notwendig
+ case SbxCHAR:
+ aTmp.pChar = &p->nChar; goto direct;
+ case SbxBYTE:
+ aTmp.pByte = &p->nByte; goto direct;
+ case SbxINTEGER:
+ case SbxBOOL:
+ aTmp.pInteger = &p->nInteger; goto direct;
+ case SbxLONG:
+ case SbxCURRENCY:
+ aTmp.pLong = &p->nLong; goto direct;
+ case SbxULONG:
+ aTmp.pULong = &p->nULong; goto direct;
+ case SbxERROR:
+ case SbxUSHORT:
+ aTmp.pUShort = &p->nUShort; goto direct;
+ case SbxSINGLE:
+ aTmp.pSingle = &p->nSingle; goto direct;
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ {
+ SbxDecimal* pDec = ImpCreateDecimal( p );
+ if( !pDec->setDouble( n ) )
+ SbxBase::SetError( SbxERR_OVERFLOW );
+ break;
+ }
+ direct:
+ aTmp.eType = SbxDataType( p->eType | SbxBYREF );
+ p = &aTmp; goto start;
+
+ // ab hier nicht mehr
+ case SbxSALINT64:
+ p->nInt64 = ImpDoubleToSalInt64( n ); break;
+ case SbxSALUINT64:
+ p->uInt64 = ImpDoubleToSalUInt64( n ); break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ p->nDouble = n; break;
+
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ if( !p->pString )
+ p->pString = new XubString;
+ ImpCvtNum( (double) n, 14, *p->pString, bCoreString );
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ pVal->PutDouble( n );
+ else
+ SbxBase::SetError( SbxERR_NO_OBJECT );
+ break;
+ }
+ case SbxBYREF | SbxCHAR:
+ if( n > SbxMAXCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXCHAR;
+ }
+ else if( n < SbxMINCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINCHAR;
+ }
+ *p->pChar = (xub_Unicode) n; break;
+ case SbxBYREF | SbxBYTE:
+ if( n > SbxMAXBYTE )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXBYTE;
+ }
+ else if( n < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
+ }
+ *p->pByte = (BYTE) n; break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ if( n > SbxMAXINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXINT;
+ }
+ else if( n < SbxMININT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMININT;
+ }
+ *p->pInteger = (INT16) n; break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ if( n > SbxMAXUINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXUINT;
+ }
+ else if( n < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
+ }
+ *p->pUShort = (UINT16) n; break;
+ case SbxBYREF | SbxLONG:
+ if( n > SbxMAXLNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXLNG;
+ }
+ else if( n < SbxMINLNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINLNG;
+ }
+ *p->pLong = (INT32) n; break;
+ case SbxBYREF | SbxULONG:
+ if( n > SbxMAXULNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXULNG;
+ }
+ else if( n < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
+ }
+ *p->pULong = (UINT32) n; break;
+ case SbxBYREF | SbxSINGLE:
+ if( n > SbxMAXSNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXSNG;
+ }
+ else if( n < SbxMINSNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINSNG;
+ }
+ else if( n > 0 && n < SbxMAXSNG2 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXSNG2;
+ }
+ else if( n < 0 && n > SbxMINSNG2 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINSNG2;
+ }
+ *p->pSingle = (float) n; break;
+ case SbxBYREF | SbxSALINT64:
+ *p->pnInt64 = ImpDoubleToSalInt64( n ); break;
+ case SbxBYREF | SbxSALUINT64:
+ *p->puInt64 = ImpDoubleToSalUInt64( n ); break;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ *p->pDouble = (double) n; break;
+ case SbxBYREF | SbxCURRENCY:
+ if( n > SbxMAXCURR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXCURR;
+ }
+ else if( n < SbxMINCURR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINCURR;
+ }
+ *p->pLong64 = ImpDoubleToCurrency( n ); break;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/sbx/sbxdec.cxx b/binfilter/bf_basic/source/sbx/sbxdec.cxx
new file mode 100644
index 000000000000..ff74d6664d92
--- /dev/null
+++ b/binfilter/bf_basic/source/sbx/sbxdec.cxx
@@ -0,0 +1,742 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <tools/errcode.hxx>
+
+#include "sbx.hxx"
+#include "sbxconv.hxx"
+
+#include <com/sun/star/bridge/oleautomation/Decimal.hpp>
+
+namespace binfilter {
+
+#ifdef WIN32
+// int GnDecCounter = 0;
+SbxDecimal::SbxDecimal( void )
+{
+ setInt( 0 );
+ mnRefCount = 0;
+ // GnDecCounter++;
+}
+#endif
+
+SbxDecimal::SbxDecimal( const SbxDecimal& rDec )
+{
+#ifdef WIN32
+ maDec = rDec.maDec;
+#else
+ (void)rDec;
+#endif
+ mnRefCount = 0;
+ // GnDecCounter++;
+}
+
+SbxDecimal::~SbxDecimal()
+{
+ // GnDecCounter--;
+}
+
+void releaseDecimalPtr( SbxDecimal*& rpDecimal )
+{
+ if( rpDecimal )
+ {
+ rpDecimal->mnRefCount--;
+ if( rpDecimal->mnRefCount == 0 )
+ {
+ delete rpDecimal;
+ rpDecimal = NULL;
+ }
+ }
+}
+
+#ifdef WIN32
+
+bool SbxDecimal::operator -= ( const SbxDecimal &r )
+{
+ HRESULT hResult = VarDecSub( &maDec, (LPDECIMAL)&r.maDec, &maDec );
+ bool bRet = ( hResult == S_OK );
+ return bRet;
+}
+
+bool SbxDecimal::operator += ( const SbxDecimal &r )
+{
+ HRESULT hResult = VarDecAdd( &maDec, (LPDECIMAL)&r.maDec, &maDec );
+ bool bRet = ( hResult == S_OK );
+ return bRet;
+}
+
+bool SbxDecimal::operator /= ( const SbxDecimal &r )
+{
+ HRESULT hResult = VarDecDiv( &maDec, (LPDECIMAL)&r.maDec, &maDec );
+ bool bRet = ( hResult == S_OK );
+ return bRet;
+}
+
+bool SbxDecimal::operator *= ( const SbxDecimal &r )
+{
+ HRESULT hResult = VarDecMul( &maDec, (LPDECIMAL)&r.maDec, &maDec );
+ bool bRet = ( hResult == S_OK );
+ return bRet;
+}
+
+bool SbxDecimal::neg( void )
+{
+ HRESULT hResult = VarDecNeg( &maDec, &maDec );
+ bool bRet = ( hResult == S_OK );
+ return bRet;
+}
+
+bool SbxDecimal::isZero( void )
+{
+ SbxDecimal aZeroDec;
+ aZeroDec.setLong( 0 );
+ bool bZero = ( EQ == compare( *this, aZeroDec ) );
+ return bZero;
+}
+
+SbxDecimal::CmpResult compare( const SbxDecimal &rLeft, const SbxDecimal &rRight )
+{
+ HRESULT hResult = VarDecCmp( (LPDECIMAL)&rLeft.maDec, (LPDECIMAL)&rRight.maDec );
+ SbxDecimal::CmpResult eRes = (SbxDecimal::CmpResult)hResult;
+ return eRes;
+}
+
+void SbxDecimal::setChar( sal_Unicode val )
+{
+ VarDecFromUI2( (USHORT)val, &maDec );
+}
+
+void SbxDecimal::setByte( BYTE val )
+{
+ VarDecFromUI1( (BYTE)val, &maDec );
+}
+
+void SbxDecimal::setShort( INT16 val )
+{
+ VarDecFromI2( (short)val, &maDec );
+}
+
+void SbxDecimal::setLong( INT32 val )
+{
+ VarDecFromI4( (long)val, &maDec );
+}
+
+void SbxDecimal::setUShort( UINT16 val )
+{
+ VarDecFromUI2( (USHORT)val, &maDec );
+}
+
+void SbxDecimal::setULong( UINT32 val )
+{
+ VarDecFromUI4( (ULONG)val, &maDec );
+}
+
+bool SbxDecimal::setSingle( float val )
+{
+ bool bRet = ( VarDecFromR4( val, &maDec ) == S_OK );
+ return bRet;
+}
+
+bool SbxDecimal::setDouble( double val )
+{
+ bool bRet = ( VarDecFromR8( val, &maDec ) == S_OK );
+ return bRet;
+}
+
+void SbxDecimal::setInt( int val )
+{
+ setLong( (INT32)val );
+}
+
+void SbxDecimal::setUInt( unsigned int val )
+{
+ setULong( (UINT32)val );
+}
+
+// sbxscan.cxx
+void ImpGetIntntlSep( sal_Unicode& rcDecimalSep, sal_Unicode& rcThousandSep );
+
+bool SbxDecimal::setString( String* pString )
+{
+ static LCID nLANGID = MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US );
+
+ // Convert delimiter
+ sal_Unicode cDecimalSep;
+ sal_Unicode cThousandSep;
+ ImpGetIntntlSep( cDecimalSep, cThousandSep );
+
+ bool bRet = false;
+ HRESULT hResult;
+ if( cDecimalSep != '.' || cThousandSep != ',' )
+ {
+ int nLen = pString->Len();
+ sal_Unicode* pBuffer = new sal_Unicode[nLen + 1];
+ pBuffer[nLen] = 0;
+
+ const sal_Unicode* pSrc = pString->GetBuffer();
+ int i;
+ for( i = 0 ; i < nLen ; ++i )
+ pBuffer[i] = pSrc[i];
+
+ sal_Unicode c;
+ i = 0;
+ while( (c = pBuffer[i]) != 0 )
+ {
+ if( c == cDecimalSep )
+ pBuffer[i] = '.';
+ else if( c == cThousandSep )
+ pBuffer[i] = ',';
+ i++;
+ }
+ hResult = VarDecFromStr( (OLECHAR*)pBuffer, nLANGID, 0, &maDec );
+ delete pBuffer;
+ }
+ else
+ {
+ hResult = VarDecFromStr( (OLECHAR*)pString->GetBuffer(), nLANGID, 0, &maDec );
+ }
+ bRet = ( hResult == S_OK );
+ return bRet;
+}
+
+
+bool SbxDecimal::getChar( sal_Unicode& rVal )
+{
+ bool bRet = ( VarUI2FromDec( &maDec, &rVal ) == S_OK );
+ return bRet;
+}
+
+bool SbxDecimal::getShort( INT16& rVal )
+{
+ bool bRet = ( VarI2FromDec( &maDec, &rVal ) == S_OK );
+ return bRet;
+}
+
+bool SbxDecimal::getLong( INT32& rVal )
+{
+ bool bRet = ( VarI4FromDec( &maDec, &rVal ) == S_OK );
+ return bRet;
+}
+
+bool SbxDecimal::getUShort( UINT16& rVal )
+{
+ bool bRet = ( VarUI2FromDec( &maDec, &rVal ) == S_OK );
+ return bRet;
+}
+
+bool SbxDecimal::getULong( UINT32& rVal )
+{
+ bool bRet = ( VarUI4FromDec( &maDec, &rVal ) == S_OK );
+ return bRet;
+}
+
+bool SbxDecimal::getSingle( float& rVal )
+{
+ bool bRet = ( VarR4FromDec( &maDec, &rVal ) == S_OK );
+ return bRet;
+}
+
+bool SbxDecimal::getDouble( double& rVal )
+{
+ bool bRet = ( VarR8FromDec( &maDec, &rVal ) == S_OK );
+ return bRet;
+}
+
+bool SbxDecimal::getUInt( unsigned int& rVal )
+{
+ UINT32 TmpVal;
+ bool bRet = getULong( TmpVal );
+ rVal = TmpVal;
+ return bRet;
+}
+
+#else
+// !WIN32
+
+bool SbxDecimal::operator -= ( const SbxDecimal &r )
+{
+ (void)r;
+ return false;
+}
+
+bool SbxDecimal::operator += ( const SbxDecimal &r )
+{
+ (void)r;
+ return false;
+}
+
+bool SbxDecimal::operator /= ( const SbxDecimal &r )
+{
+ (void)r;
+ return false;
+}
+
+bool SbxDecimal::operator *= ( const SbxDecimal &r )
+{
+ (void)r;
+ return false;
+}
+
+bool SbxDecimal::neg( void )
+{
+ return false;
+}
+
+bool SbxDecimal::isZero( void )
+{
+ return false;
+}
+
+SbxDecimal::CmpResult compare( const SbxDecimal &rLeft, const SbxDecimal &rRight )
+{
+ (void)rLeft;
+ (void)rRight;
+ return (SbxDecimal::CmpResult)0;
+}
+
+void SbxDecimal::setChar( sal_Unicode val ) { (void)val; }
+void SbxDecimal::setByte( BYTE val ) { (void)val; }
+void SbxDecimal::setLong( INT32 val ) { (void)val; }
+void SbxDecimal::setULong( UINT32 val ) { (void)val; }
+bool SbxDecimal::setSingle( float val ) { (void)val; return false; }
+bool SbxDecimal::setDouble( double val ) { (void)val; return false; }
+void SbxDecimal::setInt( int val ) { (void)val; }
+void SbxDecimal::setUInt( unsigned int val ) { (void)val; }
+
+bool SbxDecimal::getSingle( float& rVal ) { (void)rVal; return false; }
+bool SbxDecimal::getDouble( double& rVal ) { (void)rVal; return false; }
+
+#endif
+
+#ifdef WIN32
+bool SbxDecimal::getString( String& rString )
+{
+ static LCID nLANGID = MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US );
+
+ bool bRet = false;
+
+ OLECHAR sz[100];
+ BSTR aBStr = SysAllocString( sz );
+ if( aBStr != NULL )
+ {
+ HRESULT hResult = VarBstrFromDec( &maDec, nLANGID, 0, &aBStr );
+ bRet = ( hResult == S_OK );
+ if( bRet )
+ {
+ // Convert delimiter
+ sal_Unicode cDecimalSep;
+ sal_Unicode cThousandSep;
+ ImpGetIntntlSep( cDecimalSep, cThousandSep );
+
+ if( cDecimalSep != '.' || cThousandSep != ',' )
+ {
+ sal_Unicode c;
+ int i = 0;
+ while( (c = aBStr[i]) != 0 )
+ {
+ if( c == '.' )
+ aBStr[i] = cDecimalSep;
+ else if( c == ',' )
+ aBStr[i] = cThousandSep;
+ i++;
+ }
+ }
+ rString = reinterpret_cast<const sal_Unicode*>(aBStr);
+ }
+
+ SysFreeString( aBStr );
+ }
+ return bRet;
+}
+#endif
+
+SbxDecimal* ImpCreateDecimal( SbxValues* p )
+{
+#ifdef WIN32
+ if( !p )
+ return NULL;
+
+ SbxDecimal*& rpDecimal = p->pDecimal;
+ if( rpDecimal == NULL )
+ {
+ rpDecimal = new SbxDecimal();
+ rpDecimal->addRef();
+ }
+ return rpDecimal;
+#else
+ (void)p;
+ return NULL;
+#endif
+}
+
+SbxDecimal* ImpGetDecimal( const SbxValues* p )
+{
+#ifdef WIN32
+ SbxValues aTmp;
+ SbxDecimal* pnDecRes;
+
+ SbxDataType eType = p->eType;
+ if( eType == SbxDECIMAL && p->pDecimal )
+ {
+ pnDecRes = new SbxDecimal( *p->pDecimal );
+ pnDecRes->addRef();
+ return pnDecRes;
+ }
+ pnDecRes = new SbxDecimal();
+ pnDecRes->addRef();
+
+start:
+ switch( +eType )
+ {
+ case SbxNULL:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ case SbxEMPTY:
+ pnDecRes->setShort( 0 ); break;
+ case SbxCHAR:
+ pnDecRes->setChar( p->nChar ); break;
+ case SbxBYTE:
+ pnDecRes->setByte( p->nByte ); break;
+ case SbxINTEGER:
+ case SbxBOOL:
+ pnDecRes->setInt( p->nInteger ); break;
+ case SbxERROR:
+ case SbxUSHORT:
+ pnDecRes->setUShort( p->nUShort ); break;
+ case SbxLONG:
+ pnDecRes->setLong( p->nLong ); break;
+ case SbxULONG:
+ pnDecRes->setULong( p->nULong ); break;
+ case SbxSINGLE:
+ if( !pnDecRes->setSingle( p->nSingle ) )
+ SbxBase::SetError( SbxERR_OVERFLOW );
+ break;
+ case SbxSALINT64:
+ {
+ double d = (double)p->nInt64;
+ pnDecRes->setDouble( d );
+ break;
+ }
+ case SbxSALUINT64:
+ {
+ double d = ImpSalUInt64ToDouble( p->uInt64 );
+ pnDecRes->setDouble( d );
+ break;
+ }
+ case SbxDATE:
+ case SbxDOUBLE:
+ case SbxLONG64:
+ case SbxULONG64:
+ case SbxCURRENCY:
+ {
+ double dVal;
+ if( p->eType == SbxCURRENCY )
+ dVal = ImpCurrencyToDouble( p->nLong64 );
+ else if( p->eType == SbxLONG64 )
+ dVal = ImpINT64ToDouble( p->nLong64 );
+ else if( p->eType == SbxULONG64 )
+ dVal = ImpUINT64ToDouble( p->nULong64 );
+ else
+ dVal = p->nDouble;
+
+ if( !pnDecRes->setDouble( dVal ) )
+ SbxBase::SetError( SbxERR_OVERFLOW );
+ break;
+ }
+ case SbxLPSTR:
+ case SbxSTRING:
+ case SbxBYREF | SbxSTRING:
+ pnDecRes->setString( p->pString ); break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ pnDecRes->setDecimal( pVal->GetDecimal() );
+ else
+ {
+ SbxBase::SetError( SbxERR_NO_OBJECT );
+ pnDecRes->setShort( 0 );
+ }
+ break;
+ }
+
+ case SbxBYREF | SbxCHAR:
+ pnDecRes->setChar( *p->pChar ); break;
+ case SbxBYREF | SbxBYTE:
+ pnDecRes->setByte( *p->pByte ); break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ pnDecRes->setInt( *p->pInteger ); break;
+ case SbxBYREF | SbxLONG:
+ pnDecRes->setLong( *p->pLong ); break;
+ case SbxBYREF | SbxULONG:
+ pnDecRes->setULong( *p->pULong ); break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ pnDecRes->setUShort( *p->pUShort ); break;
+
+ // ab hier muss getestet werden
+ case SbxBYREF | SbxSINGLE:
+ aTmp.nSingle = *p->pSingle; goto ref;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ aTmp.nDouble = *p->pDouble; goto ref;
+ case SbxBYREF | SbxULONG64:
+ aTmp.nULong64 = *p->pULong64; goto ref;
+ case SbxBYREF | SbxLONG64:
+ case SbxBYREF | SbxCURRENCY:
+ aTmp.nLong64 = *p->pLong64; goto ref;
+ case SbxBYREF | SbxSALINT64:
+ aTmp.nInt64 = *p->pnInt64; goto ref;
+ case SbxBYREF | SbxSALUINT64:
+ aTmp.uInt64 = *p->puInt64; goto ref;
+ ref:
+ aTmp.eType = SbxDataType( p->eType & 0x0FFF );
+ p = &aTmp; goto start;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION ); pnDecRes->setShort( 0 );
+ }
+ return pnDecRes;
+#else
+ (void)p;
+ return NULL;
+#endif
+}
+
+
+void ImpPutDecimal( SbxValues* p, SbxDecimal* pDec )
+{
+#ifdef WIN32
+ if( !pDec )
+ return;
+
+ SbxValues aTmp;
+start:
+ switch( +p->eType )
+ {
+ // hier muss getestet werden
+ case SbxCHAR:
+ aTmp.pChar = &p->nChar; goto direct;
+ case SbxBYTE:
+ aTmp.pByte = &p->nByte; goto direct;
+ case SbxULONG:
+ aTmp.pULong = &p->nULong; goto direct;
+ case SbxERROR:
+ case SbxUSHORT:
+ aTmp.pUShort = &p->nUShort; goto direct;
+ case SbxSALUINT64:
+ aTmp.puInt64 = &p->uInt64; goto direct;
+ case SbxINTEGER:
+ case SbxBOOL:
+ aTmp.pInteger = &p->nInteger; goto direct;
+ case SbxLONG:
+ aTmp.pLong = &p->nLong; goto direct;
+ case SbxSALINT64:
+ aTmp.pnInt64 = &p->nInt64; goto direct;
+ case SbxCURRENCY:
+ aTmp.pLong64 = &p->nLong64; goto direct;
+ direct:
+ aTmp.eType = SbxDataType( p->eType | SbxBYREF );
+ p = &aTmp; goto start;
+
+ // ab hier nicht mehr
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ {
+ if( pDec != p->pDecimal )
+ {
+ releaseDecimalPtr( p->pDecimal );
+ // if( p->pDecimal )
+ // p->pDecimal->ReleaseRef();
+ p->pDecimal = pDec;
+ if( pDec )
+ pDec->addRef();
+ }
+ break;
+ }
+ case SbxSINGLE:
+ {
+ float f;
+ pDec->getSingle( f );
+ p->nSingle = f;
+ break;
+ }
+ case SbxDATE:
+ case SbxDOUBLE:
+ {
+ double d;
+ pDec->getDouble( d );
+ p->nDouble = d;
+ break;
+ }
+ case SbxULONG64:
+ {
+ double d;
+ pDec->getDouble( d );
+ p->nULong64 = ImpDoubleToUINT64( d );
+ break;
+ }
+ case SbxLONG64:
+ {
+ double d;
+ pDec->getDouble( d );
+ p->nLong64 = ImpDoubleToINT64( d );
+ break;
+ }
+
+ case SbxLPSTR:
+ case SbxSTRING:
+ case SbxBYREF | SbxSTRING:
+ if( !p->pString )
+ p->pString = new XubString;
+ // ImpCvtNum( (double) n, 0, *p->pString );
+ pDec->getString( *p->pString );
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ pVal->PutDecimal( pDec );
+ else
+ SbxBase::SetError( SbxERR_NO_OBJECT );
+ break;
+ }
+
+ case SbxBYREF | SbxCHAR:
+ if( !pDec->getChar( *p->pChar ) )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW );
+ *p->pChar = 0;
+ }
+ break;
+ case SbxBYREF | SbxBYTE:
+ if( !pDec->getChar( *p->pChar ) )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW );
+ *p->pByte = 0;
+ }
+ break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ if( !pDec->getShort( *p->pInteger ) )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW );
+ *p->pInteger = 0;
+ }
+ break;
+ // *p->pInteger = n; break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ if( !pDec->getUShort( *p->pUShort ) )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW );
+ *p->pUShort = 0;
+ }
+ break;
+ case SbxBYREF | SbxLONG:
+ if( !pDec->getLong( *p->pLong ) )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW );
+ *p->pLong = 0;
+ }
+ break;
+ case SbxBYREF | SbxULONG:
+ if( !pDec->getULong( *p->pULong ) )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW );
+ *p->pULong = 0;
+ }
+ break;
+ case SbxBYREF | SbxSALINT64:
+ {
+ double d;
+ if( !pDec->getDouble( d ) )
+ SbxBase::SetError( SbxERR_OVERFLOW );
+ else
+ *p->pnInt64 = ImpDoubleToSalInt64( d );
+ break;
+ }
+ case SbxBYREF | SbxSALUINT64:
+ {
+ double d;
+ if( !pDec->getDouble( d ) )
+ SbxBase::SetError( SbxERR_OVERFLOW );
+ else
+ *p->puInt64 = ImpDoubleToSalUInt64( d );
+ break;
+ }
+ case SbxBYREF | SbxSINGLE:
+ if( !pDec->getSingle( *p->pSingle ) )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW );
+ *p->pSingle = 0;
+ }
+ break;
+ // *p->pSingle = (float) n; break;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ if( !pDec->getDouble( *p->pDouble ) )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW );
+ *p->pDouble = 0;
+ }
+ break;
+ case SbxBYREF | SbxULONG64:
+ {
+ double d;
+ pDec->getDouble( d );
+ *p->pULong64 = ImpDoubleToUINT64( d );
+ break;
+ }
+ case SbxBYREF | SbxLONG64:
+ {
+ double d;
+ pDec->getDouble( d );
+ *p->pLong64 = ImpDoubleToINT64( d );
+ break;
+ }
+ case SbxBYREF | SbxCURRENCY:
+ {
+ double d;
+ pDec->getDouble( d );
+ *p->pLong64 = ImpDoubleToCurrency( d );
+ break;
+ }
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ }
+#else
+ (void)p;
+ (void)pDec;
+#endif
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/sbx/sbxdec.hxx b/binfilter/bf_basic/source/sbx/sbxdec.hxx
new file mode 100644
index 000000000000..3fd5019c934f
--- /dev/null
+++ b/binfilter/bf_basic/source/sbx/sbxdec.hxx
@@ -0,0 +1,127 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef __SBX_SBX_DEC_HXX
+#define __SBX_SBX_DEC_HXX
+
+#ifdef WIN32
+
+#include <tools/prewin.h>
+} // close extern "C" {
+
+#ifndef __MINGW32__
+#include <comutil.h>
+#endif
+#include <oleauto.h>
+
+extern "C" { // reopen extern "C" {
+#include <tools/postwin.h>
+
+#endif
+#endif
+
+#include "sbx.hxx"
+
+#include <com/sun/star/bridge/oleautomation/Decimal.hpp>
+
+namespace binfilter {
+
+// Decimal support
+// Implementation only for windows
+
+class SbxDecimal
+{
+ friend void releaseDecimalPtr( SbxDecimal*& rpDecimal );
+
+#ifdef WIN32
+ DECIMAL maDec;
+#endif
+ INT32 mnRefCount;
+
+public:
+#ifdef WIN32
+ SbxDecimal();
+#endif
+ SbxDecimal( const SbxDecimal& rDec );
+
+ ~SbxDecimal();
+
+ void addRef( void )
+ { mnRefCount++; }
+
+ void setChar( sal_Unicode val );
+ void setByte( BYTE val );
+#ifdef WIN32
+ void setShort( INT16 val );
+ bool setString( String* pString );
+ void setUShort( UINT16 val );
+#endif
+ void setLong( INT32 val );
+ void setULong( UINT32 val );
+ bool setSingle( float val );
+ bool setDouble( double val );
+ void setInt( int val );
+ void setUInt( unsigned int val );
+ void setDecimal( SbxDecimal* pDecimal )
+ {
+#ifdef WIN32
+ if( pDecimal )
+ maDec = pDecimal->maDec;
+#else
+ (void)pDecimal;
+#endif
+ }
+
+#ifdef WIN32
+ bool getShort( INT16& rVal );
+ bool getChar( sal_Unicode& rVal );
+ bool getLong( INT32& rVal );
+ bool getString( String& rString );
+ bool getUInt( unsigned int& rVal );
+ bool getULong( UINT32& rVal );
+ bool getUShort( UINT16& rVal );
+#endif
+ bool getSingle( float& rVal );
+ bool getDouble( double& rVal );
+
+ bool operator -= ( const SbxDecimal &r );
+ bool operator += ( const SbxDecimal &r );
+ bool operator /= ( const SbxDecimal &r );
+ bool operator *= ( const SbxDecimal &r );
+ bool neg( void );
+
+ bool isZero( void );
+
+ enum CmpResult { LT, EQ, GT };
+ friend CmpResult compare( const SbxDecimal &rLeft, const SbxDecimal &rRight );
+};
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/sbx/sbxexec.cxx b/binfilter/bf_basic/source/sbx/sbxexec.cxx
new file mode 100644
index 000000000000..679495e228be
--- /dev/null
+++ b/binfilter/bf_basic/source/sbx/sbxexec.cxx
@@ -0,0 +1,402 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <tools/errcode.hxx>
+#include <vcl/svapp.hxx>
+#include "sbx.hxx"
+
+namespace binfilter {
+
+class SbxSimpleCharClass
+{
+public:
+ BOOL isAlpha( sal_Unicode c ) const
+ {
+ BOOL bRet = (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
+ return bRet;
+ }
+
+ BOOL isDigit( sal_Unicode c ) const
+ {
+ BOOL bRet = (c >= '0' && c <= '9');
+ return bRet;
+ }
+
+ BOOL isAlphaNumeric( sal_Unicode c ) const
+ {
+ BOOL bRet = isDigit( c ) || isAlpha( c );
+ return bRet;
+ }
+};
+
+
+static SbxVariable* Element
+ ( SbxObject* pObj, SbxObject* pGbl, const xub_Unicode** ppBuf,
+ SbxClassType, const SbxSimpleCharClass& rCharClass );
+
+static const xub_Unicode* SkipWhitespace( const xub_Unicode* p )
+{
+ while( *p && ( *p == ' ' || *p == '\t' ) )
+ p++;
+ return p;
+}
+
+// Scannen eines Symbol. Das Symbol wird in rSym eingetragen, der Returnwert
+// ist die neue Scanposition. Bei Fehlern ist das Symbol leer.
+
+static const xub_Unicode* Symbol( const xub_Unicode* p, XubString& rSym, const SbxSimpleCharClass& rCharClass )
+{
+ USHORT nLen = 0;
+ // Haben wir ein Sondersymbol?
+ if( *p == '[' )
+ {
+ rSym = ++p;
+ while( *p && *p != ']' )
+ p++, nLen++;
+ p++;
+ }
+ else
+ {
+ // Ein Symbol muss mit einem Buchstaben oder einem Underline beginnen
+ if( !rCharClass.isAlpha( *p ) && *p != '_' )
+ SbxBase::SetError( SbxERR_SYNTAX );
+ else
+ {
+ rSym = p;
+ // Dann darf es Buchstaben, Zahlen oder Underlines enthalten
+ while( *p && (rCharClass.isAlphaNumeric( *p ) || *p == '_') )
+ p++, nLen++;
+ // BASIC-Standard-Suffixe werden ignoriert
+ if( *p && (*p == '%' || *p == '&' || *p == '!' || *p == '#' || *p == '$' ) )
+ p++;
+ }
+ }
+ rSym.Erase( nLen );
+ return p;
+}
+
+// Qualifizierter Name. Element.Element....
+
+static SbxVariable* QualifiedName
+ ( SbxObject* pObj, SbxObject* pGbl, const xub_Unicode** ppBuf, SbxClassType t )
+{
+ static SbxSimpleCharClass aCharClass;
+
+ SbxVariableRef refVar;
+ const xub_Unicode* p = SkipWhitespace( *ppBuf );
+ if( aCharClass.isAlpha( *p ) || *p == '_' || *p == '[' )
+ {
+ // Element einlesen
+ refVar = Element( pObj, pGbl, &p, t, aCharClass );
+ while( refVar.Is() && (*p == '.' || *p == '!') )
+ {
+ // Es folgt noch ein Objektelement. Das aktuelle Element
+ // muss also ein SBX-Objekt sein oder liefern!
+ pObj = PTR_CAST(SbxObject,(SbxVariable*) refVar);
+ if( !pObj )
+ // Dann muss es ein Objekt liefern
+ pObj = PTR_CAST(SbxObject,refVar->GetObject());
+ refVar.Clear();
+ if( !pObj )
+ break;
+ p++;
+ // Und das naechste Element bitte
+ refVar = Element( pObj, pGbl, &p, t, aCharClass );
+ }
+ }
+ else
+ SbxBase::SetError( SbxERR_SYNTAX );
+ *ppBuf = p;
+ if( refVar.Is() )
+ refVar->AddRef();
+ return refVar;
+}
+
+// Einlesen eines Operanden. Dies kann eine Zahl, ein String oder
+// eine Funktion (mit optionalen Parametern) sein.
+
+static SbxVariable* Operand
+ ( SbxObject* pObj, SbxObject* pGbl, const xub_Unicode** ppBuf, BOOL bVar )
+{
+ static SbxSimpleCharClass aCharClass;
+
+ SbxVariableRef refVar( new SbxVariable );
+ const xub_Unicode* p = SkipWhitespace( *ppBuf );
+ if( !bVar && ( aCharClass.isDigit( *p )
+ || ( *p == '.' && aCharClass.isDigit( *( p+1 ) ) )
+ || *p == '-'
+ || *p == '&' ) )
+ {
+ // Eine Zahl kann direkt eingescant werden!
+ USHORT nLen;
+ if( !refVar->Scan( XubString( p ), &nLen ) )
+ refVar.Clear();
+ else
+ p += nLen;
+ }
+ else if( !bVar && *p == '"' )
+ {
+ // Ein String
+ XubString aString;
+ p++;
+ for( ;; )
+ {
+ // Das ist wohl ein Fehler
+ if( !*p )
+ return NULL;
+ // Doppelte Quotes sind OK
+ if( *p == '"' )
+ if( *++p != '"' )
+ break;
+ aString += *p++;
+ }
+ refVar->PutString( aString );
+ }
+ else
+ refVar = QualifiedName( pObj, pGbl, &p, SbxCLASS_DONTCARE );
+ *ppBuf = p;
+ if( refVar.Is() )
+ refVar->AddRef();
+ return refVar;
+}
+
+// Einlesen einer einfachen Term. Die Operatoren +, -, * und /
+// werden unterstuetzt.
+
+static SbxVariable* MulDiv( SbxObject* pObj, SbxObject* pGbl, const xub_Unicode** ppBuf )
+{
+ const xub_Unicode* p = *ppBuf;
+ SbxVariableRef refVar( Operand( pObj, pGbl, &p, FALSE ) );
+ p = SkipWhitespace( p );
+ while( refVar.Is() && ( *p == '*' || *p == '/' ) )
+ {
+ xub_Unicode cOp = *p++;
+ SbxVariableRef refVar2( Operand( pObj, pGbl, &p, FALSE ) );
+ if( refVar2.Is() )
+ {
+ // temporaere Variable!
+ SbxVariable* pVar = refVar;
+ pVar = new SbxVariable( *pVar );
+ refVar = pVar;
+ if( cOp == '*' )
+ *refVar *= *refVar2;
+ else
+ *refVar /= *refVar2;
+ }
+ else
+ {
+ refVar.Clear();
+ break;
+ }
+ }
+ *ppBuf = p;
+ if( refVar.Is() )
+ refVar->AddRef();
+ return refVar;
+}
+
+static SbxVariable* PlusMinus( SbxObject* pObj, SbxObject* pGbl, const xub_Unicode** ppBuf )
+{
+ const xub_Unicode* p = *ppBuf;
+ SbxVariableRef refVar( MulDiv( pObj, pGbl, &p ) );
+ p = SkipWhitespace( p );
+ while( refVar.Is() && ( *p == '+' || *p == '-' ) )
+ {
+ xub_Unicode cOp = *p++;
+ SbxVariableRef refVar2( MulDiv( pObj, pGbl, &p ) );
+ if( refVar2.Is() )
+ {
+ // temporaere Variable!
+ SbxVariable* pVar = refVar;
+ pVar = new SbxVariable( *pVar );
+ refVar = pVar;
+ if( cOp == '+' )
+ *refVar += *refVar2;
+ else
+ *refVar -= *refVar2;
+ }
+ else
+ {
+ refVar.Clear();
+ break;
+ }
+ }
+ *ppBuf = p;
+ if( refVar.Is() )
+ refVar->AddRef();
+ return refVar;
+}
+
+/*?*/ // static SbxVariable* Assign( SbxObject* pObj, SbxObject* pGbl, const xub_Unicode** ppBuf )
+/*?*/ // {
+/*?*/ // const xub_Unicode* p = *ppBuf;
+/*?*/ // SbxVariableRef refVar( Operand( pObj, pGbl, &p, TRUE ) );
+/*?*/ // p = SkipWhitespace( p );
+/*?*/ // if( refVar.Is() )
+/*?*/ // {
+/*?*/ // if( *p == '=' )
+/*?*/ // {
+/*?*/ // // Nur auf Props zuweisen!
+/*?*/ // if( refVar->GetClass() != SbxCLASS_PROPERTY )
+/*?*/ // {
+/*?*/ // SbxBase::SetError( SbxERR_BAD_ACTION );
+/*?*/ // refVar.Clear();
+/*?*/ // }
+/*?*/ // else
+/*?*/ // {
+/*?*/ // p++;
+/*?*/ // SbxVariableRef refVar2( PlusMinus( pObj, pGbl, &p ) );
+/*?*/ // if( refVar2.Is() )
+/*?*/ // {
+/*?*/ // SbxVariable* pVar = refVar;
+/*?*/ // SbxVariable* pVar2 = refVar2;
+/*?*/ // *pVar = *pVar2;
+/*?*/ // pVar->SetParameters( NULL );
+/*?*/ // }
+/*?*/ // }
+/*?*/ // }
+/*?*/ // else
+/*?*/ // // Einfacher Aufruf: einmal aktivieren
+/*?*/ // refVar->Broadcast( SBX_HINT_DATAWANTED );
+/*?*/ // }
+/*?*/ // *ppBuf = p;
+/*?*/ // if( refVar.Is() )
+/*?*/ // refVar->AddRef();
+/*?*/ // return refVar;
+/*?*/ // }
+/*?*/ //
+/*?*/ // // Einlesen eines Elements. Dies ist ein Symbol, optional gefolgt
+/*?*/ // // von einer Parameterliste. Das Symbol wird im angegebenen Objekt
+/*?*/ // // gesucht und die Parameterliste wird ggf. angefuegt.
+
+static SbxVariable* Element
+ ( SbxObject* pObj, SbxObject* pGbl, const xub_Unicode** ppBuf,
+ SbxClassType t, const SbxSimpleCharClass& rCharClass )
+{
+ XubString aSym;
+ const xub_Unicode* p = Symbol( *ppBuf, aSym, rCharClass );
+ SbxVariableRef refVar;
+ if( aSym.Len() )
+ {
+ USHORT nOld = pObj->GetFlags();
+ if( pObj == pGbl )
+ pObj->SetFlag( SBX_GBLSEARCH );
+ refVar = pObj->Find( aSym, t );
+ pObj->SetFlags( nOld );
+ if( refVar.Is() )
+ {
+ refVar->SetParameters( NULL );
+ // folgen noch Parameter?
+ p = SkipWhitespace( p );
+ if( *p == '(' )
+ {
+ p++;
+ SbxArrayRef refPar = new SbxArray;
+ USHORT nArg = 0;
+ // Wird sind mal relaxed und akzeptieren auch
+ // das Zeilen- oder Komandoende als Begrenzer
+ // Parameter immer global suchen!
+ while( *p && *p != ')' && *p != ']' )
+ {
+ SbxVariableRef refArg = PlusMinus( pGbl, pGbl, &p );
+ if( !refArg )
+ {
+ // Fehler beim Parsing
+ refVar.Clear(); break;
+ }
+ else
+ {
+ // Man kopiere den Parameter, damit
+ // man den aktuellen Zustand hat (loest auch
+ // den Aufruf per Zugriff aus)
+ SbxVariable* pArg = refArg;
+ refPar->Put( new SbxVariable( *pArg ), ++nArg );
+ }
+ p = SkipWhitespace( p );
+ if( *p == ',' )
+ p++;
+ }
+ if( *p == ')' )
+ p++;
+ if( refVar.Is() )
+ refVar->SetParameters( refPar );
+ }
+ }
+ else
+ SbxBase::SetError( SbxERR_NO_METHOD );
+ }
+ *ppBuf = p;
+ if( refVar.Is() )
+ refVar->AddRef();
+ return refVar;
+}
+
+/*?*/ // // Hauptroutine
+/*?*/ //
+/*?*/ // SbxVariable* SbxObject::Execute( const XubString& rTxt )
+/*?*/ // {
+/*?*/ // SbxVariable* pVar = NULL;
+/*?*/ // const xub_Unicode* p = rTxt.GetBuffer();
+/*?*/ // for( ;; )
+/*?*/ // {
+/*?*/ // p = SkipWhitespace( p );
+/*?*/ // if( !*p )
+/*?*/ // break;
+/*?*/ // if( *p++ != '[' )
+/*?*/ // {
+/*?*/ // SetError( SbxERR_SYNTAX ); break;
+/*?*/ // }
+/*?*/ // pVar = Assign( this, this, &p );
+/*?*/ // if( !pVar )
+/*?*/ // break;
+/*?*/ // p = SkipWhitespace( p );
+/*?*/ // if( *p++ != ']' )
+/*?*/ // {
+/*?*/ // SetError( SbxERR_SYNTAX ); break;
+/*?*/ // }
+/*?*/ // }
+/*?*/ // return pVar;
+/*?*/ // }
+/*?*/ //
+SbxVariable* SbxObject::FindQualified( const XubString& rName, SbxClassType t )
+{
+ SbxVariable* pVar = NULL;
+ const xub_Unicode* p = rName.GetBuffer();
+ p = SkipWhitespace( p );
+ if( !*p )
+ return NULL;;
+ pVar = QualifiedName( this, this, &p, t );
+ p = SkipWhitespace( p );
+ if( *p )
+ SetError( SbxERR_SYNTAX );
+ return pVar;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/sbx/sbxint.cxx b/binfilter/bf_basic/source/sbx/sbxint.cxx
new file mode 100644
index 000000000000..f358bd4b0f2b
--- /dev/null
+++ b/binfilter/bf_basic/source/sbx/sbxint.cxx
@@ -0,0 +1,970 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <tools/errcode.hxx>
+#include "sbx.hxx"
+#include "sbxconv.hxx"
+
+namespace binfilter {
+
+double ImpRound( double d )
+{
+ return d + ( d < 0 ? -0.5 : 0.5 );
+}
+
+INT16 ImpGetInteger( const SbxValues* p )
+{
+ SbxValues aTmp;
+ INT16 nRes;
+start:
+ switch( +p->eType )
+ {
+ case SbxNULL:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ case SbxEMPTY:
+ nRes = 0; break;
+ case SbxCHAR:
+ nRes = p->nChar; break;
+ case SbxBYTE:
+ nRes = p->nByte; break;
+ case SbxINTEGER:
+ case SbxBOOL:
+ nRes = p->nInteger; break;
+ case SbxERROR:
+ case SbxUSHORT:
+ if( p->nUShort > (USHORT) SbxMAXINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXINT;
+ }
+ else
+ nRes = (INT16) p->nUShort;
+ break;
+ case SbxLONG:
+ if( p->nLong > SbxMAXINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXINT;
+ }
+ else if( p->nLong < SbxMININT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMININT;
+ }
+ else
+ nRes = (INT16) p->nLong;
+ break;
+ case SbxULONG:
+ if( p->nULong > SbxMAXINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXINT;
+ }
+ else
+ nRes = (INT16) p->nULong;
+ break;
+ case SbxSINGLE:
+ if( p->nSingle > SbxMAXINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXINT;
+ }
+ else if( p->nSingle < SbxMININT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMININT;
+ }
+ else
+ nRes = (INT16) ImpRound( p->nSingle );
+ break;
+ case SbxSALINT64:
+ if( p->nInt64 > SbxMAXINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXINT;
+ }
+ else if( p->nInt64 < SbxMININT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMININT;
+ }
+ else
+ nRes = (INT16) p->nInt64;
+ break;
+ case SbxSALUINT64:
+ if( p->uInt64 > SbxMAXINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXINT;
+ }
+ else
+ nRes = (INT16) p->uInt64;
+ break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ case SbxLONG64:
+ case SbxULONG64:
+ case SbxCURRENCY:
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ {
+ double dVal;
+ if( p->eType == SbxCURRENCY )
+ dVal = ImpCurrencyToDouble( p->nLong64 );
+ else if( p->eType == SbxLONG64 )
+ dVal = ImpINT64ToDouble( p->nLong64 );
+ else if( p->eType == SbxULONG64 )
+ dVal = ImpUINT64ToDouble( p->nULong64 );
+ else if( p->eType == SbxDECIMAL )
+ {
+ dVal = 0.0;
+ if( p->pDecimal )
+ p->pDecimal->getDouble( dVal );
+ }
+ else
+ dVal = p->nDouble;
+
+ if( dVal > SbxMAXINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXINT;
+ }
+ else if( dVal < SbxMININT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMININT;
+ }
+ else
+ nRes = (INT16) ImpRound( dVal );
+ break;
+ }
+ case SbxLPSTR:
+ case SbxSTRING:
+ case SbxBYREF | SbxSTRING:
+ if( !p->pString )
+ nRes = 0;
+ else
+ {
+ double d;
+ SbxDataType t;
+ if( ImpScan( *p->pString, d, t, NULL ) != SbxERR_OK )
+ nRes = 0;
+ else if( d > SbxMAXINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXINT;
+ }
+ else if( d < SbxMININT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMININT;
+ }
+ else
+ nRes = (INT16) ImpRound( d );
+ }
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ nRes = pVal->GetInteger();
+ else
+ {
+ SbxBase::SetError( SbxERR_NO_OBJECT ); nRes = 0;
+ }
+ break;
+ }
+
+ case SbxBYREF | SbxCHAR:
+ nRes = *p->pChar; break;
+ case SbxBYREF | SbxBYTE:
+ nRes = *p->pByte; break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ nRes = *p->pInteger; break;
+
+ // ab hier muss getestet werden
+ case SbxBYREF | SbxLONG:
+ aTmp.nLong = *p->pLong; goto ref;
+ case SbxBYREF | SbxULONG:
+ aTmp.nULong = *p->pULong; goto ref;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ aTmp.nUShort = *p->pUShort; goto ref;
+ case SbxBYREF | SbxSINGLE:
+ aTmp.nSingle = *p->pSingle; goto ref;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ aTmp.nDouble = *p->pDouble; goto ref;
+ case SbxBYREF | SbxULONG64:
+ aTmp.nULong64 = *p->pULong64; goto ref;
+ case SbxBYREF | SbxLONG64:
+ case SbxBYREF | SbxCURRENCY:
+ aTmp.nLong64 = *p->pLong64; goto ref;
+ case SbxBYREF | SbxSALINT64:
+ aTmp.nInt64 = *p->pnInt64; goto ref;
+ case SbxBYREF | SbxSALUINT64:
+ aTmp.uInt64 = *p->puInt64; goto ref;
+ ref:
+ aTmp.eType = SbxDataType( p->eType & 0x0FFF );
+ p = &aTmp; goto start;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
+ }
+ return nRes;
+}
+
+void ImpPutInteger( SbxValues* p, INT16 n )
+{
+ SbxValues aTmp;
+start:
+ switch( +p->eType )
+ {
+ // hier muss getestet werden
+ case SbxCHAR:
+ aTmp.pChar = &p->nChar; goto direct;
+ case SbxBYTE:
+ aTmp.pByte = &p->nByte; goto direct;
+ case SbxULONG:
+ aTmp.pULong = &p->nULong; goto direct;
+ case SbxERROR:
+ case SbxUSHORT:
+ aTmp.pUShort = &p->nUShort; goto direct;
+ case SbxSALUINT64:
+ aTmp.puInt64 = &p->uInt64; goto direct;
+ direct:
+ aTmp.eType = SbxDataType( p->eType | SbxBYREF );
+ p = &aTmp; goto start;
+
+ // ab hier nicht mehr
+ case SbxINTEGER:
+ case SbxBOOL:
+ p->nInteger = n; break;
+ case SbxLONG:
+ p->nLong = n; break;
+ case SbxSINGLE:
+ p->nSingle = n; break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ p->nDouble = n; break;
+ case SbxSALINT64:
+ p->nInt64 = n; break;
+ case SbxULONG64:
+ p->nULong64 = ImpDoubleToUINT64( (double)n ); break;
+ case SbxLONG64:
+ p->nLong64 = ImpDoubleToINT64( (double)n ); break;
+ case SbxCURRENCY:
+ p->nLong64 = ImpDoubleToCurrency( (double)n ); break;
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ ImpCreateDecimal( p )->setInt( n );
+ break;
+
+ case SbxLPSTR:
+ case SbxSTRING:
+ case SbxBYREF | SbxSTRING:
+ if( !p->pString )
+ p->pString = new XubString;
+ ImpCvtNum( (double) n, 0, *p->pString );
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ pVal->PutInteger( n );
+ else
+ SbxBase::SetError( SbxERR_NO_OBJECT );
+ break;
+ }
+ case SbxBYREF | SbxCHAR:
+ if( n < SbxMINCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINCHAR;
+ }
+ *p->pChar = (char) n; break;
+ case SbxBYREF | SbxBYTE:
+ if( n > SbxMAXBYTE )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXBYTE;
+ }
+ else if( n < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
+ }
+ *p->pByte = (BYTE) n; break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ *p->pInteger = n; break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ if( n < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
+ }
+ *p->pUShort = (UINT16) n; break;
+ case SbxBYREF | SbxLONG:
+ *p->pLong = (INT32) n; break;
+ case SbxBYREF | SbxULONG:
+ if( n < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
+ }
+ *p->pULong = (UINT32) n; break;
+ case SbxBYREF | SbxSALINT64:
+ *p->pnInt64 = n; break;
+ case SbxBYREF | SbxSALUINT64:
+ if( n < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); *p->puInt64 = 0;
+ }
+ else
+ *p->puInt64 = n;
+ break;
+ case SbxBYREF | SbxSINGLE:
+ *p->pSingle = (float) n; break;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ *p->pDouble = (double) n; break;
+ case SbxBYREF | SbxULONG64:
+ *p->pULong64 = ImpDoubleToUINT64( (double)n ); break;
+ case SbxBYREF | SbxLONG64:
+ *p->pLong64 = ImpDoubleToINT64( (double)n ); break;
+ case SbxBYREF | SbxCURRENCY:
+ *p->pLong64 = ImpDoubleToCurrency( (double)n ); break;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ }
+}
+
+
+// sal_Int64 / hyper
+
+sal_Int64 ImpDoubleToSalInt64( double d )
+{
+ sal_Int64 nRes;
+ if( d > SbxMAXSALINT64 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXSALINT64;
+ }
+ else if( d < SbxMINSALINT64 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMINSALINT64;
+ }
+ else
+ nRes = (sal_Int64) ImpRound( d );
+ return nRes;
+}
+
+sal_uInt64 ImpDoubleToSalUInt64( double d )
+{
+ sal_uInt64 nRes;
+ if( d > SbxMAXSALUINT64 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXSALUINT64;
+ }
+ else if( d < 0.0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
+ }
+ else
+ nRes = (sal_uInt64) ImpRound( d );
+ return nRes;
+}
+
+double ImpSalUInt64ToDouble( sal_uInt64 n )
+{
+ double d = 0.0;
+ if( n > SbxMAXSALINT64 )
+ SbxBase::SetError( SbxERR_CONVERSION );
+ else
+ d = (double)(sal_Int64) n;
+ return d;
+}
+
+
+sal_Int64 ImpGetInt64( const SbxValues* p )
+{
+ SbxValues aTmp;
+ sal_Int64 nRes;
+start:
+ switch( +p->eType )
+ {
+ case SbxNULL:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ case SbxEMPTY:
+ nRes = 0; break;
+ case SbxCHAR:
+ nRes = p->nChar; break;
+ case SbxBYTE:
+ nRes = p->nByte; break;
+ case SbxINTEGER:
+ case SbxBOOL:
+ nRes = p->nInteger; break;
+ case SbxERROR:
+ case SbxUSHORT:
+ nRes = p->nUShort; break;
+ case SbxLONG:
+ nRes = p->nLong; break;
+ case SbxULONG:
+ nRes = (sal_Int64) p->nULong; break;
+ case SbxSINGLE:
+ nRes = ImpDoubleToSalInt64( (double)p->nSingle );
+ break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ case SbxLONG64:
+ case SbxULONG64:
+ case SbxCURRENCY:
+ {
+ double dVal;
+ if( p->eType == SbxCURRENCY )
+ dVal = ImpCurrencyToDouble( p->nLong64 );
+ else if( p->eType == SbxLONG64 )
+ dVal = ImpINT64ToDouble( p->nLong64 );
+ else if( p->eType == SbxULONG64 )
+ dVal = ImpUINT64ToDouble( p->nULong64 );
+ else
+ dVal = p->nDouble;
+
+ nRes = ImpDoubleToSalInt64( dVal );
+ break;
+ }
+ case SbxSALINT64:
+ nRes = p->nInt64; break;
+ case SbxSALUINT64:
+ if( p->uInt64 > SbxMAXSALINT64 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXSALINT64;
+ }
+ else
+ nRes = (sal_Int64) p->uInt64;
+ break;
+
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ if( !p->pString )
+ nRes = 0;
+ else
+ {
+ ::rtl::OUString aOUStr( *p->pString );
+ ::rtl::OString aOStr = ::rtl::OUStringToOString
+ ( aOUStr, RTL_TEXTENCODING_ASCII_US );
+ nRes = aOStr.toInt64();
+ if( nRes == 0 )
+ {
+ // Check if really 0 or invalid conversion
+ double d;
+ SbxDataType t;
+ if( ImpScan( *p->pString, d, t, NULL ) != SbxERR_OK )
+ nRes = 0;
+ else
+ nRes = ImpDoubleToSalInt64( d );
+ }
+ }
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ nRes = pVal->GetInt64();
+ else
+ {
+ SbxBase::SetError( SbxERR_NO_OBJECT ); nRes = 0;
+ }
+ break;
+ }
+
+ case SbxBYREF | SbxCHAR:
+ nRes = *p->pChar; break;
+ case SbxBYREF | SbxBYTE:
+ nRes = *p->pByte; break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ nRes = *p->pInteger; break;
+ case SbxBYREF | SbxLONG:
+ nRes = *p->pLong; break;
+ case SbxBYREF | SbxULONG:
+ nRes = *p->pULong; break;
+ case SbxBYREF | SbxSALINT64:
+ nRes = *p->pnInt64; break;
+
+ // from here the values has to be checked
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ aTmp.nUShort = *p->pUShort; goto ref;
+ case SbxBYREF | SbxSINGLE:
+ aTmp.nSingle = *p->pSingle; goto ref;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ aTmp.nDouble = *p->pDouble; goto ref;
+ case SbxBYREF | SbxULONG64:
+ aTmp.nULong64 = *p->pULong64; goto ref;
+ case SbxBYREF | SbxLONG64:
+ case SbxBYREF | SbxCURRENCY:
+ aTmp.nLong64 = *p->pLong64; goto ref;
+ case SbxBYREF | SbxSALUINT64:
+ aTmp.uInt64 = *p->puInt64; goto ref;
+ ref:
+ aTmp.eType = SbxDataType( p->eType & 0x0FFF );
+ p = &aTmp; goto start;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
+ }
+ return nRes;
+}
+
+void ImpPutInt64( SbxValues* p, sal_Int64 n )
+{
+ SbxValues aTmp;
+
+start:
+ switch( +p->eType )
+ {
+ // Check neccessary
+ case SbxCHAR:
+ aTmp.pChar = &p->nChar; goto direct;
+ case SbxBYTE:
+ aTmp.pByte = &p->nByte; goto direct;
+ case SbxINTEGER:
+ case SbxBOOL:
+ aTmp.pInteger = &p->nInteger; goto direct;
+ case SbxULONG64:
+ aTmp.pULong64 = &p->nULong64; goto direct;
+ case SbxLONG64:
+ case SbxCURRENCY:
+ aTmp.pLong64 = &p->nLong64; goto direct;
+ case SbxULONG:
+ aTmp.pULong = &p->nULong; goto direct;
+ case SbxERROR:
+ case SbxUSHORT:
+ aTmp.pUShort = &p->nUShort; goto direct;
+ case SbxLONG:
+ aTmp.pnInt64 = &p->nInt64; goto direct;
+ case SbxSALUINT64:
+ aTmp.puInt64 = &p->uInt64; goto direct;
+
+ direct:
+ aTmp.eType = SbxDataType( p->eType | SbxBYREF );
+ p = &aTmp; goto start;
+
+ // Check not neccessary
+ case SbxSALINT64:
+ p->nInt64 = n; break;
+ case SbxSINGLE:
+ p->nSingle = (float) n; break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ p->nDouble = (double) n; break;
+
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ {
+ if( !p->pString )
+ p->pString = new XubString;
+
+ ::rtl::OString aOStr = ::rtl::OString::valueOf( n );
+ ::rtl::OUString aOUStr = ::rtl::OStringToOUString
+ ( aOStr, RTL_TEXTENCODING_ASCII_US );
+ (*p->pString) = aOUStr;
+ break;
+ }
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ pVal->PutInt64( n );
+ else
+ SbxBase::SetError( SbxERR_NO_OBJECT );
+ break;
+ }
+ case SbxBYREF | SbxCHAR:
+ if( n > SbxMAXCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXCHAR;
+ }
+ else if( n < SbxMINCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINCHAR;
+ }
+ *p->pChar = (xub_Unicode) n; break;
+ case SbxBYREF | SbxBYTE:
+ if( n > SbxMAXBYTE )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXBYTE;
+ }
+ else if( n < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
+ }
+ *p->pByte = (BYTE) n; break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ if( n > SbxMAXINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXINT;
+ }
+ else if( n < SbxMININT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMININT;
+ }
+ *p->pInteger = (INT16) n; break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ if( n > SbxMAXUINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXUINT;
+ }
+ else if( n < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
+ }
+ *p->pUShort = (UINT16) n; break;
+ case SbxBYREF | SbxLONG:
+ if( n > SbxMAXLNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXLNG;
+ }
+ else if( n < SbxMINLNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINLNG;
+ }
+ *p->pLong = (INT32) n; break;
+ case SbxBYREF | SbxULONG:
+ if( n > SbxMAXULNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXULNG;
+ }
+ else if( n < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
+ }
+ *p->pULong = (UINT32) n; break;
+ case SbxBYREF | SbxSINGLE:
+ *p->pSingle = (float) n; break;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ *p->pDouble = (double) n; break;
+ case SbxBYREF | SbxCURRENCY:
+ if( n > SbxMAXCURR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = (sal_Int64) SbxMAXCURR;
+ }
+ else if( n < SbxMINCURR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = (sal_Int64) SbxMINCURR;
+ }
+ *p->pLong64 = ImpDoubleToCurrency( (double)n ); break;
+
+ case SbxBYREF | SbxSALINT64:
+ *p->pnInt64 = n; break;
+ case SbxBYREF | SbxSALUINT64:
+ if( n < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
+ }
+ *p->puInt64 = (sal_Int64) n; break;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ }
+}
+
+sal_uInt64 ImpGetUInt64( const SbxValues* p )
+{
+ SbxValues aTmp;
+ sal_uInt64 nRes;
+start:
+ switch( +p->eType )
+ {
+ case SbxNULL:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ case SbxEMPTY:
+ nRes = 0; break;
+ case SbxCHAR:
+ nRes = p->nChar; break;
+ case SbxBYTE:
+ nRes = p->nByte; break;
+ case SbxINTEGER:
+ case SbxBOOL:
+ nRes = p->nInteger; break;
+ case SbxERROR:
+ case SbxUSHORT:
+ nRes = p->nUShort; break;
+ case SbxLONG:
+ nRes = p->nLong; break;
+ case SbxULONG:
+ nRes = (sal_uInt64) p->nULong; break;
+ case SbxSINGLE:
+ nRes = ImpDoubleToSalUInt64( (double)p->nSingle );
+ break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ case SbxLONG64:
+ case SbxULONG64:
+ case SbxCURRENCY:
+ {
+ double dVal;
+ if( p->eType == SbxCURRENCY )
+ dVal = ImpCurrencyToDouble( p->nLong64 );
+ else if( p->eType == SbxLONG64 )
+ dVal = ImpINT64ToDouble( p->nLong64 );
+ else if( p->eType == SbxULONG64 )
+ dVal = ImpUINT64ToDouble( p->nULong64 );
+ else
+ dVal = p->nDouble;
+
+ nRes = ImpDoubleToSalUInt64( dVal );
+ break;
+ }
+ case SbxSALINT64:
+ if( p->nInt64 < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
+ }
+ else
+ nRes = (sal_uInt64) p->nInt64;
+ case SbxSALUINT64:
+ nRes = p->uInt64; break;
+
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ if( !p->pString )
+ nRes = 0;
+ else
+ {
+ ::rtl::OUString aOUStr( *p->pString );
+ ::rtl::OString aOStr = ::rtl::OUStringToOString
+ ( aOUStr, RTL_TEXTENCODING_ASCII_US );
+ sal_Int64 n64 = aOStr.toInt64();
+ if( n64 == 0 )
+ {
+ // Check if really 0 or invalid conversion
+ double d;
+ SbxDataType t;
+ if( ImpScan( *p->pString, d, t, NULL ) != SbxERR_OK )
+ nRes = 0;
+ else if( d > SbxMAXSALUINT64 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXSALUINT64;
+ }
+ else if( d < 0.0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
+ }
+ else
+ nRes = (sal_uInt64) ImpRound( d );
+ }
+ else if( n64 < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
+ }
+ else
+ {
+ nRes = n64;
+ }
+ }
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ nRes = pVal->GetUInt64();
+ else
+ {
+ SbxBase::SetError( SbxERR_NO_OBJECT ); nRes = 0;
+ }
+ break;
+ }
+
+ case SbxBYREF | SbxCHAR:
+ nRes = *p->pChar; break;
+ case SbxBYREF | SbxBYTE:
+ nRes = *p->pByte; break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ nRes = *p->pInteger; break;
+ case SbxBYREF | SbxLONG:
+ nRes = *p->pLong; break;
+ case SbxBYREF | SbxULONG:
+ nRes = *p->pULong; break;
+ case SbxBYREF | SbxSALUINT64:
+ nRes = *p->puInt64; break;
+
+ // from here the values has to be checked
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ aTmp.nUShort = *p->pUShort; goto ref;
+ case SbxBYREF | SbxSINGLE:
+ aTmp.nSingle = *p->pSingle; goto ref;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ aTmp.nDouble = *p->pDouble; goto ref;
+ case SbxBYREF | SbxULONG64:
+ aTmp.nULong64 = *p->pULong64; goto ref;
+ case SbxBYREF | SbxLONG64:
+ case SbxBYREF | SbxCURRENCY:
+ aTmp.nLong64 = *p->pLong64; goto ref;
+ case SbxBYREF | SbxSALINT64:
+ aTmp.nInt64 = *p->pnInt64; goto ref;
+ ref:
+ aTmp.eType = SbxDataType( p->eType & 0x0FFF );
+ p = &aTmp; goto start;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
+ }
+ return nRes;
+}
+
+void ImpPutUInt64( SbxValues* p, sal_uInt64 n )
+{
+ SbxValues aTmp;
+
+start:
+ switch( +p->eType )
+ {
+ // Check neccessary
+ case SbxCHAR:
+ aTmp.pChar = &p->nChar; goto direct;
+ case SbxBYTE:
+ aTmp.pByte = &p->nByte; goto direct;
+ case SbxINTEGER:
+ case SbxBOOL:
+ aTmp.pInteger = &p->nInteger; goto direct;
+ case SbxULONG64:
+ aTmp.pULong64 = &p->nULong64; goto direct;
+ case SbxLONG64:
+ case SbxCURRENCY:
+ aTmp.pLong64 = &p->nLong64; goto direct;
+ case SbxULONG:
+ aTmp.pULong = &p->nULong; goto direct;
+ case SbxERROR:
+ case SbxUSHORT:
+ aTmp.pUShort = &p->nUShort; goto direct;
+ case SbxLONG:
+ aTmp.pnInt64 = &p->nInt64; goto direct;
+ case SbxSALINT64:
+ aTmp.pnInt64 = &p->nInt64; goto direct;
+ case SbxSINGLE:
+ aTmp.pSingle = &p->nSingle; goto direct;
+ case SbxDATE:
+ case SbxDOUBLE:
+ aTmp.pDouble = &p->nDouble; goto direct;
+
+ direct:
+ aTmp.eType = SbxDataType( p->eType | SbxBYREF );
+ p = &aTmp; goto start;
+
+ // Check not neccessary
+ case SbxSALUINT64:
+ p->uInt64 = n; break;
+
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ if( !p->pString )
+ p->pString = new XubString;
+ if( n > SbxMAXSALINT64 )
+ SbxBase::SetError( SbxERR_CONVERSION );
+ else
+ {
+ ::rtl::OString aOStr = ::rtl::OString::valueOf( (sal_Int64)n );
+ ::rtl::OUString aOUStr = ::rtl::OStringToOUString
+ ( aOStr, RTL_TEXTENCODING_ASCII_US );
+ (*p->pString) = aOUStr;
+ }
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ pVal->PutUInt64( n );
+ else
+ SbxBase::SetError( SbxERR_NO_OBJECT );
+ break;
+ }
+ case SbxBYREF | SbxCHAR:
+ if( n > SbxMAXCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXCHAR;
+ }
+ *p->pChar = (xub_Unicode) n; break;
+ case SbxBYREF | SbxBYTE:
+ if( n > SbxMAXBYTE )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXBYTE;
+ }
+ *p->pByte = (BYTE) n; break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ if( n > SbxMAXINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXINT;
+ }
+ *p->pInteger = (INT16) n; break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ if( n > SbxMAXUINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXUINT;
+ }
+ *p->pUShort = (UINT16) n; break;
+ case SbxBYREF | SbxLONG:
+ if( n > SbxMAXLNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXLNG;
+ }
+ *p->pLong = (INT32) n; break;
+ case SbxBYREF | SbxULONG:
+ if( n > SbxMAXULNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXULNG;
+ }
+ *p->pULong = (UINT32) n; break;
+ case SbxBYREF | SbxSINGLE:
+ *p->pDouble = (float)ImpSalUInt64ToDouble( n ); break;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ *p->pDouble = ImpSalUInt64ToDouble( n ); break;
+ case SbxBYREF | SbxCURRENCY:
+ if( n > SbxMAXSALINT64 || (sal_Int64)n > SbxMAXCURR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = (sal_Int64) SbxMAXCURR;
+ }
+ *p->pLong64 = ImpDoubleToCurrency( (double)(sal_Int64) n ); break;
+
+ case SbxBYREF | SbxSALUINT64:
+ *p->puInt64 = n; break;
+ case SbxBYREF | SbxSALINT64:
+ if( n > SbxMAXSALINT64 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
+ }
+ *p->pnInt64 = (sal_Int64) n; break;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/sbx/sbxlng.cxx b/binfilter/bf_basic/source/sbx/sbxlng.cxx
new file mode 100644
index 000000000000..566eb1e68e70
--- /dev/null
+++ b/binfilter/bf_basic/source/sbx/sbxlng.cxx
@@ -0,0 +1,345 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <tools/errcode.hxx>
+#include "sbx.hxx"
+#include "sbxconv.hxx"
+
+namespace binfilter {
+
+INT32 ImpGetLong( const SbxValues* p )
+{
+ SbxValues aTmp;
+ INT32 nRes;
+start:
+ switch( +p->eType )
+ {
+ case SbxNULL:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ case SbxEMPTY:
+ nRes = 0; break;
+ case SbxCHAR:
+ nRes = p->nChar; break;
+ case SbxBYTE:
+ nRes = p->nByte; break;
+ case SbxINTEGER:
+ case SbxBOOL:
+ nRes = p->nInteger; break;
+ case SbxERROR:
+ case SbxUSHORT:
+ nRes = p->nUShort; break;
+ case SbxLONG:
+ nRes = p->nLong; break;
+ case SbxULONG:
+ if( p->nULong > SbxMAXLNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXLNG;
+ }
+ else
+ nRes = (INT32) p->nULong;
+ break;
+ case SbxSINGLE:
+ if( p->nSingle > SbxMAXLNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXLNG;
+ }
+ else if( p->nSingle < SbxMINLNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMINLNG;
+ }
+ else
+ nRes = (INT32) ImpRound( p->nSingle );
+ break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ case SbxLONG64:
+ case SbxULONG64:
+ case SbxSALINT64:
+ case SbxSALUINT64:
+ case SbxCURRENCY:
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ {
+ double dVal;
+ if( p->eType == SbxCURRENCY )
+ dVal = ImpCurrencyToDouble( p->nLong64 );
+ else if( p->eType == SbxLONG64 )
+ dVal = ImpINT64ToDouble( p->nLong64 );
+ else if( p->eType == SbxULONG64 )
+ dVal = ImpUINT64ToDouble( p->nULong64 );
+ else if( p->eType == SbxSALINT64 )
+ dVal = static_cast< double >(p->nInt64);
+ else if( p->eType == SbxSALUINT64 )
+ dVal = ImpSalUInt64ToDouble( p->uInt64 );
+ else if( p->eType == SbxDECIMAL )
+ {
+ dVal = 0.0;
+ if( p->pDecimal )
+ p->pDecimal->getDouble( dVal );
+ }
+ else
+ dVal = p->nDouble;
+
+ if( dVal > SbxMAXLNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXLNG;
+ }
+ else if( dVal < SbxMINLNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMINLNG;
+ }
+ else
+ nRes = (INT32) ImpRound( dVal );
+ break;
+ }
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ if( !p->pString )
+ nRes = 0;
+ else
+ {
+ double d;
+ SbxDataType t;
+ if( ImpScan( *p->pString, d, t, NULL ) != SbxERR_OK )
+ nRes = 0;
+ else if( d > SbxMAXLNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXLNG;
+ }
+ else if( d < SbxMINLNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMINLNG;
+ }
+ else
+ nRes = (INT32) ImpRound( d );
+ }
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ nRes = pVal->GetLong();
+ else
+ {
+ SbxBase::SetError( SbxERR_NO_OBJECT ); nRes = 0;
+ }
+ break;
+ }
+
+ case SbxBYREF | SbxCHAR:
+ nRes = *p->pChar; break;
+ case SbxBYREF | SbxBYTE:
+ nRes = *p->pByte; break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ nRes = *p->pInteger; break;
+ case SbxBYREF | SbxLONG:
+ nRes = *p->pLong; break;
+
+ // ab hier muss getestet werden
+ case SbxBYREF | SbxULONG:
+ aTmp.nULong = *p->pULong; goto ref;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ aTmp.nUShort = *p->pUShort; goto ref;
+ case SbxBYREF | SbxSINGLE:
+ aTmp.nSingle = *p->pSingle; goto ref;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ aTmp.nDouble = *p->pDouble; goto ref;
+ case SbxBYREF | SbxSALINT64:
+ aTmp.nInt64 = *p->pnInt64; goto ref;
+ case SbxBYREF | SbxSALUINT64:
+ aTmp.uInt64 = *p->puInt64; goto ref;
+ case SbxBYREF | SbxULONG64:
+ aTmp.nULong64 = *p->pULong64; goto ref;
+ case SbxBYREF | SbxLONG64:
+ case SbxBYREF | SbxCURRENCY:
+ aTmp.nLong64 = *p->pLong64; goto ref;
+ ref:
+ aTmp.eType = SbxDataType( p->eType & 0x0FFF );
+ p = &aTmp; goto start;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
+ }
+ return nRes;
+}
+
+void ImpPutLong( SbxValues* p, INT32 n )
+{
+ SbxValues aTmp;
+
+start:
+ switch( +p->eType )
+ {
+ // Ab hier muss getestet werden
+ case SbxCHAR:
+ aTmp.pChar = &p->nChar; goto direct;
+ case SbxBYTE:
+ aTmp.pByte = &p->nByte; goto direct;
+ case SbxINTEGER:
+ case SbxBOOL:
+ aTmp.pInteger = &p->nInteger; goto direct;
+ case SbxULONG64:
+ aTmp.pULong64 = &p->nULong64; goto direct;
+ case SbxLONG64:
+ case SbxCURRENCY:
+ aTmp.pLong64 = &p->nLong64; goto direct;
+ case SbxULONG:
+ aTmp.pULong = &p->nULong; goto direct;
+ case SbxSALUINT64:
+ aTmp.puInt64 = &p->uInt64; goto direct;
+ case SbxERROR:
+ case SbxUSHORT:
+ aTmp.pUShort = &p->nUShort;
+ direct:
+ aTmp.eType = SbxDataType( p->eType | SbxBYREF );
+ p = &aTmp; goto start;
+
+ // ab hier nicht mehr
+ case SbxLONG:
+ p->nLong = n; break;
+ case SbxSINGLE:
+ p->nSingle = (float) n; break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ p->nDouble = n; break;
+ case SbxSALINT64:
+ p->nInt64 = n; break;
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ ImpCreateDecimal( p )->setLong( n );
+ break;
+
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ if( !p->pString )
+ p->pString = new XubString;
+ ImpCvtNum( (double) n, 0, *p->pString );
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ pVal->PutLong( n );
+ else
+ SbxBase::SetError( SbxERR_NO_OBJECT );
+ break;
+ }
+ case SbxBYREF | SbxCHAR:
+ if( n > SbxMAXCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXCHAR;
+ }
+ else if( n < SbxMINCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINCHAR;
+ }
+ *p->pChar = (xub_Unicode) n; break;
+ case SbxBYREF | SbxBYTE:
+ if( n > SbxMAXBYTE )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXBYTE;
+ }
+ else if( n < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
+ }
+ *p->pByte = (BYTE) n; break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ if( n > SbxMAXINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXINT;
+ }
+ else if( n < SbxMININT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMININT;
+ }
+ *p->pInteger = (INT16) n; break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ if( n > SbxMAXUINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXUINT;
+ }
+ else if( n < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
+ }
+ *p->pUShort = (UINT16) n; break;
+ case SbxBYREF | SbxLONG:
+ *p->pLong = n; break;
+ case SbxBYREF | SbxULONG:
+ if( n < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
+ }
+ *p->pULong = (UINT32) n; break;
+ case SbxBYREF | SbxSALINT64:
+ *p->pnInt64 = n; break;
+ case SbxBYREF | SbxSALUINT64:
+ if( n < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); *p->puInt64 = 0;
+ }
+ else
+ *p->puInt64 = n;
+ break;
+ case SbxBYREF | SbxSINGLE:
+ *p->pSingle = (float) n; break;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ *p->pDouble = (double) n; break;
+ case SbxBYREF | SbxCURRENCY:
+ double d;
+ if( n > SbxMAXCURR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); d = SbxMAXCURR;
+ }
+ else if( n < SbxMINCURR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); d = SbxMINCURR;
+ }
+ else
+ {
+ d = n;
+ }
+ *p->pLong64 = ImpDoubleToCurrency( d ); break;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/sbx/sbxobj.cxx b/binfilter/bf_basic/source/sbx/sbxobj.cxx
new file mode 100644
index 000000000000..45e6e34417d1
--- /dev/null
+++ b/binfilter/bf_basic/source/sbx/sbxobj.cxx
@@ -0,0 +1,926 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <tools/stream.hxx>
+#include <vcl/sound.hxx>
+#include "sbx.hxx"
+#include "sbxbase.hxx"
+#include "sbxres.hxx"
+
+#include <bf_svtools/brdcst.hxx>
+
+namespace binfilter {
+
+TYPEINIT1(SbxMethod,SbxVariable)
+TYPEINIT1(SbxProperty,SbxVariable)
+TYPEINIT2(SbxObject,SbxVariable,SfxListener)
+
+static const char* pNameProp; // Name-Property
+static const char* pParentProp; // Parent-Property
+
+static USHORT nNameHash = 0, nParentHash = 0;
+
+/////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////
+
+SbxObject::SbxObject( const XubString& rClass )
+ : SbxVariable( SbxOBJECT ), aClassName( rClass )
+{
+ aData.pObj = this;
+ if( !nNameHash )
+ {
+ pNameProp = GetSbxRes( STRING_NAMEPROP );
+ pParentProp = GetSbxRes( STRING_PARENTPROP );
+ nNameHash = MakeHashCode( String::CreateFromAscii( pNameProp ) );
+ nParentHash = MakeHashCode( String::CreateFromAscii( pParentProp ) );
+ }
+ SbxObject::Clear();
+ SbxObject::SetName( rClass );
+}
+
+SbxObject::SbxObject( const SbxObject& rObj )
+ : SvRefBase( rObj ), SbxVariable( rObj.GetType() ),
+ SfxListener( rObj )
+{
+ *this = rObj;
+}
+
+SbxObject& SbxObject::operator=( const SbxObject& r )
+{
+ if( &r != this )
+ {
+ SbxVariable::operator=( r );
+ aClassName = r.aClassName;
+ pMethods = new SbxArray;
+ pProps = new SbxArray;
+ pObjs = new SbxArray( SbxOBJECT );
+ // Die Arrays werden kopiert, die Inhalte uebernommen
+ *pMethods = *r.pMethods;
+ *pProps = *r.pProps;
+ *pObjs = *r.pObjs;
+ // Da die Variablen uebernommen wurden, ist dies OK
+ pDfltProp = r.pDfltProp;
+ SetName( r.GetName() );
+ SetFlags( r.GetFlags() );
+ SetModified( TRUE );
+ }
+ return *this;
+}
+
+static void CheckParentsOnDelete( SbxObject* pObj, SbxArray* p )
+{
+ for( USHORT i = 0; i < p->Count(); i++ )
+ {
+ SbxVariableRef& rRef = p->GetRef( i );
+ if( rRef->IsBroadcaster() )
+ pObj->EndListening( rRef->GetBroadcaster(), TRUE );
+ // Hat das Element mehr als eine Referenz und noch einen Listener?
+ if( rRef->GetRefCount() > 1 )
+ {
+ rRef->SetParent( NULL );
+ DBG_ASSERT( !rRef->IsBroadcaster() || rRef->GetBroadcaster().GetListenerCount(), "Object element with dangling parent" );
+ }
+ }
+}
+
+SbxObject::~SbxObject()
+{
+ CheckParentsOnDelete( this, pProps );
+ CheckParentsOnDelete( this, pMethods );
+ CheckParentsOnDelete( this, pObjs );
+}
+
+SbxDataType SbxObject::GetType() const
+{
+ return SbxOBJECT;
+}
+
+SbxClassType SbxObject::GetClass() const
+{
+ return SbxCLASS_OBJECT;
+}
+
+void SbxObject::Clear()
+{
+ pMethods = new SbxArray;
+ pProps = new SbxArray;
+ pObjs = new SbxArray( SbxOBJECT );
+ SbxVariable* p;
+ p = Make( String::CreateFromAscii( pNameProp ), SbxCLASS_PROPERTY, SbxSTRING );
+ p->SetFlag( SBX_DONTSTORE );
+ p = Make( String::CreateFromAscii( pParentProp ), SbxCLASS_PROPERTY, SbxOBJECT );
+ p->ResetFlag( SBX_WRITE );
+ p->SetFlag( SBX_DONTSTORE );
+ pDfltProp = NULL;
+ SetModified( FALSE );
+}
+
+void SbxObject::SFX_NOTIFY( SfxBroadcaster&, const TypeId&,
+ const SfxHint& rHint, const TypeId& )
+{
+ const SbxHint* p = PTR_CAST(SbxHint,&rHint);
+ if( p )
+ {
+ ULONG nId = p->GetId();
+ BOOL bRead = BOOL( nId == SBX_HINT_DATAWANTED );
+ BOOL bWrite = BOOL( nId == SBX_HINT_DATACHANGED );
+ SbxVariable* pVar = p->GetVar();
+ if( bRead || bWrite )
+ {
+ XubString aVarName( pVar->GetName() );
+ USHORT nHash_ = MakeHashCode( aVarName );
+ if( nHash_ == nNameHash
+ && aVarName.EqualsIgnoreCaseAscii( pNameProp ) )
+ {
+ if( bRead )
+ pVar->PutString( GetName() );
+ else
+ SetName( pVar->GetString() );
+ }
+ else if( nHash_ == nParentHash
+ && aVarName.EqualsIgnoreCaseAscii( pParentProp ) )
+ {
+ SbxObject* p_ = GetParent();
+ if( !p_ )
+ p_ = this;
+ pVar->PutObject( p_ );
+ }
+ }
+ }
+}
+
+BOOL SbxObject::IsClass( const XubString& rName ) const
+{
+ return BOOL( aClassName.EqualsIgnoreCaseAscii( rName ) );
+}
+
+SbxVariable* SbxObject::FindUserData( UINT32 nData )
+{
+ if( !GetAll( SbxCLASS_DONTCARE ) )
+ return NULL;
+
+ SbxVariable* pRes = pMethods->FindUserData( nData );
+ if( !pRes )
+ pRes = pProps->FindUserData( nData );
+ if( !pRes )
+ pRes = pObjs->FindUserData( nData );
+ // Search in den Parents?
+ if( !pRes && IsSet( SBX_GBLSEARCH ) )
+ {
+ SbxObject* pCur = this;
+ while( !pRes && pCur->pParent )
+ {
+ // Ich selbst bin schon durchsucht worden!
+ USHORT nOwn = pCur->GetFlags();
+ pCur->ResetFlag( SBX_EXTSEARCH );
+ // Ich suche bereits global!
+ USHORT nPar = pCur->pParent->GetFlags();
+ pCur->pParent->ResetFlag( SBX_GBLSEARCH );
+ pRes = pCur->pParent->FindUserData( nData );
+ pCur->SetFlags( nOwn );
+ pCur->pParent->SetFlags( nPar );
+ pCur = pCur->pParent;
+ }
+ }
+ return pRes;
+}
+
+SbxVariable* SbxObject::Find( const XubString& rName, SbxClassType t )
+{
+#ifdef DBG_UTIL
+ static USHORT nLvl = 0;
+ static const char* pCls[] =
+ { "DontCare","Array","Value","Variable","Method","Property","Object" };
+ ByteString aNameStr1( (const UniString&)rName, RTL_TEXTENCODING_ASCII_US );
+ ByteString aNameStr2( (const UniString&)SbxVariable::GetName(), RTL_TEXTENCODING_ASCII_US );
+ DbgOutf( "SBX: Search %.*s %s %s in %s",
+ nLvl++, " ",
+ ( t >= SbxCLASS_DONTCARE && t <= SbxCLASS_OBJECT )
+ ? pCls[ t-1 ] : "Unknown class", aNameStr1.GetBuffer(), aNameStr1.GetBuffer() );
+#endif
+
+ if( !GetAll( t ) )
+ return NULL;
+ SbxVariable* pRes = NULL;
+ pObjs->SetFlag( SBX_EXTSEARCH );
+ if( t == SbxCLASS_DONTCARE )
+ {
+ pRes = pMethods->Find( rName, SbxCLASS_METHOD );
+ if( !pRes )
+ pRes = pProps->Find( rName, SbxCLASS_PROPERTY );
+ if( !pRes )
+ pRes = pObjs->Find( rName, t );
+ }
+ else
+ {
+ SbxArray* pArray = NULL;
+ switch( t )
+ {
+ case SbxCLASS_VARIABLE:
+ case SbxCLASS_PROPERTY: pArray = pProps; break;
+ case SbxCLASS_METHOD: pArray = pMethods; break;
+ case SbxCLASS_OBJECT: pArray = pObjs; break;
+ default:
+ DBG_ASSERT( !this, "Ungueltige SBX-Klasse" );
+ }
+ if( pArray )
+ pRes = pArray->Find( rName, t );
+ }
+ // Extended Search im Objekt-Array?
+ // Fuer Objekte und DontCare ist das Objektarray bereits
+ // durchsucht worden
+ if( !pRes && ( t == SbxCLASS_METHOD || t == SbxCLASS_PROPERTY ) )
+ pRes = pObjs->Find( rName, t );
+ // Search in den Parents?
+ if( !pRes && IsSet( SBX_GBLSEARCH ) )
+ {
+ SbxObject* pCur = this;
+ while( !pRes && pCur->pParent )
+ {
+ // Ich selbst bin schon durchsucht worden!
+ USHORT nOwn = pCur->GetFlags();
+ pCur->ResetFlag( SBX_EXTSEARCH );
+ // Ich suche bereits global!
+ USHORT nPar = pCur->pParent->GetFlags();
+ pCur->pParent->ResetFlag( SBX_GBLSEARCH );
+ pRes = pCur->pParent->Find( rName, t );
+ pCur->SetFlags( nOwn );
+ pCur->pParent->SetFlags( nPar );
+ pCur = pCur->pParent;
+ }
+ }
+#ifdef DBG_UTIL
+ nLvl--;
+ if( pRes )
+ {
+ ByteString aNameStr3( (const UniString&)rName, RTL_TEXTENCODING_ASCII_US );
+ ByteString aNameStr4( (const UniString&)SbxVariable::GetName(), RTL_TEXTENCODING_ASCII_US );
+ DbgOutf( "SBX: Found %.*s %s in %s",
+ nLvl, " ", aNameStr3.GetBuffer(), aNameStr4.GetBuffer() );
+ }
+#endif
+ return pRes;
+}
+
+// Kurzform: Die Parent-Kette wird durchsucht
+// Das ganze rekursiv, da Call() ueberladen sein kann
+// Qualified Names sind zugelassen
+
+BOOL SbxObject::Call( const XubString& rName, SbxArray* pParam )
+{
+ SbxVariable* pMeth = FindQualified( rName, SbxCLASS_DONTCARE);
+ if( pMeth && pMeth->ISA(SbxMethod) )
+ {
+ // FindQualified() koennte schon zugeschlagen haben!
+ if( pParam )
+ pMeth->SetParameters( pParam );
+ pMeth->Broadcast( SBX_HINT_DATAWANTED );
+ pMeth->SetParameters( NULL );
+ return TRUE;
+ }
+ SetError( SbxERR_NO_METHOD );
+ return FALSE;
+}
+
+SbxProperty* SbxObject::GetDfltProperty()
+{
+ if ( !pDfltProp && aDfltPropName.Len() )
+ {
+ pDfltProp = (SbxProperty*) Find( aDfltPropName, SbxCLASS_PROPERTY );
+ if( !pDfltProp )
+ pDfltProp = (SbxProperty*) Make( aDfltPropName, SbxCLASS_PROPERTY, SbxVARIANT );
+ }
+ return pDfltProp;
+}
+
+// Suchen einer bereits vorhandenen Variablen. Falls sie gefunden wurde,
+// wird der Index gesetzt, sonst wird der Count des Arrays geliefert.
+// In jedem Fall wird das korrekte Array geliefert.
+
+SbxArray* SbxObject::FindVar( SbxVariable* pVar, USHORT& nArrayIdx )
+{
+ SbxArray* pArray = NULL;
+ if( pVar ) switch( pVar->GetClass() )
+ {
+ case SbxCLASS_VARIABLE:
+ case SbxCLASS_PROPERTY: pArray = pProps; break;
+ case SbxCLASS_METHOD: pArray = pMethods; break;
+ case SbxCLASS_OBJECT: pArray = pObjs; break;
+ default:
+ DBG_ASSERT( !this, "Ungueltige SBX-Klasse" );
+ }
+ if( pArray )
+ {
+ nArrayIdx = pArray->Count();
+ // ist die Variable per Name vorhanden?
+ pArray->ResetFlag( SBX_EXTSEARCH );
+ SbxVariable* pOld = pArray->Find( pVar->GetName(), pVar->GetClass() );
+ if( pOld )
+ for( USHORT i = 0; i < pArray->Count(); i++ )
+ {
+ SbxVariableRef& rRef = pArray->GetRef( i );
+ if( (SbxVariable*) rRef == pOld )
+ {
+ nArrayIdx = i; break;
+ }
+ }
+ }
+ return pArray;
+}
+
+// Falls ein neues Objekt eingerichtet wird, wird es, falls es bereits
+// eines mit diesem Namen gibt, indiziert.
+
+SbxVariable* SbxObject::Make( const XubString& rName, SbxClassType ct, SbxDataType dt )
+{
+ // Ist das Objekt bereits vorhanden?
+ SbxArray* pArray = NULL;
+ switch( ct )
+ {
+ case SbxCLASS_VARIABLE:
+ case SbxCLASS_PROPERTY: pArray = pProps; break;
+ case SbxCLASS_METHOD: pArray = pMethods; break;
+ case SbxCLASS_OBJECT: pArray = pObjs; break;
+ default:
+ DBG_ASSERT( !this, "Ungueltige SBX-Klasse" );
+ }
+ if( !pArray )
+ return NULL;
+ // Collections duerfen gleichnamige Objekte enthalten
+ if( !( ct == SbxCLASS_OBJECT && ISA(SbxCollection) ) )
+ {
+ SbxVariable* pRes = pArray->Find( rName, ct );
+ if( pRes )
+ {
+/* Wegen haeufiger Probleme (z.B. #67000) erstmal ganz raus
+#ifdef DBG_UTIL
+ if( pRes->GetHashCode() != nNameHash
+ && pRes->GetHashCode() != nParentHash )
+ {
+ XubString aMsg( "SBX-Element \"" );
+ aMsg += pRes->GetName();
+ aMsg += "\"\n in Objekt \"";
+ aMsg += GetName();
+ aMsg += "\" bereits vorhanden";
+ DbgError( (const char*)aMsg.GetStr() );
+ }
+#endif
+*/
+ return pRes;
+ }
+ }
+ SbxVariable* pVar = NULL;
+ switch( ct )
+ {
+ case SbxCLASS_VARIABLE:
+ case SbxCLASS_PROPERTY:
+ pVar = new SbxProperty( rName, dt );
+ break;
+ case SbxCLASS_METHOD:
+ pVar = new SbxMethod( rName, dt );
+ break;
+ case SbxCLASS_OBJECT:
+ pVar = CreateObject( rName );
+ break;
+ default: break;
+ }
+ pVar->SetParent( this );
+ pArray->Put( pVar, pArray->Count() );
+ SetModified( TRUE );
+ // Das Objekt lauscht immer
+ StartListening( pVar->GetBroadcaster(), TRUE );
+ Broadcast( SBX_HINT_OBJECTCHANGED );
+ return pVar;
+}
+
+SbxObject* SbxObject::MakeObject( const XubString& rName, const XubString& rClass )
+{
+ // Ist das Objekt bereits vorhanden?
+ if( !ISA(SbxCollection) )
+ {
+ SbxVariable* pRes = pObjs->Find( rName, SbxCLASS_OBJECT );
+ if( pRes )
+ {
+/* Wegen haeufiger Probleme (z.B. #67000) erstmal ganz raus
+#ifdef DBG_UTIL
+ if( pRes->GetHashCode() != nNameHash
+ && pRes->GetHashCode() != nParentHash )
+ {
+ XubString aMsg( "SBX-Objekt \"" );
+ aMsg += pRes->GetName();
+ aMsg += "\"\n in Objekt \"";
+ aMsg += GetName();
+ aMsg += "\" bereits vorhanden";
+ DbgError( (const char*)aMsg.GetStr() );
+ }
+#endif
+*/
+ return PTR_CAST(SbxObject,pRes);
+ }
+ }
+ SbxObject* pVar = CreateObject( rClass );
+ if( pVar )
+ {
+ pVar->SetName( rName );
+ pVar->SetParent( this );
+ pObjs->Put( pVar, pObjs->Count() );
+ SetModified( TRUE );
+ // Das Objekt lauscht immer
+ StartListening( pVar->GetBroadcaster(), TRUE );
+ Broadcast( SBX_HINT_OBJECTCHANGED );
+ }
+ return pVar;
+}
+
+void SbxObject::Insert( SbxVariable* pVar )
+{
+ USHORT nIdx;
+ SbxArray* pArray = FindVar( pVar, nIdx );
+ if( pArray )
+ {
+ // Hinein damit. Man sollte allerdings auf die Pointer aufpassen!
+ if( nIdx < pArray->Count() )
+ {
+ // dann gibt es dieses Element bereits
+ // Bei Collections duerfen gleichnamige Objekte hinein
+ if( pArray == pObjs && ISA(SbxCollection) )
+ nIdx = pArray->Count();
+ else
+ {
+ SbxVariable* pOld = pArray->Get( nIdx );
+ // schon drin: ueberschreiben
+ if( pOld == pVar )
+ return;
+
+/* Wegen haeufiger Probleme (z.B. #67000) erstmal ganz raus
+#ifdef DBG_UTIL
+ if( pOld->GetHashCode() != nNameHash
+ && pOld->GetHashCode() != nParentHash )
+ {
+ XubString aMsg( "SBX-Element \"" );
+ aMsg += pVar->GetName();
+ aMsg += "\"\n in Objekt \"";
+ aMsg += GetName();
+ aMsg += "\" bereits vorhanden";
+ DbgError( (const char*)aMsg.GetStr() );
+ }
+#endif
+*/
+ EndListening( pOld->GetBroadcaster(), TRUE );
+ if( pVar->GetClass() == SbxCLASS_PROPERTY )
+ {
+ if( pOld == pDfltProp )
+ pDfltProp = (SbxProperty*) pVar;
+ }
+ }
+ }
+ StartListening( pVar->GetBroadcaster(), TRUE );
+ pArray->Put( pVar, nIdx );
+ if( pVar->GetParent() != this )
+ pVar->SetParent( this );
+ SetModified( TRUE );
+ Broadcast( SBX_HINT_OBJECTCHANGED );
+#ifdef DBG_UTIL
+ static const char* pCls[] =
+ { "DontCare","Array","Value","Variable","Method","Property","Object" };
+ XubString aVarName( pVar->GetName() );
+ if ( !aVarName.Len() && pVar->ISA(SbxObject) )
+ aVarName = PTR_CAST(SbxObject,pVar)->GetClassName();
+ ByteString aNameStr1( (const UniString&)aVarName, RTL_TEXTENCODING_ASCII_US );
+ ByteString aNameStr2( (const UniString&)SbxVariable::GetName(), RTL_TEXTENCODING_ASCII_US );
+ DbgOutf( "SBX: Insert %s %s in %s",
+ ( pVar->GetClass() >= SbxCLASS_DONTCARE &&
+ pVar->GetClass() <= SbxCLASS_OBJECT )
+ ? pCls[ pVar->GetClass()-1 ] : "Unknown class", aNameStr1.GetBuffer(), aNameStr1.GetBuffer() );
+#endif
+ }
+}
+
+// AB 23.4.1997, Optimierung, Einfuegen ohne Ueberpruefung auf doppelte
+// Eintraege und ohne Broadcasts, wird nur in SO2/auto.cxx genutzt
+void SbxObject::QuickInsert( SbxVariable* pVar )
+{
+ SbxArray* pArray = NULL;
+ if( pVar )
+ {
+ switch( pVar->GetClass() )
+ {
+ case SbxCLASS_VARIABLE:
+ case SbxCLASS_PROPERTY: pArray = pProps; break;
+ case SbxCLASS_METHOD: pArray = pMethods; break;
+ case SbxCLASS_OBJECT: pArray = pObjs; break;
+ default:
+ DBG_ASSERT( !this, "Ungueltige SBX-Klasse" );
+ }
+ }
+ if( pArray )
+ {
+ StartListening( pVar->GetBroadcaster(), TRUE );
+ pArray->Put( pVar, pArray->Count() );
+ if( pVar->GetParent() != this )
+ pVar->SetParent( this );
+ SetModified( TRUE );
+#ifdef DBG_UTIL
+ static const char* pCls[] =
+ { "DontCare","Array","Value","Variable","Method","Property","Object" };
+ XubString aVarName( pVar->GetName() );
+ if ( !aVarName.Len() && pVar->ISA(SbxObject) )
+ aVarName = PTR_CAST(SbxObject,pVar)->GetClassName();
+ ByteString aNameStr1( (const UniString&)aVarName, RTL_TEXTENCODING_ASCII_US );
+ ByteString aNameStr2( (const UniString&)SbxVariable::GetName(), RTL_TEXTENCODING_ASCII_US );
+ DbgOutf( "SBX: Insert %s %s in %s",
+ ( pVar->GetClass() >= SbxCLASS_DONTCARE &&
+ pVar->GetClass() <= SbxCLASS_OBJECT )
+ ? pCls[ pVar->GetClass()-1 ] : "Unknown class", aNameStr1.GetBuffer(), aNameStr1.GetBuffer() );
+#endif
+ }
+}
+
+void SbxObject::Remove( const XubString& rName, SbxClassType t )
+{
+ Remove( SbxObject::Find( rName, t ) );
+}
+
+void SbxObject::Remove( SbxVariable* pVar )
+{
+ USHORT nIdx;
+ SbxArray* pArray = FindVar( pVar, nIdx );
+ if( pArray && nIdx < pArray->Count() )
+ {
+#ifdef DBG_UTIL
+ XubString aVarName( pVar->GetName() );
+ if ( !aVarName.Len() && pVar->ISA(SbxObject) )
+ aVarName = PTR_CAST(SbxObject,pVar)->GetClassName();
+ ByteString aNameStr1( (const UniString&)aVarName, RTL_TEXTENCODING_ASCII_US );
+ ByteString aNameStr2( (const UniString&)SbxVariable::GetName(), RTL_TEXTENCODING_ASCII_US );
+#endif
+ SbxVariableRef pVar_ = pArray->Get( nIdx );
+ if( pVar_->IsBroadcaster() )
+ EndListening( pVar_->GetBroadcaster(), TRUE );
+ if( (SbxVariable*) pVar_ == pDfltProp )
+ pDfltProp = NULL;
+ pArray->Remove( nIdx );
+ if( pVar_->GetParent() == this )
+ pVar_->SetParent( NULL );
+ SetModified( TRUE );
+ Broadcast( SBX_HINT_OBJECTCHANGED );
+ }
+}
+
+static BOOL LoadArray( SvStream& rStrm, SbxObject* pThis, SbxArray* pArray )
+{
+ SbxArrayRef p = (SbxArray*) SbxBase::Load( rStrm );
+ if( !p.Is() )
+ return FALSE;
+ for( USHORT i = 0; i < p->Count(); i++ )
+ {
+ SbxVariableRef& r = p->GetRef( i );
+ SbxVariable* pVar = r;
+ if( pVar )
+ {
+ pVar->SetParent( pThis );
+ pThis->StartListening( pVar->GetBroadcaster(), TRUE );
+ }
+ }
+ pArray->Merge( p );
+ return TRUE;
+}
+
+// Der Load eines Objekts ist additiv!
+
+BOOL SbxObject::LoadData( SvStream& rStrm, USHORT nVer )
+{
+ // Hilfe fuer das Einlesen alter Objekte: einfach TRUE zurueck,
+ // LoadPrivateData() muss Default-Zustand herstellen
+ if( !nVer )
+ return TRUE;
+
+ pDfltProp = NULL;
+ if( !SbxVariable::LoadData( rStrm, nVer ) )
+ return FALSE;
+ // Wenn kein fremdes Objekt enthalten ist, uns selbst eintragen
+ if( aData.eType == SbxOBJECT && !aData.pObj )
+ aData.pObj = this;
+ sal_uInt32 nSize;
+ XubString aDfltProp;
+ rStrm.ReadByteString( aClassName, RTL_TEXTENCODING_ASCII_US );
+ rStrm.ReadByteString( aDfltProp, RTL_TEXTENCODING_ASCII_US );
+ ULONG nPos = rStrm.Tell();
+ rStrm >> nSize;
+ if( !LoadPrivateData( rStrm, nVer ) )
+ return FALSE;
+ ULONG nNewPos = rStrm.Tell();
+ nPos += nSize;
+ DBG_ASSERT( nPos >= nNewPos, "SBX: Zu viele Daten eingelesen" );
+ if( nPos != nNewPos )
+ rStrm.Seek( nPos );
+ if( !LoadArray( rStrm, this, pMethods )
+ || !LoadArray( rStrm, this, pProps )
+ || !LoadArray( rStrm, this, pObjs ) )
+ return FALSE;
+ // Properties setzen
+ if( aDfltProp.Len() )
+ pDfltProp = (SbxProperty*) pProps->Find( aDfltProp, SbxCLASS_PROPERTY );
+ SetModified( FALSE );
+ return TRUE;
+}
+
+BOOL SbxObject::StoreData( SvStream& rStrm ) const
+{
+ if( !SbxVariable::StoreData( rStrm ) )
+ return FALSE;
+ XubString aDfltProp;
+ if( pDfltProp )
+ aDfltProp = pDfltProp->GetName();
+ rStrm.WriteByteString( aClassName, RTL_TEXTENCODING_ASCII_US );
+ rStrm.WriteByteString( aDfltProp, RTL_TEXTENCODING_ASCII_US );
+ ULONG nPos = rStrm.Tell();
+ rStrm << (UINT32) 0L;
+ if( !StorePrivateData( rStrm ) )
+ return FALSE;
+ ULONG nNew = rStrm.Tell();
+ rStrm.Seek( nPos );
+ rStrm << (UINT32) ( nNew - nPos );
+ rStrm.Seek( nNew );
+ if( !pMethods->Store( rStrm ) )
+ return FALSE;
+ if( !pProps->Store( rStrm ) )
+ return FALSE;
+ if( !pObjs->Store( rStrm ) )
+ return FALSE;
+ ((SbxObject*) this)->SetModified( FALSE );
+ return TRUE;
+}
+
+XubString SbxObject::GenerateSource( const XubString &rLinePrefix,
+ const SbxObject* )
+{
+ // Properties in einem String einsammeln
+ XubString aSource;
+ SbxArrayRef xProps( GetProperties() );
+ FASTBOOL bLineFeed = FALSE;
+ for ( USHORT nProp = 0; nProp < xProps->Count(); ++nProp )
+ {
+ SbxPropertyRef xProp = (SbxProperty*) xProps->Get(nProp);
+ XubString aPropName( xProp->GetName() );
+ if ( xProp->CanWrite()
+ && !( xProp->GetHashCode() == nNameHash
+ && aPropName.EqualsIgnoreCaseAscii( pNameProp ) ) )
+ {
+ // ausser vor dem ersten Property immer einen Umbruch einfuegen
+ if ( bLineFeed )
+ aSource.AppendAscii( "\n" );
+ else
+ bLineFeed = TRUE;
+
+ aSource += rLinePrefix;
+ aSource += '.';
+ aSource += aPropName;
+ aSource.AppendAscii( " = " );
+
+ // den Property-Wert textuell darstellen
+ switch ( xProp->GetType() )
+ {
+ case SbxEMPTY:
+ case SbxNULL:
+ // kein Wert
+ break;
+
+ case SbxSTRING:
+ {
+ // Strings in Anf"uhrungszeichen
+ aSource.AppendAscii( "\"" );
+ aSource += xProp->GetString();
+ aSource.AppendAscii( "\"" );
+ break;
+ }
+
+ default:
+ {
+ // sonstiges wie z.B. Zahlen direkt
+ aSource += xProp->GetString();
+ break;
+ }
+ }
+ }
+ }
+ return aSource;
+}
+
+static BOOL CollectAttrs( const SbxBase* p, XubString& rRes )
+{
+ XubString aAttrs;
+ if( p->IsHidden() )
+ aAttrs.AssignAscii( "Hidden" );
+ if( p->IsSet( SBX_EXTSEARCH ) )
+ {
+ if( aAttrs.Len() )
+ aAttrs += ',';
+ aAttrs.AppendAscii( "ExtSearch" );
+ }
+ if( !p->IsVisible() )
+ {
+ if( aAttrs.Len() )
+ aAttrs += ',';
+ aAttrs.AppendAscii( "Invisible" );
+ }
+ if( p->IsSet( SBX_DONTSTORE ) )
+ {
+ if( aAttrs.Len() )
+ aAttrs += ',';
+ aAttrs.AppendAscii( "DontStore" );
+ }
+ if( aAttrs.Len() )
+ {
+ rRes.AssignAscii( " (" );
+ rRes += aAttrs;
+ rRes += ')';
+ return TRUE;
+ }
+ else
+ {
+ rRes.Erase();
+ return FALSE;
+ }
+}
+
+void SbxObject::Dump( SvStream& rStrm, BOOL bFill )
+{
+ // Einr"uckung
+ static USHORT nLevel = 0;
+ if ( nLevel > 10 )
+ {
+ rStrm << "<too deep>" << endl;
+ return;
+ }
+ ++nLevel;
+ String aIndent;
+ for ( USHORT n = 1; n < nLevel; ++n )
+ aIndent.AppendAscii( " " );
+
+ // ggf. Objekt vervollst"andigen
+ if ( bFill )
+ GetAll( SbxCLASS_DONTCARE );
+
+ // Daten des Objekts selbst ausgeben
+ ByteString aNameStr( (const UniString&)GetName(), RTL_TEXTENCODING_ASCII_US );
+ ByteString aClassNameStr( (const UniString&)aClassName, RTL_TEXTENCODING_ASCII_US );
+ rStrm << "Object( "
+ << ByteString::CreateFromInt64( (ULONG) this ).GetBuffer() << "=='"
+ << ( aNameStr.Len() ? aNameStr.GetBuffer() : "<unnamed>" ) << "', "
+ << "of class '" << aClassNameStr.GetBuffer() << "', "
+ << "counts "
+ << ByteString::CreateFromInt64( GetRefCount() ).GetBuffer()
+ << " refs, ";
+ if ( GetParent() )
+ {
+ ByteString aParentNameStr( (const UniString&)GetName(), RTL_TEXTENCODING_ASCII_US );
+ rStrm << "in parent "
+ << ByteString::CreateFromInt64( (ULONG) GetParent() ).GetBuffer()
+ << "=='" << ( aParentNameStr.Len() ? aParentNameStr.GetBuffer() : "<unnamed>" ) << "'";
+ }
+ else
+ rStrm << "no parent ";
+ rStrm << " )" << endl;
+ ByteString aIndentNameStr( (const UniString&)aIndent, RTL_TEXTENCODING_ASCII_US );
+ rStrm << aIndentNameStr.GetBuffer() << "{" << endl;
+
+ // Flags
+ XubString aAttrs;
+ if( CollectAttrs( this, aAttrs ) )
+ {
+ ByteString aAttrStr( (const UniString&)aAttrs, RTL_TEXTENCODING_ASCII_US );
+ rStrm << aIndentNameStr.GetBuffer() << "- Flags: " << aAttrStr.GetBuffer() << endl;
+ }
+
+ // Methods
+ rStrm << aIndentNameStr.GetBuffer() << "- Methods:" << endl;
+ for( USHORT i = 0; i < pMethods->Count(); i++ )
+ {
+ SbxVariableRef& r = pMethods->GetRef( i );
+ SbxVariable* pVar = r;
+ if( pVar )
+ {
+ XubString aLine( aIndent );
+ aLine.AppendAscii( " - " );
+ aLine += pVar->GetName( SbxNAME_SHORT_TYPES );
+ XubString aAttrs2;
+ if( CollectAttrs( pVar, aAttrs2 ) )
+ aLine += aAttrs2;
+ if( !pVar->IsA( TYPE(SbxMethod) ) )
+ aLine.AppendAscii( " !! Not a Method !!" );
+ rStrm.WriteByteString( aLine, RTL_TEXTENCODING_ASCII_US );
+
+ // bei Object-Methods auch das Object ausgeben
+ if ( pVar->GetValues_Impl().eType == SbxOBJECT &&
+ pVar->GetValues_Impl().pObj &&
+ pVar->GetValues_Impl().pObj != this &&
+ pVar->GetValues_Impl().pObj != GetParent() )
+ {
+ rStrm << " contains ";
+ ((SbxObject*) pVar->GetValues_Impl().pObj)->Dump( rStrm, bFill );
+ }
+ else
+ rStrm << endl;
+ }
+ }
+
+ // Properties
+ rStrm << aIndentNameStr.GetBuffer() << "- Properties:" << endl;
+ {
+ for( USHORT i = 0; i < pProps->Count(); i++ )
+ {
+ SbxVariableRef& r = pProps->GetRef( i );
+ SbxVariable* pVar = r;
+ if( pVar )
+ {
+ XubString aLine( aIndent );
+ aLine.AppendAscii( " - " );
+ aLine += pVar->GetName( SbxNAME_SHORT_TYPES );
+ XubString aAttrs3;
+ if( CollectAttrs( pVar, aAttrs3 ) )
+ aLine += aAttrs3;
+ if( !pVar->IsA( TYPE(SbxProperty) ) )
+ aLine.AppendAscii( " !! Not a Property !!" );
+ rStrm.WriteByteString( aLine, RTL_TEXTENCODING_ASCII_US );
+
+ // bei Object-Properties auch das Object ausgeben
+ if ( pVar->GetValues_Impl().eType == SbxOBJECT &&
+ pVar->GetValues_Impl().pObj &&
+ pVar->GetValues_Impl().pObj != this &&
+ pVar->GetValues_Impl().pObj != GetParent() )
+ {
+ rStrm << " contains ";
+ ((SbxObject*) pVar->GetValues_Impl().pObj)->Dump( rStrm, bFill );
+ }
+ else
+ rStrm << endl;
+ }
+ }
+ }
+
+ // Objects
+ rStrm << aIndentNameStr.GetBuffer() << "- Objects:" << endl;
+ {
+ for( USHORT i = 0; i < pObjs->Count(); i++ )
+ {
+ SbxVariableRef& r = pObjs->GetRef( i );
+ SbxVariable* pVar = r;
+ if ( pVar )
+ {
+ rStrm << aIndentNameStr.GetBuffer() << " - Sub";
+ if ( pVar->ISA(SbxObject) )
+ ((SbxObject*) pVar)->Dump( rStrm, bFill );
+ else if ( pVar->ISA(SbxVariable) )
+ ((SbxVariable*) pVar)->Dump( rStrm, bFill );
+ }
+ }
+ }
+
+ rStrm << aIndentNameStr.GetBuffer() << "}" << endl << endl;
+ --nLevel;
+}
+
+SvDispatch* SbxObject::GetSvDispatch()
+{
+ return NULL;
+}
+
+SbxClassType SbxMethod::GetClass() const
+{
+ return SbxCLASS_METHOD;
+}
+
+SbxClassType SbxProperty::GetClass() const
+{
+ return SbxCLASS_PROPERTY;
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/sbx/sbxres.cxx b/binfilter/bf_basic/source/sbx/sbxres.cxx
new file mode 100644
index 000000000000..d6c7ec33da7a
--- /dev/null
+++ b/binfilter/bf_basic/source/sbx/sbxres.cxx
@@ -0,0 +1,94 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "sbxres.hxx"
+
+namespace binfilter {
+
+static const char* pSbxRes[] = {
+ "Empty",
+ "Null",
+ "Integer",
+ "Long",
+ "Single",
+ "Double",
+ "Currency",
+ "Date",
+ "String",
+ "Object",
+ "Error",
+ "Boolean",
+ "Variant",
+ "Any",
+ "Type14",
+ "Type15",
+ "Char",
+ "Byte",
+ "UShort",
+ "ULong",
+ "Long64",
+ "ULong64",
+ "Int",
+ "UInt",
+ "Void",
+ "HResult",
+ "Pointer",
+ "DimArray",
+ "CArray",
+ "Any",
+ "LpStr",
+ "LpWStr",
+ " As ",
+ "Optional ",
+ "Byref ",
+
+ "Name",
+ "Parent",
+ "Application",
+ "Count",
+ "Add",
+ "Item",
+ "Remove",
+
+ "Error ", // mit Blank!
+ "False",
+ "True"
+};
+
+const char* GetSbxRes( USHORT nId )
+{
+ return ( ( nId > SBXRES_MAX ) ? "???" : pSbxRes[ nId ] );
+}
+
+SbxRes::SbxRes( USHORT nId )
+ : XubString( String::CreateFromAscii( GetSbxRes( nId ) ) )
+{}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/sbx/sbxres.hxx b/binfilter/bf_basic/source/sbx/sbxres.hxx
new file mode 100644
index 000000000000..9f03fab4b8bc
--- /dev/null
+++ b/binfilter/bf_basic/source/sbx/sbxres.hxx
@@ -0,0 +1,93 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SBXRES_HXX
+#define _SBXRES_HXX
+
+#include <tools/string.hxx>
+
+// Zur Zeit sind Ressources im SVTOOLS-Projekt nicht vorgesehen.
+// Da es sich um unkritische Ressourcen handelt (BASIC-Keywords),
+// koennen wir mit Dummies arbeiten.
+
+#define STRING_TYPES 0
+#define STRING_EMPTY 0
+#define STRING_NULL 1
+#define STRING_INTEGER 2
+#define STRING_LONG 3
+#define STRING_SINGLE 4
+#define STRING_DOUBLE 5
+#define STRING_CURRENCY 6
+#define STRING_DATE 7
+#define STRING_STRING 8
+#define STRING_OBJECT 9
+#define STRING_ERROR 10
+#define STRING_BOOL 11
+#define STRING_VARIANT 12
+#define STRING_ANY 13
+#define STRING_CHAR 16
+#define STRING_BYTE 17
+#define STRING_USHORT 18
+#define STRING_ULONG 19
+#define STRING_INT 22
+#define STRING_UINT 23
+#define STRING_LPSTR 30
+#define STRING_LPWSTR 31
+#define STRING_AS 32
+#define STRING_OPTIONAL 33
+#define STRING_BYREF 34
+
+#define STRING_NAMEPROP 35
+#define STRING_PARENTPROP 36
+#define STRING_APPLPROP 37
+#define STRING_COUNTPROP 38
+#define STRING_ADDMETH 39
+#define STRING_ITEMMETH 40
+#define STRING_REMOVEMETH 41
+
+#define STRING_ERRORMSG 42
+#define STRING_FALSE 43
+#define STRING_TRUE 44
+
+#define SBXRES_MAX 44
+
+namespace binfilter {
+
+class SbxRes : public String
+{
+public:
+ SbxRes( USHORT );
+};
+
+const char* GetSbxRes( USHORT );
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/sbx/sbxscan.cxx b/binfilter/bf_basic/source/sbx/sbxscan.cxx
new file mode 100644
index 000000000000..a5d4417afae1
--- /dev/null
+++ b/binfilter/bf_basic/source/sbx/sbxscan.cxx
@@ -0,0 +1,517 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <tools/errcode.hxx>
+#include "sbx.hxx"
+#include "sbxconv.hxx"
+
+#include "bf_svtools/syslocale.hxx"
+
+#if defined ( UNX )
+#include <stdlib.h>
+#endif
+
+#include <vcl/svapp.hxx>
+#include <math.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "sbxres.hxx"
+#include "sbxbase.hxx"
+#include <bf_svtools/svtools.hrc>
+
+namespace binfilter {
+
+void ImpGetIntntlSep( sal_Unicode& rcDecimalSep, sal_Unicode& rcThousandSep )
+{
+ SvtSysLocale aSysLocale;
+ const LocaleDataWrapper& rData = aSysLocale.GetLocaleData();
+ rcDecimalSep = rData.getNumDecimalSep().GetBuffer()[0];
+ rcThousandSep = rData.getNumThousandSep().GetBuffer()[0];
+}
+
+// Scannen eines Strings nach BASIC-Konventionen
+// Dies entspricht den ueblichen Konventionen, nur dass der Exponent
+// auch ein D sein darf, was den Datentyp auf SbxDOUBLE festlegt.
+// Die Routine versucht, den Datentyp so klein wie moeglich zu gestalten.
+// Das ganze gibt auch noch einen Konversionsfehler, wenn der Datentyp
+// Fixed ist und das ganze nicht hineinpasst!
+
+SbxError ImpScan( const XubString& rWSrc, double& nVal, SbxDataType& rType,
+ USHORT* pLen, BOOL bAllowIntntl, BOOL bOnlyIntntl )
+{
+ ByteString aBStr( rWSrc, RTL_TEXTENCODING_ASCII_US );
+
+ // Bei International Komma besorgen
+ char cIntntlComma, cIntntl1000;
+ char cNonIntntlComma = '.';
+
+ sal_Unicode cDecimalSep, cThousandSep = 0;
+ if( bAllowIntntl || bOnlyIntntl )
+ {
+ ImpGetIntntlSep( cDecimalSep, cThousandSep );
+ cIntntlComma = (char)cDecimalSep;
+ cIntntl1000 = (char)cThousandSep;
+ }
+ // Sonst einfach auch auf . setzen
+ else
+ {
+ cIntntlComma = cNonIntntlComma;
+ cIntntl1000 = cNonIntntlComma; // Unschaedlich machen
+ }
+ // Nur International -> IntnlComma uebernehmen
+ if( bOnlyIntntl )
+ {
+ cNonIntntlComma = cIntntlComma;
+ cIntntl1000 = (char)cThousandSep;
+ }
+
+ const char* pStart = aBStr.GetBuffer();
+ const char* p = pStart;
+ char buf[ 80 ], *q = buf;
+ BOOL bRes = TRUE;
+ BOOL bMinus = FALSE;
+ nVal = 0;
+ SbxDataType eScanType = SbxSINGLE;
+ // Whitespace wech
+ while( *p &&( *p == ' ' || *p == '\t' ) ) p++;
+ // Zahl? Dann einlesen und konvertieren.
+ if( *p == '-' )
+ p++, bMinus = TRUE;
+ if( isdigit( *p ) ||( (*p == cNonIntntlComma || *p == cIntntlComma ||
+ *p == cIntntl1000) && isdigit( *(p+1 ) ) ) )
+ {
+ short exp = 0; // >0: Exponentteil
+ short comma = 0; // >0: Nachkomma
+ short ndig = 0; // Anzahl Ziffern
+ short ncdig = 0; // Anzahl Ziffern nach Komma
+ ByteString aSearchStr( "0123456789DEde" );
+ // Kommas ergaenzen
+ aSearchStr += cNonIntntlComma;
+ if( cIntntlComma != cNonIntntlComma )
+ aSearchStr += cIntntlComma;
+ if( bOnlyIntntl )
+ aSearchStr += cIntntl1000;
+ const char* pSearchStr = aSearchStr.GetBuffer();
+ while( strchr( pSearchStr, *p ) && *p )
+ {
+ // 1000er-Trenner ueberlesen
+ if( bOnlyIntntl && *p == cIntntl1000 )
+ {
+ p++;
+ continue;
+ }
+
+ // Komma oder Exponent?
+ if( *p == cNonIntntlComma || *p == cIntntlComma )
+ {
+ // Immer '.' einfuegen, damit atof funktioniert
+ p++;
+ if( ++comma > 1 )
+ continue;
+ else
+ *q++ = '.';
+ }
+ else if( strchr( "DdEe", *p ) )
+ {
+ if( ++exp > 1 )
+ {
+ p++; continue;
+ }
+ if( toupper( *p ) == 'D' )
+ eScanType = SbxDOUBLE;
+ *q++ = 'E'; p++;
+ // Vorzeichen hinter Exponent?
+ if( *p == '+' )
+ p++;
+ else
+ if( *p == '-' )
+ *q++ = *p++;
+ }
+ else
+ {
+ *q++ = *p++;
+ if( comma && !exp ) ncdig++;
+ }
+ if( !exp ) ndig++;
+ }
+ *q = 0;
+ // Komma, Exponent mehrfach vorhanden?
+ if( comma > 1 || exp > 1 )
+ bRes = FALSE;
+ // Kann auf Integer gefaltet werden?
+ if( !comma && !exp )
+ {
+ if( nVal >= SbxMININT && nVal <= SbxMAXINT )
+ eScanType = SbxINTEGER;
+ else if( nVal >= SbxMINLNG && nVal <= SbxMAXLNG )
+ eScanType = SbxLONG;
+ }
+
+ nVal = atof( buf );
+ ndig = ndig - comma;
+ // zu viele Zahlen fuer SINGLE?
+ if( ndig > 15 || ncdig > 6 )
+ eScanType = SbxDOUBLE;
+
+ // Typkennung?
+ if( strchr( "%!&#", *p ) && *p ) p++;
+ }
+ // Hex/Oktalzahl? Einlesen und konvertieren:
+ else if( *p == '&' )
+ {
+ p++;
+ eScanType = SbxLONG;
+ const char *cmp = "0123456789ABCDEF";
+ char base = 16;
+ char ndig = 8;
+ char xch = *p++;
+ switch( toupper( xch ) )
+ {
+ case 'O': cmp = "01234567"; base = 8; ndig = 11; break;
+ case 'H': break;
+ default : bRes = FALSE;
+ }
+ long l = 0;
+ int i;
+ while( isalnum( *p ) )
+ {
+ char ch = sal::static_int_cast< char >( toupper( *p ) );
+ p++;
+ if( strchr( cmp, ch ) ) *q++ = ch;
+ else bRes = FALSE;
+ }
+ *q = 0;
+ for( q = buf; *q; q++ )
+ {
+ i =( *q & 0xFF ) - '0';
+ if( i > 9 ) i -= 7;
+ l =( l * base ) + i;
+ if( !ndig-- )
+ bRes = FALSE;
+ }
+ if( *p == '&' ) p++;
+ nVal = (double) l;
+ if( l >= SbxMININT && l <= SbxMAXINT )
+ eScanType = SbxINTEGER;
+ }
+ if( pLen )
+ *pLen = (USHORT) ( p - pStart );
+ if( !bRes )
+ return SbxERR_CONVERSION;
+ if( bMinus )
+ nVal = -nVal;
+ rType = eScanType;
+ return SbxERR_OK;
+}
+
+////////////////////////////////////////////////////////////////////////////
+
+static double roundArray[] = {
+ 5.0e+0, 0.5e+0, 0.5e-1, 0.5e-2, 0.5e-3, 0.5e-4, 0.5e-5, 0.5e-6, 0.5e-7,
+ 0.5e-8, 0.5e-9, 0.5e-10,0.5e-11,0.5e-12,0.5e-13,0.5e-14,0.5e-15 };
+
+/***************************************************************************
+|*
+|* void myftoa( double, char *, short, short, BOOL, BOOL )
+|*
+|* Beschreibung: Konversion double --> ASCII
+|* Parameter: double die Zahl.
+|* char * der Zielpuffer
+|* short Anzahl Nachkommastellen
+|* short Weite des Exponenten( 0=kein E )
+|* BOOL TRUE: mit 1000er Punkten
+|* BOOL TRUE: formatfreie Ausgabe
+|*
+***************************************************************************/
+
+static void myftoa( double nNum, char * pBuf, short nPrec, short nExpWidth,
+ BOOL bPt, BOOL bFix, sal_Unicode cForceThousandSep = 0 )
+{
+
+ short nExp = 0; // Exponent
+ short nDig = nPrec + 1; // Anzahl Digits in Zahl
+ short nDec; // Anzahl Vorkommastellen
+ register int i, digit;
+
+ // Komma besorgen
+ sal_Unicode cDecimalSep, cThousandSep;
+ ImpGetIntntlSep( cDecimalSep, cThousandSep );
+ if( cForceThousandSep )
+ cThousandSep = cForceThousandSep;
+
+ // Exponentberechnung:
+ nExp = 0;
+ if( nNum > 0.0 )
+ {
+ while( nNum < 1.0 ) nNum *= 10.0, nExp--;
+ while( nNum >= 10.0 ) nNum /= 10.0, nExp++;
+ }
+ if( !bFix && !nExpWidth )
+ nDig = nDig + nExp;
+ else if( bFix && !nPrec )
+ nDig = nExp + 1;
+
+ // Zahl runden:
+ if( (nNum += roundArray [( nDig > 16 ) ? 16 : nDig] ) >= 10.0 )
+ {
+ nNum = 1.0;
+ ++nExp;
+ if( !nExpWidth ) ++nDig;
+ }
+
+ // Bestimmung der Vorkommastellen:
+ if( !nExpWidth )
+ {
+ if( nExp < 0 )
+ {
+ // #41691: Auch bei bFix eine 0 spendieren
+ *pBuf++ = '0';
+ if( nPrec ) *pBuf++ = (char)cDecimalSep;
+ i = -nExp - 1;
+ if( nDig <= 0 ) i = nPrec;
+ while( i-- ) *pBuf++ = '0';
+ nDec = 0;
+ }
+ else
+ nDec = nExp+1;
+ }
+ else
+ nDec = 1;
+
+ // Zahl ausgeben:
+ if( nDig > 0 )
+ {
+ for( i = 0 ; ; ++i )
+ {
+ if( i < 16 )
+ {
+ digit = (int) nNum;
+ *pBuf++ = sal::static_int_cast< char >(digit + '0');
+ nNum =( nNum - digit ) * 10.0;
+ } else
+ *pBuf++ = '0';
+ if( --nDig == 0 ) break;
+ if( nDec )
+ {
+ nDec--;
+ if( !nDec )
+ *pBuf++ = (char)cDecimalSep;
+ else if( !(nDec % 3 ) && bPt )
+ *pBuf++ = (char)cThousandSep;
+ }
+ }
+ }
+
+ // Exponent ausgeben:
+ if( nExpWidth )
+ {
+ if( nExpWidth < 3 ) nExpWidth = 3;
+ nExpWidth -= 2;
+ *pBuf++ = 'E';
+ *pBuf++ =( nExp < 0 ) ?( (nExp = -nExp ), '-' ) : '+';
+ while( nExpWidth > 3 ) *pBuf++ = '0', nExpWidth--;
+ if( nExp >= 100 || nExpWidth == 3 )
+ {
+ *pBuf++ = sal::static_int_cast< char >(nExp/100 + '0');
+ nExp %= 100;
+ }
+ if( nExp/10 || nExpWidth >= 2 )
+ *pBuf++ = sal::static_int_cast< char >(nExp/10 + '0');
+ *pBuf++ = sal::static_int_cast< char >(nExp%10 + '0');
+ }
+ *pBuf = 0;
+}
+
+// Die Zahl wird unformatiert mit der angegebenen Anzahl NK-Stellen
+// aufbereitet. Evtl. wird ein Minus vorangestellt.
+// Diese Routine ist public, weil sie auch von den Put-Funktionen
+// der Klasse SbxImpSTRING verwendet wird.
+
+#ifdef _MSC_VER
+#pragma optimize( "", off )
+#pragma warning(disable: 4748) // "... because optimizations are disabled ..."
+#endif
+
+void ImpCvtNum( double nNum, short nPrec, XubString& rRes, BOOL bCoreString )
+{
+ char *q;
+ char cBuf[ 40 ], *p = cBuf;
+
+ sal_Unicode cDecimalSep, cThousandSep;
+ ImpGetIntntlSep( cDecimalSep, cThousandSep );
+ if( bCoreString )
+ cDecimalSep = '.';
+
+ if( nNum < 0.0 ) {
+ nNum = -nNum;
+ *p++ = '-';
+ }
+ double dMaxNumWithoutExp = (nPrec == 6) ? 1E6 : 1E14;
+ myftoa( nNum, p, nPrec,( nNum &&( nNum < 1E-1 || nNum > dMaxNumWithoutExp ) ) ? 4:0,
+ FALSE, TRUE, cDecimalSep );
+ // Trailing Zeroes weg:
+ for( p = cBuf; *p &&( *p != 'E' ); p++ ) {}
+ q = p; p--;
+ while( nPrec && *p == '0' ) nPrec--, p--;
+ if( *p == cDecimalSep ) p--;
+ while( *q ) *++p = *q++;
+ *++p = 0;
+ rRes = String::CreateFromAscii( cBuf );
+}
+
+#ifdef _MSC_VER
+#pragma optimize( "", on )
+#endif
+
+// Formatierte Zahlenausgabe
+// Der Returnwert ist die Anzahl Zeichen, die aus dem
+// Format verwendt wurden.
+
+#ifdef _old_format_code_
+// lasse diesen Code vorl"aufig drin, zum 'abgucken'
+// der bisherigen Implementation
+
+static USHORT printfmtnum( double nNum, XubString& rRes, const XubString& rWFmt )
+{
+ const String& rFmt = rWFmt;
+ char cFill = ' '; // Fuellzeichen
+ char cPre = 0; // Startzeichen( evtl. "$" )
+ short nExpDig= 0; // Anzahl Exponentstellen
+ short nPrec = 0; // Anzahl Nachkommastellen
+ short nWidth = 0; // Zahlenweite gesamnt
+ short nLen; // Laenge konvertierte Zahl
+ BOOL bPoint = FALSE; // TRUE: mit 1000er Kommas
+ BOOL bTrail = FALSE; // TRUE, wenn folgendes Minus
+ BOOL bSign = FALSE; // TRUE: immer mit Vorzeichen
+ BOOL bNeg = FALSE; // TRUE: Zahl ist negativ
+ char cBuf [1024]; // Zahlenpuffer
+ char * p;
+ const char* pFmt = rFmt;
+ rRes.Erase();
+ // $$ und ** abfangen. Einfach wird als Zeichen ausgegeben.
+ if( *pFmt == '$' )
+ if( *++pFmt != '$' ) rRes += '$';
+ if( *pFmt == '*' )
+ if( *++pFmt != '*' ) rRes += '*';
+
+ switch( *pFmt++ )
+ {
+ case 0:
+ break;
+ case '+':
+ bSign = TRUE; nWidth++; break;
+ case '*':
+ nWidth++; cFill = '*';
+ if( *pFmt == '$' ) nWidth++, pFmt++, cPre = '$';
+ break;
+ case '$':
+ nWidth++; cPre = '$'; break;
+ case '#':
+ case '.':
+ case ',':
+ pFmt--; break;
+ }
+ // Vorkomma:
+ for( ;; )
+ {
+ while( *pFmt == '#' ) pFmt++, nWidth++;
+ // 1000er Kommas?
+ if( *pFmt == ',' )
+ {
+ nWidth++; pFmt++; bPoint = TRUE;
+ } else break;
+ }
+ // Nachkomma:
+ if( *pFmt == '.' )
+ {
+ while( *++pFmt == '#' ) nPrec++;
+ nWidth += nPrec + 1;
+ }
+ // Exponent:
+ while( *pFmt == '^' )
+ pFmt++, nExpDig++, nWidth++;
+ // Folgendes Minus:
+ if( !bSign && *pFmt == '-' )
+ pFmt++, bTrail = TRUE;
+
+ // Zahl konvertieren:
+ if( nPrec > 15 ) nPrec = 15;
+ if( nNum < 0.0 ) nNum = -nNum, bNeg = TRUE;
+ p = cBuf;
+ if( bSign ) *p++ = bNeg ? '-' : '+';
+ myftoa( nNum, p, nPrec, nExpDig, bPoint, FALSE );
+ nLen = strlen( cBuf );
+
+ // Ueberlauf?
+ if( cPre ) nLen++;
+ if( nLen > nWidth ) rRes += '%';
+ else {
+ nWidth -= nLen;
+ while( nWidth-- ) rRes += (xub_Unicode)cFill;
+ if( cPre ) rRes += (xub_Unicode)cPre;
+ }
+ rRes += (xub_Unicode*)&(cBuf[0]);
+ if( bTrail )
+ rRes += bNeg ? '-' : ' ';
+
+ return (USHORT) ( pFmt - (const char*) rFmt );
+}
+
+#endif //_old_format_code_
+
+/////////////////////////////////////////////////////////////////////////
+
+BOOL SbxValue::Scan( const XubString& rSrc, USHORT* pLen )
+{
+ SbxError eRes = SbxERR_OK;
+ if( !CanWrite() )
+ eRes = SbxERR_PROP_READONLY;
+ else
+ {
+ double n;
+ SbxDataType t;
+ eRes = ImpScan( rSrc, n, t, pLen );
+ if( eRes == SbxERR_OK )
+ {
+ if( !IsFixed() )
+ SetType( t );
+ PutDouble( n );
+ }
+ }
+ if( eRes )
+ {
+ SetError( eRes ); return FALSE;
+ }
+ else
+ return TRUE;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/sbx/sbxsng.cxx b/binfilter/bf_basic/source/sbx/sbxsng.cxx
new file mode 100644
index 000000000000..7e5732d0f258
--- /dev/null
+++ b/binfilter/bf_basic/source/sbx/sbxsng.cxx
@@ -0,0 +1,363 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <tools/errcode.hxx>
+#include "sbx.hxx"
+#include "sbxconv.hxx"
+
+namespace binfilter {
+
+float ImpGetSingle( const SbxValues* p )
+{
+ SbxValues aTmp;
+ float nRes;
+start:
+ switch( +p->eType )
+ {
+ case SbxNULL:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ case SbxEMPTY:
+ nRes = 0; break;
+ case SbxCHAR:
+ nRes = p->nChar; break;
+ case SbxBYTE:
+ nRes = p->nByte; break;
+ case SbxINTEGER:
+ case SbxBOOL:
+ nRes = p->nInteger; break;
+ case SbxERROR:
+ case SbxUSHORT:
+ nRes = p->nUShort; break;
+ case SbxLONG:
+ nRes = (float) p->nLong; break;
+ case SbxULONG:
+ nRes = (float) p->nULong; break;
+ case SbxSINGLE:
+ nRes = p->nSingle; break;
+ case SbxSALINT64:
+ nRes = (float) p->nInt64; break;
+ case SbxSALUINT64:
+ nRes = (float) ImpSalUInt64ToDouble( p->uInt64 ); break;
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ if( p->pDecimal )
+ p->pDecimal->getSingle( nRes );
+ else
+ nRes = 0.0;
+ break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ case SbxLONG64:
+ case SbxULONG64:
+ case SbxCURRENCY:
+ {
+ double dVal;
+ if( p->eType == SbxCURRENCY )
+ dVal = ImpCurrencyToDouble( p->nLong64 );
+ else if( p->eType == SbxLONG64 )
+ dVal = ImpINT64ToDouble( p->nLong64 );
+ else if( p->eType == SbxULONG64 )
+ dVal = ImpUINT64ToDouble( p->nULong64 );
+ else
+ dVal = p->nDouble;
+
+ if( dVal > SbxMAXSNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW );
+ nRes = static_cast< float >(SbxMAXSNG);
+ }
+ else if( dVal < SbxMINSNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW );
+ nRes = static_cast< float >(SbxMINSNG);
+ }
+ else if( dVal > 0 && dVal < SbxMAXSNG2 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW );
+ nRes = static_cast< float >(SbxMAXSNG2);
+ }
+ else if( dVal < 0 && dVal > SbxMINSNG2 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW );
+ nRes = static_cast< float >(SbxMINSNG2);
+ }
+ else
+ nRes = (float) dVal;
+ break;
+ }
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ if( !p->pString )
+ nRes = 0;
+ else
+ {
+ double d;
+ SbxDataType t;
+ if( ImpScan( *p->pString, d, t, NULL ) != SbxERR_OK )
+ nRes = 0;
+ else if( d > SbxMAXSNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW );
+ nRes = static_cast< float >(SbxMAXSNG);
+ }
+ else if( d < SbxMINSNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW );
+ nRes = static_cast< float >(SbxMINSNG);
+ }
+ else
+ nRes = (float) d;
+ }
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ nRes = pVal->GetSingle();
+ else
+ {
+ SbxBase::SetError( SbxERR_NO_OBJECT ); nRes = 0;
+ }
+ break;
+ }
+
+ case SbxBYREF | SbxCHAR:
+ nRes = *p->pChar; break;
+ case SbxBYREF | SbxBYTE:
+ nRes = *p->pByte; break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ nRes = *p->pInteger; break;
+ case SbxBYREF | SbxLONG:
+ nRes = (float) *p->pLong; break;
+ case SbxBYREF | SbxULONG:
+ nRes = (float) *p->pULong; break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ nRes = *p->pUShort; break;
+ case SbxBYREF | SbxSINGLE:
+ nRes = *p->pSingle; break;
+ // ab hier muss getestet werden
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ aTmp.nDouble = *p->pDouble; goto ref;
+ case SbxBYREF | SbxULONG64:
+ aTmp.nULong64 = *p->pULong64; goto ref;
+ case SbxBYREF | SbxLONG64:
+ case SbxBYREF | SbxSALINT64:
+ nRes = (float) *p->pnInt64; break;
+ case SbxBYREF | SbxSALUINT64:
+ nRes = (float) ImpSalUInt64ToDouble( *p->puInt64 ); break;
+ case SbxBYREF | SbxCURRENCY:
+ aTmp.nLong64 = *p->pLong64; goto ref;
+ ref:
+ aTmp.eType = SbxDataType( p->eType & 0x0FFF );
+ p = &aTmp; goto start;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
+ }
+ return nRes;
+}
+
+void ImpPutSingle( SbxValues* p, float n )
+{
+ SbxValues aTmp;
+start:
+ switch( +p->eType )
+ {
+ case SbxCHAR:
+ aTmp.pChar = &p->nChar; goto direct;
+ case SbxBYTE:
+ aTmp.pByte = &p->nByte; goto direct;
+ case SbxINTEGER:
+ case SbxBOOL:
+ aTmp.pInteger = &p->nInteger; goto direct;
+ case SbxLONG:
+ aTmp.pLong = &p->nLong; goto direct;
+ case SbxULONG:
+ aTmp.pULong = &p->nULong; goto direct;
+ case SbxERROR:
+ case SbxUSHORT:
+ aTmp.pUShort = &p->nUShort; goto direct;
+ case SbxULONG64:
+ aTmp.pULong64 = &p->nULong64; goto direct;
+ case SbxLONG64:
+ case SbxCURRENCY:
+ aTmp.pLong64 = &p->nLong64; goto direct;
+ case SbxSALINT64:
+ aTmp.pnInt64 = &p->nInt64; goto direct;
+ case SbxSALUINT64:
+ aTmp.puInt64 = &p->uInt64; goto direct;
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ {
+ SbxDecimal* pDec = ImpCreateDecimal( p );
+ if( !pDec->setSingle( n ) )
+ SbxBase::SetError( SbxERR_OVERFLOW );
+ break;
+ }
+ direct:
+ aTmp.eType = SbxDataType( p->eType | SbxBYREF );
+ p = &aTmp; goto start;
+
+ // keine Tests ab hier
+ case SbxSINGLE:
+ p->nSingle = n; break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ p->nDouble = n; break;
+
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ {
+ if( !p->pString )
+ p->pString = new XubString;
+ ImpCvtNum( (double) n, 6, *p->pString );
+ break;
+ }
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ pVal->PutSingle( n );
+ else
+ SbxBase::SetError( SbxERR_NO_OBJECT );
+ break;
+ }
+ case SbxBYREF | SbxCHAR:
+ if( n > SbxMAXCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXCHAR;
+ }
+ else if( n < SbxMINCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINCHAR;
+ }
+ *p->pChar = (xub_Unicode) n; break;
+ case SbxBYREF | SbxBYTE:
+ if( n > SbxMAXBYTE )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXBYTE;
+ }
+ else if( n < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
+ }
+ *p->pByte = (BYTE) n; break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ if( n > SbxMAXINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXINT;
+ }
+ else if( n < SbxMININT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMININT;
+ }
+ *p->pInteger = (INT16) n; break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ if( n > SbxMAXUINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXUINT;
+ }
+ else if( n < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
+ }
+ *p->pUShort = (UINT16) n; break;
+ case SbxBYREF | SbxLONG:
+ {
+ INT32 i;
+ if( n > SbxMAXLNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); i = SbxMAXLNG;
+ }
+ else if( n < SbxMINLNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); i = SbxMINLNG;
+ }
+ else
+ {
+ i = sal::static_int_cast< INT32 >(n);
+ }
+ *p->pLong = i; break;
+ }
+ case SbxBYREF | SbxULONG:
+ {
+ UINT32 i;
+ if( n > SbxMAXULNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); i = SbxMAXULNG;
+ }
+ else if( n < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); i = 0;
+ }
+ else
+ {
+ i = sal::static_int_cast< UINT32 >(n);
+ }
+ *p->pULong = i; break;
+ }
+ case SbxBYREF | SbxSINGLE:
+ *p->pSingle = n; break;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ *p->pDouble = (double) n; break;
+ case SbxBYREF | SbxSALINT64:
+ *p->pnInt64 = ImpDoubleToSalInt64( (double) n ); break;
+ case SbxBYREF | SbxSALUINT64:
+ *p->puInt64 = ImpDoubleToSalUInt64( (double) n ); break;
+ case SbxBYREF | SbxCURRENCY:
+ double d;
+ if( n > SbxMAXCURR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); d = SbxMAXCURR;
+ }
+ else if( n < SbxMINCURR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); d = SbxMINCURR;
+ }
+ else
+ {
+ d = n;
+ }
+ *p->pLong64 = ImpDoubleToCurrency( n ); break;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/sbx/sbxstr.cxx b/binfilter/bf_basic/source/sbx/sbxstr.cxx
new file mode 100644
index 000000000000..193d9a99bc11
--- /dev/null
+++ b/binfilter/bf_basic/source/sbx/sbxstr.cxx
@@ -0,0 +1,246 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <tools/errcode.hxx>
+#include "sbx.hxx"
+#include "sbxconv.hxx"
+#include "sbxres.hxx"
+
+namespace binfilter {
+
+// Die Konversion eines Items auf String wird ueber die Put-Methoden
+// der einzelnen Datentypen abgewickelt, um doppelten Code zu vermeiden.
+
+XubString ImpGetString( const SbxValues* p )
+{
+ SbxValues aTmp;
+ XubString aRes;
+ aTmp.eType = SbxSTRING;
+ aTmp.pString = &aRes;
+ switch( +p->eType )
+ {
+ case SbxNULL:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ case SbxEMPTY:
+ break;
+ case SbxCHAR:
+ ImpPutChar( &aTmp, p->nChar ); break;
+ case SbxBYTE:
+ ImpPutByte( &aTmp, p->nByte ); break;
+ case SbxINTEGER:
+ ImpPutInteger( &aTmp, p->nInteger ); break;
+ case SbxBOOL:
+ ImpPutBool( &aTmp, p->nUShort ); break;
+ case SbxUSHORT:
+ ImpPutUShort( &aTmp, p->nUShort ); break;
+ case SbxLONG:
+ ImpPutLong( &aTmp, p->nLong ); break;
+ case SbxULONG:
+ ImpPutULong( &aTmp, p->nULong ); break;
+ case SbxSINGLE:
+ ImpPutSingle( &aTmp, p->nSingle ); break;
+ case SbxDOUBLE:
+ ImpPutDouble( &aTmp, p->nDouble ); break;
+ case SbxCURRENCY:
+ ImpPutCurrency( &aTmp, p->nLong64 ); break;
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ ImpPutDecimal( &aTmp, p->pDecimal ); break;
+ case SbxSALINT64:
+ ImpPutInt64( &aTmp, p->nInt64 ); break;
+ case SbxSALUINT64:
+ ImpPutUInt64( &aTmp, p->uInt64 ); break;
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ if( p->pString )
+ aRes = *p->pString;
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ aRes = pVal->GetString();
+ else
+ SbxBase::SetError( SbxERR_NO_OBJECT );
+ break;
+ }
+ case SbxERROR:
+ // Hier wird der String "Error n" erzeugt
+ aRes = SbxRes( STRING_ERRORMSG );
+ aRes += p->nUShort; break;
+ case SbxDATE:
+ ImpPutDate( &aTmp, p->nDouble ); break;
+
+ case SbxBYREF | SbxCHAR:
+ ImpPutChar( &aTmp, *p->pChar ); break;
+ case SbxBYREF | SbxBYTE:
+ ImpPutByte( &aTmp, *p->pByte ); break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ ImpPutInteger( &aTmp, *p->pInteger ); break;
+ case SbxBYREF | SbxLONG:
+ ImpPutLong( &aTmp, *p->pLong ); break;
+ case SbxBYREF | SbxULONG:
+ ImpPutULong( &aTmp, *p->pULong ); break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ ImpPutUShort( &aTmp, *p->pUShort ); break;
+ case SbxBYREF | SbxSINGLE:
+ ImpPutSingle( &aTmp, *p->pSingle ); break;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ ImpPutDouble( &aTmp, *p->pDouble ); break;
+ case SbxBYREF | SbxCURRENCY:
+ ImpPutCurrency( &aTmp, *p->pLong64 ); break;
+ case SbxBYREF | SbxSALINT64:
+ ImpPutInt64( &aTmp, *p->pnInt64 ); break;
+ case SbxBYREF | SbxSALUINT64:
+ ImpPutUInt64( &aTmp, *p->puInt64 ); break;
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ }
+ return aRes;
+}
+
+// AB 10.4.97, neue Funktion fuer SbxValue::GetCoreString()
+XubString ImpGetCoreString( const SbxValues* p )
+{
+ // Vorerst nur fuer double
+ if( ( p->eType & (~SbxBYREF) ) == SbxDOUBLE )
+ {
+ SbxValues aTmp;
+ XubString aRes;
+ aTmp.eType = SbxSTRING;
+ aTmp.pString = &aRes;
+ if( p->eType == SbxDOUBLE )
+ ImpPutDouble( &aTmp, p->nDouble, /*bCoreString=*/TRUE );
+ else
+ ImpPutDouble( &aTmp, *p->pDouble, /*bCoreString=*/TRUE );
+ return aRes;
+ }
+ else
+ return ImpGetString( p );
+}
+
+void ImpPutString( SbxValues* p, const XubString* n )
+{
+ SbxValues aTmp;
+ aTmp.eType = SbxSTRING;
+ XubString* pTmp = NULL;
+ // Sicherheitshalber, falls ein NULL-Ptr kommt
+ if( !n )
+ n = pTmp = new XubString;
+ aTmp.pString = (XubString*) n;
+ switch( +p->eType )
+ {
+ case SbxCHAR:
+ p->nChar = ImpGetChar( &aTmp ); break;
+ case SbxBYTE:
+ p->nByte = ImpGetByte( &aTmp ); break;
+ case SbxINTEGER:
+ case SbxBOOL:
+ p->nInteger = ImpGetInteger( &aTmp ); break;
+ case SbxLONG:
+ p->nLong = ImpGetLong( &aTmp ); break;
+ case SbxULONG:
+ p->nULong = ImpGetULong( &aTmp ); break;
+ case SbxERROR:
+ case SbxUSHORT:
+ p->nUShort = ImpGetUShort( &aTmp ); break;
+ case SbxSINGLE:
+ p->nSingle = ImpGetSingle( &aTmp ); break;
+ case SbxDATE:
+ p->nDouble = ImpGetDate( &aTmp ); break;
+ case SbxDOUBLE:
+ p->nDouble = ImpGetDouble( &aTmp ); break;
+ case SbxULONG64:
+ p->nLong64 = ImpGetCurrency( &aTmp ); break;
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ releaseDecimalPtr( p->pDecimal );
+ p->pDecimal = ImpGetDecimal( &aTmp ); break;
+ case SbxSALINT64:
+ p->nInt64 = ImpGetInt64( &aTmp ); break;
+ case SbxSALUINT64:
+ p->uInt64 = ImpGetUInt64( &aTmp ); break;
+
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ if( n->Len() )
+ {
+ if( !p->pString )
+ p->pString = new XubString;
+ *p->pString = *n;
+ }
+ else
+ delete p->pString, p->pString = NULL;
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ pVal->PutString( *n );
+ else
+ SbxBase::SetError( SbxERR_NO_OBJECT );
+ break;
+ }
+ case SbxBYREF | SbxCHAR:
+ *p->pChar = ImpGetChar( p ); break;
+ case SbxBYREF | SbxBYTE:
+ *p->pByte = ImpGetByte( p ); break;
+ case SbxBYREF | SbxINTEGER:
+ *p->pInteger = ImpGetInteger( p ); break;
+ case SbxBYREF | SbxBOOL:
+ *p->pUShort = sal::static_int_cast< UINT16 >( ImpGetBool( p ) );
+ break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ *p->pUShort = ImpGetUShort( p ); break;
+ case SbxBYREF | SbxLONG:
+ *p->pLong = ImpGetLong( p ); break;
+ case SbxBYREF | SbxULONG:
+ *p->pULong = ImpGetULong( p ); break;
+ case SbxBYREF | SbxSINGLE:
+ *p->pSingle = ImpGetSingle( p ); break;
+ case SbxBYREF | SbxDATE:
+ *p->pDouble = ImpGetDate( p ); break;
+ case SbxBYREF | SbxDOUBLE:
+ *p->pDouble = ImpGetDouble( p ); break;
+ case SbxBYREF | SbxCURRENCY:
+ *p->pLong64 = ImpGetCurrency( p ); break;
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ }
+ delete pTmp;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/sbx/sbxuint.cxx b/binfilter/bf_basic/source/sbx/sbxuint.cxx
new file mode 100644
index 000000000000..9eb3d0cbf2fb
--- /dev/null
+++ b/binfilter/bf_basic/source/sbx/sbxuint.cxx
@@ -0,0 +1,335 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <tools/errcode.hxx>
+#include "sbx.hxx"
+#include "sbxconv.hxx"
+
+namespace binfilter {
+
+UINT16 ImpGetUShort( const SbxValues* p )
+{
+ SbxValues aTmp;
+ UINT16 nRes;
+start:
+ switch( +p->eType )
+ {
+ case SbxNULL:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ case SbxEMPTY:
+ nRes = 0; break;
+ case SbxCHAR:
+ nRes = p->nChar;
+ break;
+ case SbxBYTE:
+ nRes = p->nByte; break;
+ case SbxINTEGER:
+ case SbxBOOL:
+ if( p->nInteger < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
+ }
+ else
+ nRes = p->nInteger;
+ break;
+ case SbxERROR:
+ case SbxUSHORT:
+ nRes = p->nUShort;
+ break;
+ case SbxLONG:
+ if( p->nLong > SbxMAXUINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXUINT;
+ }
+ else if( p->nLong < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
+ }
+ else
+ nRes = (UINT16) p->nLong;
+ break;
+ case SbxULONG:
+ if( p->nULong > SbxMAXUINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXUINT;
+ }
+ else
+ nRes = (UINT16) p->nULong;
+ break;
+ case SbxSALINT64:
+ if( p->nInt64 > SbxMAXUINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXUINT;
+ }
+ else if( p->nInt64 < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
+ }
+ else
+ nRes = (UINT16) p->nInt64;
+ break;
+ case SbxSALUINT64:
+ if( p->uInt64 > SbxMAXUINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXUINT;
+ }
+ else
+ nRes = (UINT16) p->uInt64;
+ break;
+ case SbxSINGLE:
+ if( p->nSingle > SbxMAXUINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXUINT;
+ }
+ else if( p->nSingle < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
+ }
+ else
+ nRes = (UINT16) ( p->nSingle + 0.5 );
+ break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ case SbxLONG64:
+ case SbxULONG64:
+ case SbxCURRENCY:
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ {
+ double dVal;
+ if( p->eType == SbxCURRENCY )
+ dVal = ImpCurrencyToDouble( p->nLong64 );
+ else if( p->eType == SbxLONG64 )
+ dVal = ImpINT64ToDouble( p->nLong64 );
+ else if( p->eType == SbxULONG64 )
+ dVal = ImpUINT64ToDouble( p->nULong64 );
+ else if( p->eType == SbxDECIMAL )
+ {
+ dVal = 0.0;
+ if( p->pDecimal )
+ p->pDecimal->getDouble( dVal );
+ }
+ else
+ dVal = p->nDouble;
+
+ if( dVal > SbxMAXUINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXUINT;
+ }
+ else if( dVal < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
+ }
+ else
+ nRes = (UINT16) ( dVal + 0.5 );
+ break;
+ }
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ if( !p->pString )
+ nRes = 0;
+ else
+ {
+ double d;
+ SbxDataType t;
+ if( ImpScan( *p->pString, d, t, NULL ) != SbxERR_OK )
+ nRes = 0;
+ else if( d > SbxMAXUINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXUINT;
+ }
+ else if( d < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
+ }
+ else
+ nRes = (UINT16) ( d + 0.5 );
+ }
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ nRes = pVal->GetUShort();
+ else
+ {
+ SbxBase::SetError( SbxERR_NO_OBJECT ); nRes = 0;
+ }
+ break;
+ }
+
+ case SbxBYREF | SbxBYTE:
+ nRes = *p->pByte; break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ nRes = *p->pUShort; break;
+
+ // ab hier wird getestet
+ case SbxBYREF | SbxCHAR:
+ aTmp.nChar = *p->pChar; goto ref;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ aTmp.nInteger = *p->pInteger; goto ref;
+ case SbxBYREF | SbxLONG:
+ aTmp.nLong = *p->pLong; goto ref;
+ case SbxBYREF | SbxULONG:
+ aTmp.nULong = *p->pULong; goto ref;
+ case SbxBYREF | SbxSINGLE:
+ aTmp.nSingle = *p->pSingle; goto ref;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ aTmp.nDouble = *p->pDouble; goto ref;
+ case SbxBYREF | SbxULONG64:
+ aTmp.nULong64 = *p->pULong64; goto ref;
+ case SbxBYREF | SbxLONG64:
+ case SbxBYREF | SbxCURRENCY:
+ aTmp.nLong64 = *p->pLong64; goto ref;
+ case SbxBYREF | SbxSALINT64:
+ aTmp.nInt64 = *p->pnInt64; goto ref;
+ case SbxBYREF | SbxSALUINT64:
+ aTmp.uInt64 = *p->puInt64; goto ref;
+ ref:
+ aTmp.eType = SbxDataType( p->eType & 0x0FFF );
+ p = &aTmp; goto start;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
+ }
+ return nRes;
+}
+
+void ImpPutUShort( SbxValues* p, UINT16 n )
+{
+ SbxValues aTmp;
+
+start:
+ switch( +p->eType )
+ {
+ case SbxERROR:
+ case SbxUSHORT:
+ p->nUShort = n; break;
+ case SbxLONG:
+ p->nLong = n; break;
+ case SbxULONG:
+ p->nULong = n; break;
+ case SbxSINGLE:
+ p->nSingle = n; break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ p->nDouble = n; break;
+ case SbxSALINT64:
+ p->nInt64 = n; break;
+ case SbxSALUINT64:
+ p->uInt64 = n; break;
+ case SbxULONG64:
+ p->nULong64 = ImpDoubleToUINT64( (double)n ); break;
+ case SbxLONG64:
+ p->nLong64 = ImpDoubleToINT64( (double)n ); break;
+ case SbxCURRENCY:
+ p->nLong64 = ImpDoubleToCurrency( (double)n ); break;
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ ImpCreateDecimal( p )->setUInt( n );
+ break;
+
+ // Tests ab hier
+ case SbxCHAR:
+ aTmp.pChar = &p->nChar; goto direct;
+ case SbxBYTE:
+ aTmp.pByte = &p->nByte; goto direct;
+ case SbxINTEGER:
+ case SbxBOOL:
+ aTmp.pInteger = &p->nInteger;
+ direct:
+ aTmp.eType = SbxDataType( p->eType | SbxBYREF );
+ p = &aTmp; goto start;
+
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ if( !p->pString )
+ p->pString = new XubString;
+ ImpCvtNum( (double) n, 0, *p->pString );
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ pVal->PutUShort( n );
+ else
+ SbxBase::SetError( SbxERR_NO_OBJECT );
+ break;
+ }
+
+ case SbxBYREF | SbxCHAR:
+ *p->pChar = (xub_Unicode) n; break;
+ case SbxBYREF | SbxBYTE:
+ if( n > SbxMAXBYTE )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXBYTE;
+ }
+ *p->pByte = (BYTE) n; break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ if( n > SbxMAXINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXINT;
+ }
+ *p->pInteger = (INT16) n; break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ *p->pUShort = n; break;
+ case SbxBYREF | SbxLONG:
+ *p->pLong = n; break;
+ case SbxBYREF | SbxULONG:
+ *p->pULong = n; break;
+ case SbxBYREF | SbxSINGLE:
+ *p->pSingle = n; break;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ *p->pDouble = n; break;
+ case SbxBYREF | SbxSALINT64:
+ *p->pnInt64 = n; break;
+ case SbxBYREF | SbxSALUINT64:
+ *p->puInt64 = n; break;
+ case SbxBYREF | SbxULONG64:
+ *p->pULong64 = ImpDoubleToUINT64( (double)n ); break;
+ case SbxBYREF | SbxLONG64:
+ *p->pLong64 = ImpDoubleToINT64( (double)n ); break;
+ case SbxBYREF | SbxCURRENCY:
+ *p->pLong64 = ImpDoubleToCurrency( (double)n ); break;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/sbx/sbxulng.cxx b/binfilter/bf_basic/source/sbx/sbxulng.cxx
new file mode 100644
index 000000000000..da49619667a1
--- /dev/null
+++ b/binfilter/bf_basic/source/sbx/sbxulng.cxx
@@ -0,0 +1,325 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <tools/errcode.hxx>
+#include "sbx.hxx"
+#include "sbxconv.hxx"
+
+namespace binfilter {
+
+UINT32 ImpGetULong( const SbxValues* p )
+{
+ SbxValues aTmp;
+ UINT32 nRes;
+start:
+ switch( +p->eType )
+ {
+ case SbxNULL:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ case SbxEMPTY:
+ nRes = 0; break;
+ case SbxCHAR:
+ nRes = p->nChar;
+ break;
+ case SbxBYTE:
+ nRes = p->nByte; break;
+ case SbxINTEGER:
+ case SbxBOOL:
+ if( p->nInteger < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
+ }
+ else
+ nRes = p->nInteger;
+ break;
+ case SbxERROR:
+ case SbxUSHORT:
+ nRes = p->nUShort;
+ break;
+ case SbxLONG:
+ if( p->nLong < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
+ }
+ else
+ nRes = p->nLong;
+ break;
+ case SbxULONG:
+ nRes = p->nULong; break;
+ case SbxSINGLE:
+ if( p->nSingle > SbxMAXULNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXULNG;
+ }
+ else if( p->nSingle < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
+ }
+ else
+ nRes = (UINT32) ( p->nSingle + 0.5 );
+ break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ case SbxLONG64:
+ case SbxULONG64:
+ case SbxSALINT64:
+ case SbxSALUINT64:
+ case SbxCURRENCY:
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ {
+ double dVal;
+ if( p->eType == SbxCURRENCY )
+ dVal = ImpCurrencyToDouble( p->nLong64 );
+ else if( p->eType == SbxLONG64 )
+ dVal = ImpINT64ToDouble( p->nLong64 );
+ else if( p->eType == SbxULONG64 )
+ dVal = ImpUINT64ToDouble( p->nULong64 );
+ else if( p->eType == SbxSALINT64 )
+ dVal = static_cast< double >(p->nInt64);
+ else if( p->eType == SbxSALUINT64 )
+ dVal = ImpSalUInt64ToDouble( p->uInt64 );
+ else if( p->eType == SbxDECIMAL )
+ {
+ dVal = 0.0;
+ if( p->pDecimal )
+ p->pDecimal->getDouble( dVal );
+ }
+ else
+ dVal = p->nDouble;
+
+ if( dVal > SbxMAXULNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXULNG;
+ }
+ else if( dVal < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
+ }
+ else
+ nRes = (UINT32) ( dVal + 0.5 );
+ break;
+ }
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ if( !p->pString )
+ nRes = 0;
+ else
+ {
+ double d;
+ SbxDataType t;
+ if( ImpScan( *p->pString, d, t, NULL ) != SbxERR_OK )
+ nRes = 0;
+ else if( d > SbxMAXULNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = SbxMAXULNG;
+ }
+ else if( d < 0 )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); nRes = 0;
+ }
+ else
+ nRes = (UINT32) ( d + 0.5 );
+ }
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ nRes = pVal->GetULong();
+ else
+ {
+ SbxBase::SetError( SbxERR_NO_OBJECT ); nRes = 0;
+ }
+ break;
+ }
+
+ case SbxBYREF | SbxBYTE:
+ nRes = *p->pByte; break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ nRes = *p->pUShort; break;
+ case SbxBYREF | SbxULONG:
+ nRes = *p->pULong; break;
+
+ // Tests ab hier
+ case SbxBYREF | SbxCHAR:
+ aTmp.nChar = *p->pChar; goto ref;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ aTmp.nInteger = *p->pInteger; goto ref;
+ case SbxBYREF | SbxLONG:
+ aTmp.nLong = *p->pLong; goto ref;
+ case SbxBYREF | SbxSINGLE:
+ aTmp.nSingle = *p->pSingle; goto ref;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ aTmp.nDouble = *p->pDouble; goto ref;
+ case SbxBYREF | SbxSALINT64:
+ aTmp.nInt64 = *p->pnInt64; goto ref;
+ case SbxBYREF | SbxSALUINT64:
+ aTmp.uInt64 = *p->puInt64; goto ref;
+ case SbxBYREF | SbxULONG64:
+ aTmp.nULong64 = *p->pULong64; goto ref;
+ case SbxBYREF | SbxLONG64:
+ case SbxBYREF | SbxCURRENCY:
+ aTmp.nLong64 = *p->pLong64; goto ref;
+ ref:
+ aTmp.eType = SbxDataType( p->eType & 0x0FFF );
+ p = &aTmp; goto start;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
+ }
+ return nRes;
+}
+
+void ImpPutULong( SbxValues* p, UINT32 n )
+{
+ SbxValues aTmp;
+start:
+ switch( +p->eType )
+ {
+ case SbxULONG:
+ p->nULong = n; break;
+ case SbxSINGLE:
+ p->nSingle = (float) n; break;
+ case SbxDATE:
+ case SbxDOUBLE:
+ p->nDouble = n; break;
+ case SbxSALINT64:
+ p->nInt64 = n; break;
+ case SbxSALUINT64:
+ p->uInt64 = n; break;
+ case SbxDECIMAL:
+ case SbxBYREF | SbxDECIMAL:
+ ImpCreateDecimal( p )->setULong( n );
+ break;
+
+ // Tests ab hier
+ case SbxCHAR:
+ aTmp.pChar = &p->nChar; goto direct;
+ case SbxUINT:
+ aTmp.pByte = &p->nByte; goto direct;
+ case SbxINTEGER:
+ case SbxBOOL:
+ aTmp.pInteger = &p->nInteger; goto direct;
+ case SbxLONG:
+ aTmp.pLong = &p->nLong; goto direct;
+ case SbxERROR:
+ case SbxUSHORT:
+ aTmp.pUShort = &p->nUShort; goto direct;
+ case SbxULONG64:
+ aTmp.pULong64 = &p->nULong64; goto direct;
+ case SbxLONG64:
+ case SbxCURRENCY:
+ aTmp.pLong64 = &p->nLong64; goto direct;
+ direct:
+ aTmp.eType = SbxDataType( p->eType | SbxBYREF );
+ p = &aTmp; goto start;
+
+ case SbxBYREF | SbxSTRING:
+ case SbxSTRING:
+ case SbxLPSTR:
+ if( !p->pString )
+ p->pString = new XubString;
+ ImpCvtNum( (double) n, 0, *p->pString );
+ break;
+ case SbxOBJECT:
+ {
+ SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
+ if( pVal )
+ pVal->PutULong( n );
+ else
+ SbxBase::SetError( SbxERR_NO_OBJECT );
+ break;
+ }
+ case SbxBYREF | SbxCHAR:
+ if( n > SbxMAXCHAR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXCHAR;
+ }
+ *p->pChar = (xub_Unicode) n; break;
+ case SbxBYREF | SbxBYTE:
+ if( n > SbxMAXBYTE )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXBYTE;
+ }
+ *p->pByte = (BYTE) n; break;
+ case SbxBYREF | SbxINTEGER:
+ case SbxBYREF | SbxBOOL:
+ if( n > SbxMAXINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXINT;
+ }
+ *p->pInteger = (INT16) n; break;
+ case SbxBYREF | SbxERROR:
+ case SbxBYREF | SbxUSHORT:
+ if( n > SbxMAXUINT )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXUINT;
+ }
+ *p->pUShort = (UINT16) n; break;
+ case SbxBYREF | SbxLONG:
+ if( n > SbxMAXLNG )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXLNG;
+ }
+ *p->pLong = (INT32) n; break;
+ case SbxBYREF | SbxULONG:
+ *p->pULong = n; break;
+ case SbxBYREF | SbxSINGLE:
+ *p->pSingle = (float) n; break;
+ case SbxBYREF | SbxDATE:
+ case SbxBYREF | SbxDOUBLE:
+ *p->pDouble = n; break;
+ case SbxBYREF | SbxSALINT64:
+ *p->pnInt64 = n; break;
+ case SbxBYREF | SbxSALUINT64:
+ *p->puInt64 = n; break;
+ case SbxBYREF | SbxCURRENCY:
+ double d;
+ if( n > SbxMAXCURR )
+ {
+ SbxBase::SetError( SbxERR_OVERFLOW ); d = SbxMAXCURR;
+ }
+ else
+ {
+ d = n;
+ }
+ *p->pLong64 = ImpDoubleToCurrency( n ); break;
+
+ default:
+ SbxBase::SetError( SbxERR_CONVERSION );
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/sbx/sbxvalue.cxx b/binfilter/bf_basic/source/sbx/sbxvalue.cxx
new file mode 100644
index 000000000000..5c88a1218706
--- /dev/null
+++ b/binfilter/bf_basic/source/sbx/sbxvalue.cxx
@@ -0,0 +1,1710 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#define _TLBIGINT_INT64
+#include <tools/bigint.hxx>
+#include <tools/stream.hxx>
+
+#include "sbx.hxx"
+#include "sbxconv.hxx"
+#include <math.h>
+
+namespace binfilter {
+
+TYPEINIT1(SbxValue,SbxBase)
+
+BigInt SbxINT64Converter::SbxINT64_2_BigInt( const SbxINT64 &r )
+{
+ BigInt a10000 = 0x10000;
+
+ BigInt aReturn( r.nHigh );
+ if( r.nHigh )
+ aReturn *= a10000;
+ aReturn += (USHORT)(r.nLow >> 16);
+ aReturn *= a10000;
+ aReturn += (USHORT)r.nLow;
+ return aReturn;
+}
+
+BOOL SbxINT64Converter::BigInt_2_SbxINT64( const BigInt& b, SbxINT64 *p )
+{
+ if( !b.IsLong() ) {
+ if( b.nLen > 4 || (b.nNum[3] & 0x8000) )
+ return FALSE;
+
+ p->nLow = ((UINT32)b.nNum[1] << 16) | (UINT32)b.nNum[0];
+ p->nHigh = ((UINT32)b.nNum[3] << 16) | (UINT32)b.nNum[2];
+ if( b.bIsNeg )
+ p->CHS();
+ }
+ else
+ p->Set( (INT32)b.nVal );
+
+ return TRUE;
+}
+
+BigInt SbxINT64Converter::SbxUINT64_2_BigInt( const SbxUINT64 &r )
+{
+ BigInt a10000 = 0x10000;
+
+ BigInt aReturn(r.nHigh);
+ if( r.nHigh )
+ aReturn *= a10000;
+ aReturn += (USHORT)(r.nLow >> 16);
+ aReturn *= a10000;
+ aReturn += (USHORT)r.nLow;
+ return aReturn;
+}
+
+BOOL SbxINT64Converter::BigInt_2_SbxUINT64( const BigInt& b, SbxUINT64 *p )
+{
+ if( b.bIsBig ) {
+ if( b.bIsNeg || b.nLen > 4 )
+ return FALSE;
+
+ p->nLow = ((UINT32)b.nNum[1] << 16) | (UINT32)b.nNum[0];
+ p->nHigh = ((UINT32)b.nNum[3] << 16) | (UINT32)b.nNum[2];
+ }
+ else {
+ if( b.nVal < 0 )
+ return FALSE;
+
+ p->Set( (UINT32)b.nVal );
+ }
+
+ return TRUE;
+}
+
+/////////////////////////// SbxINT64 /////////////////////////////////////
+SbxINT64 &SbxINT64::operator -= ( const SbxINT64 &r )
+{
+ BigInt b( SbxINT64Converter::SbxINT64_2_BigInt( *this ) );
+ b -= SbxINT64Converter::SbxINT64_2_BigInt( r );
+ SbxINT64Converter::BigInt_2_SbxINT64( b, this );
+ return *this;
+}
+SbxINT64 &SbxINT64::operator += ( const SbxINT64 &r )
+{
+ BigInt b( SbxINT64Converter::SbxINT64_2_BigInt( *this ) );
+ b += SbxINT64Converter::SbxINT64_2_BigInt( r );
+ SbxINT64Converter::BigInt_2_SbxINT64( b, this );
+ return *this;
+}
+SbxINT64 &SbxINT64::operator *= ( const SbxINT64 &r )
+{
+ BigInt b( SbxINT64Converter::SbxINT64_2_BigInt( *this ) );
+ b *= SbxINT64Converter::SbxINT64_2_BigInt( r );
+ SbxINT64Converter::BigInt_2_SbxINT64( b, this );
+ return *this;
+}
+SbxINT64 &SbxINT64::operator %= ( const SbxINT64 &r )
+{
+ BigInt b( SbxINT64Converter::SbxINT64_2_BigInt( *this ) );
+ b %= SbxINT64Converter::SbxINT64_2_BigInt( r );
+ SbxINT64Converter::BigInt_2_SbxINT64( b, this );
+ return *this;
+}
+SbxINT64 &SbxINT64::operator /= ( const SbxINT64 &r )
+{
+ BigInt b( SbxINT64Converter::SbxINT64_2_BigInt( *this ) );
+ b /= SbxINT64Converter::SbxINT64_2_BigInt( r );
+ SbxINT64Converter::BigInt_2_SbxINT64( b, this );
+ return *this;
+}
+SbxINT64 &SbxINT64::operator &= ( const SbxINT64 &r )
+{
+ nHigh &= r.nHigh;
+ nLow &= r.nLow;
+ return *this;
+}
+SbxINT64 &SbxINT64::operator |= ( const SbxINT64 &r )
+{
+ nHigh |= r.nHigh;
+ nLow |= r.nLow;
+ return *this;
+}
+SbxINT64 &SbxINT64::operator ^= ( const SbxINT64 &r )
+{
+ nHigh ^= r.nHigh;
+ nLow ^= r.nLow;
+ return *this;
+}
+
+SbxINT64 operator - ( const SbxINT64 &l, const SbxINT64 &r )
+{
+ SbxINT64 a(l);
+ a -= r;
+ return a;
+}
+SbxINT64 operator + ( const SbxINT64 &l, const SbxINT64 &r )
+{
+ SbxINT64 a(l);
+ a += r;
+ return a;
+}
+SbxINT64 operator / ( const SbxINT64 &l, const SbxINT64 &r )
+{
+ SbxINT64 a(l);
+ a /= r;
+ return a;
+}
+SbxINT64 operator % ( const SbxINT64 &l, const SbxINT64 &r )
+{
+ SbxINT64 a(l);
+ a %= r;
+ return a;
+}
+SbxINT64 operator * ( const SbxINT64 &l, const SbxINT64 &r )
+{
+ SbxINT64 a(l);
+ a *= r;
+ return a;
+}
+SbxINT64 operator & ( const SbxINT64 &l, const SbxINT64 &r )
+{
+ SbxINT64 a;
+ a.nHigh = r.nHigh & l.nHigh;
+ a.nLow = r.nLow & l.nLow;
+ return a;
+}
+SbxINT64 operator | ( const SbxINT64 &l, const SbxINT64 &r )
+{
+ SbxINT64 a;
+ a.nHigh = r.nHigh | l.nHigh;
+ a.nLow = r.nLow | l.nLow;
+ return a;
+}
+SbxINT64 operator ^ ( const SbxINT64 &r, const SbxINT64 &l )
+{
+ SbxINT64 a;
+ a.nHigh = r.nHigh ^ l.nHigh;
+ a.nLow = r.nLow ^ l.nLow;
+ return a;
+}
+
+SbxINT64 operator - ( const SbxINT64 &r )
+{
+ SbxINT64 a( r );
+ a.CHS();
+ return a;
+}
+SbxINT64 operator ~ ( const SbxINT64 &r )
+{
+ SbxINT64 a;
+ a.nHigh = ~r.nHigh;
+ a.nLow = ~r.nLow;
+ return a;
+}
+
+SbxUINT64 &SbxUINT64::operator %= ( const SbxUINT64 &r )
+{
+ BigInt b( SbxINT64Converter::SbxUINT64_2_BigInt( *this ) );
+ b %= SbxINT64Converter::SbxUINT64_2_BigInt( r );
+ SbxINT64Converter::BigInt_2_SbxUINT64( b, this );
+ return *this;
+}
+SbxUINT64 &SbxUINT64::operator /= ( const SbxUINT64 &r )
+{
+ BigInt b( SbxINT64Converter::SbxUINT64_2_BigInt( *this ) );
+ b /= SbxINT64Converter::SbxUINT64_2_BigInt( r );
+ SbxINT64Converter::BigInt_2_SbxUINT64( b, this );
+ return *this;
+}
+/////////////////////////// Fehlerbehandlung /////////////////////////////
+
+#ifdef _USED
+// NOCH NACHZUBAUEN!
+
+// Das Default-Handling setzt nur den Fehlercode.
+
+#ifndef WNT
+#if defined ( UNX )
+int matherr( struct exception* p )
+#else
+int matherr( struct _exception* p )
+#endif
+{
+ switch( p->type )
+ {
+#if defined ( UNX )
+ case OVERFLOW: SbxBase::SetError( SbxERR_OVERFLOW ); break;
+#else
+ case _OVERFLOW: SbxBase::SetError( SbxERR_OVERFLOW ); break;
+#endif
+ default: SbxBase::SetError( SbxERR_NOTIMP ); break;
+ }
+ return TRUE;
+}
+#endif
+
+#endif // _USED
+
+
+///////////////////////////// Konstruktoren //////////////////////////////
+
+SbxValue::SbxValue() : SbxBase()
+{
+ aData.eType = SbxEMPTY;
+}
+
+SbxValue::SbxValue( SbxDataType t, void* p ) : SbxBase()
+{
+ int n = t & 0x0FFF;
+ if( p )
+ n |= SbxBYREF;
+ if( n == SbxVARIANT )
+ n = SbxEMPTY;
+ else
+ SetFlag( SBX_FIXED );
+ if( p )
+ switch( t & 0x0FFF )
+ {
+ case SbxINTEGER: n |= SbxBYREF; aData.pInteger = (INT16*) p; break;
+ case SbxULONG64: n |= SbxBYREF; aData.pULong64 = (SbxUINT64*) p; break;
+ case SbxLONG64:
+ case SbxCURRENCY: n |= SbxBYREF; aData.pLong64 = (SbxINT64*) p; break;
+ case SbxLONG: n |= SbxBYREF; aData.pLong = (INT32*) p; break;
+ case SbxSINGLE: n |= SbxBYREF; aData.pSingle = (float*) p; break;
+ case SbxDATE:
+ case SbxDOUBLE: n |= SbxBYREF; aData.pDouble = (double*) p; break;
+ case SbxSTRING: n |= SbxBYREF; aData.pString = (XubString*) p; break;
+ case SbxERROR:
+ case SbxUSHORT:
+ case SbxBOOL: n |= SbxBYREF; aData.pUShort = (UINT16*) p; break;
+ case SbxULONG: n |= SbxBYREF; aData.pULong = (UINT32*) p; break;
+ case SbxCHAR: n |= SbxBYREF; aData.pChar = (xub_Unicode*) p; break;
+ case SbxBYTE: n |= SbxBYREF; aData.pByte = (BYTE*) p; break;
+ case SbxINT: n |= SbxBYREF; aData.pInt = (int*) p; break;
+ case SbxOBJECT:
+ aData.pObj = (SbxBase*) p;
+ if( p )
+ aData.pObj->AddRef();
+ break;
+ case SbxDECIMAL:
+ aData.pDecimal = (SbxDecimal*) p;
+ if( p )
+ aData.pDecimal->addRef();
+ break;
+ default:
+ DBG_ASSERT( !this, "Angabe eines Pointers unzulaessig" );
+ n = SbxNULL;
+ }
+ else
+ memset( &aData, 0, sizeof( SbxValues ) );
+ aData.eType = SbxDataType( n );
+}
+
+SbxValue::SbxValue( const SbxValue& r )
+ : SvRefBase( r ), SbxBase( r )
+{
+ if( !r.CanRead() )
+ {
+ SetError( SbxERR_PROP_WRITEONLY );
+ if( !IsFixed() )
+ aData.eType = SbxNULL;
+ }
+ else
+ {
+ ((SbxValue*) &r)->Broadcast( SBX_HINT_DATAWANTED );
+ aData = r.aData;
+ // Pointer kopieren, Referenzen inkrementieren
+ switch( aData.eType )
+ {
+ case SbxSTRING:
+ if( aData.pString )
+ aData.pString = new XubString( *aData.pString );
+ break;
+ case SbxOBJECT:
+ if( aData.pObj )
+ aData.pObj->AddRef();
+ break;
+ case SbxDECIMAL:
+ if( aData.pDecimal )
+ aData.pDecimal->addRef();
+ break;
+ default: break;
+ }
+ }
+}
+
+SbxValue& SbxValue::operator=( const SbxValue& r )
+{
+ if( &r != this )
+ {
+ if( !CanWrite() )
+ SetError( SbxERR_PROP_READONLY );
+ else
+ {
+ // Den Inhalt der Variablen auslesen
+ SbxValues aNew;
+ if( IsFixed() )
+ // fest: dann muss der Typ stimmen
+ aNew.eType = aData.eType;
+ else if( r.IsFixed() )
+ // Quelle fest: Typ uebernehmen
+ aNew.eType = SbxDataType( r.aData.eType & 0x0FFF );
+ else
+ // beides Variant: dann isses egal
+ aNew.eType = SbxVARIANT;
+ if( r.Get( aNew ) )
+ Put( aNew );
+ }
+ }
+ return *this;
+}
+
+SbxValue::~SbxValue()
+{
+#ifndef C50
+ Broadcast( SBX_HINT_DYING );
+ SetFlag( SBX_WRITE );
+ SbxValue::Clear();
+#else
+ // Provisorischer Fix fuer Solaris 5.0 Compiler Bug
+ // bei Nutzung virtueller Vererbung. Virtuelle Calls
+ // im Destruktor vermeiden. Statt Clear() zu rufen
+ // moegliche Objekt-Referenzen direkt freigeben.
+ if( aData.eType == SbxOBJECT )
+ {
+ if( aData.pObj && aData.pObj != this )
+ {
+ HACK(nicht bei Parent-Prop - sonst CyclicRef)
+ SbxVariable *pThisVar = PTR_CAST(SbxVariable, this);
+ BOOL bParentProp = pThisVar && 5345 ==
+ ( (INT16) ( pThisVar->GetUserData() & 0xFFFF ) );
+ if ( !bParentProp )
+ aData.pObj->ReleaseRef();
+ }
+ }
+ else if( aData.eType == SbxDECIMAL )
+ {
+ releaseDecimalPtr( aData.pDecimal );
+ }
+#endif
+}
+
+void SbxValue::Clear()
+{
+ switch( aData.eType )
+ {
+ case SbxNULL:
+ case SbxEMPTY:
+ case SbxVOID:
+ break;
+ case SbxSTRING:
+ delete aData.pString; aData.pString = NULL;
+ break;
+ case SbxOBJECT:
+ if( aData.pObj )
+ {
+ if( aData.pObj != this )
+ {
+ HACK(nicht bei Parent-Prop - sonst CyclicRef)
+ SbxVariable *pThisVar = PTR_CAST(SbxVariable, this);
+ BOOL bParentProp = pThisVar && 5345 ==
+ ( (INT16) ( pThisVar->GetUserData() & 0xFFFF ) );
+ if ( !bParentProp )
+ aData.pObj->ReleaseRef();
+ }
+ aData.pObj = NULL;
+ }
+ break;
+ case SbxDECIMAL:
+ if( aData.eType == SbxDECIMAL )
+ releaseDecimalPtr( aData.pDecimal );
+ break;
+ case SbxDATAOBJECT:
+ aData.pData = NULL; break;
+ default:
+ {
+ SbxValues aEmpty;
+ memset( &aEmpty, 0, sizeof( SbxValues ) );
+ aEmpty.eType = GetType();
+ Put( aEmpty );
+ }
+ }
+}
+
+// Dummy
+
+void SbxValue::Broadcast( ULONG )
+{}
+
+//////////////////////////// Daten auslesen //////////////////////////////
+
+// Ermitteln der "richtigen" Variablen. Falls es ein Objekt ist, wird
+// entweder das Objekt selbst oder dessen Default-Property angesprochen.
+// Falls die Variable eine Variable oder ein Objekt enthaelt, wird
+// dieses angesprochen.
+
+SbxValue* SbxValue::TheRealValue() const
+{
+ return TheRealValue( TRUE );
+}
+
+// #55226 Zusaetzliche Info transportieren
+SbxValue* SbxValue::TheRealValue( BOOL bObjInObjError ) const
+{
+ SbxValue* p = (SbxValue*) this;
+ for( ;; )
+ {
+ SbxDataType t = SbxDataType( p->aData.eType & 0x0FFF );
+ if( t == SbxOBJECT )
+ {
+ // Der Block enthaelt ein Objekt oder eine Variable
+ SbxObject* pObj = PTR_CAST(SbxObject,p->aData.pObj);
+ if( pObj )
+ {
+ // Hat das Objekt eine Default-Property?
+ SbxVariable* pDflt = pObj->GetDfltProperty();
+
+ // Falls dies ein Objekt ist und sich selbst enthaelt,
+ // koennen wir nicht darauf zugreifen
+ // #55226# Die alte Bedingung, um einen Fehler zu setzen,
+ // ist nicht richtig, da z.B. eine ganz normale Variant-
+ // Variable mit Objekt davon betroffen sein kann, wenn ein
+ // anderer Wert zugewiesen werden soll. Daher mit Flag.
+ if( bObjInObjError && !pDflt &&
+ ((SbxValue*) pObj)->aData.eType == SbxOBJECT &&
+ ((SbxValue*) pObj)->aData.pObj == pObj )
+ {
+ SetError( SbxERR_BAD_PROP_VALUE );
+ p = NULL;
+ }
+ else if( pDflt )
+ p = pDflt;
+ /* ALT:
+ else
+ p = pDflt ? pDflt : (SbxVariable*) pObj;
+ */
+ break;
+ }
+ // Haben wir ein Array?
+ SbxArray* pArray = PTR_CAST(SbxArray,p->aData.pObj);
+ if( pArray )
+ {
+ // Ggf. Parameter holen
+ SbxArray* pPar = NULL;
+ SbxVariable* pVar = PTR_CAST(SbxVariable,p);
+ if( pVar )
+ pPar = pVar->GetParameters();
+ if( pPar )
+ {
+ // Haben wir ein dimensioniertes Array?
+ SbxDimArray* pDimArray = PTR_CAST(SbxDimArray,p->aData.pObj);
+ if( pDimArray )
+ p = pDimArray->Get( pPar );
+ else
+ p = pArray->Get( pPar->Get( 1 )->GetInteger() );
+ break;
+ }
+ }
+ // Sonst einen SbxValue annehmen
+ SbxValue* pVal = PTR_CAST(SbxValue,p->aData.pObj);
+ if( pVal )
+ p = pVal;
+ else
+ break;
+ }
+ else
+ break;
+ }
+ return p;
+}
+
+BOOL SbxValue::Get( SbxValues& rRes ) const
+{
+ BOOL bRes = FALSE;
+ SbxError eOld = GetError();
+ if( eOld != SbxERR_OK )
+ ResetError();
+ if( !CanRead() )
+ {
+ SetError( SbxERR_PROP_WRITEONLY );
+ rRes.pObj = NULL;
+ }
+ else
+ {
+ // Falls nach einem Objekt oder einem VARIANT gefragt wird, nicht
+ // die wahren Werte suchen
+ SbxValue* p = (SbxValue*) this;
+ if( rRes.eType != SbxOBJECT && rRes.eType != SbxVARIANT )
+ p = TheRealValue();
+ if( p )
+ {
+ p->Broadcast( SBX_HINT_DATAWANTED );
+ switch( rRes.eType )
+ {
+ case SbxEMPTY:
+ case SbxVOID:
+ case SbxNULL: break;
+ case SbxVARIANT: rRes = p->aData; break;
+ case SbxINTEGER: rRes.nInteger = ImpGetInteger( &p->aData ); break;
+ case SbxLONG: rRes.nLong = ImpGetLong( &p->aData ); break;
+ case SbxSALINT64: rRes.nInt64 = ImpGetInt64( &p->aData ); break;
+ case SbxSALUINT64: rRes.uInt64 = ImpGetUInt64( &p->aData ); break;
+ case SbxSINGLE: rRes.nSingle = ImpGetSingle( &p->aData ); break;
+ case SbxDOUBLE: rRes.nDouble = ImpGetDouble( &p->aData ); break;
+ case SbxCURRENCY:rRes.nLong64 = ImpGetCurrency( &p->aData ); break;
+ case SbxDECIMAL: rRes.pDecimal = ImpGetDecimal( &p->aData ); break;
+ case SbxDATE: rRes.nDouble = ImpGetDate( &p->aData ); break;
+ case SbxBOOL:
+ rRes.nUShort = sal::static_int_cast< UINT16 >(
+ ImpGetBool( &p->aData ) );
+ break;
+ case SbxCHAR: rRes.nChar = ImpGetChar( &p->aData ); break;
+ case SbxBYTE: rRes.nByte = ImpGetByte( &p->aData ); break;
+ case SbxUSHORT: rRes.nUShort = ImpGetUShort( &p->aData ); break;
+ case SbxULONG: rRes.nULong = ImpGetULong( &p->aData ); break;
+ case SbxLPSTR:
+ case SbxSTRING: p->aPic = ImpGetString( &p->aData );
+ rRes.pString = &p->aPic; break;
+ case SbxCoreSTRING: p->aPic = ImpGetCoreString( &p->aData );
+ rRes.pString = &p->aPic; break;
+ case SbxINT:
+#if SAL_TYPES_SIZEOFINT == 2
+ rRes.nInt = (int) ImpGetInteger( &p->aData );
+#else
+ rRes.nInt = (int) ImpGetLong( &p->aData );
+#endif
+ break;
+ case SbxUINT:
+#if SAL_TYPES_SIZEOFINT == 2
+ rRes.nUInt = (int) ImpGetUShort( &p->aData );
+#else
+ rRes.nUInt = (int) ImpGetULong( &p->aData );
+#endif
+ break;
+ case SbxOBJECT:
+ if( p->aData.eType == SbxOBJECT )
+ rRes.pObj = p->aData.pObj;
+ else
+ {
+ SetError( SbxERR_NO_OBJECT );
+ rRes.pObj = NULL;
+ }
+ break;
+ default:
+ if( p->aData.eType == rRes.eType )
+ rRes = p->aData;
+ else
+ {
+ SetError( SbxERR_CONVERSION );
+ rRes.pObj = NULL;
+ }
+ }
+ }
+ else
+ {
+ // Objekt enthielt sich selbst
+ SbxDataType eTemp = rRes.eType;
+ memset( &rRes, 0, sizeof( SbxValues ) );
+ rRes.eType = eTemp;
+ }
+ }
+ if( !IsError() )
+ {
+ bRes = TRUE;
+ if( eOld != SbxERR_OK )
+ SetError( eOld );
+ }
+ return bRes;
+}
+
+const XubString& SbxValue::GetString() const
+{
+ SbxValues aRes;
+ aRes.eType = SbxSTRING;
+ if( Get( aRes ) )
+ // Geht in Ordnung, da Ptr eine Kopie ist
+ return *aRes.pString;
+ else
+ {
+ ((SbxValue*) this)->aPic.Erase();
+ return aPic;
+ }
+}
+
+const XubString& SbxValue::GetCoreString() const
+{
+ SbxValues aRes;
+ aRes.eType = SbxCoreSTRING;
+ if( Get( aRes ) )
+ // Geht in Ordnung, da Ptr eine Kopie ist
+ return *aRes.pString;
+ else
+ {
+ ((SbxValue*) this)->aPic.Erase();
+ return aPic;
+ }
+}
+
+BOOL SbxValue::GetBool() const
+{
+ SbxValues aRes;
+ aRes.eType = SbxBOOL;
+ Get( aRes );
+ return BOOL( aRes.nUShort != 0 );
+}
+
+#define GET( g, e, t, m ) \
+t SbxValue::g() const { SbxValues aRes(e); Get( aRes ); return aRes.m; }
+
+GET( GetByte, SbxBYTE, BYTE, nByte )
+GET( GetChar, SbxCHAR, xub_Unicode, nChar )
+GET( GetCurrency, SbxCURRENCY, SbxINT64, nLong64 )
+GET( GetDate, SbxDATE, double, nDouble )
+GET( GetDouble, SbxDOUBLE, double, nDouble )
+GET( GetInteger, SbxINTEGER, INT16, nInteger )
+GET( GetLong, SbxLONG, INT32, nLong )
+GET( GetObject, SbxOBJECT, SbxBase*, pObj )
+GET( GetSingle, SbxSINGLE, float, nSingle )
+GET( GetULong, SbxULONG, UINT32, nULong )
+GET( GetUShort, SbxUSHORT, UINT16, nUShort )
+GET( GetInt64, SbxSALINT64, sal_Int64, nInt64 )
+GET( GetUInt64, SbxSALUINT64, sal_uInt64, uInt64 )
+#ifdef WNT
+GET( GetDecimal, SbxDECIMAL, SbxDecimal*, pDecimal )
+#endif
+
+//////////////////////////// Daten schreiben /////////////////////////////
+
+BOOL SbxValue::Put( const SbxValues& rVal )
+{
+ BOOL bRes = FALSE;
+ SbxError eOld = GetError();
+ if( eOld != SbxERR_OK )
+ ResetError();
+ if( !CanWrite() )
+ SetError( SbxERR_PROP_READONLY );
+ else if( rVal.eType & 0xF000 )
+ SetError( SbxERR_NOTIMP );
+ else
+ {
+ // Falls nach einem Objekt gefragt wird, nicht
+ // die wahren Werte suchen
+ SbxValue* p = this;
+ if( rVal.eType != SbxOBJECT )
+ p = TheRealValue( FALSE ); // #55226 Hier keinen Fehler erlauben
+ if( p )
+ {
+ if( !p->CanWrite() )
+ SetError( SbxERR_PROP_READONLY );
+ else if( p->IsFixed() || p->SetType( (SbxDataType) ( rVal.eType & 0x0FFF ) ) )
+ switch( rVal.eType & 0x0FFF )
+ {
+ case SbxEMPTY:
+ case SbxVOID:
+ case SbxNULL: break;
+ case SbxINTEGER: ImpPutInteger( &p->aData, rVal.nInteger ); break;
+ case SbxLONG: ImpPutLong( &p->aData, rVal.nLong ); break;
+ case SbxSALINT64: ImpPutInt64( &p->aData, rVal.nInt64 ); break;
+ case SbxSALUINT64: ImpPutUInt64( &p->aData, rVal.uInt64 ); break;
+ case SbxSINGLE: ImpPutSingle( &p->aData, rVal.nSingle ); break;
+ case SbxDOUBLE: ImpPutDouble( &p->aData, rVal.nDouble ); break;
+ case SbxCURRENCY: ImpPutCurrency( &p->aData, rVal.nLong64 ); break;
+ case SbxDECIMAL: ImpPutDecimal( &p->aData, rVal.pDecimal ); break;
+ case SbxDATE: ImpPutDate( &p->aData, rVal.nDouble ); break;
+ case SbxBOOL: ImpPutBool( &p->aData, rVal.nInteger ); break;
+ case SbxCHAR: ImpPutChar( &p->aData, rVal.nChar ); break;
+ case SbxBYTE: ImpPutByte( &p->aData, rVal.nByte ); break;
+ case SbxUSHORT: ImpPutUShort( &p->aData, rVal.nUShort ); break;
+ case SbxULONG: ImpPutULong( &p->aData, rVal.nULong ); break;
+ case SbxLPSTR:
+ case SbxSTRING: ImpPutString( &p->aData, rVal.pString ); break;
+ case SbxINT:
+#if SAL_TYPES_SIZEOFINT == 2
+ ImpPutInteger( &p->aData, (INT16) rVal.nInt );
+#else
+ ImpPutLong( &p->aData, (INT32) rVal.nInt );
+#endif
+ break;
+ case SbxUINT:
+#if SAL_TYPES_SIZEOFINT == 2
+ ImpPutUShort( &p->aData, (UINT16) rVal.nUInt );
+#else
+ ImpPutULong( &p->aData, (UINT32) rVal.nUInt );
+#endif
+ break;
+ case SbxOBJECT:
+ if( !p->IsFixed() || p->aData.eType == SbxOBJECT )
+ {
+ // ist schon drin
+ if( p->aData.eType == SbxOBJECT && p->aData.pObj == rVal.pObj )
+ break;
+
+ // Nur den Werteteil loeschen!
+ p->SbxValue::Clear();
+
+ // eingentliche Zuweisung
+ p->aData.pObj = rVal.pObj;
+
+ // ggf. Ref-Count mitzaehlen
+ if( p->aData.pObj && p->aData.pObj != p )
+ {
+ if ( p != this )
+ {
+ DBG_ERROR( "TheRealValue" );
+ }
+ HACK(nicht bei Parent-Prop - sonst CyclicRef)
+ SbxVariable *pThisVar = PTR_CAST(SbxVariable, this);
+ BOOL bParentProp = pThisVar && 5345 ==
+ ( (INT16) ( pThisVar->GetUserData() & 0xFFFF ) );
+ if ( !bParentProp )
+ p->aData.pObj->AddRef();
+ }
+ }
+ else
+ SetError( SbxERR_CONVERSION );
+ break;
+ default:
+ if( p->aData.eType == rVal.eType )
+ p->aData = rVal;
+ else
+ {
+ SetError( SbxERR_CONVERSION );
+ if( !p->IsFixed() )
+ p->aData.eType = SbxNULL;
+ }
+ }
+ if( !IsError() )
+ {
+ p->SetModified( TRUE );
+ p->Broadcast( SBX_HINT_DATACHANGED );
+ if( eOld != SbxERR_OK )
+ SetError( eOld );
+ bRes = TRUE;
+ }
+ }
+ }
+ return bRes;
+}
+
+BOOL SbxValue::PutBool( BOOL b )
+{
+ SbxValues aRes;
+ aRes.eType = SbxBOOL;
+ aRes.nUShort = sal::static_int_cast< UINT16 >(b ? SbxTRUE : SbxFALSE);
+ Put( aRes );
+ return BOOL( !IsError() );
+}
+
+BOOL SbxValue::PutEmpty()
+{
+ BOOL bRet = SetType( SbxEMPTY );
+ SetModified( TRUE );
+ return bRet;
+}
+
+BOOL SbxValue::PutString( const XubString& r )
+{
+ SbxValues aRes;
+ aRes.eType = SbxSTRING;
+ aRes.pString = (XubString*) &r;
+ Put( aRes );
+ return BOOL( !IsError() );
+}
+
+#define PUT( p, e, t, m ) \
+BOOL SbxValue::p( t n ) \
+{ SbxValues aRes(e); aRes.m = n; Put( aRes ); return BOOL( !IsError() ); }
+
+PUT( PutByte, SbxBYTE, BYTE, nByte )
+PUT( PutChar, SbxCHAR, xub_Unicode, nChar )
+PUT( PutCurrency, SbxCURRENCY, const SbxINT64&, nLong64 )
+PUT( PutDate, SbxDATE, double, nDouble )
+PUT( PutDouble, SbxDOUBLE, double, nDouble )
+PUT( PutInteger, SbxINTEGER, INT16, nInteger )
+PUT( PutLong, SbxLONG, INT32, nLong )
+PUT( PutObject, SbxOBJECT, SbxBase*, pObj )
+PUT( PutSingle, SbxSINGLE, float, nSingle )
+PUT( PutULong, SbxULONG, UINT32, nULong )
+PUT( PutUShort, SbxUSHORT, UINT16, nUShort )
+PUT( PutInt64, SbxSALINT64, sal_Int64, nInt64 )
+PUT( PutUInt64, SbxSALUINT64, sal_uInt64, uInt64 )
+#ifdef WNT
+PUT( PutDecimal, SbxDECIMAL, SbxDecimal*, pDecimal )
+#endif
+
+////////////////////////// Setzen des Datentyps ///////////////////////////
+
+BOOL SbxValue::IsFixed() const
+{
+ return ( (GetFlags() & SBX_FIXED) | (aData.eType & SbxBYREF) ) != 0;
+}
+
+// Eine Variable ist numerisch, wenn sie EMPTY oder wirklich numerisch ist
+// oder einen vollstaendig konvertierbaren String enthaelt
+
+// #41692, fuer RTL und Basic-Core getrennt implementieren
+BOOL SbxValue::IsNumeric() const
+{
+ return ImpIsNumeric( /*bOnlyIntntl*/FALSE );
+}
+
+BOOL SbxValue::ImpIsNumeric( BOOL bOnlyIntntl ) const
+{
+
+ if( !CanRead() )
+ {
+ SetError( SbxERR_PROP_WRITEONLY ); return FALSE;
+ }
+ // Downcast pruefen!!!
+ if( this->ISA(SbxVariable) )
+ ((SbxVariable*)this)->Broadcast( SBX_HINT_DATAWANTED );
+ SbxDataType t = GetType();
+ if( t == SbxSTRING )
+ {
+ if( aData.pString )
+ {
+ XubString s( *aData.pString );
+ double n;
+ SbxDataType t2;
+ USHORT nLen = 0;
+ if( ImpScan( s, n, t2, &nLen, /*bAllowIntntl*/FALSE, bOnlyIntntl ) == SbxERR_OK )
+ return BOOL( nLen == s.Len() );
+ }
+ return FALSE;
+ }
+ else
+ return BOOL( t == SbxEMPTY
+ || ( t >= SbxINTEGER && t <= SbxCURRENCY )
+ || ( t >= SbxCHAR && t <= SbxUINT ) );
+}
+
+SbxClassType SbxValue::GetClass() const
+{
+ return SbxCLASS_VALUE;
+}
+
+SbxDataType SbxValue::GetType() const
+{
+ return SbxDataType( aData.eType & 0x0FFF );
+}
+
+SbxDataType SbxValue::GetFullType() const
+{
+ return aData.eType;
+}
+
+BOOL SbxValue::SetType( SbxDataType t )
+{
+ DBG_ASSERT( !( t & 0xF000 ), "Setzen von BYREF|ARRAY verboten!" );
+ if( ( t == SbxEMPTY && aData.eType == SbxVOID )
+ || ( aData.eType == SbxEMPTY && t == SbxVOID ) )
+ return TRUE;
+ if( ( t & 0x0FFF ) == SbxVARIANT )
+ {
+ // Versuch, den Datentyp auf Variant zu setzen
+ ResetFlag( SBX_FIXED );
+ if( IsFixed() )
+ {
+ SetError( SbxERR_CONVERSION ); return FALSE;
+ }
+ t = SbxEMPTY;
+ }
+ if( ( t & 0x0FFF ) != ( aData.eType & 0x0FFF ) )
+ {
+ if( !CanWrite() || IsFixed() )
+ {
+ SetError( SbxERR_CONVERSION ); return FALSE;
+ }
+ else
+ {
+ // Eventuelle Objekte freigeben
+ switch( aData.eType )
+ {
+ case SbxSTRING:
+ delete aData.pString;
+ break;
+ case SbxOBJECT:
+ if( aData.pObj && aData.pObj != this )
+ {
+ HACK(nicht bei Parent-Prop - sonst CyclicRef)
+ SbxVariable *pThisVar = PTR_CAST(SbxVariable, this);
+ UINT16 nSlotId = pThisVar
+ ? ( (INT16) ( pThisVar->GetUserData() & 0xFFFF ) )
+ : 0;
+ DBG_ASSERT( nSlotId != 5345 || pThisVar->GetName() == UniString::CreateFromAscii( "Parent" ),
+ "SID_PARENTOBJECT heisst nicht 'Parent'" );
+ BOOL bParentProp = 5345 == nSlotId;
+ if ( !bParentProp )
+ aData.pObj->ReleaseRef();
+ }
+ break;
+ default: break;
+ }
+ // Das klappt immer, da auch die Float-Repraesentationen 0 sind.
+ memset( &aData, 0, sizeof( SbxValues ) );
+ aData.eType = t;
+ }
+ }
+ return TRUE;
+}
+
+BOOL SbxValue::Convert( SbxDataType eTo )
+{
+ eTo = SbxDataType( eTo & 0x0FFF );
+ if( ( aData.eType & 0x0FFF ) == eTo )
+ return TRUE;
+ if( !CanWrite() )
+ return FALSE;
+ if( eTo == SbxVARIANT )
+ {
+ // Versuch, den Datentyp auf Variant zu setzen
+ ResetFlag( SBX_FIXED );
+ if( IsFixed() )
+ {
+ SetError( SbxERR_CONVERSION ); return FALSE;
+ }
+ else
+ return TRUE;
+ }
+ // Convert from Null geht niemals. Einmal Null, immer Null!
+ if( aData.eType == SbxNULL )
+ {
+ SetError( SbxERR_CONVERSION ); return FALSE;
+ }
+
+ // Konversion der Daten:
+ SbxValues aNew;
+ aNew.eType = eTo;
+ if( Get( aNew ) )
+ {
+ // Der Datentyp konnte konvertiert werden. Bei Fixed-Elementen
+ // ist hier Ende, da die Daten nicht uebernommen zu werden brauchen
+ if( !IsFixed() )
+ {
+ SetType( eTo );
+ Put( aNew );
+ SetModified( TRUE );
+ }
+ Broadcast( SBX_HINT_CONVERTED );
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+////////////////////////////////// Rechnen /////////////////////////////////
+
+BOOL SbxValue::Compute( SbxOperator eOp, const SbxValue& rOp )
+{
+ SbxDataType eThisType = GetType();
+ SbxDataType eOpType = rOp.GetType();
+ SbxError eOld = GetError();
+ if( eOld != SbxERR_OK )
+ ResetError();
+ if( !CanWrite() )
+ SetError( SbxERR_PROP_READONLY );
+ else if( !rOp.CanRead() )
+ SetError( SbxERR_PROP_WRITEONLY );
+ // Sonderregel 1: Ist ein Operand Null, ist das Ergebnis Null
+ else if( eThisType == SbxNULL || eOpType == SbxNULL )
+ SetType( SbxNULL );
+ // Sonderregel 2: Ist ein Operand Empty, ist das Ergebnis der 2. Operand
+ else if( eThisType == SbxEMPTY )
+ *this = rOp;
+ // 13.2.96: Nicht schon vor Get auf SbxEMPTY pruefen
+ else
+ {
+ SbxValues aL, aR;
+ bool bDecimal = false;
+ if( eThisType == SbxSTRING || eOp == SbxCAT )
+ {
+ if( eOp == SbxCAT || eOp == SbxPLUS )
+ {
+ // AB 5.11.1999, OUString beruecksichtigen
+ aL.eType = aR.eType = SbxSTRING;
+ rOp.Get( aR );
+ // AB 8.12.1999, #70399: Hier wieder GetType() rufen, Get() kann Typ aendern!
+ if( rOp.GetType() == SbxEMPTY )
+ goto Lbl_OpIsEmpty;
+ Get( aL );
+
+ // #30576: Erstmal testen, ob Wandlung geklappt hat
+ if( aL.pString != NULL && aR.pString != NULL )
+ {
+ *aL.pString += *aR.pString;
+ }
+ // Nicht einmal Left OK?
+ else if( aL.pString == NULL )
+ {
+ aL.pString = new String();
+ }
+ Put( aL );
+ }
+ else
+ SetError( SbxERR_CONVERSION );
+ }
+ else if( eOpType == SbxSTRING && rOp.IsFixed() )
+ { // Numerisch: rechts darf kein String stehen
+ SetError( SbxERR_CONVERSION );
+ }
+ else if( ( eOp >= SbxIDIV && eOp <= SbxNOT ) || eOp == SbxMOD )
+ {
+ if( GetType() == eOpType )
+ {
+ if( GetType() == SbxULONG64
+ || GetType() == SbxLONG64
+ || GetType() == SbxCURRENCY
+ || GetType() == SbxULONG )
+ aL.eType = aR.eType = GetType();
+// else if( GetType() == SbxDouble || GetType() == SbxSingle )
+// aL.eType = aR.eType = SbxLONG64;
+ else
+ aL.eType = aR.eType = SbxLONG;
+ }
+ else if( GetType() == SbxCURRENCY || eOpType == SbxCURRENCY
+ || GetType() == SbxULONG64 || eOpType == SbxULONG64
+ || GetType() == SbxLONG64 || eOpType == SbxLONG64 )
+ aL.eType = aR.eType = SbxLONG64;
+// else if( GetType() == SbxDouble || rOP.GetType() == SbxDouble
+// || GetType() == SbxSingle || rOP.GetType() == SbxSingle )
+// aL.eType = aR.eType = SbxLONG64;
+ else
+ aL.eType = aR.eType = SbxLONG;
+
+ if( rOp.Get( aR ) )
+ {
+ if( rOp.GetType() == SbxEMPTY )
+ goto Lbl_OpIsEmpty;
+ if( Get( aL ) ) switch( eOp )
+ {
+ case SbxIDIV:
+ if( aL.eType == SbxCURRENCY )
+ aL.eType = SbxLONG64;
+ if( aL.eType == SbxLONG64 )
+ if( !aR.nLong64 ) SetError( SbxERR_ZERODIV );
+ else aL.nLong64 /= aR.nLong64;
+ else if( aL.eType == SbxULONG64 )
+ if( !aR.nULong64 ) SetError( SbxERR_ZERODIV );
+ else aL.nULong64 /= aR.nULong64;
+ else if( aL.eType == SbxLONG )
+ if( !aR.nLong ) SetError( SbxERR_ZERODIV );
+ else aL.nLong /= aR.nLong;
+ else
+ if( !aR.nULong ) SetError( SbxERR_ZERODIV );
+ else aL.nULong /= aR.nULong;
+ break;
+ case SbxMOD:
+ if( aL.eType == SbxCURRENCY )
+ aL.eType = SbxLONG64;
+ if( aL.eType == SbxLONG64 )
+ if( !aR.nLong64 ) SetError( SbxERR_ZERODIV );
+ else aL.nLong64 %= aR.nLong64;
+ else if( aL.eType == SbxULONG64 )
+ if( !aR.nULong64 ) SetError( SbxERR_ZERODIV );
+ else aL.nULong64 %= aR.nULong64;
+ else if( aL.eType == SbxLONG )
+ if( !aR.nLong ) SetError( SbxERR_ZERODIV );
+ else aL.nLong %= aR.nLong;
+ else
+ if( !aR.nULong ) SetError( SbxERR_ZERODIV );
+ else aL.nULong %= aR.nULong;
+ break;
+ case SbxAND:
+ if( aL.eType != SbxLONG && aL.eType != SbxULONG )
+ aL.nLong64 &= aR.nLong64;
+ else
+ aL.nLong &= aR.nLong;
+ break;
+ case SbxOR:
+ if( aL.eType != SbxLONG && aL.eType != SbxULONG )
+ aL.nLong64 |= aR.nLong64;
+ else
+ aL.nLong |= aR.nLong;
+ break;
+ case SbxXOR:
+ if( aL.eType != SbxLONG && aL.eType != SbxULONG )
+ aL.nLong64 ^= aR.nLong64;
+ else
+ aL.nLong ^= aR.nLong;
+ break;
+ case SbxEQV:
+ if( aL.eType != SbxLONG && aL.eType != SbxULONG )
+ aL.nLong64 = (aL.nLong64 & aR.nLong64) | (~aL.nLong64 & ~aR.nLong64);
+ else
+ aL.nLong = (aL.nLong & aR.nLong) | (~aL.nLong & ~aR.nLong);
+ break;
+ case SbxIMP:
+ if( aL.eType != SbxLONG && aL.eType != SbxULONG )
+ aL.nLong64 = ~aL.nLong64 | aR.nLong64;
+ else
+ aL.nLong = ~aL.nLong | aR.nLong;
+ break;
+ case SbxNOT:
+ if( aL.eType != SbxLONG && aL.eType != SbxULONG )
+ aL.nLong64 = ~aL.nLong64;
+ else
+ aL.nLong = ~aL.nLong;
+ break;
+ default: break;
+ }
+ }
+ }
+ else if( ( GetType() == SbxDECIMAL || rOp.GetType() == SbxDECIMAL ) &&
+ ( eOp == SbxMUL || eOp == SbxDIV || eOp == SbxPLUS || eOp == SbxMINUS || eOp == SbxNEG ) )
+ {
+ aL.eType = aR.eType = SbxDECIMAL;
+ bDecimal = true;
+ if( rOp.Get( aR ) )
+ {
+ if( rOp.GetType() == SbxEMPTY )
+ {
+ releaseDecimalPtr( aL.pDecimal );
+ goto Lbl_OpIsEmpty;
+ }
+ if( Get( aL ) )
+ {
+ if( aL.pDecimal && aR.pDecimal )
+ {
+ bool bOk = true;
+ switch( eOp )
+ {
+ case SbxMUL:
+ bOk = ( *(aL.pDecimal) *= *(aR.pDecimal) );
+ break;
+ case SbxDIV:
+ if( aR.pDecimal->isZero() )
+ SetError( SbxERR_ZERODIV );
+ else
+ bOk = ( *(aL.pDecimal) /= *(aR.pDecimal) );
+ break;
+ case SbxPLUS:
+ bOk = ( *(aL.pDecimal) += *(aR.pDecimal) );
+ break;
+ case SbxMINUS:
+ bOk = ( *(aL.pDecimal) -= *(aR.pDecimal) );
+ break;
+ case SbxNEG:
+ bOk = ( aL.pDecimal->neg() );
+ break;
+ default:
+ SetError( SbxERR_NOTIMP );
+ }
+ if( !bOk )
+ SetError( SbxERR_OVERFLOW );
+ }
+ else
+ {
+ SetError( SbxERR_CONVERSION );
+ }
+ }
+ }
+ }
+ else if( GetType() == SbxCURRENCY || rOp.GetType() == SbxCURRENCY )
+ {
+ aL.eType = SbxCURRENCY;
+ aR.eType = SbxCURRENCY;
+
+ if( rOp.Get( aR ) )
+ {
+ static BigInt n10K( 10000 );
+
+ if( rOp.GetType() == SbxEMPTY )
+ goto Lbl_OpIsEmpty;
+
+ if( Get( aL ) ) switch( eOp )
+ {
+ case SbxMUL:
+ {
+ // #i20704 Implement directly
+ BigInt b1( SbxINT64Converter::SbxINT64_2_BigInt( aL.nLong64 ) );
+ BigInt b2( SbxINT64Converter::SbxINT64_2_BigInt( aR.nLong64 ) );
+ b1 *= b2;
+ b1 /= n10K;
+ double d = double( b1 ) / 10000.0;
+ if( d > SbxMAXCURR || d < SbxMINCURR )
+ SetError( SbxERR_OVERFLOW );
+ else
+ SbxINT64Converter::BigInt_2_SbxINT64( b1, &aL.nLong64 );
+ break;
+ }
+ case SbxDIV:
+ if( !aR.nLong64 )
+ {
+ SetError( SbxERR_ZERODIV );
+ }
+ else
+ {
+ // #i20704 Implement directly
+ BigInt b1( SbxINT64Converter::SbxINT64_2_BigInt( aL.nLong64 ) );
+ BigInt b2( SbxINT64Converter::SbxINT64_2_BigInt( aR.nLong64 ) );
+ b1 *= n10K;
+ b1 /= b2;
+ double d = double( b1 ) / 10000.0;
+ if( d > SbxMAXCURR || d < SbxMINCURR )
+ SetError( SbxERR_OVERFLOW );
+ else
+ SbxINT64Converter::BigInt_2_SbxINT64( b1, &aL.nLong64 );
+ }
+ break;
+ case SbxPLUS:
+ aL.nLong64 += aR.nLong64; break;
+ case SbxMINUS:
+ aL.nLong64 -= aR.nLong64; break;
+ case SbxNEG:
+ aL.nLong64 = -aL.nLong64; break;
+ default:
+ SetError( SbxERR_NOTIMP );
+ }
+ }
+ }
+ else
+ { // Andere Operatoren
+ aL.eType = aR.eType = SbxDOUBLE;
+ if( rOp.Get( aR ) )
+ {
+ if( rOp.GetType() == SbxEMPTY )
+ goto Lbl_OpIsEmpty;
+ if( Get( aL ) )
+ {
+ switch( eOp )
+ {
+ case SbxEXP:
+ aL.nDouble = pow( aL.nDouble, aR.nDouble );
+ break;
+ case SbxMUL:
+ aL.nDouble *= aR.nDouble; break;
+ case SbxDIV:
+ if( !aR.nDouble ) SetError( SbxERR_ZERODIV );
+ else aL.nDouble /= aR.nDouble; break;
+ case SbxPLUS:
+ aL.nDouble += aR.nDouble; break;
+ case SbxMINUS:
+ aL.nDouble -= aR.nDouble; break;
+ case SbxNEG:
+ aL.nDouble = -aL.nDouble; break;
+ default:
+ SetError( SbxERR_NOTIMP );
+ }
+
+ // #45465 Date braucht bei + eine Spezial-Behandlung
+ if( eOp == SbxPLUS && (GetType() == SbxDATE || rOp.GetType() == SbxDATE ) )
+ aL.eType = SbxDATE;
+ }
+ }
+
+ }
+ if( !IsError() )
+ Put( aL );
+ if( bDecimal )
+ {
+ releaseDecimalPtr( aL.pDecimal );
+ releaseDecimalPtr( aR.pDecimal );
+ }
+ }
+Lbl_OpIsEmpty:
+
+ BOOL bRes = BOOL( !IsError() );
+ if( bRes && eOld != SbxERR_OK )
+ SetError( eOld );
+ return bRes;
+}
+
+// Die Vergleichs-Routine liefert TRUE oder FALSE.
+
+BOOL SbxValue::Compare( SbxOperator eOp, const SbxValue& rOp ) const
+{
+ BOOL bRes = FALSE;
+ SbxError eOld = GetError();
+ if( eOld != SbxERR_OK )
+ ResetError();
+ if( !CanRead() || !rOp.CanRead() )
+ SetError( SbxERR_PROP_WRITEONLY );
+ else if( GetType() == SbxNULL && rOp.GetType() == SbxNULL )
+ bRes = TRUE;
+ else if( GetType() == SbxEMPTY && rOp.GetType() == SbxEMPTY )
+ bRes = TRUE;
+ // Sonderregel 1: Ist ein Operand Null, ist das Ergebnis FALSE
+ else if( GetType() == SbxNULL || rOp.GetType() == SbxNULL )
+ bRes = FALSE;
+ // Sonderregel 2: Wenn beide Variant sind und einer ist numerisch,
+ // und der andere ein String, ist num < str
+ else if( !IsFixed() && !rOp.IsFixed()
+ && ( rOp.GetType() == SbxSTRING && GetType() != SbxSTRING && IsNumeric() ) )
+ bRes = BOOL( eOp == SbxLT || eOp == SbxLE || eOp == SbxNE );
+ else if( !IsFixed() && !rOp.IsFixed()
+ && ( GetType() == SbxSTRING && rOp.GetType() != SbxSTRING && rOp.IsNumeric() ) )
+ bRes = BOOL( eOp == SbxGT || eOp == SbxGE || eOp == SbxNE );
+ else
+ {
+ SbxValues aL, aR;
+ // Wenn einer der Operanden ein String ist,
+ // findet ein Stringvergleich statt
+ if( GetType() == SbxSTRING || rOp.GetType() == SbxSTRING )
+ {
+ aL.eType = aR.eType = SbxSTRING;
+ if( Get( aL ) && rOp.Get( aR ) ) switch( eOp )
+ {
+ case SbxEQ:
+ bRes = BOOL( *aL.pString == *aR.pString ); break;
+ case SbxNE:
+ bRes = BOOL( *aL.pString != *aR.pString ); break;
+ case SbxLT:
+ bRes = BOOL( *aL.pString < *aR.pString ); break;
+ case SbxGT:
+ bRes = BOOL( *aL.pString > *aR.pString ); break;
+ case SbxLE:
+ bRes = BOOL( *aL.pString <= *aR.pString ); break;
+ case SbxGE:
+ bRes = BOOL( *aL.pString >= *aR.pString ); break;
+ default:
+ SetError( SbxERR_NOTIMP );
+ }
+ }
+ // AB 19.12.95: Wenn SbxSINGLE beteiligt, auf SINGLE konvertieren,
+ // sonst gibt es numerische Fehler
+ else if( GetType() == SbxSINGLE || rOp.GetType() == SbxSINGLE )
+ {
+ aL.eType = aR.eType = SbxSINGLE;
+ if( Get( aL ) && rOp.Get( aR ) )
+ switch( eOp )
+ {
+ case SbxEQ:
+ bRes = BOOL( aL.nSingle == aR.nSingle ); break;
+ case SbxNE:
+ bRes = BOOL( aL.nSingle != aR.nSingle ); break;
+ case SbxLT:
+ bRes = BOOL( aL.nSingle < aR.nSingle ); break;
+ case SbxGT:
+ bRes = BOOL( aL.nSingle > aR.nSingle ); break;
+ case SbxLE:
+ bRes = BOOL( aL.nSingle <= aR.nSingle ); break;
+ case SbxGE:
+ bRes = BOOL( aL.nSingle >= aR.nSingle ); break;
+ default:
+ SetError( SbxERR_NOTIMP );
+ }
+ }
+ else if( GetType() == SbxDECIMAL && rOp.GetType() == SbxDECIMAL )
+ {
+ aL.eType = aR.eType = SbxDECIMAL;
+ Get( aL );
+ rOp.Get( aR );
+ if( aL.pDecimal && aR.pDecimal )
+ {
+ SbxDecimal::CmpResult eRes = compare( *aL.pDecimal, *aR.pDecimal );
+ switch( eOp )
+ {
+ case SbxEQ:
+ bRes = BOOL( eRes == SbxDecimal::EQ ); break;
+ case SbxNE:
+ bRes = BOOL( eRes != SbxDecimal::EQ ); break;
+ case SbxLT:
+ bRes = BOOL( eRes == SbxDecimal::LT ); break;
+ case SbxGT:
+ bRes = BOOL( eRes == SbxDecimal::GT ); break;
+ case SbxLE:
+ bRes = BOOL( eRes != SbxDecimal::GT ); break;
+ case SbxGE:
+ bRes = BOOL( eRes != SbxDecimal::LT ); break;
+ default:
+ SetError( SbxERR_NOTIMP );
+ }
+ }
+ else
+ {
+ SetError( SbxERR_CONVERSION );
+ }
+ releaseDecimalPtr( aL.pDecimal );
+ releaseDecimalPtr( aR.pDecimal );
+ }
+ // Alles andere auf SbxDOUBLE-Basis vergleichen
+ else
+ {
+ aL.eType = aR.eType = SbxDOUBLE;
+ if( Get( aL ) && rOp.Get( aR ) )
+ switch( eOp )
+ {
+ case SbxEQ:
+ bRes = BOOL( aL.nDouble == aR.nDouble ); break;
+ case SbxNE:
+ bRes = BOOL( aL.nDouble != aR.nDouble ); break;
+ case SbxLT:
+ bRes = BOOL( aL.nDouble < aR.nDouble ); break;
+ case SbxGT:
+ bRes = BOOL( aL.nDouble > aR.nDouble ); break;
+ case SbxLE:
+ bRes = BOOL( aL.nDouble <= aR.nDouble ); break;
+ case SbxGE:
+ bRes = BOOL( aL.nDouble >= aR.nDouble ); break;
+ default:
+ SetError( SbxERR_NOTIMP );
+ }
+ }
+ }
+ if( eOld != SbxERR_OK )
+ SetError( eOld );
+ return bRes;
+}
+
+///////////////////////////// Lesen/Schreiben ////////////////////////////
+
+BOOL SbxValue::LoadData( SvStream& r, USHORT )
+{
+ SbxValue::Clear();
+ UINT16 nType;
+ r >> nType;
+ aData.eType = SbxDataType( nType );
+ switch( nType )
+ {
+ case SbxBOOL:
+ case SbxINTEGER:
+ r >> aData.nInteger; break;
+ case SbxLONG:
+ r >> aData.nLong; break;
+ case SbxSINGLE:
+ {
+ // Floats als ASCII
+ XubString aVal;
+ r.ReadByteString( aVal, RTL_TEXTENCODING_ASCII_US );
+ double d;
+ SbxDataType t;
+ if( ImpScan( aVal, d, t, NULL ) != SbxERR_OK || t == SbxDOUBLE )
+ {
+ aData.nSingle = 0.0F;
+ return FALSE;
+ }
+ aData.nSingle = (float) d;
+ break;
+ }
+ case SbxDATE:
+ case SbxDOUBLE:
+ {
+ // Floats als ASCII
+ XubString aVal;
+ r.ReadByteString( aVal, RTL_TEXTENCODING_ASCII_US );
+ SbxDataType t;
+ if( ImpScan( aVal, aData.nDouble, t, NULL ) != SbxERR_OK )
+ {
+ aData.nDouble = 0.0;
+ return FALSE;
+ }
+ break;
+ }
+ case SbxULONG64:
+ {
+ r >> aData.nULong64.nHigh >> aData.nULong64.nLow;
+ break;
+ }
+ case SbxLONG64:
+ case SbxCURRENCY:
+ {
+ r >> aData.nLong64.nHigh >> aData.nLong64.nLow;
+ break;
+ }
+ case SbxSTRING:
+ {
+ XubString aVal;
+ r.ReadByteString( aVal, RTL_TEXTENCODING_ASCII_US );
+ if( aVal.Len() )
+ aData.pString = new XubString( aVal );
+ else
+ aData.pString = NULL; // JSM 22.09.1995
+ break;
+ }
+ case SbxERROR:
+ case SbxUSHORT:
+ r >> aData.nUShort; break;
+ case SbxOBJECT:
+ {
+ BYTE nMode;
+ r >> nMode;
+ switch( nMode )
+ {
+ case 0:
+ aData.pObj = NULL;
+ break;
+ case 1:
+ aData.pObj = SbxBase::Load( r );
+ return BOOL( aData.pObj != NULL );
+ case 2:
+ aData.pObj = this;
+ break;
+ }
+ break;
+ }
+ case SbxCHAR:
+ {
+ char c;
+ r >> c;
+ aData.nChar = c;
+ break;
+ }
+ case SbxBYTE:
+ r >> aData.nByte; break;
+ case SbxULONG:
+ r >> aData.nULong; break;
+ case SbxINT:
+ {
+ BYTE n;
+ r >> n;
+ // Passt der Int auf diesem System?
+ if( n > SAL_TYPES_SIZEOFINT )
+ r >> aData.nLong, aData.eType = SbxLONG;
+ else
+ r >> aData.nInt;
+ break;
+ }
+ case SbxUINT:
+ {
+ BYTE n;
+ r >> n;
+ // Passt der UInt auf diesem System?
+ if( n > SAL_TYPES_SIZEOFINT )
+ r >> aData.nULong, aData.eType = SbxULONG;
+ else
+ r >> (sal_uInt32&)aData.nUInt;
+ break;
+ }
+ case SbxEMPTY:
+ case SbxNULL:
+ case SbxVOID:
+ break;
+ case SbxDATAOBJECT:
+ r >> aData.nLong;
+ break;
+ // #78919 For backwards compatibility
+ case SbxWSTRING:
+ case SbxWCHAR:
+ break;
+ default:
+ memset (&aData,0,sizeof(aData));
+ ResetFlag(SBX_FIXED);
+ aData.eType = SbxNULL;
+ DBG_ASSERT( !this, "Nicht unterstuetzer Datentyp geladen" );
+ return FALSE;
+ }
+ return TRUE;
+}
+
+BOOL SbxValue::StoreData( SvStream& r ) const
+{
+ UINT16 nType = sal::static_int_cast< UINT16 >(aData.eType);
+ r << nType;
+ switch( nType & 0x0FFF )
+ {
+ case SbxBOOL:
+ case SbxINTEGER:
+ r << aData.nInteger; break;
+ case SbxLONG:
+ r << aData.nLong; break;
+ case SbxDATE:
+ // #49935: Als double speichern, sonst Fehler beim Einlesen
+ ((SbxValue*)this)->aData.eType = (SbxDataType)( ( nType & 0xF000 ) | SbxDOUBLE );
+ r.WriteByteString( GetCoreString(), RTL_TEXTENCODING_ASCII_US );
+ ((SbxValue*)this)->aData.eType = (SbxDataType)nType;
+ break;
+ case SbxSINGLE:
+ case SbxDOUBLE:
+ r.WriteByteString( GetCoreString(), RTL_TEXTENCODING_ASCII_US );
+ break;
+ case SbxULONG64:
+ {
+ r << aData.nULong64.nHigh << aData.nULong64.nLow;
+ break;
+ }
+ case SbxLONG64:
+ case SbxCURRENCY:
+ {
+ r << aData.nLong64.nHigh << aData.nLong64.nLow;
+ break;
+ }
+ case SbxSTRING:
+ if( aData.pString )
+ {
+ r.WriteByteString( *aData.pString, RTL_TEXTENCODING_ASCII_US );
+ }
+ else
+ {
+ String aEmpty;
+ r.WriteByteString( aEmpty, RTL_TEXTENCODING_ASCII_US );
+ }
+ break;
+ case SbxERROR:
+ case SbxUSHORT:
+ r << aData.nUShort; break;
+ case SbxOBJECT:
+ // sich selbst als Objektptr speichern geht nicht!
+ if( aData.pObj )
+ {
+ if( PTR_CAST(SbxValue,aData.pObj) != this )
+ {
+ r << (BYTE) 1;
+ return aData.pObj->Store( r );
+ }
+ else
+ r << (BYTE) 2;
+ }
+ else
+ r << (BYTE) 0;
+ break;
+ case SbxCHAR:
+ {
+ char c = sal::static_int_cast< char >(aData.nChar);
+ r << c;
+ break;
+ }
+ case SbxBYTE:
+ r << aData.nByte; break;
+ case SbxULONG:
+ r << aData.nULong; break;
+ case SbxINT:
+ {
+ BYTE n = SAL_TYPES_SIZEOFINT;
+ r << n << (sal_Int32)aData.nInt;
+ break;
+ }
+ case SbxUINT:
+ {
+ BYTE n = SAL_TYPES_SIZEOFINT;
+ r << n << (sal_uInt32)aData.nUInt;
+ break;
+ }
+ case SbxEMPTY:
+ case SbxNULL:
+ case SbxVOID:
+ break;
+ case SbxDATAOBJECT:
+ r << aData.nLong;
+ break;
+ // #78919 For backwards compatibility
+ case SbxWSTRING:
+ case SbxWCHAR:
+ break;
+ default:
+ DBG_ASSERT( !this, "Speichern eines nicht unterstuetzten Datentyps" );
+ return FALSE;
+ }
+ return TRUE;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/sbx/sbxvar.cxx b/binfilter/bf_basic/source/sbx/sbxvar.cxx
new file mode 100644
index 000000000000..43c431ba847d
--- /dev/null
+++ b/binfilter/bf_basic/source/sbx/sbxvar.cxx
@@ -0,0 +1,565 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#include <tools/stream.hxx>
+#include "bf_svtools/brdcst.hxx"
+
+#include "sbx.hxx"
+#include "sbxbase.hxx"
+#include "sbxres.hxx"
+#include "sbxconv.hxx"
+#include <math.h>
+#include <ctype.h>
+
+namespace binfilter {
+
+///////////////////////////// SbxVariable //////////////////////////////
+
+TYPEINIT1(SbxVariable,SbxValue)
+TYPEINIT1(SbxHint,SfxSimpleHint)
+
+extern UINT32 nVarCreator; // in SBXBASE.CXX, fuer LoadData()
+#ifdef DBG_UTIL
+static ULONG nVar = 0;
+#endif
+
+///////////////////////////// Konstruktoren //////////////////////////////
+
+SbxVariable::SbxVariable() : SbxValue()
+{
+ pCst = NULL;
+ pParent = NULL;
+ nUserData = 0;
+ nHash = 0;
+#ifdef DBG_UTIL
+ DbgOutf( "SbxVariable::Ctor %lx=%ld", (void*)this, ++nVar );
+ GetSbxData_Impl()->aVars.Insert( this, LIST_APPEND );
+#endif
+}
+
+SbxVariable::SbxVariable( const SbxVariable& r )
+ : SvRefBase( r ), SbxValue( r ), mpPar( r.mpPar ), pInfo( r.pInfo )
+{
+ pCst = NULL;
+ if( r.CanRead() )
+ {
+ pParent = r.pParent;
+ nUserData = r.nUserData;
+ maName = r.maName;
+ nHash = r.nHash;
+ }
+ else
+ {
+ pParent = NULL;
+ nUserData = 0;
+ nHash = 0;
+ }
+#ifdef DBG_UTIL
+ static sal_Char const aCellsStr[] = "Cells";
+ if ( maName.EqualsAscii( aCellsStr ) )
+ maName.AssignAscii( aCellsStr, sizeof( aCellsStr )-1 );
+ DbgOutf( "SbxVariable::Ctor %lx=%ld", (void*)this, ++nVar );
+ GetSbxData_Impl()->aVars.Insert( this, LIST_APPEND );
+#endif
+}
+
+SbxVariable::SbxVariable( SbxDataType t, void* p ) : SbxValue( t, p )
+{
+ pCst = NULL;
+ pParent = NULL;
+ nUserData = 0;
+ nHash = 0;
+#ifdef DBG_UTIL
+ DbgOutf( "SbxVariable::Ctor %lx=%ld", (void*)this, ++nVar );
+ GetSbxData_Impl()->aVars.Insert( this, LIST_APPEND );
+#endif
+}
+
+SbxVariable::~SbxVariable()
+{
+#ifdef DBG_UTIL
+ ByteString aBStr( (const UniString&)maName, RTL_TEXTENCODING_ASCII_US );
+ DbgOutf( "SbxVariable::Dtor %lx (%s)", (void*)this, aBStr.GetBuffer() );
+ static sal_Char const aCellsStr[] = "Cells";
+ if ( maName.EqualsAscii( aCellsStr ) )
+ maName.AssignAscii( aCellsStr, sizeof( aCellsStr )-1 );
+ GetSbxData_Impl()->aVars.Remove( this );
+#endif
+ delete pCst;
+}
+
+////////////////////////////// Broadcasting //////////////////////////////
+
+SfxBroadcaster& SbxVariable::GetBroadcaster()
+{
+ if( !pCst )
+ pCst = new SfxBroadcaster;
+ return *pCst;
+}
+
+// Eines Tages kann man vielleicht den Parameter 0 schleifen,
+// dann entfaellt die Kopiererei...
+
+void SbxVariable::Broadcast( ULONG nHintId )
+{
+ if( pCst && !IsSet( SBX_NO_BROADCAST ) && StaticIsEnabledBroadcasting() )
+ {
+ // Da die Methode von aussen aufrufbar ist, hier noch einmal
+ // die Berechtigung testen
+ if( nHintId & SBX_HINT_DATAWANTED )
+ if( !CanRead() )
+ return;
+ if( nHintId & SBX_HINT_DATACHANGED )
+ if( !CanWrite() )
+ return;
+ // Weitere Broadcasts verhindern
+ SfxBroadcaster* pSave = pCst;
+ pCst = NULL;
+ USHORT nSaveFlags = GetFlags();
+ SetFlag( SBX_READWRITE );
+ if( mpPar.Is() )
+ // this, als Element 0 eintragen, aber den Parent nicht umsetzen!
+ mpPar->GetRef( 0 ) = this;
+ pSave->Broadcast( SbxHint( nHintId, this ) );
+ delete pCst; // wer weiss schon, auf welche Gedanken mancher kommt?
+ pCst = pSave;
+ SetFlags( nSaveFlags );
+ }
+}
+
+SbxInfo* SbxVariable::GetInfo()
+{
+ if( !pInfo )
+ {
+ Broadcast( SBX_HINT_INFOWANTED );
+ if( pInfo.Is() )
+ SetModified( TRUE );
+ }
+ return pInfo;
+}
+
+void SbxVariable::SetParameters( SbxArray* p )
+{
+ mpPar = p;
+}
+
+
+/////////////////////////// Name der Variablen ///////////////////////////
+
+void SbxVariable::SetName( const XubString& rName )
+{
+ maName = rName;
+ nHash = MakeHashCode( rName );
+}
+
+const XubString& SbxVariable::GetName( SbxNameType t ) const
+{
+ static char cSuffixes[] = " %&!#@ $";
+ if( t == SbxNAME_NONE )
+ return maName;
+ // Parameter-Infos anfordern (nicht fuer Objekte)
+ ((SbxVariable*)this)->GetInfo();
+ // Nix anfuegen, wenn einfache Property (keine leeren Klammern)
+ if( !pInfo
+ || ( !pInfo->aParams.Count() && GetClass() == SbxCLASS_PROPERTY ) )
+ return maName;
+ xub_Unicode cType = ' ';
+ XubString aTmp( maName );
+ // Kurzer Typ? Dann holen, evtl. ist dieser 0.
+ SbxDataType et = GetType();
+ if( t == SbxNAME_SHORT_TYPES )
+ {
+ if( et <= SbxSTRING )
+ cType = cSuffixes[ et ];
+ if( cType != ' ' )
+ aTmp += cType;
+ }
+ aTmp += '(';
+ for( USHORT i = 0; i < pInfo->aParams.Count(); i++ )
+ {
+ const SbxParamInfo* q = pInfo->aParams.GetObject( i );
+ int nt = q->eType & 0x0FFF;
+ if( i )
+ aTmp += ',';
+ if( q->nFlags & SBX_OPTIONAL )
+ aTmp += SbxRes( STRING_OPTIONAL );
+ if( q->eType & SbxBYREF )
+ aTmp += SbxRes( STRING_BYREF );
+ aTmp += q->aName;
+ cType = ' ';
+ // Kurzer Typ? Dann holen, evtl. ist dieser 0.
+ if( t == SbxNAME_SHORT_TYPES )
+ {
+ if( nt <= SbxSTRING )
+ cType = cSuffixes[ nt ];
+ }
+ if( cType != ' ' )
+ {
+ aTmp += cType;
+ if( q->eType & SbxARRAY )
+ aTmp.AppendAscii( "()" );
+ }
+ else
+ {
+ if( q->eType & SbxARRAY )
+ aTmp.AppendAscii( "()" );
+ // langer Typ?
+ if( t != SbxNAME_SHORT )
+ {
+ aTmp += SbxRes( STRING_AS );
+ if( nt < 32 )
+ aTmp += SbxRes(
+ sal::static_int_cast< USHORT >( STRING_TYPES + nt ) );
+ else
+ aTmp += SbxRes( STRING_ANY );
+ }
+ }
+ }
+ aTmp += ')';
+ // Langer Typ? Dann holen
+ if( t == SbxNAME_LONG_TYPES && et != SbxEMPTY )
+ {
+ aTmp += SbxRes( STRING_AS );
+ if( et < 32 )
+ aTmp += SbxRes(
+ sal::static_int_cast< USHORT >( STRING_TYPES + et ) );
+ else
+ aTmp += SbxRes( STRING_ANY );
+ }
+ ((SbxVariable*) this)->aPic = aTmp;
+ return aPic;
+}
+
+// Einen simplen Hashcode erzeugen: Es werden die ersten 6 Zeichen gewertet.
+
+USHORT SbxVariable::MakeHashCode( const XubString& rName )
+{
+ USHORT n = 0;
+ USHORT nLen = rName.Len();
+ if( nLen > 6 )
+ nLen = 6;
+ const xub_Unicode* p = rName.GetBuffer();
+ while( nLen-- )
+ {
+ BYTE c = (BYTE)*p;
+ p++;
+ // Falls wir ein Schweinezeichen haben, abbrechen!!
+ if( c >= 0x80 )
+ return 0;
+ n = sal::static_int_cast< USHORT >( ( n << 3 ) + toupper( c ) );
+ }
+ return n;
+}
+
+////////////////////////////// Operatoren ////////////////////////////////
+
+SbxVariable& SbxVariable::operator=( const SbxVariable& r )
+{
+ SbxValue::operator=( r );
+ return *this;
+}
+
+//////////////////////////////// Konversion ////////////////////////////////
+
+SbxDataType SbxVariable::GetType() const
+{
+ if( aData.eType == SbxOBJECT )
+ return aData.pObj ? aData.pObj->GetType() : SbxOBJECT;
+ else if( aData.eType == SbxVARIANT )
+ return aData.pObj ? aData.pObj->GetType() : SbxVARIANT;
+ else
+ return aData.eType;
+}
+
+SbxClassType SbxVariable::GetClass() const
+{
+ return SbxCLASS_VARIABLE;
+}
+
+void SbxVariable::SetModified( BOOL b )
+{
+ if( IsSet( SBX_NO_MODIFY ) )
+ return;
+ SbxBase::SetModified( b );
+ if( pParent && pParent != this ) //??? HotFix: Rekursion raus MM
+ pParent->SetModified( b );
+}
+
+void SbxVariable::SetParent( SbxObject* p )
+{
+#ifdef DBG_UTIL
+ // wird der Parent eines SbxObjects gesetzt?
+ if ( p && ISA(SbxObject) )
+ {
+ // dann mu\s dieses auch Child vom neuen Parent sein
+ BOOL bFound = FALSE;
+ SbxArray *pChilds = p->GetObjects();
+ if ( pChilds )
+ {
+ for ( USHORT nIdx = 0; !bFound && nIdx < pChilds->Count(); ++nIdx )
+ bFound = ( this == pChilds->Get(nIdx) );
+ }
+ if ( !bFound )
+ {
+ String aMsg = String::CreateFromAscii( "dangling: [" );
+ aMsg += GetName();
+ aMsg.AppendAscii( "].SetParent([" );
+ aMsg += p->GetName();
+ aMsg.AppendAscii( "])" );
+ ByteString aBStr( (const UniString&)aMsg, RTL_TEXTENCODING_ASCII_US );
+ DbgOut( aBStr.GetBuffer(), DBG_OUT_WARNING, __FILE__, __LINE__);
+ }
+ }
+#endif
+
+ pParent = p;
+}
+
+////////////////////////////// Laden/Speichern /////////////////////////////
+
+BOOL SbxVariable::LoadData( SvStream& rStrm, USHORT nVer )
+{
+ UINT16 nType;
+ BYTE cMark;
+ rStrm >> cMark;
+ if( cMark == 0xFF )
+ {
+ if( !SbxValue::LoadData( rStrm, nVer ) )
+ return FALSE;
+ rStrm.ReadByteString( maName, RTL_TEXTENCODING_ASCII_US );
+ rStrm >> nUserData;
+ }
+ else
+ {
+ rStrm.SeekRel( -1L );
+ rStrm >> nType;
+ rStrm.ReadByteString( maName, RTL_TEXTENCODING_ASCII_US );
+ rStrm >> nUserData;
+ // Korrektur: Alte Methoden haben statt SbxNULL jetzt SbxEMPTY
+ if( nType == SbxNULL && GetClass() == SbxCLASS_METHOD )
+ nType = SbxEMPTY;
+ SbxValues aTmp;
+ XubString aVal;
+ aTmp.eType = aData.eType = (SbxDataType) nType;
+ aTmp.pString = &aVal;
+ switch( nType )
+ {
+ case SbxBOOL:
+ case SbxERROR:
+ case SbxINTEGER:
+ rStrm >> aTmp.nInteger; break;
+ case SbxLONG:
+ rStrm >> aTmp.nLong; break;
+ case SbxSINGLE:
+ {
+ // Floats als ASCII
+ rStrm.ReadByteString( aVal, RTL_TEXTENCODING_ASCII_US );
+ double d;
+ SbxDataType t;
+ if( ImpScan( aVal, d, t, NULL ) != SbxERR_OK || t == SbxDOUBLE )
+ {
+ aTmp.nSingle = 0;
+ return FALSE;
+ }
+ aTmp.nSingle = (float) d;
+ break;
+ }
+ case SbxDATE:
+ case SbxDOUBLE:
+ {
+ // Floats als ASCII
+ rStrm.ReadByteString( aVal, RTL_TEXTENCODING_ASCII_US );
+ SbxDataType t;
+ if( ImpScan( aVal, aTmp.nDouble, t, NULL ) != SbxERR_OK )
+ {
+ aTmp.nDouble = 0;
+ return FALSE;
+ }
+ break;
+ }
+ case SbxSTRING:
+ rStrm.ReadByteString( aVal, RTL_TEXTENCODING_ASCII_US );
+ break;
+ case SbxEMPTY:
+ case SbxNULL:
+ break;
+ default:
+ aData.eType = SbxNULL;
+ DBG_ASSERT( !this, "Nicht unterstuetzer Datentyp geladen" );
+ return FALSE;
+ }
+ // Wert putten
+ if( nType != SbxNULL && nType != SbxEMPTY && !Put( aTmp ) )
+ return FALSE;
+ }
+ rStrm >> cMark;
+ // cMark ist auch eine Versionsnummer!
+ // 1: initial version
+ // 2: mit nUserData
+ if( cMark )
+ {
+ if( cMark > 2 )
+ return FALSE;
+ pInfo = new SbxInfo;
+ pInfo->LoadData( rStrm, (USHORT) cMark );
+ }
+ // Privatdaten nur laden, wenn es eine SbxVariable ist
+ if( GetClass() == SbxCLASS_VARIABLE && !LoadPrivateData( rStrm, nVer ) )
+ return FALSE;
+ ((SbxVariable*) this)->Broadcast( SBX_HINT_DATACHANGED );
+ nHash = MakeHashCode( maName );
+ SetModified( TRUE );
+ return TRUE;
+}
+
+BOOL SbxVariable::StoreData( SvStream& rStrm ) const
+{
+ rStrm << (BYTE) 0xFF; // Marker
+ BOOL bValStore;
+ if( this->IsA( TYPE(SbxMethod) ) )
+ {
+ // #50200 Verhindern, dass Objekte, die zur Laufzeit als Return-Wert
+ // in der Methode als Value gespeichert sind, mit gespeichert werden
+ SbxVariable* pThis = (SbxVariable*)this;
+ USHORT nSaveFlags = GetFlags();
+ pThis->SetFlag( SBX_WRITE );
+ pThis->SbxValue::Clear();
+ pThis->SetFlags( nSaveFlags );
+
+ // Damit die Methode in keinem Fall ausgefuehrt wird!
+ // CAST, um const zu umgehen!
+ pThis->SetFlag( SBX_NO_BROADCAST );
+ bValStore = SbxValue::StoreData( rStrm );
+ pThis->ResetFlag( SBX_NO_BROADCAST );
+ }
+ else
+ bValStore = SbxValue::StoreData( rStrm );
+ if( !bValStore )
+ return FALSE;
+ // if( !SbxValue::StoreData( rStrm ) )
+ // return FALSE;
+ rStrm.WriteByteString( maName, RTL_TEXTENCODING_ASCII_US );
+ rStrm << nUserData;
+ if( pInfo.Is() )
+ {
+ rStrm << (BYTE) 2; // Version 2: mit UserData!
+ pInfo->StoreData( rStrm );
+ }
+ else
+ rStrm << (BYTE) 0;
+ // Privatdaten nur speichern, wenn es eine SbxVariable ist
+ if( GetClass() == SbxCLASS_VARIABLE )
+ return StorePrivateData( rStrm );
+ else
+ return TRUE;
+}
+
+////////////////////////////// SbxInfo ///////////////////////////////////
+
+SbxInfo::SbxInfo() : aHelpFile(), nHelpId( 0 ), aParams()
+{}
+
+////////////////////////////// SbxAlias //////////////////////////////////
+
+SbxAlias::SbxAlias( const SbxAlias& r )
+ : SvRefBase( r ), SbxVariable( r ),
+ SfxListener( r ), xAlias( r.xAlias )
+{}
+
+SbxAlias& SbxAlias::operator=( const SbxAlias& r )
+{
+ xAlias = r.xAlias;
+ return *this;
+}
+
+SbxAlias::~SbxAlias()
+{
+ if( xAlias.Is() )
+ EndListening( xAlias->GetBroadcaster() );
+}
+
+void SbxAlias::Broadcast( ULONG nHt )
+{
+ if( xAlias.Is() && StaticIsEnabledBroadcasting() )
+ {
+ xAlias->SetParameters( GetParameters() );
+ if( nHt == SBX_HINT_DATAWANTED )
+ SbxVariable::operator=( *xAlias );
+ else if( nHt == SBX_HINT_DATACHANGED || nHt == SBX_HINT_CONVERTED )
+ *xAlias = *this;
+ else if( nHt == SBX_HINT_INFOWANTED )
+ {
+ xAlias->Broadcast( nHt );
+ pInfo = xAlias->GetInfo();
+ }
+ }
+}
+
+void SbxAlias::SFX_NOTIFY( SfxBroadcaster&, const TypeId&,
+ const SfxHint& rHint, const TypeId& )
+{
+ const SbxHint* p = PTR_CAST(SbxHint,&rHint);
+ if( p && p->GetId() == SBX_HINT_DYING )
+ {
+ xAlias.Clear();
+ // Alias loeschen?
+ if( pParent )
+ pParent->Remove( this );
+ }
+}
+
+void SbxVariable::Dump( SvStream& rStrm, BOOL bFill )
+{
+ ByteString aBNameStr( (const UniString&)GetName( SbxNAME_SHORT_TYPES ), RTL_TEXTENCODING_ASCII_US );
+ rStrm << "Variable( "
+ << ByteString::CreateFromInt64( (ULONG) this ).GetBuffer() << "=="
+ << aBNameStr.GetBuffer();
+ ByteString aBParentNameStr( (const UniString&)GetParent()->GetName(), RTL_TEXTENCODING_ASCII_US );
+ if ( GetParent() )
+ rStrm << " in parent '" << aBParentNameStr.GetBuffer() << "'";
+ else
+ rStrm << " no parent";
+ rStrm << " ) ";
+
+ // bei Object-Vars auch das Object ausgeben
+ if ( GetValues_Impl().eType == SbxOBJECT &&
+ GetValues_Impl().pObj &&
+ GetValues_Impl().pObj != this &&
+ GetValues_Impl().pObj != GetParent() )
+ {
+ rStrm << " contains ";
+ ((SbxObject*) GetValues_Impl().pObj)->Dump( rStrm, bFill );
+ }
+ else
+ rStrm << endl;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/util/makefile.mk b/binfilter/bf_basic/util/makefile.mk
new file mode 100644
index 000000000000..5c20d63dcd27
--- /dev/null
+++ b/binfilter/bf_basic/util/makefile.mk
@@ -0,0 +1,88 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+BFPRJ=..
+PRJ=..$/..
+
+PRJNAME=binfilter
+TARGET=bf_sb
+
+# --- Settings ---------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Allgemein ---------------------------------------------------
+
+LIB1TARGET=$(SLB)$/$(TARGET).lib
+LIB1FILES= \
+ $(SLB)$/basic_basicmgr.lib \
+ $(SLB)$/basic_sbx.lib \
+ $(SLB)$/basic_classes.lib \
+ $(SLB)$/basic_comp.lib \
+ $(SLB)$/basic_runtime.lib
+
+SHL1TARGET=$(TARGET)$(DLLPOSTFIX)
+SHL1IMPLIB=$(TARGET)
+
+SHL1STDLIBS= \
+ $(TOOLSLIB) \
+ $(CPPULIB) \
+ $(CPPUHELPERLIB) \
+ $(BFSVTOOLLIB) \
+ $(SALLIB) \
+ $(COMPHELPERLIB) \
+ $(UNOTOOLSLIB) \
+ $(SOTLIB) \
+ $(VCLLIB)
+
+.IF "$(GUI)"=="WNT"
+SHL1STDLIBS+= \
+ $(UWINAPILIB) \
+ $(OLEAUT32LIB)
+.ENDIF # WNT
+
+SHL1DEF= $(MISC)$/$(SHL1TARGET).def
+SHL1LIBS= $(SLB)$/$(TARGET).lib
+
+DEF1NAME =$(SHL1TARGET)
+DEF1DEPN = \
+ $(MISC)$/$(SHL1TARGET).flt
+
+DEFLIB1NAME =$(TARGET)
+
+# --- Targets -----------------------------------------------------------
+
+.INCLUDE : target.mk
+
+# --- Basic-Filter-Datei ---
+
+$(MISC)$/$(SHL1TARGET).flt: makefile.mk
+ @echo ------------------------------
+ @echo Making: $@
+ @echo __CT >> $@
+
+