/************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2008 by Sun Microsystems, Inc. * * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: typeblop.cxx,v $ * $Revision: 1.10 $ * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ #include #ifndef __REGISTRY_REFLWRIT_HXX__ #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include 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 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"