Bug Summary

File:home/maarten/src/libreoffice/core/include/rtl/ref.hxx
Warning:line 192, column 9
Use of memory after it is freed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name backingcomp.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -isystem /usr/include/libxml2 -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D SFX2_DLLIMPLEMENTATION -D ENABLE_CUPS -D SYSTEM_LIBXML -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/liborcus/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/liborcus/include -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/sfx2/inc -I /home/maarten/src/libreoffice/core/sfx2/source/inc -I /home/maarten/src/libreoffice/core/workdir/SdiTarget/sfx2/sdi -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/officecfg/registry -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/sfx2/source/dialog/backingcomp.cxx

/home/maarten/src/libreoffice/core/sfx2/source/dialog/backingcomp.cxx

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#include "backingwindow.hxx"
21
22#include <com/sun/star/frame/XDispatchProvider.hpp>
23#include <com/sun/star/beans/XPropertySet.hpp>
24#include <com/sun/star/awt/KeyEvent.hpp>
25#include <com/sun/star/frame/XLayoutManager.hpp>
26#include <com/sun/star/lang/XServiceInfo.hpp>
27#include <com/sun/star/lang/XInitialization.hpp>
28#include <com/sun/star/awt/XWindow.hpp>
29#include <com/sun/star/awt/XKeyListener.hpp>
30#include <com/sun/star/uno/XComponentContext.hpp>
31#include <com/sun/star/frame/XFrame.hpp>
32#include <com/sun/star/frame/XDispatch.hpp>
33#include <com/sun/star/lang/XEventListener.hpp>
34#include <com/sun/star/lang/XComponent.hpp>
35#include <com/sun/star/lang/XTypeProvider.hpp>
36
37#include <cppuhelper/supportsservice.hxx>
38#include <cppuhelper/queryinterface.hxx>
39#include <cppuhelper/typeprovider.hxx>
40#include <cppuhelper/weak.hxx>
41#include <toolkit/helper/vclunohelper.hxx>
42#include <vcl/wrkwin.hxx>
43#include <vcl/svapp.hxx>
44#include <vcl/syswin.hxx>
45
46#include <sfx2/notebookbar/SfxNotebookBar.hxx>
47
48namespace {
49
50/**
51 implements the backing component.
52
53 This component is a special one, which doesn't provide a controller
54 nor a model. It supports the following features:
55 - Drag & Drop
56 - Key Accelerators
57 - Simple Menu
58 - Progress Bar
59 - Background
60 */
61class BackingComp : public css::lang::XTypeProvider
62 , public css::lang::XServiceInfo
63 , public css::lang::XInitialization
64 , public css::frame::XController // => XComponent
65 , public css::awt::XKeyListener // => XEventListener
66 , public css::frame::XDispatchProvider
67 , public css::frame::XDispatch
68 , public ::cppu::OWeakObject
69{
70private:
71 /** reference to the component window. */
72 css::uno::Reference< css::awt::XWindow > m_xWindow;
73
74 /** the owner frame of this component. */
75 css::uno::Reference< css::frame::XFrame > m_xFrame;
76
77 Size m_aInitialWindowMinSize;
78
79public:
80
81 explicit BackingComp();
82
83 // XInterface
84 virtual css::uno::Any SAL_CALL queryInterface( const css::uno::Type& aType ) override;
85 virtual void SAL_CALL acquire ( ) throw( ) override;
86 virtual void SAL_CALL release ( ) throw( ) override;
87
88 // XTypeProvide
89 virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes () override;
90 virtual css::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() override;
91
92 // XServiceInfo
93 virtual OUString SAL_CALL getImplementationName ( ) override;
94 virtual sal_Bool SAL_CALL supportsService ( const OUString& sServiceName ) override;
95 virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override;
96
97 // XInitialization
98 virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& lArgs ) override;
99
100 // XController
101 virtual void SAL_CALL attachFrame( const css::uno::Reference< css::frame::XFrame >& xFrame ) override;
102 virtual sal_Bool SAL_CALL attachModel( const css::uno::Reference< css::frame::XModel >& xModel ) override;
103 virtual sal_Bool SAL_CALL suspend( sal_Bool bSuspend ) override;
104 virtual css::uno::Any SAL_CALL getViewData() override;
105 virtual void SAL_CALL restoreViewData( const css::uno::Any& aData ) override;
106 virtual css::uno::Reference< css::frame::XModel > SAL_CALL getModel() override;
107 virtual css::uno::Reference< css::frame::XFrame > SAL_CALL getFrame() override;
108
109 // XKeyListener
110 virtual void SAL_CALL keyPressed ( const css::awt::KeyEvent& aEvent ) override;
111 virtual void SAL_CALL keyReleased( const css::awt::KeyEvent& aEvent ) override;
112
113 // XEventListener
114 virtual void SAL_CALL disposing( const css::lang::EventObject& aEvent ) override;
115
116 // XComponent
117 virtual void SAL_CALL dispose ( ) override;
118 virtual void SAL_CALL addEventListener ( const css::uno::Reference< css::lang::XEventListener >& xListener ) override;
119 virtual void SAL_CALL removeEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener ) override;
120
121 // XDispatchProvider
122 virtual css::uno::Reference< css::frame::XDispatch > SAL_CALL queryDispatch( const css::util::URL& aURL, const OUString& sTargetFrameName , sal_Int32 nSearchFlags ) override;
123 virtual css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL queryDispatches( const css::uno::Sequence< css::frame::DispatchDescriptor >& lDescriptions ) override;
124
125 // XDispatch
126 virtual void SAL_CALL dispatch( const css::util::URL& aURL, const css::uno::Sequence< css::beans::PropertyValue >& lArguments ) override;
127 virtual void SAL_CALL addStatusListener( const css::uno::Reference< css::frame::XStatusListener >& xListener, const css::util::URL& aURL ) override;
128 virtual void SAL_CALL removeStatusListener( const css::uno::Reference< css::frame::XStatusListener >& xListener, const css::util::URL& aURL ) override;
129};
130
131BackingComp::BackingComp()
132{
133}
134
135/** return information about supported interfaces.
136
137 Some interfaces are supported by his class directly, but some other ones are
138 used by aggregation. An instance of this class must provide some window interfaces.
139 But it must represent a VCL window behind such interfaces too! So we use an internal
140 saved window member to ask it for its interfaces and return it. But we must be aware then,
141 that it can be destroyed from outside too ...
142
143 @param aType
144 describe the required interface type
145
146 @return An Any holding the instance, which provides the queried interface.
147 Note: There exist two possible results ... this instance itself and her window member!
148 */
149
150css::uno::Any SAL_CALL BackingComp::queryInterface( /*IN*/ const css::uno::Type& aType )
151{
152 // first look for own supported interfaces
153 css::uno::Any aResult = ::cppu::queryInterface(
154 aType,
155 static_cast< css::lang::XTypeProvider* >(this),
156 static_cast< css::lang::XServiceInfo* >(this),
157 static_cast< css::lang::XInitialization* >(this),
158 static_cast< css::frame::XController* >(this),
159 static_cast< css::lang::XComponent* >(this),
160 static_cast< css::lang::XEventListener* >(this),
161 static_cast< css::awt::XKeyListener* >(static_cast< css::lang::XEventListener* >(this)),
162 static_cast< css::frame::XDispatchProvider* >(this),
163 static_cast< css::frame::XDispatch* >(this) );
164
165 // then look for supported window interfaces
166 // Note: They exist only, if this instance was initialized
167 // with a valid window reference. It's aggregation on demand ...
168 if (!aResult.hasValue())
169 {
170 /* SAFE { */
171 SolarMutexGuard aGuard;
172 if (m_xWindow.is())
173 aResult = m_xWindow->queryInterface(aType);
174 /* } SAFE */
175 }
176
177 // look for XWeak and XInterface
178 if (!aResult.hasValue())
179 aResult = OWeakObject::queryInterface(aType);
180
181 return aResult;
182}
183
184
185/** increase ref count of this instance.
186 */
187
188void SAL_CALL BackingComp::acquire()
189 throw()
190{
191 OWeakObject::acquire();
192}
193
194
195/** decrease ref count of this instance.
196 */
197
198void SAL_CALL BackingComp::release()
199 throw()
200{
201 OWeakObject::release();
202}
203
204
205/** return collection about all supported interfaces.
206
207 Optimize this method !
208 We initialize a static variable only one time.
209 And we don't must use a mutex at every call!
210 For the first call; pTypeCollection is NULL -
211 for the second call pTypeCollection is different from NULL!
212
213 @return A list of all supported interface types.
214*/
215
216css::uno::Sequence< css::uno::Type > SAL_CALL BackingComp::getTypes()
217{
218 static cppu::OTypeCollection aTypeCollection = [this]() {
219 SolarMutexGuard aGuard;
220 css::uno::Reference<css::lang::XTypeProvider> xProvider(m_xWindow, css::uno::UNO_QUERY);
221
222 css::uno::Sequence<css::uno::Type> lWindowTypes;
223 if (xProvider.is())
224 lWindowTypes = xProvider->getTypes();
225
226 return cppu::OTypeCollection(
227 cppu::UnoType<css::lang::XInitialization>::get(),
228 cppu::UnoType<css::lang::XTypeProvider>::get(),
229 cppu::UnoType<css::lang::XServiceInfo>::get(),
230 cppu::UnoType<css::frame::XController>::get(),
231 cppu::UnoType<css::lang::XComponent>::get(),
232 cppu::UnoType<css::frame::XDispatchProvider>::get(),
233 cppu::UnoType<css::frame::XDispatch>::get(), lWindowTypes);
234 }();
235
236 return aTypeCollection.getTypes();
237}
238
239
240/** create one unique Id for all instances of this class.
241
242 Optimize this method
243 We initialize a static variable only one time. And we don't must use a mutex at every call!
244 For the first call; pID is NULL - for the second call pID is different from NULL!
245
246 @return A byte array, which represent the unique id.
247*/
248
249css::uno::Sequence< sal_Int8 > SAL_CALL BackingComp::getImplementationId()
250{
251 return css::uno::Sequence<sal_Int8>();
252}
253
254OUString SAL_CALL BackingComp::getImplementationName()
255{
256 return "com.sun.star.comp.sfx2.BackingComp";
257}
258
259sal_Bool SAL_CALL BackingComp::supportsService( /*IN*/ const OUString& sServiceName )
260{
261 return cppu::supportsService(this, sServiceName);
262}
263
264css::uno::Sequence< OUString > SAL_CALL BackingComp::getSupportedServiceNames()
265{
266 return { "com.sun.star.frame.StartModule", "com.sun.star.frame.ProtocolHandler" };
267}
268
269
270/**
271 attach this component to a target frame.
272
273 We have to use the container window of this frame as parent window of our own component window.
274 But it's not allowed to work with it really. May another component used it too.
275 Currently we need it only to create our child component window and support it's
276 interfaces inside our queryInterface() method. The user of us must have e.g. the
277 XWindow interface of it to be able to call setComponent(xWindow,xController) at the
278 frame!
279
280 May he will do the following things:
281
282 <listing>
283 XController xBackingComp = (XController)UnoRuntime.queryInterface(
284 XController.class,
285 xSMGR.createInstance(SERVICENAME_STARTMODULE));
286
287 // at this time XWindow isn't present at this instance!
288 XWindow xBackingComp = (XWindow)UnoRuntime.queryInterface(
289 XWindow.class,
290 xBackingComp);
291
292 // attach controller to the frame
293 // We will use its container window, to create
294 // the component window. From now we offer the window interfaces!
295 xBackingComp.attachFrame(xFrame);
296
297 XWindow xBackingComp = (XWindow)UnoRuntime.queryInterface(
298 XWindow.class,
299 xBackingComp);
300
301 // Our user can set us at the frame as new component
302 xFrame.setComponent(xBackingWin, xBackingComp);
303
304 // But that had no effect to our view state.
305 // We must be started to create our UI elements like e.g. menu, title, background ...
306 XInitialization xBackingInit = (XInitialization)UnoRuntime.queryInterface(
307 XInitialization.class,
308 xBackingComp);
309
310 xBackingInit.initialize(lArgs);
311 </listing>
312
313 @param xFrame
314 reference to our new target frame
315
316 @throw css::uno::RuntimeException
317 if the given frame reference is wrong or component window couldn't be created
318 successfully.
319 We throw it too, if we already attached to a frame. Because we don't support
320 reparenting of our component window on demand!
321*/
322
323void SAL_CALL BackingComp::attachFrame( /*IN*/ const css::uno::Reference< css::frame::XFrame >& xFrame )
324{
325 /* SAFE */
326 SolarMutexGuard aGuard;
327
328 // check some required states
329 if (m_xFrame.is())
330 throw css::uno::RuntimeException(
331 "already attached",
332 static_cast< ::cppu::OWeakObject* >(this));
333
334 if (!xFrame.is())
335 throw css::uno::RuntimeException(
336 "invalid frame reference",
337 static_cast< ::cppu::OWeakObject* >(this));
338
339 if (!m_xWindow.is())
340 return; // disposed
341
342 // safe the frame reference
343 m_xFrame = xFrame;
344
345 // initialize the component and its parent window
346 css::uno::Reference< css::awt::XWindow > xParentWindow = xFrame->getContainerWindow();
347 VclPtr< WorkWindow > pParent = static_cast<WorkWindow*>(VCLUnoHelper::GetWindow(xParentWindow).get());
348 VclPtr< vcl::Window > pWindow = VCLUnoHelper::GetWindow(m_xWindow);
349
350 // disable full screen mode of the frame!
351 if (pParent && pParent->IsFullScreenMode())
352 {
353 pParent->ShowFullScreenMode(false);
354 pParent->SetMenuBarMode(MenuBarMode::Normal);
355 }
356
357 // create the menu bar for the backing component
358 css::uno::Reference< css::beans::XPropertySet > xPropSet(m_xFrame, css::uno::UNO_QUERY_THROW);
359 css::uno::Reference< css::frame::XLayoutManager > xLayoutManager;
360 xPropSet->getPropertyValue("LayoutManager") >>= xLayoutManager;
361 if (xLayoutManager.is())
362 {
363 xLayoutManager->lock();
364 xLayoutManager->createElement("private:resource/menubar/menubar");
365 xLayoutManager->unlock();
366 }
367
368 if (pWindow)
369 {
370 // set help ID for our canvas
371 pWindow->SetHelpId("FWK_HID_BACKINGWINDOW");
372 }
373
374 // inform BackingWindow about frame
375 BackingWindow* pBack = dynamic_cast<BackingWindow*>(pWindow.get());
376 if( pBack )
377 pBack->setOwningFrame( m_xFrame );
378
379 // set NotebookBar
380 SystemWindow* pSysWindow = pParent;
381 if (pSysWindow)
382 {
383 //sfx2::SfxNotebookBar::StateMethod(pSysWindow, m_xFrame, "sfx/ui/notebookbar.ui");
384 }
385
386 // Set a minimum size for Start Center
387 if( !pParent || !pBack )
388 return;
389
390 long nMenuHeight = 0;
391 vcl::Window* pMenu = pParent->GetWindow(GetWindowType::Next);
392 if( pMenu )
393 nMenuHeight = pMenu->GetSizePixel().Height();
394
395 m_aInitialWindowMinSize = pParent->GetMinOutputSizePixel();
396 if (!m_aInitialWindowMinSize.Width())
397 m_aInitialWindowMinSize.AdjustWidth(1);
398 if (!m_aInitialWindowMinSize.Height())
399 m_aInitialWindowMinSize.AdjustHeight(1);
400
401 pParent->SetMinOutputSizePixel(
402 Size(
403 pBack->get_width_request(),
404 pBack->get_height_request() + nMenuHeight));
405
406 /* } SAFE */
407}
408
409
410/** not supported.
411
412 This component does not know any model. It will be represented by a window and
413 its controller only.
414
415 return <FALSE/> every time.
416 */
417
418sal_Bool SAL_CALL BackingComp::attachModel( /*IN*/ const css::uno::Reference< css::frame::XModel >& )
419{
420 return false;
421}
422
423
424/** not supported.
425
426 This component does not know any model. It will be represented by a window and
427 its controller only.
428
429 return An empty reference every time.
430 */
431
432css::uno::Reference< css::frame::XModel > SAL_CALL BackingComp::getModel()
433{
434 return css::uno::Reference< css::frame::XModel >();
435}
436
437
438/** not supported.
439
440 return An empty value.
441 */
442
443css::uno::Any SAL_CALL BackingComp::getViewData()
444{
445 return css::uno::Any();
446}
447
448
449/** not supported.
450
451 @param aData
452 not used.
453 */
454
455void SAL_CALL BackingComp::restoreViewData( /*IN*/ const css::uno::Any& )
456{
457}
458
459
460/** returns the attached frame for this component.
461
462 @see attachFrame()
463
464 @return The internally saved frame reference.
465 Can be null, if attachFrame() was not called before.
466 */
467
468css::uno::Reference< css::frame::XFrame > SAL_CALL BackingComp::getFrame()
469{
470 /* SAFE { */
471 SolarMutexGuard aGuard;
472 return m_xFrame;
473 /* } SAFE */
474}
475
476
477/** ask controller for its current working state.
478
479 If someone wishes to close this component, it must suspend the controller before.
480 That will be a chance for it to disagree with that AND show any UI for a possible
481 UI user.
482
483 @param bSuspend
484 If it's set to sal_True this controller should be suspended.
485 sal_False will resuspend it.
486
487 @return sal_True if the request could be finished successfully; sal_False otherwise.
488 */
489
490sal_Bool SAL_CALL BackingComp::suspend( /*IN*/ sal_Bool )
491{
492 /* FIXME ... implemented by using default :-( */
493 return true;
494}
495
496
497/** callback from our window member.
498
499 Our internal saved window wish to die. It will be disposed from outside (may be the frame)
500 and inform us. We must release its reference only here. Of course we check the given reference
501 here and reject callback from unknown sources.
502
503 Note: deregistration as listener isn't necessary here. The broadcaster do it automatically.
504
505 @param aEvent
506 describe the broadcaster of this callback
507
508 @throw css::uno::RuntimeException
509 if the broadcaster doesn't represent the expected window reference.
510*/
511
512void SAL_CALL BackingComp::disposing( /*IN*/ const css::lang::EventObject& aEvent )
513{
514 // Attention: don't free m_pAccExec here! see comments inside dtor and
515 // keyPressed() for further details.
516
517 /* SAFE { */
518 SolarMutexGuard aGuard;
519
520 if (!aEvent.Source.is() || aEvent.Source!=m_xWindow || !m_xWindow.is())
521 throw css::uno::RuntimeException(
522 "unexpected source or called twice",
523 static_cast< ::cppu::OWeakObject* >(this));
524
525 m_xWindow.clear();
526
527 /* } SAFE */
528}
529
530
531/** kill this instance.
532
533 It can be called from our owner frame only. But there is no possibility to check the caller.
534 We have to release all our internal used resources and die. From this point we can throw
535 DisposedExceptions for every further interface request... but current implementation doesn't do so...
536
537*/
538
539void SAL_CALL BackingComp::dispose()
540{
541 /* SAFE { */
542 SolarMutexGuard aGuard;
543
544 if (m_xFrame.is())
1
Taking true branch
545 {
546 css::uno::Reference< css::awt::XWindow > xParentWindow = m_xFrame->getContainerWindow();
547 VclPtr< WorkWindow > pParent = static_cast<WorkWindow*>(VCLUnoHelper::GetWindow(xParentWindow).get());
2
Calling constructor for 'VclPtr<WorkWindow>'
7
Returning from constructor for 'VclPtr<WorkWindow>'
8
Calling implicit destructor for 'VclPtr<vcl::Window>'
9
Calling '~Reference'
16
Returning from '~Reference'
17
Returning from destructor for 'VclPtr<vcl::Window>'
548 if (pParent)
18
Calling 'VclPtr::operator bool'
549 {
550 pParent->SetMinOutputSizePixel(m_aInitialWindowMinSize);
551 // hide NotebookBar
552 sfx2::SfxNotebookBar::CloseMethod(static_cast<SystemWindow*>(pParent));
553 }
554 }
555
556 // stop listening at the window
557 if (m_xWindow.is())
558 {
559 m_xWindow->removeEventListener(this);
560 m_xWindow->removeKeyListener(this);
561 m_xWindow.clear();
562 }
563
564 // forget all other used references
565 m_xFrame.clear();
566
567 /* } SAFE */
568}
569
570
571/** not supported.
572
573 @param xListener
574 not used.
575
576 @throw css::uno::RuntimeException
577 because the listener expect to be holded alive by this container.
578 We must inform it about this unsupported feature.
579 */
580
581void SAL_CALL BackingComp::addEventListener( /*IN*/ const css::uno::Reference< css::lang::XEventListener >& )
582{
583 throw css::uno::RuntimeException(
584 "not supported",
585 static_cast< ::cppu::OWeakObject* >(this));
586}
587
588
589/** not supported.
590
591 Because registration is not supported too, we must do nothing here. Nobody can call this method really.
592
593 @param xListener
594 not used.
595 */
596
597void SAL_CALL BackingComp::removeEventListener( /*IN*/ const css::uno::Reference< css::lang::XEventListener >& )
598{
599}
600
601
602/**
603 force initialization for this component.
604
605 Inside attachFrame() we created our component window. But it was not allowed there, to
606 initialize it. E.g. the menu must be set at the container window of the frame, which
607 is our parent window. But may at that time another component used it.
608 That's why our creator has to inform us, when it's time to initialize us really.
609 Currently only calling of this method must be done. But further implementations
610 can use special in parameter to configure this initialization...
611
612 @param lArgs
613 currently not used
614
615 @throw css::uno::RuntimeException
616 if some resources are missing
617 Means if may be attachedFrame() wasn't called before.
618 */
619
620void SAL_CALL BackingComp::initialize( /*IN*/ const css::uno::Sequence< css::uno::Any >& lArgs )
621{
622 /* SAFE { */
623 SolarMutexGuard aGuard;
624
625 if (m_xWindow.is())
626 throw css::uno::Exception(
627 "already initialized",
628 static_cast< ::cppu::OWeakObject* >(this));
629
630 css::uno::Reference< css::awt::XWindow > xParentWindow;
631 if (
632 (lArgs.getLength()!=1 ) ||
633 (!(lArgs[0] >>= xParentWindow)) ||
634 (!xParentWindow.is() )
635 )
636 {
637 throw css::uno::Exception(
638 "wrong or corrupt argument list",
639 static_cast< ::cppu::OWeakObject* >(this));
640 }
641
642 // create the component window
643 VclPtr<vcl::Window> pParent = VCLUnoHelper::GetWindow(xParentWindow);
644 VclPtr<vcl::Window> pWindow = VclPtr<BackingWindow>::Create(pParent);
645 m_xWindow = VCLUnoHelper::GetInterface(pWindow);
646
647 if (!m_xWindow.is())
648 throw css::uno::RuntimeException(
649 "couldn't create component window",
650 static_cast< ::cppu::OWeakObject* >(this));
651
652 // start listening for window disposing
653 // It's set at our owner frame as component window later too. So it will may be disposed there ...
654 m_xWindow->addEventListener(static_cast< css::lang::XEventListener* >(this));
655
656 m_xWindow->setVisible(true);
657
658 /* } SAFE */
659}
660
661
662void SAL_CALL BackingComp::keyPressed( /*IN*/ const css::awt::KeyEvent& )
663{
664}
665
666
667void SAL_CALL BackingComp::keyReleased( /*IN*/ const css::awt::KeyEvent& )
668{
669 /* Attention
670 Please use keyPressed() instead of this method. Otherwise it would be possible, that
671 - a key input may be first switch to the backing mode
672 - and this component register itself as key listener too
673 - and it's first event will be a keyReleased() for the already well known event, which switched to the backing mode!
674 So it will be handled twice! document => backing mode => exit app...
675 */
676}
677
678// XDispatchProvider
679css::uno::Reference< css::frame::XDispatch > SAL_CALL BackingComp::queryDispatch( const css::util::URL& aURL, const OUString& /*sTargetFrameName*/, sal_Int32 /*nSearchFlags*/ )
680{
681 css::uno::Reference< css::frame::XDispatch > xDispatch;
682 if ( aURL.Protocol == "vnd.org.libreoffice.recentdocs:" )
683 xDispatch = this;
684
685 return xDispatch;
686}
687
688css::uno::Sequence < css::uno::Reference< css::frame::XDispatch > > SAL_CALL BackingComp::queryDispatches( const css::uno::Sequence < css::frame::DispatchDescriptor >& seqDescripts )
689{
690 sal_Int32 nCount = seqDescripts.getLength();
691 css::uno::Sequence < css::uno::Reference < XDispatch > > lDispatcher( nCount );
692
693 std::transform(seqDescripts.begin(), seqDescripts.end(), lDispatcher.begin(),
694 [this](const css::frame::DispatchDescriptor& rDesc) -> css::uno::Reference<XDispatch> {
695 return queryDispatch(rDesc.FeatureURL, rDesc.FrameName, rDesc.SearchFlags); });
696
697 return lDispatcher;
698}
699
700// XDispatch
701void SAL_CALL BackingComp::dispatch( const css::util::URL& aURL, const css::uno::Sequence < css::beans::PropertyValue >& /*lArgs*/ )
702{
703 // vnd.org.libreoffice.recentdocs:ClearRecentFileList - clear recent files
704 if ( aURL.Path != "ClearRecentFileList" )
705 return;
706
707 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow(m_xWindow);
708 BackingWindow* pBack = dynamic_cast<BackingWindow*>(pWindow.get());
709 if( !pBack )
710 return;
711
712 pBack->clearRecentFileList();
713
714 // Recalculate minimum width
715 css::uno::Reference< css::awt::XWindow > xParentWindow = m_xFrame->getContainerWindow();
716 VclPtr< WorkWindow > pParent = static_cast<WorkWindow*>(VCLUnoHelper::GetWindow(xParentWindow).get());
717 if( pParent )
718 {
719 pParent->SetMinOutputSizePixel( Size(
720 pBack->get_width_request(),
721 pParent->GetMinOutputSizePixel().Height()) );
722 }
723}
724
725void SAL_CALL BackingComp::addStatusListener( const css::uno::Reference< css::frame::XStatusListener >& /*xControl*/, const css::util::URL& /*aURL*/ )
726{
727}
728
729void SAL_CALL BackingComp::removeStatusListener( const css::uno::Reference< css::frame::XStatusListener >& /*xControl*/, const css::util::URL& /*aURL*/ )
730{
731}
732
733}
734
735extern "C" SAL_DLLPUBLIC_EXPORT__attribute__ ((visibility("default"))) css::uno::XInterface *
736com_sun_star_comp_sfx2_BackingComp_get_implementation(
737 css::uno::XComponentContext *,
738 css::uno::Sequence<css::uno::Any> const &)
739{
740 return cppu::acquire(new BackingComp);
741}
742
743/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx

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#ifndef INCLUDED_VCL_PTR_HXX
21#define INCLUDED_VCL_PTR_HXX
22
23#include <sal/config.h>
24
25#include <rtl/ref.hxx>
26
27#include <utility>
28#include <type_traits>
29
30#ifdef DBG_UTIL
31#ifndef _WIN32
32#include <vcl/vclmain.hxx>
33#endif
34#endif
35
36class VclReferenceBase;
37
38namespace vcl::detail {
39
40template<typename>
41constexpr bool isIncompleteOrDerivedFromVclReferenceBase(...) { return true; }
42
43template<typename T> constexpr bool isIncompleteOrDerivedFromVclReferenceBase(
44 int (*)[sizeof(T)])
45{ return std::is_base_of<VclReferenceBase, T>::value; }
46
47} // namespace vcl::detail
48
49/**
50 * A thin wrapper around rtl::Reference to implement the acquire and dispose semantics we want for references to vcl::Window subclasses.
51 *
52 * For more details on the design please see vcl/README.lifecycle
53 *
54 * @param reference_type must be a subclass of vcl::Window
55 */
56template <class reference_type>
57class VclPtr
58{
59 static_assert(
60 vcl::detail::isIncompleteOrDerivedFromVclReferenceBase<reference_type>(
61 nullptr),
62 "template argument type must be derived from VclReferenceBase");
63
64 ::rtl::Reference<reference_type> m_rInnerRef;
65
66public:
67 /** Constructor...
68 */
69 VclPtr()
70 : m_rInnerRef()
71 {}
72
73 /** Constructor...
74 */
75 VclPtr (reference_type * pBody)
76 : m_rInnerRef(pBody)
3
Calling constructor for 'Reference<WorkWindow>'
6
Returning from constructor for 'Reference<WorkWindow>'
77 {}
78
79 /** Constructor... that doesn't take a ref.
80 */
81 VclPtr (reference_type * pBody, __sal_NoAcquire)
82 : m_rInnerRef(pBody, SAL_NO_ACQUIRE)
83 {}
84
85 /** Up-casting conversion constructor: Copies interface reference.
86
87 Does not work for up-casts to ambiguous bases. For the special case of
88 up-casting to Reference< XInterface >, see the corresponding conversion
89 operator.
90
91 @param rRef another reference
92 */
93 template< class derived_type >
94 VclPtr(
95 const VclPtr< derived_type > & rRef,
96 typename std::enable_if<
97 std::is_base_of<reference_type, derived_type>::value, int>::type
98 = 0 )
99 : m_rInnerRef( static_cast<reference_type*>(rRef) )
100 {
101 }
102
103#if defined(DBG_UTIL) && !defined(_WIN32)
104 virtual ~VclPtr()
105 {
106 assert(m_rInnerRef.get() == nullptr || vclmain::isAlive())(static_cast <bool> (m_rInnerRef.get() == nullptr || vclmain
::isAlive()) ? void (0) : __assert_fail ("m_rInnerRef.get() == nullptr || vclmain::isAlive()"
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 106, __extension__ __PRETTY_FUNCTION__))
;
107 // We can be one of the intermediate counts, but if we are the last
108 // VclPtr keeping this object alive, then something forgot to call dispose().
109 assert((!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1)(static_cast <bool> ((!m_rInnerRef.get() || m_rInnerRef
->isDisposed() || m_rInnerRef->getRefCount() > 1) &&
"someone forgot to call dispose()") ? void (0) : __assert_fail
("(!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1) && \"someone forgot to call dispose()\""
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 110, __extension__ __PRETTY_FUNCTION__))
110 && "someone forgot to call dispose()")(static_cast <bool> ((!m_rInnerRef.get() || m_rInnerRef
->isDisposed() || m_rInnerRef->getRefCount() > 1) &&
"someone forgot to call dispose()") ? void (0) : __assert_fail
("(!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1) && \"someone forgot to call dispose()\""
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 110, __extension__ __PRETTY_FUNCTION__))
;
111 }
112 VclPtr(VclPtr const &) = default;
113 VclPtr(VclPtr &&) = default;
114 VclPtr & operator =(VclPtr const &) = default;
115 VclPtr & operator =(VclPtr &&) = default;
116#endif
117
118 /**
119 * A construction helper for VclPtr. Since VclPtr types are created
120 * with a reference-count of one - to help fit into the existing
121 * code-flow; this helps us to construct them easily.
122 *
123 * For more details on the design please see vcl/README.lifecycle
124 *
125 * @tparam reference_type must be a subclass of vcl::Window
126 */
127 template<typename... Arg> [[nodiscard]] static VclPtr< reference_type > Create(Arg &&... arg)
128 {
129 return VclPtr< reference_type >( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE );
130 }
131
132 /** Probably most common used: handle->someBodyOp().
133 */
134 reference_type * operator->() const
135 {
136 return m_rInnerRef.get();
137 }
138
139 /** Get the body. Can be used instead of operator->().
140 I.e. handle->someBodyOp() and handle.get()->someBodyOp()
141 are the same.
142 */
143 reference_type * get() const
144 {
145 return m_rInnerRef.get();
146 }
147
148 void set(reference_type *pBody)
149 {
150 m_rInnerRef.set(pBody);
151 }
152
153 void reset(reference_type *pBody)
154 {
155 m_rInnerRef.set(pBody);
156 }
157
158 /** Up-casting copy assignment operator.
159
160 Does not work for up-casts to ambiguous bases.
161
162 @param rRef another reference
163 */
164 template<typename derived_type>
165 typename std::enable_if<
166 std::is_base_of<reference_type, derived_type>::value,
167 VclPtr &>::type
168 operator =(VclPtr<derived_type> const & rRef)
169 {
170 m_rInnerRef.set(rRef.get());
171 return *this;
172 }
173
174 VclPtr & operator =(reference_type * pBody)
175 {
176 m_rInnerRef.set(pBody);
177 return *this;
178 }
179
180 operator reference_type * () const
181 {
182 return m_rInnerRef.get();
183 }
184
185 explicit operator bool () const
186 {
187 return m_rInnerRef.get() != nullptr;
19
Calling 'Reference::get'
188 }
189
190 void clear()
191 {
192 m_rInnerRef.clear();
193 }
194
195 void reset()
196 {
197 m_rInnerRef.clear();
198 }
199
200 void disposeAndClear()
201 {
202 // hold it alive for the lifetime of this method
203 ::rtl::Reference<reference_type> aTmp(m_rInnerRef);
204 m_rInnerRef.clear(); // we should use some 'swap' method ideally ;-)
205 if (aTmp.get()) {
206 aTmp->disposeOnce();
207 }
208 }
209
210 /** Needed to place VclPtr's into STL collection.
211 */
212 bool operator< (const VclPtr<reference_type> & handle) const
213 {
214 return (m_rInnerRef < handle.m_rInnerRef);
215 }
216}; // class VclPtr
217
218template<typename T1, typename T2>
219inline bool operator ==(VclPtr<T1> const & p1, VclPtr<T2> const & p2) {
220 return p1.get() == p2.get();
221}
222
223template<typename T> inline bool operator ==(VclPtr<T> const & p1, T const * p2)
224{
225 return p1.get() == p2;
226}
227
228template<typename T> inline bool operator ==(VclPtr<T> const & p1, T * p2) {
229 return p1.get() == p2;
230}
231
232template<typename T> inline bool operator ==(T const * p1, VclPtr<T> const & p2)
233{
234 return p1 == p2.get();
235}
236
237template<typename T> inline bool operator ==(T * p1, VclPtr<T> const & p2) {
238 return p1 == p2.get();
239}
240
241template<typename T1, typename T2>
242inline bool operator !=(VclPtr<T1> const & p1, VclPtr<T2> const & p2) {
243 return !(p1 == p2);
244}
245
246template<typename T> inline bool operator !=(VclPtr<T> const & p1, T const * p2)
247{
248 return !(p1 == p2);
249}
250
251template<typename T> inline bool operator !=(VclPtr<T> const & p1, T * p2) {
252 return !(p1 == p2);
253}
254
255template<typename T> inline bool operator !=(T const * p1, VclPtr<T> const & p2)
256{
257 return !(p1 == p2);
258}
259
260template<typename T> inline bool operator !=(T * p1, VclPtr<T> const & p2) {
261 return !(p1 == p2);
262}
263
264/**
265 * A construction helper for a temporary VclPtr. Since VclPtr types
266 * are created with a reference-count of one - to help fit into
267 * the existing code-flow; this helps us to construct them easily.
268 * see also VclPtr::Create and ScopedVclPtr
269 *
270 * For more details on the design please see vcl/README.lifecycle
271 *
272 * @param reference_type must be a subclass of vcl::Window
273 */
274template <class reference_type>
275class SAL_WARN_UNUSED__attribute__((warn_unused)) VclPtrInstance final : public VclPtr<reference_type>
276{
277public:
278 template<typename... Arg> VclPtrInstance(Arg &&... arg)
279 : VclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE )
280 {
281 }
282
283 /**
284 * Override and disallow this, to prevent people accidentally calling it and actually
285 * getting VclPtr::Create and getting a naked VclPtr<> instance
286 */
287 template<typename... Arg> static VclPtrInstance< reference_type > Create(Arg &&... ) = delete;
288};
289
290template <class reference_type>
291class ScopedVclPtr : public VclPtr<reference_type>
292{
293public:
294 /** Constructor...
295 */
296 ScopedVclPtr()
297 : VclPtr<reference_type>()
298 {}
299
300 /** Constructor
301 */
302 ScopedVclPtr (reference_type * pBody)
303 : VclPtr<reference_type>(pBody)
304 {}
305
306 /** Copy constructor...
307 */
308 ScopedVclPtr (const VclPtr<reference_type> & handle)
309 : VclPtr<reference_type>(handle)
310 {}
311
312 /**
313 Assignment that releases the last reference.
314 */
315 void disposeAndReset(reference_type *pBody)
316 {
317 if (pBody != this->get()) {
318 VclPtr<reference_type>::disposeAndClear();
319 VclPtr<reference_type>::set(pBody);
320 }
321 }
322
323 /**
324 Assignment that releases the last reference.
325 */
326 ScopedVclPtr<reference_type>& operator = (reference_type * pBody)
327 {
328 disposeAndReset(pBody);
329 return *this;
330 }
331
332 /** Up-casting conversion constructor: Copies interface reference.
333
334 Does not work for up-casts to ambiguous bases. For the special case of
335 up-casting to Reference< XInterface >, see the corresponding conversion
336 operator.
337
338 @param rRef another reference
339 */
340 template< class derived_type >
341 ScopedVclPtr(
342 const VclPtr< derived_type > & rRef,
343 typename std::enable_if<
344 std::is_base_of<reference_type, derived_type>::value, int>::type
345 = 0 )
346 : VclPtr<reference_type>( rRef )
347 {
348 }
349
350 /** Up-casting assignment operator.
351
352 Does not work for up-casts to ambiguous bases.
353
354 @param rRef another VclPtr
355 */
356 template<typename derived_type>
357 typename std::enable_if<
358 std::is_base_of<reference_type, derived_type>::value,
359 ScopedVclPtr &>::type
360 operator =(VclPtr<derived_type> const & rRef)
361 {
362 disposeAndReset(rRef.get());
363 return *this;
364 }
365
366 /**
367 * Override and disallow this, to prevent people accidentally calling it and actually
368 * getting VclPtr::Create and getting a naked VclPtr<> instance
369 */
370 template<typename... Arg> static ScopedVclPtr< reference_type > Create(Arg &&... ) = delete;
371
372 ~ScopedVclPtr()
373 {
374 VclPtr<reference_type>::disposeAndClear();
375 assert(VclPtr<reference_type>::get() == nullptr)(static_cast <bool> (VclPtr<reference_type>::get(
) == nullptr) ? void (0) : __assert_fail ("VclPtr<reference_type>::get() == nullptr"
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 375, __extension__ __PRETTY_FUNCTION__))
; // make sure there are no lingering references
376 }
377
378private:
379 // Most likely we don't want this default copy-constructor.
380 ScopedVclPtr (const ScopedVclPtr<reference_type> &) = delete;
381 // And certainly we don't want a default assignment operator.
382 ScopedVclPtr<reference_type>& operator = (const ScopedVclPtr<reference_type> &) = delete;
383 // And disallow reset as that doesn't call disposeAndClear on the original reference
384 void reset() = delete;
385 void reset(reference_type *pBody) = delete;
386
387protected:
388 ScopedVclPtr (reference_type * pBody, __sal_NoAcquire)
389 : VclPtr<reference_type>(pBody, SAL_NO_ACQUIRE)
390 {}
391};
392
393/**
394 * A construction helper for ScopedVclPtr. Since VclPtr types are created
395 * with a reference-count of one - to help fit into the existing
396 * code-flow; this helps us to construct them easily.
397 *
398 * For more details on the design please see vcl/README.lifecycle
399 *
400 * @param reference_type must be a subclass of vcl::Window
401 */
402#if defined _MSC_VER
403#pragma warning(push)
404#pragma warning(disable: 4521) // " multiple copy constructors specified"
405#endif
406template <class reference_type>
407class SAL_WARN_UNUSED__attribute__((warn_unused)) ScopedVclPtrInstance final : public ScopedVclPtr<reference_type>
408{
409public:
410 template<typename... Arg> ScopedVclPtrInstance(Arg &&... arg)
411 : ScopedVclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE )
412 {
413 }
414
415 /**
416 * Override and disallow this, to prevent people accidentally calling it and actually
417 * getting VclPtr::Create and getting a naked VclPtr<> instance
418 */
419 template<typename... Arg> static ScopedVclPtrInstance< reference_type > Create(Arg &&...) = delete;
420
421private:
422 // Prevent the above perfect forwarding ctor from hijacking (accidental)
423 // attempts at ScopedVclPtrInstance copy construction (where the hijacking
424 // would typically lead to somewhat obscure error messages); both non-const
425 // and const variants are needed here, as the ScopedVclPtr base class has a
426 // const--variant copy ctor, so the implicitly declared copy ctor for
427 // ScopedVclPtrInstance would also be the const variant, so non-const copy
428 // construction attempts would be hijacked by the perfect forwarding ctor;
429 // but if we only declared a non-const variant here, the const variant would
430 // no longer be implicitly declared (as there would already be an explicitly
431 // declared copy ctor), so const copy construction attempts would then be
432 // hijacked by the perfect forwarding ctor:
433 ScopedVclPtrInstance(ScopedVclPtrInstance &) = delete;
434 ScopedVclPtrInstance(ScopedVclPtrInstance const &) = delete;
435};
436#if defined _MSC_VER
437#pragma warning(pop)
438#endif
439
440#endif // INCLUDED_VCL_PTR_HXX
441
442/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/rtl/ref.hxx

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#ifndef INCLUDED_RTL_REF_HXX
21#define INCLUDED_RTL_REF_HXX
22
23#include "sal/config.h"
24
25#include <cassert>
26#include <cstddef>
27#include <functional>
28#ifdef LIBO_INTERNAL_ONLY1
29#include <type_traits>
30#endif
31
32#include "sal/types.h"
33
34namespace rtl
35{
36
37/** Template reference class for reference type.
38*/
39template <class reference_type>
40class Reference
41{
42 /** The <b>reference_type</b> body pointer.
43 */
44 reference_type * m_pBody;
45
46
47public:
48 /** Constructor...
49 */
50 Reference()
51 : m_pBody (NULL__null)
52 {}
53
54
55 /** Constructor...
56 */
57 Reference (reference_type * pBody, __sal_NoAcquire)
58 : m_pBody (pBody)
59 {
60 }
61
62 /** Constructor...
63 */
64 Reference (reference_type * pBody)
65 : m_pBody (pBody)
66 {
67 if (m_pBody)
4
Assuming field 'm_pBody' is non-null
5
Taking true branch
68 m_pBody->acquire();
69 }
70
71 /** Copy constructor...
72 */
73 Reference (const Reference<reference_type> & handle)
74 : m_pBody (handle.m_pBody)
75 {
76 if (m_pBody)
77 m_pBody->acquire();
78 }
79
80#ifdef LIBO_INTERNAL_ONLY1
81 /** Move constructor...
82 */
83 Reference (Reference<reference_type> && handle) noexcept
84 : m_pBody (handle.m_pBody)
85 {
86 handle.m_pBody = nullptr;
87 }
88#endif
89
90#if defined LIBO_INTERNAL_ONLY1
91 /** Up-casting conversion constructor: Copies interface reference.
92
93 Does not work for up-casts to ambiguous bases.
94
95 @param rRef another reference
96 */
97 template< class derived_type >
98 inline Reference(
99 const Reference< derived_type > & rRef,
100 std::enable_if_t<std::is_base_of_v<reference_type, derived_type>, int> = 0 )
101 : m_pBody (rRef.get())
102 {
103 if (m_pBody)
104 m_pBody->acquire();
105 }
106#endif
107
108 /** Destructor...
109 */
110 ~Reference() COVERITY_NOEXCEPT_FALSE
111 {
112 if (m_pBody
9.1
Field 'm_pBody' is non-null
9.1
Field 'm_pBody' is non-null
9.1
Field 'm_pBody' is non-null
9.1
Field 'm_pBody' is non-null
)
10
Taking true branch
113 m_pBody->release();
11
Calling 'VclReferenceBase::release'
15
Returning; memory was released
114 }
115
116 /** Set...
117 Similar to assignment.
118 */
119 Reference<reference_type> &
120 SAL_CALL set (reference_type * pBody)
121 {
122 if (pBody)
123 pBody->acquire();
124 reference_type * const pOld = m_pBody;
125 m_pBody = pBody;
126 if (pOld)
127 pOld->release();
128 return *this;
129 }
130
131 /** Assignment.
132 Unbinds this instance from its body (if bound) and
133 bind it to the body represented by the handle.
134 */
135 Reference<reference_type> &
136 SAL_CALL operator= (const Reference<reference_type> & handle)
137 {
138 return set( handle.m_pBody );
139 }
140
141#ifdef LIBO_INTERNAL_ONLY1
142 /** Assignment.
143 * Unbinds this instance from its body (if bound),
144 * bind it to the body represented by the handle, and
145 * set the body represented by the handle to nullptr.
146 */
147 Reference<reference_type> &
148 operator= (Reference<reference_type> && handle)
149 {
150 // self-movement guts ourself
151 if (m_pBody)
152 m_pBody->release();
153 m_pBody = handle.m_pBody;
154 handle.m_pBody = nullptr;
155 return *this;
156 }
157#endif
158
159 /** Assignment...
160 */
161 Reference<reference_type> &
162 SAL_CALL operator= (reference_type * pBody)
163 {
164 return set( pBody );
165 }
166
167 /** Unbind the body from this handle.
168 Note that for a handle representing a large body,
169 "handle.clear().set(new body());" _might_
170 perform a little bit better than "handle.set(new body());",
171 since in the second case two large objects exist in memory
172 (the old body and the new body).
173 */
174 Reference<reference_type> & SAL_CALL clear()
175 {
176 if (m_pBody)
177 {
178 reference_type * const pOld = m_pBody;
179 m_pBody = NULL__null;
180 pOld->release();
181 }
182 return *this;
183 }
184
185
186 /** Get the body. Can be used instead of operator->().
187 I.e. handle->someBodyOp() and handle.get()->someBodyOp()
188 are the same.
189 */
190 reference_type * SAL_CALL get() const
191 {
192 return m_pBody;
20
Use of memory after it is freed
193 }
194
195
196 /** Probably most common used: handle->someBodyOp().
197 */
198 reference_type * SAL_CALL operator->() const
199 {
200 assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail
("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx"
, 200, __extension__ __PRETTY_FUNCTION__))
;
201 return m_pBody;
202 }
203
204
205 /** Allows (*handle).someBodyOp().
206 */
207 reference_type & SAL_CALL operator*() const
208 {
209 assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail
("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx"
, 209, __extension__ __PRETTY_FUNCTION__))
;
210 return *m_pBody;
211 }
212
213
214 /** Returns True if the handle does point to a valid body.
215 */
216 bool SAL_CALL is() const
217 {
218 return (m_pBody != NULL__null);
219 }
220
221#if defined LIBO_INTERNAL_ONLY1
222 /** Returns True if the handle does point to a valid body.
223 */
224 explicit operator bool() const
225 {
226 return is();
227 }
228#endif
229
230 /** Returns True if this points to pBody.
231 */
232 bool SAL_CALL operator== (const reference_type * pBody) const
233 {
234 return (m_pBody == pBody);
235 }
236
237
238 /** Returns True if handle points to the same body.
239 */
240 bool
241 SAL_CALL operator== (const Reference<reference_type> & handle) const
242 {
243 return (m_pBody == handle.m_pBody);
244 }
245
246
247 /** Needed to place References into STL collection.
248 */
249 bool
250 SAL_CALL operator!= (const Reference<reference_type> & handle) const
251 {
252 return (m_pBody != handle.m_pBody);
253 }
254
255
256 /** Needed to place References into STL collection.
257 */
258 bool
259 SAL_CALL operator< (const Reference<reference_type> & handle) const
260 {
261 return (m_pBody < handle.m_pBody);
262 }
263
264
265 /** Needed to place References into STL collection.
266 */
267 bool
268 SAL_CALL operator> (const Reference<reference_type> & handle) const
269 {
270 return (m_pBody > handle.m_pBody);
271 }
272};
273
274} // namespace rtl
275
276#if defined LIBO_INTERNAL_ONLY1
277namespace std
278{
279
280/// @cond INTERNAL
281/**
282 Make rtl::Reference hashable by default for use in STL containers.
283
284 @since LibreOffice 6.3
285*/
286template<typename T>
287struct hash<::rtl::Reference<T>>
288{
289 std::size_t operator()(::rtl::Reference<T> const & s) const
290 { return std::size_t(s.get()); }
291};
292/// @endcond
293
294}
295
296#endif
297
298#endif /* ! INCLUDED_RTL_REF_HXX */
299
300/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/vcl/vclreferencebase.hxx

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#ifndef INCLUDED_VCL_Reference_HXX
20#define INCLUDED_VCL_Reference_HXX
21
22#include <vcl/dllapi.h>
23#include <osl/interlck.h>
24
25class VCL_DLLPUBLIC__attribute__ ((visibility("default"))) VclReferenceBase
26{
27 mutable oslInterlockedCount mnRefCnt;
28
29 template<typename T> friend class VclPtr;
30
31public:
32 void acquire() const
33 {
34 osl_atomic_increment(&mnRefCnt)__sync_add_and_fetch((&mnRefCnt), 1);
35 }
36
37 void release() const
38 {
39 if (osl_atomic_decrement(&mnRefCnt)__sync_sub_and_fetch((&mnRefCnt), 1) == 0)
12
Assuming the condition is true
13
Taking true branch
40 delete this;
14
Memory is released
41 }
42#ifdef DBG_UTIL
43#ifndef _WIN32
44 sal_Int32 getRefCount() const { return mnRefCnt; }
45#endif
46#endif
47
48
49private:
50 VclReferenceBase(const VclReferenceBase&) = delete;
51 VclReferenceBase& operator=(const VclReferenceBase&) = delete;
52
53 bool mbDisposed : 1;
54
55protected:
56 VclReferenceBase();
57protected:
58 virtual ~VclReferenceBase();
59
60protected:
61 virtual void dispose();
62
63public:
64 void disposeOnce();
65 bool isDisposed() const { return mbDisposed; }
66
67};
68#endif