| /************************************************************** |
| * |
| * 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" |
| |
| |
| |