Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/LibreOffice/comphelper/source/misc/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 9 kB image not shown  

Quelle  compbase.cxx   Sprache: C

 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */


#include <comphelper/compbase.hxx>
#include <cppuhelper/queryinterface.hxx>
#include <sal/log.hxx>
#include <osl/diagnose.h>

namespace comphelper
{
WeakComponentImplHelperBase::~WeakComponentImplHelperBase() {}

// css::lang::XComponent
void SAL_CALL WeakComponentImplHelperBase::dispose()
{
    std::unique_lock aGuard(m_aMutex);
    if (m_bDisposed)
        return;
    m_bDisposed = true;
    disposing(aGuard);
    if (!aGuard.owns_lock())
        aGuard.lock();
    css::lang::EventObject aEvt(static_cast<OWeakObject*>(this));
    maEventListeners.disposeAndClear(aGuard, aEvt);
}

// This is only called from the destructor to do cleanup that
// might not have occurred
void WeakComponentImplHelperBase::disposeOnDestruct()
{
    std::unique_lock aGuard(m_aMutex);
    assert(m_refCount == 0 && "only supposed to be called from the destructor");
    if (m_bDisposed)
        return;
    m_bDisposed = true;
    // bump the ref-count so we don't accidentally do a double delete
    // if something else increases and then decreases our ref-count
    cppu::OWeakObject::acquire();
    disposing(aGuard);
}

void WeakComponentImplHelperBase::disposing(std::unique_lock<std::mutex>&) {}

void SAL_CALL WeakComponentImplHelperBase::addEventListener(
    css::uno::Reference<css::lang::XEventListener> const& rxListener)
{
    std::unique_lock aGuard(m_aMutex);
    if (m_bDisposed)
        return;
    maEventListeners.addInterface(aGuard, rxListener);
}

void SAL_CALL WeakComponentImplHelperBase::removeEventListener(
    css::uno::Reference<css::lang::XEventListener> const& rxListener)
{
    std::unique_lock aGuard(m_aMutex);
    maEventListeners.removeInterface(aGuard, rxListener);
}

css::uno::Any SAL_CALL WeakComponentImplHelperBase::queryInterface(css::uno::Type const& rType)
{
    css::uno::Any aReturn = ::cppu::queryInterface(rType, static_cast<css::uno::XWeak*>(this),
                                                   static_cast<css::lang::XComponent*>(this));
    if (aReturn.hasValue())
        return aReturn;
    return OWeakObject::queryInterface(rType);
}

static void checkInterface(css::uno::Type const& rType)
{
    if (css::uno::TypeClass_INTERFACE != rType.getTypeClass())
    {
        OUString msg("querying for interface \"" + rType.getTypeName() + "\": no interface type!");
        SAL_WARN("cppuhelper", msg);
        throw css::uno::RuntimeException(msg);
    }
}

static bool isXInterface(rtl_uString* pStr)
{
    return OUString::unacquired(&pStr) == "com.sun.star.uno.XInterface";
}

static bool td_equals(typelib_TypeDescriptionReference const* pTDR1,
                      typelib_TypeDescriptionReference const* pTDR2)
{
    return ((pTDR1 == pTDR2)
            || OUString::unacquired(&pTDR1->pTypeName) == OUString::unacquired(&pTDR2->pTypeName));
}

static cppu::type_entry* getTypeEntries(cppu::class_data* cd)
{
    cppu::type_entry* pEntries = cd->m_typeEntries;
    if (!cd->m_storedTypeRefs) // not inited?
    {
        static std::mutex aMutex;
        std::scoped_lock guard(aMutex);
        if (!cd->m_storedTypeRefs) // not inited?
        {
            // get all types
            for (sal_Int32 n = cd->m_nTypes; n--;)
            {
                cppu::type_entry* pEntry = &pEntries[n];
                css::uno::Type const& rType = (*pEntry->m_type.getCppuType)(nullptr);
                OSL_ENSURE(rType.getTypeClass() == css::uno::TypeClass_INTERFACE,
                           "### wrong helper init: expected interface!");
                OSL_ENSURE(
                    !isXInterface(rType.getTypeLibType()->pTypeName),
                    "### want to implement XInterface: template argument is XInterface?!?!?!");
                if (rType.getTypeClass() != css::uno::TypeClass_INTERFACE)
                {
                    OUString msg("type \"" + rType.getTypeName() + "\" is no interface type!");
                    SAL_WARN("cppuhelper", msg);
                    throw css::uno::RuntimeException(msg);
                }
                // ref is statically held by getCppuType()
                pEntry->m_type.typeRef = rType.getTypeLibType();
            }
            OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
            cd->m_storedTypeRefs = true;
        }
    }
    else
    {
        OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
    }
    return pEntries;
}

static void* makeInterface(sal_IntPtr nOffset, void* that)
{
    return (static_cast<char*>(that) + nOffset);
}

static bool recursivelyFindType(typelib_TypeDescriptionReference const* demandedType,
                                typelib_InterfaceTypeDescription const* type, sal_IntPtr* offset)
{
    // This code assumes that the vtables of a multiple-inheritance class (the
    // offset amount by which to adjust the this pointer) follow one another in
    // the object layout, and that they contain slots for the inherited classes
    // in a specific order.  In theory, that need not hold for any given
    // platform; in practice, it seems to work well on all supported platforms:
next:
    for (sal_Int32 i = 0; i < type->nBaseTypes; ++i)
    {
        if (i > 0)
        {
            *offset += sizeof(void*);
        }
        typelib_InterfaceTypeDescription const* base = type->ppBaseTypes[i];
        // ignore XInterface:
        if (base->nBaseTypes > 0)
        {
            if (td_equals(reinterpret_cast<typelib_TypeDescriptionReference const*>(base),
                          demandedType))
            {
                return true;
            }
            // Profiling showed that it is important to speed up the common case
            // of only one base:
            if (type->nBaseTypes == 1)
            {
                type = base;
                goto next;
            }
            if (recursivelyFindType(demandedType, base, offset))
            {
                return true;
            }
        }
    }
    return false;
}

static void* queryDeepNoXInterface(typelib_TypeDescriptionReference const* pDemandedTDR,
                                   cppu::class_data* cd, void* that)
{
    cppu::type_entry* pEntries = getTypeEntries(cd);
    sal_Int32 nTypes = cd->m_nTypes;
    sal_Int32 n;

    // try top interfaces without getting td
    for (n = 0; n < nTypes; ++n)
    {
        if (td_equals(pEntries[n].m_type.typeRef, pDemandedTDR))
        {
            return makeInterface(pEntries[n].m_offset, that);
        }
    }
    // query deep getting td
    for (n = 0; n < nTypes; ++n)
    {
        typelib_TypeDescription* pTD = nullptr;
        TYPELIB_DANGER_GET(&pTD, pEntries[n].m_type.typeRef);
        if (pTD)
        {
            // exclude top (already tested) and bottom (XInterface) interface
            OSL_ENSURE(reinterpret_cast<typelib_InterfaceTypeDescription*>(pTD)->nBaseTypes > 0,
                       "### want to implement XInterface:"
                       " template argument is XInterface?!?!?!");
            sal_IntPtr offset = pEntries[n].m_offset;
            bool found = recursivelyFindType(
                pDemandedTDR, reinterpret_cast<typelib_InterfaceTypeDescription*>(pTD), &offset);
            TYPELIB_DANGER_RELEASE(pTD);
            if (found)
            {
                return makeInterface(offset, that);
            }
        }
        else
        {
            OUString msg("cannot get type description for type \""
                         + OUString::unacquired(&pEntries[n].m_type.typeRef->pTypeName) + "\"!");
            SAL_WARN("cppuhelper", msg);
            throw css::uno::RuntimeException(msg);
        }
    }
    return nullptr;
}

css::uno::Any WeakComponentImplHelper_query(css::uno::Type const& rType, cppu::class_data* cd,
                                            WeakComponentImplHelperBase* pBase)
{
    checkInterface(rType);
    typelib_TypeDescriptionReference* pTDR = rType.getTypeLibType();

    // shortcut XInterface to WeakComponentImplHelperBase
    if (!isXInterface(pTDR->pTypeName))
    {
        void* p = queryDeepNoXInterface(pTDR, cd, pBase);
        if (p)
        {
            return css::uno::Any(&p, pTDR);
        }
    }
    return pBase->comphelper::WeakComponentImplHelperBase::queryInterface(rType);
}

WeakImplHelperBase::~WeakImplHelperBase() {}

css::uno::Any SAL_CALL WeakImplHelperBase::queryInterface(css::uno::Type constrType)
{
    css::uno::Any aReturn = ::cppu::queryInterface(rType, static_cast<css::uno::XWeak*>(this));
    if (aReturn.hasValue())
        return aReturn;
    return OWeakObject::queryInterface(rType);
}

css::uno::Any WeakImplHelper_query(css::uno::Type const& rType, cppu::class_data* cd,
                                   WeakImplHelperBase* pBase)
{
    checkInterface(rType);
    typelib_TypeDescriptionReference* pTDR = rType.getTypeLibType();

    // shortcut XInterface to WeakComponentImplHelperBase
    if (!isXInterface(pTDR->pTypeName))
    {
        void* p = queryDeepNoXInterface(pTDR, cd, pBase);
        if (p)
        {
            return css::uno::Any(&p, pTDR);
        }
    }
    return pBase->comphelper::WeakImplHelperBase::queryInterface(rType);
}

// namespace comphelper

/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */

Messung V0.5
C=93 H=90 G=91

¤ Dauer der Verarbeitung: 0.12 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.