summaryrefslogtreecommitdiff
path: root/cppuhelper/source/implbase.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'cppuhelper/source/implbase.cxx')
-rw-r--r--cppuhelper/source/implbase.cxx474
1 files changed, 474 insertions, 0 deletions
diff --git a/cppuhelper/source/implbase.cxx b/cppuhelper/source/implbase.cxx
new file mode 100644
index 000000000000..162f11d81cc8
--- /dev/null
+++ b/cppuhelper/source/implbase.cxx
@@ -0,0 +1,474 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_cppuhelper.hxx"
+#include <cppuhelper/implbase.hxx>
+#include <cppuhelper/compbase.hxx>
+#include <osl/diagnose.h>
+#include <rtl/uuid.h>
+
+#include <com/sun/star/lang/XComponent.hpp>
+#include "com/sun/star/uno/RuntimeException.hpp"
+
+using namespace ::osl;
+using namespace ::rtl;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+namespace cppu
+{
+//==================================================================================================
+Mutex & SAL_CALL getImplHelperInitMutex(void) SAL_THROW( () )
+{
+ static Mutex * s_pMutex = 0;
+ if (! s_pMutex)
+ {
+ MutexGuard aGuard( Mutex::getGlobalMutex() );
+ if (! s_pMutex)
+ {
+ static Mutex s_aMutex;
+ s_pMutex = & s_aMutex;
+ }
+ }
+ return * s_pMutex;
+}
+
+// ClassDataBase
+//__________________________________________________________________________________________________
+ClassDataBase::ClassDataBase() SAL_THROW( () )
+ : bOffsetsInit( sal_False )
+ , nType2Offset( 0 )
+ , nClassCode( 0 )
+ , pTypes( 0 )
+ , pId( 0 )
+{
+}
+//__________________________________________________________________________________________________
+ClassDataBase::ClassDataBase( sal_Int32 nClassCode_ ) SAL_THROW( () )
+ : bOffsetsInit( sal_False )
+ , nType2Offset( 0 )
+ , nClassCode( nClassCode_ )
+ , pTypes( 0 )
+ , pId( 0 )
+{
+}
+//__________________________________________________________________________________________________
+ClassDataBase::~ClassDataBase() SAL_THROW( () )
+{
+ 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 ) SAL_THROW( () )
+{
+ arType2Offset[nType2Offset].nOffset = nOffset;
+
+ arType2Offset[nType2Offset].pTD = 0;
+ typelib_typedescriptionreference_getDescription(
+ (typelib_TypeDescription **)&arType2Offset[nType2Offset].pTD, rType.getTypeLibType() );
+
+ if (arType2Offset[nType2Offset].pTD)
+ ++nType2Offset;
+#if OSL_DEBUG_LEVEL > 1
+ else
+ {
+ OString msg( "### cannot get type description for " );
+ msg += OUStringToOString( rType.getTypeName(), RTL_TEXTENCODING_ASCII_US );
+ OSL_FAIL( msg.getStr() );
+ }
+#endif
+}
+//__________________________________________________________________________________________________
+void ClassData::initTypeProvider() SAL_THROW( () )
+{
+ ::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< lang::XTypeProvider > *)0 );
+
+ // class code extra types: [[XComponent,] XWeak[, XAggregation]]
+ switch (nClassCode)
+ {
+ case 4:
+ pTypeAr[nType2Offset +2] = ::getCppuType( (const Reference< lang::XComponent > *)0 );
+ pTypeAr[nType2Offset +1] = ::getCppuType( (const Reference< XWeak > *)0 );
+ break;
+ case 3:
+ pTypeAr[nType2Offset +3] = ::getCppuType( (const Reference< lang::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() SAL_THROW( () )
+{
+ if (! pTypes)
+ initTypeProvider();
+ return *pTypes;
+}
+//__________________________________________________________________________________________________
+Sequence< sal_Int8 > ClassData::getImplementationId() SAL_THROW( () )
+{
+ if (! pTypes)
+ initTypeProvider();
+ return *pId;
+}
+
+//--------------------------------------------------------------------------------------------------
+static inline sal_Bool td_equals(
+ typelib_TypeDescription * pTD, typelib_TypeDescriptionReference * pType )
+ SAL_THROW( () )
+{
+ 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, lang::XTypeProvider * pBase ) SAL_THROW( () )
+{
+ 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< lang::XTypeProvider > *)0 ))
+ return Any( &pBase, ::getCppuType( (const Reference< lang::XTypeProvider > *)0 ) );
+
+ return Any();
+}
+
+//##################################################################################################
+//##################################################################################################
+//##################################################################################################
+
+// WeakComponentImplHelperBase
+//__________________________________________________________________________________________________
+WeakComponentImplHelperBase::WeakComponentImplHelperBase( Mutex & rMutex )
+ SAL_THROW( () )
+ : rBHelper( rMutex )
+{
+}
+//__________________________________________________________________________________________________
+WeakComponentImplHelperBase::~WeakComponentImplHelperBase()
+ SAL_THROW( () )
+{
+}
+//__________________________________________________________________________________________________
+void WeakComponentImplHelperBase::disposing()
+{
+}
+//__________________________________________________________________________________________________
+Any WeakComponentImplHelperBase::queryInterface( Type const & rType )
+ throw (RuntimeException)
+{
+ if (rType == ::getCppuType( (Reference< lang::XComponent > const *)0 ))
+ {
+ void * p = static_cast< lang::XComponent * >( this );
+ return Any( &p, rType );
+ }
+ return OWeakObject::queryInterface( rType );
+}
+//__________________________________________________________________________________________________
+void WeakComponentImplHelperBase::acquire()
+ throw ()
+{
+ OWeakObject::acquire();
+}
+//__________________________________________________________________________________________________
+void WeakComponentImplHelperBase::release()
+ throw ()
+{
+ if (osl_decrementInterlockedCount( &m_refCount ) == 0) {
+ // ensure no other references are created, via the weak connection point, from now on
+ disposeWeakConnectionPoint();
+ // restore reference count:
+ osl_incrementInterlockedCount( &m_refCount );
+ if (! rBHelper.bDisposed) {
+ try {
+ dispose();
+ }
+ catch (RuntimeException const& exc) { // don't break throw ()
+ OSL_FAIL(
+ OUStringToOString(
+ exc.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
+ static_cast<void>(exc);
+ }
+ OSL_ASSERT( rBHelper.bDisposed );
+ }
+ OWeakObject::release();
+ }
+}
+//__________________________________________________________________________________________________
+void WeakComponentImplHelperBase::dispose()
+ throw (RuntimeException)
+{
+ ClearableMutexGuard aGuard( rBHelper.rMutex );
+ if (!rBHelper.bDisposed && !rBHelper.bInDispose)
+ {
+ rBHelper.bInDispose = sal_True;
+ aGuard.clear();
+ try
+ {
+ // side effect: keeping a reference to this
+ lang::EventObject aEvt( static_cast< OWeakObject * >( this ) );
+ try
+ {
+ rBHelper.aLC.disposeAndClear( aEvt );
+ disposing();
+ }
+ catch (...)
+ {
+ MutexGuard aGuard2( rBHelper.rMutex );
+ // bDisposed and bInDispose must be set in this order:
+ rBHelper.bDisposed = sal_True;
+ rBHelper.bInDispose = sal_False;
+ throw;
+ }
+ MutexGuard aGuard2( rBHelper.rMutex );
+ // bDisposed and bInDispose must be set in this order:
+ rBHelper.bDisposed = sal_True;
+ rBHelper.bInDispose = sal_False;
+ }
+ catch (RuntimeException &)
+ {
+ throw;
+ }
+ catch (Exception & exc)
+ {
+ throw RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "unexpected UNO exception caught: ") ) +
+ exc.Message, Reference< XInterface >() );
+ }
+ }
+}
+//__________________________________________________________________________________________________
+void WeakComponentImplHelperBase::addEventListener(
+ Reference< lang::XEventListener > const & xListener )
+ throw (RuntimeException)
+{
+ ClearableMutexGuard aGuard( rBHelper.rMutex );
+ if (rBHelper.bDisposed || rBHelper.bInDispose)
+ {
+ aGuard.clear();
+ lang::EventObject aEvt( static_cast< OWeakObject * >( this ) );
+ xListener->disposing( aEvt );
+ }
+ else
+ {
+ rBHelper.addListener( ::getCppuType( &xListener ), xListener );
+ }
+}
+//__________________________________________________________________________________________________
+void WeakComponentImplHelperBase::removeEventListener(
+ Reference< lang::XEventListener > const & xListener )
+ throw (RuntimeException)
+{
+ rBHelper.removeListener( ::getCppuType( &xListener ), xListener );
+}
+
+// WeakAggComponentImplHelperBase
+//__________________________________________________________________________________________________
+WeakAggComponentImplHelperBase::WeakAggComponentImplHelperBase( Mutex & rMutex )
+ SAL_THROW( () )
+ : rBHelper( rMutex )
+{
+}
+//__________________________________________________________________________________________________
+WeakAggComponentImplHelperBase::~WeakAggComponentImplHelperBase()
+ SAL_THROW( () )
+{
+}
+//__________________________________________________________________________________________________
+void WeakAggComponentImplHelperBase::disposing()
+{
+}
+//__________________________________________________________________________________________________
+Any WeakAggComponentImplHelperBase::queryInterface( Type const & rType )
+ throw (RuntimeException)
+{
+ return OWeakAggObject::queryInterface( rType );
+}
+//__________________________________________________________________________________________________
+Any WeakAggComponentImplHelperBase::queryAggregation( Type const & rType )
+ throw (RuntimeException)
+{
+ if (rType == ::getCppuType( (Reference< lang::XComponent > const *)0 ))
+ {
+ void * p = static_cast< lang::XComponent * >( this );
+ return Any( &p, rType );
+ }
+ return OWeakAggObject::queryAggregation( rType );
+}
+//__________________________________________________________________________________________________
+void WeakAggComponentImplHelperBase::acquire()
+ throw ()
+{
+ OWeakAggObject::acquire();
+}
+//__________________________________________________________________________________________________
+void WeakAggComponentImplHelperBase::release()
+ throw ()
+{
+ Reference<XInterface> const xDelegator_(xDelegator);
+ if (xDelegator_.is()) {
+ OWeakAggObject::release();
+ }
+ else if (osl_decrementInterlockedCount( &m_refCount ) == 0) {
+ // ensure no other references are created, via the weak connection point, from now on
+ disposeWeakConnectionPoint();
+ // restore reference count:
+ osl_incrementInterlockedCount( &m_refCount );
+ if (! rBHelper.bDisposed) {
+ try {
+ dispose();
+ }
+ catch (RuntimeException const& exc) { // don't break throw ()
+ OSL_FAIL(
+ OUStringToOString(
+ exc.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
+ static_cast<void>(exc);
+ }
+ OSL_ASSERT( rBHelper.bDisposed );
+ }
+ OWeakAggObject::release();
+ }
+}
+//__________________________________________________________________________________________________
+void WeakAggComponentImplHelperBase::dispose()
+ throw (RuntimeException)
+{
+ ClearableMutexGuard aGuard( rBHelper.rMutex );
+ if (!rBHelper.bDisposed && !rBHelper.bInDispose)
+ {
+ rBHelper.bInDispose = sal_True;
+ aGuard.clear();
+ try
+ {
+ // side effect: keeping a reference to this
+ lang::EventObject aEvt( static_cast< OWeakObject * >( this ) );
+ try
+ {
+ rBHelper.aLC.disposeAndClear( aEvt );
+ disposing();
+ }
+ catch (...)
+ {
+ MutexGuard aGuard2( rBHelper.rMutex );
+ // bDisposed and bInDispose must be set in this order:
+ rBHelper.bDisposed = sal_True;
+ rBHelper.bInDispose = sal_False;
+ throw;
+ }
+ MutexGuard aGuard2( rBHelper.rMutex );
+ // bDisposed and bInDispose must be set in this order:
+ rBHelper.bDisposed = sal_True;
+ rBHelper.bInDispose = sal_False;
+ }
+ catch (RuntimeException &)
+ {
+ throw;
+ }
+ catch (Exception & exc)
+ {
+ throw RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "unexpected UNO exception caught: ") ) +
+ exc.Message, Reference< XInterface >() );
+ }
+ }
+}
+//__________________________________________________________________________________________________
+void WeakAggComponentImplHelperBase::addEventListener(
+ Reference< lang::XEventListener > const & xListener )
+ throw (RuntimeException)
+{
+ ClearableMutexGuard aGuard( rBHelper.rMutex );
+ if (rBHelper.bDisposed || rBHelper.bInDispose)
+ {
+ aGuard.clear();
+ lang::EventObject aEvt( static_cast< OWeakObject * >( this ) );
+ xListener->disposing( aEvt );
+ }
+ else
+ {
+ rBHelper.addListener( ::getCppuType( &xListener ), xListener );
+ }
+}
+//__________________________________________________________________________________________________
+void WeakAggComponentImplHelperBase::removeEventListener(
+ Reference< lang::XEventListener > const & xListener )
+ throw (RuntimeException)
+{
+ rBHelper.removeListener( ::getCppuType( &xListener ), xListener );
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */