1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 #ifndef _CPPUHELPER_INTERFACECONTAINER_HXX_
24 #define _CPPUHELPER_INTERFACECONTAINER_HXX_
25 
26 #include <cppuhelper/interfacecontainer.h>
27 
28 
29 namespace cppu
30 {
31 
32 template< class key , class hashImpl , class equalImpl >
OMultiTypeInterfaceContainerHelperVar(::osl::Mutex & rMutex_)33 inline OMultiTypeInterfaceContainerHelperVar< key , hashImpl , equalImpl >::OMultiTypeInterfaceContainerHelperVar( ::osl::Mutex & rMutex_ )
34 	SAL_THROW( () )
35 	: rMutex( rMutex_ )
36 {
37 	m_pMap = new InterfaceMap;
38 }
39 
40 //===================================================================
41 template< class key , class hashImpl , class equalImpl >
~OMultiTypeInterfaceContainerHelperVar()42 inline OMultiTypeInterfaceContainerHelperVar< key , hashImpl , equalImpl >::~OMultiTypeInterfaceContainerHelperVar()
43 	SAL_THROW( () )
44 {
45 	typename InterfaceMap::iterator iter = m_pMap->begin();
46 	typename InterfaceMap::iterator end = m_pMap->end();
47 
48 	while( iter != end )
49 	{
50 		delete (OInterfaceContainerHelper*)(*iter).second;
51 		(*iter).second = 0;
52 		++iter;
53 	}
54 	delete m_pMap;
55 }
56 
57 //===================================================================
58 template< class key , class hashImpl , class equalImpl >
getContainedTypes() const59 inline ::com::sun::star::uno::Sequence< key > OMultiTypeInterfaceContainerHelperVar< key , hashImpl , equalImpl >::getContainedTypes() const
60 	SAL_THROW( () )
61 {
62 	::osl::MutexGuard aGuard( rMutex );
63 	typename InterfaceMap::size_type nSize = m_pMap->size();
64 	if( nSize != 0 )
65 	{
66 		::com::sun::star::uno::Sequence< key > aInterfaceTypes( nSize );
67 		key * pArray = aInterfaceTypes.getArray();
68 
69 		typename InterfaceMap::iterator iter = m_pMap->begin();
70 		typename InterfaceMap::iterator end = m_pMap->end();
71 
72 		sal_uInt32 i = 0;
73 		while( iter != end )
74 		{
75 			// are interfaces added to this container?
76 			if( ((OInterfaceContainerHelper*)(*iter).second)->getLength() )
77 				// yes, put the type in the array
78 				pArray[i++] = (*iter).first;
79 			iter++;
80 		}
81 		if( i != nSize ) {
82 			// may be empty container, reduce the sequence to the right size
83 			aInterfaceTypes = ::com::sun::star::uno::Sequence<key>( pArray, i );
84 		}
85 		return aInterfaceTypes;
86 	}
87 	return ::com::sun::star::uno::Sequence<key>();
88 }
89 
90 //===================================================================
91 template< class key , class hashImpl , class equalImpl >
getContainer(const key & rKey) const92 OInterfaceContainerHelper * OMultiTypeInterfaceContainerHelperVar< key , hashImpl , equalImpl >::getContainer(
93 	const key & rKey ) const SAL_THROW( () )
94 {
95 	::osl::MutexGuard aGuard( rMutex );
96 
97  	typename InterfaceMap::iterator iter = find( rKey );
98 	if( iter != m_pMap->end() )
99 			return (OInterfaceContainerHelper*) (*iter).second;
100 	return 0;
101 }
102 
103 //===================================================================
104 template< class key , class hashImpl , class equalImpl >
addInterface(const key & rKey,const::com::sun::star::uno::Reference<::com::sun::star::uno::XInterface> & rListener)105 sal_Int32 OMultiTypeInterfaceContainerHelperVar< key , hashImpl , equalImpl >::addInterface(
106 	const key & rKey,
107 	const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > & rListener )
108 	SAL_THROW( () )
109 {
110 	::osl::MutexGuard aGuard( rMutex );
111 	typename InterfaceMap::iterator iter = find( rKey );
112 	if( iter == m_pMap->end() )
113 	{
114 		OInterfaceContainerHelper * pLC = new OInterfaceContainerHelper( rMutex );
115         m_pMap->push_back(std::pair<key, void*>(rKey, pLC));
116 		return pLC->addInterface( rListener );
117 	}
118 	else
119 		return ((OInterfaceContainerHelper*)(*iter).second)->addInterface( rListener );
120 }
121 
122 //===================================================================
123 template< class key , class hashImpl , class equalImpl >
removeInterface(const key & rKey,const::com::sun::star::uno::Reference<::com::sun::star::uno::XInterface> & rListener)124 inline sal_Int32 OMultiTypeInterfaceContainerHelperVar< key , hashImpl , equalImpl >::removeInterface(
125 	const key & rKey,
126 	const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > & rListener )
127 	SAL_THROW( () )
128 {
129 	::osl::MutexGuard aGuard( rMutex );
130 
131 	// search container with id nUik
132 	typename InterfaceMap::iterator iter = find( rKey );
133     // container found?
134 	if( iter != m_pMap->end() )
135         return ((OInterfaceContainerHelper*)(*iter).second)->removeInterface( rListener );
136 
137 	// no container with this id. Always return 0
138 	return 0;
139 }
140 
141 //===================================================================
142 template< class key , class hashImpl , class equalImpl >
disposeAndClear(const::com::sun::star::lang::EventObject & rEvt)143 void OMultiTypeInterfaceContainerHelperVar< key , hashImpl , equalImpl >::disposeAndClear(
144 	const ::com::sun::star::lang::EventObject & rEvt )
145 	SAL_THROW( () )
146 {
147 	typename InterfaceMap::size_type nSize = 0;
148 	OInterfaceContainerHelper ** ppListenerContainers = NULL;
149 	{
150 		::osl::MutexGuard aGuard( rMutex );
151         nSize = m_pMap->size();
152 		if( nSize )
153 		{
154 			typedef OInterfaceContainerHelper* ppp;
155 			ppListenerContainers = new ppp[nSize];
156 			//ppListenerContainers = new (ListenerContainer*)[nSize];
157 
158 			typename InterfaceMap::iterator iter = m_pMap->begin();
159 			typename InterfaceMap::iterator end = m_pMap->end();
160 
161 			typename InterfaceMap::size_type i = 0;
162 			while( iter != end )
163 			{
164 				ppListenerContainers[i++] = (OInterfaceContainerHelper*)(*iter).second;
165 				++iter;
166 			}
167 		}
168 	}
169 
170 	// create a copy, because do not fire event in a guarded section
171 	for( typename InterfaceMap::size_type i = 0; i < nSize; i++ )
172 	{
173 		if( ppListenerContainers[i] )
174 			ppListenerContainers[i]->disposeAndClear( rEvt );
175 	}
176 
177 	delete [] ppListenerContainers;
178 }
179 
180 //===================================================================
181 template< class key , class hashImpl , class equalImpl >
clear()182 void OMultiTypeInterfaceContainerHelperVar< key , hashImpl , equalImpl >::clear() SAL_THROW( () )
183 {
184 	::osl::MutexGuard aGuard( rMutex );
185 	typename InterfaceMap::iterator iter = m_pMap->begin();
186 	typename InterfaceMap::iterator end = m_pMap->end();
187 
188 	while( iter != end )
189 	{
190 		((OInterfaceContainerHelper*)(*iter).second)->clear();
191 		++iter;
192 	}
193 }
194 
195 
196 }
197 
198 #endif
199 
200