blob: 82d7df9bbba6e35fabf376e4ab563b66f64f69e9 [file] [log] [blame]
/**************************************************************
*
* 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
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_stoc.hxx"
#include <osl/diagnose.h>
#include <rtl/ustrbuf.hxx>
#include "registry/reader.hxx"
#include "registry/version.h"
#include <com/sun/star/reflection/XInterfaceMemberTypeDescription.hpp>
#include <com/sun/star/reflection/XInterfaceAttributeTypeDescription2.hpp>
#include <com/sun/star/reflection/XInterfaceMethodTypeDescription.hpp>
#include <com/sun/star/reflection/XMethodParameter.hpp>
#include <com/sun/star/reflection/XParameter.hpp>
#include "com/sun/star/uno/RuntimeException.hpp"
#include "base.hxx"
#include "functiondescription.hxx"
#include "methoddescription.hxx"
#include <memory>
#include <set>
namespace stoc_rdbtdp
{
//==================================================================================================
class InterfaceMethodImpl : public WeakImplHelper1< XInterfaceMethodTypeDescription >
{
stoc::registry_tdprovider::MethodDescription _desc;
Reference< XHierarchicalNameAccess > _xTDMgr;
OUString _aTypeName;
OUString _aReturnType;
Reference< XTypeDescription > _xReturnTD;
sal_Bool _bIsOneWay;
sal_Int32 _nPosition;
public:
InterfaceMethodImpl( const Reference< XHierarchicalNameAccess > & xTDMgr,
const OUString & rTypeName,
const OUString & rMemberName,
const OUString & rReturnType,
const Sequence< sal_Int8 > & rBytes,
sal_uInt16 nMethodIndex,
sal_Bool bIsOneWay,
sal_Int32 nPosition )
: _desc(xTDMgr, rMemberName, rBytes, nMethodIndex)
, _xTDMgr( xTDMgr )
, _aTypeName( rTypeName )
, _aReturnType( rReturnType )
, _bIsOneWay( bIsOneWay )
, _nPosition( nPosition )
{
g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
}
virtual ~InterfaceMethodImpl();
// XTypeDescription
virtual TypeClass SAL_CALL getTypeClass() throw(::com::sun::star::uno::RuntimeException);
virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException);
// XInterfaceMemberTypeDescription
virtual OUString SAL_CALL getMemberName() throw(::com::sun::star::uno::RuntimeException)
{ return _desc.getName(); }
virtual sal_Int32 SAL_CALL getPosition() throw(::com::sun::star::uno::RuntimeException);
// XInterfaceMethodTypeDescription
virtual Reference< XTypeDescription > SAL_CALL getReturnType() throw(::com::sun::star::uno::RuntimeException);
virtual sal_Bool SAL_CALL isOneway() throw(::com::sun::star::uno::RuntimeException);
virtual Sequence< Reference< XMethodParameter > > SAL_CALL getParameters() throw(::com::sun::star::uno::RuntimeException);
virtual Sequence< Reference< XTypeDescription > > SAL_CALL getExceptions() throw(::com::sun::star::uno::RuntimeException);
};
//__________________________________________________________________________________________________
InterfaceMethodImpl::~InterfaceMethodImpl()
{
g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
}
// XTypeDescription
//__________________________________________________________________________________________________
TypeClass InterfaceMethodImpl::getTypeClass()
throw(::com::sun::star::uno::RuntimeException)
{
return TypeClass_INTERFACE_METHOD;
}
//__________________________________________________________________________________________________
OUString InterfaceMethodImpl::getName()
throw(::com::sun::star::uno::RuntimeException)
{
return _aTypeName;
}
// XInterfaceMemberTypeDescription
//__________________________________________________________________________________________________
sal_Int32 InterfaceMethodImpl::getPosition()
throw(::com::sun::star::uno::RuntimeException)
{
return _nPosition;
}
// XInterfaceMethodTypeDescription
//__________________________________________________________________________________________________
Reference<XTypeDescription > InterfaceMethodImpl::getReturnType()
throw(::com::sun::star::uno::RuntimeException)
{
if (!_xReturnTD.is() && _aReturnType.getLength())
{
try
{
Reference< XTypeDescription > xReturnTD;
if (_xTDMgr->getByHierarchicalName( _aReturnType ) >>= xReturnTD)
{
MutexGuard aGuard( getMutex() );
if (! _xReturnTD.is())
_xReturnTD = xReturnTD;
return _xReturnTD;
}
}
catch (NoSuchElementException &)
{
}
// never try again, if no td was found
_aReturnType = OUString();
}
return _xReturnTD;
}
//__________________________________________________________________________________________________
sal_Bool InterfaceMethodImpl::isOneway()
throw(::com::sun::star::uno::RuntimeException)
{
return _bIsOneWay;
}
//__________________________________________________________________________________________________
Sequence<Reference<XMethodParameter > > InterfaceMethodImpl::getParameters()
throw(::com::sun::star::uno::RuntimeException)
{
Sequence< Reference< XParameter > > s1(_desc.getParameters());
Sequence< Reference< XMethodParameter > > s2(s1.getLength());
for (sal_Int32 i = 0; i < s1.getLength(); ++i) {
s2[i] = s1[i].get();
}
return s2;
}
//__________________________________________________________________________________________________
Sequence<Reference<XTypeDescription > > InterfaceMethodImpl::getExceptions()
throw(::com::sun::star::uno::RuntimeException)
{
Sequence< Reference< XCompoundTypeDescription > > s1(
_desc.getExceptions());
Sequence< Reference< XTypeDescription > > s2(s1.getLength());
for (sal_Int32 i = 0; i < s1.getLength(); ++i) {
s2[i] = s1[i].get();
}
return s2;
}
//##################################################################################################
//##################################################################################################
//##################################################################################################
//==================================================================================================
class InterfaceAttributeImpl : public WeakImplHelper1< XInterfaceAttributeTypeDescription2 >
{
Reference< XHierarchicalNameAccess > _xTDMgr;
OUString _aTypeName;
OUString _aMemberName;
OUString _aMemberTypeName;
Reference< XTypeDescription > _xMemberTD;
sal_Bool _bReadOnly;
sal_Bool _bBound;
sal_Int32 _nPosition;
std::auto_ptr< stoc::registry_tdprovider::FunctionDescription > _getter;
std::auto_ptr< stoc::registry_tdprovider::FunctionDescription > _setter;
public:
InterfaceAttributeImpl(
const Reference< XHierarchicalNameAccess > & xTDMgr,
const OUString & rTypeName,
const OUString & rMemberName,
const OUString & rMemberTypeName,
sal_Bool bReadOnly,
sal_Bool bBound,
std::auto_ptr< stoc::registry_tdprovider::FunctionDescription > &
getter,
std::auto_ptr< stoc::registry_tdprovider::FunctionDescription > &
setter,
sal_Int32 nPosition )
: _xTDMgr( xTDMgr )
, _aTypeName( rTypeName )
, _aMemberName( rMemberName )
, _aMemberTypeName( rMemberTypeName )
, _bReadOnly( bReadOnly )
, _bBound( bBound )
, _nPosition( nPosition )
, _getter( getter )
, _setter( setter )
{
g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
}
virtual ~InterfaceAttributeImpl();
// XTypeDescription
virtual TypeClass SAL_CALL getTypeClass() throw(::com::sun::star::uno::RuntimeException);
virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException);
// XInterfaceMemberTypeDescription
virtual OUString SAL_CALL getMemberName() throw(::com::sun::star::uno::RuntimeException);
virtual sal_Int32 SAL_CALL getPosition() throw(::com::sun::star::uno::RuntimeException);
// XInterfaceAttributeTypeDescription2
virtual sal_Bool SAL_CALL isReadOnly() throw(::com::sun::star::uno::RuntimeException);
virtual Reference< XTypeDescription > SAL_CALL getType() throw(::com::sun::star::uno::RuntimeException);
virtual sal_Bool SAL_CALL isBound() throw (RuntimeException)
{ return _bBound; }
virtual Sequence< Reference< XCompoundTypeDescription > > SAL_CALL
getGetExceptions() throw (RuntimeException)
{
if (_getter.get() != 0) {
return _getter->getExceptions();
} else {
return Sequence< Reference< XCompoundTypeDescription > >();
}
}
virtual Sequence< Reference< XCompoundTypeDescription > > SAL_CALL
getSetExceptions() throw (RuntimeException)
{
if (_setter.get() != 0) {
return _setter->getExceptions();
} else {
return Sequence< Reference< XCompoundTypeDescription > >();
}
}
};
InterfaceAttributeImpl::~InterfaceAttributeImpl()
{
g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
}
// XTypeDescription
//__________________________________________________________________________________________________
TypeClass InterfaceAttributeImpl::getTypeClass()
throw(::com::sun::star::uno::RuntimeException)
{
return TypeClass_INTERFACE_ATTRIBUTE;
}
//__________________________________________________________________________________________________
OUString InterfaceAttributeImpl::getName()
throw(::com::sun::star::uno::RuntimeException)
{
return _aTypeName;
}
// XInterfaceMemberTypeDescription
//__________________________________________________________________________________________________
OUString InterfaceAttributeImpl::getMemberName()
throw(::com::sun::star::uno::RuntimeException)
{
return _aMemberName;
}
//__________________________________________________________________________________________________
sal_Int32 InterfaceAttributeImpl::getPosition()
throw(::com::sun::star::uno::RuntimeException)
{
return _nPosition;
}
// XInterfaceAttributeTypeDescription2
//__________________________________________________________________________________________________
sal_Bool InterfaceAttributeImpl::isReadOnly()
throw(::com::sun::star::uno::RuntimeException)
{
return _bReadOnly;
}
//__________________________________________________________________________________________________
Reference<XTypeDescription > InterfaceAttributeImpl::getType()
throw(::com::sun::star::uno::RuntimeException)
{
if (!_xMemberTD.is() && _aMemberTypeName.getLength())
{
try
{
Reference< XTypeDescription > xMemberTD;
if (_xTDMgr->getByHierarchicalName( _aMemberTypeName ) >>= xMemberTD)
{
MutexGuard aGuard( getMutex() );
if (! _xMemberTD.is())
_xMemberTD = xMemberTD;
return _xMemberTD;
}
}
catch (NoSuchElementException &)
{
}
// never try again, if no td was found
_aMemberTypeName = OUString();
}
return _xMemberTD;
}
//##################################################################################################
//##################################################################################################
//##################################################################################################
void InterfaceTypeDescriptionImpl::checkInterfaceType(
Reference< XTypeDescription > const & type)
{
if (resolveTypedefs(type)->getTypeClass() != TypeClass_INTERFACE) {
throw RuntimeException(
OUString(
RTL_CONSTASCII_USTRINGPARAM(
"Interface base is not an interface type")),
static_cast< OWeakObject * >(this));
}
}
namespace {
class BaseOffset {
public:
BaseOffset(Reference< XInterfaceTypeDescription2 > const & desc);
sal_Int32 get() const { return offset; }
private:
void calculateBases(Reference< XInterfaceTypeDescription2 > const & desc);
void calculate(Reference< XInterfaceTypeDescription2 > const & desc);
std::set< rtl::OUString > set;
sal_Int32 offset;
};
BaseOffset::BaseOffset(Reference< XInterfaceTypeDescription2 > const & desc) {
offset = 0;
calculateBases(desc);
}
void BaseOffset::calculateBases(
Reference< XInterfaceTypeDescription2 > const & desc)
{
Sequence< Reference < XTypeDescription > > bases(desc->getBaseTypes());
for (sal_Int32 i = 0; i < bases.getLength(); ++i) {
calculate(
Reference< XInterfaceTypeDescription2 >(
resolveTypedefs(bases[i]), UNO_QUERY_THROW));
}
}
void BaseOffset::calculate(Reference< XInterfaceTypeDescription2 > const & desc)
{
if (set.insert(desc->getName()).second) {
calculateBases(desc);
offset += desc->getMembers().getLength();
}
}
}
//__________________________________________________________________________________________________
InterfaceTypeDescriptionImpl::InterfaceTypeDescriptionImpl(
const Reference< XHierarchicalNameAccess > & xTDMgr,
const OUString & rName, const Sequence< OUString > & rBaseTypes,
const Sequence< OUString > & rOptionalBaseTypes,
const Sequence< sal_Int8 > & rBytes, bool published )
: _xTDMgr( xTDMgr )
, _aBytes( rBytes )
, _aName( rName )
, _aBaseTypes( rBaseTypes )
, _aOptionalBaseTypes( rOptionalBaseTypes )
, _membersInit( false )
, _published( published )
{
g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
}
//__________________________________________________________________________________________________
InterfaceTypeDescriptionImpl::~InterfaceTypeDescriptionImpl()
{
g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
}
// XTypeDescription
//__________________________________________________________________________________________________
TypeClass InterfaceTypeDescriptionImpl::getTypeClass()
throw(::com::sun::star::uno::RuntimeException)
{
return TypeClass_INTERFACE;
}
//__________________________________________________________________________________________________
OUString InterfaceTypeDescriptionImpl::getName()
throw(::com::sun::star::uno::RuntimeException)
{
return _aName;
}
// XInterfaceTypeDescription2
//__________________________________________________________________________________________________
Reference< XTypeDescription > InterfaceTypeDescriptionImpl::getBaseType()
throw(::com::sun::star::uno::RuntimeException)
{
Sequence< Reference< XTypeDescription > > aBaseTypes(getBaseTypes());
return aBaseTypes.getLength() >= 1 ? aBaseTypes[0] : 0;
}
//__________________________________________________________________________________________________
Uik SAL_CALL InterfaceTypeDescriptionImpl::getUik()
throw(::com::sun::star::uno::RuntimeException)
{
return Uik();
}
//__________________________________________________________________________________________________
Sequence< Reference< XInterfaceMemberTypeDescription > > InterfaceTypeDescriptionImpl::getMembers()
throw(::com::sun::star::uno::RuntimeException)
{
osl::MutexGuard guard(getMutex());
if (!_membersInit) {
_nBaseOffset = BaseOffset(this).get();
typereg::Reader reader(
_aBytes.getConstArray(), _aBytes.getLength(), false,
TYPEREG_VERSION_1);
sal_Int32 count = 0;
sal_uInt16 methodCount = reader.getMethodCount();
{for (sal_uInt16 i = 0; i < methodCount; ++i) {
RTMethodMode flags = reader.getMethodFlags(i);
if (flags != RT_MODE_ATTRIBUTE_GET
&& flags != RT_MODE_ATTRIBUTE_SET)
{
++count;
}
}}
sal_uInt16 fieldCount = reader.getFieldCount();
count += fieldCount;
_members.realloc(count);
sal_Int32 index = 0;
{for (sal_uInt16 i = 0; i < fieldCount; ++i) {
rtl::OUString name(reader.getFieldName(i));
rtl::OUStringBuffer typeName(getName());
typeName.appendAscii(RTL_CONSTASCII_STRINGPARAM("::"));
typeName.append(name);
RTFieldAccess flags = reader.getFieldFlags(i);
std::auto_ptr< stoc::registry_tdprovider::FunctionDescription >
getter;
std::auto_ptr< stoc::registry_tdprovider::FunctionDescription >
setter;
for (sal_uInt16 j = 0; j < methodCount; ++j) {
if (reader.getMethodName(j) == name) {
switch (reader.getMethodFlags(j)) {
case RT_MODE_ATTRIBUTE_GET:
OSL_ASSERT(getter.get() == 0);
getter.reset(
new stoc::registry_tdprovider::FunctionDescription(
_xTDMgr, _aBytes, j));
break;
case RT_MODE_ATTRIBUTE_SET:
OSL_ASSERT(setter.get() == 0);
setter.reset(
new stoc::registry_tdprovider::FunctionDescription(
_xTDMgr, _aBytes, j));
break;
default:
OSL_ASSERT(false);
break;
}
}
}
_members[index] = new InterfaceAttributeImpl(
_xTDMgr, typeName.makeStringAndClear(), name,
reader.getFieldTypeName(i).replace('/', '.'),
(flags & RT_ACCESS_READONLY) != 0,
(flags & RT_ACCESS_BOUND) != 0, getter, setter,
_nBaseOffset + index);
++index;
}}
{for (sal_uInt16 i = 0; i < methodCount; ++i) {
RTMethodMode flags = reader.getMethodFlags(i);
if (flags != RT_MODE_ATTRIBUTE_GET
&& flags != RT_MODE_ATTRIBUTE_SET)
{
rtl::OUString name(reader.getMethodName(i));
rtl::OUStringBuffer typeName(getName());
typeName.appendAscii(RTL_CONSTASCII_STRINGPARAM("::"));
typeName.append(name);
_members[index] = new InterfaceMethodImpl(
_xTDMgr, typeName.makeStringAndClear(), name,
reader.getMethodReturnTypeName(i).replace('/', '.'),
_aBytes, i, flags == RT_MODE_ONEWAY, _nBaseOffset + index);
++index;
}
}}
_membersInit = true;
}
return _members;
}
Sequence< Reference< XTypeDescription > >
InterfaceTypeDescriptionImpl::getBaseTypes() throw (RuntimeException) {
MutexGuard guard(getMutex());
if (_xBaseTDs.getLength() == 0 && _aBaseTypes.getLength() != 0) {
Sequence< Reference< XTypeDescription > > tds(_aBaseTypes.getLength());
for (sal_Int32 i = 0; i < _aBaseTypes.getLength(); ++i) {
try {
_xTDMgr->getByHierarchicalName(_aBaseTypes[i]) >>= tds[i];
} catch (NoSuchElementException & e) {
throw RuntimeException(
(OUString(
RTL_CONSTASCII_USTRINGPARAM(
"com.sun.star.container.NoSuchElementException: "))
+ e.Message),
static_cast< OWeakObject * >(this));
}
OSL_ASSERT(tds[i].is());
checkInterfaceType(tds[i]);
}
_xBaseTDs = tds;
}
return _xBaseTDs;
}
Sequence< Reference< XTypeDescription > >
InterfaceTypeDescriptionImpl::getOptionalBaseTypes() throw (RuntimeException) {
MutexGuard guard(getMutex());
if (_xOptionalBaseTDs.getLength() == 0
&& _aOptionalBaseTypes.getLength() != 0)
{
Sequence< Reference< XTypeDescription > > tds(
_aOptionalBaseTypes.getLength());
for (sal_Int32 i = 0; i < _aOptionalBaseTypes.getLength(); ++i) {
try {
_xTDMgr->getByHierarchicalName(_aOptionalBaseTypes[i])
>>= tds[i];
} catch (NoSuchElementException & e) {
throw RuntimeException(
(OUString(
RTL_CONSTASCII_USTRINGPARAM(
"com.sun.star.container.NoSuchElementException: "))
+ e.Message),
static_cast< OWeakObject * >(this));
}
OSL_ASSERT(tds[i].is());
checkInterfaceType(tds[i]);
}
_xOptionalBaseTDs = tds;
}
return _xOptionalBaseTDs;
}
}