#i111793# make cppuhelper/interfacecontainer strict aliasing safe
This commit is contained in:
@@ -44,6 +44,17 @@
|
|||||||
namespace cppu
|
namespace cppu
|
||||||
{
|
{
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
union element_alias
|
||||||
|
{
|
||||||
|
::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > > *pAsSequence;
|
||||||
|
::com::sun::star::uno::XInterface * pAsInterface;
|
||||||
|
element_alias() : pAsInterface(0) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
//===================================================================
|
//===================================================================
|
||||||
class OInterfaceContainerHelper;
|
class OInterfaceContainerHelper;
|
||||||
/**
|
/**
|
||||||
@@ -95,7 +106,9 @@ public:
|
|||||||
private:
|
private:
|
||||||
OInterfaceContainerHelper & rCont;
|
OInterfaceContainerHelper & rCont;
|
||||||
sal_Bool bIsList;
|
sal_Bool bIsList;
|
||||||
void * pData;
|
|
||||||
|
detail::element_alias aData;
|
||||||
|
|
||||||
sal_Int32 nRemain;
|
sal_Int32 nRemain;
|
||||||
|
|
||||||
OInterfaceIteratorHelper( const OInterfaceIteratorHelper & ) SAL_THROW( () );
|
OInterfaceIteratorHelper( const OInterfaceIteratorHelper & ) SAL_THROW( () );
|
||||||
@@ -222,14 +235,14 @@ public:
|
|||||||
private:
|
private:
|
||||||
friend class OInterfaceIteratorHelper;
|
friend class OInterfaceIteratorHelper;
|
||||||
/**
|
/**
|
||||||
bIsList == TRUE -> pData of type Sequence< XInterfaceSequence >,
|
bIsList == TRUE -> aData.pAsSequence of type Sequence< XInterfaceSequence >,
|
||||||
otherwise pData == of type (XEventListener *)
|
otherwise aData.pAsInterface == of type (XEventListener *)
|
||||||
*/
|
*/
|
||||||
void * pData;
|
detail::element_alias aData;
|
||||||
::osl::Mutex & rMutex;
|
::osl::Mutex & rMutex;
|
||||||
/** TRUE -> used by an iterator. */
|
/** TRUE -> used by an iterator. */
|
||||||
sal_Bool bInUse;
|
sal_Bool bInUse;
|
||||||
/** TRUE -> pData is of type Sequence< XInterfaceSequence >. */
|
/** TRUE -> aData.pAsSequence is of type Sequence< XInterfaceSequence >. */
|
||||||
sal_Bool bIsList;
|
sal_Bool bIsList;
|
||||||
|
|
||||||
OInterfaceContainerHelper( const OInterfaceContainerHelper & ) SAL_THROW( () );
|
OInterfaceContainerHelper( const OInterfaceContainerHelper & ) SAL_THROW( () );
|
||||||
|
@@ -100,15 +100,15 @@ OInterfaceIteratorHelper::OInterfaceIteratorHelper( OInterfaceContainerHelper &
|
|||||||
// worst case, two iterators at the same time
|
// worst case, two iterators at the same time
|
||||||
rCont.copyAndResetInUse();
|
rCont.copyAndResetInUse();
|
||||||
bIsList = rCont_.bIsList;
|
bIsList = rCont_.bIsList;
|
||||||
pData = rCont_.pData;
|
aData = rCont_.aData;
|
||||||
if( bIsList )
|
if( bIsList )
|
||||||
{
|
{
|
||||||
rCont.bInUse = sal_True;
|
rCont.bInUse = sal_True;
|
||||||
nRemain = ((Sequence< Reference< XInterface > >*)pData)->getLength();
|
nRemain = aData.pAsSequence->getLength();
|
||||||
}
|
}
|
||||||
else if( pData )
|
else if( aData.pAsInterface )
|
||||||
{
|
{
|
||||||
((XInterface *)pData)->acquire();
|
aData.pAsInterface->acquire();
|
||||||
nRemain = 1;
|
nRemain = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -121,7 +121,7 @@ OInterfaceIteratorHelper::~OInterfaceIteratorHelper() SAL_THROW( () )
|
|||||||
{
|
{
|
||||||
MutexGuard aGuard( rCont.rMutex );
|
MutexGuard aGuard( rCont.rMutex );
|
||||||
// bResetInUse protect the iterator against recursion
|
// bResetInUse protect the iterator against recursion
|
||||||
bShared = pData == rCont.pData && rCont.bIsList;
|
bShared = aData.pAsSequence == rCont.aData.pAsSequence && rCont.bIsList;
|
||||||
if( bShared )
|
if( bShared )
|
||||||
{
|
{
|
||||||
OSL_ENSURE( rCont.bInUse, "OInterfaceContainerHelper must be in use" );
|
OSL_ENSURE( rCont.bInUse, "OInterfaceContainerHelper must be in use" );
|
||||||
@@ -133,10 +133,10 @@ OInterfaceIteratorHelper::~OInterfaceIteratorHelper() SAL_THROW( () )
|
|||||||
{
|
{
|
||||||
if( bIsList )
|
if( bIsList )
|
||||||
// Sequence owned by the iterator
|
// Sequence owned by the iterator
|
||||||
delete (Sequence< Reference< XInterface > >*)pData;
|
delete aData.pAsSequence;
|
||||||
else if( pData )
|
else if( aData.pAsInterface )
|
||||||
// Interface is acquired by the iterator
|
// Interface is acquired by the iterator
|
||||||
((XInterface*)pData)->release();
|
aData.pAsInterface->release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,9 +147,9 @@ XInterface * OInterfaceIteratorHelper::next() SAL_THROW( () )
|
|||||||
nRemain--;
|
nRemain--;
|
||||||
if( bIsList )
|
if( bIsList )
|
||||||
// typecase to const,so the getArray method is faster
|
// typecase to const,so the getArray method is faster
|
||||||
return ((const Sequence< Reference< XInterface > >*)pData)->getConstArray()[nRemain].get();
|
return aData.pAsSequence->getConstArray()[nRemain].get();
|
||||||
else if( pData )
|
else if( aData.pAsInterface )
|
||||||
return (XInterface*)pData;
|
return aData.pAsInterface;
|
||||||
}
|
}
|
||||||
// exception
|
// exception
|
||||||
return 0;
|
return 0;
|
||||||
@@ -160,15 +160,14 @@ void OInterfaceIteratorHelper::remove() SAL_THROW( () )
|
|||||||
if( bIsList )
|
if( bIsList )
|
||||||
{
|
{
|
||||||
OSL_ASSERT( nRemain >= 0 &&
|
OSL_ASSERT( nRemain >= 0 &&
|
||||||
nRemain < ((const Sequence< Reference< XInterface > >*)pData)->getLength() );
|
nRemain < aData.pAsSequence->getLength() );
|
||||||
XInterface * p =
|
XInterface * p = aData.pAsSequence->getConstArray()[nRemain].get();
|
||||||
((const Sequence< Reference< XInterface > >*)pData)->getConstArray()[nRemain].get();
|
|
||||||
rCont.removeInterface( * reinterpret_cast< const Reference< XInterface > * >( &p ) );
|
rCont.removeInterface( * reinterpret_cast< const Reference< XInterface > * >( &p ) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
OSL_ASSERT( 0 == nRemain );
|
OSL_ASSERT( 0 == nRemain );
|
||||||
rCont.removeInterface( * reinterpret_cast< const Reference< XInterface > * >(&pData));
|
rCont.removeInterface( * reinterpret_cast< const Reference< XInterface > * >(&aData.pAsInterface));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,8 +177,7 @@ void OInterfaceIteratorHelper::remove() SAL_THROW( () )
|
|||||||
|
|
||||||
|
|
||||||
OInterfaceContainerHelper::OInterfaceContainerHelper( Mutex & rMutex_ ) SAL_THROW( () )
|
OInterfaceContainerHelper::OInterfaceContainerHelper( Mutex & rMutex_ ) SAL_THROW( () )
|
||||||
: pData( 0 )
|
: rMutex( rMutex_ )
|
||||||
, rMutex( rMutex_ )
|
|
||||||
, bInUse( sal_False )
|
, bInUse( sal_False )
|
||||||
, bIsList( sal_False )
|
, bIsList( sal_False )
|
||||||
{
|
{
|
||||||
@@ -189,17 +187,17 @@ OInterfaceContainerHelper::~OInterfaceContainerHelper() SAL_THROW( () )
|
|||||||
{
|
{
|
||||||
OSL_ENSURE( !bInUse, "~OInterfaceContainerHelper but is in use" );
|
OSL_ENSURE( !bInUse, "~OInterfaceContainerHelper but is in use" );
|
||||||
if( bIsList )
|
if( bIsList )
|
||||||
delete (Sequence< Reference< XInterface > >*)pData;
|
delete aData.pAsSequence;
|
||||||
else if( pData )
|
else if( aData.pAsInterface )
|
||||||
((XInterface*)pData)->release();
|
aData.pAsInterface->release();
|
||||||
}
|
}
|
||||||
|
|
||||||
sal_Int32 OInterfaceContainerHelper::getLength() const SAL_THROW( () )
|
sal_Int32 OInterfaceContainerHelper::getLength() const SAL_THROW( () )
|
||||||
{
|
{
|
||||||
MutexGuard aGuard( rMutex );
|
MutexGuard aGuard( rMutex );
|
||||||
if( bIsList )
|
if( bIsList )
|
||||||
return ((Sequence< Reference< XInterface > >*)pData)->getLength();
|
return aData.pAsSequence->getLength();
|
||||||
else if( pData )
|
else if( aData.pAsInterface )
|
||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -208,10 +206,10 @@ Sequence< Reference<XInterface> > OInterfaceContainerHelper::getElements() const
|
|||||||
{
|
{
|
||||||
MutexGuard aGuard( rMutex );
|
MutexGuard aGuard( rMutex );
|
||||||
if( bIsList )
|
if( bIsList )
|
||||||
return *(Sequence< Reference< XInterface > >*)pData;
|
return *aData.pAsSequence;
|
||||||
else if( pData )
|
else if( aData.pAsInterface )
|
||||||
{
|
{
|
||||||
Reference<XInterface> x( (XInterface *)pData );
|
Reference<XInterface> x( aData.pAsInterface );
|
||||||
return Sequence< Reference< XInterface > >( &x, 1 );
|
return Sequence< Reference< XInterface > >( &x, 1 );
|
||||||
}
|
}
|
||||||
return Sequence< Reference< XInterface > >();
|
return Sequence< Reference< XInterface > >();
|
||||||
@@ -225,9 +223,9 @@ void OInterfaceContainerHelper::copyAndResetInUse() SAL_THROW( () )
|
|||||||
// this should be the worst case. If a iterator is active
|
// this should be the worst case. If a iterator is active
|
||||||
// and a new Listener is added.
|
// and a new Listener is added.
|
||||||
if( bIsList )
|
if( bIsList )
|
||||||
pData = new Sequence< Reference< XInterface > >( *(Sequence< Reference< XInterface > >*)pData );
|
aData.pAsSequence = new Sequence< Reference< XInterface > >( *aData.pAsSequence );
|
||||||
else if( pData )
|
else if( aData.pAsInterface )
|
||||||
((XInterface*)pData)->acquire();
|
aData.pAsInterface->acquire();
|
||||||
|
|
||||||
bInUse = sal_False;
|
bInUse = sal_False;
|
||||||
}
|
}
|
||||||
@@ -242,25 +240,25 @@ sal_Int32 OInterfaceContainerHelper::addInterface( const Reference<XInterface> &
|
|||||||
|
|
||||||
if( bIsList )
|
if( bIsList )
|
||||||
{
|
{
|
||||||
sal_Int32 nLen = ((Sequence< Reference< XInterface > >*)pData)->getLength();
|
sal_Int32 nLen = aData.pAsSequence->getLength();
|
||||||
realloc( *(Sequence< Reference< XInterface > >*)pData, nLen +1 );
|
realloc( *aData.pAsSequence, nLen +1 );
|
||||||
((Sequence< Reference< XInterface > >*)pData)->getArray()[ nLen ] = rListener;
|
aData.pAsSequence->getArray()[ nLen ] = rListener;
|
||||||
return nLen +1;
|
return nLen +1;
|
||||||
}
|
}
|
||||||
else if( pData )
|
else if( aData.pAsInterface )
|
||||||
{
|
{
|
||||||
Sequence< Reference< XInterface > > * pSeq = new Sequence< Reference< XInterface > >( 2 );
|
Sequence< Reference< XInterface > > * pSeq = new Sequence< Reference< XInterface > >( 2 );
|
||||||
Reference<XInterface> * pArray = pSeq->getArray();
|
Reference<XInterface> * pArray = pSeq->getArray();
|
||||||
pArray[0] = (XInterface *)pData;
|
pArray[0] = aData.pAsInterface;
|
||||||
pArray[1] = rListener;
|
pArray[1] = rListener;
|
||||||
((XInterface *)pData)->release();
|
aData.pAsInterface->release();
|
||||||
pData = pSeq;
|
aData.pAsSequence = pSeq;
|
||||||
bIsList = sal_True;
|
bIsList = sal_True;
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pData = rListener.get();
|
aData.pAsInterface = rListener.get();
|
||||||
if( rListener.is() )
|
if( rListener.is() )
|
||||||
rListener->acquire();
|
rListener->acquire();
|
||||||
return 1;
|
return 1;
|
||||||
@@ -276,8 +274,8 @@ sal_Int32 OInterfaceContainerHelper::removeInterface( const Reference<XInterface
|
|||||||
|
|
||||||
if( bIsList )
|
if( bIsList )
|
||||||
{
|
{
|
||||||
const Reference<XInterface> * pL = ((const Sequence< Reference< XInterface > >*)pData)->getConstArray();
|
const Reference<XInterface> * pL = aData.pAsSequence->getConstArray();
|
||||||
sal_Int32 nLen = ((Sequence< Reference< XInterface > >*)pData)->getLength();
|
sal_Int32 nLen = aData.pAsSequence->getLength();
|
||||||
sal_Int32 i;
|
sal_Int32 i;
|
||||||
for( i = 0; i < nLen; i++ )
|
for( i = 0; i < nLen; i++ )
|
||||||
{
|
{
|
||||||
@@ -285,7 +283,7 @@ sal_Int32 OInterfaceContainerHelper::removeInterface( const Reference<XInterface
|
|||||||
// more faster.
|
// more faster.
|
||||||
if( pL[i].get() == rListener.get() )
|
if( pL[i].get() == rListener.get() )
|
||||||
{
|
{
|
||||||
sequenceRemoveElementAt( *(Sequence< Reference< XInterface > >*)pData, i );
|
sequenceRemoveElementAt( *aData.pAsSequence, i );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -297,30 +295,30 @@ sal_Int32 OInterfaceContainerHelper::removeInterface( const Reference<XInterface
|
|||||||
{
|
{
|
||||||
if( pL[i] == rListener )
|
if( pL[i] == rListener )
|
||||||
{
|
{
|
||||||
sequenceRemoveElementAt(*(Sequence< Reference< XInterface > >*)pData, i );
|
sequenceRemoveElementAt(*aData.pAsSequence, i );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ((Sequence< Reference< XInterface > >*)pData)->getLength() == 1 )
|
if( aData.pAsSequence->getLength() == 1 )
|
||||||
{
|
{
|
||||||
XInterface * p = ((const Sequence< Reference< XInterface > >*)pData)->getConstArray()[0].get();
|
XInterface * p = aData.pAsSequence->getConstArray()[0].get();
|
||||||
p->acquire();
|
p->acquire();
|
||||||
delete (Sequence< Reference< XInterface > >*)pData;
|
delete aData.pAsSequence;
|
||||||
pData = p;
|
aData.pAsInterface = p;
|
||||||
bIsList = sal_False;
|
bIsList = sal_False;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return ((Sequence< Reference< XInterface > >*)pData)->getLength();
|
return aData.pAsSequence->getLength();
|
||||||
}
|
}
|
||||||
else if( pData && Reference<XInterface>( (XInterface*)pData ) == rListener )
|
else if( aData.pAsInterface && Reference<XInterface>( aData.pAsInterface ) == rListener )
|
||||||
{
|
{
|
||||||
((XInterface *)pData)->release();
|
aData.pAsInterface->release();
|
||||||
pData = 0;
|
aData.pAsInterface = 0;
|
||||||
}
|
}
|
||||||
return pData ? 1 : 0;
|
return aData.pAsInterface ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OInterfaceContainerHelper::disposeAndClear( const EventObject & rEvt ) SAL_THROW( () )
|
void OInterfaceContainerHelper::disposeAndClear( const EventObject & rEvt ) SAL_THROW( () )
|
||||||
@@ -329,10 +327,10 @@ void OInterfaceContainerHelper::disposeAndClear( const EventObject & rEvt ) SAL_
|
|||||||
OInterfaceIteratorHelper aIt( *this );
|
OInterfaceIteratorHelper aIt( *this );
|
||||||
// Release container, in case new entries come while disposing
|
// Release container, in case new entries come while disposing
|
||||||
OSL_ENSURE( !bIsList || bInUse, "OInterfaceContainerHelper not in use" );
|
OSL_ENSURE( !bIsList || bInUse, "OInterfaceContainerHelper not in use" );
|
||||||
if( !bIsList && pData )
|
if( !bIsList && aData.pAsInterface )
|
||||||
((XInterface *)pData)->release();
|
aData.pAsInterface->release();
|
||||||
// set the member to null, use the iterator to delete the values
|
// set the member to null, use the iterator to delete the values
|
||||||
pData = NULL;
|
aData.pAsInterface = NULL;
|
||||||
bIsList = sal_False;
|
bIsList = sal_False;
|
||||||
bInUse = sal_False;
|
bInUse = sal_False;
|
||||||
aGuard.clear();
|
aGuard.clear();
|
||||||
@@ -359,10 +357,10 @@ void OInterfaceContainerHelper::clear() SAL_THROW( () )
|
|||||||
OInterfaceIteratorHelper aIt( *this );
|
OInterfaceIteratorHelper aIt( *this );
|
||||||
// Release container, in case new entries come while disposing
|
// Release container, in case new entries come while disposing
|
||||||
OSL_ENSURE( !bIsList || bInUse, "OInterfaceContainerHelper not in use" );
|
OSL_ENSURE( !bIsList || bInUse, "OInterfaceContainerHelper not in use" );
|
||||||
if( !bIsList && pData )
|
if( !bIsList && aData.pAsInterface )
|
||||||
((XInterface *)pData)->release();
|
aData.pAsInterface->release();
|
||||||
// set the member to null, use the iterator to delete the values
|
// set the member to null, use the iterator to delete the values
|
||||||
pData = 0;
|
aData.pAsInterface = 0;
|
||||||
bIsList = sal_False;
|
bIsList = sal_False;
|
||||||
bInUse = sal_False;
|
bInUse = sal_False;
|
||||||
// release mutex before aIt destructor call
|
// release mutex before aIt destructor call
|
||||||
|
Reference in New Issue
Block a user