diff options
Diffstat (limited to 'cppuhelper/source')
-rw-r--r-- | cppuhelper/source/component.cxx | 212 | ||||
-rw-r--r-- | cppuhelper/source/exc_thrower.cxx | 287 | ||||
-rw-r--r-- | cppuhelper/source/factory.cxx | 719 | ||||
-rw-r--r-- | cppuhelper/source/implbase.cxx | 227 | ||||
-rw-r--r-- | cppuhelper/source/interfacecontainer.cxx | 383 | ||||
-rw-r--r-- | cppuhelper/source/makefile.mk | 167 | ||||
-rw-r--r-- | cppuhelper/source/propshlp.cxx | 1106 | ||||
-rw-r--r-- | cppuhelper/source/servicefactory.cxx | 507 | ||||
-rw-r--r-- | cppuhelper/source/stdidlclass.cxx | 240 | ||||
-rw-r--r-- | cppuhelper/source/typeprovider.cxx | 344 | ||||
-rw-r--r-- | cppuhelper/source/weak.cxx | 521 |
11 files changed, 4713 insertions, 0 deletions
diff --git a/cppuhelper/source/component.cxx b/cppuhelper/source/component.cxx new file mode 100644 index 000000000000..1e21d6e7a554 --- /dev/null +++ b/cppuhelper/source/component.cxx @@ -0,0 +1,212 @@ +/************************************************************************* + * + * $RCSfile: component.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:26:10 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _OSL_DIAGNOSE_H_ +#include <osl/diagnose.h> +#endif +#ifndef _CPPUHELPER_COMPONENT_HXX_ +#include <cppuhelper/component.hxx> +#endif +#ifndef _CPPUHELPER_QUERYINTERFACE_HXX_ +#include <cppuhelper/queryinterface.hxx> +#endif + +using namespace osl; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::lang; + +namespace cppu +{ + +// ---------------------------------------------------- +// class OComponentHelper +// ---------------------------------------------------- +OComponentHelper::OComponentHelper( Mutex & rMutex ) + : rBHelper( rMutex ) +{ +} + +/** + * Call dispose if not previous called. + */ +OComponentHelper::~OComponentHelper() +{ +} + +// XInterface +void OComponentHelper::release() throw() +{ + Reference<XInterface > x( xDelegator ); + if (! x.is()) + { + if (osl_decrementInterlockedCount( &m_refCount ) == 0) + { + if (! rBHelper.bDisposed) + { + Reference<XInterface > xHoldAlive( *this ); + // First dispose + try + { + dispose(); + } + catch(::com::sun::star::uno::Exception&) + { + // release should not throw exceptions + } + + // only the alive ref holds the object + OSL_ASSERT( m_refCount == 1 ); + // destroy the object if xHoldAlive decrement the refcount to 0 + return; + } + } + // restore the reference count + osl_incrementInterlockedCount( &m_refCount ); + } + OWeakAggObject::release(); +} + +// XComponent +void OComponentHelper::disposing() +{ +} + +// XComponent +void OComponentHelper::dispose() + throw(::com::sun::star::uno::RuntimeException) +{ + // An frequently programming error is to release the last + // reference to this object in the disposing message. + // Make it rubust, hold a self Reference. + Reference<XComponent > xSelf( this ); + + // Guard dispose against multible threading + // Remark: It is an error to call dispose more than once + sal_Bool bDoDispose = sal_False; + { + MutexGuard aGuard( rBHelper.rMutex ); + if( !rBHelper.bDisposed && !rBHelper.bInDispose ) + { + // only one call go into this section + rBHelper.bInDispose = sal_True; + bDoDispose = sal_True; + } + } + + OSL_ENSHURE( bDoDispose, "dispose called twice" ); + // Do not hold the mutex because we are broadcasting + if( bDoDispose ) + { + // Create an event with this as sender + try + { + Reference<XInterface > xSource( Reference<XInterface >::query( (XComponent *)this ) ); + EventObject aEvt; + aEvt.Source = xSource; + // inform all listeners to release this object + // The listener container are automaticly cleared + rBHelper.aLC.disposeAndClear( aEvt ); + // notify subclasses to do their dispose + disposing(); + } + catch(::com::sun::star::uno::Exception& e) + { + // catch exception and throw again but signal that + // the object was disposed. Dispose should be called + // only once. + rBHelper.bDisposed = sal_True; + rBHelper.bInDispose = sal_False; + throw e; + } + + // the values bDispose and bInDisposing must set in this order. + // No multithread call overcome the "!rBHelper.bDisposed && !rBHelper.bInDispose" guard. + rBHelper.bDisposed = sal_True; + rBHelper.bInDispose = sal_False; + } +} + +// XComponent +void OComponentHelper::addEventListener(const Reference<XEventListener > & rxListener) + throw(::com::sun::star::uno::RuntimeException) +{ + MutexGuard aGuard( rBHelper.rMutex ); + OSL_ENSHURE( !rBHelper.bInDispose, "do not add listeners in the dispose call" ); + OSL_ENSHURE( !rBHelper.bDisposed, "object is disposed" ); + if( !rBHelper.bInDispose && !rBHelper.bDisposed ) + // only add listeners if you are not disposed + rBHelper.aLC.addInterface( ::getCppuType( (Reference< XEventListener > *)0 ), rxListener ); +} + +// XComponent +void OComponentHelper::removeEventListener(const Reference<XEventListener > & rxListener) + throw(::com::sun::star::uno::RuntimeException) +{ + MutexGuard aGuard( rBHelper.rMutex ); + OSL_ENSHURE( !rBHelper.bDisposed, "object is disposed" ); + // all listeners are automaticly released in a dispose call + if( !rBHelper.bInDispose && !rBHelper.bDisposed ) + rBHelper.aLC.removeInterface( ::getCppuType( (Reference< XEventListener > *)0 ), rxListener ); +} + +} + diff --git a/cppuhelper/source/exc_thrower.cxx b/cppuhelper/source/exc_thrower.cxx new file mode 100644 index 000000000000..3fc8103d865e --- /dev/null +++ b/cppuhelper/source/exc_thrower.cxx @@ -0,0 +1,287 @@ +/************************************************************************* + * + * $RCSfile: exc_thrower.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:26:10 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _OSL_DIAGNOSE_H_ +#include <osl/diagnose.h> +#endif +#ifndef _OSL_INTERLOCK_H_ +#include <osl/interlck.h> +#endif +#ifndef _UNO_DISPATCHER_H_ +#include <uno/dispatcher.h> +#endif +#ifndef _UNO_MAPPING_HXX_ +#include <uno/mapping.hxx> +#endif + +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Exception.hpp> +#include <com/sun/star/uno/RuntimeException.hpp> +#include <com/sun/star/uno/XInterface.hpp> + +using namespace com::sun::star::uno; +using namespace rtl; + + +namespace cppu +{ + +//************************************** generated, slightly modified for unicode revision +class XThrower : public ::com::sun::star::uno::XInterface +{ +public: + + // Methods + virtual void SAL_CALL throwException( const ::com::sun::star::uno::Any& rExc ) throw(::com::sun::star::uno::Exception) = 0; +}; + +static +const ::com::sun::star::uno::Type& getCppuType( const ::com::sun::star::uno::Reference< ::cppu::XThrower >* ) +{ + static ::com::sun::star::uno::Type * pType_cppu_XThrower = 0; + + if ( !pType_cppu_XThrower ) + { + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + if ( !pType_cppu_XThrower ) + { + // Start inline typedescription generation + typelib_InterfaceTypeDescription * pTD = 0; + + const Type & rSuperType = ::getCppuType( ( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > *)0 ); + typelib_TypeDescriptionReference * pMembers[1] = { 0 }; + OUString aMemberTypeName( RTL_CONSTASCII_USTRINGPARAM("cppu.XThrower::throwException") ); + typelib_typedescriptionreference_new( &pMembers[0], + (typelib_TypeClass)::com::sun::star::uno::TypeClass_INTERFACE_METHOD, + aMemberTypeName.pData ); + + OUString aTypeName( RTL_CONSTASCII_USTRINGPARAM("cppu.XThrower") ); + typelib_typedescription_newInterface( + &pTD, + aTypeName.pData, 0x3313e220, 0xb491, 0xb491, 0x9ede0050, 0x04d7677e, + rSuperType.getTypeLibType(), + 1, + pMembers ); + + typelib_typedescription_register( (typelib_TypeDescription**)&pTD ); + typelib_typedescriptionreference_release( pMembers[0] ); + typelib_typedescription_release( (typelib_TypeDescription*)pTD ); + + static ::com::sun::star::uno::Type aType_cppu_XThrower( + ::com::sun::star::uno::TypeClass_INTERFACE, aTypeName.pData ); + ::getCppuType( (const ::com::sun::star::uno::Exception*)0 ); + + typelib_InterfaceMethodTypeDescription * pMethod = 0; + { + typelib_Parameter_Init aParameters[1]; + OUString aParamName( RTL_CONSTASCII_USTRINGPARAM("rExc") ); + aParameters[0].pParamName = aParamName.pData; + aParameters[0].eTypeClass = (typelib_TypeClass)::com::sun::star::uno::TypeClass_ANY; + OUString aParamTypeName( RTL_CONSTASCII_USTRINGPARAM("any") ); + aParameters[0].pTypeName = aParamTypeName.pData; + aParameters[0].bIn = sal_True; + aParameters[0].bOut = sal_False; + OUString aExceptionName( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.Exception") ); + OUString aVoidName( RTL_CONSTASCII_USTRINGPARAM("void") ); + typelib_typedescription_newInterfaceMethod( &pMethod, + 3, sal_False, + aMemberTypeName.pData, + (typelib_TypeClass)::com::sun::star::uno::TypeClass_VOID, aVoidName.pData, + 1, aParameters, + 1, &aExceptionName.pData ); + typelib_typedescription_register( (typelib_TypeDescription**)&pMethod ); + } + typelib_typedescription_release( (typelib_TypeDescription*)pMethod ); + // End inline typedescription generation + pType_cppu_XThrower = &aType_cppu_XThrower; + } + } + return *pType_cppu_XThrower; +} +//************************************** + + +//================================================================================================== +struct ExceptionThrower : public uno_Interface +{ + oslInterlockedCount nRef; + + inline ExceptionThrower(); +}; +//-------------------------------------------------------------------------------------------------- +void SAL_CALL ExceptionThrower_acquire( uno_Interface * pUnoI ) +{ + osl_incrementInterlockedCount( & SAL_STATIC_CAST( ExceptionThrower *, pUnoI )->nRef ); +} +//-------------------------------------------------------------------------------------------------- +void SAL_CALL ExceptionThrower_release( uno_Interface * pUnoI ) +{ + if (! osl_decrementInterlockedCount( & SAL_STATIC_CAST( ExceptionThrower *, pUnoI )->nRef )) + delete SAL_STATIC_CAST( ExceptionThrower *, pUnoI ); +} +//-------------------------------------------------------------------------------------------------- +static void SAL_CALL ExceptionThrower_dispatch( + uno_Interface * pUnoI, const typelib_TypeDescription * pMemberType, + void * pReturn, void * pArgs[], uno_Any ** ppException ) +{ + OSL_ASSERT( pMemberType->eTypeClass == typelib_TypeClass_INTERFACE_METHOD ); + + switch (((typelib_InterfaceMemberTypeDescription *)pMemberType)->nPosition) + { + case 0: // queryInterace() + { + if (::getCppuType( (const Reference< XInterface > *)0 ).equals( *(const Type *)pArgs[0] )) + { + const Type & rType = ::getCppuType( (const Reference< XInterface > *)0 ); + typelib_TypeDescription * pTD = 0; + TYPELIB_DANGER_GET( &pTD, rType.getTypeLibType() ); + uno_any_construct( (uno_Any *)pReturn, &pUnoI, pTD, 0 ); + TYPELIB_DANGER_RELEASE( pTD ); + } + else if (getCppuType( (const Reference< XThrower > *)0 ).equals( *(const Type *)pArgs[0] )) + { + const Type & rType = getCppuType( (const Reference< XThrower > *)0 ); + typelib_TypeDescription * pTD = 0; + TYPELIB_DANGER_GET( &pTD, rType.getTypeLibType() ); + uno_any_construct( (uno_Any *)pReturn, &pUnoI, pTD, 0 ); + TYPELIB_DANGER_RELEASE( pTD ); + } + else + { + uno_any_construct( (uno_Any *)pReturn, 0, 0, 0 ); + } + *ppException = 0; + break; + } + case 1: // acquire() + ExceptionThrower_acquire( pUnoI ); + *ppException = 0; + break; + case 2: // release() + ExceptionThrower_release( pUnoI ); + *ppException = 0; + break; + case 3: // throwException() + { + OSL_ASSERT( ((uno_Any *)pArgs[0])->pType->eTypeClass == typelib_TypeClass_EXCEPTION ); + + uno_type_any_construct( + *ppException, ((uno_Any *)pArgs[0])->pData, ((uno_Any *)pArgs[0])->pType, 0 ); + break; + } + default: + OSL_ENSHURE( sal_False, "### illegal member called!" ); + } +} +//__________________________________________________________________________________________________ +inline ExceptionThrower::ExceptionThrower() + : nRef( 0 ) +{ + uno_Interface::acquire = ExceptionThrower_acquire; + uno_Interface::release = ExceptionThrower_release; + uno_Interface::pDispatcher = ExceptionThrower_dispatch; +} + +//================================================================================================== +void SAL_CALL throwException( const Any & rExc ) + throw (Exception) +{ + if (rExc.getValueTypeClass() == TypeClass_EXCEPTION) + { + OUString aExceptionName( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.Exception") ); + typelib_TypeDescription * pComp = 0; + TYPELIB_DANGER_GET( &pComp, rExc.getValueTypeRef() ); + // must be derived from com.sun.star.uno.Exception + for ( typelib_CompoundTypeDescription * pTD = (typelib_CompoundTypeDescription *)pComp; + pTD; pTD = pTD->pBaseTypeDescription ) + { + if (aExceptionName == ((typelib_TypeDescription *)pTD)->pTypeName) + { + Mapping aUno2Cpp( OUString( RTL_CONSTASCII_USTRINGPARAM(UNO_LB_UNO) ), + OUString( RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME) ) ); + OSL_ENSHURE( aUno2Cpp.is(), "### cannot get uno to cpp mapping!" ); + if (aUno2Cpp.is()) + { + uno_Interface * pUnoI = new ExceptionThrower(); + (*pUnoI->acquire)( pUnoI ); + Reference< XThrower > xThrower; + aUno2Cpp.mapInterface( + reinterpret_cast< void ** >( &xThrower ), + pUnoI, ::cppu::getCppuType( (const Reference< XThrower > *)0 ) ); + (*pUnoI->release)( pUnoI ); + + if (xThrower.is()) + { + TYPELIB_DANGER_RELEASE( pComp ); + xThrower->throwException( rExc ); + } + } + break; + } + } + TYPELIB_DANGER_RELEASE( pComp ); + } + throw RuntimeException( + OUString( RTL_CONSTASCII_USTRINGPARAM("failed throwing exception generically!") ), + Reference< XInterface >() ); +} + +} diff --git a/cppuhelper/source/factory.cxx b/cppuhelper/source/factory.cxx new file mode 100644 index 000000000000..5271391d0beb --- /dev/null +++ b/cppuhelper/source/factory.cxx @@ -0,0 +1,719 @@ +/************************************************************************* + * + * $RCSfile: factory.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:26:10 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _OSL_DIAGNOSE_H_ +#include <osl/diagnose.h> +#endif +#ifndef _OSL_MUTEX_HXX_ +#include <osl/mutex.hxx> +#endif + +#ifndef _CPPUHELPER_WEAK_HXX_ +#include <cppuhelper/weak.hxx> +#endif +#ifndef _CPPUHELPER_COMPONENT_HXX_ +#include <cppuhelper/component.hxx> +#endif +#ifndef _CPPUHELPER_FACTORY_HXX_ +#include <cppuhelper/factory.hxx> +#endif +#ifndef _CPPUHELPER_IMPLBASE2_HXX +#include <cppuhelper/implbase2.hxx> +#endif + +#ifndef _CPPUHELPER_TYPEPROVIDER_HXX_ +#include <cppuhelper/typeprovider.hxx> +#endif + +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/loader/XImplementationLoader.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> + +using namespace osl; +using namespace rtl; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::loader; +using namespace com::sun::star::registry; + +namespace cppu +{ + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +class OSingleFactoryHelper + : public XServiceInfo + , public XSingleServiceFactory +{ +public: + OSingleFactoryHelper( const Reference<XMultiServiceFactory > & rServiceManager, + const OUString & rImplementationName_, + ComponentInstantiation pCreateFunction_, + const Sequence< OUString > * pServiceNames_ ) + : xSMgr( rServiceManager ) + , aImplementationName( rImplementationName_ ) + , pCreateFunction( pCreateFunction_ ) + { + if( pServiceNames_ ) + aServiceNames = *pServiceNames_; + } + + // old function, only for backward compatibility + OSingleFactoryHelper( const Reference<XMultiServiceFactory > & rServiceManager, + const OUString & rImplementationName_ ) + : xSMgr( rServiceManager ) + , aImplementationName( rImplementationName_ ) + , pCreateFunction( NULL ) + { + } + + // XInterface + Any SAL_CALL queryInterface( const Type & rType ) + throw(::com::sun::star::uno::RuntimeException); + + // XSingleServiceFactory + Reference<XInterface > SAL_CALL createInstance(void) + throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + virtual Reference<XInterface > SAL_CALL createInstanceWithArguments(const Sequence<Any>& Arguments) + throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + + // XServiceInfo + OUString SAL_CALL getImplementationName() + throw(::com::sun::star::uno::RuntimeException); + sal_Bool SAL_CALL supportsService(const OUString& ServiceName) + throw(::com::sun::star::uno::RuntimeException); + Sequence< OUString > SAL_CALL getSupportedServiceNames(void) + throw(::com::sun::star::uno::RuntimeException); + +protected: + /** + * Create an instance specified by the factory. The one instance logic is implemented + * in the createInstance and createInstanceWithArguments methods. + * @return the newly created instance. Do not return a previous (one instance) instance. + */ + virtual Reference<XInterface > createInstanceEveryTime() + throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + + Reference<XMultiServiceFactory > xSMgr; + ComponentInstantiation pCreateFunction; + Sequence< OUString > aServiceNames; + OUString aImplementationName; +}; + +//----------------------------------------------------------------------------- +Any OSingleFactoryHelper::queryInterface( const Type & rType ) + throw(::com::sun::star::uno::RuntimeException) +{ + return ::cppu::queryInterface( + rType, static_cast< XSingleServiceFactory * >( this ), static_cast< XServiceInfo * >( this ) ); +} + +// OSingleFactoryHelper +Reference<XInterface > OSingleFactoryHelper::createInstanceEveryTime() + throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) +{ + if( pCreateFunction ) + return pCreateFunction( xSMgr ); + else + return Reference<XInterface >(); +} + +// XSingleServiceFactory +Reference<XInterface > OSingleFactoryHelper::createInstance() + throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) +{ + return createInstanceEveryTime(); +} + +// XSingleServiceFactory +Reference<XInterface > OSingleFactoryHelper::createInstanceWithArguments +( + const Sequence<Any>& Arguments +) + throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) +{ + Reference<XInterface > xRet = createInstanceEveryTime(); + + if( Arguments.getLength() ) + { + Reference<XInitialization > xInit( xRet, UNO_QUERY ); + if( xInit.is() ) + xInit->initialize( Arguments ); + else + throw IllegalArgumentException(); + } + return xRet; +} + +// XServiceInfo +OUString OSingleFactoryHelper::getImplementationName() + throw(::com::sun::star::uno::RuntimeException) +{ + return aImplementationName; +} + +// XServiceInfo +sal_Bool OSingleFactoryHelper::supportsService(const OUString& ServiceName) + throw(::com::sun::star::uno::RuntimeException) +{ + Sequence< OUString > seqServices = getSupportedServiceNames(); + const OUString * pServices = seqServices.getConstArray(); + for( sal_Int32 i = 0; i < seqServices.getLength(); i++ ) + if( pServices[i] == ServiceName ) + return sal_True; + + return sal_False; +} + +// XServiceInfo +Sequence< OUString > OSingleFactoryHelper::getSupportedServiceNames(void) + throw(::com::sun::star::uno::RuntimeException) +{ + return aServiceNames; +} + + +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +struct OFactoryComponentHelper_Mutex +{ + Mutex aMutex; +}; + +class OFactoryComponentHelper + : public OFactoryComponentHelper_Mutex + , public OComponentHelper + , public OSingleFactoryHelper +{ +public: + OFactoryComponentHelper( const Reference<XMultiServiceFactory > & rServiceManager, + const OUString & rImplementationName_, + ComponentInstantiation pCreateFunction_, + const Sequence< OUString > * pServiceNames_, + sal_Bool bOneInstance_ = sal_False ) + : OComponentHelper( aMutex ) + , OSingleFactoryHelper( rServiceManager, rImplementationName_, pCreateFunction_, pServiceNames_ ) + , bOneInstance( bOneInstance_ ) + { + } + + // old function, only for backward compatibility + OFactoryComponentHelper( const Reference<XMultiServiceFactory > & rServiceManager, + const OUString & rImplementationName_, + sal_Bool bOneInstance_ = sal_False ) + : OComponentHelper( aMutex ) + , OSingleFactoryHelper( rServiceManager, rImplementationName_ ) + , bOneInstance( bOneInstance_ ) + { + } + + // XInterface + Any SAL_CALL queryInterface( const Type & rType ) throw(::com::sun::star::uno::RuntimeException) + { return OComponentHelper::queryInterface( rType ); } + void SAL_CALL acquire() throw(::com::sun::star::uno::RuntimeException) + { OComponentHelper::acquire(); } + void SAL_CALL release() throw(::com::sun::star::uno::RuntimeException) + { OComponentHelper::release(); } + + // XSingleServiceFactory + Reference<XInterface > SAL_CALL createInstance() + throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + Reference<XInterface > SAL_CALL createInstanceWithArguments( const Sequence<Any>& Arguments ) + throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + + // XTypeProvider + virtual Sequence< Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException); + virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() throw(::com::sun::star::uno::RuntimeException); + + // XAggregation + Any SAL_CALL queryAggregation( const Type & rType ) + throw(::com::sun::star::uno::RuntimeException); + + // OComponentHelper + void SAL_CALL dispose() throw(::com::sun::star::uno::RuntimeException); + +private: + Reference<XInterface > xTheInstance; + sal_Bool bOneInstance; +}; + +// XAggregation +Any OFactoryComponentHelper::queryAggregation( const Type & rType ) + throw(::com::sun::star::uno::RuntimeException) +{ + Any aRet( OComponentHelper::queryAggregation( rType ) ); + return (aRet.hasValue() ? aRet : OSingleFactoryHelper::queryInterface( rType )); +} + +// XTypeProvider +Sequence< Type > OFactoryComponentHelper::getTypes() + throw (::com::sun::star::uno::RuntimeException) +{ + static OTypeCollection * pTypes = 0; + if (! pTypes) + { + MutexGuard aGuard( Mutex::getGlobalMutex() ); + if (! pTypes) + { + static OTypeCollection aTypes( + ::getCppuType( (const Reference< XSingleServiceFactory > *)0 ), + ::getCppuType( (const Reference< XServiceInfo > *)0 ), + OComponentHelper::getTypes() ); + pTypes = &aTypes; + } + } + return pTypes->getTypes(); +} +Sequence< sal_Int8 > OFactoryComponentHelper::getImplementationId() + throw (::com::sun::star::uno::RuntimeException) +{ + static OImplementationId * pId = 0; + if (! pId) + { + MutexGuard aGuard( Mutex::getGlobalMutex() ); + if (! pId) + { + static OImplementationId aId; + pId = &aId; + } + } + return pId->getImplementationId(); +} + +// XSingleServiceFactory +Reference<XInterface > OFactoryComponentHelper::createInstance() + throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) +{ + if( bOneInstance ) + { + MutexGuard aGuard( aMutex ); + if( !xTheInstance.is() ) + xTheInstance = OSingleFactoryHelper::createInstance(); + return xTheInstance; + } + return OSingleFactoryHelper::createInstance(); +} + +Reference<XInterface > OFactoryComponentHelper::createInstanceWithArguments( + const Sequence<Any>& Arguments ) + throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) +{ + if( bOneInstance ) + { + MutexGuard aGuard( aMutex ); + if( !xTheInstance.is() ) + xTheInstance = OSingleFactoryHelper::createInstanceWithArguments( Arguments ); + return xTheInstance; + } + return OSingleFactoryHelper::createInstanceWithArguments( Arguments ); +} + +// OComponentHelper +void OFactoryComponentHelper::dispose() + throw(::com::sun::star::uno::RuntimeException) +{ + OComponentHelper::dispose(); + + Reference<XInterface > x; + { + // do not delete in the guard section + MutexGuard aGuard( aMutex ); + x = xTheInstance; + xTheInstance = Reference<XInterface >(); + } + // if it is a component call dispose at the component + Reference<XComponent > xComp( x, UNO_QUERY ); + if( xComp.is() ) + xComp->dispose(); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +class ORegistryFactoryHelper + : public OFactoryComponentHelper +{ +public: + ORegistryFactoryHelper( const Reference<XMultiServiceFactory > & rServiceManager, + const OUString & rImplementationName_, + const Reference<XRegistryKey > & xImplementationKey_, + sal_Bool bOneInstance_ = sal_False ) + : OFactoryComponentHelper( rServiceManager, rImplementationName_, 0, 0, bOneInstance_ ) + , xImplementationKey( xImplementationKey_ ) + {} + + // OSingleFactoryHelper + Reference<XInterface > createInstanceEveryTime() + throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + + // XSingleServiceFactory + Reference<XInterface > SAL_CALL createInstanceWithArguments(const Sequence<Any>& Arguments) + throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + + // XServiceInfo + Sequence< OUString > SAL_CALL getSupportedServiceNames(void) + throw(::com::sun::star::uno::RuntimeException); + +private: + Reference< XSingleServiceFactory > createModuleFactory() + throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + + /** The registry key of the implementation section */ + Reference<XRegistryKey > xImplementationKey; + /** The factory created with the loader. */ + Reference<XSingleServiceFactory > xModuleFactory; +}; + +Reference<XInterface > ORegistryFactoryHelper::createInstanceEveryTime() + throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) +{ + if( pCreateFunction ) + // the create function is set, do not use the implementation loader. + return OFactoryComponentHelper::createInstanceEveryTime(); + + if( !xModuleFactory.is() ) + xModuleFactory = createModuleFactory(); + + if( xModuleFactory.is() ) + return xModuleFactory->createInstance(); + + return Reference<XInterface >(); +} + +// OSingleFactoryHelper +Reference< XSingleServiceFactory > ORegistryFactoryHelper::createModuleFactory() + throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) +{ + Reference<XSingleServiceFactory > xFactory; + try + { + MutexGuard aGuard( aMutex ); + + OUString aActivatorUrl; + OUString aActivatorName; + OUString aLocation; + + Reference<XRegistryKey > xActivatorKey = xImplementationKey->openKey( + OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO/ACTIVATOR") ) ); + if( xActivatorKey.is() && xActivatorKey->getValueType() == RegistryValueType_ASCII ) + { + aActivatorUrl = xActivatorKey->getAsciiValue(); + + OUString tmpActivator(aActivatorUrl.getStr()); + aActivatorName = tmpActivator.getToken(0, L':').getStr(); + + Reference<XRegistryKey > xLocationKey = xImplementationKey->openKey( + OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO/LOCATION") ) ); + if( xLocationKey.is() && xLocationKey->getValueType() == RegistryValueType_ASCII ) + aLocation = xLocationKey->getAsciiValue(); + } + else + { + // old style"url" + // the location of the program code of the implementation + Reference<XRegistryKey > xLocationKey = xImplementationKey->openKey( + OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO/URL") ) ); + // is the the key of the right type ? + if( xLocationKey.is() && xLocationKey->getValueType() == RegistryValueType_ASCII ) + { + // one implementation found -> try to activate + aLocation = xLocationKey->getAsciiValue(); + + // search protocol delemitter + sal_Int32 nPos = aLocation.search( + OUString( RTL_CONSTASCII_USTRINGPARAM("://") ) ); + if( nPos != -1 ) + { + aActivatorName = aLocation.copy( 0, nPos ); + if( aActivatorName.compareToAscii( "java" ) == 0 ) + aActivatorName = OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.loader.Java") ); + else if( aActivatorName.compareToAscii( "module" ) == 0 ) + aActivatorName = OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.loader.SharedLibrary") ); + aLocation = aLocation.copy( nPos + 3 ); + } + } + } + + if( aActivatorName.len() != 0 ) + { + Reference<XInterface > x = xSMgr->createInstance( aActivatorName ); + Reference<XImplementationLoader > xLoader( x, UNO_QUERY ); + Reference<XInterface > xMF; + if (xLoader.is()) + { + // JSC: This exception must not be catched if a concept for exception handling + // is specified, implemented and used. + try + { + xMF = xLoader->activate( aImplementationName, aActivatorUrl, aLocation, xImplementationKey ); + } + catch( CannotActivateFactoryException& e) + { + OString msg( OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US) ); + OSL_ENSHURE( !msg.getLength(), msg.getStr() ); + } + } + xFactory = Reference<XSingleServiceFactory >( xMF, UNO_QUERY ); + } + } + catch (InvalidRegistryException &) + { + } + + return xFactory; +} + +Reference<XInterface > SAL_CALL ORegistryFactoryHelper::createInstanceWithArguments(const Sequence<Any>& Arguments) + throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) +{ + if( !xModuleFactory.is() ) + xModuleFactory = createModuleFactory(); + + if( xModuleFactory.is() ) + return xModuleFactory->createInstanceWithArguments( Arguments ); + + return Reference<XInterface >(); +} + +// XServiceInfo +Sequence< OUString > ORegistryFactoryHelper::getSupportedServiceNames(void) + throw(::com::sun::star::uno::RuntimeException) +{ + MutexGuard aGuard( aMutex ); + if( aServiceNames.getLength() == 0 ) + { + // not yet loaded + try + { + Reference<XRegistryKey > xKey = xImplementationKey->openKey( + OUString( RTL_CONSTASCII_USTRINGPARAM("UNO/SERVICES") ) ); + + if (xKey.is()) + { + // length of prefix. +1 for the '/' at the end + sal_Int32 nPrefixLen = xKey->getKeyName().len() + 1; + + // Full qualified names like "IMPLEMENTATIONS/TEST/UNO/SERVICES/com.sun.star..." + Sequence<OUString> seqKeys = xKey->getKeyNames(); + OUString* pKeys = seqKeys.getArray(); + for( sal_Int32 i = 0; i < seqKeys.getLength(); i++ ) + pKeys[i] = pKeys[i].copy(nPrefixLen); + + aServiceNames = seqKeys; + } + } + catch (InvalidRegistryException &) + { + } + } + return aServiceNames; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + + +class OFactoryProxyHelper : public WeakImplHelper2< XServiceInfo, XSingleServiceFactory > +{ + Reference<XSingleServiceFactory > xFactory; + +public: + + OFactoryProxyHelper( const Reference<XMultiServiceFactory > & /*rServiceManager*/, + const Reference<XSingleServiceFactory > & rFactory ) + : xFactory( rFactory ) + {} + + // XSingleServiceFactory + Reference<XInterface > SAL_CALL createInstance() + throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + Reference<XInterface > SAL_CALL createInstanceWithArguments(const Sequence<Any>& Arguments) + throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + + // XServiceInfo + OUString SAL_CALL getImplementationName() + throw(::com::sun::star::uno::RuntimeException); + sal_Bool SAL_CALL supportsService(const OUString& ServiceName) + throw(::com::sun::star::uno::RuntimeException); + Sequence< OUString > SAL_CALL getSupportedServiceNames(void) + throw(::com::sun::star::uno::RuntimeException); +}; + +// XSingleServiceFactory +Reference<XInterface > OFactoryProxyHelper::createInstance() + throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) +{ + return xFactory->createInstance(); +} + +// XSingleServiceFactory +Reference<XInterface > OFactoryProxyHelper::createInstanceWithArguments +( + const Sequence<Any>& Arguments +) + throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) +{ + return xFactory->createInstanceWithArguments( Arguments ); +} + +// XServiceInfo +OUString OFactoryProxyHelper::getImplementationName() + throw(::com::sun::star::uno::RuntimeException) +{ + Reference<XServiceInfo > xInfo( xFactory, UNO_QUERY ); + if( xInfo.is() ) + return xInfo->getImplementationName(); + return OUString(); +} + +// XServiceInfo +sal_Bool OFactoryProxyHelper::supportsService(const OUString& ServiceName) + throw(::com::sun::star::uno::RuntimeException) +{ + Reference<XServiceInfo > xInfo( xFactory, UNO_QUERY ); + if( xInfo.is() ) + return xInfo->supportsService( ServiceName ); + return sal_False; +} + +// XServiceInfo +Sequence< OUString > OFactoryProxyHelper::getSupportedServiceNames(void) + throw(::com::sun::star::uno::RuntimeException) +{ + Reference<XServiceInfo > xInfo( xFactory, UNO_QUERY ); + if( xInfo.is() ) + return xInfo->getSupportedServiceNames(); + return Sequence< OUString >(); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +// global function +Reference<XSingleServiceFactory > SAL_CALL createSingleFactory +( + const Reference<XMultiServiceFactory > & rServiceManager, + const OUString & rImplementationName, + ComponentInstantiation pCreateFunction, + const Sequence< OUString > & rServiceNames +) +{ + return new OFactoryComponentHelper( rServiceManager, rImplementationName, + pCreateFunction, &rServiceNames, sal_False ); +} + +// global function +Reference<XSingleServiceFactory > SAL_CALL createFactoryProxy +( + const Reference<XMultiServiceFactory > & rServiceManager, + const Reference<XSingleServiceFactory > & rFactory +) +{ + return new OFactoryProxyHelper( rServiceManager, rFactory ); +} + +// global function +Reference<XSingleServiceFactory > SAL_CALL createOneInstanceFactory +( + const Reference<XMultiServiceFactory > & rServiceManager, + const OUString & rImplementationName, + ComponentInstantiation pCreateFunction, + const Sequence< OUString > & rServiceNames +) +{ + return new OFactoryComponentHelper( rServiceManager, rImplementationName, + pCreateFunction, &rServiceNames, sal_True ); +} + +// global function +SAL_DLLEXPORT Reference<XSingleServiceFactory > SAL_CALL createSingleRegistryFactory +( + const Reference<XMultiServiceFactory > & rServiceManager, + const OUString & rImplementationName, + const Reference<XRegistryKey > & rImplementationKey +) +{ + return new ORegistryFactoryHelper( rServiceManager, rImplementationName, + rImplementationKey, sal_False ); +} + +// global function +Reference<XSingleServiceFactory > SAL_CALL createOneInstanceRegistryFactory +( + const Reference<XMultiServiceFactory > & rServiceManager, + const OUString & rImplementationName, + const Reference<XRegistryKey > & rImplementationKey +) +{ + return new ORegistryFactoryHelper( rServiceManager, rImplementationName, + rImplementationKey, sal_True ); +} + +} + + diff --git a/cppuhelper/source/implbase.cxx b/cppuhelper/source/implbase.cxx new file mode 100644 index 000000000000..a01c12fde4e0 --- /dev/null +++ b/cppuhelper/source/implbase.cxx @@ -0,0 +1,227 @@ +/************************************************************************* + * + * $RCSfile: implbase.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:26:10 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _CPPUHELPER_IMPLBASE_HXX_ +#include <cppuhelper/implbase.hxx> +#endif + +#ifndef _OSL_DIAGNOSE_H_ +#include <osl/diagnose.h> +#endif +#ifndef _RTL_UUID_H_ +#include <rtl/uuid.h> +#endif + +#include <com/sun/star/lang/XComponent.hpp> + +using namespace osl; +using namespace rtl; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; + +namespace cppu +{ + +// ClassDataBase +//__________________________________________________________________________________________________ +ClassDataBase::ClassDataBase() + : bOffsetsInit( sal_False ) + , nType2Offset( 0 ) + , nClassCode( 0 ) + , pTypes( 0 ) + , pId( 0 ) +{ +} +//__________________________________________________________________________________________________ +ClassDataBase::ClassDataBase( sal_Int32 nClassCode_ ) + : bOffsetsInit( sal_False ) + , nType2Offset( 0 ) + , nClassCode( nClassCode_ ) + , pTypes( 0 ) + , pId( 0 ) +{ +} +//__________________________________________________________________________________________________ +ClassDataBase::~ClassDataBase() +{ + delete pTypes; + delete pId; + + for ( sal_Int32 nPos = nType2Offset; nPos--; ) + { + typelib_typedescription_release( + (typelib_TypeDescription *)((ClassData *)this)->arType2Offset[nPos].pTD ); + } +} + +// ClassData +//__________________________________________________________________________________________________ +void ClassData::writeTypeOffset( const Type & rType, sal_Int32 nOffset ) +{ + arType2Offset[nType2Offset].nOffset = nOffset; + + arType2Offset[nType2Offset].pTD = 0; + typelib_typedescriptionreference_getDescription( + (typelib_TypeDescription **)&arType2Offset[nType2Offset].pTD, rType.getTypeLibType() ); + + if (arType2Offset[nType2Offset].pTD) + ++nType2Offset; +#ifdef DEBUG + else + { + OString msg( "### cannot get type description for " ); + msg += OUStringToOString( rType.getTypeName(), RTL_TEXTENCODING_ASCII_US ); + OSL_ENSHURE( sal_False, msg.getStr() ); + } +#endif +} +//__________________________________________________________________________________________________ +void ClassData::initTypeProvider() +{ + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + if (! pTypes) + { + // create id + pId = new Sequence< sal_Int8 >( 16 ); + rtl_createUuid( (sal_uInt8 *)pId->getArray(), 0, sal_True ); + + // collect types + Sequence< Type > * types = new Sequence< Type >( + nType2Offset + 1 + (nClassCode == 4 ? 2 : nClassCode) ); + Type * pTypeAr = types->getArray(); + + // given types + sal_Int32 nPos = nType2Offset; + while (nPos--) + pTypeAr[nPos] = ((typelib_TypeDescription *)arType2Offset[nPos].pTD)->pWeakRef; + + // XTypeProvider + pTypeAr[nType2Offset] = ::getCppuType( (const Reference< XTypeProvider > *)0 ); + + // class code extra types: [[XComponent,] XWeak[, XAggregation]] + switch (nClassCode) + { + case 4: + pTypeAr[nType2Offset +2] = ::getCppuType( (const Reference< XComponent > *)0 ); + pTypeAr[nType2Offset +1] = ::getCppuType( (const Reference< XWeak > *)0 ); + break; + case 3: + pTypeAr[nType2Offset +3] = ::getCppuType( (const Reference< XComponent > *)0 ); + case 2: + pTypeAr[nType2Offset +2] = ::getCppuType( (const Reference< XAggregation > *)0 ); + case 1: + pTypeAr[nType2Offset +1] = ::getCppuType( (const Reference< XWeak > *)0 ); + } + + pTypes = types; + } +} +//__________________________________________________________________________________________________ +Sequence< Type > ClassData::getTypes() +{ + if (! pTypes) + initTypeProvider(); + return *pTypes; +} +//__________________________________________________________________________________________________ +Sequence< sal_Int8 > ClassData::getImplementationId() +{ + if (! pTypes) + initTypeProvider(); + return *pId; +} + +//-------------------------------------------------------------------------------------------------- +static inline sal_Bool td_equals( typelib_TypeDescription * pTD, + typelib_TypeDescriptionReference * pType ) +{ + return (pTD->pWeakRef == pType || + (pTD->pTypeName->length == pType->pTypeName->length && + rtl_ustr_compare( pTD->pTypeName->buffer, pType->pTypeName->buffer ) == 0)); +} +//__________________________________________________________________________________________________ +Any ClassData::query( const Type & rType, XTypeProvider * pBase ) +{ + if (rType == ::getCppuType( (const Reference< XInterface > *)0 )) + return Any( &pBase, ::getCppuType( (const Reference< XInterface > *)0 ) ); + for ( sal_Int32 nPos = 0; nPos < nType2Offset; ++nPos ) + { + const Type_Offset & rTO = arType2Offset[nPos]; + typelib_InterfaceTypeDescription * pTD = rTO.pTD; + while (pTD) + { + if (td_equals( (typelib_TypeDescription *)pTD, + *(typelib_TypeDescriptionReference **)&rType )) + { + void * pInterface = (char *)pBase + rTO.nOffset; + return Any( &pInterface, (typelib_TypeDescription *)pTD ); + } + pTD = pTD->pBaseTypeDescription; + } + } + if (rType == ::getCppuType( (const Reference< XTypeProvider > *)0 )) + return Any( &pBase, ::getCppuType( (const Reference< XTypeProvider > *)0 ) ); + + return Any(); +} + +} + diff --git a/cppuhelper/source/interfacecontainer.cxx b/cppuhelper/source/interfacecontainer.cxx new file mode 100644 index 000000000000..baf0d696249a --- /dev/null +++ b/cppuhelper/source/interfacecontainer.cxx @@ -0,0 +1,383 @@ +/************************************************************************* + * + * $RCSfile: interfacecontainer.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:26:10 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#include <cppuhelper/interfacecontainer.hxx> +#include <cppuhelper/queryinterface.hxx> + +#include <osl/diagnose.h> +#include <osl/mutex.hxx> + +#include <hash_map> + +#include <assert.h> + +#include <com/sun/star/lang/XEventListener.hpp> + + +using namespace osl; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; + +namespace cppu +{ + +//=================================================================== +//=================================================================== +//=================================================================== +/** + * Reallocate the sequence. + */ +static void realloc( Sequence< Reference< XInterface > > & rSeq, sal_Int32 nNewLen ) +{ + Sequence< Reference< XInterface > > aNewSeq( nNewLen ); + Reference< XInterface > * pDest = aNewSeq.getArray(); + // getArray on a const sequence is faster + const Reference< XInterface > * pSource = ((const Sequence< Reference< XInterface > > &)rSeq).getConstArray(); + for( sal_Int32 i = (nNewLen < rSeq.getLength() ? nNewLen : rSeq.getLength()) -1; i >= 0; i-- ) + pDest[i] = pSource[i]; + rSeq = aNewSeq; +} + +/** + * Remove an element from an interface sequence. + */ +static void sequenceRemoveElementAt( Sequence< Reference< XInterface > > & rSeq, sal_Int32 index ) +{ + sal_Int32 nNewLen = rSeq.getLength() - 1; + + Sequence< Reference< XInterface > > aDestSeq( rSeq.getLength() - 1 ); + // getArray on a const sequence is faster + const Reference< XInterface > * pSource = ((const Sequence< Reference< XInterface > > &)rSeq).getConstArray(); + Reference< XInterface > * pDest = aDestSeq.getArray(); + sal_Int32 i = 0; + for( ; i < index; i++ ) + pDest[i] = pSource[i]; + for( sal_Int32 j = i ; j < nNewLen; j++ ) + pDest[j] = pSource[j+1]; + rSeq = aDestSeq; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +#ifdef SAL_WNT +#pragma warning( disable: 4786 ) +#endif + +//=================================================================== +//=================================================================== +//=================================================================== +OInterfaceIteratorHelper::OInterfaceIteratorHelper( OInterfaceContainerHelper & rCont_ ) + : rCont( rCont_ ) +{ + MutexGuard aGuard( rCont.rMutex ); + if( rCont.bInUse ) + // worst case, two iterators at the same time + rCont.copyAndResetInUse(); + bIsList = rCont_.bIsList; + pData = rCont_.pData; + if( bIsList ) + { + rCont.bInUse = sal_True; + nRemain = ((Sequence< Reference< XInterface > >*)pData)->getLength(); + } + else if( pData ) + { + ((XInterface *)pData)->acquire(); + nRemain = 1; + } + else + nRemain = 0; +} + +OInterfaceIteratorHelper::~OInterfaceIteratorHelper() +{ + sal_Bool bShared; + { + MutexGuard aGuard( rCont.rMutex ); + // bResetInUse protect the iterator against recursion + bShared = pData == rCont.pData && rCont.bIsList; + if( bShared ) + { + OSL_ENSHURE( rCont.bInUse, "OInterfaceContainerHelper must be in use" ); + rCont.bInUse = sal_False; + } + } + + if( !bShared ) + { + if( bIsList ) + // Sequence owned by the iterator + delete (Sequence< Reference< XInterface > >*)pData; + else if( pData ) + // Interface is acquired by the iterator + ((XInterface*)pData)->release(); + } +} + +XInterface * OInterfaceIteratorHelper::next() +{ + if( nRemain ) + { + nRemain--; + if( bIsList ) + // typecase to const,so the getArray method is faster + return ((const Sequence< Reference< XInterface > >*)pData)->getConstArray()[nRemain].get(); + else if( pData ) + return (XInterface*)pData; + } + // exception + return 0; +} + +//=================================================================== +//=================================================================== +//=================================================================== + + +OInterfaceContainerHelper::OInterfaceContainerHelper( Mutex & rMutex_ ) + : rMutex( rMutex_ ) + , bInUse( sal_False ) + , bIsList( sal_False ) + , pData( 0 ) +{ +} + +OInterfaceContainerHelper::~OInterfaceContainerHelper() +{ + OSL_ENSHURE( !bInUse, "~OInterfaceContainerHelper but is in use" ); + if( bIsList ) + delete (Sequence< Reference< XInterface > >*)pData; + else if( pData ) + ((XInterface*)pData)->release(); +} + +sal_Int32 OInterfaceContainerHelper::getLength() const +{ + MutexGuard aGuard( rMutex ); + if( bIsList ) + return ((Sequence< Reference< XInterface > >*)pData)->getLength(); + else if( pData ) + return 1; + return 0; +} + +Sequence< Reference<XInterface> > OInterfaceContainerHelper::getElements() const +{ + MutexGuard aGuard( rMutex ); + if( bIsList ) + return *(Sequence< Reference< XInterface > >*)pData; + else if( pData ) + { + Reference<XInterface> x( (XInterface *)pData ); + return Sequence< Reference< XInterface > >( &x, 1 ); + } + return Sequence< Reference< XInterface > >(); +} + +void OInterfaceContainerHelper::copyAndResetInUse() +{ + OSL_ENSHURE( bInUse, "OInterfaceContainerHelper not in use" ); + if( bInUse ) + { + // this should be the worst case. If a iterator is active + // and a new Listener is added. + if( bIsList ) + pData = new Sequence< Reference< XInterface > >( *(Sequence< Reference< XInterface > >*)pData ); + else if( pData ) + ((XInterface*)pData)->acquire(); + + bInUse = sal_False; + } +} + +sal_Int32 OInterfaceContainerHelper::addInterface( const Reference<XInterface> & rListener ) +{ + assert( rListener.is() ); + MutexGuard aGuard( rMutex ); + if( bInUse ) + copyAndResetInUse(); + + if( bIsList ) + { + sal_Int32 nLen = ((Sequence< Reference< XInterface > >*)pData)->getLength(); + realloc( *(Sequence< Reference< XInterface > >*)pData, nLen +1 ); + ((Sequence< Reference< XInterface > >*)pData)->getArray()[ nLen ] = rListener; + return nLen +1; + } + else if( pData ) + { + Sequence< Reference< XInterface > > * pSeq = new Sequence< Reference< XInterface > >( 2 ); + Reference<XInterface> * pArray = pSeq->getArray(); + pArray[0] = (XInterface *)pData; + pArray[1] = rListener; + ((XInterface *)pData)->release(); + pData = pSeq; + bIsList = sal_True; + return 2; + } + else + { + pData = rListener.get(); + if( rListener.is() ) + rListener->acquire(); + return 1; + } +} + +sal_Int32 OInterfaceContainerHelper::removeInterface( const Reference<XInterface> & rListener ) +{ + assert( rListener.is() ); + MutexGuard aGuard( rMutex ); + if( bInUse ) + copyAndResetInUse(); + + if( bIsList ) + { + const Reference<XInterface> * pL = ((const Sequence< Reference< XInterface > >*)pData)->getConstArray(); + sal_Int32 nLen = ((Sequence< Reference< XInterface > >*)pData)->getLength(); + sal_Int32 i; + for( i = 0; i < nLen; i++ ) + { + // It is not valid to compare the Pointer direkt, but is is is much + // more faster. + if( pL[i].get() == rListener.get() ) + { + sequenceRemoveElementAt( *(Sequence< Reference< XInterface > >*)pData, i ); + break; + } + } + + if( i == nLen ) + { + // interface not found, use the correct compare method + for( i = 0; i < nLen; i++ ) + { + if( pL[i] == rListener ) + { + sequenceRemoveElementAt(*(Sequence< Reference< XInterface > >*)pData, i ); + break; + } + } + } + + if( ((Sequence< Reference< XInterface > >*)pData)->getLength() == 1 ) + { + XInterface * pL = ((const Sequence< Reference< XInterface > >*)pData)->getConstArray()[0].get(); + pL->acquire(); + delete (Sequence< Reference< XInterface > >*)pData; + pData = pL; + bIsList = sal_False; + return 1; + } + else + return ((Sequence< Reference< XInterface > >*)pData)->getLength(); + } + else if( Reference<XInterface>( (XInterface*)pData ) == rListener ) + { + ((XInterface *)pData)->release(); + pData = 0; + } + return pData ? 1 : 0; +} + +void OInterfaceContainerHelper::disposeAndClear( const EventObject & rEvt ) +{ + ClearableMutexGuard aGuard( rMutex ); + OInterfaceIteratorHelper aIt( *this ); + // Container freigeben, falls im disposing neue Eintrge kommen + OSL_ENSHURE( !bIsList || bInUse, "OInterfaceContainerHelper not in use" ); + if( !bIsList && pData ) + ((XInterface *)pData)->release(); + // set the member to null, the iterator delete the values + pData = NULL; + bIsList = sal_False; + bInUse = sal_False; + aGuard.clear(); + while( aIt.hasMoreElements() ) + { + Reference<XEventListener > xLst( aIt.next(), UNO_QUERY ); + if( xLst.is() ) + xLst->disposing( rEvt ); + } +} + + +void OInterfaceContainerHelper::clear( ) +{ + ClearableMutexGuard aGuard( rMutex ); + OInterfaceIteratorHelper aIt( *this ); + // Container freigeben, falls im disposing neue Eintrge kommen + OSL_ENSHURE( !bIsList || bInUse, "OInterfaceContainerHelper not in use" ); + if( !bIsList && pData ) + ((XInterface *)pData)->release(); + // set the member to null, the iterator delete the values + pData = 0; + bIsList = sal_False; + bInUse = sal_False; + // release mutex before aIt destructor call + aGuard.clear(); +} + + +} + diff --git a/cppuhelper/source/makefile.mk b/cppuhelper/source/makefile.mk new file mode 100644 index 000000000000..08c617b3fbf0 --- /dev/null +++ b/cppuhelper/source/makefile.mk @@ -0,0 +1,167 @@ +#************************************************************************* +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.1.1.1 $ +# +# last change: $Author: hr $ $Date: 2000-09-18 15:26:10 $ +# +# The Contents of this file are made available subject to the terms of +# either of the following licenses +# +# - GNU Lesser General Public License Version 2.1 +# - Sun Industry Standards Source License Version 1.1 +# +# Sun Microsystems Inc., October, 2000 +# +# GNU Lesser General Public License Version 2.1 +# ============================================= +# Copyright 2000 by Sun Microsystems, Inc. +# 901 San Antonio Road, Palo Alto, CA 94303, USA +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1, as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +# +# Sun Industry Standards Source License Version 1.1 +# ================================================= +# The contents of this file are subject to the Sun Industry Standards +# Source License Version 1.1 (the "License"); You may not use this file +# except in compliance with the License. You may obtain a copy of the +# License at http://www.openoffice.org/license.html. +# +# Software provided under this License is provided on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, +# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. +# See the License for the specific provisions governing your rights and +# obligations concerning the Software. +# +# The Initial Developer of the Original Code is: Sun Microsystems, Inc. +# +# Copyright: 2000 by Sun Microsystems, Inc. +# +# All Rights Reserved. +# +# Contributor(s): _______________________________________ +# +# +# +#************************************************************************* +PRJ=.. + +PRJNAME= cppuhelper +TARGET= cppuhelper +NO_BSYMBOLIC= TRUE +ENABLE_EXCEPTIONS=TRUE + +USE_DEFFILE= TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : svpre.mk +.INCLUDE : settings.mk +.INCLUDE : sv.mk + +.INCLUDE : ..$/version.mk + +# --- Files -------------------------------------------------------- + +UNOUCRDEP= $(SOLARBINDIR)$/applicat.rdb +UNOUCRRDB= $(SOLARBINDIR)$/applicat.rdb +UNOUCROUT= $(OUT)$/inc +INCPRE+= $(OUT)$/inc + +CPPUMAKERFLAGS = + +UNOTYPES= \ + com.sun.star.registry.XSimpleRegistry \ + com.sun.star.registry.XImplementationRegistration \ + com.sun.star.container.XSet \ + com.sun.star.uno.XWeak \ + com.sun.star.uno.XAggregation \ + com.sun.star.lang.XMultiServiceFactory \ + com.sun.star.lang.XSingleServiceFactory \ + com.sun.star.lang.XServiceInfo \ + com.sun.star.lang.XInitialization \ + com.sun.star.reflection.XIdlReflection \ + com.sun.star.reflection.XIdlClass \ + com.sun.star.reflection.XIdlClassProvider \ + com.sun.star.beans.XPropertySet \ + com.sun.star.beans.XMultiPropertySet \ + com.sun.star.beans.XFastPropertySet \ + com.sun.star.beans.PropertyAttribute \ + com.sun.star.registry.XRegistryKey \ + com.sun.star.loader.XImplementationLoader \ + com.sun.star.lang.XTypeProvider \ + com.sun.star.lang.XComponent + +# LIB1TARGET= $(LB)$/a$(TARGET).lib +# LIB1ARCHIV= $(LB)$/lib$(TARGET)$(CPPUHELPER_MAJOR)$(COM).a +# LIB1FILES= $(LB)$/$(TARGET).lib + +SLOFILES= \ + $(SLO)$/typeprovider.obj \ + $(SLO)$/exc_thrower.obj \ + $(SLO)$/servicefactory.obj \ + $(SLO)$/implbase.obj \ + $(SLO)$/propshlp.obj \ + $(SLO)$/weak.obj \ + $(SLO)$/interfacecontainer.obj \ + $(SLO)$/stdidlclass.obj \ + $(SLO)$/factory.obj \ + $(SLO)$/component.obj + +# OBJFILES= \ +# $(OBJ)$/typeprovider.obj \ +# $(OBJ)$/exc_thrower.obj \ +# $(OBJ)$/servicefactory.obj \ +# $(OBJ)$/implbase.obj \ +# $(OBJ)$/propshlp.obj \ +# $(OBJ)$/weak.obj \ +# $(OBJ)$/interfacecontainer.obj \ +# $(OBJ)$/stdidlclass.obj \ +# $(OBJ)$/factory.obj \ +# $(OBJ)$/component.obj + +# NETBSD: somewhere we have to instantiate the static data members. +# NETBSD-1.2.1 doesn't know about weak symbols so the default mechanism for GCC won't work. +# SCO and MACOSX: the linker does know about weak symbols, but we can't ignore multiple defined symbols +.IF "$(OS)"=="NETBSD" || "$(OS)"=="SCO" || "$(OS)$(COM)"=="OS2GCC" || "$(OS)"=="MACOSX" +SLOFILES+=$(SLO)$/staticmb.obj +#OBJFILES+=$(OBJ)$/staticmb.obj +.ENDIF + +SHL1TARGET= $(TARGET)$(CPPUHELPER_MAJOR)$(COM) + +SHL1STDLIBS= \ + $(CPPULIB) \ + $(SALLIB) + +SHL1DEPN= +SHL1IMPLIB= i$(TARGET) +SHL1LIBS= $(SLB)$/$(TARGET).lib +SHL1DEF= $(MISC)$/$(SHL1TARGET).def + +DEF1NAME= $(SHL1TARGET) +DEF1DEPN= $(MISC)$/$(SHL1TARGET).flt +DEFLIB1NAME= $(TARGET) + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + +$(MISC)$/$(SHL1TARGET).flt : makefile.mk + +echo _TI2 >$@ + +echo _TI1 >>$@ diff --git a/cppuhelper/source/propshlp.cxx b/cppuhelper/source/propshlp.cxx new file mode 100644 index 000000000000..1783d853908e --- /dev/null +++ b/cppuhelper/source/propshlp.cxx @@ -0,0 +1,1106 @@ +/************************************************************************* + * + * $RCSfile: propshlp.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:26:10 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + + +#ifndef _CPPUHELPER_IMPLBASE1_HXX +#include <cppuhelper/implbase1.hxx> +#endif + +#include <osl/diagnose.h> + +#include <cppuhelper/weak.hxx> +#include <cppuhelper/propshlp.hxx> + +#include <com/sun/star/beans/PropertyAttribute.hpp> + + +using namespace osl; +using namespace com::sun::star::uno; +using namespace com::sun::star::beans; +using namespace com::sun::star::lang; +using namespace rtl; +using namespace cppu; + +namespace cppu { + +IPropertyArrayHelper::~IPropertyArrayHelper() +{ +} + +inline const ::com::sun::star::uno::Type & getPropertyTypeIdentifier( ) +{ + return ::getCppuType( (Reference< XPropertyChangeListener > *)0 ); +} +inline const ::com::sun::star::uno::Type & getPropertiesTypeIdentifier() +{ + return ::getCppuType( (Reference< XPropertiesChangeListener > *)0 ); +} +inline const ::com::sun::star::uno::Type & getVetoableTypeIdentifier() +{ + return ::getCppuType( (Reference< XVetoableChangeListener > *)0 ); +} + +int SAL_CALL compare_OUString_Property_Impl( const void *arg1, const void *arg2 ) +{ + return ((OUString *)arg1)->compareTo( ((Property *)arg2)->Name ); +} + +/** + * The class which implements the PropertySetInfo interface. + */ +class OPropertySetHelperInfo_Impl + : public WeakImplHelper1< ::com::sun::star::beans::XPropertySetInfo > +{ + Sequence < Property > aInfos; + +public: + OPropertySetHelperInfo_Impl( IPropertyArrayHelper & rHelper_ ); + + // XPropertySetInfo-Methoden + virtual Sequence< Property > SAL_CALL getProperties(void); + virtual Property SAL_CALL getPropertyByName(const OUString& PropertyName); + virtual sal_Bool SAL_CALL hasPropertyByName(const OUString& PropertyName); +}; + + +/** + * Create an object that implements XPropertySetInfo IPropertyArrayHelper. + */ +OPropertySetHelperInfo_Impl::OPropertySetHelperInfo_Impl( IPropertyArrayHelper & rHelper_ ) + :aInfos( rHelper_.getProperties() ) +{ +} + +/** + * Return the sequence of properties, which are provided throug the constructor. + */ +Sequence< Property > OPropertySetHelperInfo_Impl::getProperties(void) +{ + return aInfos; +} + +/** + * Return the sequence of properties, which are provided throug the constructor. + */ +Property OPropertySetHelperInfo_Impl::getPropertyByName( const OUString & PropertyName ) +{ + Property * pR; + pR = (Property *)bsearch( &PropertyName, aInfos.getConstArray(), aInfos.getLength(), + sizeof( Property ), + compare_OUString_Property_Impl ); + if( !pR ) { + throw UnknownPropertyException(); + } + + return *pR; +} + +/** + * Return the sequence of properties, which are provided throug the constructor. + */ +sal_Bool OPropertySetHelperInfo_Impl::hasPropertyByName( const OUString & PropertyName ) +{ + Property * pR; + pR = (Property *)bsearch( &PropertyName, aInfos.getConstArray(), aInfos.getLength(), + sizeof( Property ), + compare_OUString_Property_Impl ); + return pR != NULL; +} + +// ---------------------------------------------------- +// class PropertySetHelper +// ---------------------------------------------------- +OPropertySetHelper::OPropertySetHelper( + OBroadcastHelper & rBHelper_ ) + : rBHelper( rBHelper_ ) + , aBoundLC( rBHelper_.rMutex ) + , aVetoableLC( rBHelper_.rMutex ) +{ +} + +/** + * You must call disposing before. + */ +OPropertySetHelper::~OPropertySetHelper() +{ +} + +/** + * These method is called from queryInterface, if no delegator is set. + * Otherwise this method is called from the delegator. + */ +// XAggregation +Any OPropertySetHelper::queryInterface( const ::com::sun::star::uno::Type & rType ) +{ + return ::cppu::queryInterface( rType, + static_cast< XPropertySet * >( this ), + static_cast< XMultiPropertySet * >( this ), + static_cast< XFastPropertySet * >( this ) ); +} + +// ComponentHelper +void OPropertySetHelper::disposing() +{ + // Create an event with this as sender + Reference < XPropertySet > rSource( SAL_STATIC_CAST( XPropertySet * , this ) , UNO_QUERY ); + EventObject aEvt; + aEvt.Source = rSource; + + // inform all listeners to reelease this object + // The listener container are automaticly cleared + aBoundLC.disposeAndClear( aEvt ); + aVetoableLC.disposeAndClear( aEvt ); +} + +Reference < XPropertySetInfo > OPropertySetHelper::createPropertySetInfo( IPropertyArrayHelper & rProperties ) +{ + return static_cast< XPropertySetInfo * >( new OPropertySetHelperInfo_Impl( rProperties ) ); +} + +// XPropertySet +void OPropertySetHelper::setPropertyValue( const OUString& rPropertyName, const Any& rValue ) +{ + // get the map table + IPropertyArrayHelper & rPH = getInfoHelper(); + // map the name to the handle + sal_Int32 nHandle = rPH.getHandleByName( rPropertyName ); + // call the method of the XFastPropertySet interface + setFastPropertyValue( nHandle, rValue ); +} + +// XPropertySet +Any OPropertySetHelper::getPropertyValue( const OUString& rPropertyName ) +{ + // get the map table + IPropertyArrayHelper & rPH = getInfoHelper(); + // map the name to the handle + sal_Int32 nHandle = rPH.getHandleByName( rPropertyName ); + // call the method of the XFastPropertySet interface + return getFastPropertyValue( nHandle ); +} + +// XPropertySet +void OPropertySetHelper::addPropertyChangeListener(const OUString& rPropertyName, + const Reference < XPropertyChangeListener > & rxListener) + throw(::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException) +{ + MutexGuard aGuard( rBHelper.rMutex ); + OSL_ENSHURE( !rBHelper.bInDispose, "do not addPropertyChangeListener in the dispose call" ); + OSL_ENSHURE( !rBHelper.bDisposed, "object is disposed" ); + if( !rBHelper.bInDispose && !rBHelper.bDisposed ) + { + // only add listeners if you are not disposed + // a listener with no name means all properties + if( rPropertyName.len() ) + { + // get the map table + IPropertyArrayHelper & rPH = getInfoHelper(); + // map the name to the handle + sal_Int32 nHandle = rPH.getHandleByName( rPropertyName ); + if( nHandle == -1 ) { + // property not known throw exception + throw UnknownPropertyException() ; + } + + sal_Int16 nAttributes; + rPH.fillPropertyMembersByHandle( NULL, &nAttributes, nHandle ); + if( !(nAttributes & ::com::sun::star::beans::PropertyAttribute::BOUND) ) + { + OSL_ENSHURE( sal_False, "add listener to an unbound property" ); + // silent ignore this + return; + } + // add the change listener to the helper container + + aBoundLC.addInterface( (sal_Int32)nHandle, rxListener ); + } + else + // add the change listener to the helper container + rBHelper.aLC.addInterface( + getPropertyTypeIdentifier( ), + rxListener + ); + } +} + + +// XPropertySet +void OPropertySetHelper::removePropertyChangeListener(const OUString& rPropertyName, + const Reference < XPropertyChangeListener >& rxListener) + throw(::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException) +{ + MutexGuard aGuard( rBHelper.rMutex ); + OSL_ENSHURE( !rBHelper.bDisposed, "object is disposed" ); + // all listeners are automaticly released in a dispose call + if( !rBHelper.bInDispose && !rBHelper.bDisposed ) + { + if( rPropertyName.len() ) + { + // get the map table + IPropertyArrayHelper & rPH = getInfoHelper(); + // map the name to the handle + sal_Int32 nHandle = rPH.getHandleByName( rPropertyName ); + if( nHandle == -1 ) + // property not known throw exception + throw UnknownPropertyException(); + aBoundLC.removeInterface( (sal_Int32)nHandle, rxListener ); + } + else { + // remove the change listener to the helper container + rBHelper.aLC.removeInterface( + getPropertyTypeIdentifier( ), + rxListener + ); + } + } +} + +// XPropertySet +void OPropertySetHelper::addVetoableChangeListener +( + const OUString& rPropertyName, + const Reference< XVetoableChangeListener > & rxListener +) + throw(::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException) +{ + MutexGuard aGuard( rBHelper.rMutex ); + OSL_ENSHURE( !rBHelper.bInDispose, "do not addVetoableChangeListener in the dispose call" ); + OSL_ENSHURE( !rBHelper.bDisposed, "object is disposed" ); + if( !rBHelper.bInDispose && !rBHelper.bDisposed ) + { + // only add listeners if you are not disposed + // a listener with no name means all properties + if( rPropertyName.len() ) + { + // get the map table + IPropertyArrayHelper & rPH = getInfoHelper(); + // map the name to the handle + sal_Int32 nHandle = rPH.getHandleByName( rPropertyName ); + if( nHandle == -1 ) { + // property not known throw exception + throw UnknownPropertyException(); + } + + sal_Int16 nAttributes; + rPH.fillPropertyMembersByHandle( NULL, &nAttributes, nHandle ); + if( !(nAttributes & PropertyAttribute::CONSTRAINED) ) + { + OSL_ENSHURE( sal_False, "addVetoableChangeListener, and property is not constrained" ); + // silent ignore this + return; + } + // add the vetoable listener to the helper container + aVetoableLC.addInterface( (sal_Int32)nHandle, rxListener ); + } + else + // add the vetoable listener to the helper container + rBHelper.aLC.addInterface( + getVetoableTypeIdentifier( ), + rxListener + ); + } +} + +// XPropertySet +void OPropertySetHelper::removeVetoableChangeListener +( + const OUString& rPropertyName, + const Reference < XVetoableChangeListener > & rxListener +) + throw(::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException) +{ + MutexGuard aGuard( rBHelper.rMutex ); + OSL_ENSHURE( !rBHelper.bDisposed, "object is disposed" ); + // all listeners are automaticly released in a dispose call + if( !rBHelper.bInDispose && !rBHelper.bDisposed ) + { + if( rPropertyName.len() ) + { + // get the map table + IPropertyArrayHelper & rPH = getInfoHelper(); + // map the name to the handle + sal_Int32 nHandle = rPH.getHandleByName( rPropertyName ); + if( nHandle == -1 ) { + // property not known throw exception + throw UnknownPropertyException(); + } + // remove the vetoable listener to the helper container + aVetoableLC.removeInterface( (sal_Int32)nHandle, rxListener ); + } + else + // add the vetoable listener to the helper container + rBHelper.aLC.removeInterface( + getVetoableTypeIdentifier( ), + rxListener + ); + } +} + +// XFastPropertySet +void OPropertySetHelper::setFastPropertyValue( sal_Int32 nHandle, const Any& rValue ) + throw(::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::beans::PropertyVetoException, + ::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException) +{ + OSL_ENSHURE( !rBHelper.bInDispose, "do not setFastPropertyValue in the dispose call" ); + OSL_ENSHURE( !rBHelper.bDisposed, "object is disposed" ); + + IPropertyArrayHelper & rInfo = getInfoHelper(); + sal_Int16 nAttributes; + if( !rInfo.fillPropertyMembersByHandle( NULL, &nAttributes, nHandle ) ) { + // unknown property + throw UnknownPropertyException(); + } + if( nAttributes & PropertyAttribute::READONLY ) + throw PropertyVetoException(); + + Any aConvertedVal; + Any aOldVal; + + // Will the property change? + sal_Bool bChanged; + { + MutexGuard aGuard( rBHelper.rMutex ); + bChanged = convertFastPropertyValue( aConvertedVal, aOldVal, nHandle, rValue ); + // release guard to fire events + } + if( bChanged ) + { + // Is it a constrained property? + if( nAttributes & PropertyAttribute::CONSTRAINED ) + { + // In aValue is the converted rValue + // fire a constarined event + // second parameter NULL means constrained + fire( &nHandle, &rValue, &aOldVal, 1, sal_True ); + } + + { + MutexGuard aGuard( rBHelper.rMutex ); + // set the property to the new value + setFastPropertyValue_NoBroadcast( nHandle, aConvertedVal ); + // release guard to fire events + } + // file a change event, if the value changed + fire( &nHandle, &rValue, &aOldVal, 1, sal_False ); + } +} + +// XFastPropertySet +Any OPropertySetHelper::getFastPropertyValue( sal_Int32 nHandle ) + throw(::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException) + +{ + IPropertyArrayHelper & rInfo = getInfoHelper(); + if( !rInfo.fillPropertyMembersByHandle( NULL, NULL, nHandle ) ) + // unknown property + throw UnknownPropertyException(); + + Any aRet; + MutexGuard aGuard( rBHelper.rMutex ); + getFastPropertyValue( aRet, nHandle ); + return aRet; +} + +//-------------------------------------------------------------------------- +void OPropertySetHelper::fire +( + sal_Int32 * pnHandles, + const Any * pNewValues, + const Any * pOldValues, + sal_Int32 nHandles, // These is the Count of the array + sal_Bool bVetoable +) +{ + // Only fire, if one or more properties changed + if( nHandles ) + { + // create the event sequence of all changed properties + Sequence< PropertyChangeEvent > aEvts( nHandles ); + PropertyChangeEvent * pEvts = aEvts.getArray(); + Reference < XInterface > xSource( (XPropertySet *)this, UNO_QUERY ); + sal_Int32 i; + sal_Int32 nChangesLen = 0; + // Loop over all changed properties to fill the event struct + for( i = 0; i < nHandles; i++ ) + { + // Vetoable fire and constrained attribute set or + // Change fire and Changed and bound attribute set + IPropertyArrayHelper & rInfo = getInfoHelper(); + sal_Int16 nAttributes; + OUString aPropName; + rInfo.fillPropertyMembersByHandle( &aPropName, &nAttributes, pnHandles[i] ); + + if( bVetoable && (nAttributes & PropertyAttribute::CONSTRAINED) + || !bVetoable && (nAttributes & PropertyAttribute::BOUND) ) + { + pEvts[nChangesLen].Source = xSource; + pEvts[nChangesLen].PropertyName = aPropName; + pEvts[nChangesLen].PropertyHandle = pnHandles[i]; + pEvts[nChangesLen].OldValue = pOldValues[i]; + pEvts[nChangesLen].NewValue = pNewValues[i]; + nChangesLen++; + } + } + + // fire the events for all changed properties + for( i = 0; i < nChangesLen; i++ ) + { + // get the listener container for the property name + OInterfaceContainerHelper * pLC; + if( bVetoable ) // fire change Events? + pLC = aVetoableLC.getContainer( pEvts[i].PropertyHandle ); + else + pLC = aBoundLC.getContainer( pEvts[i].PropertyHandle ); + if( pLC ) + { + // Ueber alle Listener iterieren und Events senden + OInterfaceIteratorHelper aIt( *pLC); + while( aIt.hasMoreElements() ) + { + XInterface * pL = aIt.next(); + if( bVetoable ) // fire change Events? + ((XVetoableChangeListener *)pL)->vetoableChange( pEvts[i] ); + else + ((XPropertyChangeListener *)pL)->propertyChange( pEvts[i] ); + } + } + // broadcast to all listeners with "" property name + if( bVetoable ){ + // fire change Events? + pLC = rBHelper.aLC.getContainer( + getVetoableTypeIdentifier() + ); + } + else { + pLC = rBHelper.aLC.getContainer( + getPropertyTypeIdentifier( ) + ); + } + if( pLC ) + { + // Ueber alle Listener iterieren und Events senden + OInterfaceIteratorHelper aIt( *pLC); + while( aIt.hasMoreElements() ) + { + XInterface * pL = aIt.next(); + if( bVetoable ) // fire change Events? + ((XVetoableChangeListener *)pL)->vetoableChange( pEvts[i] ); + else + ((XPropertyChangeListener *)pL)->propertyChange( pEvts[i] ); + } + } + } + + // reduce array to changed properties + aEvts.realloc( nChangesLen ); + + if( !bVetoable ) + { + OInterfaceContainerHelper * pCont = 0; + pCont = rBHelper.aLC.getContainer( + getPropertiesTypeIdentifier( ) + ); + if( pCont ) + { + // Here is a Bug, unbound properties are also fired + OInterfaceIteratorHelper aIt( *pCont ); + while( aIt.hasMoreElements() ) + { + XPropertiesChangeListener * pL = (XPropertiesChangeListener *)aIt.next(); + // fire the hole event sequence to the XPropertiesChangeListener's + pL->propertiesChange( aEvts ); + } + } + } + } +} + +// OPropertySetHelper +void OPropertySetHelper::setFastPropertyValues +( + sal_Int32 nSeqLen, + sal_Int32 * pHandles, + const Any * pValues, + sal_Int32 nHitCount +) +throw (Exception) +{ + OSL_ENSHURE( !rBHelper.bInDispose, "do not getFastPropertyValue in the dispose call" ); + OSL_ENSHURE( !rBHelper.bDisposed, "object is disposed" ); + + Any * pConvertedValues = NULL; + Any * pOldValues = NULL; + + try + { + // get the map table + IPropertyArrayHelper & rPH = getInfoHelper(); + + pConvertedValues = new Any[ nHitCount ]; + pOldValues = new Any[ nHitCount ]; + sal_Int32 nHitCount = 0; + sal_Int32 i; + + { + // must lock the mutex outside the loop. So all values are consistent. + MutexGuard aGuard( rBHelper.rMutex ); + for( i = 0; i < nSeqLen; i++ ) + { + if( pHandles[i] != -1 ) + { + sal_Int16 nAttributes; + rPH.fillPropertyMembersByHandle( NULL, &nAttributes, pHandles[i] ); + if( nAttributes & PropertyAttribute::READONLY ) { + throw PropertyVetoException(); + } + // Will the property change? + if( convertFastPropertyValue( pConvertedValues[ nHitCount ], pOldValues[nHitCount], + pHandles[i], pValues[i] ) ) + { + // only increment if the property really change + pHandles[nHitCount] = pHandles[i]; + nHitCount++; + } + } + } + // release guard to fire events + } + + // fire vetoable events + fire( pHandles, pConvertedValues, pOldValues, nHitCount, sal_True ); + + { + // must lock the mutex outside the loop. + MutexGuard aGuard( rBHelper.rMutex ); + // Loop over all changed properties + for( i = 0; i < nHitCount; i++ ) + { + // Will the property change? + setFastPropertyValue_NoBroadcast( pHandles[i], pConvertedValues[i] ); + } + // release guard to fire events + } + + // fire change events + fire( pHandles, pConvertedValues, pOldValues, nHitCount, sal_False ); + } + catch( ... ) + { + delete [] pOldValues; + delete [] pConvertedValues; + throw; + } + delete [] pOldValues; + delete [] pConvertedValues; +} + +// XMultiPropertySet +/** + * The sequence may be conatain not known properties. The implementation + * must ignore these properties. + */ +void OPropertySetHelper::setPropertyValues +( + const Sequence<OUString>& rPropertyNames, + const Sequence<Any>& rValues +) +{ + sal_Int32 * pHandles = NULL; + try + { + sal_Int32 nSeqLen = rPropertyNames.getLength(); + pHandles = new sal_Int32[ nSeqLen ]; + // get the map table + IPropertyArrayHelper & rPH = getInfoHelper(); + // fill the handle array + sal_Int32 nHitCount = rPH.fillHandles( pHandles, rPropertyNames ); + if( nHitCount != 0 ) + setFastPropertyValues( nSeqLen, pHandles, rValues.getConstArray(), nHitCount ); + } + catch( ... ) + { + delete [] pHandles; + throw; + } + delete [] pHandles; +} + +// XMultiPropertySet +Sequence<Any> OPropertySetHelper::getPropertyValues( const Sequence<OUString>& rPropertyNames ) +{ + sal_Int32 nSeqLen = rPropertyNames.getLength(); + sal_Int32 * pHandles = new sal_Int32[ nSeqLen ]; + Sequence< Any > aValues( nSeqLen ); + + // get the map table + IPropertyArrayHelper & rPH = getInfoHelper(); + // fill the handle array + rPH.fillHandles( pHandles, rPropertyNames ); + + Any * pValues = aValues.getArray(); + const OUString * pNames = rPropertyNames.getConstArray(); + + MutexGuard aGuard( rBHelper.rMutex ); + // fill the sequence with the values + for( sal_Int32 i = 0; i < nSeqLen; i++ ) + getFastPropertyValue( pValues[i], pHandles[i] ); + + delete [] pHandles; + return aValues; +} + +// XMultiPropertySet +void OPropertySetHelper::addPropertiesChangeListener ( + const Sequence<OUString> & , + const Reference < XPropertiesChangeListener > & rListener + ) +{ + MutexGuard aGuard( rBHelper.rMutex ); + OSL_ENSHURE( !rBHelper.bInDispose, "do not addPropertyChangeListener in the dispose call" ); + OSL_ENSHURE( !rBHelper.bDisposed, "object is disposed" ); + // all listeners are automaticly released in a dispose call + if( !rBHelper.bInDispose && !rBHelper.bDisposed ) + { + // Listener wird zu allen Properties angemeldet, besser ist + // sie ueber die Namen anzumelden + rBHelper.aLC.addInterface( + getPropertiesTypeIdentifier( ), + rListener + ); + } +} + +// XMultiPropertySet +void OPropertySetHelper::removePropertiesChangeListener + ( const Reference < XPropertiesChangeListener > & rxListener ) +{ + MutexGuard aGuard( rBHelper.rMutex ); + OSL_ENSHURE( !rBHelper.bDisposed, "object is disposed" ); + // all listeners are automaticly released in a dispose call + if( !rBHelper.bInDispose && !rBHelper.bDisposed ) + { + rBHelper.aLC.removeInterface( + getPropertiesTypeIdentifier( ), + rxListener + ); + } +} + +// XMultiPropertySet +void OPropertySetHelper::firePropertiesChangeEvent +( + const Sequence<OUString>& rPropertyNames, + const Reference < XPropertiesChangeListener >& rListener +) +{ + sal_Int32 nLen = rPropertyNames.getLength(); + sal_Int32 * pHandles = new sal_Int32[nLen]; + IPropertyArrayHelper & rPH = getInfoHelper(); + rPH.fillHandles( pHandles, rPropertyNames ); + const OUString* pNames = rPropertyNames.getConstArray(); + + // get the count of matching properties + sal_Int32 nFireLen = 0; + sal_Int32 i; + for( i = 0; i < nLen; i++ ) + if( pHandles[i] != -1 ) + nFireLen++; + + Sequence<PropertyChangeEvent> aChanges( nFireLen ); + PropertyChangeEvent* pChanges = aChanges.getArray(); + + sal_Int32 nFirePos = 0; + { + // must lock the mutex outside the loop. So all values are consistent. + MutexGuard aGuard( rBHelper.rMutex ); + Reference < XInterface > xSource( (XPropertySet *)this, UNO_QUERY ); + for( i = 0; i < nLen; i++ ) + { + if( pHandles[i] != -1 ) + { + pChanges[nFirePos].Source = xSource; + pChanges[nFirePos].PropertyName = pNames[i]; + pChanges[nFirePos].PropertyHandle = pHandles[i]; + getFastPropertyValue( pChanges[nFirePos].OldValue, pHandles[i] ); + pChanges[nFirePos].NewValue = pChanges[nFirePos].OldValue; + nFirePos++; + } + } + // release guard to fire events + } + if( nFireLen ) + rListener->propertiesChange( aChanges ); + + delete [] pHandles; +} + +#ifdef xdvnsdfln +// XPropertyState +PropertyState OPropertySetHelper::getPropertyState( const OUString& PropertyName ) +{ + PropertyState aState; + return aState; +} + +// XPropertyState +Sequence< PropertyState > OPropertySetHelper::getPropertyStates( const Sequence< OUString >& PropertyNames ) +{ + ULONG nNames = PropertyNames.getLength(); + const OUString* pNames = PropertyNames.getConstArray(); + + Sequence< PropertyState > aStates( nNames ); + return aStates; + +} + +void OPropertySetHelper::setPropertyToDefault( const OUString& aPropertyName ) +{ + setPropertyValue( aPropertyName, Any() ); +} + +Any OPropertySetHelper::getPropertyDefault( const OUString& aPropertyName ) const +{ + return Any(); +} + +void OPropertySetHelper::addPropertyStateChangeListener( const OUString& aPropertyName, const XPropertyStateChangeListenerRef& Listener ) +{ +} + +void OPropertySetHelper::removePropertyStateChangeListener( const OUString& aPropertyName, const XPropertyStateChangeListenerRef& Listener ) +{ +} +#endif + +//======================================================================== +//== OPropertyArrayHelper ================================================ +//======================================================================== + +//======================================================================== + +// static OUString makeOUString( sal_Char *p ) +// { +// sal_Int32 nLen = strlen(p); +// sal_Unicode *pw = new sal_Unicode[nLen]; + +// for( int i = 0 ; i < nLen ; i ++ ) { + +// // Only ascii strings allowed with this helper ! +// OSL_ASSERT( p[i] < 127 ); +// pw[i] = p[i]; +// } +// OUString ow( pw , nLen ); +// delete pw; +// return ow; +// } + +int SAL_CALL compare_Property_Impl( const void *arg1, const void *arg2 ) +{ + return ((Property *)arg1)->Name.compareTo( ((Property *)arg2)->Name ); +} + +void OPropertyArrayHelper::init( sal_Bool bSorted ) +{ + sal_Int32 i, nElements = aInfos.getLength(); + const Property* pProperties = aInfos.getConstArray(); + + for( i = 1; i < nElements; i++ ) + { + if( pProperties[i-1].Name >= pProperties[i].Name ) + { + OSL_ENSHURE( !bSorted, "Property array is not sorted" ); + // not sorted + qsort( aInfos.getArray(), nElements, sizeof( Property ), + compare_Property_Impl ); + break; + } + } + // may be that the array is resorted + pProperties = aInfos.getConstArray(); + for( i = 0; i < nElements; i++ ) + if( pProperties[i].Handle != i ) + return; + // The handle is the index + bRightOrdered = sal_True; +} + +OPropertyArrayHelper::OPropertyArrayHelper +( + Property * pProps, + sal_Int32 nEle, + sal_Bool bSorted +) + : aInfos(pProps, nEle) + , bRightOrdered( sal_False ) +{ + init( bSorted ); +} + +OPropertyArrayHelper::OPropertyArrayHelper +( + const Sequence< Property > & aProps, + sal_Bool bSorted +) + : aInfos(aProps) + , bRightOrdered( sal_False ) +{ + init( bSorted ); +} + +//======================================================================== +sal_Int32 OPropertyArrayHelper::getCount() const +{ + return aInfos.getLength(); +} + +//======================================================================== +sal_Bool OPropertyArrayHelper::fillPropertyMembersByHandle +( + OUString * pPropName, + sal_Int16 * pAttributes, + sal_Int32 nHandle +) +{ + const Property* pProperties = aInfos.getConstArray(); + sal_Int32 nElements = aInfos.getLength(); + + if( bRightOrdered ) + { + if( nHandle < 0 || nHandle >= nElements ) + return sal_False; + if( pPropName ) + *pPropName = pProperties[ nHandle ].Name; + if( pAttributes ) + *pAttributes = pProperties[ nHandle ].Attributes; + return sal_True; + } + else + { + // normally the array is sorted + for( sal_Int32 i = 0; i < nElements; i++ ) + { + if( pProperties[i].Handle == nHandle ) + { + if( pPropName ) + *pPropName = pProperties[ i ].Name; + if( pAttributes ) + *pAttributes = pProperties[ i ].Attributes; + return sal_True; + } + } + } + return sal_False; +} + +//======================================================================== +Sequence< Property > OPropertyArrayHelper::getProperties(void) +{ + /*if( aInfos.getLength() != nElements ) + { + ((OPropertyArrayHelper *)this)->aInfos.realloc( nElements ); + Property * pProps = ((OPropertyArrayHelper *)this)->aInfos.getArray(); + for( sal_Int32 i = 0; i < nElements; i++ ) + { + pProps[i].Name = pProperties[i].Name; + pProps[i].Handle = pProperties[i].Handle; + pProps[i].Type = pProperties[i].Type; + pProps[i].Attributes = pProperties[i].Attributes; + } + }*/ + return aInfos; +} + +//======================================================================== +Property OPropertyArrayHelper::getPropertyByName(const OUString& aPropertyName) + throw (UnknownPropertyException) +{ + Property * pR; + pR = (Property *)bsearch( &aPropertyName, aInfos.getConstArray(), aInfos.getLength(), + sizeof( Property ), + compare_OUString_Property_Impl ); + if( !pR ) { + throw UnknownPropertyException(); + } + + /*Property aProp; + aProp.Name = pR->Name; + aProp.Handle = pR->Handle; + aProp.Type = pR->Type; + aProp.Attributes = pR->Attributes; + return aProp;*/ + return *pR; +} + +//======================================================================== +sal_Bool OPropertyArrayHelper::hasPropertyByName(const OUString& aPropertyName) +{ + Property * pR; + pR = (Property *)bsearch( &aPropertyName, aInfos.getConstArray(), aInfos.getLength(), + sizeof( Property ), + compare_OUString_Property_Impl ); + return pR != NULL; +} + +//======================================================================== +sal_Int32 OPropertyArrayHelper::getHandleByName( const OUString & rPropName ) +{ + Property * pR; + pR = (Property *)bsearch( &rPropName, aInfos.getConstArray(), aInfos.getLength(), + sizeof( Property ), + compare_OUString_Property_Impl ); + return pR ? pR->Handle : -1; +} + +//======================================================================== +sal_Int32 OPropertyArrayHelper::fillHandles( sal_Int32 * pHandles, const Sequence< OUString > & rPropNames ) +{ + sal_Int32 nHitCount = 0; + const OUString * pReqProps = rPropNames.getConstArray(); + sal_Int32 nReqLen = rPropNames.getLength(); + const Property * pCur = aInfos.getConstArray(); + const Property * pEnd = pCur + aInfos.getLength(); + + for( sal_Int32 i = 0; i < nReqLen; i++ ) + { + // Logarithmus ermitteln + sal_Int32 n = (sal_Int32)(pEnd - pCur); + sal_Int32 nLog = 0; + while( n ) + { + nLog += 1; + n = n >> 1; + } + + // Anzahl der noch zu suchenden Properties * dem Log2 der verbleibenden + // zu dursuchenden Properties. + if( (nReqLen - i) * nLog >= pEnd - pCur ) + { + // linear search is better + while( pCur < pEnd && pReqProps[i] > pCur->Name ) + { + pCur++; + } + if( pCur < pEnd && pReqProps[i] == pCur->Name ) + { + pHandles[i] = pCur->Handle; + nHitCount++; + } + else + pHandles[i] = -1; + } + else + { + // binary search is better + sal_Int32 nCompVal = 1; + const Property * pOldEnd = pEnd--; + const Property * pMid = pCur; + + while( nCompVal != 0 && pCur <= pEnd ) + { + pMid = (pEnd - pCur) / 2 + pCur; + + nCompVal = pReqProps[i].compareTo( pMid->Name ); + + if( nCompVal > 0 ) + pCur = pMid + 1; + else + pEnd = pMid - 1; + } + + if( nCompVal == 0 ) + { + pHandles[i] = pMid->Handle; + nHitCount++; + pCur = pMid +1; + } + else if( nCompVal > 0 ) + { + pHandles[i] = -1; + pCur = pMid +1; + } + else + { + pHandles[i] = -1; + pCur = pMid; + } + pEnd = pOldEnd; + } + } + return nHitCount; +} + +} // end namespace cppu + + + diff --git a/cppuhelper/source/servicefactory.cxx b/cppuhelper/source/servicefactory.cxx new file mode 100644 index 000000000000..3e0bebf9b55c --- /dev/null +++ b/cppuhelper/source/servicefactory.cxx @@ -0,0 +1,507 @@ +/************************************************************************* + * + * $RCSfile: servicefactory.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:26:10 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _OSL_DIAGNOSE_H_ +#include <osl/diagnose.h> +#endif +#ifndef _OSL_MODULE_H_ +#include <osl/module.h> +#endif +#ifndef _RTL_STRING_HXX_ +#include <rtl/string.hxx> +#endif +#ifndef _RTL_USTRBUF_HXX_ +#include <rtl/ustrbuf.hxx> +#endif + +#ifndef _UNO_ENVIRONMENT_H_ +#include <uno/environment.h> +#endif +#ifndef _UNO_MAPPING_HXX_ +#include <uno/mapping.hxx> +#endif +#ifndef _CPPUHELPER_FACTORY_HXX_ +#include <cppuhelper/factory.hxx> +#endif + +#include <com/sun/star/container/XSet.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/registry/XSimpleRegistry.hpp> +#include <com/sun/star/registry/XImplementationRegistration.hpp> + +using namespace rtl; +using namespace osl; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::registry; +using namespace com::sun::star::container; + + +namespace cppu +{ + +//================================================================================================== +static Reference< XSingleServiceFactory > loadLibComponentFactory( + const OUString & rLibName, const OUString & rImplName, const OUString & rBootstrapPath, + const Reference< XMultiServiceFactory > & xSF, const Reference< XRegistryKey > & xKey ) +{ + Reference< XSingleServiceFactory > xRet; + sal_uInt32 bufLen = 32; + + if ( rBootstrapPath.getLength() > 0 ) + { + bufLen += rBootstrapPath.getLength() + 1; + } + + OUStringBuffer aLibNameBuf( bufLen ); + if ( bufLen > 32 ) + { + aLibNameBuf.append( rBootstrapPath ); + aLibNameBuf.appendAscii( RTL_CONSTASCII_STRINGPARAM("/") ); + } + +#ifdef SAL_UNX + aLibNameBuf.appendAscii( RTL_CONSTASCII_STRINGPARAM("lib") ); + aLibNameBuf.append( rLibName ); + aLibNameBuf.appendAscii( RTL_CONSTASCII_STRINGPARAM(".so") ); +#else + aLibNameBuf.append( rLibName ); + aLibNameBuf.appendAscii( RTL_CONSTASCII_STRINGPARAM(".dll") ); +#endif + OUString aLibName( aLibNameBuf.makeStringAndClear() ); + oslModule lib = osl_loadModule( aLibName.pData, SAL_LOADMODULE_LAZY | SAL_LOADMODULE_GLOBAL ); + + if (lib) + { + void * pSym; + + // ========================= LATEST VERSION ========================= + OUString aGetEnvName( RTL_CONSTASCII_USTRINGPARAM(COMPONENT_GETENV) ); + if (pSym = osl_getSymbol( lib, aGetEnvName.pData )) + { + uno_Environment * pCurrentEnv = 0; + uno_Environment * pEnv = 0; + const sal_Char * pEnvTypeName = 0; + (*((component_getImplementationEnvironmentFunc)pSym))( &pEnvTypeName, &pEnv ); + + sal_Bool bNeedsMapping = + (pEnv || 0 != rtl_str_compare( pEnvTypeName, CPPU_CURRENT_LANGUAGE_BINDING_NAME )); + + OUString aEnvTypeName( OUString::createFromAscii( pEnvTypeName ) ); + + if (bNeedsMapping) + { + if (! pEnv) + uno_getEnvironment( &pEnv, aEnvTypeName.pData, 0 ); + if (pEnv) + { + OUString aCppEnvTypeName( RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME) ); + uno_getEnvironment( &pCurrentEnv, aCppEnvTypeName.pData, 0 ); + if (pCurrentEnv) + bNeedsMapping = (pEnv != pCurrentEnv); + } + } + + OUString aGetFactoryName( RTL_CONSTASCII_USTRINGPARAM(COMPONENT_GETFACTORY) ); + if (pSym = osl_getSymbol( lib, aGetFactoryName.pData )) + { + OString aImplName( OUStringToOString( rImplName, RTL_TEXTENCODING_ASCII_US ) ); + + if (bNeedsMapping) + { + if (pEnv && pCurrentEnv) + { + Mapping aCurrent2Env( pCurrentEnv, pEnv ); + Mapping aEnv2Current( pEnv, pCurrentEnv ); + + if (aCurrent2Env.is() && aEnv2Current.is()) + { + void * pSMgr = aCurrent2Env.mapInterface( + xSF.get(), ::getCppuType( (const Reference< XMultiServiceFactory > *)0 ) ); + void * pKey = aCurrent2Env.mapInterface( + xKey.get(), ::getCppuType( (const Reference< XRegistryKey > *)0 ) ); + + void * pSSF = (*((component_getFactoryFunc)pSym))( + aImplName.getStr(), pSMgr, pKey ); + + if (pKey) + (*pEnv->pExtEnv->releaseInterface)( pEnv->pExtEnv, pKey ); + if (pSMgr) + (*pEnv->pExtEnv->releaseInterface)( pEnv->pExtEnv, pSMgr ); + + if (pSSF) + { + aEnv2Current.mapInterface( + reinterpret_cast< void ** >( &xRet ), + pSSF, ::getCppuType( (const Reference< XSingleServiceFactory > *)0 ) ); + (*pEnv->pExtEnv->releaseInterface)( pEnv->pExtEnv, pSSF ); + } + } + } + } + else + { + XSingleServiceFactory * pRet = (XSingleServiceFactory *) + (*((component_getFactoryFunc)pSym))( + aImplName.getStr(), xSF.get(), xKey.get() ); + if (pRet) + { + xRet = pRet; + pRet->release(); + } + } + } + + if (pEnv) + (*pEnv->release)( pEnv ); + if (pCurrentEnv) + (*pCurrentEnv->release)( pCurrentEnv ); + } + + if (! xRet.is()) + osl_unloadModule( lib ); + } + + return xRet; +} +//================================================================================================== +static Reference< ::com::sun::star::lang::XSingleServiceFactory> SAL_CALL createLoaderFactory( + const Reference< XMultiServiceFactory > & xSF, const OUString & rBootstrapPath ) +{ + return loadLibComponentFactory( + OUString( RTL_CONSTASCII_USTRINGPARAM("cpld") ), + OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.stoc.DLLComponentLoader") ), + rBootstrapPath, xSF, Reference< XRegistryKey >() ); +} +//================================================================================================== +static Reference< XSingleServiceFactory > SAL_CALL createSimpleRegistryFactory( + const Reference< XMultiServiceFactory > & xSF, const OUString & rBootstrapPath ) +{ + return loadLibComponentFactory( + OUString( RTL_CONSTASCII_USTRINGPARAM("simreg") ), + OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.stoc.SimpleRegistry") ), + rBootstrapPath, xSF, Reference< XRegistryKey >() ); +} +//================================================================================================== +static Reference< XSingleServiceFactory> SAL_CALL createDefaultRegistryFactory( + const Reference< XMultiServiceFactory > & xSF, const OUString & rBootstrapPath ) +{ + return loadLibComponentFactory( + OUString( RTL_CONSTASCII_USTRINGPARAM("defreg") ), + OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.stoc.DefaultRegistry") ), + rBootstrapPath, xSF, Reference< XRegistryKey >() ); +} +//================================================================================================== +static Reference< XSingleServiceFactory> SAL_CALL createNestedRegistryFactory( + const Reference< XMultiServiceFactory > & xSF, const OUString & rBootstrapPath ) +{ + return loadLibComponentFactory( + OUString( RTL_CONSTASCII_USTRINGPARAM("defreg") ), + OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.stoc.NestedRegistry") ), + rBootstrapPath, xSF, Reference< XRegistryKey >() ); +} +//================================================================================================== +static Reference< XSingleServiceFactory> SAL_CALL createImplRegFactory( + const Reference< XMultiServiceFactory > & xSF, const OUString & rBootstrapPath ) +{ + return loadLibComponentFactory( + OUString( RTL_CONSTASCII_USTRINGPARAM("impreg") ), + OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.stoc.ImplementationRegistration") ), + rBootstrapPath, xSF, Reference< XRegistryKey >() ); +} +//================================================================================================== +static Reference< XSingleServiceFactory> SAL_CALL createRegTDProviderFactory( + const Reference< XMultiServiceFactory > & xSF, const OUString & rBootstrapPath ) +{ + return loadLibComponentFactory( + OUString( RTL_CONSTASCII_USTRINGPARAM("rdbtdp") ), + OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.stoc.RegistryTypeDescriptionProvider") ), + rBootstrapPath, xSF, Reference< XRegistryKey >() ); +} +//================================================================================================== +static Reference< XSingleServiceFactory> SAL_CALL createTDManagerFactory( + const Reference< XMultiServiceFactory > & xSF, const OUString & rBootstrapPath ) +{ + return loadLibComponentFactory( + OUString( RTL_CONSTASCII_USTRINGPARAM("tdmgr") ), + OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.stoc.TypeDescriptionManager") ), + rBootstrapPath, xSF, Reference< XRegistryKey >() ); +} +//================================================================================================== +static Reference< XMultiServiceFactory > createImplServiceFactory( const OUString & rWriteRegistry, + const OUString & rReadRegistry, + sal_Bool bReadOnly, + const OUString & rBootstrapPath ) + throw( ::com::sun::star::uno::Exception ) +{ + // mappings held to avoid binding unloading... + Mapping aCpp2Uno( + OUString( RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME) ), + OUString( RTL_CONSTASCII_USTRINGPARAM(UNO_LB_UNO) ) ); + Mapping aUno2Cpp( + OUString( RTL_CONSTASCII_USTRINGPARAM(UNO_LB_UNO) ), + OUString( RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME) ) ); + + Reference< XSingleServiceFactory > xSMFac( loadLibComponentFactory( + OUString( RTL_CONSTASCII_USTRINGPARAM("smgr") ), + OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.stoc.ORegistryServiceManager") ), + rBootstrapPath, Reference< XMultiServiceFactory >(), Reference< XRegistryKey >() ) ); + + // stop here if not at least a service manager is available + if ( !xSMFac.is() ) + { + throw Exception( OUString(RTL_CONSTASCII_USTRINGPARAM("service manager component not available")), + Reference< XInterface >() ); + } + + Reference< XMultiServiceFactory > xSF( xSMFac->createInstance(), UNO_QUERY ); + Reference< XInitialization > xInit( xSF, UNO_QUERY ); + + OSL_ENSHURE( xInit.is() && xSF.is(), "### failed loading servicemanager!" ); + if (xInit.is() && xSF.is()) + { + Reference< XSingleServiceFactory > xSimRegFac( createSimpleRegistryFactory( xSF, rBootstrapPath ) ); + Reference< XSingleServiceFactory > xNesRegFac( createNestedRegistryFactory( xSF, rBootstrapPath ) ); + OSL_ENSHURE( xSimRegFac.is() && xNesRegFac.is(), "### cannot get registry factories!" ); + + // write initial shared lib loader, simple registry, default registry, impl reg + Reference< XSet > xSet( xSF, UNO_QUERY ); + + // loader + { + Reference< XSingleServiceFactory > xFac( createLoaderFactory( xSF, rBootstrapPath ) ); + if ( !xFac.is() ) + { + throw Exception( OUString(RTL_CONSTASCII_USTRINGPARAM("shared library loader component not available")), + Reference< XInterface >() ); + } + xSet->insert( makeAny( xFac ) ); + OSL_ENSHURE( xSet->has( makeAny( xFac ) ), "### failed registering loader!" ); + } + // simple registry + { + if ( !xSimRegFac.is() ) + { + throw Exception( OUString(RTL_CONSTASCII_USTRINGPARAM("simple registry component not available")), + Reference< XInterface >() ); + } + xSet->insert( makeAny( xSimRegFac ) ); + OSL_ENSHURE( xSet->has( makeAny( xSimRegFac ) ), "### failed registering simple registry!" ); + } + // nested registry + { + if ( !xNesRegFac.is() ) + { + throw Exception( OUString(RTL_CONSTASCII_USTRINGPARAM("nested registry component not available")), + Reference< XInterface >() ); + } + xSet->insert( makeAny( xNesRegFac ) ); + OSL_ENSHURE( xSet->has( makeAny( xNesRegFac ) ), "### failed registering default registry!" ); + } + // implementation registration + { + Reference< XSingleServiceFactory > xFac( createImplRegFactory( xSF, rBootstrapPath ) ); + if ( !xFac.is() ) + { + throw Exception( OUString(RTL_CONSTASCII_USTRINGPARAM("implementation registration component not available")), + Reference< XInterface >() ); + } + xSet->insert( makeAny( xFac ) ); + OSL_ENSHURE( xSet->has( makeAny( xFac ) ), "### failed registering impl reg!" ); + } + + Reference< XSimpleRegistry > xRegistry; + + // open a registry + sal_Bool bRegistryShouldBeValid = sal_False; + if (rWriteRegistry.getLength() && !rReadRegistry.getLength()) + { + bRegistryShouldBeValid = sal_True; + xRegistry = Reference< XSimpleRegistry >::query( xSimRegFac->createInstance() ); + if (xRegistry.is()) + { + if (bReadOnly) + { + xRegistry->open( rWriteRegistry, sal_True, sal_False ); + } else + { + xRegistry->open( rWriteRegistry, sal_False, sal_True ); + } + } + } + else // default registry + if (rWriteRegistry.getLength() && rReadRegistry.getLength() ) + { + bRegistryShouldBeValid = sal_True; + xRegistry = Reference< XSimpleRegistry >::query( xNesRegFac->createInstance() ); + + Reference< XSimpleRegistry > xWriteReg = Reference< XSimpleRegistry >::query( xSimRegFac->createInstance() ); + if ( xWriteReg.is() ) + { + if (bReadOnly) + { + try + { + xWriteReg->open( rWriteRegistry, sal_True, sal_False ); + } + catch(InvalidRegistryException&) + { + } + + if (!xWriteReg->isValid()) + { + throw Exception( OUString(RTL_CONSTASCII_USTRINGPARAM("specified first registry could not be open readonly")), + Reference< XInterface >() ); + } + } else + { + xWriteReg->open( rWriteRegistry, sal_False, sal_True ); + } + } + + Reference< XSimpleRegistry > xReadReg = Reference< XSimpleRegistry >::query( xSimRegFac->createInstance() ); + if ( xReadReg.is() ) + { + xReadReg->open( rReadRegistry, sal_True, sal_False ); + } + + Reference< XInitialization > xInit( xRegistry, UNO_QUERY ); + Sequence< Any > aInitSeq( 2 ); + aInitSeq[0] <<= xWriteReg; + aInitSeq[1] <<= xReadReg; + xInit->initialize( aInitSeq ); + } + + if (bRegistryShouldBeValid && (!xRegistry.is() || !xRegistry->isValid())) + { + throw Exception( OUString(RTL_CONSTASCII_USTRINGPARAM("specified registry could not be initialized")), + Reference< XInterface >() ); + } + +// OSL_ENSHURE( xRegistry.is(), "### got no registry!" ); + Reference< XInterface > xInst; + if (xRegistry.is()) + { + // init service factory with registry + Sequence< Any > aSeq( 1 ); + // registry to work on + aSeq[0] = makeAny( xRegistry ); + xInit->initialize( aSeq ); + + xInst = xSF->createInstance( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.reflection.TypeDescriptionManager")) ); + } + + // initial td manager held by service manager + if (! xInst.is()) + { + // td registry provider registration + { + Reference< XSingleServiceFactory > xFac( createRegTDProviderFactory( xSF, rBootstrapPath ) ); + if ( !xFac.is() ) + { + throw Exception( OUString(RTL_CONSTASCII_USTRINGPARAM("type description provider component not available")), + Reference< XInterface >() ); + } + xSet->insert( makeAny( xFac ) ); + OSL_ENSHURE( xSet->has( makeAny( xFac ) ), "### failed registering registry td provider!" ); + } + // stoc td manager registration + { + Reference< XSingleServiceFactory > xFac( createTDManagerFactory( xSF, rBootstrapPath ) ); + if ( !xFac.is() ) + { + throw Exception( OUString(RTL_CONSTASCII_USTRINGPARAM("type description manager component not available")), + Reference< XInterface >() ); + } + xSet->insert( makeAny( xFac ) ); + OSL_ENSHURE( xSet->has( makeAny( xFac ) ), "### failed registering td manager!" ); + } + xInst = xSF->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.reflection.TypeDescriptionManager")) ); + } + if (xInst.is()) + { + Reference< XInitialization > xTDMInit( xInst, UNO_QUERY ); + if (xTDMInit.is()) + xTDMInit->initialize( Sequence< Any >() ); + } else + { + throw Exception( OUString(RTL_CONSTASCII_USTRINGPARAM("service \"com.sun.star.reflection.TypeDescriptionManager\" could not be initialized")), + Reference< XInterface >() ); + } + return xSF; + } + return Reference< XMultiServiceFactory >(); +} + +//================================================================================================== +Reference< XMultiServiceFactory > SAL_CALL createRegistryServiceFactory( const OUString & rWriteRegistry, + const OUString & rReadRegistry, + sal_Bool bReadOnly, + const OUString & rBootstrapPath ) + throw( ::com::sun::star::uno::Exception ) +{ + return createImplServiceFactory( rWriteRegistry, rReadRegistry, bReadOnly, rBootstrapPath ); +} + +} + diff --git a/cppuhelper/source/stdidlclass.cxx b/cppuhelper/source/stdidlclass.cxx new file mode 100644 index 000000000000..139e1a8b53d1 --- /dev/null +++ b/cppuhelper/source/stdidlclass.cxx @@ -0,0 +1,240 @@ +/************************************************************************* + * + * $RCSfile: stdidlclass.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:26:10 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#include <cppuhelper/weakref.hxx> +#include <cppuhelper/weak.hxx> +#include <cppuhelper/stdidlclass.hxx> + +#include <com/sun/star/reflection/XIdlClassProvider.hpp> +#include <com/sun/star/reflection/XIdlReflection.hpp> + +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::reflection; +using namespace rtl; + +namespace cppu { + +/*--------------------------------------------------------- +* This helper class implements XIdlClass. Is used by +* createStdIdlClass() +*---------------------------------------------------------*/ +class OStdIdlClass : + public OWeakObject, + public XIdlClass, + public XIdlClassProvider +{ +public: + OStdIdlClass( + const Reference < XMultiServiceFactory > &rSMgr , + const OUString & sImplementationName , + const Reference < XIdlClass > & rSuperClass, + const Sequence < OUString > &seq + ); + + // XInterface + Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) + throw(::com::sun::star::uno::RuntimeException); + + void SAL_CALL acquire() { OWeakObject::acquire(); } + void SAL_CALL release() { OWeakObject::release(); } + + // XIdlClassProvider + Sequence< Reference < XIdlClass > > SAL_CALL getIdlClasses(void); + + // XIdlClass + virtual Sequence< Reference< XIdlClass > > SAL_CALL getClasses( ) throw(RuntimeException) + { return Sequence < Reference < XIdlClass > > (); } + virtual Reference< XIdlClass > SAL_CALL getClass( const ::rtl::OUString& aName ) throw(RuntimeException) + { return Reference < XIdlClass > (); } + virtual sal_Bool SAL_CALL equals( const Reference< XIdlClass >& Type ) throw(RuntimeException) + { return getName() == Type->getName(); } + virtual sal_Bool SAL_CALL isAssignableFrom( const Reference< XIdlClass >& xType ) throw(RuntimeException) + { return equals( xType ); } + virtual TypeClass SAL_CALL getTypeClass( ) throw(RuntimeException) + { return TypeClass_UNKNOWN; } + virtual OUString SAL_CALL getName( ) throw(RuntimeException) + { return m_sImplementationName; } + virtual Uik SAL_CALL getUik( ) throw(RuntimeException) + { return Uik(); } + virtual Sequence< Reference< XIdlClass > > SAL_CALL getSuperclasses( ) throw(RuntimeException) + { return m_seqSuperClasses; } + virtual Sequence< Reference< XIdlClass > > SAL_CALL getInterfaces( ) throw(RuntimeException); + + virtual Reference< XIdlClass > SAL_CALL getComponentType( ) throw(RuntimeException) + { return Reference < XIdlClass > (); } + virtual Reference< XIdlField > SAL_CALL getField( const ::rtl::OUString& aName ) throw(RuntimeException) + { return Reference < XIdlField > (); } + virtual Sequence< Reference< XIdlField > > SAL_CALL getFields( ) throw(RuntimeException) + { return Sequence< Reference < XIdlField > > (); } + virtual Reference< XIdlMethod > SAL_CALL getMethod( const ::rtl::OUString& aName ) throw(RuntimeException) + { return Reference < XIdlMethod > (); } + virtual Sequence< Reference< XIdlMethod > > SAL_CALL getMethods( ) throw(RuntimeException) + { return Sequence < Reference < XIdlMethod > > (); } + virtual Reference< XIdlArray > SAL_CALL getArray( ) throw(RuntimeException) + { return Reference < XIdlArray > (); } + virtual void SAL_CALL createObject( Any& obj ) throw(RuntimeException) {} + +private: + OUString m_sImplementationName; + Sequence < OUString > m_seqSupportedInterface; + Sequence < Reference < XIdlClass > > m_seqSuperClasses; + Reference < XMultiServiceFactory > m_rSMgr; +}; + + +OStdIdlClass::OStdIdlClass( + const Reference < XMultiServiceFactory > &rSMgr , + const OUString & sImplementationName , + const Reference < XIdlClass > & rSuperClass, + const Sequence < OUString > &seq + ) : + m_rSMgr( rSMgr ) , + m_sImplementationName( sImplementationName ) , + m_seqSupportedInterface( seq ) +{ + if( rSuperClass.is() ) + m_seqSuperClasses = Sequence< Reference < XIdlClass > >( &rSuperClass, 1 ); + +} + +Any SAL_CALL OStdIdlClass::queryInterface( const Type & rType ) + throw(::com::sun::star::uno::RuntimeException) +{ + Any aRet( ::cppu::queryInterface( + rType, static_cast< XIdlClass * >( this ), static_cast< XIdlClassProvider * >( this ) ) ); + + return (aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType )); +} + + +Sequence< Reference< XIdlClass > > SAL_CALL OStdIdlClass::getInterfaces( ) throw(RuntimeException) +{ + int nMax = m_seqSupportedInterface.getLength(); + + if( m_rSMgr.is() ) { + Reference < XIdlReflection > rCoreRefl = Reference < XIdlReflection > ( + m_rSMgr->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.reflection.CoreReflection") ) ), + UNO_QUERY ); + + if( rCoreRefl.is() ) { + + Sequence< Reference< XIdlClass > > seqClasses( nMax ); + + for( int n = 0 ; n < nMax ; n++ ) { + seqClasses.getArray()[n] = rCoreRefl->forName( m_seqSupportedInterface.getArray()[n] ); + } + + return seqClasses; + } + } + return Sequence< Reference< XIdlClass > > () ; +} + + +// XIdlClassProvider +Sequence< Reference < XIdlClass > > SAL_CALL OStdIdlClass::getIdlClasses(void) +{ + // weak reference to cache the standard class + static WeakReference< XIdlClass > weakRef; + + // try to make weakref hard + Reference < XIdlClass > r = weakRef; + + if( ! r.is() ) { + // xidlclass has not been initialized before or has been destroyed already. + r = ::cppu::createStandardClass( + m_rSMgr , + OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.cppuhelper.OStdIdlClass") ) , + Reference < XIdlClass > () , + SAL_STATIC_CAST( XIdlClassProvider * , this ) , + SAL_STATIC_CAST( XIdlClass * , this ) + ); + + // store reference for later use + weakRef = r; + } + + return Sequence < Reference < XIdlClass > > ( &r , 1 ); +} + + + + +// external constructor +XIdlClass * SAL_CALL createStandardClassWithSequence( + const Reference < XMultiServiceFactory > &rSMgr , + const OUString & sImplementationName , + const Reference < XIdlClass > & rSuperClass, + const Sequence < OUString > &seqInterfaceNames ) +{ + return SAL_STATIC_CAST( + XIdlClass * , + new OStdIdlClass( + rSMgr , + sImplementationName, + rSuperClass, + seqInterfaceNames + ) + ); +} + +} //end namespace cppu diff --git a/cppuhelper/source/typeprovider.cxx b/cppuhelper/source/typeprovider.cxx new file mode 100644 index 000000000000..585c50a68071 --- /dev/null +++ b/cppuhelper/source/typeprovider.cxx @@ -0,0 +1,344 @@ +/************************************************************************* + * + * $RCSfile: typeprovider.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:26:10 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#include <cppuhelper/typeprovider.hxx> +#include <osl/mutex.hxx> + +using namespace osl; +using namespace com::sun::star::uno; + +namespace cppu +{ + +//__________________________________________________________________________________________________ +OImplementationId::~OImplementationId() +{ + delete _pSeq; +} +//__________________________________________________________________________________________________ +Sequence< sal_Int8 > OImplementationId::getImplementationId() const +{ + if (! _pSeq) + { + MutexGuard aGuard( Mutex::getGlobalMutex() ); + if (! _pSeq) + { + Sequence< sal_Int8 > * pSeq = new Sequence< sal_Int8 >( 16 ); + ::rtl_createUuid( (sal_uInt8 *)pSeq->getArray(), 0, _bUseEthernetAddress ); + _pSeq = pSeq; + } + } + return *_pSeq; +} + +//-------------------------------------------------------------------------------------------------- +static inline void copy( Sequence< Type > & rDest, const Sequence< Type > & rSource, sal_Int32 nOffset ) +{ + Type * pDest = rDest.getArray(); + const Type * pSource = rSource.getConstArray(); + + for ( sal_Int32 nPos = rSource.getLength(); nPos--; ) + pDest[nOffset+ nPos] = pSource[nPos]; +} + +//__________________________________________________________________________________________________ +OTypeCollection::OTypeCollection( + const Type & rType1, + const Sequence< Type > & rAddTypes ) + : _aTypes( 1 + rAddTypes.getLength() ) +{ + _aTypes[0] = rType1; + copy( _aTypes, rAddTypes, 1 ); +} +//__________________________________________________________________________________________________ +OTypeCollection::OTypeCollection( + const Type & rType1, + const Type & rType2, + const Sequence< Type > & rAddTypes ) + : _aTypes( 2 + rAddTypes.getLength() ) +{ + _aTypes[0] = rType1; + _aTypes[1] = rType2; + copy( _aTypes, rAddTypes, 2 ); +} +//__________________________________________________________________________________________________ +OTypeCollection::OTypeCollection( + const Type & rType1, + const Type & rType2, + const Type & rType3, + const Sequence< Type > & rAddTypes ) + : _aTypes( 3 + rAddTypes.getLength() ) +{ + _aTypes[0] = rType1; + _aTypes[1] = rType2; + _aTypes[2] = rType3; + copy( _aTypes, rAddTypes, 3 ); +} +//__________________________________________________________________________________________________ +OTypeCollection::OTypeCollection( + const Type & rType1, + const Type & rType2, + const Type & rType3, + const Type & rType4, + const Sequence< Type > & rAddTypes ) + : _aTypes( 4 + rAddTypes.getLength() ) +{ + _aTypes[0] = rType1; + _aTypes[1] = rType2; + _aTypes[2] = rType3; + _aTypes[3] = rType4; + copy( _aTypes, rAddTypes, 4 ); +} +//__________________________________________________________________________________________________ +OTypeCollection::OTypeCollection( + const Type & rType1, + const Type & rType2, + const Type & rType3, + const Type & rType4, + const Type & rType5, + const Sequence< Type > & rAddTypes ) + : _aTypes( 5 + rAddTypes.getLength() ) +{ + _aTypes[0] = rType1; + _aTypes[1] = rType2; + _aTypes[2] = rType3; + _aTypes[3] = rType4; + _aTypes[4] = rType5; + copy( _aTypes, rAddTypes, 5 ); +} +//__________________________________________________________________________________________________ +OTypeCollection::OTypeCollection( + const Type & rType1, + const Type & rType2, + const Type & rType3, + const Type & rType4, + const Type & rType5, + const Type & rType6, + const Sequence< Type > & rAddTypes ) + : _aTypes( 6 + rAddTypes.getLength() ) +{ + _aTypes[0] = rType1; + _aTypes[1] = rType2; + _aTypes[2] = rType3; + _aTypes[3] = rType4; + _aTypes[4] = rType5; + _aTypes[5] = rType6; + copy( _aTypes, rAddTypes, 6 ); +} +//__________________________________________________________________________________________________ +OTypeCollection::OTypeCollection( + const Type & rType1, + const Type & rType2, + const Type & rType3, + const Type & rType4, + const Type & rType5, + const Type & rType6, + const Type & rType7, + const Sequence< Type > & rAddTypes ) + : _aTypes( 7 + rAddTypes.getLength() ) +{ + _aTypes[0] = rType1; + _aTypes[1] = rType2; + _aTypes[2] = rType3; + _aTypes[3] = rType4; + _aTypes[4] = rType5; + _aTypes[5] = rType6; + _aTypes[6] = rType7; + copy( _aTypes, rAddTypes, 7 ); +} +//__________________________________________________________________________________________________ +OTypeCollection::OTypeCollection( + const Type & rType1, + const Type & rType2, + const Type & rType3, + const Type & rType4, + const Type & rType5, + const Type & rType6, + const Type & rType7, + const Type & rType8, + const Sequence< Type > & rAddTypes ) + : _aTypes( 8 + rAddTypes.getLength() ) +{ + _aTypes[0] = rType1; + _aTypes[1] = rType2; + _aTypes[2] = rType3; + _aTypes[3] = rType4; + _aTypes[4] = rType5; + _aTypes[5] = rType6; + _aTypes[6] = rType7; + _aTypes[7] = rType8; + copy( _aTypes, rAddTypes, 8 ); +} +//__________________________________________________________________________________________________ +OTypeCollection::OTypeCollection( + const Type & rType1, + const Type & rType2, + const Type & rType3, + const Type & rType4, + const Type & rType5, + const Type & rType6, + const Type & rType7, + const Type & rType8, + const Type & rType9, + const Sequence< Type > & rAddTypes ) + : _aTypes( 9 + rAddTypes.getLength() ) +{ + _aTypes[0] = rType1; + _aTypes[1] = rType2; + _aTypes[2] = rType3; + _aTypes[3] = rType4; + _aTypes[4] = rType5; + _aTypes[5] = rType6; + _aTypes[6] = rType7; + _aTypes[7] = rType8; + _aTypes[8] = rType9; + copy( _aTypes, rAddTypes, 9 ); +} +//__________________________________________________________________________________________________ +OTypeCollection::OTypeCollection( + const Type & rType1, + const Type & rType2, + const Type & rType3, + const Type & rType4, + const Type & rType5, + const Type & rType6, + const Type & rType7, + const Type & rType8, + const Type & rType9, + const Type & rType10, + const Sequence< Type > & rAddTypes ) + : _aTypes( 10 + rAddTypes.getLength() ) +{ + _aTypes[0] = rType1; + _aTypes[1] = rType2; + _aTypes[2] = rType3; + _aTypes[3] = rType4; + _aTypes[4] = rType5; + _aTypes[5] = rType6; + _aTypes[6] = rType7; + _aTypes[7] = rType8; + _aTypes[8] = rType9; + _aTypes[9] = rType10; + copy( _aTypes, rAddTypes, 10 ); +} +//__________________________________________________________________________________________________ +OTypeCollection::OTypeCollection( + const Type & rType1, + const Type & rType2, + const Type & rType3, + const Type & rType4, + const Type & rType5, + const Type & rType6, + const Type & rType7, + const Type & rType8, + const Type & rType9, + const Type & rType10, + const Type & rType11, + const Sequence< Type > & rAddTypes ) + : _aTypes( 11 + rAddTypes.getLength() ) +{ + _aTypes[0] = rType1; + _aTypes[1] = rType2; + _aTypes[2] = rType3; + _aTypes[3] = rType4; + _aTypes[4] = rType5; + _aTypes[5] = rType6; + _aTypes[6] = rType7; + _aTypes[7] = rType8; + _aTypes[8] = rType9; + _aTypes[9] = rType10; + _aTypes[10] = rType11; + copy( _aTypes, rAddTypes, 11 ); +} +//__________________________________________________________________________________________________ +OTypeCollection::OTypeCollection( + const Type & rType1, + const Type & rType2, + const Type & rType3, + const Type & rType4, + const Type & rType5, + const Type & rType6, + const Type & rType7, + const Type & rType8, + const Type & rType9, + const Type & rType10, + const Type & rType11, + const Type & rType12, + const Sequence< Type > & rAddTypes ) + : _aTypes( 12 + rAddTypes.getLength() ) +{ + _aTypes[0] = rType1; + _aTypes[1] = rType2; + _aTypes[2] = rType3; + _aTypes[3] = rType4; + _aTypes[4] = rType5; + _aTypes[5] = rType6; + _aTypes[6] = rType7; + _aTypes[7] = rType8; + _aTypes[8] = rType9; + _aTypes[9] = rType10; + _aTypes[10] = rType11; + _aTypes[11] = rType12; + copy( _aTypes, rAddTypes, 12 ); +} + +} + diff --git a/cppuhelper/source/weak.cxx b/cppuhelper/source/weak.cxx new file mode 100644 index 000000000000..3765fc5e7852 --- /dev/null +++ b/cppuhelper/source/weak.cxx @@ -0,0 +1,521 @@ +/************************************************************************* + * + * $RCSfile: weak.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:26:10 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ +#ifndef _OSL_MUTEX_HXX_ +#include <osl/mutex.hxx> +#endif +#ifndef _CPPU_WEAKAGG_HXX_ +#include <cppuhelper/weakagg.hxx> +#endif +#ifndef _CPPU_HELPER_INTERFACECONTAINER_HXX_ +#include <cppuhelper/interfacecontainer.hxx> +#endif + +using namespace osl; +using namespace com::sun::star::uno; + +/** */ //for docpp +namespace cppu +{ + +/** + The mutex to synchronize the the queryAdapted call throug the connection point + with the release call at the weak object. + */ +/* +struct WeakMutexStatic +{ + Mutex aMutex; + sal_Bool bDestructed; + + WeakMutexStatic() + : bDestructed( sal_False ) + {} + ~WeakMutexStatic() + { bDestructed = sal_True; } +}; + +inline static Mutex & getWeakMutex() throw() +{ + static WeakMutexStatic s_wmstatic; + if (s_wmstatic.bDestructed) + return *Mutex::getGlobalMutex(); + else + return s_wmstatic.aMutex; +} +*/ + +// due to static Reflection destruction from usr, ther must be a mutex leak (#73272#) +inline static Mutex & getWeakMutex() throw() +{ + static Mutex * s_pMutex = 0; + if (! s_pMutex) + s_pMutex = new Mutex(); + return *s_pMutex; +} + +//------------------------------------------------------------------------ +//-- OWeakConnectionPoint ---------------------------------------------------- +//------------------------------------------------------------------------ +class OWeakConnectionPoint : public XAdapter +{ +public: + /** + Hold the weak object without an acquire (only the pointer). + */ + OWeakConnectionPoint( OWeakObject* pObj ) throw() + : m_aRefCount( 0 ) + , m_pObject(pObj) + , m_aReferences( getWeakMutex() ) + {} + + // XInterface + Any SAL_CALL queryInterface( const Type & rType ) throw(::com::sun::star::uno::RuntimeException); + void SAL_CALL acquire() throw(); + void SAL_CALL release() throw(); + + // XAdapter + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL queryAdapted() throw(::com::sun::star::uno::RuntimeException); + void SAL_CALL addReference( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XReference >& xRef ) throw(::com::sun::star::uno::RuntimeException); + void SAL_CALL removeReference( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XReference >& xRef ) throw(::com::sun::star::uno::RuntimeException); + + /// Called from the weak object if the reference count goes to zero. + void SAL_CALL dispose() throw(::com::sun::star::uno::RuntimeException); +protected: + /// The reference counter. + oslInterlockedCount m_aRefCount; + /// The weak object + OWeakObject* m_pObject; + /// The container to hold the weak references + OInterfaceContainerHelper m_aReferences; +}; + +// XInterface +Any SAL_CALL OWeakConnectionPoint::queryInterface( const Type & rType ) + throw(com::sun::star::uno::RuntimeException) +{ + return ::cppu::queryInterface( + rType, static_cast< XAdapter * >( this ), static_cast< XInterface * >( this ) ); +} + +// XInterface +void SAL_CALL OWeakConnectionPoint::acquire() throw() +{ + osl_incrementInterlockedCount( &m_aRefCount ); +} + +// XInterface +void SAL_CALL OWeakConnectionPoint::release() throw() +{ + if (! osl_decrementInterlockedCount( &m_aRefCount )) + delete this; +} + +void SAL_CALL OWeakConnectionPoint::dispose() throw(::com::sun::star::uno::RuntimeException) +{ + OInterfaceIteratorHelper aIt( m_aReferences ); + while( aIt.hasMoreElements() ) + ((XReference *)aIt.next())->dispose(); +} + +// XInterface +Reference< XInterface > SAL_CALL OWeakConnectionPoint::queryAdapted() throw(::com::sun::star::uno::RuntimeException) +{ + Reference< XInterface > ret; + + ClearableMutexGuard guard(getWeakMutex()); + + if (m_pObject) + { + oslInterlockedCount n = osl_incrementInterlockedCount( &m_pObject->m_refCount ); + + if (n > 1) + { + // The refence is incremented. The object cannot be destroyed. + // Release the guard at the earliest point. + guard.clear(); + // WeakObject has a (XInterface *) cast operator + ret = *m_pObject; + n = osl_decrementInterlockedCount( &m_pObject->m_refCount ); + } + else + // Another thread wait in the dispose method at the guard + n = osl_decrementInterlockedCount( &m_pObject->m_refCount ); + } + + return ret; +} + +// XInterface +void SAL_CALL OWeakConnectionPoint::addReference(const Reference< XReference >& rRef) + throw(::com::sun::star::uno::RuntimeException) +{ + m_aReferences.addInterface( (const Reference< XInterface > &)rRef ); +} + +// XInterface +void SAL_CALL OWeakConnectionPoint::removeReference(const Reference< XReference >& rRef) + throw(::com::sun::star::uno::RuntimeException) +{ + m_aReferences.removeInterface( (const Reference< XInterface > &)rRef ); +} + + +//------------------------------------------------------------------------ +//-- OWeakObject ------------------------------------------------------- +//------------------------------------------------------------------------ + +// XInterface +Any SAL_CALL OWeakObject::queryInterface( const Type & rType ) throw(::com::sun::star::uno::RuntimeException) +{ + return ::cppu::queryInterface( + rType, + static_cast< XWeak * >( this ), static_cast< XInterface * >( this ) ); +} + +// XInterface +void SAL_CALL OWeakObject::acquire() throw() +{ + osl_incrementInterlockedCount( &m_refCount ); +} + +// XInterface +void SAL_CALL OWeakObject::release() throw() +{ + if (osl_decrementInterlockedCount( &m_refCount ) == 0) + { + if (m_pWeakConnectionPoint) + { + OWeakConnectionPoint * p = m_pWeakConnectionPoint; + m_pWeakConnectionPoint = 0; + p->dispose(); + p->release(); + } + delete this; + } +} + +OWeakObject::~OWeakObject() throw(::com::sun::star::uno::RuntimeException) +{ +} + +// XWeak +Reference< XAdapter > SAL_CALL OWeakObject::queryAdapter(void) throw() +{ + if (!m_pWeakConnectionPoint) + { + // only acquire mutex if member is not created + MutexGuard aGuard( getWeakMutex() ); + if( !m_pWeakConnectionPoint ) + { + OWeakConnectionPoint * p = new OWeakConnectionPoint(this); + p->acquire(); + m_pWeakConnectionPoint = p; + } + } + + return m_pWeakConnectionPoint; +} + +//------------------------------------------------------------------------ +//-- OWeakAggObject ---------------------------------------------------- +//------------------------------------------------------------------------ +OWeakAggObject::~OWeakAggObject() +{ +} + +// XInterface +void OWeakAggObject::acquire() throw() +{ + Reference<XInterface > x( xDelegator ); + if (x.is()) + x->acquire(); + else + OWeakObject::acquire(); +} + +// XInterface +void OWeakAggObject::release() throw() +{ + Reference<XInterface > x( xDelegator ); + if (x.is()) + x->release(); + else + OWeakObject::release(); +} + +// XInterface +Any OWeakAggObject::queryInterface( const Type & rType ) throw(::com::sun::star::uno::RuntimeException) +{ + Reference< XInterface > x( xDelegator ); // harden ref + return (x.is() ? x->queryInterface( rType ) : queryAggregation( rType )); + +// // set rOut to zero, if failed +// if( !xDelegator.queryHardRef( aUik, rOut ) ) +// { +// XInterfaceRef x; +// if( !xDelegator.queryHardRef( ((XInterface*)0)->getSmartUik(), x ) ) +// // reference is not valid +// queryAggregation( aUik, rOut ); +// } +// return rOut.is(); +} + +// XAggregation +Any OWeakAggObject::queryAggregation( const Type & rType ) throw(::com::sun::star::uno::RuntimeException) +{ + return ::cppu::queryInterface( + rType, + static_cast< XInterface * >( static_cast< OWeakObject * >( this ) ), + static_cast< XAggregation * >( this ), + static_cast< XWeak * >( this ) ); +} + +// XAggregation +void OWeakAggObject::setDelegator( const Reference<XInterface > & rDelegator ) throw(::com::sun::star::uno::RuntimeException) +{ + xDelegator = rDelegator; +} + +} + +/** */ //for docpp +namespace com +{ +/** */ //for docpp +namespace sun +{ +/** */ //for docpp +namespace star +{ +/** */ //for docpp +namespace uno +{ + + +//------------------------------------------------------------------------ +//-- OWeakRefListener ----------------------------------------------------- +//------------------------------------------------------------------------ +class OWeakRefListener : public XReference +{ +public: + OWeakRefListener(); + OWeakRefListener(const OWeakRefListener& rRef); + OWeakRefListener(const Reference< XInterface >& xInt); + ~OWeakRefListener(); + + // XInterface + Any SAL_CALL queryInterface( const Type & rType ) throw(); + void SAL_CALL acquire() throw(); + void SAL_CALL release() throw(); + + // XReference + void SAL_CALL dispose() throw(::com::sun::star::uno::RuntimeException); + + /// The reference counter. + oslInterlockedCount m_aRefCount; + /// The connection point of the weak object + Reference< XAdapter > m_XWeakConnectionPoint; + +private: + OWeakRefListener& SAL_CALL operator=(const OWeakRefListener& rRef); +}; + +OWeakRefListener::OWeakRefListener() + : m_aRefCount( 0 ) +{ +} + +OWeakRefListener::OWeakRefListener(const OWeakRefListener& rRef) + : m_aRefCount( 0 ) +{ + m_XWeakConnectionPoint = rRef.m_XWeakConnectionPoint; + + if (m_XWeakConnectionPoint.is()) + m_XWeakConnectionPoint->addReference((XReference*)this); +} + +OWeakRefListener::OWeakRefListener(const Reference< XInterface >& xInt) + : m_aRefCount( 0 ) +{ + Reference< XWeak > xWeak( Reference< XWeak >::query( xInt ) ); + + if (xWeak.is()) + { + m_XWeakConnectionPoint = xWeak->queryAdapter(); + + if (m_XWeakConnectionPoint.is()) + { + m_XWeakConnectionPoint->addReference((XReference*)this); + } + } +} + +OWeakRefListener::~OWeakRefListener() +{ + acquire(); // dont die again + if (m_XWeakConnectionPoint.is()) + m_XWeakConnectionPoint->removeReference((XReference*)this); +} + +// XInterface +Any SAL_CALL OWeakRefListener::queryInterface( const Type & rType ) throw() +{ + return ::cppu::queryInterface( + rType, static_cast< XReference * >( this ), static_cast< XInterface * >( this ) ); +} + +// XInterface +void SAL_CALL OWeakRefListener::acquire() throw() +{ + osl_incrementInterlockedCount( &m_aRefCount ); +} + +// XInterface +void SAL_CALL OWeakRefListener::release() throw() +{ + if( ! osl_decrementInterlockedCount( &m_aRefCount ) ) + delete this; +} + +void SAL_CALL OWeakRefListener::dispose() + throw(::com::sun::star::uno::RuntimeException) +{ + Reference< XAdapter > xAdp; + { + MutexGuard guard(cppu::getWeakMutex()); + if( m_XWeakConnectionPoint.is() ) + { + xAdp = m_XWeakConnectionPoint; + m_XWeakConnectionPoint.clear(); + } + } + + if( xAdp.is() ) + xAdp->removeReference((XReference*)this); +} + +//------------------------------------------------------------------------ +//-- WeakReferenceHelper ---------------------------------------------------------- +//------------------------------------------------------------------------ +WeakReferenceHelper::WeakReferenceHelper(const Reference< XInterface >& xInt) +{ + m_pImpl = new OWeakRefListener(xInt); + m_pImpl->acquire(); +} + +WeakReferenceHelper::WeakReferenceHelper(const WeakReferenceHelper& rWeakRef) +{ + m_pImpl = rWeakRef.m_pImpl; + + if( m_pImpl ) + m_pImpl->acquire(); +} + +WeakReferenceHelper& WeakReferenceHelper::operator=(const WeakReferenceHelper& rWeakRef) +{ + OWeakRefListener* pOldImpl; + { + // the weak reference is multithread save + MutexGuard guard(cppu::getWeakMutex()); + if (m_pImpl == rWeakRef.m_pImpl) + return *this; + + pOldImpl = m_pImpl; + + m_pImpl = rWeakRef.m_pImpl; + if ( m_pImpl ) + { + m_pImpl->acquire(); + } + } + + // maybe call the destructor. It is better to release the guard before this call. + if( pOldImpl ) + pOldImpl->release(); + return *this; +} + +WeakReferenceHelper::~WeakReferenceHelper() +{ + if (m_pImpl) + m_pImpl->release(); +} + +Reference< XInterface > WeakReferenceHelper::get() const +{ + Reference< XAdapter > xAdp; + { + MutexGuard guard(cppu::getWeakMutex()); + if( m_pImpl && m_pImpl->m_XWeakConnectionPoint.is() ) + xAdp = m_pImpl->m_XWeakConnectionPoint; + } + + if (xAdp.is()) + return xAdp->queryAdapted(); + + return Reference< XInterface >(); +} + +} +} +} +} + |