/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * 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/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
type_entry * getTypeEntries( class_data * cd )
{
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--; )
{
type_entry * pEntry = &pEntries[ n ];
Type const & rType = (*pEntry->m_type.getCppuType)( nullptr );
OSL_ENSURE( rType.getTypeClass() == TypeClass_INTERFACE, "### wrong helper init: expected interface!" );
OSL_ENSURE( ! isXInterface( rType.getTypeLibType()->pTypeName ), "### want to implement XInterface: template argument is XInterface?!?!?!" ); if (rType.getTypeClass() != TypeClass_INTERFACE)
{
OUString msg( "type \"" + rType.getTypeName() + "\" is no interface type!" );
SAL_WARN( "cppuhelper", msg ); throw 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;
}
staticvoid fillTypes( Type * types, class_data * cd )
{
type_entry * pEntries = getTypeEntries( cd ); for ( sal_Int32 n = cd->m_nTypes; n--; )
{
types[ n ] = pEntries[ n ].m_type.typeRef;
}
}
namespace {
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))
{ returntrue;
} // 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)) { returntrue;
}
}
} returnfalse;
}
// 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) + "an>\"!" );
SAL_WARN( "cppuhelper", msg ); throw RuntimeException( msg );
}
} return nullptr;
}
// ImplHelper
Any SAL_CALL ImplHelper_query(
Type const & rType, class_data * cd, void * that )
{
checkInterface( rType );
typelib_TypeDescriptionReference * pTDR = rType.getTypeLibType();
void * p; // shortcut for XInterface if (isXInterface( pTDR->pTypeName ))
{ // take first one
p = makeInterface( cd->m_typeEntries[ 0 ].m_offset, that );
} else
{
p = queryDeepNoXInterface( pTDR, cd, that ); if (! p)
{ return Any();
}
} return Any( &p, pTDR );
}
Any SAL_CALL ImplHelper_queryNoXInterface(
Type const & rType, class_data * cd, void * that )
{
checkInterface( rType );
typelib_TypeDescriptionReference * pTDR = rType.getTypeLibType();
void * p = queryDeepNoXInterface( pTDR, cd, that ); if (p)
{ return Any( &p, pTDR );
} return Any();
}
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 ist noch experimentell.