| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_sot.hxx" |
| |
| #define _SOT_FACTORY_CXX |
| #define SOT_STRING_LIST |
| |
| #include <sot/factory.hxx> |
| #include <tools/debug.hxx> |
| #include <tools/string.hxx> |
| #include <sot/object.hxx> |
| #include <sot/sotdata.hxx> |
| #include <sot/clsids.hxx> |
| #include <rtl/instance.hxx> |
| #include <com/sun/star/datatransfer/DataFlavor.hpp> |
| |
| /************** class SotData_Impl *********************************************/ |
| /************************************************************************* |
| |* SotData_Impl::SotData_Impl |
| |* |
| |* Beschreibung |
| *************************************************************************/ |
| SotData_Impl::SotData_Impl() |
| : nSvObjCount( 0 ) |
| , pObjectList( NULL ) |
| , pFactoryList( NULL ) |
| , pSotObjectFactory( NULL ) |
| , pSotStorageStreamFactory( NULL ) |
| , pSotStorageFactory( NULL ) |
| , pDataFlavorList( NULL ) |
| { |
| } |
| /************************************************************************* |
| |* SOTDATA() |
| |* |
| |* Beschreibung |
| *************************************************************************/ |
| namespace { struct ImplData : public rtl::Static<SotData_Impl, ImplData> {}; } |
| SotData_Impl * SOTDATA() |
| { |
| return &ImplData::get(); |
| } |
| |
| /************************************************************************* |
| |* SotFactory::DeInit() |
| |* |
| |* Beschreibung |
| *************************************************************************/ |
| void SotFactory::DeInit() |
| { |
| SotData_Impl * pSotData = SOTDATA(); |
| |
| if( pSotData->nSvObjCount ) |
| { |
| #ifdef DBG_UTIL |
| ByteString aStr( "Objects alive: " ); |
| aStr.Append( ByteString::CreateFromInt32( pSotData->nSvObjCount ) ); |
| DBG_WARNING( aStr.GetBuffer() ); |
| |
| /* |
| SotObjectList *pObjList = pSotData->pObjectList; |
| |
| if( pObjList ) |
| { |
| SotObject * p = pObjList->First(); |
| while( p ) |
| { |
| String aStr( "Factory: " ); |
| aStr += p->GetSvFactory()->GetClassName(); |
| aStr += " Count: "; |
| aStr += p->GetRefCount(); |
| DBG_TRACE( "\tReferences:" ); |
| p->TestObjRef( sal_False ); |
| #ifdef TEST_INVARIANT |
| DBG_TRACE( "\tInvariant:" ); |
| p->TestInvariant( sal_True ); |
| #endif |
| p = pObjList->Next(); |
| } |
| } |
| */ |
| #endif |
| return; |
| } |
| |
| // Muss von hinten nach vorne zerstoert werden. Das ist die umgekehrte |
| // Reihenfolge der Erzeugung |
| SotFactoryList* pFactoryList = pSotData->pFactoryList; |
| if( pFactoryList ) |
| { |
| SotFactory * pFact = pFactoryList->Last(); |
| while( NULL != (pFact = pFactoryList->Remove()) ) |
| { |
| delete pFact; |
| pFact = pFactoryList->Last(); |
| } |
| delete pFactoryList; |
| pSotData->pFactoryList = NULL; |
| } |
| |
| delete pSotData->pObjectList; |
| pSotData->pObjectList = NULL; |
| if( pSotData->pDataFlavorList ) |
| { |
| |
| for( sal_uLong i = 0, nMax = pSotData->pDataFlavorList->Count(); i < nMax; i++ ) |
| delete (::com::sun::star::datatransfer::DataFlavor*) pSotData->pDataFlavorList->GetObject( i ); |
| delete pSotData->pDataFlavorList; |
| pSotData->pDataFlavorList = NULL; |
| } |
| //delete pSOTDATA(); |
| //SOTDATA() = NULL; |
| } |
| |
| |
| /************** class SotFactory *****************************************/ |
| /************************************************************************* |
| |* SotFactory::SotFactory() |
| |* |
| |* Beschreibung |
| *************************************************************************/ |
| TYPEINIT0(SotFactory); |
| |
| SotFactory::SotFactory( const SvGlobalName & rName, |
| const String & rClassName, |
| CreateInstanceType pCreateFuncP ) |
| : SvGlobalName ( rName ) |
| , nSuperCount ( 0 ) |
| , pSuperClasses ( NULL ) |
| , pCreateFunc ( pCreateFuncP ) |
| , aClassName ( rClassName ) |
| { |
| #ifdef DBG_UTIL |
| SvGlobalName aEmptyName; |
| if( aEmptyName != *this ) |
| { // wegen Sfx-BasicFactories |
| DBG_ASSERT( aEmptyName != *this, "create factory without SvGlobalName" ); |
| if( Find( *this ) ) |
| { |
| /* |
| String aStr( GetClassName() ); |
| aStr += ", UniqueName: "; |
| aStr += GetHexName(); |
| aStr += ", create factories with the same unique name"; |
| DBG_ERROR( aStr ); |
| */ |
| DBG_ERROR( "create factories with the same unique name" ); |
| } |
| } |
| #endif |
| SotData_Impl * pSotData = SOTDATA(); |
| if( !pSotData->pFactoryList ) |
| pSotData->pFactoryList = new SotFactoryList(); |
| // muss nach hinten, wegen Reihenfolge beim zerstoeren |
| pSotData->pFactoryList->Insert( this, LIST_APPEND ); |
| } |
| |
| |
| //========================================================================= |
| SotFactory::~SotFactory() |
| { |
| delete [] pSuperClasses; |
| } |
| |
| |
| /************************************************************************* |
| |* SotFactory:: |
| |* |
| |* Beschreibung Zugriffsmethoden auf SotData_Impl-Daten |
| *************************************************************************/ |
| sal_uInt32 SotFactory::GetSvObjectCount() |
| { |
| return SOTDATA()->nSvObjCount; |
| } |
| |
| |
| const SotFactoryList * SotFactory::GetFactoryList() |
| { |
| return SOTDATA()->pFactoryList; |
| } |
| |
| /************************************************************************* |
| |* SotFactory::Find() |
| |* |
| |* Beschreibung |
| *************************************************************************/ |
| const SotFactory* SotFactory::Find( const SvGlobalName & rFactName ) |
| { |
| SvGlobalName aEmpty; |
| SotData_Impl * pSotData = SOTDATA(); |
| if( rFactName != aEmpty && pSotData->pFactoryList ) |
| { |
| SotFactory * pFact = pSotData->pFactoryList->First(); |
| while( pFact ) |
| { |
| if( *pFact == rFactName ) |
| return pFact; |
| pFact = pSotData->pFactoryList->Next(); |
| } |
| } |
| |
| return 0; |
| } |
| |
| /************************************************************************* |
| |* SotFactory::PutSuperClass() |
| |* |
| |* Beschreibung |
| *************************************************************************/ |
| void SotFactory::PutSuperClass( const SotFactory * pFact ) |
| { |
| nSuperCount++; |
| if( !pSuperClasses ) |
| pSuperClasses = new const SotFactory * [ nSuperCount ]; |
| else |
| { |
| const SotFactory ** pTmp = new const SotFactory * [ nSuperCount ]; |
| memcpy( (void *)pTmp, (void *)pSuperClasses, |
| sizeof( void * ) * (nSuperCount -1) ); |
| delete [] pSuperClasses; |
| pSuperClasses = pTmp; |
| } |
| pSuperClasses[ nSuperCount -1 ] = pFact; |
| } |
| |
| |
| /************************************************************************* |
| |* SotFactory::IncSvObjectCount() |
| |* |
| |* Beschreibung |
| *************************************************************************/ |
| void SotFactory::IncSvObjectCount( SotObject * pObj ) |
| { |
| SotData_Impl * pSotData = SOTDATA(); |
| pSotData->nSvObjCount++; |
| if( !pSotData->pObjectList ) |
| pSotData->pObjectList = new SotObjectList(); |
| if( pObj ) |
| pSotData->pObjectList->Insert( pObj ); |
| } |
| |
| |
| /************************************************************************* |
| |* SotFactory::DecSvObjectCount() |
| |* |
| |* Beschreibung |
| *************************************************************************/ |
| void SotFactory::DecSvObjectCount( SotObject * pObj ) |
| { |
| SotData_Impl * pSotData = SOTDATA(); |
| pSotData->nSvObjCount--; |
| if( pObj ) |
| pSotData->pObjectList->Remove( pObj ); |
| if( !pSotData->nSvObjCount ) |
| { |
| //keine internen und externen Referenzen mehr |
| } |
| } |
| |
| |
| /************************************************************************* |
| |* SotFactory::TestInvariant() |
| |* |
| |* Beschreibung |
| *************************************************************************/ |
| void SotFactory::TestInvariant() |
| { |
| #ifdef TEST_INVARIANT |
| SotData_Impl * pSotData = SOTDATA(); |
| if( pSotData->pObjectList ) |
| { |
| sal_uLong nCount = pSotData->pObjectList->Count(); |
| for( sal_uLong i = 0; i < nCount ; i++ ) |
| { |
| pSotData->pObjectList->GetObject( i )->TestInvariant( sal_False ); |
| } |
| } |
| #endif |
| } |
| |
| /************************************************************************* |
| |* SotFactory::CreateInstance() |
| |* |
| |* Beschreibung |
| *************************************************************************/ |
| void * SotFactory::CreateInstance( SotObject ** ppObj ) const |
| { |
| DBG_ASSERT( pCreateFunc, "SotFactory::CreateInstance: pCreateFunc == 0" ); |
| return pCreateFunc( ppObj ); |
| } |
| |
| //========================================================================= |
| void * SotFactory::CastAndAddRef |
| ( |
| SotObject * pObj /* Das Objekt von dem der Typ gepr"uft wird. */ |
| ) const |
| /* [Beschreibung] |
| |
| Ist eine Optimierung, damit die Ref-Klassen k"urzer implementiert |
| werden k"onnen. pObj wird auf den Typ der Factory gecastet. |
| In c++ (wenn es immer erlaubt w"are) w"urde der void * wie im |
| Beispiel gebildet. |
| Factory der Klasse SvPersist. |
| void * p = (void *)(SvPersist *)pObj; |
| |
| [R"uckgabewert] |
| |
| void *, NULL, pObj war NULL oder das Objekt war nicht vom Typ |
| der Factory. |
| Ansonsten wird pObj zuerst auf den Typ der Factory |
| gecastet und dann auf void *. |
| |
| [Querverweise] |
| |
| <SotObject::CastAndAddRef> |
| */ |
| { |
| return pObj ? pObj->CastAndAddRef( this ) : NULL; |
| } |
| |
| /************************************************************************* |
| |* SotFactory::Is() |
| |* |
| |* Beschreibung |
| *************************************************************************/ |
| sal_Bool SotFactory::Is( const SotFactory * pSuperCl ) const |
| { |
| if( this == pSuperCl ) |
| return sal_True; |
| |
| for( sal_uInt16 i = 0; i < nSuperCount; i++ ) |
| { |
| if( pSuperClasses[ i ]->Is( pSuperCl ) ) |
| return sal_True; |
| } |
| return sal_False; |
| } |
| |
| |
| |
| |