Avoid potential negative array index access to cached text.
[LibreOffice.git] / cppuhelper / source / implbase.cxx
blob0673ce6927386e9971f6396a0c33ec99356fb7b5
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <cppuhelper/compbase_ex.hxx>
21 #include <cppuhelper/exc_hlp.hxx>
22 #include <osl/diagnose.h>
23 #include <sal/log.hxx>
25 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
26 #include <com/sun/star/uno/RuntimeException.hpp>
28 using namespace ::osl;
29 using namespace ::com::sun::star;
30 using namespace ::com::sun::star::uno;
33 namespace cppu
36 // WeakComponentImplHelperBase
38 WeakComponentImplHelperBase::WeakComponentImplHelperBase( Mutex & rMutex )
39 : rBHelper( rMutex )
43 WeakComponentImplHelperBase::~WeakComponentImplHelperBase()
47 void WeakComponentImplHelperBase::disposing()
51 Any WeakComponentImplHelperBase::queryInterface( Type const & rType )
53 if (rType == cppu::UnoType<lang::XComponent>::get())
55 void * p = static_cast< lang::XComponent * >( this );
56 return Any( &p, rType );
58 return OWeakObject::queryInterface( rType );
61 void WeakComponentImplHelperBase::acquire()
62 noexcept
64 OWeakObject::acquire();
67 void WeakComponentImplHelperBase::release()
68 noexcept
70 if (osl_atomic_decrement( &m_refCount ) != 0)
71 return;
73 // ensure no other references are created, via the weak connection point, from now on
74 disposeWeakConnectionPoint();
75 // restore reference count:
76 osl_atomic_increment( &m_refCount );
77 if (! rBHelper.bDisposed) {
78 try {
79 dispose();
81 catch (RuntimeException const& exc) { // don't break throw ()
82 SAL_WARN( "cppuhelper", exc );
84 OSL_ASSERT( rBHelper.bDisposed );
86 OWeakObject::release();
89 void WeakComponentImplHelperBase::dispose()
91 ClearableMutexGuard aGuard( rBHelper.rMutex );
92 if (rBHelper.bDisposed || rBHelper.bInDispose)
93 return;
95 rBHelper.bInDispose = true;
96 aGuard.clear();
97 try
99 // side effect: keeping a reference to this
100 lang::EventObject aEvt( static_cast< OWeakObject * >( this ) );
103 rBHelper.aLC.disposeAndClear( aEvt );
104 disposing();
106 catch (...)
108 MutexGuard aGuard2( rBHelper.rMutex );
109 // bDisposed and bInDispose must be set in this order:
110 rBHelper.bDisposed = true;
111 rBHelper.bInDispose = false;
112 throw;
114 MutexGuard aGuard2( rBHelper.rMutex );
115 // bDisposed and bInDispose must be set in this order:
116 rBHelper.bDisposed = true;
117 rBHelper.bInDispose = false;
119 catch (RuntimeException &)
121 throw;
123 catch (Exception & exc)
125 css::uno::Any anyEx = cppu::getCaughtException();
126 throw lang::WrappedTargetRuntimeException(
127 "unexpected UNO exception caught: " + exc.Message,
128 nullptr, anyEx );
132 void WeakComponentImplHelperBase::addEventListener(
133 Reference< lang::XEventListener > const & xListener )
135 ClearableMutexGuard aGuard( rBHelper.rMutex );
136 if (rBHelper.bDisposed || rBHelper.bInDispose)
138 aGuard.clear();
139 lang::EventObject aEvt( static_cast< OWeakObject * >( this ) );
140 xListener->disposing( aEvt );
142 else
144 rBHelper.addListener( cppu::UnoType<decltype(xListener)>::get(), xListener );
148 void WeakComponentImplHelperBase::removeEventListener(
149 Reference< lang::XEventListener > const & xListener )
151 rBHelper.removeListener( cppu::UnoType<decltype(xListener)>::get(), xListener );
154 // WeakAggComponentImplHelperBase
156 WeakAggComponentImplHelperBase::WeakAggComponentImplHelperBase( Mutex & rMutex )
157 : rBHelper( rMutex )
161 WeakAggComponentImplHelperBase::~WeakAggComponentImplHelperBase()
165 void WeakAggComponentImplHelperBase::disposing()
169 Any WeakAggComponentImplHelperBase::queryInterface( Type const & rType )
171 return OWeakAggObject::queryInterface( rType );
174 Any WeakAggComponentImplHelperBase::queryAggregation( Type const & rType )
176 if (rType == cppu::UnoType<lang::XComponent>::get())
178 void * p = static_cast< lang::XComponent * >( this );
179 return Any( &p, rType );
181 return OWeakAggObject::queryAggregation( rType );
184 void WeakAggComponentImplHelperBase::acquire()
185 noexcept
187 OWeakAggObject::acquire();
190 void WeakAggComponentImplHelperBase::release()
191 noexcept
193 Reference<XInterface> const xDelegator_(xDelegator);
194 if (xDelegator_.is()) {
195 OWeakAggObject::release();
197 else if (osl_atomic_decrement( &m_refCount ) == 0) {
198 // ensure no other references are created, via the weak connection point, from now on
199 disposeWeakConnectionPoint();
200 // restore reference count:
201 osl_atomic_increment( &m_refCount );
202 if (! rBHelper.bDisposed) {
203 try {
204 dispose();
206 catch (RuntimeException const& exc) { // don't break throw ()
207 SAL_WARN( "cppuhelper", exc );
209 OSL_ASSERT( rBHelper.bDisposed );
211 OWeakAggObject::release();
215 void WeakAggComponentImplHelperBase::dispose()
217 ClearableMutexGuard aGuard( rBHelper.rMutex );
218 if (rBHelper.bDisposed || rBHelper.bInDispose)
219 return;
221 rBHelper.bInDispose = true;
222 aGuard.clear();
225 // side effect: keeping a reference to this
226 lang::EventObject aEvt( static_cast< OWeakObject * >( this ) );
229 rBHelper.aLC.disposeAndClear( aEvt );
230 disposing();
232 catch (...)
234 MutexGuard aGuard2( rBHelper.rMutex );
235 // bDisposed and bInDispose must be set in this order:
236 rBHelper.bDisposed = true;
237 rBHelper.bInDispose = false;
238 throw;
240 MutexGuard aGuard2( rBHelper.rMutex );
241 // bDisposed and bInDispose must be set in this order:
242 rBHelper.bDisposed = true;
243 rBHelper.bInDispose = false;
245 catch (RuntimeException &)
247 throw;
249 catch (Exception & exc)
251 css::uno::Any anyEx = cppu::getCaughtException();
252 throw lang::WrappedTargetRuntimeException(
253 "unexpected UNO exception caught: " + exc.Message,
254 nullptr, anyEx );
258 void WeakAggComponentImplHelperBase::addEventListener(
259 Reference< lang::XEventListener > const & xListener )
261 ClearableMutexGuard aGuard( rBHelper.rMutex );
262 if (rBHelper.bDisposed || rBHelper.bInDispose)
264 aGuard.clear();
265 lang::EventObject aEvt( static_cast< OWeakObject * >( this ) );
266 xListener->disposing( aEvt );
268 else
270 rBHelper.addListener( cppu::UnoType<decltype(xListener)>::get(), xListener );
274 void WeakAggComponentImplHelperBase::removeEventListener(
275 Reference< lang::XEventListener > const & xListener )
277 // if we have disposed, then we have cleared the list already
278 MutexGuard aGuard( rBHelper.rMutex );
279 if (!rBHelper.bDisposed)
280 rBHelper.removeListener( cppu::UnoType<decltype(xListener)>::get(), xListener );
285 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */