2018 lines
		
	
	
		
			81 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			2018 lines
		
	
	
		
			81 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
|   | /*************************************************************************
 | |||
|  |  * | |||
|  |  *  OpenOffice.org - a multi-platform office productivity suite | |||
|  |  * | |||
|  |  *  $RCSfile: cli_data.cxx,v $ | |||
|  |  * | |||
|  |  *  $Revision: 1.2 $ | |||
|  |  * | |||
|  |  *  last change: $Author: kz $ $Date: 2007-05-09 13:31:06 $ | |||
|  |  * | |||
|  |  *  The Contents of this file are made available subject to | |||
|  |  *  the terms of GNU Lesser General Public License Version 2.1. | |||
|  |  * | |||
|  |  * | |||
|  |  *    GNU Lesser General Public License Version 2.1 | |||
|  |  *    ============================================= | |||
|  |  *    Copyright 2005 by Sun Microsystems, Inc. | |||
|  |  *    901 San Antonio Road, Palo Alto, CA 94303, USA | |||
|  |  * | |||
|  |  *    This library is free software; you can redistribute it and/or | |||
|  |  *    modify it under the terms of the GNU Lesser General Public | |||
|  |  *    License version 2.1, as published by the Free Software Foundation. | |||
|  |  * | |||
|  |  *    This library 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 for more details. | |||
|  |  * | |||
|  |  *    You should have received a copy of the GNU Lesser General Public | |||
|  |  *    License along with this library; if not, write to the Free Software | |||
|  |  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |||
|  |  *    MA  02111-1307  USA | |||
|  |  * | |||
|  |  ************************************************************************/ | |||
|  | 
 | |||
|  | // MARKER(update_precomp.py): autogen include statement, do not remove
 | |||
|  | #include "precompiled_cli_ure.hxx"
 | |||
|  | 
 | |||
|  | #pragma warning(push, 1)
 | |||
|  | #include "windows.h"
 | |||
|  | #pragma warning(pop)
 | |||
|  | 
 | |||
|  | #include <memory>
 | |||
|  | 
 | |||
|  | 
 | |||
|  | #include "rtl/ustring.hxx"
 | |||
|  | #include "rtl/ustrbuf.hxx"
 | |||
|  | #include "uno/sequence2.h"
 | |||
|  | #include "typelib/typedescription.hxx"
 | |||
|  | #include "cli_proxy.h"
 | |||
|  | #include "cli_base.h"
 | |||
|  | #include "cli_bridge.h"
 | |||
|  | 
 | |||
|  | 
 | |||
|  | #undef VOID
 | |||
|  | 
 | |||
|  | namespace css = com::sun::star; | |||
|  | 
 | |||
|  | namespace sri = System::Runtime::InteropServices; | |||
|  | namespace sr = System::Reflection; | |||
|  | namespace st = System::Text; | |||
|  | namespace ucss = unoidl::com::sun::star; | |||
|  | 
 | |||
|  | using namespace rtl; | |||
|  | using namespace std; | |||
|  | 
 | |||
|  | 
 | |||
|  | namespace cli_uno | |||
|  | { | |||
|  | System::String* mapUnoPolymorphicName(System::String* unoName); | |||
|  | OUString mapCliTypeName(System::String* typeName); | |||
|  | System::String* mapCliPolymorphicName(System::String* unoName); | |||
|  | System::String* mapPolymorphicName(System::String* unoName, bool bCliToUno); | |||
|  | 
 | |||
|  | inline auto_ptr< rtl_mem > seq_allocate( sal_Int32 nElements, sal_Int32 nSize ) | |||
|  | { | |||
|  |     auto_ptr< rtl_mem > seq( | |||
|  |         rtl_mem::allocate( SAL_SEQUENCE_HEADER_SIZE + (nElements * nSize) ) ); | |||
|  |     uno_Sequence * p = (uno_Sequence *)seq.get(); | |||
|  |     p->nRefCount = 1; | |||
|  |     p->nElements = nElements; | |||
|  |     return seq; | |||
|  | } | |||
|  | 
 | |||
|  | 
 | |||
|  | System::Object* Bridge::map_uno2cli(uno_Interface * pUnoI, typelib_InterfaceTypeDescription *pTD) const | |||
|  | { | |||
|  |     System::Object* retVal= NULL; | |||
|  | // get oid
 | |||
|  |     rtl_uString * pOid = 0; | |||
|  |     (*m_uno_env->getObjectIdentifier)( m_uno_env, &pOid, pUnoI ); | |||
|  |     OSL_ASSERT( 0 != pOid ); | |||
|  |     OUString oid(pOid, SAL_NO_ACQUIRE); | |||
|  | 
 | |||
|  |     //see if the interface was already mapped
 | |||
|  |     System::Type* ifaceType= mapUnoType(reinterpret_cast<typelib_TypeDescription*>(pTD)); | |||
|  |     System::String* sOid= mapUnoString(oid.pData); | |||
|  | 
 | |||
|  |     System::Threading::Monitor::Enter( CliEnvHolder::g_cli_env ); | |||
|  |     try | |||
|  |     { | |||
|  |         retVal = CliEnvHolder::g_cli_env->getRegisteredInterface(sOid, ifaceType); | |||
|  |         if (retVal) | |||
|  |         { | |||
|  |             // There is already an registered object. It can either be a proxy
 | |||
|  |             // for the UNO object or a real cli object. In the first case we
 | |||
|  |             // tell the proxy that it shall also represent the current UNO
 | |||
|  |             // interface. If it already does that, then it does nothing
 | |||
|  |             if (srr::RemotingServices::IsTransparentProxy(retVal)) | |||
|  |             { | |||
|  |                 UnoInterfaceProxy* p = static_cast<UnoInterfaceProxy*>( | |||
|  |                     srr::RemotingServices::GetRealProxy(retVal)); | |||
|  |                 p->addUnoInterface(pUnoI, pTD); | |||
|  |             } | |||
|  |         } | |||
|  |         else | |||
|  |         { | |||
|  |             retVal = UnoInterfaceProxy::create( | |||
|  |                 (Bridge *) this, pUnoI, pTD, oid ); | |||
|  |         } | |||
|  |     } | |||
|  |     __finally | |||
|  |     { | |||
|  |         System::Threading::Monitor::Exit( CliEnvHolder::g_cli_env ); | |||
|  |     } | |||
|  | 
 | |||
|  |     return retVal; | |||
|  | } | |||
|  | 
 | |||
|  | uno_Interface* Bridge::map_cli2uno(System::Object* cliObj, typelib_TypeDescription *pTD) const | |||
|  | { | |||
|  |     uno_Interface* retIface = NULL; | |||
|  |     // get oid from dot net environment
 | |||
|  |     System::String* ds_oid = CliEnvHolder::g_cli_env->getObjectIdentifier( cliObj); | |||
|  |     OUString ousOid = mapCliString(ds_oid); | |||
|  |     // look if interface is already mapped
 | |||
|  |     m_uno_env->getRegisteredInterface(m_uno_env, (void**) &retIface, ousOid.pData, | |||
|  |                                       (typelib_InterfaceTypeDescription*) pTD); | |||
|  |     if ( ! retIface) | |||
|  |     { | |||
|  |         System::Threading::Monitor::Enter(__typeof(Cli_environment)); | |||
|  |         try | |||
|  |         { | |||
|  |             m_uno_env->getRegisteredInterface(m_uno_env, (void**) &retIface, ousOid.pData, | |||
|  |                                                (typelib_InterfaceTypeDescription*) pTD); | |||
|  |             if ( ! retIface) | |||
|  |             { | |||
|  |                 retIface = CliProxy::create((Bridge*)this, cliObj, pTD, ousOid); | |||
|  |             } | |||
|  |         } | |||
|  |         __finally | |||
|  |         { | |||
|  |             System::Threading::Monitor::Exit(__typeof(Cli_environment)); | |||
|  |         } | |||
|  |     } | |||
|  |     return retIface; | |||
|  | } | |||
|  | 
 | |||
|  | inline System::Type* loadCliType(rtl_uString * unoName) | |||
|  | { | |||
|  |      return loadCliType(mapUnoTypeName(unoName)); | |||
|  | } | |||
|  | 
 | |||
|  | System::Type* loadCliType(System::String * unoName) | |||
|  | { | |||
|  |     System::Type* retVal= NULL; | |||
|  |     try | |||
|  |     { | |||
|  |         //If unoName denotes a polymorphic type, e.g com.sun.star.beans.Defaulted<System.Char>
 | |||
|  |         //then we remove the type list, otherwise the type could not be loaded.
 | |||
|  |         bool bIsPolymorphic = false; | |||
|  | 
 | |||
|  |         System::String * loadName = unoName; | |||
|  |         int index = unoName->IndexOf('<'); | |||
|  |         if (index != -1) | |||
|  |         { | |||
|  |             loadName = unoName->Substring(0, index); | |||
|  |             bIsPolymorphic = true; | |||
|  |         } | |||
|  |         System::AppDomain*  currentDomain = System::AppDomain::CurrentDomain; | |||
|  |         sr::Assembly*  assems[] = currentDomain->GetAssemblies(); | |||
|  |         for (int i = 0; i < assems->Length; i++) | |||
|  |         { | |||
|  |             retVal = assems[i]->GetType(loadName, false); | |||
|  |             if (retVal) | |||
|  |                 break; | |||
|  |         } | |||
|  | 
 | |||
|  |         if (retVal == NULL) | |||
|  |         { | |||
|  |             System::String * msg = new System::String(S"A type could not be loaded: "); | |||
|  |             msg = System::String::Concat(msg, loadName); | |||
|  |             throw BridgeRuntimeError(mapCliString(msg)); | |||
|  |         } | |||
|  | 
 | |||
|  |         if (bIsPolymorphic) | |||
|  |         { | |||
|  |             retVal = uno::PolymorphicType::GetType(retVal, unoName); | |||
|  |         } | |||
|  |     } | |||
|  |     catch( System::Exception * e) | |||
|  |     { | |||
|  |         rtl::OUString ouMessage(mapCliString(e->get_Message())); | |||
|  |         throw BridgeRuntimeError(ouMessage); | |||
|  |     } | |||
|  |     return retVal; | |||
|  | } | |||
|  | 
 | |||
|  | 
 | |||
|  | System::Type* mapUnoType(typelib_TypeDescription const * pTD) | |||
|  | { | |||
|  |     return mapUnoType(pTD->pWeakRef); | |||
|  | } | |||
|  | 
 | |||
|  | System::Type* mapUnoType(typelib_TypeDescriptionReference const * pTD) | |||
|  | { | |||
|  |     System::Type * retVal = 0; | |||
|  |     switch (pTD->eTypeClass) | |||
|  |     { | |||
|  |     case typelib_TypeClass_VOID: | |||
|  |         retVal= __typeof(void); break; | |||
|  |     case typelib_TypeClass_CHAR: | |||
|  |         retVal= __typeof(System::Char); break; | |||
|  |     case typelib_TypeClass_BOOLEAN: | |||
|  |         retVal= __typeof(System::Boolean); break; | |||
|  |     case typelib_TypeClass_BYTE: | |||
|  |         retVal= __typeof(System::Byte); break; | |||
|  |     case typelib_TypeClass_SHORT: | |||
|  |         retVal= __typeof(System::Int16); break; | |||
|  |     case typelib_TypeClass_UNSIGNED_SHORT: | |||
|  |         retVal= __typeof(System::UInt16); break; | |||
|  |     case typelib_TypeClass_LONG: | |||
|  |         retVal= __typeof(System::Int32); break; | |||
|  |     case typelib_TypeClass_UNSIGNED_LONG: | |||
|  |         retVal= __typeof(System::UInt32); break; | |||
|  |     case typelib_TypeClass_HYPER: | |||
|  |         retVal= __typeof(System::Int64); break; | |||
|  |     case typelib_TypeClass_UNSIGNED_HYPER: | |||
|  |         retVal= __typeof(System::UInt64); break; | |||
|  |     case typelib_TypeClass_FLOAT: | |||
|  |         retVal= __typeof(System::Single); break; | |||
|  |     case typelib_TypeClass_DOUBLE: | |||
|  |         retVal= __typeof(System::Double); break; | |||
|  |     case typelib_TypeClass_STRING: | |||
|  |         retVal= __typeof(System::String); break; | |||
|  |     case typelib_TypeClass_TYPE: | |||
|  |         retVal= __typeof(System::Type); break; | |||
|  |     case typelib_TypeClass_ANY: | |||
|  |         retVal= __typeof(uno::Any); break; | |||
|  |     case typelib_TypeClass_ENUM: | |||
|  |     case typelib_TypeClass_STRUCT: | |||
|  |     case typelib_TypeClass_EXCEPTION: | |||
|  |         retVal= loadCliType(pTD->pTypeName); break; | |||
|  |     case typelib_TypeClass_INTERFACE: | |||
|  |     { | |||
|  |         //special handling for XInterface, since it does not exist in cli.
 | |||
|  |         rtl::OUString usXInterface(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.XInterface")); | |||
|  |         if (usXInterface.equals(pTD->pTypeName)) | |||
|  |             retVal= __typeof(System::Object); | |||
|  |         else | |||
|  |             retVal= loadCliType(pTD->pTypeName); | |||
|  |         break; | |||
|  |     } | |||
|  |     case typelib_TypeClass_SEQUENCE: | |||
|  |     { | |||
|  |         css::uno::TypeDescription seqType( | |||
|  |             const_cast<typelib_TypeDescriptionReference*>(pTD)); | |||
|  |         typelib_TypeDescriptionReference* pElementTDRef= | |||
|  |             reinterpret_cast<typelib_IndirectTypeDescription*>(seqType.get())->pType; | |||
|  |         switch (pElementTDRef->eTypeClass) | |||
|  |         { | |||
|  |         case typelib_TypeClass_CHAR: | |||
|  |             retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArChar)); break; | |||
|  |         case typelib_TypeClass_BOOLEAN: | |||
|  |             retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArBoolean)); | |||
|  |             break; | |||
|  |         case typelib_TypeClass_BYTE: | |||
|  |             retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArByte)); | |||
|  |             break; | |||
|  |         case typelib_TypeClass_SHORT: | |||
|  |             retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArInt16)); | |||
|  |             break; | |||
|  |         case typelib_TypeClass_UNSIGNED_SHORT: | |||
|  |             retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArUInt16)); | |||
|  |             break; | |||
|  |         case typelib_TypeClass_LONG: | |||
|  |             retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArInt32)); | |||
|  |             break; | |||
|  |         case typelib_TypeClass_UNSIGNED_LONG: | |||
|  |             retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArUInt32)); | |||
|  |             break; | |||
|  |         case typelib_TypeClass_HYPER: | |||
|  |             retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArInt64)); | |||
|  |             break; | |||
|  |         case typelib_TypeClass_UNSIGNED_HYPER: | |||
|  |             retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArUInt64)); | |||
|  |             break; | |||
|  |         case typelib_TypeClass_FLOAT: | |||
|  |             retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArSingle)); | |||
|  |             break; | |||
|  |         case typelib_TypeClass_DOUBLE: | |||
|  |             retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArDouble)); | |||
|  |             break; | |||
|  |         case typelib_TypeClass_STRING: | |||
|  |             retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArString)); | |||
|  |             break; | |||
|  |         case typelib_TypeClass_TYPE: | |||
|  |             retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArType)); | |||
|  |             break; | |||
|  |         case typelib_TypeClass_ANY: | |||
|  |         case typelib_TypeClass_ENUM: | |||
|  |         case typelib_TypeClass_EXCEPTION: | |||
|  |         case typelib_TypeClass_STRUCT: | |||
|  |         case typelib_TypeClass_INTERFACE: | |||
|  |         case typelib_TypeClass_SEQUENCE: | |||
|  |         { | |||
|  |             retVal= loadCliType(pTD->pTypeName); | |||
|  |             break; | |||
|  |         } | |||
|  |         default: | |||
|  |             //All cases should be handled by the case statements above
 | |||
|  |             OSL_ASSERT(0); | |||
|  |             break; | |||
|  |         } | |||
|  |         break; | |||
|  |     } | |||
|  |     default: | |||
|  |         OSL_ASSERT(false); | |||
|  |         break; | |||
|  |     } | |||
|  |     return retVal; | |||
|  | } | |||
|  | 
 | |||
|  | /** Returns an acquired td.
 | |||
|  |  */ | |||
|  | typelib_TypeDescriptionReference* mapCliType(System::Type* cliType) | |||
|  | { | |||
|  |     typelib_TypeDescriptionReference* retVal= NULL; | |||
|  |     if (cliType == NULL) | |||
|  |     { | |||
|  |         retVal = * typelib_static_type_getByTypeClass( | |||
|  |             typelib_TypeClass_VOID ); | |||
|  |         typelib_typedescriptionreference_acquire( retVal ); | |||
|  |         return retVal; | |||
|  |     } | |||
|  |     //check for Enum first,
 | |||
|  |     //because otherwise case System::TypeCode::Int32 applies
 | |||
|  |     if (cliType->get_IsEnum()) | |||
|  |     { | |||
|  |         OUString usTypeName= mapCliTypeName(cliType->get_FullName()); | |||
|  |         css::uno::Type unoType(css::uno::TypeClass_ENUM, usTypeName); | |||
|  |         retVal= unoType.getTypeLibType(); | |||
|  |         typelib_typedescriptionreference_acquire(retVal); | |||
|  |     } | |||
|  |     else | |||
|  |     { | |||
|  |         switch (System::Type::GetTypeCode(cliType)) | |||
|  |         { | |||
|  |         case System::TypeCode::Boolean: | |||
|  |             retVal = * typelib_static_type_getByTypeClass( | |||
|  |                 typelib_TypeClass_BOOLEAN ); | |||
|  |             typelib_typedescriptionreference_acquire( retVal ); | |||
|  |             break; | |||
|  |         case System::TypeCode::Char: | |||
|  |             retVal = * typelib_static_type_getByTypeClass( | |||
|  |                 typelib_TypeClass_CHAR ); | |||
|  |             typelib_typedescriptionreference_acquire( retVal ); | |||
|  |             break; | |||
|  |         case System::TypeCode::Byte: | |||
|  |             retVal = * typelib_static_type_getByTypeClass( | |||
|  |                 typelib_TypeClass_BYTE ); | |||
|  |             typelib_typedescriptionreference_acquire( retVal ); | |||
|  |             break; | |||
|  |         case System::TypeCode::Int16: | |||
|  |             retVal = * typelib_static_type_getByTypeClass( | |||
|  |                 typelib_TypeClass_SHORT ); | |||
|  |             typelib_typedescriptionreference_acquire( retVal ); | |||
|  |             break; | |||
|  |         case System::TypeCode::Int32: | |||
|  |             retVal = * typelib_static_type_getByTypeClass( | |||
|  |                 typelib_TypeClass_LONG ); | |||
|  |             typelib_typedescriptionreference_acquire( retVal ); | |||
|  |             break; | |||
|  |         case System::TypeCode::Int64: | |||
|  |             retVal = * typelib_static_type_getByTypeClass( | |||
|  |                 typelib_TypeClass_HYPER ); | |||
|  |             typelib_typedescriptionreference_acquire( retVal ); | |||
|  |             break; | |||
|  |         case System::TypeCode::UInt16: | |||
|  |             retVal = * typelib_static_type_getByTypeClass( | |||
|  |                 typelib_TypeClass_UNSIGNED_SHORT ); | |||
|  |             typelib_typedescriptionreference_acquire( retVal ); | |||
|  |             break; | |||
|  |         case System::TypeCode::UInt32: | |||
|  |             retVal = * typelib_static_type_getByTypeClass( | |||
|  |                 typelib_TypeClass_UNSIGNED_LONG ); | |||
|  |             typelib_typedescriptionreference_acquire( retVal ); | |||
|  |             break; | |||
|  |         case System::TypeCode::UInt64: | |||
|  |             retVal = * typelib_static_type_getByTypeClass( | |||
|  |                 typelib_TypeClass_UNSIGNED_HYPER ); | |||
|  |             typelib_typedescriptionreference_acquire( retVal ); | |||
|  |             break; | |||
|  |         case System::TypeCode::Single: | |||
|  |             retVal = * typelib_static_type_getByTypeClass( | |||
|  |                 typelib_TypeClass_FLOAT ); | |||
|  |             typelib_typedescriptionreference_acquire( retVal ); | |||
|  |             break; | |||
|  |         case System::TypeCode::Double: | |||
|  |             retVal = * typelib_static_type_getByTypeClass( | |||
|  |                 typelib_TypeClass_DOUBLE ); | |||
|  |             typelib_typedescriptionreference_acquire( retVal ); | |||
|  |             break; | |||
|  |         case System::TypeCode::String: | |||
|  |             retVal = * typelib_static_type_getByTypeClass( | |||
|  |                 typelib_TypeClass_STRING ); | |||
|  |             typelib_typedescriptionreference_acquire( retVal ); | |||
|  |             break; | |||
|  |         default: | |||
|  |             break; | |||
|  |         } | |||
|  |     } | |||
|  |     if (retVal == NULL) | |||
|  |     { | |||
|  |         System::String* cliTypeName= cliType->get_FullName(); | |||
|  |         // Void
 | |||
|  |         if (const_cast<System::String*>(Constants::sVoid)->Equals( | |||
|  |                 cliTypeName)) | |||
|  |         { | |||
|  |             retVal = * typelib_static_type_getByTypeClass( | |||
|  |                 typelib_TypeClass_VOID ); | |||
|  |             typelib_typedescriptionreference_acquire( retVal ); | |||
|  |         } | |||
|  |         // Type
 | |||
|  |         else if (const_cast<System::String*>(Constants::sType)->Equals( | |||
|  |                      cliTypeName)) | |||
|  |         { | |||
|  |             retVal = * typelib_static_type_getByTypeClass( | |||
|  |                 typelib_TypeClass_TYPE ); | |||
|  |             typelib_typedescriptionreference_acquire( retVal ); | |||
|  |         } | |||
|  |         // Any
 | |||
|  |         else if (const_cast<System::String*>(Constants::sAny)->Equals( | |||
|  |                      cliTypeName)) | |||
|  |         { | |||
|  |             retVal = * typelib_static_type_getByTypeClass( | |||
|  |                 typelib_TypeClass_ANY ); | |||
|  |             typelib_typedescriptionreference_acquire( retVal ); | |||
|  |         } | |||
|  |         //struct, interfaces, sequences
 | |||
|  |         else | |||
|  |         { | |||
|  |             OUString usTypeName; | |||
|  |             uno::PolymorphicType * poly = dynamic_cast<uno::PolymorphicType*>(cliType); | |||
|  |             if (poly != NULL) | |||
|  |                 usTypeName = mapCliTypeName( poly->PolymorphicName); | |||
|  |             else | |||
|  |                 usTypeName = mapCliTypeName(cliTypeName); | |||
|  |             typelib_TypeDescription* td = NULL; | |||
|  |             typelib_typedescription_getByName(&td, usTypeName.pData); | |||
|  |             if (td) | |||
|  |             { | |||
|  |                 retVal = td->pWeakRef; | |||
|  |                 typelib_typedescriptionreference_acquire(retVal); | |||
|  |                 typelib_typedescription_release(td); | |||
|  |             } | |||
|  |         } | |||
|  |     } | |||
|  |     if (retVal == NULL) | |||
|  |     { | |||
|  |         OUStringBuffer buf( 128 ); | |||
|  |         buf.appendAscii( | |||
|  |             RTL_CONSTASCII_STRINGPARAM("[cli_uno bridge] mapCliType():" | |||
|  |                                        "could not map type: ") ); | |||
|  |         buf.append(mapCliString(cliType->get_FullName())); | |||
|  |         throw BridgeRuntimeError( buf.makeStringAndClear() ); | |||
|  |     } | |||
|  |     return retVal; | |||
|  | } | |||
|  | 
 | |||
|  | /**
 | |||
|  |     Otherwise a leading "unoidl." is removed. | |||
|  |  */ | |||
|  | System::String* mapUnoTypeName(rtl_uString const * typeName) | |||
|  | { | |||
|  |     OUString usUnoName( const_cast< rtl_uString * >( typeName ) ); | |||
|  |     st::StringBuilder* buf= new st::StringBuilder(); | |||
|  |     //determine if the type is a sequence and its dimensions
 | |||
|  |     int dims= 0; | |||
|  |     if (usUnoName[0] == '[') | |||
|  |     { | |||
|  |         sal_Int32 index= 1; | |||
|  |         while (true) | |||
|  |         { | |||
|  |             if (usUnoName[index++] == ']') | |||
|  |                 dims++; | |||
|  |             if (usUnoName[index++] != '[') | |||
|  |                 break; | |||
|  |         } | |||
|  |         usUnoName = usUnoName.copy(index - 1); | |||
|  |     } | |||
|  |     System::String * sUnoName = mapUnoString(usUnoName.pData); | |||
|  |     if (sUnoName->Equals(const_cast<System::String*>(Constants::usBool))) | |||
|  |         buf->Append(const_cast<System::String*>(Constants::sBoolean)); | |||
|  |     else if (sUnoName->Equals(const_cast<System::String*>(Constants::usChar))) | |||
|  |         buf->Append(const_cast<System::String*>(Constants::sChar)); | |||
|  |     else if (sUnoName->Equals(const_cast<System::String*>(Constants::usByte))) | |||
|  |         buf->Append(const_cast<System::String*>(Constants::sByte)); | |||
|  |     else if (sUnoName->Equals(const_cast<System::String*>(Constants::usShort))) | |||
|  |         buf->Append(const_cast<System::String*>(Constants::sInt16)); | |||
|  |     else if (sUnoName->Equals(const_cast<System::String*>(Constants::usUShort))) | |||
|  |         buf->Append(const_cast<System::String*>(Constants::sUInt16)); | |||
|  |     else if (sUnoName->Equals(const_cast<System::String*>(Constants::usLong))) | |||
|  |         buf->Append(const_cast<System::String*>(Constants::sInt32)); | |||
|  |     else if (sUnoName->Equals(const_cast<System::String*>(Constants::usULong))) | |||
|  |         buf->Append(const_cast<System::String*>(Constants::sUInt32)); | |||
|  |     else if (sUnoName->Equals(const_cast<System::String*>(Constants::usHyper))) | |||
|  |         buf->Append(const_cast<System::String*>(Constants::sInt64)); | |||
|  |     else if (sUnoName->Equals(const_cast<System::String*>(Constants::usUHyper))) | |||
|  |         buf->Append(const_cast<System::String*>(Constants::sUInt64)); | |||
|  |     else if (sUnoName->Equals(const_cast<System::String*>(Constants::usFloat))) | |||
|  |         buf->Append(const_cast<System::String*>(Constants::sSingle)); | |||
|  |     else if (sUnoName->Equals(const_cast<System::String*>(Constants::usDouble))) | |||
|  |         buf->Append(const_cast<System::String*>(Constants::sDouble)); | |||
|  |     else if (sUnoName->Equals(const_cast<System::String*>(Constants::usString))) | |||
|  |         buf->Append(const_cast<System::String*>(Constants::sString)); | |||
|  |     else if (sUnoName->Equals(const_cast<System::String*>(Constants::usVoid))) | |||
|  |         buf->Append(const_cast<System::String*>(Constants::sVoid)); | |||
|  |     else if (sUnoName->Equals(const_cast<System::String*>(Constants::usType))) | |||
|  |         buf->Append(const_cast<System::String*>(Constants::sType)); | |||
|  |     else if (sUnoName->Equals(const_cast<System::String*>(Constants::usXInterface))) | |||
|  |         buf->Append(const_cast<System::String*>(Constants::sObject)); | |||
|  |     else if (sUnoName->Equals(const_cast<System::String*>(Constants::usAny))) | |||
|  |     { | |||
|  |         buf->Append(const_cast<System::String*>(Constants::sAny)); | |||
|  |     } | |||
|  |     else | |||
|  |     { | |||
|  |         //put "unoidl." at the beginning
 | |||
|  |         buf->Append(const_cast<System::String*>(Constants::sUnoidl)); | |||
|  |         //for polymorphic struct types remove the brackets, e.g mystruct<bool> -> mystruct
 | |||
|  |         System::String * sName = mapUnoPolymorphicName(sUnoName); | |||
|  |         buf->Append(sName); | |||
|  |     } | |||
|  |     // apend []
 | |||
|  |     for (;dims--;) | |||
|  |         buf->Append(const_cast<System::String*>(Constants::sBrackets)); | |||
|  | 
 | |||
|  |     return buf->ToString(); | |||
|  | } | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | /** For example, there is a uno type
 | |||
|  |     com.sun.star.Foo<char, long>. | |||
|  |     The values in the type list | |||
|  |     are uno types and are replaced by cli types, such as System.Char, | |||
|  |     System.Int32, etc. | |||
|  |     The pr<EFBFBD>fix unoidl is not added. | |||
|  |  */ | |||
|  | inline System::String* mapUnoPolymorphicName(System::String* unoName) | |||
|  | { | |||
|  |        return mapPolymorphicName(unoName, false); | |||
|  | } | |||
|  | /** For example, there is a type name such as
 | |||
|  |     com.sun.star.Foo<System.Char, System.Int32>. | |||
|  |     The values in the type list | |||
|  |     are CLI types and are replaced by uno types, such as char, | |||
|  |     long, etc. | |||
|  |     The pr<EFBFBD>fix unoidl remains. | |||
|  |  */ | |||
|  | inline System::String* mapCliPolymorphicName(System::String* unoName) | |||
|  | { | |||
|  |     return mapPolymorphicName(unoName, true); | |||
|  | } | |||
|  | 
 | |||
|  | System::String* mapPolymorphicName(System::String* unoName, bool bCliToUno) | |||
|  | { | |||
|  |     int index = unoName->IndexOf('<'); | |||
|  |     if (index == -1) | |||
|  |         return unoName; | |||
|  | 
 | |||
|  |     System::Text::StringBuilder * builder = new System::Text::StringBuilder(256); | |||
|  |     builder->Append(unoName->Substring(0, index +1 )); | |||
|  | 
 | |||
|  |     //Find the first occurrence of ','
 | |||
|  |     //If the parameter is a polymorphic struct then we neede to ignore everything
 | |||
|  |     //between the brackets because it can also contain commas
 | |||
|  |     //get the type list within < and >
 | |||
|  |     int endIndex = unoName->Length - 1; | |||
|  |     index++; | |||
|  |     int cur = index; | |||
|  |     int countParams = 0; | |||
|  |     while (cur <= endIndex) | |||
|  |     { | |||
|  |         System::Char c = unoName->Chars[cur]; | |||
|  |         if (c == ',' || c == '>') | |||
|  |         { | |||
|  |             //insert a comma if needed
 | |||
|  |             if (countParams != 0) | |||
|  |                 builder->Append(S","); | |||
|  |             countParams++; | |||
|  |             System::String * sParam = unoName->Substring(index, cur - index); | |||
|  |             //skip the comma
 | |||
|  |             cur++; | |||
|  |             //the the index to the beginning of the next param
 | |||
|  |             index = cur; | |||
|  |             if (bCliToUno) | |||
|  |             { | |||
|  |                 builder->Append(mapCliTypeName(sParam)); | |||
|  |             } | |||
|  |             else | |||
|  |             { | |||
|  |                 OUString s = mapCliString(sParam); | |||
|  |                 builder->Append(mapUnoTypeName(s.pData)); | |||
|  |             } | |||
|  |         } | |||
|  |         else if (c == '<') | |||
|  |         { | |||
|  |             cur++; | |||
|  |             //continue until the matching '>'
 | |||
|  |             int numNested = 0; | |||
|  |             for (;;cur++) | |||
|  |             { | |||
|  |                 System::Char curChar = unoName->Chars[cur]; | |||
|  |                 if (curChar == '<') | |||
|  |                 { | |||
|  |                     numNested ++; | |||
|  |                 } | |||
|  |                 else if (curChar == '>') | |||
|  |                 { | |||
|  |                     if (numNested > 0) | |||
|  |                         numNested--; | |||
|  |                     else | |||
|  |                         break; | |||
|  |                 } | |||
|  |             } | |||
|  |         } | |||
|  |         cur++; | |||
|  |     } | |||
|  | 
 | |||
|  |     builder->Append((System::Char) '>'); | |||
|  |     return builder->ToString(); | |||
|  | } | |||
|  | 
 | |||
|  | OUString mapCliTypeName(System::String* typeName) | |||
|  | { | |||
|  |     int dims= 0; | |||
|  |     // Array? determine the "rank" (number of "[]")
 | |||
|  |     // move from the rightmost end to the left, for example
 | |||
|  |     // unoidl.PolymorphicStruct<System.Char[]>[]
 | |||
|  |     // has only a "dimension" of 1
 | |||
|  |     int cur = typeName->Length - 1; | |||
|  |     bool bRightBracket = false; | |||
|  |     while (cur >= 0) | |||
|  |     { | |||
|  |         System::Char c = typeName->Chars[cur]; | |||
|  |         if (c == ']') | |||
|  |         { | |||
|  |             bRightBracket = true; | |||
|  |         } | |||
|  |         else if (c == '[') | |||
|  |         { | |||
|  |             if (!bRightBracket) | |||
|  |                 throw BridgeRuntimeError( | |||
|  |                     OUSTR("Typename is wrong. No matching brackets for sequence. Name is: ") + | |||
|  |                     mapCliString(typeName)); | |||
|  |             bRightBracket = false; | |||
|  |             dims ++; | |||
|  |         } | |||
|  |         else | |||
|  |         { | |||
|  |             if (bRightBracket) | |||
|  |                 throw BridgeRuntimeError( | |||
|  |                     OUSTR("Typename is wrong. No matching brackets for sequence. Name is: ") + | |||
|  |                     mapCliString(typeName)); | |||
|  |             break; | |||
|  |         } | |||
|  |         cur--; | |||
|  |     } | |||
|  | 
 | |||
|  |     if (bRightBracket || cur < 0) | |||
|  |         throw BridgeRuntimeError( | |||
|  |             OUSTR("Typename is wrong. ") + | |||
|  |             mapCliString(typeName)); | |||
|  | 
 | |||
|  |     typeName = typeName->Substring(0, cur + 1); | |||
|  | 
 | |||
|  |     System::Text::StringBuilder * buf = new System::Text::StringBuilder(512); | |||
|  | 
 | |||
|  |     //Put the "[]" at the beginning of the uno type name
 | |||
|  |     for (;dims--;) | |||
|  |         buf->Append(const_cast<System::String*>(Constants::usBrackets)); | |||
|  | 
 | |||
|  |     if (typeName->Equals(const_cast<System::String*>(Constants::sBoolean))) | |||
|  |         buf->Append(const_cast<System::String*>(Constants::usBool)); | |||
|  |     else if (typeName->Equals(const_cast<System::String*>(Constants::sChar))) | |||
|  |         buf->Append(const_cast<System::String*>(Constants::usChar)); | |||
|  |     else if (typeName->Equals(const_cast<System::String*>(Constants::sByte))) | |||
|  |         buf->Append(const_cast<System::String*>(Constants::usByte)); | |||
|  |     else if (typeName->Equals(const_cast<System::String*>(Constants::sInt16))) | |||
|  |         buf->Append(const_cast<System::String*>(Constants::usShort)); | |||
|  |     else if (typeName->Equals(const_cast<System::String*>(Constants::sUInt16))) | |||
|  |         buf->Append(const_cast<System::String*>(Constants::usUShort)); | |||
|  |     else if (typeName->Equals(const_cast<System::String*>(Constants::sInt32))) | |||
|  |         buf->Append(const_cast<System::String*>(Constants::usLong)); | |||
|  |     else if (typeName->Equals(const_cast<System::String*>(Constants::sUInt32))) | |||
|  |         buf->Append(const_cast<System::String*>(Constants::usULong)); | |||
|  |     else if (typeName->Equals(const_cast<System::String*>(Constants::sInt64))) | |||
|  |         buf->Append(const_cast<System::String*>(Constants::usHyper)); | |||
|  |     else if (typeName->Equals(const_cast<System::String*>(Constants::sUInt64))) | |||
|  |         buf->Append(const_cast<System::String*>(Constants::usUHyper)); | |||
|  |     else if (typeName->Equals(const_cast<System::String*>(Constants::sSingle))) | |||
|  |         buf->Append(const_cast<System::String*>(Constants::usFloat)); | |||
|  |     else if (typeName->Equals(const_cast<System::String*>(Constants::sDouble))) | |||
|  |         buf->Append(const_cast<System::String*>(Constants::usDouble)); | |||
|  |     else if (typeName->Equals(const_cast<System::String*>(Constants::sString))) | |||
|  |         buf->Append(const_cast<System::String*>(Constants::usString)); | |||
|  |     else if (typeName->Equals(const_cast<System::String*>(Constants::sVoid))) | |||
|  |         buf->Append(const_cast<System::String*>(Constants::usVoid)); | |||
|  |     else if (typeName->Equals(const_cast<System::String*>(Constants::sType))) | |||
|  |         buf->Append(const_cast<System::String*>(Constants::usType)); | |||
|  |     else if (typeName->Equals(const_cast<System::String*>(Constants::sObject))) | |||
|  |         buf->Append(const_cast<System::String*>(Constants::usXInterface)); | |||
|  |     else if (typeName->Equals(const_cast<System::String*>(Constants::sAny))) | |||
|  |         buf->Append(const_cast<System::String*>(Constants::usAny)); | |||
|  |     else | |||
|  |     { | |||
|  |         System::String * sName = mapCliPolymorphicName(typeName); | |||
|  |         int i= sName->IndexOf(L'.'); | |||
|  |         buf->Append(sName->Substring(i + 1)); | |||
|  |     } | |||
|  |     return mapCliString(buf->ToString()); | |||
|  | } | |||
|  | /** Maps uno types to dot net types.
 | |||
|  |  *  If uno_data is null then the type description is converted to System::Type | |||
|  |  */ | |||
|  | inline System::String* mapUnoString( rtl_uString const * data) | |||
|  | { | |||
|  |     OSL_ASSERT(data); | |||
|  |     return new System::String((__wchar_t*) data->buffer, 0, data->length); | |||
|  | } | |||
|  | 
 | |||
|  | OUString mapCliString(System::String const * data) | |||
|  | { | |||
|  | 
 | |||
|  |     if (data != NULL) | |||
|  |     { | |||
|  |         OSL_ASSERT(sizeof(wchar_t) == sizeof(sal_Unicode)); | |||
|  |         wchar_t const __pin * pdata= PtrToStringChars(data); | |||
|  |         return OUString(pdata, const_cast<System::String*>(data)->get_Length()); | |||
|  |     } | |||
|  |     else | |||
|  |     { | |||
|  |         return OUString(); | |||
|  |     } | |||
|  | } | |||
|  | 
 | |||
|  | // ToDo convert cli types to expected types, e.g a long to a short where the uno type
 | |||
|  | // is a sal_Int16. This could be necessary if a scripting language (typeless) is used
 | |||
|  | // @param assign the uno_data has to be destructed (in/out args)
 | |||
|  | void Bridge::map_to_uno(void * uno_data, System::Object* cli_data, | |||
|  |                         typelib_TypeDescriptionReference * type, | |||
|  |                         bool assign) const | |||
|  | { | |||
|  |     try{ | |||
|  |         switch (type->eTypeClass) | |||
|  |         { | |||
|  |         case typelib_TypeClass_VOID: | |||
|  |             break; | |||
|  |         case typelib_TypeClass_CHAR: | |||
|  |         { | |||
|  |             System::Char aChar= *__try_cast<System::Char*>(cli_data); | |||
|  |             *(sal_Unicode*) uno_data= aChar; | |||
|  |             break; | |||
|  |         } | |||
|  |         case typelib_TypeClass_BOOLEAN: | |||
|  |         { | |||
|  |             System::Boolean aBool= *__try_cast<System::Boolean*>(cli_data); | |||
|  |             *(sal_Bool*)uno_data= aBool == true ? sal_True : sal_False; | |||
|  |             break; | |||
|  |         } | |||
|  |         case typelib_TypeClass_BYTE: | |||
|  |         { | |||
|  |             System::Byte aByte= *__try_cast<System::Byte*>(cli_data); | |||
|  |             *(sal_Int8*) uno_data= aByte; | |||
|  |             break; | |||
|  |         } | |||
|  |         case typelib_TypeClass_SHORT: | |||
|  |         { | |||
|  |             System::Int16 aShort= *__try_cast<System::Int16*>(cli_data); | |||
|  |             *(sal_Int16*) uno_data= aShort; | |||
|  |             break; | |||
|  |         } | |||
|  |         case typelib_TypeClass_UNSIGNED_SHORT: | |||
|  |         { | |||
|  |             System::UInt16 aUShort= *__try_cast<System::UInt16*>(cli_data); | |||
|  |             *(sal_uInt16*) uno_data= aUShort; | |||
|  |             break; | |||
|  |         } | |||
|  |         case typelib_TypeClass_LONG: | |||
|  |         { | |||
|  |             System::Int32 aLong= *__try_cast<System::Int32*>(cli_data); | |||
|  |             *(sal_Int32*) uno_data= aLong; | |||
|  |             break; | |||
|  |         } | |||
|  |         case typelib_TypeClass_UNSIGNED_LONG: | |||
|  |         { | |||
|  |             System::UInt32 aULong= *__try_cast<System::UInt32*>(cli_data); | |||
|  |             *(sal_uInt32*) uno_data= aULong; | |||
|  |             break; | |||
|  |         } | |||
|  |         case typelib_TypeClass_HYPER: | |||
|  |         { | |||
|  |             System::Int64 aHyper= *__try_cast<System::Int64*>(cli_data); | |||
|  |             *(sal_Int64*) uno_data= aHyper; | |||
|  |             break; | |||
|  |         } | |||
|  |         case typelib_TypeClass_UNSIGNED_HYPER: | |||
|  |         { | |||
|  |             System::UInt64 aLong= *__try_cast<System::UInt64*>(cli_data); | |||
|  |             *(sal_uInt64*) uno_data= aLong; | |||
|  |             break; | |||
|  |         } | |||
|  |         case typelib_TypeClass_FLOAT: | |||
|  |         { | |||
|  |             System::Single aFloat= *__try_cast<System::Single*>(cli_data); | |||
|  |             *(float*) uno_data= aFloat; | |||
|  |             break; | |||
|  |         } | |||
|  |         case typelib_TypeClass_DOUBLE: | |||
|  |         { | |||
|  |             System::Double aDouble= *__try_cast<System::Double*>(cli_data); | |||
|  |             *(double*) uno_data= aDouble; | |||
|  |             break; | |||
|  |         } | |||
|  |         case typelib_TypeClass_STRING: | |||
|  |         { | |||
|  |             if (assign && *(rtl_uString**) uno_data) | |||
|  |                 rtl_uString_release(*(rtl_uString**) uno_data); | |||
|  | 
 | |||
|  |             *(rtl_uString **)uno_data = 0; | |||
|  |             if (cli_data == NULL) | |||
|  |             { | |||
|  |                  rtl_uString_new((rtl_uString**) uno_data); | |||
|  |             } | |||
|  |             else | |||
|  |             { | |||
|  |                 System::String *s= __try_cast<System::String*>(cli_data); | |||
|  |                 wchar_t const __pin * pdata= PtrToStringChars(s); | |||
|  |                 rtl_uString_newFromStr_WithLength( (rtl_uString**) uno_data, | |||
|  |                                                   pdata, s->get_Length() ); | |||
|  |             } | |||
|  |             break; | |||
|  |         } | |||
|  |         case typelib_TypeClass_TYPE: | |||
|  |         { | |||
|  |             typelib_TypeDescriptionReference* td= mapCliType(__try_cast<System::Type*>( | |||
|  |                                                                     cli_data)); | |||
|  |             if (assign) | |||
|  |             { | |||
|  |                 typelib_typedescriptionreference_release( | |||
|  |                     *(typelib_TypeDescriptionReference **)uno_data ); | |||
|  |             } | |||
|  |             *(typelib_TypeDescriptionReference **)uno_data = td; | |||
|  |             break; | |||
|  |         } | |||
|  |         case typelib_TypeClass_ANY: | |||
|  |         { | |||
|  |             uno_Any * pAny = (uno_Any *)uno_data; | |||
|  |             if (cli_data == NULL) // null-ref or uninitialized any maps to empty any
 | |||
|  |             { | |||
|  |                 if (assign) | |||
|  |                     uno_any_destruct( pAny, 0 ); | |||
|  |                 uno_any_construct( pAny, 0, 0, 0 ); | |||
|  |                 break; | |||
|  |             } | |||
|  |             uno::Any aAny= *__try_cast<uno::Any*>(cli_data); | |||
|  |             css::uno::Type  value_td( mapCliType(aAny.Type), SAL_NO_ACQUIRE); | |||
|  | 
 | |||
|  |             if (assign) | |||
|  |                 uno_any_destruct( pAny, 0 ); | |||
|  | 
 | |||
|  |             try | |||
|  |             { | |||
|  |                 switch (value_td.getTypeClass()) | |||
|  |                 { | |||
|  |                 case typelib_TypeClass_VOID: | |||
|  |                     pAny->pData = &pAny->pReserved; | |||
|  |                     break; | |||
|  |                 case typelib_TypeClass_CHAR: | |||
|  |                     pAny->pData = &pAny->pReserved; | |||
|  |                     *(sal_Unicode*) &pAny->pReserved = *__try_cast<System::Char*>(aAny.Value); | |||
|  |                     break; | |||
|  |                 case typelib_TypeClass_BOOLEAN: | |||
|  |                     pAny->pData = &pAny->pReserved; | |||
|  |                     *(sal_Bool *) &pAny->pReserved = *__try_cast<System::Boolean*>(aAny.Value); | |||
|  |                     break; | |||
|  |                 case typelib_TypeClass_BYTE: | |||
|  |                     pAny->pData = &pAny->pReserved; | |||
|  |                     *(sal_Int8*) &pAny->pReserved =  *__try_cast<System::Byte*>(aAny.Value); | |||
|  |                     break; | |||
|  |                 case typelib_TypeClass_SHORT: | |||
|  |                     pAny->pData = &pAny->pReserved; | |||
|  |                     *(sal_Int16*) &pAny->pReserved =  *__try_cast<System::Int16*>(aAny.Value); | |||
|  |                     break; | |||
|  |                 case typelib_TypeClass_UNSIGNED_SHORT: | |||
|  |                     pAny->pData = &pAny->pReserved; | |||
|  |                     *(sal_uInt16*) &pAny->pReserved =  *__try_cast<System::UInt16*>(aAny.Value); | |||
|  |                     break; | |||
|  |                 case typelib_TypeClass_LONG: | |||
|  |                     pAny->pData = &pAny->pReserved; | |||
|  |                     *(sal_Int32*) &pAny->pReserved =  *__try_cast<System::Int32*>(aAny.Value); | |||
|  |                     break; | |||
|  |                 case typelib_TypeClass_UNSIGNED_LONG: | |||
|  |                     pAny->pData = &pAny->pReserved; | |||
|  |                     *(sal_uInt32*) &pAny->pReserved =  *__try_cast<System::UInt32*>(aAny.Value); | |||
|  |                     break; | |||
|  |                 case typelib_TypeClass_HYPER: | |||
|  |                     if (sizeof (sal_Int64) <= sizeof (void *)) | |||
|  |                     { | |||
|  |                         pAny->pData = &pAny->pReserved; | |||
|  |                         *(sal_Int64*) &pAny->pReserved = *__try_cast<System::Int64*>(aAny.Value); | |||
|  |                     } | |||
|  |                     else | |||
|  |                     { | |||
|  |                         auto_ptr< rtl_mem > mem( rtl_mem::allocate( sizeof (sal_Int64) ) ); | |||
|  |                         *(sal_Int64 *) mem.get()=  *__try_cast<System::Int64*>(aAny.Value); | |||
|  |                         pAny->pData = mem.release(); | |||
|  |                     } | |||
|  |                     break; | |||
|  |                 case typelib_TypeClass_UNSIGNED_HYPER: | |||
|  |                     if (sizeof (sal_uInt64) <= sizeof (void *)) | |||
|  |                     { | |||
|  |                         pAny->pData = &pAny->pReserved; | |||
|  |                         *(sal_uInt64*) &pAny->pReserved = *__try_cast<System::UInt64*>(aAny.Value); | |||
|  |                     } | |||
|  |                     else | |||
|  |                     { | |||
|  |                         auto_ptr< rtl_mem > mem( rtl_mem::allocate( sizeof (sal_uInt64) ) ); | |||
|  |                         *(sal_uInt64 *) mem.get()=  *__try_cast<System::UInt64*>(aAny.Value); | |||
|  |                         pAny->pData = mem.release(); | |||
|  |                     } | |||
|  |                     break; | |||
|  |                 case typelib_TypeClass_FLOAT: | |||
|  |                     if (sizeof (float) <= sizeof (void *)) | |||
|  |                     { | |||
|  |                         pAny->pData = &pAny->pReserved; | |||
|  |                         *(float*) &pAny->pReserved = *__try_cast<System::Single*>(aAny.Value); | |||
|  |                     } | |||
|  |                     else | |||
|  |                     { | |||
|  |                         auto_ptr< rtl_mem > mem( rtl_mem::allocate( sizeof (float) ) ); | |||
|  |                         *(float*) mem.get() = *__try_cast<System::Single*>(aAny.Value); | |||
|  |                         pAny->pData = mem.release(); | |||
|  |                     } | |||
|  |                     break; | |||
|  |                 case typelib_TypeClass_DOUBLE: | |||
|  |                     if (sizeof (double) <= sizeof (void *)) | |||
|  |                     { | |||
|  |                         pAny->pData = &pAny->pReserved; | |||
|  |                         *(double*) &pAny->pReserved= *__try_cast<System::Double*>(aAny.Value); | |||
|  |                     } | |||
|  |                     else | |||
|  |                     { | |||
|  |                         auto_ptr< rtl_mem > mem( rtl_mem::allocate( sizeof (double) ) ); | |||
|  |                         *(double*) mem.get()= *__try_cast<System::Double*>(aAny.Value); | |||
|  |                         pAny->pData= mem.release(); | |||
|  |                     } | |||
|  |                     break; | |||
|  |                 case typelib_TypeClass_STRING: // anies often contain strings; copy string directly
 | |||
|  |                 { | |||
|  |                     pAny->pData= &pAny->pReserved; | |||
|  |                     OUString _s = mapCliString(static_cast<System::String*>(aAny.Value)); | |||
|  |                     pAny->pReserved= _s.pData; | |||
|  |                     rtl_uString_acquire(_s.pData); | |||
|  |                     break; | |||
|  |                 } | |||
|  |                 case typelib_TypeClass_TYPE: | |||
|  |                 case typelib_TypeClass_ENUM:  //ToDo copy enum direct
 | |||
|  |                 case typelib_TypeClass_SEQUENCE: | |||
|  |                 case typelib_TypeClass_INTERFACE: | |||
|  |                     pAny->pData = &pAny->pReserved; | |||
|  |                     pAny->pReserved = 0; | |||
|  |                     map_to_uno( | |||
|  |                         &pAny->pReserved, aAny.Value, value_td.getTypeLibType(), | |||
|  |                                                   false /* no assign */); | |||
|  |                     break; | |||
|  |                 case typelib_TypeClass_STRUCT: | |||
|  |                 case typelib_TypeClass_EXCEPTION: | |||
|  |                 { | |||
|  |                     css::uno::Type anyType(value_td); | |||
|  |                     typelib_TypeDescription* td= NULL; | |||
|  |                     anyType.getDescription(&td); | |||
|  |                     auto_ptr< rtl_mem > mem(rtl_mem::allocate(td->nSize)); | |||
|  |                     typelib_typedescription_release(td); | |||
|  |                     map_to_uno( | |||
|  |                         mem.get(), aAny.Value, value_td.getTypeLibType(), | |||
|  |                         false /* no assign */); | |||
|  |                     pAny->pData = mem.release(); | |||
|  |                     break; | |||
|  |                 } | |||
|  |                 default: | |||
|  |                 { | |||
|  |                     OUStringBuffer buf( 128 ); | |||
|  |                     buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") ); | |||
|  |                     buf.append(value_td.getTypeName()); | |||
|  |                     buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] unsupported value type of any!") ); | |||
|  |                     throw BridgeRuntimeError( buf.makeStringAndClear() ); | |||
|  |                 } | |||
|  |                 } | |||
|  |             } | |||
|  |             catch(System::InvalidCastException* ) | |||
|  |             { | |||
|  | // ToDo check this
 | |||
|  |                 if (assign) | |||
|  |                     uno_any_construct( pAny, 0, 0, 0 ); // restore some valid any
 | |||
|  |                 OUStringBuffer buf( 256 ); | |||
|  |                 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():Any") ); | |||
|  |                 buf.append(value_td.getTypeName()); | |||
|  |                 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("]The Any type ")); | |||
|  |                 buf.append(value_td.getTypeName()); | |||
|  |                 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" does not correspont  " | |||
|  |                                                             "to its value type: ") ); | |||
|  |                 if(aAny.Value != NULL) | |||
|  |                 { | |||
|  |                     css::uno::Type td(mapCliType(aAny.Value->GetType()), SAL_NO_ACQUIRE); | |||
|  |                     buf.append(td.getTypeName()); | |||
|  |                 } | |||
|  |                 if (assign) | |||
|  |                     uno_any_construct( pAny, 0, 0, 0 ); // restore some valid any
 | |||
|  |                 throw BridgeRuntimeError( buf.makeStringAndClear() ); | |||
|  |             } | |||
|  |             catch (BridgeRuntimeError& ) | |||
|  |             { | |||
|  |                 if (assign) | |||
|  |                     uno_any_construct( pAny, 0, 0, 0 ); // restore some valid any
 | |||
|  |                 throw; | |||
|  |             } | |||
|  |             catch (...) | |||
|  |             { | |||
|  |                 if (assign) | |||
|  |                     uno_any_construct( pAny, 0, 0, 0 ); // restore some valid any
 | |||
|  |                 throw; | |||
|  |             } | |||
|  | 
 | |||
|  |             pAny->pType = value_td.getTypeLibType(); | |||
|  |             typelib_typedescriptionreference_acquire(pAny->pType); | |||
|  |             break; | |||
|  |         } | |||
|  |         case typelib_TypeClass_ENUM: | |||
|  |         { | |||
|  |             // InvalidCastException is caught at the end of this method
 | |||
|  |             System::Int32 aEnum= System::Convert::ToInt32((cli_data)); | |||
|  |             *(sal_Int32*) uno_data = aEnum; | |||
|  |             break; | |||
|  |         } | |||
|  |         case typelib_TypeClass_STRUCT: | |||
|  |         case typelib_TypeClass_EXCEPTION: | |||
|  |         { | |||
|  |             css::uno::TypeDescription td(type); | |||
|  |             typelib_CompoundTypeDescription * comp_td = | |||
|  |                 (typelib_CompoundTypeDescription*) td.get(); | |||
|  | 
 | |||
|  |             typelib_StructTypeDescription * struct_td = NULL; | |||
|  |             if (type->eTypeClass == typelib_TypeClass_STRUCT) | |||
|  |                 struct_td = (typelib_StructTypeDescription*) td.get(); | |||
|  | 
 | |||
|  |             if ( ! ((typelib_TypeDescription*) comp_td)->bComplete) | |||
|  |                 ::typelib_typedescription_complete( | |||
|  |                     (typelib_TypeDescription**) & comp_td ); | |||
|  | 
 | |||
|  |             sal_Int32 nMembers = comp_td->nMembers; | |||
|  |             boolean bException= false; | |||
|  |             System::Type* cliType = NULL; | |||
|  |             if (cli_data) | |||
|  |                 cliType = cli_data->GetType(); | |||
|  | 
 | |||
|  |             if (0 != comp_td->pBaseTypeDescription) | |||
|  |             { | |||
|  |                 map_to_uno( | |||
|  |                     uno_data, cli_data, | |||
|  |                     ((typelib_TypeDescription *)comp_td->pBaseTypeDescription)->pWeakRef, | |||
|  |                     assign); | |||
|  |             } | |||
|  |             sal_Int32 nPos = 0; | |||
|  |             try | |||
|  |             { | |||
|  |                 typelib_TypeDescriptionReference * member_type= NULL; | |||
|  | 
 | |||
|  |                 rtl::OUString usUnoException(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.Exception")); | |||
|  |                 for (; nPos < nMembers; ++nPos) | |||
|  |                 { | |||
|  |                     member_type= comp_td->ppTypeRefs[nPos]; | |||
|  | #if OSL_DEBUG_LEVEL >= 2
 | |||
|  |                     System::String* __s; | |||
|  |                     sr::FieldInfo* arFields[]; | |||
|  |                     __s = mapUnoString(comp_td->ppMemberNames[nPos]); | |||
|  |                     arFields = cliType != NULL ? cliType->GetFields() : NULL; | |||
|  | #endif
 | |||
|  |                     System::Object* val= NULL; | |||
|  |                     if (cli_data != NULL) | |||
|  |                     { | |||
|  |                         sr::FieldInfo* aField= cliType->GetField( | |||
|  |                             mapUnoString(comp_td->ppMemberNames[nPos])); | |||
|  |                         // special case for Exception.Message property
 | |||
|  |                         // The com.sun.star.uno.Exception.Message field is mapped to the
 | |||
|  |                         // System.Exception property. Type.GetField("Message") returns null
 | |||
|  |                         if ( ! aField && usUnoException.equals(td.get()->pTypeName)) | |||
|  |                         {// get Exception.Message property
 | |||
|  |                             rtl::OUString usMessageMember(RTL_CONSTASCII_USTRINGPARAM("Message")); | |||
|  |                             if (usMessageMember.equals(comp_td->ppMemberNames[nPos])) | |||
|  |                             { | |||
|  |                                 sr::PropertyInfo* pi= cliType->GetProperty( | |||
|  |                                     mapUnoString(comp_td->ppMemberNames[nPos])); | |||
|  |                                 val= pi->GetValue(cli_data, NULL); | |||
|  |                             } | |||
|  |                             else | |||
|  |                             { | |||
|  |                                 OUStringBuffer buf(512); | |||
|  |                                 buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("[map_to_uno(): Member: ")); | |||
|  |                                 buf.append(comp_td->ppMemberNames[nPos]); | |||
|  |                                 throw BridgeRuntimeError(buf.makeStringAndClear()); | |||
|  |                             } | |||
|  |                         } | |||
|  |                         else | |||
|  |                         { | |||
|  |                             val= aField->GetValue(cli_data); | |||
|  |                         } | |||
|  |                     } | |||
|  |                     void * p = (char *) uno_data + comp_td->pMemberOffsets[ nPos ]; | |||
|  |                     //When using polymorphic structs then the parameterized members can be null.
 | |||
|  |                     //Then we set a default value.
 | |||
|  |                     bool bDefault = ((struct_td != NULL | |||
|  |                                      && struct_td->pParameterizedTypes != NULL | |||
|  |                                      && struct_td->pParameterizedTypes[nPos] == sal_True | |||
|  |                                       && val == NULL) | |||
|  |                                      || cli_data == NULL) ? true : false; | |||
|  |                     switch (member_type->eTypeClass) | |||
|  |                     { | |||
|  |                     case typelib_TypeClass_CHAR: | |||
|  |                         if (bDefault) | |||
|  |                             *(sal_Unicode*) p = 0; | |||
|  |                         else | |||
|  |                             *(sal_Unicode*) p = *__try_cast<System::Char*>(val); | |||
|  |                         break; | |||
|  |                     case typelib_TypeClass_BOOLEAN: | |||
|  |                         if (bDefault) | |||
|  |                             *(sal_Bool*) p = sal_False; | |||
|  |                         else | |||
|  |                             *(sal_Bool*) p = *__try_cast<System::Boolean*>(val); | |||
|  |                         break; | |||
|  |                     case typelib_TypeClass_BYTE: | |||
|  |                         if (bDefault) | |||
|  |                             *(sal_Int8*) p = 0; | |||
|  |                         else | |||
|  |                             *(sal_Int8*) p = *__try_cast<System::Byte*>(val); | |||
|  |                         break; | |||
|  |                     case typelib_TypeClass_SHORT: | |||
|  |                         if (bDefault) | |||
|  |                             *(sal_Int16*) p = 0; | |||
|  |                         else | |||
|  |                             *(sal_Int16*) p = *__try_cast<System::Int16*>(val); | |||
|  |                         break; | |||
|  |                     case typelib_TypeClass_UNSIGNED_SHORT: | |||
|  |                         if (bDefault) | |||
|  |                             *(sal_uInt16*) p = 0; | |||
|  |                         else | |||
|  |                             *(sal_uInt16*) p = *__try_cast<System::UInt16*>(val); | |||
|  |                         break; | |||
|  |                     case typelib_TypeClass_LONG: | |||
|  |                         if (bDefault) | |||
|  |                             *(sal_Int32*) p = 0; | |||
|  |                         else | |||
|  |                             *(sal_Int32*) p = *__try_cast<System::Int32*>(val); | |||
|  |                         break; | |||
|  |                     case typelib_TypeClass_UNSIGNED_LONG: | |||
|  |                         if (bDefault) | |||
|  |                             *(sal_uInt32*) p = 0; | |||
|  |                         else | |||
|  |                             *(sal_uInt32*) p = *__try_cast<System::UInt32*>(val); | |||
|  |                         break; | |||
|  |                     case typelib_TypeClass_HYPER: | |||
|  |                         if (bDefault) | |||
|  |                             *(sal_Int64*) p = 0; | |||
|  |                         else | |||
|  |                             *(sal_Int64*) p = *__try_cast<System::Int64*>(val); | |||
|  |                         break; | |||
|  |                     case typelib_TypeClass_UNSIGNED_HYPER: | |||
|  |                         if (bDefault) | |||
|  |                             *(sal_uInt64*) p = 0; | |||
|  |                         else | |||
|  |                             *(sal_uInt64*) p= *__try_cast<System::UInt64*>(val); | |||
|  |                         break; | |||
|  |                     case typelib_TypeClass_FLOAT: | |||
|  |                         if (bDefault) | |||
|  |                             *(float*) p = 0.; | |||
|  |                         else | |||
|  |                             *(float*) p = *__try_cast<System::Single*>(val); | |||
|  |                         break; | |||
|  |                     case typelib_TypeClass_DOUBLE: | |||
|  |                         if (bDefault) | |||
|  |                             *(double*) p = 0.; | |||
|  |                         else | |||
|  |                             *(double*) p = *__try_cast<System::Double*>(val); | |||
|  |                         break; | |||
|  |                     default: | |||
|  |                     {   // ToDo enum, should be converted here
 | |||
|  |                          map_to_uno(p, val, member_type, assign); | |||
|  |                         break; | |||
|  |                     } | |||
|  |                     } | |||
|  |                 } | |||
|  |             } | |||
|  |             catch (BridgeRuntimeError& e) | |||
|  |             { | |||
|  |                 bException= true; | |||
|  |                 OUStringBuffer buf(512); | |||
|  |                 buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("[map_to_uno():")); | |||
|  |                 if (cliType) | |||
|  |                 { | |||
|  |                     buf.append(mapCliString(cliType->get_FullName())); | |||
|  |                     buf.appendAscii(RTL_CONSTASCII_STRINGPARAM(".")); | |||
|  |                     buf.append(comp_td->ppMemberNames[nPos]); | |||
|  |                     buf.appendAscii(RTL_CONSTASCII_STRINGPARAM(" ")); | |||
|  |                 } | |||
|  |                 buf.append(e.m_message); | |||
|  |                 throw BridgeRuntimeError(buf.makeStringAndClear()); | |||
|  |             } | |||
|  |             catch (System::InvalidCastException* ) | |||
|  |             { | |||
|  |                 bException= true; | |||
|  |                 OUStringBuffer buf( 256 ); | |||
|  |                 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") ); | |||
|  |                 if (cliType) | |||
|  |                 { | |||
|  |                     buf.append(mapCliString(cliType->get_FullName())); | |||
|  |                     buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(".")); | |||
|  |                     buf.append(comp_td->ppMemberNames[nPos]); | |||
|  |                 } | |||
|  |                 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] Value has not the required type.")); | |||
|  |                 throw BridgeRuntimeError(buf.makeStringAndClear()); | |||
|  |             } | |||
|  |             catch (...) | |||
|  |             { | |||
|  |                 OSL_ASSERT(0); | |||
|  |                 bException= true; | |||
|  |                 throw; | |||
|  |             } | |||
|  |             __finally | |||
|  |             { | |||
|  |                 if (bException && !assign) // if assign then caller cleans up
 | |||
|  |                 { | |||
|  |                     // cleanup the members which we have converted so far
 | |||
|  |                     for ( sal_Int32 nCleanup = 0; nCleanup < nPos; ++nCleanup ) | |||
|  |                     { | |||
|  |                         uno_type_destructData( | |||
|  |                             uno_data, comp_td->ppTypeRefs[ nCleanup ], 0 ); | |||
|  |                     } | |||
|  |                     if (0 != comp_td->pBaseTypeDescription) | |||
|  |                     { | |||
|  |                         uno_destructData( | |||
|  |                             uno_data, (typelib_TypeDescription *)comp_td->pBaseTypeDescription, 0 ); | |||
|  |                     } | |||
|  |                 } | |||
|  |             } | |||
|  |             break; | |||
|  |         } | |||
|  |         case typelib_TypeClass_SEQUENCE: | |||
|  |         { | |||
|  |             TypeDescr td( type ); | |||
|  |             typelib_TypeDescriptionReference * element_type = | |||
|  |                 ((typelib_IndirectTypeDescription *)td.get())->pType; | |||
|  | 
 | |||
|  |             auto_ptr< rtl_mem > seq; | |||
|  | 
 | |||
|  |             System::Array* ar = NULL; | |||
|  |             if (cli_data != NULL) | |||
|  |             { | |||
|  |                 ar = __try_cast<System::Array*>(cli_data); | |||
|  |                 sal_Int32 nElements = ar->GetLength(0); | |||
|  | 
 | |||
|  |                 try | |||
|  |                 { | |||
|  |                     switch (element_type->eTypeClass) | |||
|  |                     { | |||
|  |                     case typelib_TypeClass_CHAR: | |||
|  |                         seq = seq_allocate(nElements, sizeof (sal_Unicode)); | |||
|  |                         sri::Marshal::Copy(__try_cast<System::Char[]>(cli_data), 0, | |||
|  |                                            & ((uno_Sequence*) seq.get())->elements, nElements); | |||
|  |                         break; | |||
|  |                     case typelib_TypeClass_BOOLEAN: | |||
|  |                         seq = seq_allocate(nElements, sizeof (sal_Bool)); | |||
|  |                         sri::Marshal::Copy(__try_cast<System::Boolean[]>(cli_data), 0, | |||
|  |                                            & ((uno_Sequence*) seq.get())->elements, nElements); | |||
|  |                         break; | |||
|  |                     case typelib_TypeClass_BYTE: | |||
|  |                         seq = seq_allocate( nElements, sizeof (sal_Int8) ); | |||
|  |                     sri::Marshal::Copy(__try_cast<System::Byte[]>(cli_data), 0, | |||
|  |                                        & ((uno_Sequence*) seq.get())->elements, nElements); | |||
|  |                     break; | |||
|  |                     case typelib_TypeClass_SHORT: | |||
|  |                         seq = seq_allocate(nElements, sizeof (sal_Int16)); | |||
|  |                         sri::Marshal::Copy(__try_cast<System::Int16[]>(cli_data), 0, | |||
|  |                                            & ((uno_Sequence*) seq.get())->elements, nElements); | |||
|  |                         break; | |||
|  |                     case typelib_TypeClass_UNSIGNED_SHORT: | |||
|  |                         seq = seq_allocate( nElements, sizeof (sal_uInt16) ); | |||
|  |                         sri::Marshal::Copy(static_cast<System::Int16[]>( | |||
|  |                                                __try_cast<System::UInt16[]>(cli_data)), 0, | |||
|  |                                            & ((uno_Sequence*) seq.get())->elements, nElements); | |||
|  |                         break; | |||
|  |                     case typelib_TypeClass_LONG: | |||
|  |                         seq = seq_allocate(nElements, sizeof (sal_Int32)); | |||
|  |                         sri::Marshal::Copy(__try_cast<System::Int32[]>(cli_data), 0, | |||
|  |                                            & ((uno_Sequence*) seq.get())->elements, nElements); | |||
|  |                         break; | |||
|  |                     case typelib_TypeClass_UNSIGNED_LONG: | |||
|  |                         seq = seq_allocate( nElements, sizeof (sal_uInt32) ); | |||
|  |                         sri::Marshal::Copy(static_cast<System::Int32[]>( | |||
|  |                                                __try_cast<System::UInt32[]>(cli_data)), 0, | |||
|  |                                            & ((uno_Sequence*) seq.get())->elements, nElements); | |||
|  |                         break; | |||
|  |                     case typelib_TypeClass_HYPER: | |||
|  |                         seq = seq_allocate(nElements, sizeof (sal_Int64)); | |||
|  |                         sri::Marshal::Copy(__try_cast<System::Int64[]>(cli_data), 0, | |||
|  |                                            & ((uno_Sequence*) seq.get())->elements, nElements); | |||
|  |                         break; | |||
|  |                     case typelib_TypeClass_UNSIGNED_HYPER: | |||
|  |                         seq = seq_allocate(nElements, sizeof (sal_uInt64)); | |||
|  |                         sri::Marshal::Copy(static_cast<System::Int64[]>( | |||
|  |                                                __try_cast<System::UInt64[]>(cli_data)), 0, | |||
|  |                                            & ((uno_Sequence*) seq.get())->elements, nElements); | |||
|  |                         break; | |||
|  |                     case typelib_TypeClass_FLOAT: | |||
|  |                         seq = seq_allocate(nElements, sizeof (float)); | |||
|  |                         sri::Marshal::Copy(__try_cast<System::Single[]>(cli_data), 0, | |||
|  |                                            & ((uno_Sequence*) seq.get())->elements, nElements); | |||
|  |                         break; | |||
|  |                     case typelib_TypeClass_DOUBLE: | |||
|  |                         seq = seq_allocate(nElements, sizeof (double)); | |||
|  |                         sri::Marshal::Copy(__try_cast<System::Double[]>(cli_data), 0, | |||
|  |                                            & ((uno_Sequence*) seq.get())->elements, nElements); | |||
|  |                         break; | |||
|  |                     case typelib_TypeClass_STRING: | |||
|  |                     { | |||
|  |                         seq = seq_allocate(nElements, sizeof (rtl_uString*)); | |||
|  |                         System::String* arStr[]= __try_cast<System::String*[]>(cli_data); | |||
|  |                         for (int i= 0; i < nElements; i++) | |||
|  |                         { | |||
|  |                             wchar_t const __pin * pdata= PtrToStringChars(arStr[i]); | |||
|  |                             rtl_uString** pStr=  & ((rtl_uString**) & | |||
|  |                                                     ((uno_Sequence*) seq.get())->elements)[i]; | |||
|  |                             *pStr= NULL; | |||
|  |                             rtl_uString_newFromStr_WithLength( pStr, pdata, | |||
|  |                                                                arStr[i]->get_Length()); | |||
|  |                         } | |||
|  |                         break; | |||
|  |                     } | |||
|  |                     case typelib_TypeClass_ENUM: | |||
|  |                         seq = seq_allocate(nElements, sizeof (sal_Int32)); | |||
|  |                         for (int i= 0; i < nElements; i++) | |||
|  |                         { | |||
|  |                             ((sal_Int32*) &((uno_Sequence*) seq.get())->elements)[i]= | |||
|  |                                 System::Convert::ToInt32(ar->GetValue(i)); | |||
|  |                         } | |||
|  |                         break; | |||
|  |                     case typelib_TypeClass_TYPE: | |||
|  |                     case typelib_TypeClass_ANY: | |||
|  |                     case typelib_TypeClass_STRUCT: | |||
|  |                     case typelib_TypeClass_EXCEPTION: | |||
|  |                     case typelib_TypeClass_SEQUENCE: | |||
|  |                     case typelib_TypeClass_INTERFACE: | |||
|  |                     { | |||
|  |                         TypeDescr element_td( element_type ); | |||
|  |                         seq = seq_allocate( nElements, element_td.get()->nSize ); | |||
|  | 
 | |||
|  |                         for (sal_Int32 nPos = 0; nPos < nElements; ++nPos) | |||
|  |                         { | |||
|  |                             try | |||
|  |                             { | |||
|  |                                 void * p= ((uno_Sequence *) seq.get())->elements + | |||
|  |                                     (nPos * element_td.get()->nSize); | |||
|  |                                 System::Object* elemData= dynamic_cast<System::Array*>(cli_data)->GetValue(nPos); | |||
|  |                                 map_to_uno( | |||
|  |                                     p, elemData, element_td.get()->pWeakRef, | |||
|  |                                     false /* no assign */); | |||
|  |                             } | |||
|  |                             catch (...) | |||
|  |                             { | |||
|  |                                 // cleanup
 | |||
|  |                                 for ( sal_Int32 nCleanPos = 0; nCleanPos < nPos; ++nCleanPos ) | |||
|  |                                 { | |||
|  |                                     void * p = | |||
|  |                                         ((uno_Sequence *)seq.get())->elements + | |||
|  |                                         (nCleanPos * element_td.get()->nSize); | |||
|  |                                     uno_destructData( p, element_td.get(), 0 ); | |||
|  |                                 } | |||
|  |                                 throw; | |||
|  |                             } | |||
|  |                         } | |||
|  |                         break; | |||
|  |                     } | |||
|  |                     default: | |||
|  |                     { | |||
|  |                         OUStringBuffer buf( 128 ); | |||
|  |                         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") ); | |||
|  |                         buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName ) ); | |||
|  |                         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] unsupported sequence element type: ") ); | |||
|  |                         buf.append( *reinterpret_cast< OUString const * >( &element_type->pTypeName ) ); | |||
|  |                         throw BridgeRuntimeError( buf.makeStringAndClear() ); | |||
|  |                     } | |||
|  |                     } | |||
|  |                 } | |||
|  |                 catch (BridgeRuntimeError& e) | |||
|  |                 { | |||
|  |                     OUStringBuffer buf( 128 ); | |||
|  |                     buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") ); | |||
|  |                     buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName )); | |||
|  |                     buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] conversion failed\n ")); | |||
|  |                     buf.append(e.m_message); | |||
|  |                     throw BridgeRuntimeError(buf.makeStringAndClear()); | |||
|  |                 } | |||
|  |                 catch (System::InvalidCastException* ) | |||
|  |                 { | |||
|  |                     // Ok, checked
 | |||
|  |                     OUStringBuffer buf( 128 ); | |||
|  |                     buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") ); | |||
|  |                     buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName) ); | |||
|  |                     buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] could not convert sequence element type: ") ); | |||
|  |                     buf.append( *reinterpret_cast< OUString const * >( &element_type->pTypeName ) ); | |||
|  |                     throw BridgeRuntimeError( buf.makeStringAndClear() ); | |||
|  |                 } | |||
|  |                 catch (...) | |||
|  |                 { | |||
|  |                     OSL_ASSERT(0); | |||
|  |                     throw; | |||
|  |                 } | |||
|  |                 __finally | |||
|  |                     { | |||
|  |                         if (assign) | |||
|  |                             uno_destructData( uno_data, td.get(), 0 ); | |||
|  |                     } | |||
|  |             } | |||
|  |             else | |||
|  |             { | |||
|  |                 seq = seq_allocate(0, sizeof (sal_Int32)); | |||
|  |             } | |||
|  |             *(uno_Sequence **)uno_data = (uno_Sequence *)seq.release(); | |||
|  |             break; | |||
|  |         } | |||
|  |         case typelib_TypeClass_INTERFACE: | |||
|  |         { | |||
|  |             if (assign) | |||
|  |             { | |||
|  |                 uno_Interface * p = *(uno_Interface **)uno_data; | |||
|  |                 if (0 != p) | |||
|  |                     (*p->release)( p ); | |||
|  |             } | |||
|  |             if (0 == cli_data) // null-ref
 | |||
|  |             { | |||
|  |                 *(uno_Interface **)uno_data = 0; | |||
|  |             } | |||
|  |             else | |||
|  |             { | |||
|  |                 TypeDescr td( type ); | |||
|  |                 uno_Interface * pUnoI = map_cli2uno(cli_data, td.get()); | |||
|  |                 *(uno_Interface **)uno_data = pUnoI; | |||
|  |             } | |||
|  |             break; | |||
|  |         } | |||
|  |         default: | |||
|  |         { | |||
|  |             //ToDo check
 | |||
|  |             OUStringBuffer buf( 128 ); | |||
|  |             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") ); | |||
|  |             buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName ) ); | |||
|  |             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] unsupported type!") ); | |||
|  |             throw BridgeRuntimeError( buf.makeStringAndClear() ); | |||
|  |         } | |||
|  |         } | |||
|  |     } | |||
|  |     // BridgeRuntimeError are allowed to be thrown
 | |||
|  |     catch (System::InvalidCastException* ) | |||
|  |     { | |||
|  |         //ToDo check
 | |||
|  |         OUStringBuffer buf( 128 ); | |||
|  |         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") ); | |||
|  |         buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName ) ); | |||
|  |         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] could not convert type!") ); | |||
|  |         throw BridgeRuntimeError( buf.makeStringAndClear() ); | |||
|  |     } | |||
|  |     catch (System::NullReferenceException * e) | |||
|  |     { | |||
|  |         OUStringBuffer buf(512); | |||
|  |         buf.appendAscii(RTL_CONSTASCII_STRINGPARAM( | |||
|  |                              "[map_to_uno()] Illegal null reference passed!\n")); | |||
|  |         buf.append(mapCliString(e->get_StackTrace())); | |||
|  |         throw BridgeRuntimeError( buf.makeStringAndClear() ); | |||
|  |     } | |||
|  |     catch (BridgeRuntimeError& ) | |||
|  |     { | |||
|  |         throw; | |||
|  |     } | |||
|  |     catch (...) | |||
|  |     { | |||
|  |         OSL_ASSERT(0); | |||
|  |         throw; | |||
|  |     } | |||
|  | 
 | |||
|  | } | |||
|  | 
 | |||
|  | /**
 | |||
|  |    @param info | |||
|  |        The expected target type. Currently info is provdided when this method is called | |||
|  |        to convert the in/out and out parameters of a call from cli to uno. Then info | |||
|  |        is always a byref type, e.g. "System.String&". info is used for Any and Enum conversion. | |||
|  |    @param bDontCreateObj | |||
|  |        false - a new object is created which holds the mapped uno value and is assigned to | |||
|  |        cli_data. | |||
|  |        true - cli_data already contains the newly constructed object. This is the case if | |||
|  |        a struct is converted then on the first call to map_to_cli the new object is created. | |||
|  |        If the struct inherits another struct then this function is called recursivly while the | |||
|  |        newly created object is passed in cli_data. | |||
|  |  */ | |||
|  | void Bridge::map_to_cli( | |||
|  |     System::Object* *cli_data, void const * uno_data, | |||
|  |     typelib_TypeDescriptionReference * type, System::Type* info, | |||
|  |     bool bDontCreateObj) const | |||
|  | { | |||
|  |     switch (type->eTypeClass) | |||
|  |     { | |||
|  |     case typelib_TypeClass_CHAR: | |||
|  |         *cli_data= __box(*(__wchar_t const*)uno_data); | |||
|  |         break; | |||
|  |     case typelib_TypeClass_BOOLEAN: | |||
|  |         *cli_data = __box((*(bool const*)uno_data) == sal_True ? true : false); | |||
|  |         break; | |||
|  |     case typelib_TypeClass_BYTE: | |||
|  |         *cli_data = __box(*(unsigned char const*) uno_data); | |||
|  |         break; | |||
|  |     case typelib_TypeClass_SHORT: | |||
|  |         *cli_data= __box(*(short const*) uno_data); | |||
|  |         break; | |||
|  |     case typelib_TypeClass_UNSIGNED_SHORT: | |||
|  |         *cli_data= __box(*(unsigned short const*) uno_data); | |||
|  |         break; | |||
|  |     case typelib_TypeClass_LONG: | |||
|  |         *cli_data= __box(*(int const*) uno_data); | |||
|  |         break; | |||
|  |     case typelib_TypeClass_UNSIGNED_LONG: | |||
|  |         *cli_data= __box(*(unsigned int const*) uno_data); | |||
|  |         break; | |||
|  |     case typelib_TypeClass_HYPER: | |||
|  |         *cli_data= __box(*(__int64 const*) uno_data); | |||
|  |         break; | |||
|  |     case typelib_TypeClass_UNSIGNED_HYPER: | |||
|  |         *cli_data= __box(*(unsigned __int64 const*) uno_data); | |||
|  |         break; | |||
|  |     case typelib_TypeClass_FLOAT: | |||
|  |         *cli_data= __box(*(float const*) uno_data); | |||
|  |         break; | |||
|  |     case typelib_TypeClass_DOUBLE: | |||
|  |         *cli_data= __box(*(double const*) uno_data); | |||
|  |         break; | |||
|  |     case typelib_TypeClass_STRING: | |||
|  |     { | |||
|  |         rtl_uString const* sVal= NULL; | |||
|  |         sVal= *(rtl_uString* const*) uno_data; | |||
|  |         *cli_data= new System::String((__wchar_t*) sVal->buffer,0, sVal->length); | |||
|  |         break; | |||
|  |     } | |||
|  |     case typelib_TypeClass_TYPE: | |||
|  |      { | |||
|  |          *cli_data= mapUnoType( *(typelib_TypeDescriptionReference * const *)uno_data ); | |||
|  |          break; | |||
|  |      } | |||
|  |     case typelib_TypeClass_ANY: | |||
|  |     { | |||
|  |         uno_Any const * pAny = (uno_Any const *)uno_data; | |||
|  |         if (typelib_TypeClass_VOID != pAny->pType->eTypeClass) | |||
|  |         { | |||
|  |             System::Object* objCli= NULL; | |||
|  |             map_to_cli( | |||
|  |                 &objCli, pAny->pData, pAny->pType, 0, | |||
|  |                 false); | |||
|  | 
 | |||
|  |             uno::Any anyVal(mapUnoType(pAny->pType), objCli); | |||
|  |             *cli_data= __box(anyVal); | |||
|  |         } | |||
|  |         else | |||
|  |         { // void any
 | |||
|  |             *cli_data= __box(uno::Any::VOID); | |||
|  |         } | |||
|  |         break; | |||
|  |     } | |||
|  |     case typelib_TypeClass_ENUM: | |||
|  |      { | |||
|  |          if (info != NULL) | |||
|  |          { | |||
|  |              OSL_ASSERT(info->get_IsByRef()); | |||
|  |              info= info->GetElementType(); | |||
|  |              *cli_data= System::Enum::ToObject(info, *(System::Int32*) uno_data); | |||
|  |          } | |||
|  |          else | |||
|  |              *cli_data= System::Enum::ToObject( | |||
|  |                  mapUnoType(type), *(System::Int32*) uno_data); | |||
|  |         break; | |||
|  |     } | |||
|  |     case typelib_TypeClass_STRUCT: | |||
|  |     case typelib_TypeClass_EXCEPTION: | |||
|  |     { | |||
|  |         TypeDescr td( type ); | |||
|  |         typelib_CompoundTypeDescription * comp_td = | |||
|  |             (typelib_CompoundTypeDescription *) td.get(); | |||
|  |         if ( ! ((typelib_TypeDescription*) comp_td)->bComplete) | |||
|  |                 ::typelib_typedescription_complete( | |||
|  |                     (typelib_TypeDescription**) & comp_td ); | |||
|  | 
 | |||
|  | 
 | |||
|  |         //create the type
 | |||
|  |         System::Type* cliType= loadCliType(td.get()->pTypeName); | |||
|  |         //detect if we recursivly convert inherited structures
 | |||
|  |         //If this point is reached because of a recursive call during convering a
 | |||
|  |         //struct then we must not create a new object rather we use the one in
 | |||
|  |         // cli_data argument.
 | |||
|  |         System::Object* cliObj; | |||
|  |         if (bDontCreateObj) | |||
|  |             cliObj = *cli_data; // recursive call
 | |||
|  |         else | |||
|  |         { | |||
|  |             //Special handling for Exception conversion. We must call constructor System::Exception
 | |||
|  |             //to pass the message string
 | |||
|  |             if (__typeof(ucss::uno::Exception)->IsAssignableFrom(cliType)) | |||
|  |             { | |||
|  |                 //We need to get the Message field. Therefore we must obtain the offset from
 | |||
|  |                 //the typedescription. The base interface of all exceptions is
 | |||
|  |                 //com::sun::star::uno::Exception which contains the message
 | |||
|  |                 typelib_CompoundTypeDescription* pCTD = comp_td; | |||
|  |                 while (pCTD->pBaseTypeDescription) | |||
|  |                     pCTD = pCTD->pBaseTypeDescription; | |||
|  |                 int nPos = -1; | |||
|  | 
 | |||
|  |                 rtl::OUString usMessageMember(RTL_CONSTASCII_USTRINGPARAM("Message")); | |||
|  |                 for (int i = 0; i < pCTD->nMembers; i ++) | |||
|  |                 { | |||
|  | #if OSL_DEBUG_LEVEL >= 2
 | |||
|  |                     System::String* sMember; | |||
|  |                     sMember = mapUnoString(pCTD->ppMemberNames[i]); | |||
|  | #endif
 | |||
|  |                     if (usMessageMember.equals(pCTD->ppMemberNames[i])) | |||
|  |                     { | |||
|  |                         nPos = i; | |||
|  |                         break; | |||
|  |                     } | |||
|  |                 } | |||
|  |                 OSL_ASSERT (nPos != -1); | |||
|  |                 int offset = pCTD->pMemberOffsets[nPos]; | |||
|  |                 //Whith the offset within the exception we can get the message string
 | |||
|  |                 System::String* sMessage = mapUnoString(*(rtl_uString**) | |||
|  |                                                         ((char*) uno_data + offset)); | |||
|  |                 //We need to find a constructor for the exception that takes the message string
 | |||
|  |                 //We assume that the first argument is the message string
 | |||
|  |                 sr::ConstructorInfo* arCtorInfo[] = cliType->GetConstructors(); | |||
|  |                 sr::ConstructorInfo* ctorInfo = NULL; | |||
|  |                 int numCtors = arCtorInfo->get_Length(); | |||
|  |                 //Constructor must at least have 2 params for the base
 | |||
|  |                 //unoidl.com.sun.star.uno.Exception (String, Object);
 | |||
|  |                 sr::ParameterInfo * arParamInfo[]; | |||
|  |                 for (int i = 0; i < numCtors; i++) | |||
|  |                 { | |||
|  |                     arParamInfo = arCtorInfo[i]->GetParameters(); | |||
|  |                     if (arParamInfo->get_Length() < 2) | |||
|  |                         continue; | |||
|  |                     ctorInfo = arCtorInfo[i]; | |||
|  |                     break; | |||
|  |                 } | |||
|  |                 OSL_ASSERT(arParamInfo[0]->get_ParameterType()->Equals(__typeof(System::String)) | |||
|  |                     && arParamInfo[1]->get_ParameterType()->Equals(__typeof(System::Object)) | |||
|  |                     && arParamInfo[0]->get_Position() == 0 | |||
|  |                     && arParamInfo[1]->get_Position() == 1); | |||
|  |                 //Prepare parameters for constructor
 | |||
|  |                 int numArgs = arParamInfo->get_Length(); | |||
|  |                 System::Object * args[] = new System::Object*[numArgs]; | |||
|  |                 //only initialize the first argument with the message
 | |||
|  |                 args[0] = sMessage; | |||
|  |                 cliObj = ctorInfo->Invoke(args); | |||
|  |             } | |||
|  |             else | |||
|  |                 cliObj = System::Activator::CreateInstance(cliType); | |||
|  |         } | |||
|  |         sal_Int32 * pMemberOffsets = comp_td->pMemberOffsets; | |||
|  | 
 | |||
|  |         if (comp_td->pBaseTypeDescription) | |||
|  |         { | |||
|  |             //convert inherited struct
 | |||
|  |             //cliObj is passed inout (args in_param, out_param are true), hence the passed
 | |||
|  |             // cliObj is used by the callee instead of a newly created struct
 | |||
|  |             map_to_cli( | |||
|  |                 &cliObj, uno_data, | |||
|  |                 ((typelib_TypeDescription *)comp_td->pBaseTypeDescription)->pWeakRef, 0, | |||
|  |                 true); | |||
|  |         } | |||
|  |         rtl::OUString usUnoException(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.Exception")); | |||
|  |         for (sal_Int32 nPos = comp_td->nMembers; nPos--; ) | |||
|  |         { | |||
|  |             typelib_TypeDescriptionReference * member_type = comp_td->ppTypeRefs[ nPos ]; | |||
|  |             System::String* sMemberName= mapUnoString(comp_td->ppMemberNames[nPos]); | |||
|  |             sr::FieldInfo* aField= cliType->GetField(sMemberName); | |||
|  |             // special case for Exception.Message. The field has already been
 | |||
|  |             // set while constructing cli object
 | |||
|  |             if ( ! aField && usUnoException.equals(td.get()->pTypeName)) | |||
|  |             { | |||
|  |                 continue; | |||
|  |             } | |||
|  |             void const * p = (char const *)uno_data + pMemberOffsets[ nPos ]; | |||
|  |             switch (member_type->eTypeClass) | |||
|  |             { | |||
|  |             case typelib_TypeClass_CHAR: | |||
|  |                 aField->SetValue(cliObj, __box(*(System::Char*) p)); | |||
|  |                 break; | |||
|  |             case typelib_TypeClass_BOOLEAN: | |||
|  |                 aField->SetValue(cliObj, __box(*(System::Boolean*) p)); | |||
|  |                 break; | |||
|  |             case typelib_TypeClass_BYTE: | |||
|  |                 aField->SetValue(cliObj, __box(*(System::Byte*) p)); | |||
|  |                 break; | |||
|  |             case typelib_TypeClass_SHORT: | |||
|  |                 aField->SetValue(cliObj, __box(*(System::Int16*) p)); | |||
|  |                 break; | |||
|  |             case typelib_TypeClass_UNSIGNED_SHORT: | |||
|  |                 aField->SetValue(cliObj, __box(*(System::UInt16*) p)); | |||
|  |                 break; | |||
|  |             case typelib_TypeClass_LONG: | |||
|  |                 aField->SetValue(cliObj, __box(*(System::Int32*) p)); | |||
|  |                 break; | |||
|  |             case typelib_TypeClass_UNSIGNED_LONG: | |||
|  |                 aField->SetValue(cliObj, __box(*(System::UInt32*) p)); | |||
|  |                 break; | |||
|  |             case typelib_TypeClass_HYPER: | |||
|  |                 aField->SetValue(cliObj, __box(*(System::Int64*) p)); | |||
|  |                 break; | |||
|  |             case typelib_TypeClass_UNSIGNED_HYPER: | |||
|  |                 aField->SetValue(cliObj, __box(*(System::UInt64*) p)); | |||
|  |                 break; | |||
|  |             case typelib_TypeClass_FLOAT: | |||
|  |                 aField->SetValue(cliObj, __box(*(System::Single*) p)); | |||
|  |                 break; | |||
|  |             case typelib_TypeClass_DOUBLE: | |||
|  |                 aField->SetValue(cliObj, __box(*(System::Double*) p)); | |||
|  |                 break; | |||
|  |             default: | |||
|  |             { | |||
|  |                 System::Object* cli_val; | |||
|  |                 map_to_cli( | |||
|  |                     &cli_val, p, member_type, 0, | |||
|  |                     false); | |||
|  |                 aField->SetValue(cliObj, cli_val); | |||
|  |                 break; | |||
|  |             } | |||
|  |             } | |||
|  |         } | |||
|  |         *cli_data= cliObj; | |||
|  |         break; | |||
|  |     } | |||
|  |     case typelib_TypeClass_SEQUENCE: | |||
|  |     { | |||
|  |         sal_Int32 nElements; | |||
|  |         uno_Sequence const * seq = 0; | |||
|  |         seq = *(uno_Sequence * const *)uno_data; | |||
|  |         nElements = seq->nElements; | |||
|  | 
 | |||
|  |         TypeDescr td( type ); | |||
|  |         typelib_TypeDescriptionReference * element_type = | |||
|  |             ((typelib_IndirectTypeDescription *)td.get())->pType; | |||
|  | 
 | |||
|  |         switch (element_type->eTypeClass) | |||
|  |         { | |||
|  |         case typelib_TypeClass_CHAR: | |||
|  |         { | |||
|  |             System::Char arChar[]= new System::Char[nElements]; | |||
|  |             sri::Marshal::Copy( (void*) &seq->elements, arChar, 0, nElements); | |||
|  |             *cli_data= arChar; | |||
|  |             break; | |||
|  |         } | |||
|  |         case typelib_TypeClass_BOOLEAN: | |||
|  |         { | |||
|  |             System::Boolean arBool[]= new System::Boolean[nElements]; | |||
|  |             sri::Marshal::Copy( (void*) &seq->elements, arBool, 0, nElements); | |||
|  |             *cli_data= arBool; | |||
|  |             break; | |||
|  |         } | |||
|  |         case typelib_TypeClass_BYTE: | |||
|  |         { | |||
|  |             System::Byte arByte[]= new System::Byte[nElements]; | |||
|  |             sri::Marshal::Copy( (void*) &seq->elements, arByte, 0, nElements); | |||
|  |             *cli_data= arByte; | |||
|  |             break; | |||
|  |         } | |||
|  |         case typelib_TypeClass_SHORT: | |||
|  |         { | |||
|  |             System::Int16 arShort[]= new System::Int16[nElements]; | |||
|  |             sri::Marshal::Copy( (void*) &seq->elements, arShort, 0, nElements); | |||
|  |             *cli_data= arShort; | |||
|  |             break; | |||
|  |         } | |||
|  |         case typelib_TypeClass_UNSIGNED_SHORT: | |||
|  |         { | |||
|  |             System::UInt16 arUInt16[]= new System::UInt16[nElements]; | |||
|  |             sri::Marshal::Copy( (void*) &seq->elements, static_cast<System::Int16[]>(arUInt16), | |||
|  |                                 0, nElements); | |||
|  |             *cli_data= arUInt16; | |||
|  |             break; | |||
|  |         } | |||
|  |         case typelib_TypeClass_LONG: | |||
|  |         { | |||
|  |             System::Int32 arInt32[]= new System::Int32[nElements]; | |||
|  |             sri::Marshal::Copy( (void*) &seq->elements, arInt32, 0, nElements); | |||
|  |             *cli_data= arInt32; | |||
|  |             break; | |||
|  |         } | |||
|  |         case typelib_TypeClass_UNSIGNED_LONG: | |||
|  |         { | |||
|  |             System::UInt32 arUInt32[]= new System::UInt32[nElements]; | |||
|  |             sri::Marshal::Copy( (void*) &seq->elements, static_cast<System::Int32[]>(arUInt32), | |||
|  |                                 0, nElements); | |||
|  |             *cli_data= arUInt32; | |||
|  |             break; | |||
|  |         } | |||
|  |         case typelib_TypeClass_HYPER: | |||
|  |         { | |||
|  |             System::Int64 arInt64[]= new System::Int64[nElements]; | |||
|  |             sri::Marshal::Copy( (void*) &seq->elements, arInt64, 0, nElements); | |||
|  |             *cli_data= arInt64; | |||
|  |             break; | |||
|  |         } | |||
|  |         case typelib_TypeClass_UNSIGNED_HYPER: | |||
|  |         { | |||
|  |             System::UInt64 arUInt64[]= new System::UInt64[nElements]; | |||
|  |             sri::Marshal::Copy( (void*) &seq->elements, arUInt64, 0, nElements); | |||
|  |             *cli_data= arUInt64; | |||
|  |             break; | |||
|  |         } | |||
|  |         case typelib_TypeClass_FLOAT: | |||
|  |         { | |||
|  |             System::Single arSingle[]= new System::Single[nElements]; | |||
|  |             sri::Marshal::Copy( (void*) &seq->elements, arSingle, 0, nElements); | |||
|  |             *cli_data= arSingle; | |||
|  |             break; | |||
|  |         } | |||
|  |         case typelib_TypeClass_DOUBLE: | |||
|  |         { | |||
|  |             System::Double arDouble[]= new System::Double[nElements]; | |||
|  |             sri::Marshal::Copy( (void*) &seq->elements, arDouble, 0, nElements); | |||
|  |             *cli_data= arDouble; | |||
|  |             break; | |||
|  |         } | |||
|  |         case typelib_TypeClass_STRING: | |||
|  |         { | |||
|  |             System::String* arString[]= new System::String*[nElements]; | |||
|  |             for (int i= 0; i < nElements; i++) | |||
|  |             { | |||
|  |                 rtl_uString *aStr= ((rtl_uString**)(&seq->elements))[i]; | |||
|  |                 arString[i]= new System::String( (__wchar_t *) &aStr->buffer, 0, aStr->length); | |||
|  |             } | |||
|  |             *cli_data= arString; | |||
|  |             break; | |||
|  |         } | |||
|  |         case typelib_TypeClass_TYPE: | |||
|  |         { | |||
|  |             System::Type* arType[]= new System::Type*[nElements]; | |||
|  |             for (int i= 0; i < nElements; i++) | |||
|  |             { | |||
|  |                 arType[i]= | |||
|  |                     mapUnoType( ((typelib_TypeDescriptionReference**) seq->elements)[i]); | |||
|  |             } | |||
|  |             *cli_data= arType; | |||
|  |             break; | |||
|  |         } | |||
|  |         case typelib_TypeClass_ANY: | |||
|  |         { | |||
|  |             uno::Any arCli[]= new uno::Any[nElements]; | |||
|  |             uno_Any const * p = (uno_Any const *)seq->elements; | |||
|  |             for (sal_Int32 nPos = 0; nPos < nElements; ++nPos ) | |||
|  |             { | |||
|  |                 System::Object* cli_obj = NULL; | |||
|  |                 map_to_cli( | |||
|  |                     &cli_obj, &p[ nPos ], element_type, 0, false); | |||
|  |                 arCli[nPos]= *__try_cast<__box uno::Any*>(cli_obj); | |||
|  |             } | |||
|  |             *cli_data= arCli; | |||
|  |             break; | |||
|  |         } | |||
|  |         case typelib_TypeClass_ENUM: | |||
|  |         { | |||
|  |             //get the Enum type
 | |||
|  |             System::Type* enumType= NULL; | |||
|  |             if (info != NULL) | |||
|  |             { | |||
|  |                 //info is EnumType[]&, remove &
 | |||
|  |                 OSL_ASSERT(info->IsByRef); | |||
|  |                 enumType = info->GetElementType(); | |||
|  |                 //enumType is EnumType[], remove []
 | |||
|  |                 enumType = enumType->GetElementType(); | |||
|  |             } | |||
|  |             else | |||
|  |                 enumType= mapUnoType(element_type); | |||
|  | 
 | |||
|  |             System::Array* arEnum = System::Array::CreateInstance( | |||
|  |                 enumType, nElements); | |||
|  |             for (int i= 0; i < nElements; i++) | |||
|  |             { | |||
|  |                 arEnum->SetValue(System::Enum::ToObject(enumType, | |||
|  |                    ((sal_Int32*) seq->elements)[i]), i); | |||
|  |             } | |||
|  |             *cli_data = arEnum; | |||
|  |             break; | |||
|  |         } | |||
|  |         case typelib_TypeClass_STRUCT: | |||
|  |         case typelib_TypeClass_EXCEPTION: | |||
|  |         { | |||
|  |             TypeDescr element_td( element_type ); | |||
|  |             System::Array* ar= System::Array::CreateInstance( | |||
|  |                 mapUnoType(element_type),nElements); | |||
|  |             if (0 < nElements) | |||
|  |             { | |||
|  |                 // ToDo check this
 | |||
|  |                 char * p = (char *) &seq->elements; | |||
|  |                 sal_Int32 nSize = element_td.get()->nSize; | |||
|  |                 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos ) | |||
|  |                 { | |||
|  |                     System::Object* val; | |||
|  |                     map_to_cli( | |||
|  |                         &val, p + (nSize * nPos), element_type, 0, false); | |||
|  |                     ar->SetValue(val, nPos); | |||
|  |                 } | |||
|  |             } | |||
|  |             *cli_data = ar; | |||
|  |             break; | |||
|  |         } | |||
|  | // ToDo, verify
 | |||
|  |         case typelib_TypeClass_SEQUENCE: | |||
|  |         { | |||
|  |             System::Array *ar= System::Array::CreateInstance( | |||
|  |                 mapUnoType(element_type), nElements); | |||
|  |             if (0 < nElements) | |||
|  |             { | |||
|  |                 TypeDescr element_td( element_type ); | |||
|  |                 uno_Sequence ** elements = (uno_Sequence**) seq->elements; | |||
|  |                 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos ) | |||
|  |                 { | |||
|  |                     System::Object* val; | |||
|  |                     map_to_cli( | |||
|  |                         &val, &elements[nPos], element_type, 0, false); | |||
|  |                     ar->SetValue(val, nPos); | |||
|  |                 } | |||
|  |             } | |||
|  |             *cli_data = ar; | |||
|  |             break; | |||
|  |         } | |||
|  |         case typelib_TypeClass_INTERFACE: | |||
|  |         { | |||
|  |             TypeDescr element_td( element_type ); | |||
|  |             System::Type * ifaceType= mapUnoType(element_type); | |||
|  |             System::Array* ar= System::Array::CreateInstance(ifaceType, nElements); | |||
|  | 
 | |||
|  |             char * p = (char *)seq->elements; | |||
|  |             sal_Int32 nSize = element_td.get()->nSize; | |||
|  |             for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos ) | |||
|  |             { | |||
|  |                 System::Object* val; | |||
|  |                 map_to_cli( | |||
|  |                     &val, p + (nSize * nPos), element_type, NULL, false); | |||
|  | 
 | |||
|  |                 ar->SetValue(val, nPos); | |||
|  |             } | |||
|  |             *cli_data= ar; | |||
|  |             break; | |||
|  |         } | |||
|  |         default: | |||
|  |         { | |||
|  |             OUStringBuffer buf( 128 ); | |||
|  |             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_cli():") ); | |||
|  |             buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName ) ); | |||
|  |             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] unsupported element type: ") ); | |||
|  |             buf.append( *reinterpret_cast< OUString const * >( &element_type->pTypeName ) ); | |||
|  |             throw BridgeRuntimeError( buf.makeStringAndClear() ); | |||
|  |         } | |||
|  |         } | |||
|  |         break; | |||
|  |     } | |||
|  |     case typelib_TypeClass_INTERFACE: | |||
|  |     { | |||
|  |         uno_Interface * pUnoI = *(uno_Interface * const *)uno_data; | |||
|  |         if (0 != pUnoI) | |||
|  |         { | |||
|  |             TypeDescr td( type ); | |||
|  |             *cli_data= map_uno2cli( pUnoI, reinterpret_cast< | |||
|  |                                           typelib_InterfaceTypeDescription*>(td.get())) ; | |||
|  |         } | |||
|  |         else | |||
|  |             *cli_data= NULL; | |||
|  |         break; | |||
|  |     } | |||
|  |     default: | |||
|  |     { | |||
|  |         //ToDo check this exception. The String is probably crippled
 | |||
|  |         OUStringBuffer buf( 128 ); | |||
|  |         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_cli():") ); | |||
|  |         buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName ) ); | |||
|  |         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] unsupported type!") ); | |||
|  |         throw BridgeRuntimeError( buf.makeStringAndClear() ); | |||
|  |     } | |||
|  |     } | |||
|  | } | |||
|  | } |