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
;
49 System::String
^ mapUnoPolymorphicName(System::String
^ unoName
);
50 OUString
mapCliTypeName(System::String
^ typeName
);
51 System::String
^ mapCliPolymorphicName(System::String
^ unoName
);
52 System::String
^ mapPolymorphicName(System::String
^ unoName
, bool bCliToUno
);
54 inline unique_ptr
< rtl_mem
> seq_allocate( sal_Int32 nElements
, sal_Int32 nSize
)
56 unique_ptr
< rtl_mem
> seq(
57 rtl_mem::allocate( SAL_SEQUENCE_HEADER_SIZE
+ (nElements
* nSize
) ) );
58 uno_Sequence
* p
= (uno_Sequence
*)seq
.get();
60 p
->nElements
= nElements
;
64 System::Object
^ Bridge::map_uno2cli(uno_Interface
* pUnoI
, typelib_InterfaceTypeDescription
*pTD
) const
66 System::Object
^ retVal
= nullptr;
68 rtl_uString
* pOid
= 0;
69 (*m_uno_env
->getObjectIdentifier
)( m_uno_env
, &pOid
, pUnoI
);
70 OSL_ASSERT( 0 != pOid
);
71 OUString
oid(pOid
, SAL_NO_ACQUIRE
);
73 // see if the interface was already mapped
74 System::Type
^ ifaceType
= mapUnoType(reinterpret_cast<typelib_TypeDescription
*>(pTD
));
75 System::String
^ sOid
= mapUnoString(oid
.pData
);
77 System::Threading::Monitor::Enter( CliEnvHolder::g_cli_env
);
80 retVal
= CliEnvHolder::g_cli_env
->getRegisteredInterface(sOid
, ifaceType
);
83 // There is already a registered object. It can either be a proxy
84 // for the UNO object or a real cli object. In the first case we
85 // tell the proxy that it shall also represent the current UNO
86 // interface. If it already does that, then it does nothing
87 if (srr::RemotingServices::IsTransparentProxy(retVal
))
89 UnoInterfaceProxy
^ p
= static_cast<UnoInterfaceProxy
^>(
90 srr::RemotingServices::GetRealProxy(retVal
));
91 p
->addUnoInterface(pUnoI
, pTD
);
96 retVal
= UnoInterfaceProxy::create(
97 (Bridge
*) this, pUnoI
, pTD
, oid
);
102 System::Threading::Monitor::Exit( CliEnvHolder::g_cli_env
);
108 uno_Interface
* Bridge::map_cli2uno(System::Object
^ cliObj
, typelib_TypeDescription
*pTD
) const
110 uno_Interface
* retIface
= NULL
;
111 // get oid from dot net environment
112 System::String
^ ds_oid
= CliEnvHolder::g_cli_env
->getObjectIdentifier( cliObj
);
113 OUString ousOid
= mapCliString(ds_oid
);
114 // look if interface is already mapped
115 m_uno_env
->getRegisteredInterface(m_uno_env
, (void**) &retIface
, ousOid
.pData
,
116 (typelib_InterfaceTypeDescription
*) pTD
);
119 System::Threading::Monitor::Enter(Cli_environment::typeid);
122 m_uno_env
->getRegisteredInterface(m_uno_env
, (void**) &retIface
, ousOid
.pData
,
123 (typelib_InterfaceTypeDescription
*) pTD
);
126 retIface
= CliProxy::create((Bridge
*)this, cliObj
, pTD
, ousOid
);
131 System::Threading::Monitor::Exit(Cli_environment::typeid);
137 inline System::Type
^ loadCliType(rtl_uString
* unoName
)
139 return loadCliType(mapUnoTypeName(unoName
));
142 System::Type
^ loadCliType(System::String
^ unoName
)
144 System::Type
^ retVal
= nullptr;
147 //If unoName denotes a polymorphic type, e.g com.sun.star.beans.Defaulted<System.Char>
148 //then we remove the type list, otherwise the type could not be loaded.
149 bool bIsPolymorphic
= false;
151 System::String
^ loadName
= unoName
;
152 int index
= unoName
->IndexOf('<');
155 loadName
= unoName
->Substring(0, index
);
156 bIsPolymorphic
= true;
158 System::AppDomain
^ currentDomain
= System::AppDomain::CurrentDomain
;
159 cli::array
<sr::Assembly
^>^ assems
= currentDomain
->GetAssemblies();
160 for (int i
= 0; i
< assems
->Length
; i
++)
162 retVal
= assems
[i
]->GetType(loadName
, false);
167 if (retVal
== nullptr)
169 System::String
^ msg
= gcnew
System::String("A type could not be loaded: ");
170 msg
= System::String::Concat(msg
, loadName
);
171 throw BridgeRuntimeError(mapCliString(msg
));
176 retVal
= uno::PolymorphicType::GetType(retVal
, unoName
);
179 catch( System::Exception
^ e
)
181 OUString
ouMessage(mapCliString(e
->Message
));
182 throw BridgeRuntimeError(ouMessage
);
187 System::Type
^ mapUnoType(typelib_TypeDescription
const * pTD
)
189 return mapUnoType(pTD
->pWeakRef
);
192 System::Type
^ mapUnoType(typelib_TypeDescriptionReference
const * pTD
)
194 System::Type
^ retVal
= nullptr;
195 switch (pTD
->eTypeClass
)
197 case typelib_TypeClass_VOID
:
198 retVal
= void::typeid; break;
199 case typelib_TypeClass_CHAR
:
200 retVal
= System::Char::typeid; break;
201 case typelib_TypeClass_BOOLEAN
:
202 retVal
= System::Boolean::typeid; break;
203 case typelib_TypeClass_BYTE
:
204 retVal
= System::Byte::typeid; break;
205 case typelib_TypeClass_SHORT
:
206 retVal
= System::Int16::typeid; break;
207 case typelib_TypeClass_UNSIGNED_SHORT
:
208 retVal
= System::UInt16::typeid; break;
209 case typelib_TypeClass_LONG
:
210 retVal
= System::Int32::typeid; break;
211 case typelib_TypeClass_UNSIGNED_LONG
:
212 retVal
= System::UInt32::typeid; break;
213 case typelib_TypeClass_HYPER
:
214 retVal
= System::Int64::typeid; break;
215 case typelib_TypeClass_UNSIGNED_HYPER
:
216 retVal
= System::UInt64::typeid; break;
217 case typelib_TypeClass_FLOAT
:
218 retVal
= System::Single::typeid; break;
219 case typelib_TypeClass_DOUBLE
:
220 retVal
= System::Double::typeid; break;
221 case typelib_TypeClass_STRING
:
222 retVal
= System::String::typeid; break;
223 case typelib_TypeClass_TYPE
:
224 retVal
= System::Type::typeid; break;
225 case typelib_TypeClass_ANY
:
226 retVal
= uno::Any::typeid; break;
227 case typelib_TypeClass_ENUM
:
228 case typelib_TypeClass_STRUCT
:
229 case typelib_TypeClass_EXCEPTION
:
230 retVal
= loadCliType(pTD
->pTypeName
); break;
231 case typelib_TypeClass_INTERFACE
:
233 //special handling for XInterface, since it does not exist in cli.
234 OUString
usXInterface("com.sun.star.uno.XInterface");
235 if (usXInterface
.equals(pTD
->pTypeName
))
236 retVal
= System::Object::typeid;
238 retVal
= loadCliType(pTD
->pTypeName
);
241 case typelib_TypeClass_SEQUENCE
:
243 css::uno::TypeDescription
seqType(
244 const_cast<typelib_TypeDescriptionReference
*>(pTD
));
245 typelib_TypeDescriptionReference
* pElementTDRef
=
246 reinterpret_cast<typelib_IndirectTypeDescription
*>(seqType
.get())->pType
;
247 switch (pElementTDRef
->eTypeClass
)
249 case typelib_TypeClass_CHAR
:
250 retVal
= System::Type::GetType(const_cast<System::String
^>(Constants::sArChar
)); break;
251 case typelib_TypeClass_BOOLEAN
:
252 retVal
= System::Type::GetType(const_cast<System::String
^>(Constants::sArBoolean
));
254 case typelib_TypeClass_BYTE
:
255 retVal
= System::Type::GetType(const_cast<System::String
^>(Constants::sArByte
));
257 case typelib_TypeClass_SHORT
:
258 retVal
= System::Type::GetType(const_cast<System::String
^>(Constants::sArInt16
));
260 case typelib_TypeClass_UNSIGNED_SHORT
:
261 retVal
= System::Type::GetType(const_cast<System::String
^>(Constants::sArUInt16
));
263 case typelib_TypeClass_LONG
:
264 retVal
= System::Type::GetType(const_cast<System::String
^>(Constants::sArInt32
));
266 case typelib_TypeClass_UNSIGNED_LONG
:
267 retVal
= System::Type::GetType(const_cast<System::String
^>(Constants::sArUInt32
));
269 case typelib_TypeClass_HYPER
:
270 retVal
= System::Type::GetType(const_cast<System::String
^>(Constants::sArInt64
));
272 case typelib_TypeClass_UNSIGNED_HYPER
:
273 retVal
= System::Type::GetType(const_cast<System::String
^>(Constants::sArUInt64
));
275 case typelib_TypeClass_FLOAT
:
276 retVal
= System::Type::GetType(const_cast<System::String
^>(Constants::sArSingle
));
278 case typelib_TypeClass_DOUBLE
:
279 retVal
= System::Type::GetType(const_cast<System::String
^>(Constants::sArDouble
));
281 case typelib_TypeClass_STRING
:
282 retVal
= System::Type::GetType(const_cast<System::String
^>(Constants::sArString
));
284 case typelib_TypeClass_TYPE
:
285 retVal
= System::Type::GetType(const_cast<System::String
^>(Constants::sArType
));
287 case typelib_TypeClass_ANY
:
288 case typelib_TypeClass_ENUM
:
289 case typelib_TypeClass_EXCEPTION
:
290 case typelib_TypeClass_STRUCT
:
291 case typelib_TypeClass_INTERFACE
:
292 case typelib_TypeClass_SEQUENCE
:
294 retVal
= loadCliType(pTD
->pTypeName
);
298 //All cases should be handled by the case statements above
311 /** Returns an acquired td.
313 typelib_TypeDescriptionReference
* mapCliType(System::Type
^ cliType
)
315 typelib_TypeDescriptionReference
* retVal
= NULL
;
316 if (cliType
== nullptr)
318 retVal
= * typelib_static_type_getByTypeClass(
319 typelib_TypeClass_VOID
);
320 typelib_typedescriptionreference_acquire( retVal
);
323 //check for Enum first,
324 //because otherwise case System::TypeCode::Int32 applies
327 OUString usTypeName
= mapCliTypeName(cliType
->FullName
);
328 css::uno::Type
unoType(css::uno::TypeClass_ENUM
, usTypeName
);
329 retVal
= unoType
.getTypeLibType();
330 typelib_typedescriptionreference_acquire(retVal
);
334 switch (System::Type::GetTypeCode(cliType
))
336 case System::TypeCode::Boolean
:
337 retVal
= * typelib_static_type_getByTypeClass(
338 typelib_TypeClass_BOOLEAN
);
339 typelib_typedescriptionreference_acquire( retVal
);
341 case System::TypeCode::Char
:
342 retVal
= * typelib_static_type_getByTypeClass(
343 typelib_TypeClass_CHAR
);
344 typelib_typedescriptionreference_acquire( retVal
);
346 case System::TypeCode::Byte
:
347 retVal
= * typelib_static_type_getByTypeClass(
348 typelib_TypeClass_BYTE
);
349 typelib_typedescriptionreference_acquire( retVal
);
351 case System::TypeCode::Int16
:
352 retVal
= * typelib_static_type_getByTypeClass(
353 typelib_TypeClass_SHORT
);
354 typelib_typedescriptionreference_acquire( retVal
);
356 case System::TypeCode::Int32
:
357 retVal
= * typelib_static_type_getByTypeClass(
358 typelib_TypeClass_LONG
);
359 typelib_typedescriptionreference_acquire( retVal
);
361 case System::TypeCode::Int64
:
362 retVal
= * typelib_static_type_getByTypeClass(
363 typelib_TypeClass_HYPER
);
364 typelib_typedescriptionreference_acquire( retVal
);
366 case System::TypeCode::UInt16
:
367 retVal
= * typelib_static_type_getByTypeClass(
368 typelib_TypeClass_UNSIGNED_SHORT
);
369 typelib_typedescriptionreference_acquire( retVal
);
371 case System::TypeCode::UInt32
:
372 retVal
= * typelib_static_type_getByTypeClass(
373 typelib_TypeClass_UNSIGNED_LONG
);
374 typelib_typedescriptionreference_acquire( retVal
);
376 case System::TypeCode::UInt64
:
377 retVal
= * typelib_static_type_getByTypeClass(
378 typelib_TypeClass_UNSIGNED_HYPER
);
379 typelib_typedescriptionreference_acquire( retVal
);
381 case System::TypeCode::Single
:
382 retVal
= * typelib_static_type_getByTypeClass(
383 typelib_TypeClass_FLOAT
);
384 typelib_typedescriptionreference_acquire( retVal
);
386 case System::TypeCode::Double
:
387 retVal
= * typelib_static_type_getByTypeClass(
388 typelib_TypeClass_DOUBLE
);
389 typelib_typedescriptionreference_acquire( retVal
);
391 case System::TypeCode::String
:
392 retVal
= * typelib_static_type_getByTypeClass(
393 typelib_TypeClass_STRING
);
394 typelib_typedescriptionreference_acquire( retVal
);
402 System::String
^ cliTypeName
= cliType
->FullName
;
404 if (const_cast<System::String
^>(Constants::sVoid
)->Equals(
407 retVal
= * typelib_static_type_getByTypeClass(
408 typelib_TypeClass_VOID
);
409 typelib_typedescriptionreference_acquire( retVal
);
412 else if (const_cast<System::String
^>(Constants::sType
)->Equals(
415 retVal
= * typelib_static_type_getByTypeClass(
416 typelib_TypeClass_TYPE
);
417 typelib_typedescriptionreference_acquire( retVal
);
420 else if (const_cast<System::String
^>(Constants::sAny
)->Equals(
423 retVal
= * typelib_static_type_getByTypeClass(
424 typelib_TypeClass_ANY
);
425 typelib_typedescriptionreference_acquire( retVal
);
427 //struct, interfaces, sequences
431 uno::PolymorphicType
^ poly
= dynamic_cast<uno::PolymorphicType
^>(cliType
);
433 usTypeName
= mapCliTypeName( poly
->PolymorphicName
);
435 usTypeName
= mapCliTypeName(cliTypeName
);
436 typelib_TypeDescription
* td
= NULL
;
437 typelib_typedescription_getByName(&td
, usTypeName
.pData
);
440 retVal
= td
->pWeakRef
;
441 typelib_typedescriptionreference_acquire(retVal
);
442 typelib_typedescription_release(td
);
448 throw BridgeRuntimeError("[cli_uno bridge] mapCliType():could not map type: " + mapCliString(cliType
->FullName
));
454 Otherwise a leading "unoidl." is removed.
456 System::String
^ mapUnoTypeName(rtl_uString
const * typeName
)
458 OUString
usUnoName( const_cast< rtl_uString
* >( typeName
) );
459 st::StringBuilder
^ buf
= gcnew
st::StringBuilder();
460 //determine if the type is a sequence and its dimensions
462 if (usUnoName
[0] == '[')
467 if (usUnoName
[index
++] == ']')
469 if (usUnoName
[index
++] != '[')
472 usUnoName
= usUnoName
.copy(index
- 1);
474 System::String
^ sUnoName
= mapUnoString(usUnoName
.pData
);
475 if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usBool
)))
476 buf
->Append(const_cast<System::String
^>(Constants::sBoolean
));
477 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usChar
)))
478 buf
->Append(const_cast<System::String
^>(Constants::sChar
));
479 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usByte
)))
480 buf
->Append(const_cast<System::String
^>(Constants::sByte
));
481 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usShort
)))
482 buf
->Append(const_cast<System::String
^>(Constants::sInt16
));
483 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usUShort
)))
484 buf
->Append(const_cast<System::String
^>(Constants::sUInt16
));
485 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usLong
)))
486 buf
->Append(const_cast<System::String
^>(Constants::sInt32
));
487 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usULong
)))
488 buf
->Append(const_cast<System::String
^>(Constants::sUInt32
));
489 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usHyper
)))
490 buf
->Append(const_cast<System::String
^>(Constants::sInt64
));
491 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usUHyper
)))
492 buf
->Append(const_cast<System::String
^>(Constants::sUInt64
));
493 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usFloat
)))
494 buf
->Append(const_cast<System::String
^>(Constants::sSingle
));
495 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usDouble
)))
496 buf
->Append(const_cast<System::String
^>(Constants::sDouble
));
497 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usString
)))
498 buf
->Append(const_cast<System::String
^>(Constants::sString
));
499 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usVoid
)))
500 buf
->Append(const_cast<System::String
^>(Constants::sVoid
));
501 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usType
)))
502 buf
->Append(const_cast<System::String
^>(Constants::sType
));
503 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usXInterface
)))
504 buf
->Append(const_cast<System::String
^>(Constants::sObject
));
505 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usAny
)))
507 buf
->Append(const_cast<System::String
^>(Constants::sAny
));
511 //put "unoidl." at the beginning
512 buf
->Append(const_cast<System::String
^>(Constants::sUnoidl
));
513 //for polymorphic struct types remove the brackets, e.g mystruct<bool> -> mystruct
514 System::String
^ sName
= mapUnoPolymorphicName(sUnoName
);
519 buf
->Append(const_cast<System::String
^>(Constants::sBrackets
));
521 return buf
->ToString();
524 /** For example, there is a uno type
525 com.sun.star.Foo<char, long>.
526 The values in the type list
527 are uno types and are replaced by cli types, such as System.Char,
529 The prefix unoidl is not added.
531 inline System::String
^ mapUnoPolymorphicName(System::String
^ unoName
)
533 return mapPolymorphicName(unoName
, false);
536 /** For example, there is a type name such as
537 com.sun.star.Foo<System.Char, System.Int32>.
538 The values in the type list
539 are CLI types and are replaced by uno types, such as char,
541 The prefix unoidl remains.
543 inline System::String
^ mapCliPolymorphicName(System::String
^ unoName
)
545 return mapPolymorphicName(unoName
, true);
548 System::String
^ mapPolymorphicName(System::String
^ unoName
, bool bCliToUno
)
550 int index
= unoName
->IndexOf('<');
554 System::Text::StringBuilder
^ builder
= gcnew
System::Text::StringBuilder(256);
555 builder
->Append(unoName
->Substring(0, index
+1 ));
557 //Find the first occurrence of ','
558 //If the parameter is a polymorphic struct then we need to ignore everything
559 //between the brackets because it can also contain commas
560 //get the type list within < and >
561 int endIndex
= unoName
->Length
- 1;
565 while (cur
<= endIndex
)
567 System::Char c
= unoName
[cur
];
568 if (c
== ',' || c
== '>')
570 //insert a comma if needed
571 if (countParams
!= 0)
572 builder
->Append(",");
574 System::String
^ sParam
= unoName
->Substring(index
, cur
- index
);
577 //the index to the beginning of the next param
581 builder
->Append(mapCliTypeName(sParam
).getStr());
585 OUString s
= mapCliString(sParam
);
586 builder
->Append(mapUnoTypeName(s
.pData
));
592 //continue until the matching '>'
596 System::Char curChar
= unoName
[cur
];
601 else if (curChar
== '>')
613 builder
->Append((System::Char
) '>');
614 return builder
->ToString();
617 OUString
mapCliTypeName(System::String
^ typeName
)
620 // Array? determine the "rank" (number of "[]")
621 // move from the rightmost end to the left, for example
622 // unoidl.PolymorphicStruct<System.Char[]>[]
623 // has only a "dimension" of 1
624 int cur
= typeName
->Length
- 1;
625 bool bRightBracket
= false;
628 System::Char c
= typeName
[cur
];
631 bRightBracket
= true;
636 throw BridgeRuntimeError(
637 "Typename is wrong. No matching brackets for sequence. Name is: " +
638 mapCliString(typeName
));
639 bRightBracket
= false;
645 throw BridgeRuntimeError(
646 "Typename is wrong. No matching brackets for sequence. Name is: " +
647 mapCliString(typeName
));
653 if (bRightBracket
|| cur
< 0)
654 throw BridgeRuntimeError(
655 "Typename is wrong. " +
656 mapCliString(typeName
));
658 typeName
= typeName
->Substring(0, cur
+ 1);
660 System::Text::StringBuilder
^ buf
= gcnew
System::Text::StringBuilder(512);
662 //Put the "[]" at the beginning of the uno type name
664 buf
->Append(const_cast<System::String
^>(Constants::usBrackets
));
666 if (typeName
->Equals(const_cast<System::String
^>(Constants::sBoolean
)))
667 buf
->Append(const_cast<System::String
^>(Constants::usBool
));
668 else if (typeName
->Equals(const_cast<System::String
^>(Constants::sChar
)))
669 buf
->Append(const_cast<System::String
^>(Constants::usChar
));
670 else if (typeName
->Equals(const_cast<System::String
^>(Constants::sByte
)))
671 buf
->Append(const_cast<System::String
^>(Constants::usByte
));
672 else if (typeName
->Equals(const_cast<System::String
^>(Constants::sInt16
)))
673 buf
->Append(const_cast<System::String
^>(Constants::usShort
));
674 else if (typeName
->Equals(const_cast<System::String
^>(Constants::sUInt16
)))
675 buf
->Append(const_cast<System::String
^>(Constants::usUShort
));
676 else if (typeName
->Equals(const_cast<System::String
^>(Constants::sInt32
)))
677 buf
->Append(const_cast<System::String
^>(Constants::usLong
));
678 else if (typeName
->Equals(const_cast<System::String
^>(Constants::sUInt32
)))
679 buf
->Append(const_cast<System::String
^>(Constants::usULong
));
680 else if (typeName
->Equals(const_cast<System::String
^>(Constants::sInt64
)))
681 buf
->Append(const_cast<System::String
^>(Constants::usHyper
));
682 else if (typeName
->Equals(const_cast<System::String
^>(Constants::sUInt64
)))
683 buf
->Append(const_cast<System::String
^>(Constants::usUHyper
));
684 else if (typeName
->Equals(const_cast<System::String
^>(Constants::sSingle
)))
685 buf
->Append(const_cast<System::String
^>(Constants::usFloat
));
686 else if (typeName
->Equals(const_cast<System::String
^>(Constants::sDouble
)))
687 buf
->Append(const_cast<System::String
^>(Constants::usDouble
));
688 else if (typeName
->Equals(const_cast<System::String
^>(Constants::sString
)))
689 buf
->Append(const_cast<System::String
^>(Constants::usString
));
690 else if (typeName
->Equals(const_cast<System::String
^>(Constants::sVoid
)))
691 buf
->Append(const_cast<System::String
^>(Constants::usVoid
));
692 else if (typeName
->Equals(const_cast<System::String
^>(Constants::sType
)))
693 buf
->Append(const_cast<System::String
^>(Constants::usType
));
694 else if (typeName
->Equals(const_cast<System::String
^>(Constants::sObject
)))
695 buf
->Append(const_cast<System::String
^>(Constants::usXInterface
));
696 else if (typeName
->Equals(const_cast<System::String
^>(Constants::sAny
)))
697 buf
->Append(const_cast<System::String
^>(Constants::usAny
));
700 System::String
^ sName
= mapCliPolymorphicName(typeName
);
701 int i
= sName
->IndexOf(L
'.');
702 buf
->Append(sName
->Substring(i
+ 1));
704 return mapCliString(buf
->ToString());
707 /** Maps uno types to dot net types.
708 * If uno_data is null then the type description is converted to System::Type
710 inline System::String
^ mapUnoString( rtl_uString
const * data
)
713 return gcnew
System::String((__wchar_t
*) data
->buffer
, 0, data
->length
);
716 OUString
mapCliString(System::String
^ data
)
721 static_assert(sizeof(wchar_t) == sizeof(sal_Unicode
), "char mismatch");
722 pin_ptr
<wchar_t const> pdata
= PtrToStringChars(data
);
724 reinterpret_cast<sal_Unicode
const *>(pdata
),
725 const_cast<System::String
^>(data
)->Length
);
733 // ToDo convert cli types to expected types, e.g a long to a short where the uno type
734 // is a sal_Int16. This could be necessary if a scripting language (typeless) is used
735 // @param assign the uno_data has to be destructed (in/out args)
736 void Bridge::map_to_uno(void * uno_data
, System::Object
^ cli_data
,
737 typelib_TypeDescriptionReference
* type
,
741 switch (type
->eTypeClass
)
743 case typelib_TypeClass_VOID
:
745 case typelib_TypeClass_CHAR
:
747 System::Char aChar
= *safe_cast
<System::Char
^>(cli_data
);
748 *(sal_Unicode
*) uno_data
= aChar
;
751 case typelib_TypeClass_BOOLEAN
:
753 System::Boolean aBool
= *safe_cast
<System::Boolean
^>(cli_data
);
754 *(sal_Bool
*)uno_data
= aBool
== true ? sal_True
: sal_False
;
757 case typelib_TypeClass_BYTE
:
759 System::Byte aByte
= *safe_cast
<System::Byte
^>(cli_data
);
760 *(sal_Int8
*) uno_data
= aByte
;
763 case typelib_TypeClass_SHORT
:
765 System::Int16 aShort
= *safe_cast
<System::Int16
^>(cli_data
);
766 *(sal_Int16
*) uno_data
= aShort
;
769 case typelib_TypeClass_UNSIGNED_SHORT
:
771 System::UInt16 aUShort
= *safe_cast
<System::UInt16
^>(cli_data
);
772 *(sal_uInt16
*) uno_data
= aUShort
;
775 case typelib_TypeClass_LONG
:
777 System::Int32 aLong
= *safe_cast
<System::Int32
^>(cli_data
);
778 *(sal_Int32
*) uno_data
= aLong
;
781 case typelib_TypeClass_UNSIGNED_LONG
:
783 System::UInt32 aULong
= *safe_cast
<System::UInt32
^>(cli_data
);
784 *(sal_uInt32
*) uno_data
= aULong
;
787 case typelib_TypeClass_HYPER
:
789 System::Int64 aHyper
= *safe_cast
<System::Int64
^>(cli_data
);
790 *(sal_Int64
*) uno_data
= aHyper
;
793 case typelib_TypeClass_UNSIGNED_HYPER
:
795 System::UInt64 aLong
= *safe_cast
<System::UInt64
^>(cli_data
);
796 *(sal_uInt64
*) uno_data
= aLong
;
799 case typelib_TypeClass_FLOAT
:
801 System::Single aFloat
= *safe_cast
<System::Single
^>(cli_data
);
802 *(float*) uno_data
= aFloat
;
805 case typelib_TypeClass_DOUBLE
:
807 System::Double aDouble
= *safe_cast
<System::Double
^>(cli_data
);
808 *(double*) uno_data
= aDouble
;
811 case typelib_TypeClass_STRING
:
813 if (assign
&& *(rtl_uString
**) uno_data
)
814 rtl_uString_release(*(rtl_uString
**) uno_data
);
816 *(rtl_uString
**)uno_data
= 0;
817 if (cli_data
== nullptr)
819 rtl_uString_new((rtl_uString
**) uno_data
);
823 System::String
^s
= safe_cast
<System::String
^>(cli_data
);
824 pin_ptr
<const wchar_t> pdata
= PtrToStringChars(s
);
825 rtl_uString_newFromStr_WithLength(
826 reinterpret_cast<rtl_uString
**>(uno_data
),
827 reinterpret_cast<sal_Unicode
const *>(pdata
), s
->Length
);
831 case typelib_TypeClass_TYPE
:
833 typelib_TypeDescriptionReference
* td
= mapCliType(safe_cast
<System::Type
^>(
837 typelib_typedescriptionreference_release(
838 *(typelib_TypeDescriptionReference
**)uno_data
);
840 *(typelib_TypeDescriptionReference
**)uno_data
= td
;
843 case typelib_TypeClass_ANY
:
845 uno_Any
* pAny
= (uno_Any
*)uno_data
;
846 if (cli_data
== nullptr) // null-ref or uninitialized any maps to empty any
849 uno_any_destruct( pAny
, 0 );
850 uno_any_construct( pAny
, 0, 0, 0 );
853 uno::Any aAny
= *safe_cast
<uno::Any
^>(cli_data
);
854 css::uno::Type
value_td( mapCliType(aAny
.Type
), SAL_NO_ACQUIRE
);
857 uno_any_destruct( pAny
, 0 );
861 switch (value_td
.getTypeClass())
863 case typelib_TypeClass_VOID
:
864 pAny
->pData
= &pAny
->pReserved
;
866 case typelib_TypeClass_CHAR
:
867 pAny
->pData
= &pAny
->pReserved
;
868 *(sal_Unicode
*) &pAny
->pReserved
= *safe_cast
<System::Char
^>(aAny
.Value
);
870 case typelib_TypeClass_BOOLEAN
:
871 pAny
->pData
= &pAny
->pReserved
;
872 *(sal_Bool
*) &pAny
->pReserved
= *safe_cast
<System::Boolean
^>(aAny
.Value
);
874 case typelib_TypeClass_BYTE
:
875 pAny
->pData
= &pAny
->pReserved
;
876 *(sal_Int8
*) &pAny
->pReserved
= *safe_cast
<System::Byte
^>(aAny
.Value
);
878 case typelib_TypeClass_SHORT
:
879 pAny
->pData
= &pAny
->pReserved
;
880 *(sal_Int16
*) &pAny
->pReserved
= *safe_cast
<System::Int16
^>(aAny
.Value
);
882 case typelib_TypeClass_UNSIGNED_SHORT
:
883 pAny
->pData
= &pAny
->pReserved
;
884 *(sal_uInt16
*) &pAny
->pReserved
= *safe_cast
<System::UInt16
^>(aAny
.Value
);
886 case typelib_TypeClass_LONG
:
887 pAny
->pData
= &pAny
->pReserved
;
888 *(sal_Int32
*) &pAny
->pReserved
= *safe_cast
<System::Int32
^>(aAny
.Value
);
890 case typelib_TypeClass_UNSIGNED_LONG
:
891 pAny
->pData
= &pAny
->pReserved
;
892 *(sal_uInt32
*) &pAny
->pReserved
= *safe_cast
<System::UInt32
^>(aAny
.Value
);
894 case typelib_TypeClass_HYPER
:
895 if (sizeof (sal_Int64
) <= sizeof (void *))
897 pAny
->pData
= &pAny
->pReserved
;
898 *(sal_Int64
*) &pAny
->pReserved
= *safe_cast
<System::Int64
^>(aAny
.Value
);
902 unique_ptr
< rtl_mem
> mem( rtl_mem::allocate( sizeof (sal_Int64
) ) );
903 *(sal_Int64
*) mem
.get()= *safe_cast
<System::Int64
^>(aAny
.Value
);
904 pAny
->pData
= mem
.release();
907 case typelib_TypeClass_UNSIGNED_HYPER
:
908 if (sizeof (sal_uInt64
) <= sizeof (void *))
910 pAny
->pData
= &pAny
->pReserved
;
911 *(sal_uInt64
*) &pAny
->pReserved
= *safe_cast
<System::UInt64
^>(aAny
.Value
);
915 unique_ptr
< rtl_mem
> mem( rtl_mem::allocate( sizeof (sal_uInt64
) ) );
916 *(sal_uInt64
*) mem
.get()= *safe_cast
<System::UInt64
^>(aAny
.Value
);
917 pAny
->pData
= mem
.release();
920 case typelib_TypeClass_FLOAT
:
921 if (sizeof (float) <= sizeof (void *))
923 pAny
->pData
= &pAny
->pReserved
;
924 *(float*) &pAny
->pReserved
= *safe_cast
<System::Single
^>(aAny
.Value
);
928 unique_ptr
< rtl_mem
> mem( rtl_mem::allocate( sizeof (float) ) );
929 *(float*) mem
.get() = *safe_cast
<System::Single
^>(aAny
.Value
);
930 pAny
->pData
= mem
.release();
933 case typelib_TypeClass_DOUBLE
:
934 if (sizeof (double) <= sizeof (void *))
936 pAny
->pData
= &pAny
->pReserved
;
937 *(double*) &pAny
->pReserved
= *safe_cast
<System::Double
^>(aAny
.Value
);
941 unique_ptr
< rtl_mem
> mem( rtl_mem::allocate( sizeof (double) ) );
942 *(double*) mem
.get()= *safe_cast
<System::Double
^>(aAny
.Value
);
943 pAny
->pData
= mem
.release();
946 case typelib_TypeClass_STRING
: // anies often contain strings; copy string directly
948 pAny
->pData
= &pAny
->pReserved
;
949 OUString _s
= mapCliString(static_cast<System::String
^>(aAny
.Value
));
950 pAny
->pReserved
= _s
.pData
;
951 rtl_uString_acquire(_s
.pData
);
954 case typelib_TypeClass_TYPE
:
955 case typelib_TypeClass_ENUM
: //ToDo copy enum direct
956 case typelib_TypeClass_SEQUENCE
:
957 case typelib_TypeClass_INTERFACE
:
958 pAny
->pData
= &pAny
->pReserved
;
961 &pAny
->pReserved
, aAny
.Value
, value_td
.getTypeLibType(),
962 false /* no assign */);
964 case typelib_TypeClass_STRUCT
:
965 case typelib_TypeClass_EXCEPTION
:
967 css::uno::Type
anyType(value_td
);
968 typelib_TypeDescription
* td
= NULL
;
969 anyType
.getDescription(&td
);
970 unique_ptr
< rtl_mem
> mem(rtl_mem::allocate(td
->nSize
));
971 typelib_typedescription_release(td
);
973 mem
.get(), aAny
.Value
, value_td
.getTypeLibType(),
974 false /* no assign */);
975 pAny
->pData
= mem
.release();
980 throw BridgeRuntimeError("[map_to_uno():" + value_td
.getTypeName() + "] unsupported value type of any!");
984 catch(System::InvalidCastException
^ )
988 uno_any_construct( pAny
, 0, 0, 0 ); // restore some valid any
989 OUString str
= "[map_to_uno():Any" + value_td
.getTypeName() + "]The Any type " + value_td
.getTypeName() + " does not correspond to its value type: ";
990 if(aAny
.Value
!= nullptr)
992 css::uno::Type
td(mapCliType(aAny
.Value
->GetType()), SAL_NO_ACQUIRE
);
993 str
+= td
.getTypeName();
996 uno_any_construct( pAny
, 0, 0, 0 ); // restore some valid any
997 throw BridgeRuntimeError(str
);
999 catch (BridgeRuntimeError
& )
1002 uno_any_construct( pAny
, 0, 0, 0 ); // restore some valid any
1008 uno_any_construct( pAny
, 0, 0, 0 ); // restore some valid any
1012 pAny
->pType
= value_td
.getTypeLibType();
1013 typelib_typedescriptionreference_acquire(pAny
->pType
);
1016 case typelib_TypeClass_ENUM
:
1018 // InvalidCastException is caught at the end of this method
1019 System::Int32 aEnum
= System::Convert::ToInt32((cli_data
));
1020 *(sal_Int32
*) uno_data
= aEnum
;
1023 case typelib_TypeClass_STRUCT
:
1024 case typelib_TypeClass_EXCEPTION
:
1026 css::uno::TypeDescription
td(type
);
1027 typelib_CompoundTypeDescription
* comp_td
=
1028 (typelib_CompoundTypeDescription
*) td
.get();
1030 typelib_StructTypeDescription
* struct_td
= NULL
;
1031 if (type
->eTypeClass
== typelib_TypeClass_STRUCT
)
1032 struct_td
= (typelib_StructTypeDescription
*) td
.get();
1034 if ( ! ((typelib_TypeDescription
*) comp_td
)->bComplete
)
1035 ::typelib_typedescription_complete(
1036 (typelib_TypeDescription
**) & comp_td
);
1038 sal_Int32 nMembers
= comp_td
->nMembers
;
1039 boolean bException
= false;
1040 System::Type
^ cliType
= nullptr;
1042 cliType
= cli_data
->GetType();
1044 if (0 != comp_td
->pBaseTypeDescription
)
1048 ((typelib_TypeDescription
*)comp_td
->pBaseTypeDescription
)->pWeakRef
,
1054 OUString
usUnoException("com.sun.star.uno.Exception");
1055 for (; nPos
< nMembers
; ++nPos
)
1057 typelib_TypeDescriptionReference
* member_type
= comp_td
->ppTypeRefs
[nPos
];
1058 System::Object
^ val
= nullptr;
1059 if (cli_data
!= nullptr)
1061 sr::FieldInfo
^ aField
= cliType
->GetField(
1062 mapUnoString(comp_td
->ppMemberNames
[nPos
]));
1063 // special case for Exception.Message property
1064 // The com.sun.star.uno.Exception.Message field is mapped to the
1065 // System.Exception property. Type.GetField("Message") returns null
1066 if ( ! aField
&& usUnoException
.equals(td
.get()->pTypeName
))
1067 {// get Exception.Message property
1068 OUString
usMessageMember("Message");
1069 if (usMessageMember
.equals(comp_td
->ppMemberNames
[nPos
]))
1071 sr::PropertyInfo
^ pi
= cliType
->GetProperty(
1072 mapUnoString(comp_td
->ppMemberNames
[nPos
]));
1073 val
= pi
->GetValue(cli_data
, nullptr);
1077 throw BridgeRuntimeError("[map_to_uno(): Member: " + OUString::unacquired(&comp_td
->ppMemberNames
[nPos
]));
1082 val
= aField
->GetValue(cli_data
);
1085 void * p
= (char *) uno_data
+ comp_td
->pMemberOffsets
[ nPos
];
1086 //When using polymorphic structs then the parameterized members can be null.
1087 //Then we set a default value.
1088 bool bDefault
= (struct_td
!= NULL
1089 && struct_td
->pParameterizedTypes
!= NULL
1090 && struct_td
->pParameterizedTypes
[nPos
] == sal_True
1092 || cli_data
== nullptr;
1093 switch (member_type
->eTypeClass
)
1095 case typelib_TypeClass_CHAR
:
1097 *(sal_Unicode
*) p
= 0;
1099 *(sal_Unicode
*) p
= *safe_cast
<System::Char
^>(val
);
1101 case typelib_TypeClass_BOOLEAN
:
1103 *(sal_Bool
*) p
= sal_False
;
1105 *(sal_Bool
*) p
= *safe_cast
<System::Boolean
^>(val
);
1107 case typelib_TypeClass_BYTE
:
1111 *(sal_Int8
*) p
= *safe_cast
<System::Byte
^>(val
);
1113 case typelib_TypeClass_SHORT
:
1115 *(sal_Int16
*) p
= 0;
1117 *(sal_Int16
*) p
= *safe_cast
<System::Int16
^>(val
);
1119 case typelib_TypeClass_UNSIGNED_SHORT
:
1121 *(sal_uInt16
*) p
= 0;
1123 *(sal_uInt16
*) p
= *safe_cast
<System::UInt16
^>(val
);
1125 case typelib_TypeClass_LONG
:
1127 *(sal_Int32
*) p
= 0;
1129 *(sal_Int32
*) p
= *safe_cast
<System::Int32
^>(val
);
1131 case typelib_TypeClass_UNSIGNED_LONG
:
1133 *(sal_uInt32
*) p
= 0;
1135 *(sal_uInt32
*) p
= *safe_cast
<System::UInt32
^>(val
);
1137 case typelib_TypeClass_HYPER
:
1139 *(sal_Int64
*) p
= 0;
1141 *(sal_Int64
*) p
= *safe_cast
<System::Int64
^>(val
);
1143 case typelib_TypeClass_UNSIGNED_HYPER
:
1145 *(sal_uInt64
*) p
= 0;
1147 *(sal_uInt64
*) p
= *safe_cast
<System::UInt64
^>(val
);
1149 case typelib_TypeClass_FLOAT
:
1153 *(float*) p
= *safe_cast
<System::Single
^>(val
);
1155 case typelib_TypeClass_DOUBLE
:
1159 *(double*) p
= *safe_cast
<System::Double
^>(val
);
1162 { // ToDo enum, should be converted here
1163 map_to_uno(p
, val
, member_type
, assign
);
1169 catch (BridgeRuntimeError
& e
)
1172 OUString str
= "[map_to_uno():";
1175 str
+= mapCliString(cliType
->FullName
) + "." + OUString::unacquired(&comp_td
->ppMemberNames
[nPos
]) + " ";
1178 throw BridgeRuntimeError(str
);
1180 catch (System::InvalidCastException
^ )
1183 OUString str
= "[map_to_uno():";
1186 str
+= mapCliString(cliType
->FullName
) + "." + OUString::unacquired(&comp_td
->ppMemberNames
[nPos
]);
1188 str
+= "] Value has not the required type.";
1189 throw BridgeRuntimeError(str
);
1199 if (bException
&& !assign
) // if assign then caller cleans up
1201 // cleanup the members which we have converted so far
1202 for ( sal_Int32 nCleanup
= 0; nCleanup
< nPos
; ++nCleanup
)
1204 uno_type_destructData(
1205 uno_data
, comp_td
->ppTypeRefs
[ nCleanup
], 0 );
1207 if (0 != comp_td
->pBaseTypeDescription
)
1210 uno_data
, (typelib_TypeDescription
*)comp_td
->pBaseTypeDescription
, 0 );
1216 case typelib_TypeClass_SEQUENCE
:
1218 TypeDescr
td( type
);
1219 typelib_TypeDescriptionReference
* element_type
=
1220 ((typelib_IndirectTypeDescription
*)td
.get())->pType
;
1222 unique_ptr
< rtl_mem
> seq
;
1224 System::Array
^ ar
= nullptr;
1225 if (cli_data
!= nullptr)
1227 ar
= safe_cast
<System::Array
^>(cli_data
);
1228 sal_Int32 nElements
= ar
->GetLength(0);
1232 switch (element_type
->eTypeClass
)
1234 case typelib_TypeClass_CHAR
:
1235 seq
= seq_allocate(nElements
, sizeof (sal_Unicode
));
1236 sri::Marshal::Copy(safe_cast
<cli::array
<System::Char
>^>(cli_data
), 0,
1237 IntPtr(& ((uno_Sequence
*) seq
.get())->elements
), nElements
);
1239 case typelib_TypeClass_BOOLEAN
:
1240 seq
= seq_allocate(nElements
, sizeof (sal_Bool
));
1241 sri::Marshal::Copy(safe_cast
<cli::array
<System::Char
>^>(cli_data
), 0,
1242 IntPtr(& ((uno_Sequence
*) seq
.get())->elements
), nElements
);
1244 case typelib_TypeClass_BYTE
:
1245 seq
= seq_allocate( nElements
, sizeof (sal_Int8
) );
1246 sri::Marshal::Copy(safe_cast
<cli::array
<System::Byte
>^>(cli_data
), 0,
1247 IntPtr(& ((uno_Sequence
*) seq
.get())->elements
), nElements
);
1249 case typelib_TypeClass_SHORT
:
1250 seq
= seq_allocate(nElements
, sizeof (sal_Int16
));
1251 sri::Marshal::Copy(safe_cast
<cli::array
<System::Int16
>^>(cli_data
), 0,
1252 IntPtr(& ((uno_Sequence
*) seq
.get())->elements
), nElements
);
1254 case typelib_TypeClass_UNSIGNED_SHORT
:
1255 seq
= seq_allocate( nElements
, sizeof (sal_uInt16
) );
1256 sri::Marshal::Copy(dynamic_cast<cli::array
<System::Int16
>^>(
1257 safe_cast
<cli::array
<System::UInt16
>^>(cli_data
)), 0,
1258 IntPtr(& ((uno_Sequence
*) seq
.get())->elements
), nElements
);
1260 case typelib_TypeClass_LONG
:
1261 seq
= seq_allocate(nElements
, sizeof (sal_Int32
));
1262 sri::Marshal::Copy(safe_cast
<cli::array
<System::Int32
>^>(cli_data
), 0,
1263 IntPtr(& ((uno_Sequence
*) seq
.get())->elements
), nElements
);
1265 case typelib_TypeClass_UNSIGNED_LONG
:
1266 seq
= seq_allocate( nElements
, sizeof (sal_uInt32
) );
1267 sri::Marshal::Copy(dynamic_cast<cli::array
<System::Int32
>^>(
1268 safe_cast
<cli::array
<System::UInt32
>^>(cli_data
)), 0,
1269 IntPtr(& ((uno_Sequence
*) seq
.get())->elements
), nElements
);
1271 case typelib_TypeClass_HYPER
:
1272 seq
= seq_allocate(nElements
, sizeof (sal_Int64
));
1273 sri::Marshal::Copy(safe_cast
<cli::array
<System::Int64
>^>(cli_data
), 0,
1274 IntPtr(& ((uno_Sequence
*) seq
.get())->elements
), nElements
);
1276 case typelib_TypeClass_UNSIGNED_HYPER
:
1277 seq
= seq_allocate(nElements
, sizeof (sal_uInt64
));
1278 sri::Marshal::Copy(dynamic_cast<cli::array
<System::Int64
>^>(
1279 safe_cast
<cli::array
<System::UInt64
>^>(cli_data
)), 0,
1280 IntPtr(& ((uno_Sequence
*) seq
.get())->elements
), nElements
);
1282 case typelib_TypeClass_FLOAT
:
1283 seq
= seq_allocate(nElements
, sizeof (float));
1284 sri::Marshal::Copy(safe_cast
<cli::array
<System::Single
>^>(cli_data
), 0,
1285 IntPtr(& ((uno_Sequence
*) seq
.get())->elements
), nElements
);
1287 case typelib_TypeClass_DOUBLE
:
1288 seq
= seq_allocate(nElements
, sizeof (double));
1289 sri::Marshal::Copy(safe_cast
<cli::array
<System::Double
>^>(cli_data
), 0,
1290 IntPtr(& ((uno_Sequence
*) seq
.get())->elements
), nElements
);
1292 case typelib_TypeClass_STRING
:
1294 seq
= seq_allocate(nElements
, sizeof (rtl_uString
*));
1295 cli::array
<System::String
^>^ arStr
= safe_cast
<cli::array
<System::String
^>^>(cli_data
);
1296 for (int i
= 0; i
< nElements
; i
++)
1298 pin_ptr
<const wchar_t> pdata
= PtrToStringChars(arStr
[i
]);
1299 rtl_uString
** pStr
= & ((rtl_uString
**) &
1300 ((uno_Sequence
*) seq
.get())->elements
)[i
];
1302 rtl_uString_newFromStr_WithLength(
1304 reinterpret_cast<sal_Unicode
const *>(pdata
),
1309 case typelib_TypeClass_ENUM
:
1310 seq
= seq_allocate(nElements
, sizeof (sal_Int32
));
1311 for (int i
= 0; i
< nElements
; i
++)
1313 ((sal_Int32
*) &((uno_Sequence
*) seq
.get())->elements
)[i
]=
1314 System::Convert::ToInt32(ar
->GetValue(i
));
1317 case typelib_TypeClass_TYPE
:
1318 case typelib_TypeClass_ANY
:
1319 case typelib_TypeClass_STRUCT
:
1320 case typelib_TypeClass_EXCEPTION
:
1321 case typelib_TypeClass_SEQUENCE
:
1322 case typelib_TypeClass_INTERFACE
:
1324 TypeDescr
element_td( element_type
);
1325 seq
= seq_allocate( nElements
, element_td
.get()->nSize
);
1327 for (sal_Int32 nPos
= 0; nPos
< nElements
; ++nPos
)
1331 void * p
= ((uno_Sequence
*) seq
.get())->elements
+
1332 (nPos
* element_td
.get()->nSize
);
1333 System::Object
^ elemData
= safe_cast
<System::Array
^>(cli_data
)->GetValue(nPos
);
1335 p
, elemData
, element_td
.get()->pWeakRef
,
1336 false /* no assign */);
1341 for ( sal_Int32 nCleanPos
= 0; nCleanPos
< nPos
; ++nCleanPos
)
1344 ((uno_Sequence
*)seq
.get())->elements
+
1345 (nCleanPos
* element_td
.get()->nSize
);
1346 uno_destructData( p
, element_td
.get(), 0 );
1355 throw BridgeRuntimeError("[map_to_uno():" + OUString::unacquired( &type
->pTypeName
) +
1356 "] unsupported sequence element type: " + OUString::unacquired( &element_type
->pTypeName
));
1360 catch (BridgeRuntimeError
& e
)
1362 throw BridgeRuntimeError("[map_to_uno():" + OUString::unacquired( &type
->pTypeName
) + "] conversion failed\n " + e
.m_message
);
1364 catch (System::InvalidCastException
^ )
1367 throw BridgeRuntimeError("[map_to_uno():" + OUString::unacquired( &type
->pTypeName
) +
1368 "] could not convert sequence element type: " + OUString::unacquired( &element_type
->pTypeName
));
1378 uno_destructData( uno_data
, td
.get(), 0 );
1383 seq
= seq_allocate(0, sizeof (sal_Int32
));
1385 *(uno_Sequence
**)uno_data
= (uno_Sequence
*)seq
.release();
1388 case typelib_TypeClass_INTERFACE
:
1392 uno_Interface
* p
= *(uno_Interface
**)uno_data
;
1396 if (nullptr == cli_data
) // null-ref
1398 *(uno_Interface
**)uno_data
= 0;
1402 TypeDescr
td( type
);
1403 uno_Interface
* pUnoI
= map_cli2uno(cli_data
, td
.get());
1404 *(uno_Interface
**)uno_data
= pUnoI
;
1411 throw BridgeRuntimeError("[map_to_uno():" + OUString::unacquired( &type
->pTypeName
) + "] unsupported type!");
1415 // BridgeRuntimeError are allowed to be thrown
1416 catch (System::InvalidCastException
^ )
1419 throw BridgeRuntimeError("[map_to_uno():" + OUString::unacquired( &type
->pTypeName
) + "] could not convert type!");
1421 catch (System::NullReferenceException
^ e
)
1423 throw BridgeRuntimeError("[map_to_uno()] Illegal null reference passed!\n" + mapCliString(e
->StackTrace
));
1425 catch (BridgeRuntimeError
& )
1438 The expected target type. Currently info is provided when this method is called
1439 to convert the in/out and out parameters of a call from cli to uno. Then info
1440 is always a byref type, e.g. "System.String&". info is used for Any and Enum conversion.
1441 @param bDontCreateObj
1442 false - a new object is created which holds the mapped uno value and is assigned to
1444 true - cli_data already contains the newly constructed object. This is the case if
1445 a struct is converted then on the first call to map_to_cli the new object is created.
1446 If the struct inherits another struct then this function is called recursively while the
1447 newly created object is passed in cli_data.
1449 void Bridge::map_to_cli(
1450 System::Object
^ *cli_data
, void const * uno_data
,
1451 typelib_TypeDescriptionReference
* type
, System::Type
^ info
,
1452 bool bDontCreateObj
) const
1454 switch (type
->eTypeClass
)
1456 case typelib_TypeClass_CHAR
:
1457 *cli_data
= *(__wchar_t
const*)uno_data
;
1459 case typelib_TypeClass_BOOLEAN
:
1460 *cli_data
= (*(bool const*)uno_data
) == sal_True
;
1462 case typelib_TypeClass_BYTE
:
1463 *cli_data
= *(unsigned char const*) uno_data
;
1465 case typelib_TypeClass_SHORT
:
1466 *cli_data
= *(short const*) uno_data
;
1468 case typelib_TypeClass_UNSIGNED_SHORT
:
1469 *cli_data
= *(unsigned short const*) uno_data
;
1471 case typelib_TypeClass_LONG
:
1472 *cli_data
= *(int const*) uno_data
;
1474 case typelib_TypeClass_UNSIGNED_LONG
:
1475 *cli_data
= *(unsigned int const*) uno_data
;
1477 case typelib_TypeClass_HYPER
:
1478 *cli_data
= *(__int64
const*) uno_data
;
1480 case typelib_TypeClass_UNSIGNED_HYPER
:
1481 *cli_data
= *(unsigned __int64
const*) uno_data
;
1483 case typelib_TypeClass_FLOAT
:
1484 *cli_data
= *(float const*) uno_data
;
1486 case typelib_TypeClass_DOUBLE
:
1487 *cli_data
= *(double const*) uno_data
;
1489 case typelib_TypeClass_STRING
:
1491 rtl_uString
const* sVal
= NULL
;
1492 sVal
= *(rtl_uString
* const*) uno_data
;
1493 *cli_data
= gcnew
System::String((__wchar_t
*) sVal
->buffer
,0, sVal
->length
);
1496 case typelib_TypeClass_TYPE
:
1498 *cli_data
= mapUnoType( *(typelib_TypeDescriptionReference
* const *)uno_data
);
1501 case typelib_TypeClass_ANY
:
1503 uno_Any
const * pAny
= (uno_Any
const *)uno_data
;
1504 if (typelib_TypeClass_VOID
!= pAny
->pType
->eTypeClass
)
1506 System::Object
^ objCli
= nullptr;
1508 &objCli
, pAny
->pData
, pAny
->pType
, nullptr,
1511 uno::Any
anyVal(mapUnoType(pAny
->pType
), objCli
);
1516 *cli_data
= uno::Any::VOID
;
1520 case typelib_TypeClass_ENUM
:
1522 if (info
!= nullptr)
1524 OSL_ASSERT(info
->IsByRef
);
1525 info
= info
->GetElementType();
1526 *cli_data
= System::Enum::ToObject(info
, *(System::Int32
*) uno_data
);
1529 *cli_data
= System::Enum::ToObject(
1530 mapUnoType(type
), *(System::Int32
*) uno_data
);
1533 case typelib_TypeClass_STRUCT
:
1534 case typelib_TypeClass_EXCEPTION
:
1536 TypeDescr
td( type
);
1537 typelib_CompoundTypeDescription
* comp_td
=
1538 (typelib_CompoundTypeDescription
*) td
.get();
1539 if ( ! ((typelib_TypeDescription
*) comp_td
)->bComplete
)
1540 ::typelib_typedescription_complete(
1541 (typelib_TypeDescription
**) & comp_td
);
1545 System::Type
^ cliType
= loadCliType(td
.get()->pTypeName
);
1546 //detect if we recursively convert inherited structures
1547 //If this point is reached because of a recursive call during covering a
1548 //struct then we must not create a new object rather we use the one in
1549 // cli_data argument.
1550 System::Object
^ cliObj
;
1552 cliObj
= *cli_data
; // recursive call
1555 //Special handling for Exception conversion. We must call constructor System::Exception
1556 //to pass the message string
1557 if (ucss::uno::Exception::typeid->IsAssignableFrom(cliType
))
1559 //We need to get the Message field. Therefore we must obtain the offset from
1560 //the typedescription. The base interface of all exceptions is
1561 //com::sun::star::uno::Exception which contains the message
1562 typelib_CompoundTypeDescription
* pCTD
= comp_td
;
1563 while (pCTD
->pBaseTypeDescription
)
1564 pCTD
= pCTD
->pBaseTypeDescription
;
1567 OUString
usMessageMember("Message");
1568 for (int i
= 0; i
< pCTD
->nMembers
; i
++)
1570 if (usMessageMember
.equals(pCTD
->ppMemberNames
[i
]))
1576 OSL_ASSERT (nPos
!= -1);
1577 int offset
= pCTD
->pMemberOffsets
[nPos
];
1578 //With the offset within the exception we can get the message string
1579 System::String
^ sMessage
= mapUnoString(*(rtl_uString
**)
1580 ((char*) uno_data
+ offset
));
1581 //We need to find a constructor for the exception that takes the message string
1582 //We assume that the first argument is the message string
1583 cli::array
<sr::ConstructorInfo
^>^ arCtorInfo
= cliType
->GetConstructors();
1584 sr::ConstructorInfo
^ ctorInfo
= nullptr;
1585 int numCtors
= arCtorInfo
->Length
;
1586 //Constructor must at least have 2 params for the base
1587 //unoidl.com.sun.star.uno.Exception (String, Object);
1588 cli::array
<sr::ParameterInfo
^>^ arParamInfo
;
1589 for (int i
= 0; i
< numCtors
; i
++)
1591 arParamInfo
= arCtorInfo
[i
]->GetParameters();
1592 if (arParamInfo
->Length
< 2)
1594 ctorInfo
= arCtorInfo
[i
];
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 ((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
, 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
, 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
, 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: */