1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #if !defined WIN32_LEAN_AND_MEAN
21 # define WIN32_LEAN_AND_MEAN
28 #include "rtl/ustring.hxx"
29 #include "rtl/ustrbuf.hxx"
30 #include "uno/sequence2.h"
31 #include "typelib/typedescription.hxx"
32 #include "cli_proxy.h"
34 #include "cli_bridge.h"
36 #using <cli_uretypes.dll>
40 namespace sri
= System::Runtime::InteropServices
;
41 namespace sr
= System::Reflection
;
42 namespace st
= System::Text
;
43 namespace ucss
= unoidl::com::sun::star
;
48 System::String
^ mapUnoPolymorphicName(System::String
^ unoName
);
49 OUString
mapCliTypeName(System::String
^ typeName
);
50 System::String
^ mapCliPolymorphicName(System::String
^ unoName
);
51 System::String
^ mapPolymorphicName(System::String
^ unoName
, bool bCliToUno
);
53 inline std::unique_ptr
< rtl_mem
> seq_allocate( sal_Int32 nElements
, sal_Int32 nSize
)
55 std::unique_ptr
< rtl_mem
> seq(
56 rtl_mem::allocate( SAL_SEQUENCE_HEADER_SIZE
+ (nElements
* nSize
) ) );
57 uno_Sequence
* p
= (uno_Sequence
*)seq
.get();
59 p
->nElements
= nElements
;
63 System::Object
^ Bridge::map_uno2cli(uno_Interface
* pUnoI
, typelib_InterfaceTypeDescription
*pTD
) const
65 System::Object
^ retVal
= nullptr;
67 rtl_uString
* pOid
= 0;
68 (*m_uno_env
->getObjectIdentifier
)( m_uno_env
, &pOid
, pUnoI
);
69 OSL_ASSERT( 0 != pOid
);
70 OUString
oid(pOid
, SAL_NO_ACQUIRE
);
72 // see if the interface was already mapped
73 System::Type
^ ifaceType
= mapUnoType(reinterpret_cast<typelib_TypeDescription
*>(pTD
));
74 System::String
^ sOid
= mapUnoString(oid
.pData
);
76 System::Threading::Monitor::Enter( CliEnvHolder::g_cli_env
);
79 retVal
= CliEnvHolder::g_cli_env
->getRegisteredInterface(sOid
, ifaceType
);
82 // There is already a registered object. It can either be a proxy
83 // for the UNO object or a real cli object. In the first case we
84 // tell the proxy that it shall also represent the current UNO
85 // interface. If it already does that, then it does nothing
86 if (srr::RemotingServices::IsTransparentProxy(retVal
))
88 UnoInterfaceProxy
^ p
= static_cast<UnoInterfaceProxy
^>(
89 srr::RemotingServices::GetRealProxy(retVal
));
90 p
->addUnoInterface(pUnoI
, pTD
);
95 retVal
= UnoInterfaceProxy::create(
96 (Bridge
*) this, pUnoI
, pTD
, oid
);
101 System::Threading::Monitor::Exit( CliEnvHolder::g_cli_env
);
107 uno_Interface
* Bridge::map_cli2uno(System::Object
^ cliObj
, typelib_TypeDescription
*pTD
) const
109 uno_Interface
* retIface
= NULL
;
110 // get oid from dot net environment
111 System::String
^ ds_oid
= CliEnvHolder::g_cli_env
->getObjectIdentifier( cliObj
);
112 OUString ousOid
= mapCliString(ds_oid
);
113 // look if interface is already mapped
114 m_uno_env
->getRegisteredInterface(m_uno_env
, (void**) &retIface
, ousOid
.pData
,
115 (typelib_InterfaceTypeDescription
*) pTD
);
118 System::Threading::Monitor::Enter(Cli_environment::typeid);
121 m_uno_env
->getRegisteredInterface(m_uno_env
, (void**) &retIface
, ousOid
.pData
,
122 (typelib_InterfaceTypeDescription
*) pTD
);
125 retIface
= CliProxy::create((Bridge
*)this, cliObj
, pTD
, ousOid
);
130 System::Threading::Monitor::Exit(Cli_environment::typeid);
136 inline System::Type
^ loadCliType(rtl_uString
* unoName
)
138 return loadCliType(mapUnoTypeName(unoName
));
141 System::Type
^ loadCliType(System::String
^ unoName
)
143 System::Type
^ retVal
= nullptr;
146 //If unoName denotes a polymorphic type, e.g com.sun.star.beans.Defaulted<System.Char>
147 //then we remove the type list, otherwise the type could not be loaded.
148 bool bIsPolymorphic
= false;
150 System::String
^ loadName
= unoName
;
151 int index
= unoName
->IndexOf('<');
154 loadName
= unoName
->Substring(0, index
);
155 bIsPolymorphic
= true;
157 System::AppDomain
^ currentDomain
= System::AppDomain::CurrentDomain
;
158 cli::array
<sr::Assembly
^>^ assems
= currentDomain
->GetAssemblies();
159 for (int i
= 0; i
< assems
->Length
; i
++)
161 retVal
= assems
[i
]->GetType(loadName
, false);
166 if (retVal
== nullptr)
168 System::String
^ msg
= gcnew
System::String("A type could not be loaded: ");
169 msg
= System::String::Concat(msg
, loadName
);
170 throw BridgeRuntimeError(mapCliString(msg
));
175 retVal
= uno::PolymorphicType::GetType(retVal
, unoName
);
178 catch( System::Exception
^ e
)
180 OUString
ouMessage(mapCliString(e
->Message
));
181 throw BridgeRuntimeError(ouMessage
);
186 System::Type
^ mapUnoType(typelib_TypeDescription
const * pTD
)
188 return mapUnoType(pTD
->pWeakRef
);
191 System::Type
^ mapUnoType(typelib_TypeDescriptionReference
const * pTD
)
193 System::Type
^ retVal
= nullptr;
194 switch (pTD
->eTypeClass
)
196 case typelib_TypeClass_VOID
:
197 retVal
= void::typeid; break;
198 case typelib_TypeClass_CHAR
:
199 retVal
= System::Char::typeid; break;
200 case typelib_TypeClass_BOOLEAN
:
201 retVal
= System::Boolean::typeid; break;
202 case typelib_TypeClass_BYTE
:
203 retVal
= System::Byte::typeid; break;
204 case typelib_TypeClass_SHORT
:
205 retVal
= System::Int16::typeid; break;
206 case typelib_TypeClass_UNSIGNED_SHORT
:
207 retVal
= System::UInt16::typeid; break;
208 case typelib_TypeClass_LONG
:
209 retVal
= System::Int32::typeid; break;
210 case typelib_TypeClass_UNSIGNED_LONG
:
211 retVal
= System::UInt32::typeid; break;
212 case typelib_TypeClass_HYPER
:
213 retVal
= System::Int64::typeid; break;
214 case typelib_TypeClass_UNSIGNED_HYPER
:
215 retVal
= System::UInt64::typeid; break;
216 case typelib_TypeClass_FLOAT
:
217 retVal
= System::Single::typeid; break;
218 case typelib_TypeClass_DOUBLE
:
219 retVal
= System::Double::typeid; break;
220 case typelib_TypeClass_STRING
:
221 retVal
= System::String::typeid; break;
222 case typelib_TypeClass_TYPE
:
223 retVal
= System::Type::typeid; break;
224 case typelib_TypeClass_ANY
:
225 retVal
= uno::Any::typeid; break;
226 case typelib_TypeClass_ENUM
:
227 case typelib_TypeClass_STRUCT
:
228 case typelib_TypeClass_EXCEPTION
:
229 retVal
= loadCliType(pTD
->pTypeName
); break;
230 case typelib_TypeClass_INTERFACE
:
232 //special handling for XInterface, since it does not exist in cli.
233 OUString
usXInterface("com.sun.star.uno.XInterface");
234 if (usXInterface
.equals(pTD
->pTypeName
))
235 retVal
= System::Object::typeid;
237 retVal
= loadCliType(pTD
->pTypeName
);
240 case typelib_TypeClass_SEQUENCE
:
242 css::uno::TypeDescription
seqType(
243 const_cast<typelib_TypeDescriptionReference
*>(pTD
));
244 typelib_TypeDescriptionReference
* pElementTDRef
=
245 reinterpret_cast<typelib_IndirectTypeDescription
*>(seqType
.get())->pType
;
246 switch (pElementTDRef
->eTypeClass
)
248 case typelib_TypeClass_CHAR
:
249 retVal
= System::Type::GetType(const_cast<System::String
^>(Constants::sArChar
)); break;
250 case typelib_TypeClass_BOOLEAN
:
251 retVal
= System::Type::GetType(const_cast<System::String
^>(Constants::sArBoolean
));
253 case typelib_TypeClass_BYTE
:
254 retVal
= System::Type::GetType(const_cast<System::String
^>(Constants::sArByte
));
256 case typelib_TypeClass_SHORT
:
257 retVal
= System::Type::GetType(const_cast<System::String
^>(Constants::sArInt16
));
259 case typelib_TypeClass_UNSIGNED_SHORT
:
260 retVal
= System::Type::GetType(const_cast<System::String
^>(Constants::sArUInt16
));
262 case typelib_TypeClass_LONG
:
263 retVal
= System::Type::GetType(const_cast<System::String
^>(Constants::sArInt32
));
265 case typelib_TypeClass_UNSIGNED_LONG
:
266 retVal
= System::Type::GetType(const_cast<System::String
^>(Constants::sArUInt32
));
268 case typelib_TypeClass_HYPER
:
269 retVal
= System::Type::GetType(const_cast<System::String
^>(Constants::sArInt64
));
271 case typelib_TypeClass_UNSIGNED_HYPER
:
272 retVal
= System::Type::GetType(const_cast<System::String
^>(Constants::sArUInt64
));
274 case typelib_TypeClass_FLOAT
:
275 retVal
= System::Type::GetType(const_cast<System::String
^>(Constants::sArSingle
));
277 case typelib_TypeClass_DOUBLE
:
278 retVal
= System::Type::GetType(const_cast<System::String
^>(Constants::sArDouble
));
280 case typelib_TypeClass_STRING
:
281 retVal
= System::Type::GetType(const_cast<System::String
^>(Constants::sArString
));
283 case typelib_TypeClass_TYPE
:
284 retVal
= System::Type::GetType(const_cast<System::String
^>(Constants::sArType
));
286 case typelib_TypeClass_ANY
:
287 case typelib_TypeClass_ENUM
:
288 case typelib_TypeClass_EXCEPTION
:
289 case typelib_TypeClass_STRUCT
:
290 case typelib_TypeClass_INTERFACE
:
291 case typelib_TypeClass_SEQUENCE
:
293 retVal
= loadCliType(pTD
->pTypeName
);
297 //All cases should be handled by the case statements above
310 /** Returns an acquired td.
312 typelib_TypeDescriptionReference
* mapCliType(System::Type
^ cliType
)
314 typelib_TypeDescriptionReference
* retVal
= NULL
;
315 if (cliType
== nullptr)
317 retVal
= * typelib_static_type_getByTypeClass(
318 typelib_TypeClass_VOID
);
319 typelib_typedescriptionreference_acquire( retVal
);
322 //check for Enum first,
323 //because otherwise case System::TypeCode::Int32 applies
326 OUString usTypeName
= mapCliTypeName(cliType
->FullName
);
327 css::uno::Type
unoType(css::uno::TypeClass_ENUM
, usTypeName
);
328 retVal
= unoType
.getTypeLibType();
329 typelib_typedescriptionreference_acquire(retVal
);
333 switch (System::Type::GetTypeCode(cliType
))
335 case System::TypeCode::Boolean
:
336 retVal
= * typelib_static_type_getByTypeClass(
337 typelib_TypeClass_BOOLEAN
);
338 typelib_typedescriptionreference_acquire( retVal
);
340 case System::TypeCode::Char
:
341 retVal
= * typelib_static_type_getByTypeClass(
342 typelib_TypeClass_CHAR
);
343 typelib_typedescriptionreference_acquire( retVal
);
345 case System::TypeCode::Byte
:
346 retVal
= * typelib_static_type_getByTypeClass(
347 typelib_TypeClass_BYTE
);
348 typelib_typedescriptionreference_acquire( retVal
);
350 case System::TypeCode::Int16
:
351 retVal
= * typelib_static_type_getByTypeClass(
352 typelib_TypeClass_SHORT
);
353 typelib_typedescriptionreference_acquire( retVal
);
355 case System::TypeCode::Int32
:
356 retVal
= * typelib_static_type_getByTypeClass(
357 typelib_TypeClass_LONG
);
358 typelib_typedescriptionreference_acquire( retVal
);
360 case System::TypeCode::Int64
:
361 retVal
= * typelib_static_type_getByTypeClass(
362 typelib_TypeClass_HYPER
);
363 typelib_typedescriptionreference_acquire( retVal
);
365 case System::TypeCode::UInt16
:
366 retVal
= * typelib_static_type_getByTypeClass(
367 typelib_TypeClass_UNSIGNED_SHORT
);
368 typelib_typedescriptionreference_acquire( retVal
);
370 case System::TypeCode::UInt32
:
371 retVal
= * typelib_static_type_getByTypeClass(
372 typelib_TypeClass_UNSIGNED_LONG
);
373 typelib_typedescriptionreference_acquire( retVal
);
375 case System::TypeCode::UInt64
:
376 retVal
= * typelib_static_type_getByTypeClass(
377 typelib_TypeClass_UNSIGNED_HYPER
);
378 typelib_typedescriptionreference_acquire( retVal
);
380 case System::TypeCode::Single
:
381 retVal
= * typelib_static_type_getByTypeClass(
382 typelib_TypeClass_FLOAT
);
383 typelib_typedescriptionreference_acquire( retVal
);
385 case System::TypeCode::Double
:
386 retVal
= * typelib_static_type_getByTypeClass(
387 typelib_TypeClass_DOUBLE
);
388 typelib_typedescriptionreference_acquire( retVal
);
390 case System::TypeCode::String
:
391 retVal
= * typelib_static_type_getByTypeClass(
392 typelib_TypeClass_STRING
);
393 typelib_typedescriptionreference_acquire( retVal
);
401 System::String
^ cliTypeName
= cliType
->FullName
;
403 if (const_cast<System::String
^>(Constants::sVoid
)->Equals(
406 retVal
= * typelib_static_type_getByTypeClass(
407 typelib_TypeClass_VOID
);
408 typelib_typedescriptionreference_acquire( retVal
);
411 else if (const_cast<System::String
^>(Constants::sType
)->Equals(
414 retVal
= * typelib_static_type_getByTypeClass(
415 typelib_TypeClass_TYPE
);
416 typelib_typedescriptionreference_acquire( retVal
);
419 else if (const_cast<System::String
^>(Constants::sAny
)->Equals(
422 retVal
= * typelib_static_type_getByTypeClass(
423 typelib_TypeClass_ANY
);
424 typelib_typedescriptionreference_acquire( retVal
);
426 //struct, interfaces, sequences
430 uno::PolymorphicType
^ poly
= dynamic_cast<uno::PolymorphicType
^>(cliType
);
432 usTypeName
= mapCliTypeName( poly
->PolymorphicName
);
434 usTypeName
= mapCliTypeName(cliTypeName
);
435 typelib_TypeDescription
* td
= NULL
;
436 typelib_typedescription_getByName(&td
, usTypeName
.pData
);
439 retVal
= td
->pWeakRef
;
440 typelib_typedescriptionreference_acquire(retVal
);
441 typelib_typedescription_release(td
);
447 throw BridgeRuntimeError("[cli_uno bridge] mapCliType():could not map type: " + mapCliString(cliType
->FullName
));
453 Otherwise a leading "unoidl." is removed.
455 System::String
^ mapUnoTypeName(rtl_uString
const * typeName
)
457 OUString
usUnoName( const_cast< rtl_uString
* >( typeName
) );
458 st::StringBuilder
^ buf
= gcnew
st::StringBuilder();
459 //determine if the type is a sequence and its dimensions
461 if (usUnoName
[0] == '[')
466 if (usUnoName
[index
++] == ']')
468 if (usUnoName
[index
++] != '[')
471 usUnoName
= usUnoName
.copy(index
- 1);
473 System::String
^ sUnoName
= mapUnoString(usUnoName
.pData
);
474 if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usBool
)))
475 buf
->Append(const_cast<System::String
^>(Constants::sBoolean
));
476 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usChar
)))
477 buf
->Append(const_cast<System::String
^>(Constants::sChar
));
478 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usByte
)))
479 buf
->Append(const_cast<System::String
^>(Constants::sByte
));
480 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usShort
)))
481 buf
->Append(const_cast<System::String
^>(Constants::sInt16
));
482 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usUShort
)))
483 buf
->Append(const_cast<System::String
^>(Constants::sUInt16
));
484 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usLong
)))
485 buf
->Append(const_cast<System::String
^>(Constants::sInt32
));
486 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usULong
)))
487 buf
->Append(const_cast<System::String
^>(Constants::sUInt32
));
488 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usHyper
)))
489 buf
->Append(const_cast<System::String
^>(Constants::sInt64
));
490 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usUHyper
)))
491 buf
->Append(const_cast<System::String
^>(Constants::sUInt64
));
492 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usFloat
)))
493 buf
->Append(const_cast<System::String
^>(Constants::sSingle
));
494 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usDouble
)))
495 buf
->Append(const_cast<System::String
^>(Constants::sDouble
));
496 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usString
)))
497 buf
->Append(const_cast<System::String
^>(Constants::sString
));
498 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usVoid
)))
499 buf
->Append(const_cast<System::String
^>(Constants::sVoid
));
500 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usType
)))
501 buf
->Append(const_cast<System::String
^>(Constants::sType
));
502 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usXInterface
)))
503 buf
->Append(const_cast<System::String
^>(Constants::sObject
));
504 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usAny
)))
506 buf
->Append(const_cast<System::String
^>(Constants::sAny
));
510 //put "unoidl." at the beginning
511 buf
->Append(const_cast<System::String
^>(Constants::sUnoidl
));
512 //for polymorphic struct types remove the brackets, e.g mystruct<bool> -> mystruct
513 System::String
^ sName
= mapUnoPolymorphicName(sUnoName
);
518 buf
->Append(const_cast<System::String
^>(Constants::sBrackets
));
520 return buf
->ToString();
523 /** For example, there is a uno type
524 com.sun.star.Foo<char, long>.
525 The values in the type list
526 are uno types and are replaced by cli types, such as System.Char,
528 The prefix unoidl is not added.
530 inline System::String
^ mapUnoPolymorphicName(System::String
^ unoName
)
532 return mapPolymorphicName(unoName
, false);
535 /** For example, there is a type name such as
536 com.sun.star.Foo<System.Char, System.Int32>.
537 The values in the type list
538 are CLI types and are replaced by uno types, such as char,
540 The prefix unoidl remains.
542 inline System::String
^ mapCliPolymorphicName(System::String
^ unoName
)
544 return mapPolymorphicName(unoName
, true);
547 System::String
^ mapPolymorphicName(System::String
^ unoName
, bool bCliToUno
)
549 int index
= unoName
->IndexOf('<');
553 System::Text::StringBuilder
^ builder
= gcnew
System::Text::StringBuilder(256);
554 builder
->Append(unoName
->Substring(0, index
+1 ));
556 //Find the first occurrence of ','
557 //If the parameter is a polymorphic struct then we need to ignore everything
558 //between the brackets because it can also contain commas
559 //get the type list within < and >
560 int endIndex
= unoName
->Length
- 1;
564 while (cur
<= endIndex
)
566 System::Char c
= unoName
[cur
];
567 if (c
== ',' || c
== '>')
569 //insert a comma if needed
570 if (countParams
!= 0)
571 builder
->Append(",");
573 System::String
^ sParam
= unoName
->Substring(index
, cur
- index
);
576 //the index to the beginning of the next param
580 builder
->Append(mapCliTypeName(sParam
).getStr());
584 OUString s
= mapCliString(sParam
);
585 builder
->Append(mapUnoTypeName(s
.pData
));
591 //continue until the matching '>'
595 System::Char curChar
= unoName
[cur
];
600 else if (curChar
== '>')
612 builder
->Append((System::Char
) '>');
613 return builder
->ToString();
616 OUString
mapCliTypeName(System::String
^ typeName
)
619 // Array? determine the "rank" (number of "[]")
620 // move from the rightmost end to the left, for example
621 // unoidl.PolymorphicStruct<System.Char[]>[]
622 // has only a "dimension" of 1
623 int cur
= typeName
->Length
- 1;
624 bool bRightBracket
= false;
627 System::Char c
= typeName
[cur
];
630 bRightBracket
= true;
635 throw BridgeRuntimeError(
636 "Typename is wrong. No matching brackets for sequence. Name is: " +
637 mapCliString(typeName
));
638 bRightBracket
= false;
644 throw BridgeRuntimeError(
645 "Typename is wrong. No matching brackets for sequence. Name is: " +
646 mapCliString(typeName
));
652 if (bRightBracket
|| cur
< 0)
653 throw BridgeRuntimeError(
654 "Typename is wrong. " +
655 mapCliString(typeName
));
657 typeName
= typeName
->Substring(0, cur
+ 1);
659 System::Text::StringBuilder
^ buf
= gcnew
System::Text::StringBuilder(512);
661 //Put the "[]" at the beginning of the uno type name
663 buf
->Append(const_cast<System::String
^>(Constants::usBrackets
));
665 if (typeName
->Equals(const_cast<System::String
^>(Constants::sBoolean
)))
666 buf
->Append(const_cast<System::String
^>(Constants::usBool
));
667 else if (typeName
->Equals(const_cast<System::String
^>(Constants::sChar
)))
668 buf
->Append(const_cast<System::String
^>(Constants::usChar
));
669 else if (typeName
->Equals(const_cast<System::String
^>(Constants::sByte
)))
670 buf
->Append(const_cast<System::String
^>(Constants::usByte
));
671 else if (typeName
->Equals(const_cast<System::String
^>(Constants::sInt16
)))
672 buf
->Append(const_cast<System::String
^>(Constants::usShort
));
673 else if (typeName
->Equals(const_cast<System::String
^>(Constants::sUInt16
)))
674 buf
->Append(const_cast<System::String
^>(Constants::usUShort
));
675 else if (typeName
->Equals(const_cast<System::String
^>(Constants::sInt32
)))
676 buf
->Append(const_cast<System::String
^>(Constants::usLong
));
677 else if (typeName
->Equals(const_cast<System::String
^>(Constants::sUInt32
)))
678 buf
->Append(const_cast<System::String
^>(Constants::usULong
));
679 else if (typeName
->Equals(const_cast<System::String
^>(Constants::sInt64
)))
680 buf
->Append(const_cast<System::String
^>(Constants::usHyper
));
681 else if (typeName
->Equals(const_cast<System::String
^>(Constants::sUInt64
)))
682 buf
->Append(const_cast<System::String
^>(Constants::usUHyper
));
683 else if (typeName
->Equals(const_cast<System::String
^>(Constants::sSingle
)))
684 buf
->Append(const_cast<System::String
^>(Constants::usFloat
));
685 else if (typeName
->Equals(const_cast<System::String
^>(Constants::sDouble
)))
686 buf
->Append(const_cast<System::String
^>(Constants::usDouble
));
687 else if (typeName
->Equals(const_cast<System::String
^>(Constants::sString
)))
688 buf
->Append(const_cast<System::String
^>(Constants::usString
));
689 else if (typeName
->Equals(const_cast<System::String
^>(Constants::sVoid
)))
690 buf
->Append(const_cast<System::String
^>(Constants::usVoid
));
691 else if (typeName
->Equals(const_cast<System::String
^>(Constants::sType
)))
692 buf
->Append(const_cast<System::String
^>(Constants::usType
));
693 else if (typeName
->Equals(const_cast<System::String
^>(Constants::sObject
)))
694 buf
->Append(const_cast<System::String
^>(Constants::usXInterface
));
695 else if (typeName
->Equals(const_cast<System::String
^>(Constants::sAny
)))
696 buf
->Append(const_cast<System::String
^>(Constants::usAny
));
699 System::String
^ sName
= mapCliPolymorphicName(typeName
);
700 int i
= sName
->IndexOf(L
'.');
701 buf
->Append(sName
->Substring(i
+ 1));
703 return mapCliString(buf
->ToString());
706 /** Maps uno types to dot net types.
707 * If uno_data is null then the type description is converted to System::Type
709 inline System::String
^ mapUnoString( rtl_uString
const * data
)
712 return gcnew
System::String((__wchar_t
*) data
->buffer
, 0, data
->length
);
715 OUString
mapCliString(System::String
^ data
)
720 static_assert(sizeof(wchar_t) == sizeof(sal_Unicode
), "char mismatch");
721 pin_ptr
<wchar_t const> pdata
= PtrToStringChars(data
);
723 reinterpret_cast<sal_Unicode
const *>(pdata
),
724 const_cast<System::String
^>(data
)->Length
);
732 // ToDo convert cli types to expected types, e.g a long to a short where the uno type
733 // is a sal_Int16. This could be necessary if a scripting language (typeless) is used
734 // @param assign the uno_data has to be destructed (in/out args)
735 void Bridge::map_to_uno(void * uno_data
, System::Object
^ cli_data
,
736 typelib_TypeDescriptionReference
* type
,
740 switch (type
->eTypeClass
)
742 case typelib_TypeClass_VOID
:
744 case typelib_TypeClass_CHAR
:
746 System::Char aChar
= *safe_cast
<System::Char
^>(cli_data
);
747 *(sal_Unicode
*) uno_data
= aChar
;
750 case typelib_TypeClass_BOOLEAN
:
752 System::Boolean aBool
= *safe_cast
<System::Boolean
^>(cli_data
);
753 *(sal_Bool
*)uno_data
= aBool
== true ? sal_True
: sal_False
;
756 case typelib_TypeClass_BYTE
:
758 System::Byte aByte
= *safe_cast
<System::Byte
^>(cli_data
);
759 *(sal_Int8
*) uno_data
= aByte
;
762 case typelib_TypeClass_SHORT
:
764 System::Int16 aShort
= *safe_cast
<System::Int16
^>(cli_data
);
765 *(sal_Int16
*) uno_data
= aShort
;
768 case typelib_TypeClass_UNSIGNED_SHORT
:
770 System::UInt16 aUShort
= *safe_cast
<System::UInt16
^>(cli_data
);
771 *(sal_uInt16
*) uno_data
= aUShort
;
774 case typelib_TypeClass_LONG
:
776 System::Int32 aLong
= *safe_cast
<System::Int32
^>(cli_data
);
777 *(sal_Int32
*) uno_data
= aLong
;
780 case typelib_TypeClass_UNSIGNED_LONG
:
782 System::UInt32 aULong
= *safe_cast
<System::UInt32
^>(cli_data
);
783 *(sal_uInt32
*) uno_data
= aULong
;
786 case typelib_TypeClass_HYPER
:
788 System::Int64 aHyper
= *safe_cast
<System::Int64
^>(cli_data
);
789 *(sal_Int64
*) uno_data
= aHyper
;
792 case typelib_TypeClass_UNSIGNED_HYPER
:
794 System::UInt64 aLong
= *safe_cast
<System::UInt64
^>(cli_data
);
795 *(sal_uInt64
*) uno_data
= aLong
;
798 case typelib_TypeClass_FLOAT
:
800 System::Single aFloat
= *safe_cast
<System::Single
^>(cli_data
);
801 *(float*) uno_data
= aFloat
;
804 case typelib_TypeClass_DOUBLE
:
806 System::Double aDouble
= *safe_cast
<System::Double
^>(cli_data
);
807 *(double*) uno_data
= aDouble
;
810 case typelib_TypeClass_STRING
:
812 if (assign
&& *(rtl_uString
**) uno_data
)
813 rtl_uString_release(*(rtl_uString
**) uno_data
);
815 *(rtl_uString
**)uno_data
= 0;
816 if (cli_data
== nullptr)
818 rtl_uString_new((rtl_uString
**) uno_data
);
822 System::String
^s
= safe_cast
<System::String
^>(cli_data
);
823 pin_ptr
<const wchar_t> pdata
= PtrToStringChars(s
);
824 rtl_uString_newFromStr_WithLength(
825 reinterpret_cast<rtl_uString
**>(uno_data
),
826 reinterpret_cast<sal_Unicode
const *>(pdata
), s
->Length
);
830 case typelib_TypeClass_TYPE
:
832 typelib_TypeDescriptionReference
* td
= mapCliType(safe_cast
<System::Type
^>(
836 typelib_typedescriptionreference_release(
837 *(typelib_TypeDescriptionReference
**)uno_data
);
839 *(typelib_TypeDescriptionReference
**)uno_data
= td
;
842 case typelib_TypeClass_ANY
:
844 uno_Any
* pAny
= (uno_Any
*)uno_data
;
845 if (cli_data
== nullptr) // null-ref or uninitialized any maps to empty any
848 uno_any_destruct( pAny
, 0 );
849 uno_any_construct( pAny
, 0, 0, 0 );
852 uno::Any aAny
= *safe_cast
<uno::Any
^>(cli_data
);
853 css::uno::Type
value_td( mapCliType(aAny
.Type
), SAL_NO_ACQUIRE
);
856 uno_any_destruct( pAny
, 0 );
860 switch (value_td
.getTypeClass())
862 case css::uno::TypeClass_VOID
:
863 pAny
->pData
= &pAny
->pReserved
;
865 case css::uno::TypeClass_CHAR
:
866 pAny
->pData
= &pAny
->pReserved
;
867 *(sal_Unicode
*) &pAny
->pReserved
= *safe_cast
<System::Char
^>(aAny
.Value
);
869 case css::uno::TypeClass_BOOLEAN
:
870 pAny
->pData
= &pAny
->pReserved
;
871 *(sal_Bool
*) &pAny
->pReserved
= *safe_cast
<System::Boolean
^>(aAny
.Value
);
873 case css::uno::TypeClass_BYTE
:
874 pAny
->pData
= &pAny
->pReserved
;
875 *(sal_Int8
*) &pAny
->pReserved
= *safe_cast
<System::Byte
^>(aAny
.Value
);
877 case css::uno::TypeClass_SHORT
:
878 pAny
->pData
= &pAny
->pReserved
;
879 *(sal_Int16
*) &pAny
->pReserved
= *safe_cast
<System::Int16
^>(aAny
.Value
);
881 case css::uno::TypeClass_UNSIGNED_SHORT
:
882 pAny
->pData
= &pAny
->pReserved
;
883 *(sal_uInt16
*) &pAny
->pReserved
= *safe_cast
<System::UInt16
^>(aAny
.Value
);
885 case css::uno::TypeClass_LONG
:
886 pAny
->pData
= &pAny
->pReserved
;
887 *(sal_Int32
*) &pAny
->pReserved
= *safe_cast
<System::Int32
^>(aAny
.Value
);
889 case css::uno::TypeClass_UNSIGNED_LONG
:
890 pAny
->pData
= &pAny
->pReserved
;
891 *(sal_uInt32
*) &pAny
->pReserved
= *safe_cast
<System::UInt32
^>(aAny
.Value
);
893 case css::uno::TypeClass_HYPER
:
894 if (sizeof (sal_Int64
) <= sizeof (void *))
896 pAny
->pData
= &pAny
->pReserved
;
897 *(sal_Int64
*) &pAny
->pReserved
= *safe_cast
<System::Int64
^>(aAny
.Value
);
901 std::unique_ptr
< rtl_mem
> mem( rtl_mem::allocate( sizeof (sal_Int64
) ) );
902 *(sal_Int64
*) mem
.get()= *safe_cast
<System::Int64
^>(aAny
.Value
);
903 pAny
->pData
= mem
.release();
906 case css::uno::TypeClass_UNSIGNED_HYPER
:
907 if (sizeof (sal_uInt64
) <= sizeof (void *))
909 pAny
->pData
= &pAny
->pReserved
;
910 *(sal_uInt64
*) &pAny
->pReserved
= *safe_cast
<System::UInt64
^>(aAny
.Value
);
914 std::unique_ptr
< rtl_mem
> mem( rtl_mem::allocate( sizeof (sal_uInt64
) ) );
915 *(sal_uInt64
*) mem
.get()= *safe_cast
<System::UInt64
^>(aAny
.Value
);
916 pAny
->pData
= mem
.release();
919 case css::uno::TypeClass_FLOAT
:
920 if (sizeof (float) <= sizeof (void *))
922 pAny
->pData
= &pAny
->pReserved
;
923 *(float*) &pAny
->pReserved
= *safe_cast
<System::Single
^>(aAny
.Value
);
927 std::unique_ptr
< rtl_mem
> mem( rtl_mem::allocate( sizeof (float) ) );
928 *(float*) mem
.get() = *safe_cast
<System::Single
^>(aAny
.Value
);
929 pAny
->pData
= mem
.release();
932 case css::uno::TypeClass_DOUBLE
:
933 if (sizeof (double) <= sizeof (void *))
935 pAny
->pData
= &pAny
->pReserved
;
936 *(double*) &pAny
->pReserved
= *safe_cast
<System::Double
^>(aAny
.Value
);
940 std::unique_ptr
< rtl_mem
> mem( rtl_mem::allocate( sizeof (double) ) );
941 *(double*) mem
.get()= *safe_cast
<System::Double
^>(aAny
.Value
);
942 pAny
->pData
= mem
.release();
945 case css::uno::TypeClass_STRING
: // anies often contain strings; copy string directly
947 pAny
->pData
= &pAny
->pReserved
;
948 OUString _s
= mapCliString(static_cast<System::String
^>(aAny
.Value
));
949 pAny
->pReserved
= _s
.pData
;
950 rtl_uString_acquire(_s
.pData
);
953 case css::uno::TypeClass_TYPE
:
954 case css::uno::TypeClass_ENUM
: //ToDo copy enum direct
955 case css::uno::TypeClass_SEQUENCE
:
956 case css::uno::TypeClass_INTERFACE
:
957 pAny
->pData
= &pAny
->pReserved
;
960 &pAny
->pReserved
, aAny
.Value
, value_td
.getTypeLibType(),
961 false /* no assign */);
963 case css::uno::TypeClass_STRUCT
:
964 case css::uno::TypeClass_EXCEPTION
:
966 css::uno::Type
anyType(value_td
);
967 typelib_TypeDescription
* td
= NULL
;
968 anyType
.getDescription(&td
);
969 std::unique_ptr
< rtl_mem
> mem(rtl_mem::allocate(td
->nSize
));
970 typelib_typedescription_release(td
);
972 mem
.get(), aAny
.Value
, value_td
.getTypeLibType(),
973 false /* no assign */);
974 pAny
->pData
= mem
.release();
979 throw BridgeRuntimeError("[map_to_uno():" + value_td
.getTypeName() + "] unsupported value type of any!");
983 catch(System::InvalidCastException
^ )
987 uno_any_construct( pAny
, 0, 0, 0 ); // restore some valid any
988 OUString str
= "[map_to_uno():Any" + value_td
.getTypeName() + "]The Any type " + value_td
.getTypeName() + " does not correspond to its value type: ";
989 if(aAny
.Value
!= nullptr)
991 css::uno::Type
td(mapCliType(aAny
.Value
->GetType()), SAL_NO_ACQUIRE
);
992 str
+= td
.getTypeName();
995 uno_any_construct( pAny
, 0, 0, 0 ); // restore some valid any
996 throw BridgeRuntimeError(str
);
998 catch (BridgeRuntimeError
& )
1001 uno_any_construct( pAny
, 0, 0, 0 ); // restore some valid any
1007 uno_any_construct( pAny
, 0, 0, 0 ); // restore some valid any
1011 pAny
->pType
= value_td
.getTypeLibType();
1012 typelib_typedescriptionreference_acquire(pAny
->pType
);
1015 case typelib_TypeClass_ENUM
:
1017 // InvalidCastException is caught at the end of this method
1018 System::Int32 aEnum
= System::Convert::ToInt32((cli_data
));
1019 *(sal_Int32
*) uno_data
= aEnum
;
1022 case typelib_TypeClass_STRUCT
:
1023 case typelib_TypeClass_EXCEPTION
:
1025 css::uno::TypeDescription
td(type
);
1026 typelib_CompoundTypeDescription
* comp_td
=
1027 (typelib_CompoundTypeDescription
*) td
.get();
1029 typelib_StructTypeDescription
* struct_td
= NULL
;
1030 if (type
->eTypeClass
== typelib_TypeClass_STRUCT
)
1031 struct_td
= (typelib_StructTypeDescription
*) td
.get();
1033 if ( ! ((typelib_TypeDescription
*) comp_td
)->bComplete
)
1034 ::typelib_typedescription_complete(
1035 (typelib_TypeDescription
**) & comp_td
);
1037 sal_Int32 nMembers
= comp_td
->nMembers
;
1038 boolean bException
= false;
1039 System::Type
^ cliType
= nullptr;
1041 cliType
= cli_data
->GetType();
1043 if (0 != comp_td
->pBaseTypeDescription
)
1047 ((typelib_TypeDescription
*)comp_td
->pBaseTypeDescription
)->pWeakRef
,
1053 OUString
usUnoException("com.sun.star.uno.Exception");
1054 for (; nPos
< nMembers
; ++nPos
)
1056 typelib_TypeDescriptionReference
* member_type
= comp_td
->ppTypeRefs
[nPos
];
1057 System::Object
^ val
= nullptr;
1058 if (cli_data
!= nullptr)
1060 sr::FieldInfo
^ aField
= cliType
->GetField(
1061 mapUnoString(comp_td
->ppMemberNames
[nPos
]));
1062 // special case for Exception.Message property
1063 // The com.sun.star.uno.Exception.Message field is mapped to the
1064 // System.Exception property. Type.GetField("Message") returns null
1065 if ( ! aField
&& usUnoException
.equals(td
.get()->pTypeName
))
1066 {// get Exception.Message property
1067 OUString
usMessageMember("Message");
1068 if (usMessageMember
.equals(comp_td
->ppMemberNames
[nPos
]))
1070 sr::PropertyInfo
^ pi
= cliType
->GetProperty(
1071 mapUnoString(comp_td
->ppMemberNames
[nPos
]));
1072 val
= pi
->GetValue(cli_data
, nullptr);
1076 throw BridgeRuntimeError("[map_to_uno(): Member: " + OUString::unacquired(&comp_td
->ppMemberNames
[nPos
]));
1081 val
= aField
->GetValue(cli_data
);
1084 void * p
= (char *) uno_data
+ comp_td
->pMemberOffsets
[ nPos
];
1085 //When using polymorphic structs then the parameterized members can be null.
1086 //Then we set a default value.
1087 bool bDefault
= (struct_td
!= NULL
1088 && struct_td
->pParameterizedTypes
!= NULL
1089 && struct_td
->pParameterizedTypes
[nPos
] == sal_True
1091 || cli_data
== nullptr;
1092 switch (member_type
->eTypeClass
)
1094 case typelib_TypeClass_CHAR
:
1096 *(sal_Unicode
*) p
= 0;
1098 *(sal_Unicode
*) p
= *safe_cast
<System::Char
^>(val
);
1100 case typelib_TypeClass_BOOLEAN
:
1102 *(sal_Bool
*) p
= sal_False
;
1104 *(sal_Bool
*) p
= *safe_cast
<System::Boolean
^>(val
);
1106 case typelib_TypeClass_BYTE
:
1110 *(sal_Int8
*) p
= *safe_cast
<System::Byte
^>(val
);
1112 case typelib_TypeClass_SHORT
:
1114 *(sal_Int16
*) p
= 0;
1116 *(sal_Int16
*) p
= *safe_cast
<System::Int16
^>(val
);
1118 case typelib_TypeClass_UNSIGNED_SHORT
:
1120 *(sal_uInt16
*) p
= 0;
1122 *(sal_uInt16
*) p
= *safe_cast
<System::UInt16
^>(val
);
1124 case typelib_TypeClass_LONG
:
1126 *(sal_Int32
*) p
= 0;
1128 *(sal_Int32
*) p
= *safe_cast
<System::Int32
^>(val
);
1130 case typelib_TypeClass_UNSIGNED_LONG
:
1132 *(sal_uInt32
*) p
= 0;
1134 *(sal_uInt32
*) p
= *safe_cast
<System::UInt32
^>(val
);
1136 case typelib_TypeClass_HYPER
:
1138 *(sal_Int64
*) p
= 0;
1140 *(sal_Int64
*) p
= *safe_cast
<System::Int64
^>(val
);
1142 case typelib_TypeClass_UNSIGNED_HYPER
:
1144 *(sal_uInt64
*) p
= 0;
1146 *(sal_uInt64
*) p
= *safe_cast
<System::UInt64
^>(val
);
1148 case typelib_TypeClass_FLOAT
:
1152 *(float*) p
= *safe_cast
<System::Single
^>(val
);
1154 case typelib_TypeClass_DOUBLE
:
1158 *(double*) p
= *safe_cast
<System::Double
^>(val
);
1161 { // ToDo enum, should be converted here
1162 map_to_uno(p
, val
, member_type
, assign
);
1168 catch (BridgeRuntimeError
& e
)
1171 OUString str
= "[map_to_uno():";
1174 str
+= mapCliString(cliType
->FullName
) + "." + OUString::unacquired(&comp_td
->ppMemberNames
[nPos
]) + " ";
1177 throw BridgeRuntimeError(str
);
1179 catch (System::InvalidCastException
^ )
1182 OUString str
= "[map_to_uno():";
1185 str
+= mapCliString(cliType
->FullName
) + "." + OUString::unacquired(&comp_td
->ppMemberNames
[nPos
]);
1187 str
+= "] Value has not the required type.";
1188 throw BridgeRuntimeError(str
);
1198 if (bException
&& !assign
) // if assign then caller cleans up
1200 // cleanup the members which we have converted so far
1201 for ( sal_Int32 nCleanup
= 0; nCleanup
< nPos
; ++nCleanup
)
1203 uno_type_destructData(
1204 uno_data
, comp_td
->ppTypeRefs
[ nCleanup
], 0 );
1206 if (0 != comp_td
->pBaseTypeDescription
)
1209 uno_data
, (typelib_TypeDescription
*)comp_td
->pBaseTypeDescription
, 0 );
1215 case typelib_TypeClass_SEQUENCE
:
1217 TypeDescr
td( type
);
1218 typelib_TypeDescriptionReference
* element_type
=
1219 ((typelib_IndirectTypeDescription
*)td
.get())->pType
;
1221 std::unique_ptr
< rtl_mem
> seq
;
1223 System::Array
^ ar
= nullptr;
1224 if (cli_data
!= nullptr)
1226 ar
= safe_cast
<System::Array
^>(cli_data
);
1227 sal_Int32 nElements
= ar
->GetLength(0);
1231 switch (element_type
->eTypeClass
)
1233 case typelib_TypeClass_CHAR
:
1234 seq
= seq_allocate(nElements
, sizeof (sal_Unicode
));
1235 sri::Marshal::Copy(safe_cast
<cli::array
<System::Char
>^>(cli_data
), 0,
1236 IntPtr(& ((uno_Sequence
*) seq
.get())->elements
), nElements
);
1238 case typelib_TypeClass_BOOLEAN
:
1239 seq
= seq_allocate(nElements
, sizeof (sal_Bool
));
1240 sri::Marshal::Copy(safe_cast
<cli::array
<System::Char
>^>(cli_data
), 0,
1241 IntPtr(& ((uno_Sequence
*) seq
.get())->elements
), nElements
);
1243 case typelib_TypeClass_BYTE
:
1244 seq
= seq_allocate( nElements
, sizeof (sal_Int8
) );
1245 sri::Marshal::Copy(safe_cast
<cli::array
<System::Byte
>^>(cli_data
), 0,
1246 IntPtr(& ((uno_Sequence
*) seq
.get())->elements
), nElements
);
1248 case typelib_TypeClass_SHORT
:
1249 seq
= seq_allocate(nElements
, sizeof (sal_Int16
));
1250 sri::Marshal::Copy(safe_cast
<cli::array
<System::Int16
>^>(cli_data
), 0,
1251 IntPtr(& ((uno_Sequence
*) seq
.get())->elements
), nElements
);
1253 case typelib_TypeClass_UNSIGNED_SHORT
:
1254 seq
= seq_allocate( nElements
, sizeof (sal_uInt16
) );
1255 sri::Marshal::Copy(dynamic_cast<cli::array
<System::Int16
>^>(
1256 safe_cast
<cli::array
<System::UInt16
>^>(cli_data
)), 0,
1257 IntPtr(& ((uno_Sequence
*) seq
.get())->elements
), nElements
);
1259 case typelib_TypeClass_LONG
:
1260 seq
= seq_allocate(nElements
, sizeof (sal_Int32
));
1261 sri::Marshal::Copy(safe_cast
<cli::array
<System::Int32
>^>(cli_data
), 0,
1262 IntPtr(& ((uno_Sequence
*) seq
.get())->elements
), nElements
);
1264 case typelib_TypeClass_UNSIGNED_LONG
:
1265 seq
= seq_allocate( nElements
, sizeof (sal_uInt32
) );
1266 sri::Marshal::Copy(dynamic_cast<cli::array
<System::Int32
>^>(
1267 safe_cast
<cli::array
<System::UInt32
>^>(cli_data
)), 0,
1268 IntPtr(& ((uno_Sequence
*) seq
.get())->elements
), nElements
);
1270 case typelib_TypeClass_HYPER
:
1271 seq
= seq_allocate(nElements
, sizeof (sal_Int64
));
1272 sri::Marshal::Copy(safe_cast
<cli::array
<System::Int64
>^>(cli_data
), 0,
1273 IntPtr(& ((uno_Sequence
*) seq
.get())->elements
), nElements
);
1275 case typelib_TypeClass_UNSIGNED_HYPER
:
1276 seq
= seq_allocate(nElements
, sizeof (sal_uInt64
));
1277 sri::Marshal::Copy(dynamic_cast<cli::array
<System::Int64
>^>(
1278 safe_cast
<cli::array
<System::UInt64
>^>(cli_data
)), 0,
1279 IntPtr(& ((uno_Sequence
*) seq
.get())->elements
), nElements
);
1281 case typelib_TypeClass_FLOAT
:
1282 seq
= seq_allocate(nElements
, sizeof (float));
1283 sri::Marshal::Copy(safe_cast
<cli::array
<System::Single
>^>(cli_data
), 0,
1284 IntPtr(& ((uno_Sequence
*) seq
.get())->elements
), nElements
);
1286 case typelib_TypeClass_DOUBLE
:
1287 seq
= seq_allocate(nElements
, sizeof (double));
1288 sri::Marshal::Copy(safe_cast
<cli::array
<System::Double
>^>(cli_data
), 0,
1289 IntPtr(& ((uno_Sequence
*) seq
.get())->elements
), nElements
);
1291 case typelib_TypeClass_STRING
:
1293 seq
= seq_allocate(nElements
, sizeof (rtl_uString
*));
1294 cli::array
<System::String
^>^ arStr
= safe_cast
<cli::array
<System::String
^>^>(cli_data
);
1295 for (int i
= 0; i
< nElements
; i
++)
1297 pin_ptr
<const wchar_t> pdata
= PtrToStringChars(arStr
[i
]);
1298 rtl_uString
** pStr
= & ((rtl_uString
**) &
1299 ((uno_Sequence
*) seq
.get())->elements
)[i
];
1301 rtl_uString_newFromStr_WithLength(
1303 reinterpret_cast<sal_Unicode
const *>(pdata
),
1308 case typelib_TypeClass_ENUM
:
1309 seq
= seq_allocate(nElements
, sizeof (sal_Int32
));
1310 for (int i
= 0; i
< nElements
; i
++)
1312 ((sal_Int32
*) &((uno_Sequence
*) seq
.get())->elements
)[i
]=
1313 System::Convert::ToInt32(ar
->GetValue(i
));
1316 case typelib_TypeClass_TYPE
:
1317 case typelib_TypeClass_ANY
:
1318 case typelib_TypeClass_STRUCT
:
1319 case typelib_TypeClass_EXCEPTION
:
1320 case typelib_TypeClass_SEQUENCE
:
1321 case typelib_TypeClass_INTERFACE
:
1323 TypeDescr
element_td( element_type
);
1324 seq
= seq_allocate( nElements
, element_td
.get()->nSize
);
1326 for (sal_Int32 nPos
= 0; nPos
< nElements
; ++nPos
)
1330 void * p
= ((uno_Sequence
*) seq
.get())->elements
+
1331 (nPos
* element_td
.get()->nSize
);
1332 System::Object
^ elemData
= safe_cast
<System::Array
^>(cli_data
)->GetValue(System::Int32(nPos
));
1334 p
, elemData
, element_td
.get()->pWeakRef
,
1335 false /* no assign */);
1340 for ( sal_Int32 nCleanPos
= 0; nCleanPos
< nPos
; ++nCleanPos
)
1343 ((uno_Sequence
*)seq
.get())->elements
+
1344 (nCleanPos
* element_td
.get()->nSize
);
1345 uno_destructData( p
, element_td
.get(), 0 );
1354 throw BridgeRuntimeError("[map_to_uno():" + OUString::unacquired( &type
->pTypeName
) +
1355 "] unsupported sequence element type: " + OUString::unacquired( &element_type
->pTypeName
));
1359 catch (BridgeRuntimeError
& e
)
1361 throw BridgeRuntimeError("[map_to_uno():" + OUString::unacquired( &type
->pTypeName
) + "] conversion failed\n " + e
.m_message
);
1363 catch (System::InvalidCastException
^ )
1366 throw BridgeRuntimeError("[map_to_uno():" + OUString::unacquired( &type
->pTypeName
) +
1367 "] could not convert sequence element type: " + OUString::unacquired( &element_type
->pTypeName
));
1377 uno_destructData( uno_data
, td
.get(), 0 );
1382 seq
= seq_allocate(0, sizeof (sal_Int32
));
1384 *(uno_Sequence
**)uno_data
= (uno_Sequence
*)seq
.release();
1387 case typelib_TypeClass_INTERFACE
:
1391 uno_Interface
* p
= *(uno_Interface
**)uno_data
;
1395 if (nullptr == cli_data
) // null-ref
1397 *(uno_Interface
**)uno_data
= 0;
1401 TypeDescr
td( type
);
1402 uno_Interface
* pUnoI
= map_cli2uno(cli_data
, td
.get());
1403 *(uno_Interface
**)uno_data
= pUnoI
;
1410 throw BridgeRuntimeError("[map_to_uno():" + OUString::unacquired( &type
->pTypeName
) + "] unsupported type!");
1414 // BridgeRuntimeError are allowed to be thrown
1415 catch (System::InvalidCastException
^ )
1418 throw BridgeRuntimeError("[map_to_uno():" + OUString::unacquired( &type
->pTypeName
) + "] could not convert type!");
1420 catch (System::NullReferenceException
^ e
)
1422 throw BridgeRuntimeError("[map_to_uno()] Illegal null reference passed!\n" + mapCliString(e
->StackTrace
));
1424 catch (BridgeRuntimeError
& )
1437 The expected target type. Currently info is provided when this method is called
1438 to convert the in/out and out parameters of a call from cli to uno. Then info
1439 is always a byref type, e.g. "System.String&". info is used for Any and Enum conversion.
1440 @param bDontCreateObj
1441 false - a new object is created which holds the mapped uno value and is assigned to
1443 true - cli_data already contains the newly constructed object. This is the case if
1444 a struct is converted then on the first call to map_to_cli the new object is created.
1445 If the struct inherits another struct then this function is called recursively while the
1446 newly created object is passed in cli_data.
1448 void Bridge::map_to_cli(
1449 System::Object
^ *cli_data
, void const * uno_data
,
1450 typelib_TypeDescriptionReference
* type
, System::Type
^ info
,
1451 bool bDontCreateObj
) const
1453 switch (type
->eTypeClass
)
1455 case typelib_TypeClass_CHAR
:
1456 *cli_data
= *(__wchar_t
const*)uno_data
;
1458 case typelib_TypeClass_BOOLEAN
:
1459 *cli_data
= (*(bool const*)uno_data
) == sal_True
;
1461 case typelib_TypeClass_BYTE
:
1462 *cli_data
= *(unsigned char const*) uno_data
;
1464 case typelib_TypeClass_SHORT
:
1465 *cli_data
= *(short const*) uno_data
;
1467 case typelib_TypeClass_UNSIGNED_SHORT
:
1468 *cli_data
= *(unsigned short const*) uno_data
;
1470 case typelib_TypeClass_LONG
:
1471 *cli_data
= *(int const*) uno_data
;
1473 case typelib_TypeClass_UNSIGNED_LONG
:
1474 *cli_data
= *(unsigned int const*) uno_data
;
1476 case typelib_TypeClass_HYPER
:
1477 *cli_data
= *(__int64
const*) uno_data
;
1479 case typelib_TypeClass_UNSIGNED_HYPER
:
1480 *cli_data
= *(unsigned __int64
const*) uno_data
;
1482 case typelib_TypeClass_FLOAT
:
1483 *cli_data
= *(float const*) uno_data
;
1485 case typelib_TypeClass_DOUBLE
:
1486 *cli_data
= *(double const*) uno_data
;
1488 case typelib_TypeClass_STRING
:
1490 rtl_uString
const* sVal
= NULL
;
1491 sVal
= *(rtl_uString
* const*) uno_data
;
1492 *cli_data
= gcnew
System::String((__wchar_t
*) sVal
->buffer
,0, sVal
->length
);
1495 case typelib_TypeClass_TYPE
:
1497 *cli_data
= mapUnoType( *(typelib_TypeDescriptionReference
* const *)uno_data
);
1500 case typelib_TypeClass_ANY
:
1502 uno_Any
const * pAny
= (uno_Any
const *)uno_data
;
1503 if (typelib_TypeClass_VOID
!= pAny
->pType
->eTypeClass
)
1505 System::Object
^ objCli
= nullptr;
1507 &objCli
, pAny
->pData
, pAny
->pType
, nullptr,
1510 uno::Any
anyVal(mapUnoType(pAny
->pType
), objCli
);
1515 *cli_data
= uno::Any::VOID
;
1519 case typelib_TypeClass_ENUM
:
1521 if (info
!= nullptr)
1523 OSL_ASSERT(info
->IsByRef
);
1524 info
= info
->GetElementType();
1525 *cli_data
= System::Enum::ToObject(info
, *(System::Int32
*) uno_data
);
1528 *cli_data
= System::Enum::ToObject(
1529 mapUnoType(type
), *(System::Int32
*) uno_data
);
1532 case typelib_TypeClass_STRUCT
:
1533 case typelib_TypeClass_EXCEPTION
:
1535 TypeDescr
td( type
);
1536 typelib_CompoundTypeDescription
* comp_td
=
1537 (typelib_CompoundTypeDescription
*) td
.get();
1538 if ( ! ((typelib_TypeDescription
*) comp_td
)->bComplete
)
1539 ::typelib_typedescription_complete(
1540 (typelib_TypeDescription
**) & comp_td
);
1544 System::Type
^ cliType
= loadCliType(td
.get()->pTypeName
);
1545 //detect if we recursively convert inherited structures
1546 //If this point is reached because of a recursive call during covering a
1547 //struct then we must not create a new object rather we use the one in
1548 // cli_data argument.
1549 System::Object
^ cliObj
;
1551 cliObj
= *cli_data
; // recursive call
1554 //Special handling for Exception conversion. We must call constructor System::Exception
1555 //to pass the message string
1556 if (ucss::uno::Exception::typeid->IsAssignableFrom(cliType
))
1558 //We need to get the Message field. Therefore we must obtain the offset from
1559 //the typedescription. The base interface of all exceptions is
1560 //com::sun::star::uno::Exception which contains the message
1561 typelib_CompoundTypeDescription
* pCTD
= comp_td
;
1562 while (pCTD
->pBaseTypeDescription
)
1563 pCTD
= pCTD
->pBaseTypeDescription
;
1566 OUString
usMessageMember("Message");
1567 for (int i
= 0; i
< pCTD
->nMembers
; i
++)
1569 if (usMessageMember
.equals(pCTD
->ppMemberNames
[i
]))
1575 OSL_ASSERT (nPos
!= -1);
1576 int offset
= pCTD
->pMemberOffsets
[nPos
];
1577 //With the offset within the exception we can get the message string
1578 System::String
^ sMessage
= mapUnoString(*(rtl_uString
**)
1579 ((char*) uno_data
+ offset
));
1580 //We need to find a constructor for the exception that takes the message string
1581 //We assume that the first argument is the message string
1582 cli::array
<sr::ConstructorInfo
^>^ arCtorInfo
= cliType
->GetConstructors();
1583 sr::ConstructorInfo
^ ctorInfo
= nullptr;
1584 int numCtors
= arCtorInfo
->Length
;
1585 //Constructor must at least have 2 params for the base
1586 //unoidl.com.sun.star.uno.Exception (String, Object);
1587 cli::array
<sr::ParameterInfo
^>^ arParamInfo
;
1588 for (int i
= 0; i
< numCtors
; i
++)
1590 arParamInfo
= arCtorInfo
[i
]->GetParameters();
1591 if (arParamInfo
->Length
< 2)
1593 ctorInfo
= arCtorInfo
[i
];
1596 assert(arParamInfo
);
1597 OSL_ASSERT(arParamInfo
[0]->ParameterType
->Equals(System::String::typeid)
1598 && arParamInfo
[1]->ParameterType
->Equals(System::Object::typeid)
1599 && arParamInfo
[0]->Position
== 0
1600 && arParamInfo
[1]->Position
== 1);
1601 //Prepare parameters for constructor
1602 int numArgs
= arParamInfo
->Length
;
1603 cli::array
<System::Object
^>^ args
= gcnew
cli::array
<System::Object
^>(numArgs
);
1604 //only initialize the first argument with the message
1606 cliObj
= ctorInfo
->Invoke(args
);
1609 cliObj
= System::Activator::CreateInstance(cliType
);
1611 sal_Int32
* pMemberOffsets
= comp_td
->pMemberOffsets
;
1613 if (comp_td
->pBaseTypeDescription
)
1615 //convert inherited struct
1616 //cliObj is passed inout (args in_param, out_param are true), hence the passed
1617 // cliObj is used by the callee instead of a newly created struct
1620 ((typelib_TypeDescription
*)comp_td
->pBaseTypeDescription
)->pWeakRef
, nullptr,
1623 OUString
usUnoException("com.sun.star.uno.Exception");
1624 for (sal_Int32 nPos
= comp_td
->nMembers
; nPos
--; )
1626 typelib_TypeDescriptionReference
* member_type
= comp_td
->ppTypeRefs
[ nPos
];
1627 System::String
^ sMemberName
= mapUnoString(comp_td
->ppMemberNames
[nPos
]);
1628 sr::FieldInfo
^ aField
= cliType
->GetField(sMemberName
);
1629 // special case for Exception.Message. The field has already been
1630 // set while constructing cli object
1631 if ( ! aField
&& usUnoException
.equals(td
.get()->pTypeName
))
1635 void const * p
= (char const *)uno_data
+ pMemberOffsets
[ nPos
];
1636 switch (member_type
->eTypeClass
)
1638 case typelib_TypeClass_CHAR
:
1639 aField
->SetValue(cliObj
, *(System::Char
*) p
);
1641 case typelib_TypeClass_BOOLEAN
:
1642 aField
->SetValue(cliObj
, *(System::Boolean
*) p
);
1644 case typelib_TypeClass_BYTE
:
1645 aField
->SetValue(cliObj
, *(System::Byte
*) p
);
1647 case typelib_TypeClass_SHORT
:
1648 aField
->SetValue(cliObj
, *(System::Int16
*) p
);
1650 case typelib_TypeClass_UNSIGNED_SHORT
:
1651 aField
->SetValue(cliObj
, *(System::UInt16
*) p
);
1653 case typelib_TypeClass_LONG
:
1654 aField
->SetValue(cliObj
, *(System::Int32
*) p
);
1656 case typelib_TypeClass_UNSIGNED_LONG
:
1657 aField
->SetValue(cliObj
, *(System::UInt32
*) p
);
1659 case typelib_TypeClass_HYPER
:
1660 aField
->SetValue(cliObj
, *(System::Int64
*) p
);
1662 case typelib_TypeClass_UNSIGNED_HYPER
:
1663 aField
->SetValue(cliObj
, *(System::UInt64
*) p
);
1665 case typelib_TypeClass_FLOAT
:
1666 aField
->SetValue(cliObj
, *(System::Single
*) p
);
1668 case typelib_TypeClass_DOUBLE
:
1669 aField
->SetValue(cliObj
, *(System::Double
*) p
);
1673 System::Object
^ cli_val
;
1675 &cli_val
, p
, member_type
, nullptr,
1677 aField
->SetValue(cliObj
, cli_val
);
1685 case typelib_TypeClass_SEQUENCE
:
1687 sal_Int32 nElements
;
1688 uno_Sequence
const * seq
= 0;
1689 seq
= *(uno_Sequence
* const *)uno_data
;
1690 nElements
= seq
->nElements
;
1692 TypeDescr
td( type
);
1693 typelib_TypeDescriptionReference
* element_type
=
1694 ((typelib_IndirectTypeDescription
*)td
.get())->pType
;
1696 switch (element_type
->eTypeClass
)
1698 case typelib_TypeClass_CHAR
:
1700 cli::array
<System::Char
>^ arChar
= gcnew
cli::array
<System::Char
>(nElements
);
1701 sri::Marshal::Copy( IntPtr((void*) &seq
->elements
), arChar
, 0, nElements
);
1705 case typelib_TypeClass_BOOLEAN
:
1707 cli::array
<System::Byte
>^ arBool
= gcnew
cli::array
<System::Byte
>(nElements
);
1708 sri::Marshal::Copy( IntPtr((void*) &seq
->elements
), arBool
, 0, nElements
);
1709 *cli_data
= dynamic_cast<cli::array
<System::Boolean
>^>(arBool
);
1712 case typelib_TypeClass_BYTE
:
1714 cli::array
<System::Byte
>^ arByte
= gcnew
cli::array
<System::Byte
>(nElements
);
1715 sri::Marshal::Copy( IntPtr((void*) &seq
->elements
), arByte
, 0, nElements
);
1719 case typelib_TypeClass_SHORT
:
1721 cli::array
<System::Int16
>^ arShort
= gcnew
cli::array
<System::Int16
>(nElements
);
1722 sri::Marshal::Copy( IntPtr((void*) &seq
->elements
), arShort
, 0, nElements
);
1726 case typelib_TypeClass_UNSIGNED_SHORT
:
1728 cli::array
<System::UInt16
>^ arUInt16
= gcnew
cli::array
<System::UInt16
>(nElements
);
1729 sri::Marshal::Copy( IntPtr((void*) &seq
->elements
), dynamic_cast<cli::array
<System::Int16
>^>(arUInt16
),
1731 *cli_data
= arUInt16
;
1734 case typelib_TypeClass_LONG
:
1736 cli::array
<System::Int32
>^ arInt32
= gcnew
cli::array
<System::Int32
>(nElements
);
1737 sri::Marshal::Copy( IntPtr((void*) &seq
->elements
), arInt32
, 0, nElements
);
1741 case typelib_TypeClass_UNSIGNED_LONG
:
1743 cli::array
<System::UInt32
>^ arUInt32
= gcnew
cli::array
<System::UInt32
>(nElements
);
1744 sri::Marshal::Copy( IntPtr((void*) &seq
->elements
), dynamic_cast<cli::array
<System::Int32
>^>(arUInt32
),
1746 *cli_data
= arUInt32
;
1749 case typelib_TypeClass_HYPER
:
1751 cli::array
<System::Int64
>^ arInt64
= gcnew
cli::array
<System::Int64
>(nElements
);
1752 sri::Marshal::Copy( IntPtr((void*) &seq
->elements
), arInt64
, 0, nElements
);
1756 //FIXME: Marshal::Copy of UInt64?
1757 case typelib_TypeClass_UNSIGNED_HYPER
:
1759 cli::array
<System::IntPtr
>^ arUInt64
= gcnew
cli::array
<System::IntPtr
>(nElements
);
1760 sri::Marshal::Copy( IntPtr((void*) &seq
->elements
), arUInt64
, 0, nElements
);
1761 *cli_data
= dynamic_cast<cli::array
<System::UInt64
>^>(arUInt64
);
1764 case typelib_TypeClass_FLOAT
:
1766 cli::array
<System::Single
>^ arSingle
= gcnew
cli::array
<System::Single
>(nElements
);
1767 sri::Marshal::Copy( IntPtr((void*) &seq
->elements
), arSingle
, 0, nElements
);
1768 *cli_data
= arSingle
;
1771 case typelib_TypeClass_DOUBLE
:
1773 cli::array
<System::Double
>^ arDouble
= gcnew
cli::array
<System::Double
>(nElements
);
1774 sri::Marshal::Copy( IntPtr((void*) &seq
->elements
), arDouble
, 0, nElements
);
1775 *cli_data
= arDouble
;
1778 case typelib_TypeClass_STRING
:
1780 cli::array
<System::String
^>^ arString
= gcnew
cli::array
<System::String
^>(nElements
);
1781 for (int i
= 0; i
< nElements
; i
++)
1783 rtl_uString
*aStr
= ((rtl_uString
**)(&seq
->elements
))[i
];
1784 arString
[i
]= gcnew
System::String( (__wchar_t
*) &aStr
->buffer
, 0, aStr
->length
);
1786 *cli_data
= arString
;
1789 case typelib_TypeClass_TYPE
:
1791 cli::array
<System::Type
^>^ arType
= gcnew
cli::array
<System::Type
^>(nElements
);
1792 for (int i
= 0; i
< nElements
; i
++)
1795 mapUnoType( ((typelib_TypeDescriptionReference
**) seq
->elements
)[i
]);
1800 case typelib_TypeClass_ANY
:
1802 cli::array
<uno::Any
>^ arCli
= gcnew
cli::array
<uno::Any
>(nElements
);
1803 uno_Any
const * p
= (uno_Any
const *)seq
->elements
;
1804 for (sal_Int32 nPos
= 0; nPos
< nElements
; ++nPos
)
1806 System::Object
^ cli_obj
= nullptr;
1808 &cli_obj
, &p
[ nPos
], element_type
, nullptr, false);
1809 arCli
[nPos
]= *safe_cast
<uno::Any
^>(cli_obj
);
1814 case typelib_TypeClass_ENUM
:
1817 System::Type
^ enumType
= nullptr;
1818 if (info
!= nullptr)
1820 //info is EnumType[]&, remove &
1821 OSL_ASSERT(info
->IsByRef
);
1822 enumType
= info
->GetElementType();
1823 //enumType is EnumType[], remove []
1824 enumType
= enumType
->GetElementType();
1827 enumType
= mapUnoType(element_type
);
1829 System::Array
^ arEnum
= System::Array::CreateInstance(
1830 enumType
, nElements
);
1831 for (int i
= 0; i
< nElements
; i
++)
1833 arEnum
->SetValue(System::Enum::ToObject(enumType
,
1834 System::Int32(((sal_Int32
*) seq
->elements
)[i
])), i
);
1839 case typelib_TypeClass_STRUCT
:
1840 case typelib_TypeClass_EXCEPTION
:
1842 TypeDescr
element_td( element_type
);
1843 System::Array
^ ar
= System::Array::CreateInstance(
1844 mapUnoType(element_type
),nElements
);
1848 char * p
= (char *) &seq
->elements
;
1849 sal_Int32 nSize
= element_td
.get()->nSize
;
1850 for ( sal_Int32 nPos
= 0; nPos
< nElements
; ++nPos
)
1852 System::Object
^ val
;
1854 &val
, p
+ (nSize
* nPos
), element_type
, nullptr, false);
1855 ar
->SetValue(val
, System::Int32(nPos
));
1862 case typelib_TypeClass_SEQUENCE
:
1864 System::Array
^ar
= System::Array::CreateInstance(
1865 mapUnoType(element_type
), nElements
);
1868 TypeDescr
element_td( element_type
);
1869 uno_Sequence
** elements
= (uno_Sequence
**) seq
->elements
;
1870 for ( sal_Int32 nPos
= 0; nPos
< nElements
; ++nPos
)
1872 System::Object
^ val
;
1874 &val
, &elements
[nPos
], element_type
, nullptr, false);
1875 ar
->SetValue(val
, System::Int32(nPos
));
1881 case typelib_TypeClass_INTERFACE
:
1883 TypeDescr
element_td( element_type
);
1884 System::Type
^ ifaceType
= mapUnoType(element_type
);
1885 System::Array
^ ar
= System::Array::CreateInstance(ifaceType
, nElements
);
1887 char * p
= (char *)seq
->elements
;
1888 sal_Int32 nSize
= element_td
.get()->nSize
;
1889 for ( sal_Int32 nPos
= 0; nPos
< nElements
; ++nPos
)
1891 System::Object
^ val
;
1893 &val
, p
+ (nSize
* nPos
), element_type
, nullptr, false);
1895 ar
->SetValue(val
, System::Int32(nPos
));
1902 throw BridgeRuntimeError("[map_to_cli():" + OUString::unacquired( &type
->pTypeName
) +
1903 "] unsupported element type: " + OUString::unacquired( &element_type
->pTypeName
));
1908 case typelib_TypeClass_INTERFACE
:
1910 uno_Interface
* pUnoI
= *(uno_Interface
* const *)uno_data
;
1913 TypeDescr
td( type
);
1914 *cli_data
= map_uno2cli( pUnoI
, reinterpret_cast<
1915 typelib_InterfaceTypeDescription
*>(td
.get())) ;
1923 //ToDo check this exception. The String is probably crippled
1924 throw BridgeRuntimeError("[map_to_cli():" + OUString::unacquired( &type
->pTypeName
) + "] unsupported type!");
1930 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */