blob: 755bb4b05e977e69b765ba53eadf38d87d87ae34 [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.
*
*************************************************************/
#include <rtl/alloc.h>
#ifndef __REGISTRY_REFLWRIT_HXX__
#include <registry/reflwrit.hxx>
#endif
#include <cppuhelper/servicefactory.hxx>
#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
#include <com/sun/star/reflection/XInterfaceTypeDescription.hpp>
#include <com/sun/star/reflection/XConstantsTypeDescription.hpp>
#include <com/sun/star/reflection/XConstantTypeDescription.hpp>
#include <com/sun/star/reflection/XModuleTypeDescription.hpp>
#include <com/sun/star/reflection/XInterfaceMethodTypeDescription.hpp>
#include <com/sun/star/reflection/XInterfaceAttributeTypeDescription.hpp>
#include <com/sun/star/reflection/XMethodParameter.hpp>
#include <com/sun/star/reflection/XCompoundTypeDescription.hpp>
#include <com/sun/star/reflection/XIndirectTypeDescription.hpp>
#include <com/sun/star/reflection/XEnumTypeDescription.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/uno/XComponentContext.hpp>
#include <codemaker/global.hxx>
using namespace com::sun::star;
using namespace com::sun::star::uno;
using namespace com::sun::star::reflection;
using namespace com::sun::star::lang;
using namespace com::sun::star::container;
using namespace cppu;
//using namespace osl;
using namespace rtl;
static Reference< XHierarchicalNameAccess > xNameAccess;
void writeConstantData( RegistryTypeWriter& rWriter, sal_uInt16 fieldIndex,
const Reference< XConstantTypeDescription >& xConstant)
{
RTConstValue constValue;
OUString uConstTypeName;
OUString uConstName = xConstant->getName();
Any aConstantAny = xConstant->getConstantValue();
switch ( aConstantAny.getValueTypeClass() )
{
case TypeClass_BOOLEAN:
{
uConstTypeName = OUString( RTL_CONSTASCII_USTRINGPARAM("boolean") );
constValue.m_type = RT_TYPE_BOOL;
aConstantAny >>= constValue.m_value.aBool;
}
break;
case TypeClass_BYTE:
{
uConstTypeName = OUString( RTL_CONSTASCII_USTRINGPARAM("byte") );
constValue.m_type = RT_TYPE_BYTE;
aConstantAny >>= constValue.m_value.aByte;
}
break;
case TypeClass_SHORT:
{
uConstTypeName = OUString( RTL_CONSTASCII_USTRINGPARAM("short") );
constValue.m_type = RT_TYPE_INT16;
aConstantAny >>= constValue.m_value.aShort;
}
break;
case TypeClass_UNSIGNED_SHORT:
{
uConstTypeName = OUString( RTL_CONSTASCII_USTRINGPARAM("unsigned short") );
constValue.m_type = RT_TYPE_UINT16;
aConstantAny >>= constValue.m_value.aUShort;
}
break;
case TypeClass_LONG:
{
uConstTypeName = OUString( RTL_CONSTASCII_USTRINGPARAM("long") );
constValue.m_type = RT_TYPE_INT32;
aConstantAny >>= constValue.m_value.aLong;
}
break;
case TypeClass_UNSIGNED_LONG:
{
uConstTypeName = OUString( RTL_CONSTASCII_USTRINGPARAM("unsigned long") );
constValue.m_type = RT_TYPE_UINT32;
aConstantAny >>= constValue.m_value.aULong;
}
break;
case TypeClass_FLOAT:
{
uConstTypeName = OUString( RTL_CONSTASCII_USTRINGPARAM("float") );
constValue.m_type = RT_TYPE_FLOAT;
aConstantAny >>= constValue.m_value.aFloat;
}
break;
case TypeClass_DOUBLE:
{
uConstTypeName = OUString( RTL_CONSTASCII_USTRINGPARAM("double") );
constValue.m_type = RT_TYPE_DOUBLE;
aConstantAny >>= constValue.m_value.aDouble;
}
break;
case TypeClass_STRING:
{
uConstTypeName = OUString( RTL_CONSTASCII_USTRINGPARAM("string") );
constValue.m_type = RT_TYPE_STRING;
constValue.m_value.aString = ((OUString*)aConstantAny.getValue())->getStr();
}
break;
default:
OSL_ASSERT(false);
break;
}
rWriter.setFieldData(fieldIndex, uConstName, uConstTypeName, OUString(),
OUString(), RT_ACCESS_CONST, constValue);
}
sal_uInt32 getInheritedMemberCount( Reference< XTypeDescription >& xType )
{
sal_uInt32 memberCount = 0;
if ( xType->getTypeClass() == TypeClass_INTERFACE )
{
Reference< XInterfaceTypeDescription > xIFace(xType, UNO_QUERY);
if ( !xIFace.is() )
return memberCount;
Reference< XTypeDescription > xSuperType = xIFace->getBaseType();
if ( xSuperType.is() )
memberCount = getInheritedMemberCount( xSuperType );
memberCount += xIFace->getMembers().getLength();
}
// } else
// if ( xType->getTypeClass() == TypeClass_Struct || xType->getTypeClass() == TypeClass_Exception )
// {
// Reference< XCompoundTypeDescription > xComp(xType, UNO_QUERY);
//
// if ( xComp.is() )
// return membercount;
//
// Reference< XTypeDescription > xSuperType = xComp->getBaseType();
//
// if ( xSuperType.is() )
// memberCount = getInheritedMemberCount( xSuperType );
//
// memberCount += xComp->getMemberNames().getLength();
// }
return memberCount;
}
void writeMethodData( RegistryTypeWriter& rWriter, sal_uInt32 calculatedMemberOffset,
const Reference< XInterfaceMemberTypeDescription >& xMember,
const Reference< XInterfaceMethodTypeDescription >& xMethod )
{
RTMethodMode methodMode = RT_MODE_TWOWAY;
if ( xMethod->isOneway() )
{
methodMode = RT_MODE_ONEWAY;
}
Sequence< Reference< XMethodParameter > > parameters( xMethod->getParameters() );
Sequence< Reference< XTypeDescription > > exceptions( xMethod->getExceptions() );
sal_uInt16 methodIndex = (sal_uInt16)(xMember->getPosition() - calculatedMemberOffset);
sal_uInt16 paramCount = (sal_uInt16)parameters.getLength();
sal_uInt16 exceptionCount = (sal_uInt16)exceptions.getLength();
rWriter.setMethodData(methodIndex, xMember->getMemberName(),
xMethod->getReturnType()->getName().replace('.', '/'),
methodMode, paramCount, exceptionCount, OUString());
RTParamMode paramMode = RT_PARAM_IN;
sal_uInt16 i;
for ( i=0; i < paramCount; i++)
{
Reference< XMethodParameter > xParam = parameters[i];
if ( xParam->isIn() && xParam->isOut())
{
paramMode = RT_PARAM_INOUT;
} else
if ( xParam->isIn() )
{
paramMode = RT_PARAM_IN;
} else
if ( xParam->isOut() )
{
paramMode = RT_PARAM_OUT;
}
rWriter.setParamData(methodIndex, (sal_uInt16)xParam->getPosition(), xParam->getType()->getName().replace('.', '/'),
xParam->getName(), paramMode);
}
for (i=0; i < exceptionCount; i++)
{
rWriter.setExcData(methodIndex, i, exceptions[i]->getName().replace('.', '/'));
}
}
extern "C"
{
sal_Bool SAL_CALL initTypeMapper( const sal_Char* pRegName )
{
try
{
if (!pRegName)
return sal_False;
Reference< XMultiServiceFactory > xSMgr( createRegistryServiceFactory( convertToFileUrl(pRegName) ) );
if ( !xSMgr.is() )
return sal_False;
Reference< XHierarchicalNameAccess > xNAccess;
Reference< beans::XPropertySet > xProps( xSMgr, UNO_QUERY );
if (xProps.is())
{
try
{
Reference< XComponentContext > xContext;
if (xProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= xContext)
{
xContext->getValueByName(
OUString( RTL_CONSTASCII_USTRINGPARAM("/singletons/com.sun.star.reflection.theTypeDescriptionManager") ) ) >>= xNAccess;
}
}
catch (beans::UnknownPropertyException &)
{
}
}
if ( !xNAccess.is() )
return sal_False;
xNameAccess = xNAccess;
}
catch( Exception& )
{
return sal_False;
}
return sal_True;
}
sal_uInt32 SAL_CALL getTypeBlop(const sal_Char* pTypeName, sal_uInt8** pBlop)
{
sal_uInt32 length = 0;
if ( !pTypeName )
return length;
OUString uTypeName( OUString::createFromAscii(pTypeName).replace('/', '.') );
try
{
Any aTypeAny( xNameAccess->getByHierarchicalName( uTypeName ) );
if ( !aTypeAny.hasValue() )
return length;
Reference< XTypeDescription > xType;
aTypeAny >>= xType;
if ( !xType.is() )
return length;
switch (xType->getTypeClass())
{
case TypeClass_CONSTANTS:
{
Reference< XConstantsTypeDescription > xCFace(xType, UNO_QUERY);
if ( !xCFace.is() )
return length;
Sequence< Reference< XConstantTypeDescription > > constTypes( xCFace->getConstants());
sal_uInt16 constCount = (sal_uInt16)constTypes.getLength();
RegistryTypeWriter writer(RT_TYPE_MODULE, uTypeName.replace('.', '/'),
OUString(), constCount, 0, 0);
for (sal_uInt16 i=0; i < constCount; i++)
writeConstantData(writer, i, constTypes[i]);
length = writer.getBlopSize();
*pBlop = (sal_uInt8*)rtl_allocateMemory( length );
rtl_copyMemory(*pBlop, writer.getBlop(), length);
}
break;
case TypeClass_MODULE:
{
Reference< XModuleTypeDescription > xMFace(xType, UNO_QUERY);
if ( !xMFace.is() )
return length;
Sequence< Reference< XTypeDescription > > memberTypes( xMFace->getMembers());
sal_uInt16 memberCount = (sal_uInt16)memberTypes.getLength();
sal_uInt16 constCount = 0;
sal_Int16 i;
for ( i=0; i < memberCount; i++)
{
if ( TypeClass_CONSTANT == memberTypes[i]->getTypeClass() )
constCount++;
}
RegistryTypeWriter writer(RT_TYPE_MODULE, uTypeName.replace('.', '/'),
OUString(), constCount, 0, 0);
if ( 0 < constCount )
{
Reference< XConstantTypeDescription > xConst;
sal_uInt16 fieldIndex = 0;
for (i=0; i < memberCount; i++)
{
if ( TypeClass_CONSTANT == memberTypes[i]->getTypeClass() )
{
xConst = Reference< XConstantTypeDescription >(memberTypes[i], UNO_QUERY);
writeConstantData(writer, ++fieldIndex, xConst);
}
}
}
length = writer.getBlopSize();
*pBlop = (sal_uInt8*)rtl_allocateMemory( length );
rtl_copyMemory(*pBlop, writer.getBlop(), length);
}
break;
case TypeClass_INTERFACE:
{
Reference< XInterfaceTypeDescription > xIFace(xType, UNO_QUERY);
if ( !xIFace.is() )
return length;
Reference< XInterfaceAttributeTypeDescription > xAttr;
Reference< XInterfaceMethodTypeDescription > xMethod;
Sequence< Reference< XInterfaceMemberTypeDescription > > memberTypes( xIFace->getMembers());
sal_uInt16 memberCount = (sal_uInt16)memberTypes.getLength();
sal_uInt16 attrCount = 0;
sal_uInt16 inheritedMemberCount = 0;
sal_Int32 i;
for ( i=0; i < memberCount; i++)
{
xAttr = Reference< XInterfaceAttributeTypeDescription >(memberTypes[i], UNO_QUERY);
if ( xAttr.is() )
{
attrCount++;
}
}
OUString uSuperType;
Reference< XTypeDescription > xSuperType = xIFace->getBaseType();
if ( xSuperType.is() )
{
uSuperType = xSuperType->getName().replace('.','/');
inheritedMemberCount = (sal_uInt16)getInheritedMemberCount( xSuperType );
}
RegistryTypeWriter writer(RT_TYPE_INTERFACE, uTypeName.replace('.', '/'),
uSuperType, attrCount, memberCount-attrCount, 0);
Uik uik = xIFace->getUik();
RTUik rtUik = { uik.m_Data1, uik.m_Data2, uik.m_Data3, uik.m_Data4, uik.m_Data5 };
writer.setUik( rtUik );
RTFieldAccess attrAccess = RT_ACCESS_READWRITE;
// reset attrCount, used for method index calculation
attrCount = 0;
for (i=0; i < memberCount; i++)
{
xAttr = Reference< XInterfaceAttributeTypeDescription >(memberTypes[i], UNO_QUERY);
if ( xAttr.is() )
{
++attrCount;
if (xAttr->isReadOnly())
{
attrAccess = RT_ACCESS_READONLY;
} else
{
attrAccess = RT_ACCESS_READWRITE;
}
writer.setFieldData(sal::static_int_cast< sal_uInt16 >(memberTypes[i]->getPosition() - inheritedMemberCount),
memberTypes[i]->getMemberName(),
xAttr->getType()->getName().replace('.', '/'),
OUString(), OUString(), attrAccess);
continue;
}
xMethod = Reference< XInterfaceMethodTypeDescription >(memberTypes[i], UNO_QUERY);
if ( xMethod.is() )
{
writeMethodData( writer, attrCount+inheritedMemberCount, memberTypes[i], xMethod );
}
}
length = writer.getBlopSize();
*pBlop = (sal_uInt8*)rtl_allocateMemory( length );
rtl_copyMemory(*pBlop, writer.getBlop(), length);
}
break;
case TypeClass_STRUCT:
case TypeClass_EXCEPTION:
{
RTTypeClass rtTypeClass = RT_TYPE_STRUCT;
if (xType->getTypeClass() == TypeClass_EXCEPTION)
{
rtTypeClass = RT_TYPE_EXCEPTION;
}
#include <com/sun/star/reflection/XConstantsTypeDescription.hpp>
Reference< XCompoundTypeDescription > xComp(xType, UNO_QUERY);
if ( !xComp.is() )
return length;
Sequence< OUString > memberNames( xComp->getMemberNames());
Sequence< Reference< XTypeDescription > > memberTypes( xComp->getMemberTypes());
sal_uInt16 memberCount = (sal_uInt16)memberNames.getLength();
OUString uSuperType;
Reference< XTypeDescription > xSuperType = xComp->getBaseType();
if ( xSuperType.is() )
{
uSuperType = xSuperType->getName().replace('.','/');
}
RegistryTypeWriter writer(rtTypeClass, uTypeName.replace('.', '/'),
uSuperType, memberCount, 0, 0);
for (sal_Int16 i=0; i < memberCount; i++)
{
writer.setFieldData(i , memberNames[i], memberTypes[i]->getName().replace('.', '/'),
OUString(), OUString(), RT_ACCESS_READWRITE);
}
length = writer.getBlopSize();
*pBlop = (sal_uInt8*)rtl_allocateMemory( length );
rtl_copyMemory(*pBlop, writer.getBlop(), length);
}
break;
case TypeClass_ENUM:
{
Reference< XEnumTypeDescription > xEnum(xType, UNO_QUERY);
if ( !xEnum.is() )
return length;
Sequence< OUString > enumNames( xEnum->getEnumNames());
Sequence< sal_Int32 > enumValues( xEnum->getEnumValues());
sal_uInt16 enumCount = (sal_uInt16)enumNames.getLength();
RegistryTypeWriter writer(RT_TYPE_ENUM, uTypeName.replace('.', '/'),
OUString(), enumCount, 0, 0);
RTConstValue constValue;
for (sal_Int16 i=0; i < enumCount; i++)
{
constValue.m_type = RT_TYPE_INT32;
constValue.m_value.aLong = enumValues[i];
writer.setFieldData(i, enumNames[i], OUString(), OUString(), OUString(),
RT_ACCESS_CONST, constValue);
}
length = writer.getBlopSize();
*pBlop = (sal_uInt8*)rtl_allocateMemory( length );
rtl_copyMemory(*pBlop, writer.getBlop(), length);
}
break;
case TypeClass_TYPEDEF:
{
Reference< XIndirectTypeDescription > xTD(xType, UNO_QUERY);
if ( !xTD.is() )
return length;
RegistryTypeWriter writer(RT_TYPE_TYPEDEF, uTypeName.replace('.', '/'),
xTD->getReferencedType()->getName().replace('.', '/'),
0, 0, 0);
length = writer.getBlopSize();
*pBlop = (sal_uInt8*)rtl_allocateMemory( length );
rtl_copyMemory(*pBlop, writer.getBlop(), length);
}
break;
default:
OSL_ASSERT(false);
break;
}
}
catch( Exception& )
{
}
return length;
}
} // extern "C"