Coverage Report

Created: 2026-03-31 11:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/cppuhelper/source/interfacecontainer.cxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
 *
9
 * This file incorporates work covered by the following license notice:
10
 *
11
 *   Licensed to the Apache Software Foundation (ASF) under one or more
12
 *   contributor license agreements. See the NOTICE file distributed
13
 *   with this work for additional information regarding copyright
14
 *   ownership. The ASF licenses this file to you under the Apache
15
 *   License, Version 2.0 (the "License"); you may not use this file
16
 *   except in compliance with the License. You may obtain a copy of
17
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18
 */
19
20
21
#include <cppuhelper/interfacecontainer.hxx>
22
#include <cppuhelper/propshlp.hxx>
23
#include <comphelper/sequence.hxx>
24
25
#include <o3tl/safeint.hxx>
26
#include <osl/diagnose.h>
27
#include <osl/mutex.hxx>
28
#include <sal/log.hxx>
29
30
#include <memory>
31
32
#include <com/sun/star/lang/XEventListener.hpp>
33
34
35
using namespace osl;
36
using namespace com::sun::star::uno;
37
using namespace com::sun::star::lang;
38
39
namespace cppu
40
{
41
42
OInterfaceIteratorHelper::OInterfaceIteratorHelper( OInterfaceContainerHelper & rCont_ )
43
31.4k
    : rCont( rCont_ )
44
31.4k
{
45
31.4k
    MutexGuard aGuard( rCont.rMutex );
46
31.4k
    if( rCont.bInUse )
47
        // worst case, two iterators at the same time
48
0
        rCont.copyAndResetInUse();
49
31.4k
    bIsList = rCont_.bIsList;
50
31.4k
    aData = rCont_.aData;
51
31.4k
    if( bIsList )
52
10.6k
    {
53
10.6k
        rCont.bInUse = true;
54
10.6k
        nRemain = aData.pAsVector->size();
55
10.6k
    }
56
20.8k
    else if( aData.pAsInterface )
57
0
    {
58
0
        aData.pAsInterface->acquire();
59
0
        nRemain = 1;
60
0
    }
61
20.8k
    else
62
20.8k
        nRemain = 0;
63
31.4k
}
64
65
OInterfaceIteratorHelper::~OInterfaceIteratorHelper()
66
31.4k
{
67
31.4k
    bool bShared;
68
31.4k
    {
69
31.4k
    MutexGuard aGuard( rCont.rMutex );
70
    // bResetInUse protect the iterator against recursion
71
31.4k
    bShared = aData.pAsVector == rCont.aData.pAsVector && rCont.bIsList;
72
31.4k
    if( bShared )
73
0
    {
74
0
        OSL_ENSURE( rCont.bInUse, "OInterfaceContainerHelper must be in use" );
75
0
        rCont.bInUse = false;
76
0
    }
77
31.4k
    }
78
79
31.4k
    if( !bShared )
80
31.4k
    {
81
31.4k
        if( bIsList )
82
            // Sequence owned by the iterator
83
10.6k
            delete aData.pAsVector;
84
20.8k
        else if( aData.pAsInterface )
85
            // Interface is acquired by the iterator
86
0
            aData.pAsInterface->release();
87
31.4k
    }
88
31.4k
}
89
90
XInterface * OInterfaceIteratorHelper::next()
91
21.3k
{
92
21.3k
    if( nRemain )
93
21.3k
    {
94
21.3k
        nRemain--;
95
21.3k
        if( bIsList )
96
            // typecase to const,so the getArray method is faster
97
21.3k
            return (*aData.pAsVector)[nRemain].get();
98
0
        if( aData.pAsInterface )
99
0
            return aData.pAsInterface;
100
0
    }
101
    // exception
102
0
    return nullptr;
103
21.3k
}
104
105
void OInterfaceIteratorHelper::remove()
106
0
{
107
0
    if( bIsList )
108
0
    {
109
0
        OSL_ASSERT( nRemain >= 0 &&
110
0
                    o3tl::make_unsigned(nRemain) < aData.pAsVector->size() );
111
0
        XInterface * p = (*aData.pAsVector)[nRemain].get();
112
0
        rCont.removeInterface( * reinterpret_cast< const Reference< XInterface > * >( &p ) );
113
0
    }
114
0
    else
115
0
    {
116
0
        OSL_ASSERT( 0 == nRemain );
117
0
        rCont.removeInterface( * reinterpret_cast< const Reference< XInterface > * >(&aData.pAsInterface));
118
0
    }
119
0
}
120
121
OInterfaceContainerHelper::OInterfaceContainerHelper( Mutex & rMutex_ )
122
31.6k
    : rMutex( rMutex_ )
123
31.6k
    , bInUse( false )
124
31.6k
    , bIsList( false )
125
31.6k
{
126
31.6k
}
127
128
OInterfaceContainerHelper::~OInterfaceContainerHelper()
129
31.4k
{
130
31.4k
    OSL_ENSURE( !bInUse, "~OInterfaceContainerHelper but is in use" );
131
31.4k
    if( bIsList )
132
0
        delete aData.pAsVector;
133
31.4k
    else if( aData.pAsInterface )
134
0
        aData.pAsInterface->release();
135
31.4k
}
136
137
sal_Int32 OInterfaceContainerHelper::getLength() const
138
0
{
139
0
    MutexGuard aGuard( rMutex );
140
0
    if( bIsList )
141
0
        return aData.pAsVector->size();
142
0
    if( aData.pAsInterface )
143
0
        return 1;
144
0
    return 0;
145
0
}
146
147
Sequence< Reference<XInterface> > OInterfaceContainerHelper::getElements() const
148
0
{
149
0
    MutexGuard aGuard( rMutex );
150
0
    if( bIsList )
151
0
        return comphelper::containerToSequence(*aData.pAsVector);
152
0
    if( aData.pAsInterface )
153
0
    {
154
0
        Reference<XInterface> x( aData.pAsInterface );
155
0
        return Sequence< Reference< XInterface > >( &x, 1 );
156
0
    }
157
0
    return Sequence< Reference< XInterface > >();
158
0
}
159
160
void OInterfaceContainerHelper::copyAndResetInUse()
161
0
{
162
0
    OSL_ENSURE( bInUse, "OInterfaceContainerHelper not in use" );
163
0
    if( bInUse )
164
0
    {
165
        // this should be the worst case. If an iterator is active
166
        // and a new Listener is added.
167
0
        if( bIsList )
168
0
            aData.pAsVector= new std::vector< Reference< XInterface > >( *aData.pAsVector );
169
0
        else if( aData.pAsInterface )
170
0
            aData.pAsInterface->acquire();
171
172
0
        bInUse = false;
173
0
    }
174
0
}
175
176
sal_Int32 OInterfaceContainerHelper::addInterface( const Reference<XInterface> & rListener )
177
52.9k
{
178
52.9k
    SAL_WARN_IF( !rListener.is(), "cppuhelper", "rListener is empty" );
179
52.9k
    MutexGuard aGuard( rMutex );
180
52.9k
    if( bInUse )
181
0
        copyAndResetInUse();
182
183
52.9k
    if( bIsList )
184
10.6k
    {
185
10.6k
        aData.pAsVector->push_back(rListener);
186
10.6k
        return aData.pAsVector->size();
187
10.6k
    }
188
42.2k
    if( aData.pAsInterface )
189
10.6k
    {
190
10.6k
        Reference<XInterface> tmp(aData.pAsInterface);
191
10.6k
        aData.pAsInterface->release();
192
10.6k
        aData.pAsVector = new std::vector<Reference<XInterface>>(2);
193
10.6k
        (*aData.pAsVector)[0] = std::move(tmp);
194
10.6k
        (*aData.pAsVector)[1] = rListener;
195
10.6k
        bIsList = true;
196
10.6k
        return 2;
197
10.6k
    }
198
31.6k
    aData.pAsInterface = rListener.get();
199
31.6k
    if( rListener.is() )
200
31.6k
        rListener->acquire();
201
31.6k
    return 1;
202
42.2k
}
203
204
sal_Int32 OInterfaceContainerHelper::removeInterface( const Reference<XInterface> & rListener )
205
31.4k
{
206
31.4k
    SAL_WARN_IF( !rListener.is(), "cppuhelper", "rListener is empty" );
207
31.4k
    MutexGuard aGuard( rMutex );
208
31.4k
    if( bInUse )
209
0
        copyAndResetInUse();
210
211
31.4k
    if( bIsList )
212
10.6k
    {
213
        // It is not valid to compare the pointer directly, but it's faster.
214
10.6k
        auto findIt = std::find_if(aData.pAsVector->begin(), aData.pAsVector->end(),
215
10.6k
                    [&](const Reference<XInterface>& r)
216
10.6k
                    { return r.get() == rListener.get(); });
217
10.6k
        if (findIt != aData.pAsVector->end())
218
10.6k
        {
219
10.6k
            aData.pAsVector->erase(findIt);
220
10.6k
        }
221
0
        else
222
0
        {
223
            // interface not found, use the correct compare method
224
0
            for( auto it = aData.pAsVector->begin(); it != aData.pAsVector->end(); ++it )
225
0
            {
226
0
                if( *it == rListener )
227
0
                {
228
0
                    aData.pAsVector->erase(it);
229
0
                    break;
230
0
                }
231
0
            }
232
0
        }
233
234
10.6k
        if( aData.pAsVector->size() == 1 )
235
0
        {
236
0
            XInterface * p = (*aData.pAsVector)[0].get();
237
0
            p->acquire();
238
0
            delete aData.pAsVector;
239
0
            aData.pAsInterface = p;
240
0
            bIsList = false;
241
0
            return 1;
242
0
        }
243
10.6k
        return aData.pAsVector->size();
244
10.6k
    }
245
20.8k
    if( aData.pAsInterface && Reference<XInterface>( aData.pAsInterface ) == rListener )
246
20.8k
    {
247
20.8k
        aData.pAsInterface->release();
248
20.8k
        aData.pAsInterface = nullptr;
249
20.8k
    }
250
20.8k
    return aData.pAsInterface ? 1 : 0;
251
31.4k
}
252
253
void OInterfaceContainerHelper::disposeAndClear( const EventObject & rEvt )
254
31.4k
{
255
31.4k
    ClearableMutexGuard aGuard( rMutex );
256
31.4k
    OInterfaceIteratorHelper aIt( *this );
257
    // Release container, in case new entries come while disposing
258
31.4k
    OSL_ENSURE( !bIsList || bInUse, "OInterfaceContainerHelper not in use" );
259
31.4k
    if( !bIsList && aData.pAsInterface )
260
0
        aData.pAsInterface->release();
261
    // set the member to null, use the iterator to delete the values
262
31.4k
    aData.pAsInterface = nullptr;
263
31.4k
    bIsList = false;
264
31.4k
    bInUse = false;
265
31.4k
    aGuard.clear();
266
52.7k
    while( aIt.hasMoreElements() )
267
21.3k
    {
268
21.3k
        try
269
21.3k
        {
270
21.3k
            Reference<XEventListener > xLst( aIt.next(), UNO_QUERY );
271
21.3k
            if( xLst.is() )
272
21.3k
                xLst->disposing( rEvt );
273
21.3k
        }
274
21.3k
        catch ( RuntimeException & )
275
21.3k
        {
276
            // be robust, if e.g. a remote bridge has disposed already.
277
            // there is no way to delegate the error to the caller :o(.
278
0
        }
279
21.3k
    }
280
31.4k
}
281
282
283
void OInterfaceContainerHelper::clear()
284
0
{
285
0
    MutexGuard aGuard( rMutex );
286
    // Release container, in case new entries come while disposing
287
0
    OSL_ENSURE( !bIsList || bInUse, "OInterfaceContainerHelper not in use" );
288
0
    if (bInUse)
289
0
        copyAndResetInUse();
290
0
    if (bIsList)
291
0
        delete aData.pAsVector;
292
0
    else if (aData.pAsInterface)
293
0
        aData.pAsInterface->release();
294
0
    aData.pAsInterface = nullptr;
295
0
    bIsList = false;
296
0
}
297
298
// specialized class for type
299
300
typedef std::vector< std::pair < Type , void* > > t_type2ptr;
301
302
OMultiTypeInterfaceContainerHelper::OMultiTypeInterfaceContainerHelper( Mutex & rMutex_ )
303
3.78M
    : rMutex( rMutex_ )
304
3.78M
{
305
3.78M
    m_pMap = new t_type2ptr;
306
3.78M
}
307
308
OMultiTypeInterfaceContainerHelper::~OMultiTypeInterfaceContainerHelper()
309
3.77M
{
310
3.77M
    t_type2ptr * pMap = static_cast<t_type2ptr *>(m_pMap);
311
312
3.77M
    for (auto& rItem : *pMap)
313
31.4k
    {
314
31.4k
        delete static_cast<OInterfaceContainerHelper*>(rItem.second);
315
31.4k
        rItem.second = nullptr;
316
31.4k
    }
317
3.77M
    delete pMap;
318
3.77M
}
319
320
Sequence< Type > OMultiTypeInterfaceContainerHelper::getContainedTypes() const
321
0
{
322
0
    t_type2ptr * pMap = static_cast<t_type2ptr *>(m_pMap);
323
0
    t_type2ptr::size_type nSize;
324
325
0
    ::osl::MutexGuard aGuard( rMutex );
326
0
    nSize = pMap->size();
327
0
    if( nSize )
328
0
    {
329
0
        css::uno::Sequence< Type > aInterfaceTypes( nSize );
330
0
        Type * pArray = aInterfaceTypes.getArray();
331
332
0
        sal_Int32 i = 0;
333
0
        for (const auto& rItem : *pMap)
334
0
        {
335
            // are interfaces added to this container?
336
0
            if( static_cast<OInterfaceContainerHelper*>(rItem.second)->getLength() )
337
                // yes, put the type in the array
338
0
                pArray[i++] = rItem.first;
339
0
        }
340
0
        if( static_cast<t_type2ptr::size_type>(i) != nSize ) {
341
            // may be empty container, reduce the sequence to the right size
342
0
            aInterfaceTypes = css::uno::Sequence< Type >( pArray, i );
343
0
        }
344
0
        return aInterfaceTypes;
345
0
    }
346
0
    return css::uno::Sequence< Type >();
347
0
}
348
349
static t_type2ptr::iterator findType(t_type2ptr *pMap, const Type & rKey )
350
988k
{
351
988k
    return std::find_if(pMap->begin(), pMap->end(),
352
988k
        [&rKey](const t_type2ptr::value_type& rItem) { return rItem.first == rKey; });
353
988k
}
354
355
OInterfaceContainerHelper * OMultiTypeInterfaceContainerHelper::getContainer( const Type & rKey ) const
356
904k
{
357
904k
    ::osl::MutexGuard aGuard( rMutex );
358
359
904k
    t_type2ptr * pMap = static_cast<t_type2ptr *>(m_pMap);
360
904k
    t_type2ptr::iterator iter = findType( pMap, rKey );
361
904k
    if( iter != pMap->end() )
362
0
            return static_cast<OInterfaceContainerHelper*>((*iter).second);
363
904k
    return nullptr;
364
904k
}
365
366
sal_Int32 OMultiTypeInterfaceContainerHelper::addInterface(
367
    const Type & rKey, const Reference< XInterface > & rListener )
368
52.9k
{
369
52.9k
    ::osl::MutexGuard aGuard( rMutex );
370
52.9k
    t_type2ptr * pMap = static_cast<t_type2ptr *>(m_pMap);
371
52.9k
    t_type2ptr::iterator iter = findType( pMap, rKey );
372
52.9k
    if( iter == pMap->end() )
373
31.6k
    {
374
31.6k
        OInterfaceContainerHelper * pLC = new OInterfaceContainerHelper( rMutex );
375
31.6k
        pMap->push_back(std::pair<Type, void*>(rKey, pLC));
376
31.6k
        return pLC->addInterface( rListener );
377
31.6k
    }
378
21.3k
    return static_cast<OInterfaceContainerHelper*>((*iter).second)->addInterface( rListener );
379
52.9k
}
380
381
sal_Int32 OMultiTypeInterfaceContainerHelper::removeInterface(
382
    const Type & rKey, const Reference< XInterface > & rListener )
383
31.4k
{
384
31.4k
    ::osl::MutexGuard aGuard( rMutex );
385
386
    // search container with id nUik
387
31.4k
    t_type2ptr * pMap = static_cast<t_type2ptr *>(m_pMap);
388
31.4k
    t_type2ptr::iterator iter = findType( pMap, rKey );
389
        // container found?
390
31.4k
    if( iter != pMap->end() )
391
31.4k
        return static_cast<OInterfaceContainerHelper*>((*iter).second)->removeInterface( rListener );
392
393
    // no container with this id. Always return 0
394
0
    return 0;
395
31.4k
}
396
397
void OMultiTypeInterfaceContainerHelper::disposeAndClear( const EventObject & rEvt )
398
3.74M
{
399
3.74M
    t_type2ptr::size_type nSize = 0;
400
3.74M
    std::unique_ptr<OInterfaceContainerHelper *[]> ppListenerContainers;
401
3.74M
    {
402
3.74M
        ::osl::MutexGuard aGuard( rMutex );
403
3.74M
        t_type2ptr * pMap = static_cast<t_type2ptr *>(m_pMap);
404
3.74M
        nSize = pMap->size();
405
3.74M
        if( nSize )
406
31.4k
        {
407
31.4k
            typedef OInterfaceContainerHelper* ppp;
408
31.4k
            ppListenerContainers.reset(new ppp[nSize]);
409
            //ppListenerContainers = new (ListenerContainer*)[nSize];
410
411
31.4k
            t_type2ptr::size_type i = 0;
412
31.4k
            for (const auto& rItem : *pMap)
413
31.4k
            {
414
31.4k
                ppListenerContainers[i++] = static_cast<OInterfaceContainerHelper*>(rItem.second);
415
31.4k
            }
416
31.4k
        }
417
3.74M
    }
418
419
    // create a copy, because do not fire event in a guarded section
420
3.74M
    for( t_type2ptr::size_type i = 0;
421
3.77M
            i < nSize; i++ )
422
31.4k
    {
423
31.4k
        if( ppListenerContainers[i] )
424
31.4k
            ppListenerContainers[i]->disposeAndClear( rEvt );
425
31.4k
    }
426
3.74M
}
427
428
void OMultiTypeInterfaceContainerHelper::clear()
429
0
{
430
0
    ::osl::MutexGuard aGuard( rMutex );
431
0
    t_type2ptr * pMap = static_cast<t_type2ptr *>(m_pMap);
432
433
0
    for (auto& rItem : *pMap)
434
0
    {
435
0
        static_cast<OInterfaceContainerHelper*>(rItem.second)->clear();
436
0
    }
437
0
}
438
439
// specialized class for long
440
441
typedef std::vector< std::pair < sal_Int32 , void* > > t_long2ptr;
442
443
static t_long2ptr::iterator findLong(t_long2ptr *pMap, sal_Int32 nKey )
444
0
{
445
0
    return std::find_if(pMap->begin(), pMap->end(),
446
0
        [&nKey](const t_long2ptr::value_type& rItem) { return rItem.first == nKey; });
447
0
}
448
449
OMultiTypeInterfaceContainerHelperInt32::OMultiTypeInterfaceContainerHelperInt32( Mutex & rMutex_ )
450
7.33M
    : m_pMap( nullptr )
451
7.33M
    , rMutex( rMutex_ )
452
7.33M
{
453
    // delay pMap allocation until necessary.
454
7.33M
}
455
456
OMultiTypeInterfaceContainerHelperInt32::~OMultiTypeInterfaceContainerHelperInt32()
457
7.32M
{
458
7.32M
    if (!m_pMap)
459
7.32M
        return;
460
461
0
    t_long2ptr * pMap = static_cast<t_long2ptr *>(m_pMap);
462
463
0
    for (auto& rItem : *pMap)
464
0
    {
465
0
        delete static_cast<OInterfaceContainerHelper*>(rItem.second);
466
0
        rItem.second = nullptr;
467
0
    }
468
0
    delete pMap;
469
0
}
470
471
Sequence< sal_Int32 > OMultiTypeInterfaceContainerHelperInt32::getContainedTypes() const
472
0
{
473
0
    t_long2ptr * pMap = static_cast<t_long2ptr *>(m_pMap);
474
0
    t_long2ptr::size_type nSize;
475
476
0
    ::osl::MutexGuard aGuard( rMutex );
477
0
    nSize = pMap ? pMap->size() : 0;
478
0
    if( nSize )
479
0
    {
480
0
        css::uno::Sequence< sal_Int32 > aInterfaceTypes( nSize );
481
0
        sal_Int32 * pArray = aInterfaceTypes.getArray();
482
483
0
        sal_Int32 i = 0;
484
0
        for (const auto& rItem : *pMap)
485
0
        {
486
            // are interfaces added to this container?
487
0
            if( static_cast<OInterfaceContainerHelper*>(rItem.second)->getLength() )
488
                // yes, put the type in the array
489
0
                pArray[i++] = rItem.first;
490
0
        }
491
0
        if( static_cast<t_long2ptr::size_type>(i) != nSize ) {
492
            // may be empty container, reduce the sequence to the right size
493
0
            aInterfaceTypes = css::uno::Sequence< sal_Int32 >( pArray, i );
494
0
        }
495
0
        return aInterfaceTypes;
496
0
    }
497
0
    return css::uno::Sequence< sal_Int32 >();
498
0
}
499
500
OInterfaceContainerHelper * OMultiTypeInterfaceContainerHelperInt32::getContainer( const sal_Int32 & rKey ) const
501
446k
{
502
446k
    ::osl::MutexGuard aGuard( rMutex );
503
504
446k
    if (!m_pMap)
505
446k
        return nullptr;
506
0
    t_long2ptr * pMap = static_cast<t_long2ptr *>(m_pMap);
507
0
    t_long2ptr::iterator iter = findLong( pMap, rKey );
508
0
    if( iter != pMap->end() )
509
0
            return static_cast<OInterfaceContainerHelper*>((*iter).second);
510
0
    return nullptr;
511
0
}
512
513
sal_Int32 OMultiTypeInterfaceContainerHelperInt32::addInterface(
514
    const sal_Int32 & rKey, const Reference< XInterface > & rListener )
515
0
{
516
0
    ::osl::MutexGuard aGuard( rMutex );
517
0
    if (!m_pMap)
518
0
        m_pMap = new t_long2ptr;
519
0
    t_long2ptr * pMap = static_cast<t_long2ptr *>(m_pMap);
520
0
    t_long2ptr::iterator iter = findLong( pMap, rKey );
521
0
    if( iter == pMap->end() )
522
0
    {
523
0
        OInterfaceContainerHelper * pLC = new OInterfaceContainerHelper( rMutex );
524
0
        pMap->push_back(std::pair< sal_Int32, void* >(rKey, pLC));
525
0
        return pLC->addInterface( rListener );
526
0
    }
527
0
    return static_cast<OInterfaceContainerHelper*>((*iter).second)->addInterface( rListener );
528
0
}
529
530
sal_Int32 OMultiTypeInterfaceContainerHelperInt32::removeInterface(
531
    const sal_Int32 & rKey, const Reference< XInterface > & rListener )
532
0
{
533
0
    ::osl::MutexGuard aGuard( rMutex );
534
535
0
    if (!m_pMap)
536
0
        return 0;
537
    // search container with id nUik
538
0
    t_long2ptr * pMap = static_cast<t_long2ptr *>(m_pMap);
539
0
    t_long2ptr::iterator iter = findLong( pMap, rKey );
540
        // container found?
541
0
    if( iter != pMap->end() )
542
0
        return static_cast<OInterfaceContainerHelper*>((*iter).second)->removeInterface( rListener );
543
544
    // no container with this id. Always return 0
545
0
    return 0;
546
0
}
547
548
void OMultiTypeInterfaceContainerHelperInt32::disposeAndClear( const EventObject & rEvt )
549
7.26M
{
550
7.26M
    t_long2ptr::size_type nSize = 0;
551
7.26M
    std::unique_ptr<OInterfaceContainerHelper *[]> ppListenerContainers;
552
7.26M
    {
553
7.26M
        ::osl::MutexGuard aGuard( rMutex );
554
7.26M
        if (!m_pMap)
555
7.26M
            return;
556
557
0
        t_long2ptr * pMap = static_cast<t_long2ptr *>(m_pMap);
558
0
        nSize = pMap->size();
559
0
        if( nSize )
560
0
        {
561
0
            typedef OInterfaceContainerHelper* ppp;
562
0
            ppListenerContainers.reset(new ppp[nSize]);
563
564
0
            t_long2ptr::size_type i = 0;
565
0
            for (const auto& rItem : *pMap)
566
0
            {
567
0
                ppListenerContainers[i++] = static_cast<OInterfaceContainerHelper*>(rItem.second);
568
0
            }
569
0
        }
570
0
    }
571
572
    // create a copy, because do not fire event in a guarded section
573
0
    for( t_long2ptr::size_type i = 0;
574
0
            i < nSize; i++ )
575
0
    {
576
0
        if( ppListenerContainers[i] )
577
0
            ppListenerContainers[i]->disposeAndClear( rEvt );
578
0
    }
579
0
}
580
581
void OMultiTypeInterfaceContainerHelperInt32::clear()
582
0
{
583
0
    ::osl::MutexGuard aGuard( rMutex );
584
0
    if (!m_pMap)
585
0
        return;
586
0
    t_long2ptr * pMap = static_cast<t_long2ptr *>(m_pMap);
587
588
0
    for (auto& rItem : *pMap)
589
0
    {
590
0
        static_cast<OInterfaceContainerHelper*>(rItem.second)->clear();
591
0
    }
592
0
}
593
594
}
595
596
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */