2010-10-14 08:30:07 +02:00
|
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
2012-06-27 17:37:30 +01:00
|
|
|
|
/*
|
|
|
|
|
* This file is part of the LibreOffice project.
|
|
|
|
|
*
|
|
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
|
*
|
|
|
|
|
* This file incorporates work covered by the following license notice:
|
|
|
|
|
*
|
|
|
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
|
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
|
|
|
* with this work for additional information regarding copyright
|
|
|
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
|
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
|
|
|
* except in compliance with the License. You may obtain a copy of
|
|
|
|
|
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
|
|
|
*/
|
2007-05-09 12:31:07 +00:00
|
|
|
|
|
|
|
|
|
#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"
|
|
|
|
|
|
2008-06-25 11:14:07 +00:00
|
|
|
|
#using <cli_uretypes.dll>
|
|
|
|
|
|
2007-05-09 12:31:07 +00:00
|
|
|
|
|
|
|
|
|
#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 std;
|
|
|
|
|
|
2011-03-02 21:53:12 +01:00
|
|
|
|
using ::rtl::OUString;
|
|
|
|
|
using ::rtl::OUStringBuffer;
|
|
|
|
|
|
2007-05-09 12:31:07 +00:00
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
{
|
2011-10-05 10:08:34 +02:00
|
|
|
|
builder->Append(mapCliTypeName(sParam).getStr());
|
2007-05-09 12:31:07 +00:00
|
|
|
|
}
|
|
|
|
|
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() );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2010-10-14 08:30:07 +02:00
|
|
|
|
|
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|