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 #pragma warning(push, 1)
26 #include "rtl/ustring.hxx"
27 #include "rtl/ustrbuf.hxx"
28 #include "uno/sequence2.h"
29 #include "typelib/typedescription.hxx"
30 #include "cli_proxy.h"
32 #include "cli_bridge.h"
34 #using <cli_uretypes.dll>
38 namespace sri
= System::Runtime::InteropServices
;
39 namespace sr
= System::Reflection
;
40 namespace st
= System::Text
;
41 namespace ucss
= unoidl::com::sun::star
;
47 System::String
^ mapUnoPolymorphicName(System::String
^ unoName
);
48 OUString
mapCliTypeName(System::String
^ typeName
);
49 System::String
^ mapCliPolymorphicName(System::String
^ unoName
);
50 System::String
^ mapPolymorphicName(System::String
^ unoName
, bool bCliToUno
);
52 inline auto_ptr
< rtl_mem
> seq_allocate( sal_Int32 nElements
, sal_Int32 nSize
)
54 auto_ptr
< rtl_mem
> seq(
55 rtl_mem::allocate( SAL_SEQUENCE_HEADER_SIZE
+ (nElements
* nSize
) ) );
56 uno_Sequence
* p
= (uno_Sequence
*)seq
.get();
58 p
->nElements
= nElements
;
62 System::Object
^ Bridge::map_uno2cli(uno_Interface
* pUnoI
, typelib_InterfaceTypeDescription
*pTD
) const
64 System::Object
^ retVal
= nullptr;
66 rtl_uString
* pOid
= 0;
67 (*m_uno_env
->getObjectIdentifier
)( m_uno_env
, &pOid
, pUnoI
);
68 OSL_ASSERT( 0 != pOid
);
69 OUString
oid(pOid
, SAL_NO_ACQUIRE
);
71 // see if the interface was already mapped
72 System::Type
^ ifaceType
= mapUnoType(reinterpret_cast<typelib_TypeDescription
*>(pTD
));
73 System::String
^ sOid
= mapUnoString(oid
.pData
);
75 System::Threading::Monitor::Enter( CliEnvHolder::g_cli_env
);
78 retVal
= CliEnvHolder::g_cli_env
->getRegisteredInterface(sOid
, ifaceType
);
81 // There is already an registered object. It can either be a proxy
82 // for the UNO object or a real cli object. In the first case we
83 // tell the proxy that it shall also represent the current UNO
84 // interface. If it already does that, then it does nothing
85 if (srr::RemotingServices::IsTransparentProxy(retVal
))
87 UnoInterfaceProxy
^ p
= static_cast<UnoInterfaceProxy
^>(
88 srr::RemotingServices::GetRealProxy(retVal
));
89 p
->addUnoInterface(pUnoI
, pTD
);
94 retVal
= UnoInterfaceProxy::create(
95 (Bridge
*) this, pUnoI
, pTD
, oid
);
100 System::Threading::Monitor::Exit( CliEnvHolder::g_cli_env
);
106 uno_Interface
* Bridge::map_cli2uno(System::Object
^ cliObj
, typelib_TypeDescription
*pTD
) const
108 uno_Interface
* retIface
= NULL
;
109 // get oid from dot net environment
110 System::String
^ ds_oid
= CliEnvHolder::g_cli_env
->getObjectIdentifier( cliObj
);
111 OUString ousOid
= mapCliString(ds_oid
);
112 // look if interface is already mapped
113 m_uno_env
->getRegisteredInterface(m_uno_env
, (void**) &retIface
, ousOid
.pData
,
114 (typelib_InterfaceTypeDescription
*) pTD
);
117 System::Threading::Monitor::Enter(Cli_environment::typeid);
120 m_uno_env
->getRegisteredInterface(m_uno_env
, (void**) &retIface
, ousOid
.pData
,
121 (typelib_InterfaceTypeDescription
*) pTD
);
124 retIface
= CliProxy::create((Bridge
*)this, cliObj
, pTD
, ousOid
);
129 System::Threading::Monitor::Exit(Cli_environment::typeid);
135 inline System::Type
^ loadCliType(rtl_uString
* unoName
)
137 return loadCliType(mapUnoTypeName(unoName
));
140 System::Type
^ loadCliType(System::String
^ unoName
)
142 System::Type
^ retVal
= nullptr;
145 //If unoName denotes a polymorphic type, e.g com.sun.star.beans.Defaulted<System.Char>
146 //then we remove the type list, otherwise the type could not be loaded.
147 bool bIsPolymorphic
= false;
149 System::String
^ loadName
= unoName
;
150 int index
= unoName
->IndexOf('<');
153 loadName
= unoName
->Substring(0, index
);
154 bIsPolymorphic
= true;
156 System::AppDomain
^ currentDomain
= System::AppDomain::CurrentDomain
;
157 array
<sr::Assembly
^>^ assems
= currentDomain
->GetAssemblies();
158 for (int i
= 0; i
< assems
->Length
; i
++)
160 retVal
= assems
[i
]->GetType(loadName
, false);
165 if (retVal
== nullptr)
167 System::String
^ msg
= gcnew
System::String("A type could not be loaded: ");
168 msg
= System::String::Concat(msg
, loadName
);
169 throw BridgeRuntimeError(mapCliString(msg
));
174 retVal
= uno::PolymorphicType::GetType(retVal
, unoName
);
177 catch( System::Exception
^ e
)
179 OUString
ouMessage(mapCliString(e
->Message
));
180 throw BridgeRuntimeError(ouMessage
);
185 System::Type
^ mapUnoType(typelib_TypeDescription
const * pTD
)
187 return mapUnoType(pTD
->pWeakRef
);
190 System::Type
^ mapUnoType(typelib_TypeDescriptionReference
const * pTD
)
192 System::Type
^ retVal
= nullptr;
193 switch (pTD
->eTypeClass
)
195 case typelib_TypeClass_VOID
:
196 retVal
= void::typeid; break;
197 case typelib_TypeClass_CHAR
:
198 retVal
= System::Char::typeid; break;
199 case typelib_TypeClass_BOOLEAN
:
200 retVal
= System::Boolean::typeid; break;
201 case typelib_TypeClass_BYTE
:
202 retVal
= System::Byte::typeid; break;
203 case typelib_TypeClass_SHORT
:
204 retVal
= System::Int16::typeid; break;
205 case typelib_TypeClass_UNSIGNED_SHORT
:
206 retVal
= System::UInt16::typeid; break;
207 case typelib_TypeClass_LONG
:
208 retVal
= System::Int32::typeid; break;
209 case typelib_TypeClass_UNSIGNED_LONG
:
210 retVal
= System::UInt32::typeid; break;
211 case typelib_TypeClass_HYPER
:
212 retVal
= System::Int64::typeid; break;
213 case typelib_TypeClass_UNSIGNED_HYPER
:
214 retVal
= System::UInt64::typeid; break;
215 case typelib_TypeClass_FLOAT
:
216 retVal
= System::Single::typeid; break;
217 case typelib_TypeClass_DOUBLE
:
218 retVal
= System::Double::typeid; break;
219 case typelib_TypeClass_STRING
:
220 retVal
= System::String::typeid; break;
221 case typelib_TypeClass_TYPE
:
222 retVal
= System::Type::typeid; break;
223 case typelib_TypeClass_ANY
:
224 retVal
= uno::Any::typeid; break;
225 case typelib_TypeClass_ENUM
:
226 case typelib_TypeClass_STRUCT
:
227 case typelib_TypeClass_EXCEPTION
:
228 retVal
= loadCliType(pTD
->pTypeName
); break;
229 case typelib_TypeClass_INTERFACE
:
231 //special handling for XInterface, since it does not exist in cli.
232 OUString
usXInterface("com.sun.star.uno.XInterface");
233 if (usXInterface
.equals(pTD
->pTypeName
))
234 retVal
= System::Object::typeid;
236 retVal
= loadCliType(pTD
->pTypeName
);
239 case typelib_TypeClass_SEQUENCE
:
241 css::uno::TypeDescription
seqType(
242 const_cast<typelib_TypeDescriptionReference
*>(pTD
));
243 typelib_TypeDescriptionReference
* pElementTDRef
=
244 reinterpret_cast<typelib_IndirectTypeDescription
*>(seqType
.get())->pType
;
245 switch (pElementTDRef
->eTypeClass
)
247 case typelib_TypeClass_CHAR
:
248 retVal
= System::Type::GetType(const_cast<System::String
^>(Constants::sArChar
)); break;
249 case typelib_TypeClass_BOOLEAN
:
250 retVal
= System::Type::GetType(const_cast<System::String
^>(Constants::sArBoolean
));
252 case typelib_TypeClass_BYTE
:
253 retVal
= System::Type::GetType(const_cast<System::String
^>(Constants::sArByte
));
255 case typelib_TypeClass_SHORT
:
256 retVal
= System::Type::GetType(const_cast<System::String
^>(Constants::sArInt16
));
258 case typelib_TypeClass_UNSIGNED_SHORT
:
259 retVal
= System::Type::GetType(const_cast<System::String
^>(Constants::sArUInt16
));
261 case typelib_TypeClass_LONG
:
262 retVal
= System::Type::GetType(const_cast<System::String
^>(Constants::sArInt32
));
264 case typelib_TypeClass_UNSIGNED_LONG
:
265 retVal
= System::Type::GetType(const_cast<System::String
^>(Constants::sArUInt32
));
267 case typelib_TypeClass_HYPER
:
268 retVal
= System::Type::GetType(const_cast<System::String
^>(Constants::sArInt64
));
270 case typelib_TypeClass_UNSIGNED_HYPER
:
271 retVal
= System::Type::GetType(const_cast<System::String
^>(Constants::sArUInt64
));
273 case typelib_TypeClass_FLOAT
:
274 retVal
= System::Type::GetType(const_cast<System::String
^>(Constants::sArSingle
));
276 case typelib_TypeClass_DOUBLE
:
277 retVal
= System::Type::GetType(const_cast<System::String
^>(Constants::sArDouble
));
279 case typelib_TypeClass_STRING
:
280 retVal
= System::Type::GetType(const_cast<System::String
^>(Constants::sArString
));
282 case typelib_TypeClass_TYPE
:
283 retVal
= System::Type::GetType(const_cast<System::String
^>(Constants::sArType
));
285 case typelib_TypeClass_ANY
:
286 case typelib_TypeClass_ENUM
:
287 case typelib_TypeClass_EXCEPTION
:
288 case typelib_TypeClass_STRUCT
:
289 case typelib_TypeClass_INTERFACE
:
290 case typelib_TypeClass_SEQUENCE
:
292 retVal
= loadCliType(pTD
->pTypeName
);
296 //All cases should be handled by the case statements above
309 /** Returns an acquired td.
311 typelib_TypeDescriptionReference
* mapCliType(System::Type
^ cliType
)
313 typelib_TypeDescriptionReference
* retVal
= NULL
;
314 if (cliType
== nullptr)
316 retVal
= * typelib_static_type_getByTypeClass(
317 typelib_TypeClass_VOID
);
318 typelib_typedescriptionreference_acquire( retVal
);
321 //check for Enum first,
322 //because otherwise case System::TypeCode::Int32 applies
325 OUString usTypeName
= mapCliTypeName(cliType
->FullName
);
326 css::uno::Type
unoType(css::uno::TypeClass_ENUM
, usTypeName
);
327 retVal
= unoType
.getTypeLibType();
328 typelib_typedescriptionreference_acquire(retVal
);
332 switch (System::Type::GetTypeCode(cliType
))
334 case System::TypeCode::Boolean
:
335 retVal
= * typelib_static_type_getByTypeClass(
336 typelib_TypeClass_BOOLEAN
);
337 typelib_typedescriptionreference_acquire( retVal
);
339 case System::TypeCode::Char
:
340 retVal
= * typelib_static_type_getByTypeClass(
341 typelib_TypeClass_CHAR
);
342 typelib_typedescriptionreference_acquire( retVal
);
344 case System::TypeCode::Byte
:
345 retVal
= * typelib_static_type_getByTypeClass(
346 typelib_TypeClass_BYTE
);
347 typelib_typedescriptionreference_acquire( retVal
);
349 case System::TypeCode::Int16
:
350 retVal
= * typelib_static_type_getByTypeClass(
351 typelib_TypeClass_SHORT
);
352 typelib_typedescriptionreference_acquire( retVal
);
354 case System::TypeCode::Int32
:
355 retVal
= * typelib_static_type_getByTypeClass(
356 typelib_TypeClass_LONG
);
357 typelib_typedescriptionreference_acquire( retVal
);
359 case System::TypeCode::Int64
:
360 retVal
= * typelib_static_type_getByTypeClass(
361 typelib_TypeClass_HYPER
);
362 typelib_typedescriptionreference_acquire( retVal
);
364 case System::TypeCode::UInt16
:
365 retVal
= * typelib_static_type_getByTypeClass(
366 typelib_TypeClass_UNSIGNED_SHORT
);
367 typelib_typedescriptionreference_acquire( retVal
);
369 case System::TypeCode::UInt32
:
370 retVal
= * typelib_static_type_getByTypeClass(
371 typelib_TypeClass_UNSIGNED_LONG
);
372 typelib_typedescriptionreference_acquire( retVal
);
374 case System::TypeCode::UInt64
:
375 retVal
= * typelib_static_type_getByTypeClass(
376 typelib_TypeClass_UNSIGNED_HYPER
);
377 typelib_typedescriptionreference_acquire( retVal
);
379 case System::TypeCode::Single
:
380 retVal
= * typelib_static_type_getByTypeClass(
381 typelib_TypeClass_FLOAT
);
382 typelib_typedescriptionreference_acquire( retVal
);
384 case System::TypeCode::Double
:
385 retVal
= * typelib_static_type_getByTypeClass(
386 typelib_TypeClass_DOUBLE
);
387 typelib_typedescriptionreference_acquire( retVal
);
389 case System::TypeCode::String
:
390 retVal
= * typelib_static_type_getByTypeClass(
391 typelib_TypeClass_STRING
);
392 typelib_typedescriptionreference_acquire( retVal
);
400 System::String
^ cliTypeName
= cliType
->FullName
;
402 if (const_cast<System::String
^>(Constants::sVoid
)->Equals(
405 retVal
= * typelib_static_type_getByTypeClass(
406 typelib_TypeClass_VOID
);
407 typelib_typedescriptionreference_acquire( retVal
);
410 else if (const_cast<System::String
^>(Constants::sType
)->Equals(
413 retVal
= * typelib_static_type_getByTypeClass(
414 typelib_TypeClass_TYPE
);
415 typelib_typedescriptionreference_acquire( retVal
);
418 else if (const_cast<System::String
^>(Constants::sAny
)->Equals(
421 retVal
= * typelib_static_type_getByTypeClass(
422 typelib_TypeClass_ANY
);
423 typelib_typedescriptionreference_acquire( retVal
);
425 //struct, interfaces, sequences
429 uno::PolymorphicType
^ poly
= dynamic_cast<uno::PolymorphicType
^>(cliType
);
431 usTypeName
= mapCliTypeName( poly
->PolymorphicName
);
433 usTypeName
= mapCliTypeName(cliTypeName
);
434 typelib_TypeDescription
* td
= NULL
;
435 typelib_typedescription_getByName(&td
, usTypeName
.pData
);
438 retVal
= td
->pWeakRef
;
439 typelib_typedescriptionreference_acquire(retVal
);
440 typelib_typedescription_release(td
);
446 OUStringBuffer
buf( 128 );
447 buf
.append( "[cli_uno bridge] mapCliType():could not map type: " );
448 buf
.append(mapCliString(cliType
->FullName
));
449 throw BridgeRuntimeError( buf
.makeStringAndClear() );
455 Otherwise a leading "unoidl." is removed.
457 System::String
^ mapUnoTypeName(rtl_uString
const * typeName
)
459 OUString
usUnoName( const_cast< rtl_uString
* >( typeName
) );
460 st::StringBuilder
^ buf
= gcnew
st::StringBuilder();
461 //determine if the type is a sequence and its dimensions
463 if (usUnoName
[0] == '[')
468 if (usUnoName
[index
++] == ']')
470 if (usUnoName
[index
++] != '[')
473 usUnoName
= usUnoName
.copy(index
- 1);
475 System::String
^ sUnoName
= mapUnoString(usUnoName
.pData
);
476 if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usBool
)))
477 buf
->Append(const_cast<System::String
^>(Constants::sBoolean
));
478 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usChar
)))
479 buf
->Append(const_cast<System::String
^>(Constants::sChar
));
480 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usByte
)))
481 buf
->Append(const_cast<System::String
^>(Constants::sByte
));
482 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usShort
)))
483 buf
->Append(const_cast<System::String
^>(Constants::sInt16
));
484 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usUShort
)))
485 buf
->Append(const_cast<System::String
^>(Constants::sUInt16
));
486 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usLong
)))
487 buf
->Append(const_cast<System::String
^>(Constants::sInt32
));
488 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usULong
)))
489 buf
->Append(const_cast<System::String
^>(Constants::sUInt32
));
490 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usHyper
)))
491 buf
->Append(const_cast<System::String
^>(Constants::sInt64
));
492 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usUHyper
)))
493 buf
->Append(const_cast<System::String
^>(Constants::sUInt64
));
494 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usFloat
)))
495 buf
->Append(const_cast<System::String
^>(Constants::sSingle
));
496 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usDouble
)))
497 buf
->Append(const_cast<System::String
^>(Constants::sDouble
));
498 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usString
)))
499 buf
->Append(const_cast<System::String
^>(Constants::sString
));
500 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usVoid
)))
501 buf
->Append(const_cast<System::String
^>(Constants::sVoid
));
502 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usType
)))
503 buf
->Append(const_cast<System::String
^>(Constants::sType
));
504 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usXInterface
)))
505 buf
->Append(const_cast<System::String
^>(Constants::sObject
));
506 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::usAny
)))
508 buf
->Append(const_cast<System::String
^>(Constants::sAny
));
512 //put "unoidl." at the beginning
513 buf
->Append(const_cast<System::String
^>(Constants::sUnoidl
));
514 //for polymorphic struct types remove the brackets, e.g mystruct<bool> -> mystruct
515 System::String
^ sName
= mapUnoPolymorphicName(sUnoName
);
520 buf
->Append(const_cast<System::String
^>(Constants::sBrackets
));
522 return buf
->ToString();
525 /** For example, there is a uno type
526 com.sun.star.Foo<char, long>.
527 The values in the type list
528 are uno types and are replaced by cli types, such as System.Char,
530 The prefix unoidl is not added.
532 inline System::String
^ mapUnoPolymorphicName(System::String
^ unoName
)
534 return mapPolymorphicName(unoName
, false);
537 /** For example, there is a type name such as
538 com.sun.star.Foo<System.Char, System.Int32>.
539 The values in the type list
540 are CLI types and are replaced by uno types, such as char,
542 The prefix unoidl remains.
544 inline System::String
^ mapCliPolymorphicName(System::String
^ unoName
)
546 return mapPolymorphicName(unoName
, true);
549 System::String
^ mapPolymorphicName(System::String
^ unoName
, bool bCliToUno
)
551 int index
= unoName
->IndexOf('<');
555 System::Text::StringBuilder
^ builder
= gcnew
System::Text::StringBuilder(256);
556 builder
->Append(unoName
->Substring(0, index
+1 ));
558 //Find the first occurrence of ','
559 //If the parameter is a polymorphic struct then we neede to ignore everything
560 //between the brackets because it can also contain commas
561 //get the type list within < and >
562 int endIndex
= unoName
->Length
- 1;
566 while (cur
<= endIndex
)
568 System::Char c
= unoName
[cur
];
569 if (c
== ',' || c
== '>')
571 //insert a comma if needed
572 if (countParams
!= 0)
573 builder
->Append(",");
575 System::String
^ sParam
= unoName
->Substring(index
, cur
- index
);
578 //the the index to the beginning of the next param
582 builder
->Append(mapCliTypeName(sParam
).getStr());
586 OUString s
= mapCliString(sParam
);
587 builder
->Append(mapUnoTypeName(s
.pData
));
593 //continue until the matching '>'
597 System::Char curChar
= unoName
[cur
];
602 else if (curChar
== '>')
614 builder
->Append((System::Char
) '>');
615 return builder
->ToString();
618 OUString
mapCliTypeName(System::String
^ typeName
)
621 // Array? determine the "rank" (number of "[]")
622 // move from the rightmost end to the left, for example
623 // unoidl.PolymorphicStruct<System.Char[]>[]
624 // has only a "dimension" of 1
625 int cur
= typeName
->Length
- 1;
626 bool bRightBracket
= false;
629 System::Char c
= typeName
[cur
];
632 bRightBracket
= true;
637 throw BridgeRuntimeError(
638 "Typename is wrong. No matching brackets for sequence. Name is: " +
639 mapCliString(typeName
));
640 bRightBracket
= false;
646 throw BridgeRuntimeError(
647 "Typename is wrong. No matching brackets for sequence. Name is: " +
648 mapCliString(typeName
));
654 if (bRightBracket
|| cur
< 0)
655 throw BridgeRuntimeError(
656 "Typename is wrong. " +
657 mapCliString(typeName
));
659 typeName
= typeName
->Substring(0, cur
+ 1);
661 System::Text::StringBuilder
^ buf
= gcnew
System::Text::StringBuilder(512);
663 //Put the "[]" at the beginning of the uno type name
665 buf
->Append(const_cast<System::String
^>(Constants::usBrackets
));
667 if (typeName
->Equals(const_cast<System::String
^>(Constants::sBoolean
)))
668 buf
->Append(const_cast<System::String
^>(Constants::usBool
));
669 else if (typeName
->Equals(const_cast<System::String
^>(Constants::sChar
)))
670 buf
->Append(const_cast<System::String
^>(Constants::usChar
));
671 else if (typeName
->Equals(const_cast<System::String
^>(Constants::sByte
)))
672 buf
->Append(const_cast<System::String
^>(Constants::usByte
));
673 else if (typeName
->Equals(const_cast<System::String
^>(Constants::sInt16
)))
674 buf
->Append(const_cast<System::String
^>(Constants::usShort
));
675 else if (typeName
->Equals(const_cast<System::String
^>(Constants::sUInt16
)))
676 buf
->Append(const_cast<System::String
^>(Constants::usUShort
));
677 else if (typeName
->Equals(const_cast<System::String
^>(Constants::sInt32
)))
678 buf
->Append(const_cast<System::String
^>(Constants::usLong
));
679 else if (typeName
->Equals(const_cast<System::String
^>(Constants::sUInt32
)))
680 buf
->Append(const_cast<System::String
^>(Constants::usULong
));
681 else if (typeName
->Equals(const_cast<System::String
^>(Constants::sInt64
)))
682 buf
->Append(const_cast<System::String
^>(Constants::usHyper
));
683 else if (typeName
->Equals(const_cast<System::String
^>(Constants::sUInt64
)))
684 buf
->Append(const_cast<System::String
^>(Constants::usUHyper
));
685 else if (typeName
->Equals(const_cast<System::String
^>(Constants::sSingle
)))
686 buf
->Append(const_cast<System::String
^>(Constants::usFloat
));
687 else if (typeName
->Equals(const_cast<System::String
^>(Constants::sDouble
)))
688 buf
->Append(const_cast<System::String
^>(Constants::usDouble
));
689 else if (typeName
->Equals(const_cast<System::String
^>(Constants::sString
)))
690 buf
->Append(const_cast<System::String
^>(Constants::usString
));
691 else if (typeName
->Equals(const_cast<System::String
^>(Constants::sVoid
)))
692 buf
->Append(const_cast<System::String
^>(Constants::usVoid
));
693 else if (typeName
->Equals(const_cast<System::String
^>(Constants::sType
)))
694 buf
->Append(const_cast<System::String
^>(Constants::usType
));
695 else if (typeName
->Equals(const_cast<System::String
^>(Constants::sObject
)))
696 buf
->Append(const_cast<System::String
^>(Constants::usXInterface
));
697 else if (typeName
->Equals(const_cast<System::String
^>(Constants::sAny
)))
698 buf
->Append(const_cast<System::String
^>(Constants::usAny
));
701 System::String
^ sName
= mapCliPolymorphicName(typeName
);
702 int i
= sName
->IndexOf(L
'.');
703 buf
->Append(sName
->Substring(i
+ 1));
705 return mapCliString(buf
->ToString());
708 /** Maps uno types to dot net types.
709 * If uno_data is null then the type description is converted to System::Type
711 inline System::String
^ mapUnoString( rtl_uString
const * data
)
714 return gcnew
System::String((__wchar_t
*) data
->buffer
, 0, data
->length
);
717 OUString
mapCliString(System::String
^ data
)
722 OSL_ASSERT(sizeof(wchar_t) == sizeof(sal_Unicode
));
723 pin_ptr
<wchar_t const> pdata
= PtrToStringChars(data
);
724 return OUString(pdata
, 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( (rtl_uString
**) uno_data
,
829 case typelib_TypeClass_TYPE
:
831 typelib_TypeDescriptionReference
* td
= mapCliType(safe_cast
<System::Type
^>(
835 typelib_typedescriptionreference_release(
836 *(typelib_TypeDescriptionReference
**)uno_data
);
838 *(typelib_TypeDescriptionReference
**)uno_data
= td
;
841 case typelib_TypeClass_ANY
:
843 uno_Any
* pAny
= (uno_Any
*)uno_data
;
844 if (cli_data
== nullptr) // null-ref or uninitialized any maps to empty any
847 uno_any_destruct( pAny
, 0 );
848 uno_any_construct( pAny
, 0, 0, 0 );
851 uno::Any aAny
= *safe_cast
<uno::Any
^>(cli_data
);
852 css::uno::Type
value_td( mapCliType(aAny
.Type
), SAL_NO_ACQUIRE
);
855 uno_any_destruct( pAny
, 0 );
859 switch (value_td
.getTypeClass())
861 case typelib_TypeClass_VOID
:
862 pAny
->pData
= &pAny
->pReserved
;
864 case typelib_TypeClass_CHAR
:
865 pAny
->pData
= &pAny
->pReserved
;
866 *(sal_Unicode
*) &pAny
->pReserved
= *safe_cast
<System::Char
^>(aAny
.Value
);
868 case typelib_TypeClass_BOOLEAN
:
869 pAny
->pData
= &pAny
->pReserved
;
870 *(sal_Bool
*) &pAny
->pReserved
= *safe_cast
<System::Boolean
^>(aAny
.Value
);
872 case typelib_TypeClass_BYTE
:
873 pAny
->pData
= &pAny
->pReserved
;
874 *(sal_Int8
*) &pAny
->pReserved
= *safe_cast
<System::Byte
^>(aAny
.Value
);
876 case typelib_TypeClass_SHORT
:
877 pAny
->pData
= &pAny
->pReserved
;
878 *(sal_Int16
*) &pAny
->pReserved
= *safe_cast
<System::Int16
^>(aAny
.Value
);
880 case typelib_TypeClass_UNSIGNED_SHORT
:
881 pAny
->pData
= &pAny
->pReserved
;
882 *(sal_uInt16
*) &pAny
->pReserved
= *safe_cast
<System::UInt16
^>(aAny
.Value
);
884 case typelib_TypeClass_LONG
:
885 pAny
->pData
= &pAny
->pReserved
;
886 *(sal_Int32
*) &pAny
->pReserved
= *safe_cast
<System::Int32
^>(aAny
.Value
);
888 case typelib_TypeClass_UNSIGNED_LONG
:
889 pAny
->pData
= &pAny
->pReserved
;
890 *(sal_uInt32
*) &pAny
->pReserved
= *safe_cast
<System::UInt32
^>(aAny
.Value
);
892 case typelib_TypeClass_HYPER
:
893 if (sizeof (sal_Int64
) <= sizeof (void *))
895 pAny
->pData
= &pAny
->pReserved
;
896 *(sal_Int64
*) &pAny
->pReserved
= *safe_cast
<System::Int64
^>(aAny
.Value
);
900 auto_ptr
< rtl_mem
> mem( rtl_mem::allocate( sizeof (sal_Int64
) ) );
901 *(sal_Int64
*) mem
.get()= *safe_cast
<System::Int64
^>(aAny
.Value
);
902 pAny
->pData
= mem
.release();
905 case typelib_TypeClass_UNSIGNED_HYPER
:
906 if (sizeof (sal_uInt64
) <= sizeof (void *))
908 pAny
->pData
= &pAny
->pReserved
;
909 *(sal_uInt64
*) &pAny
->pReserved
= *safe_cast
<System::UInt64
^>(aAny
.Value
);
913 auto_ptr
< rtl_mem
> mem( rtl_mem::allocate( sizeof (sal_uInt64
) ) );
914 *(sal_uInt64
*) mem
.get()= *safe_cast
<System::UInt64
^>(aAny
.Value
);
915 pAny
->pData
= mem
.release();
918 case typelib_TypeClass_FLOAT
:
919 if (sizeof (float) <= sizeof (void *))
921 pAny
->pData
= &pAny
->pReserved
;
922 *(float*) &pAny
->pReserved
= *safe_cast
<System::Single
^>(aAny
.Value
);
926 auto_ptr
< rtl_mem
> mem( rtl_mem::allocate( sizeof (float) ) );
927 *(float*) mem
.get() = *safe_cast
<System::Single
^>(aAny
.Value
);
928 pAny
->pData
= mem
.release();
931 case typelib_TypeClass_DOUBLE
:
932 if (sizeof (double) <= sizeof (void *))
934 pAny
->pData
= &pAny
->pReserved
;
935 *(double*) &pAny
->pReserved
= *safe_cast
<System::Double
^>(aAny
.Value
);
939 auto_ptr
< rtl_mem
> mem( rtl_mem::allocate( sizeof (double) ) );
940 *(double*) mem
.get()= *safe_cast
<System::Double
^>(aAny
.Value
);
941 pAny
->pData
= mem
.release();
944 case typelib_TypeClass_STRING
: // anies often contain strings; copy string directly
946 pAny
->pData
= &pAny
->pReserved
;
947 OUString _s
= mapCliString(static_cast<System::String
^>(aAny
.Value
));
948 pAny
->pReserved
= _s
.pData
;
949 rtl_uString_acquire(_s
.pData
);
952 case typelib_TypeClass_TYPE
:
953 case typelib_TypeClass_ENUM
: //ToDo copy enum direct
954 case typelib_TypeClass_SEQUENCE
:
955 case typelib_TypeClass_INTERFACE
:
956 pAny
->pData
= &pAny
->pReserved
;
959 &pAny
->pReserved
, aAny
.Value
, value_td
.getTypeLibType(),
960 false /* no assign */);
962 case typelib_TypeClass_STRUCT
:
963 case typelib_TypeClass_EXCEPTION
:
965 css::uno::Type
anyType(value_td
);
966 typelib_TypeDescription
* td
= NULL
;
967 anyType
.getDescription(&td
);
968 auto_ptr
< rtl_mem
> mem(rtl_mem::allocate(td
->nSize
));
969 typelib_typedescription_release(td
);
971 mem
.get(), aAny
.Value
, value_td
.getTypeLibType(),
972 false /* no assign */);
973 pAny
->pData
= mem
.release();
978 OUStringBuffer
buf( 128 );
979 buf
.append( "[map_to_uno():" );
980 buf
.append(value_td
.getTypeName());
981 buf
.append( "] unsupported value type of any!" );
982 throw BridgeRuntimeError( buf
.makeStringAndClear() );
986 catch(System::InvalidCastException
^ )
990 uno_any_construct( pAny
, 0, 0, 0 ); // restore some valid any
991 OUStringBuffer
buf( 256 );
992 buf
.append( "[map_to_uno():Any" );
993 buf
.append(value_td
.getTypeName());
994 buf
.append( "]The Any type ");
995 buf
.append(value_td
.getTypeName());
996 buf
.append( " does not correspond to its value type: " );
997 if(aAny
.Value
!= nullptr)
999 css::uno::Type
td(mapCliType(aAny
.Value
->GetType()), SAL_NO_ACQUIRE
);
1000 buf
.append(td
.getTypeName());
1003 uno_any_construct( pAny
, 0, 0, 0 ); // restore some valid any
1004 throw BridgeRuntimeError( buf
.makeStringAndClear() );
1006 catch (BridgeRuntimeError
& )
1009 uno_any_construct( pAny
, 0, 0, 0 ); // restore some valid any
1015 uno_any_construct( pAny
, 0, 0, 0 ); // restore some valid any
1019 pAny
->pType
= value_td
.getTypeLibType();
1020 typelib_typedescriptionreference_acquire(pAny
->pType
);
1023 case typelib_TypeClass_ENUM
:
1025 // InvalidCastException is caught at the end of this method
1026 System::Int32 aEnum
= System::Convert::ToInt32((cli_data
));
1027 *(sal_Int32
*) uno_data
= aEnum
;
1030 case typelib_TypeClass_STRUCT
:
1031 case typelib_TypeClass_EXCEPTION
:
1033 css::uno::TypeDescription
td(type
);
1034 typelib_CompoundTypeDescription
* comp_td
=
1035 (typelib_CompoundTypeDescription
*) td
.get();
1037 typelib_StructTypeDescription
* struct_td
= NULL
;
1038 if (type
->eTypeClass
== typelib_TypeClass_STRUCT
)
1039 struct_td
= (typelib_StructTypeDescription
*) td
.get();
1041 if ( ! ((typelib_TypeDescription
*) comp_td
)->bComplete
)
1042 ::typelib_typedescription_complete(
1043 (typelib_TypeDescription
**) & comp_td
);
1045 sal_Int32 nMembers
= comp_td
->nMembers
;
1046 boolean bException
= false;
1047 System::Type
^ cliType
= nullptr;
1049 cliType
= cli_data
->GetType();
1051 if (0 != comp_td
->pBaseTypeDescription
)
1055 ((typelib_TypeDescription
*)comp_td
->pBaseTypeDescription
)->pWeakRef
,
1061 typelib_TypeDescriptionReference
* member_type
= NULL
;
1063 OUString
usUnoException("com.sun.star.uno.Exception");
1064 for (; nPos
< nMembers
; ++nPos
)
1066 member_type
= comp_td
->ppTypeRefs
[nPos
];
1067 #if OSL_DEBUG_LEVEL >= 2
1068 System::String
* __s
;
1069 sr::FieldInfo
* arFields
[];
1070 __s
= mapUnoString(comp_td
->ppMemberNames
[nPos
]);
1071 arFields
= cliType
!= NULL
? cliType
->GetFields() : NULL
;
1073 System::Object
^ val
= nullptr;
1074 if (cli_data
!= nullptr)
1076 sr::FieldInfo
^ aField
= cliType
->GetField(
1077 mapUnoString(comp_td
->ppMemberNames
[nPos
]));
1078 // special case for Exception.Message property
1079 // The com.sun.star.uno.Exception.Message field is mapped to the
1080 // System.Exception property. Type.GetField("Message") returns null
1081 if ( ! aField
&& usUnoException
.equals(td
.get()->pTypeName
))
1082 {// get Exception.Message property
1083 OUString
usMessageMember("Message");
1084 if (usMessageMember
.equals(comp_td
->ppMemberNames
[nPos
]))
1086 sr::PropertyInfo
^ pi
= cliType
->GetProperty(
1087 mapUnoString(comp_td
->ppMemberNames
[nPos
]));
1088 val
= pi
->GetValue(cli_data
, nullptr);
1092 OUStringBuffer
buf(512);
1093 buf
.append("[map_to_uno(): Member: ");
1094 buf
.append(comp_td
->ppMemberNames
[nPos
]);
1095 throw BridgeRuntimeError(buf
.makeStringAndClear());
1100 val
= aField
->GetValue(cli_data
);
1103 void * p
= (char *) uno_data
+ comp_td
->pMemberOffsets
[ nPos
];
1104 //When using polymorphic structs then the parameterized members can be null.
1105 //Then we set a default value.
1106 bool bDefault
= ((struct_td
!= NULL
1107 && struct_td
->pParameterizedTypes
!= NULL
1108 && struct_td
->pParameterizedTypes
[nPos
] == sal_True
1110 || cli_data
== nullptr) ? true : false;
1111 switch (member_type
->eTypeClass
)
1113 case typelib_TypeClass_CHAR
:
1115 *(sal_Unicode
*) p
= 0;
1117 *(sal_Unicode
*) p
= *safe_cast
<System::Char
^>(val
);
1119 case typelib_TypeClass_BOOLEAN
:
1121 *(sal_Bool
*) p
= sal_False
;
1123 *(sal_Bool
*) p
= *safe_cast
<System::Boolean
^>(val
);
1125 case typelib_TypeClass_BYTE
:
1129 *(sal_Int8
*) p
= *safe_cast
<System::Byte
^>(val
);
1131 case typelib_TypeClass_SHORT
:
1133 *(sal_Int16
*) p
= 0;
1135 *(sal_Int16
*) p
= *safe_cast
<System::Int16
^>(val
);
1137 case typelib_TypeClass_UNSIGNED_SHORT
:
1139 *(sal_uInt16
*) p
= 0;
1141 *(sal_uInt16
*) p
= *safe_cast
<System::UInt16
^>(val
);
1143 case typelib_TypeClass_LONG
:
1145 *(sal_Int32
*) p
= 0;
1147 *(sal_Int32
*) p
= *safe_cast
<System::Int32
^>(val
);
1149 case typelib_TypeClass_UNSIGNED_LONG
:
1151 *(sal_uInt32
*) p
= 0;
1153 *(sal_uInt32
*) p
= *safe_cast
<System::UInt32
^>(val
);
1155 case typelib_TypeClass_HYPER
:
1157 *(sal_Int64
*) p
= 0;
1159 *(sal_Int64
*) p
= *safe_cast
<System::Int64
^>(val
);
1161 case typelib_TypeClass_UNSIGNED_HYPER
:
1163 *(sal_uInt64
*) p
= 0;
1165 *(sal_uInt64
*) p
= *safe_cast
<System::UInt64
^>(val
);
1167 case typelib_TypeClass_FLOAT
:
1171 *(float*) p
= *safe_cast
<System::Single
^>(val
);
1173 case typelib_TypeClass_DOUBLE
:
1177 *(double*) p
= *safe_cast
<System::Double
^>(val
);
1180 { // ToDo enum, should be converted here
1181 map_to_uno(p
, val
, member_type
, assign
);
1187 catch (BridgeRuntimeError
& e
)
1190 OUStringBuffer
buf(512);
1191 buf
.append("[map_to_uno():");
1194 buf
.append(mapCliString(cliType
->FullName
));
1196 buf
.append(comp_td
->ppMemberNames
[nPos
]);
1199 buf
.append(e
.m_message
);
1200 throw BridgeRuntimeError(buf
.makeStringAndClear());
1202 catch (System::InvalidCastException
^ )
1205 OUStringBuffer
buf( 256 );
1206 buf
.append( "[map_to_uno():" );
1209 buf
.append(mapCliString(cliType
->FullName
));
1211 buf
.append(comp_td
->ppMemberNames
[nPos
]);
1213 buf
.append( "] Value has not the required type." );
1214 throw BridgeRuntimeError(buf
.makeStringAndClear());
1224 if (bException
&& !assign
) // if assign then caller cleans up
1226 // cleanup the members which we have converted so far
1227 for ( sal_Int32 nCleanup
= 0; nCleanup
< nPos
; ++nCleanup
)
1229 uno_type_destructData(
1230 uno_data
, comp_td
->ppTypeRefs
[ nCleanup
], 0 );
1232 if (0 != comp_td
->pBaseTypeDescription
)
1235 uno_data
, (typelib_TypeDescription
*)comp_td
->pBaseTypeDescription
, 0 );
1241 case typelib_TypeClass_SEQUENCE
:
1243 TypeDescr
td( type
);
1244 typelib_TypeDescriptionReference
* element_type
=
1245 ((typelib_IndirectTypeDescription
*)td
.get())->pType
;
1247 auto_ptr
< rtl_mem
> seq
;
1249 System::Array
^ ar
= nullptr;
1250 if (cli_data
!= nullptr)
1252 ar
= safe_cast
<System::Array
^>(cli_data
);
1253 sal_Int32 nElements
= ar
->GetLength(0);
1257 switch (element_type
->eTypeClass
)
1259 case typelib_TypeClass_CHAR
:
1260 seq
= seq_allocate(nElements
, sizeof (sal_Unicode
));
1261 sri::Marshal::Copy(safe_cast
<array
<System::Char
>^>(cli_data
), 0,
1262 IntPtr(& ((uno_Sequence
*) seq
.get())->elements
), nElements
);
1264 case typelib_TypeClass_BOOLEAN
:
1265 seq
= seq_allocate(nElements
, sizeof (sal_Bool
));
1266 sri::Marshal::Copy(safe_cast
<array
<System::Char
>^>(cli_data
), 0,
1267 IntPtr(& ((uno_Sequence
*) seq
.get())->elements
), nElements
);
1269 case typelib_TypeClass_BYTE
:
1270 seq
= seq_allocate( nElements
, sizeof (sal_Int8
) );
1271 sri::Marshal::Copy(safe_cast
<array
<System::Byte
>^>(cli_data
), 0,
1272 IntPtr(& ((uno_Sequence
*) seq
.get())->elements
), nElements
);
1274 case typelib_TypeClass_SHORT
:
1275 seq
= seq_allocate(nElements
, sizeof (sal_Int16
));
1276 sri::Marshal::Copy(safe_cast
<array
<System::Int16
>^>(cli_data
), 0,
1277 IntPtr(& ((uno_Sequence
*) seq
.get())->elements
), nElements
);
1279 case typelib_TypeClass_UNSIGNED_SHORT
:
1280 seq
= seq_allocate( nElements
, sizeof (sal_uInt16
) );
1281 sri::Marshal::Copy(dynamic_cast<array
<System::Int16
>^>(
1282 safe_cast
<array
<System::UInt16
>^>(cli_data
)), 0,
1283 IntPtr(& ((uno_Sequence
*) seq
.get())->elements
), nElements
);
1285 case typelib_TypeClass_LONG
:
1286 seq
= seq_allocate(nElements
, sizeof (sal_Int32
));
1287 sri::Marshal::Copy(safe_cast
<array
<System::Int32
>^>(cli_data
), 0,
1288 IntPtr(& ((uno_Sequence
*) seq
.get())->elements
), nElements
);
1290 case typelib_TypeClass_UNSIGNED_LONG
:
1291 seq
= seq_allocate( nElements
, sizeof (sal_uInt32
) );
1292 sri::Marshal::Copy(dynamic_cast<array
<System::Int32
>^>(
1293 safe_cast
<array
<System::UInt32
>^>(cli_data
)), 0,
1294 IntPtr(& ((uno_Sequence
*) seq
.get())->elements
), nElements
);
1296 case typelib_TypeClass_HYPER
:
1297 seq
= seq_allocate(nElements
, sizeof (sal_Int64
));
1298 sri::Marshal::Copy(safe_cast
<array
<System::Int64
>^>(cli_data
), 0,
1299 IntPtr(& ((uno_Sequence
*) seq
.get())->elements
), nElements
);
1301 case typelib_TypeClass_UNSIGNED_HYPER
:
1302 seq
= seq_allocate(nElements
, sizeof (sal_uInt64
));
1303 sri::Marshal::Copy(dynamic_cast<array
<System::Int64
>^>(
1304 safe_cast
<array
<System::UInt64
>^>(cli_data
)), 0,
1305 IntPtr(& ((uno_Sequence
*) seq
.get())->elements
), nElements
);
1307 case typelib_TypeClass_FLOAT
:
1308 seq
= seq_allocate(nElements
, sizeof (float));
1309 sri::Marshal::Copy(safe_cast
<array
<System::Single
>^>(cli_data
), 0,
1310 IntPtr(& ((uno_Sequence
*) seq
.get())->elements
), nElements
);
1312 case typelib_TypeClass_DOUBLE
:
1313 seq
= seq_allocate(nElements
, sizeof (double));
1314 sri::Marshal::Copy(safe_cast
<array
<System::Double
>^>(cli_data
), 0,
1315 IntPtr(& ((uno_Sequence
*) seq
.get())->elements
), nElements
);
1317 case typelib_TypeClass_STRING
:
1319 seq
= seq_allocate(nElements
, sizeof (rtl_uString
*));
1320 array
<System::String
^>^ arStr
= safe_cast
<array
<System::String
^>^>(cli_data
);
1321 for (int i
= 0; i
< nElements
; i
++)
1323 pin_ptr
<const wchar_t> pdata
= PtrToStringChars(arStr
[i
]);
1324 rtl_uString
** pStr
= & ((rtl_uString
**) &
1325 ((uno_Sequence
*) seq
.get())->elements
)[i
];
1327 rtl_uString_newFromStr_WithLength( pStr
, pdata
,
1332 case typelib_TypeClass_ENUM
:
1333 seq
= seq_allocate(nElements
, sizeof (sal_Int32
));
1334 for (int i
= 0; i
< nElements
; i
++)
1336 ((sal_Int32
*) &((uno_Sequence
*) seq
.get())->elements
)[i
]=
1337 System::Convert::ToInt32(ar
->GetValue(i
));
1340 case typelib_TypeClass_TYPE
:
1341 case typelib_TypeClass_ANY
:
1342 case typelib_TypeClass_STRUCT
:
1343 case typelib_TypeClass_EXCEPTION
:
1344 case typelib_TypeClass_SEQUENCE
:
1345 case typelib_TypeClass_INTERFACE
:
1347 TypeDescr
element_td( element_type
);
1348 seq
= seq_allocate( nElements
, element_td
.get()->nSize
);
1350 for (sal_Int32 nPos
= 0; nPos
< nElements
; ++nPos
)
1354 void * p
= ((uno_Sequence
*) seq
.get())->elements
+
1355 (nPos
* element_td
.get()->nSize
);
1356 System::Object
^ elemData
= dynamic_cast<System::Array
^>(cli_data
)->GetValue(nPos
);
1358 p
, elemData
, element_td
.get()->pWeakRef
,
1359 false /* no assign */);
1364 for ( sal_Int32 nCleanPos
= 0; nCleanPos
< nPos
; ++nCleanPos
)
1367 ((uno_Sequence
*)seq
.get())->elements
+
1368 (nCleanPos
* element_td
.get()->nSize
);
1369 uno_destructData( p
, element_td
.get(), 0 );
1378 OUStringBuffer
buf( 128 );
1379 buf
.append( "[map_to_uno():" );
1380 buf
.append( *reinterpret_cast< OUString
const * >( &type
->pTypeName
) );
1381 buf
.append( "] unsupported sequence element type: " );
1382 buf
.append( *reinterpret_cast< OUString
const * >( &element_type
->pTypeName
) );
1383 throw BridgeRuntimeError( buf
.makeStringAndClear() );
1387 catch (BridgeRuntimeError
& e
)
1389 OUStringBuffer
buf( 128 );
1390 buf
.append( "[map_to_uno():" );
1391 buf
.append( *reinterpret_cast< OUString
const * >( &type
->pTypeName
));
1392 buf
.append( "] conversion failed\n ");
1393 buf
.append(e
.m_message
);
1394 throw BridgeRuntimeError(buf
.makeStringAndClear());
1396 catch (System::InvalidCastException
^ )
1399 OUStringBuffer
buf( 128 );
1400 buf
.append( "[map_to_uno():" );
1401 buf
.append( *reinterpret_cast< OUString
const * >( &type
->pTypeName
) );
1402 buf
.append( "] could not convert sequence element type: " );
1403 buf
.append( *reinterpret_cast< OUString
const * >( &element_type
->pTypeName
) );
1404 throw BridgeRuntimeError( buf
.makeStringAndClear() );
1414 uno_destructData( uno_data
, td
.get(), 0 );
1419 seq
= seq_allocate(0, sizeof (sal_Int32
));
1421 *(uno_Sequence
**)uno_data
= (uno_Sequence
*)seq
.release();
1424 case typelib_TypeClass_INTERFACE
:
1428 uno_Interface
* p
= *(uno_Interface
**)uno_data
;
1432 if (nullptr == cli_data
) // null-ref
1434 *(uno_Interface
**)uno_data
= 0;
1438 TypeDescr
td( type
);
1439 uno_Interface
* pUnoI
= map_cli2uno(cli_data
, td
.get());
1440 *(uno_Interface
**)uno_data
= pUnoI
;
1447 OUStringBuffer
buf( 128 );
1448 buf
.append( "[map_to_uno():" );
1449 buf
.append( *reinterpret_cast< OUString
const * >( &type
->pTypeName
) );
1450 buf
.append( "] unsupported type!" );
1451 throw BridgeRuntimeError( buf
.makeStringAndClear() );
1455 // BridgeRuntimeError are allowed to be thrown
1456 catch (System::InvalidCastException
^ )
1459 OUStringBuffer
buf( 128 );
1460 buf
.append( "[map_to_uno():" );
1461 buf
.append( *reinterpret_cast< OUString
const * >( &type
->pTypeName
) );
1462 buf
.append( "] could not convert type!" );
1463 throw BridgeRuntimeError( buf
.makeStringAndClear() );
1465 catch (System::NullReferenceException
^ e
)
1467 OUStringBuffer
buf(512);
1468 buf
.append( "[map_to_uno()] Illegal null reference passed!\n" );
1469 buf
.append(mapCliString(e
->StackTrace
));
1470 throw BridgeRuntimeError( buf
.makeStringAndClear() );
1472 catch (BridgeRuntimeError
& )
1485 The expected target type. Currently info is provdided when this method is called
1486 to convert the in/out and out parameters of a call from cli to uno. Then info
1487 is always a byref type, e.g. "System.String&". info is used for Any and Enum conversion.
1488 @param bDontCreateObj
1489 false - a new object is created which holds the mapped uno value and is assigned to
1491 true - cli_data already contains the newly constructed object. This is the case if
1492 a struct is converted then on the first call to map_to_cli the new object is created.
1493 If the struct inherits another struct then this function is called recursivly while the
1494 newly created object is passed in cli_data.
1496 void Bridge::map_to_cli(
1497 System::Object
^ *cli_data
, void const * uno_data
,
1498 typelib_TypeDescriptionReference
* type
, System::Type
^ info
,
1499 bool bDontCreateObj
) const
1501 switch (type
->eTypeClass
)
1503 case typelib_TypeClass_CHAR
:
1504 *cli_data
= *(__wchar_t
const*)uno_data
;
1506 case typelib_TypeClass_BOOLEAN
:
1507 *cli_data
= (*(bool const*)uno_data
) == sal_True
? true : false;
1509 case typelib_TypeClass_BYTE
:
1510 *cli_data
= *(unsigned char const*) uno_data
;
1512 case typelib_TypeClass_SHORT
:
1513 *cli_data
= *(short const*) uno_data
;
1515 case typelib_TypeClass_UNSIGNED_SHORT
:
1516 *cli_data
= *(unsigned short const*) uno_data
;
1518 case typelib_TypeClass_LONG
:
1519 *cli_data
= *(int const*) uno_data
;
1521 case typelib_TypeClass_UNSIGNED_LONG
:
1522 *cli_data
= *(unsigned int const*) uno_data
;
1524 case typelib_TypeClass_HYPER
:
1525 *cli_data
= *(__int64
const*) uno_data
;
1527 case typelib_TypeClass_UNSIGNED_HYPER
:
1528 *cli_data
= *(unsigned __int64
const*) uno_data
;
1530 case typelib_TypeClass_FLOAT
:
1531 *cli_data
= *(float const*) uno_data
;
1533 case typelib_TypeClass_DOUBLE
:
1534 *cli_data
= *(double const*) uno_data
;
1536 case typelib_TypeClass_STRING
:
1538 rtl_uString
const* sVal
= NULL
;
1539 sVal
= *(rtl_uString
* const*) uno_data
;
1540 *cli_data
= gcnew
System::String((__wchar_t
*) sVal
->buffer
,0, sVal
->length
);
1543 case typelib_TypeClass_TYPE
:
1545 *cli_data
= mapUnoType( *(typelib_TypeDescriptionReference
* const *)uno_data
);
1548 case typelib_TypeClass_ANY
:
1550 uno_Any
const * pAny
= (uno_Any
const *)uno_data
;
1551 if (typelib_TypeClass_VOID
!= pAny
->pType
->eTypeClass
)
1553 System::Object
^ objCli
= nullptr;
1555 &objCli
, pAny
->pData
, pAny
->pType
, nullptr,
1558 uno::Any
anyVal(mapUnoType(pAny
->pType
), objCli
);
1563 *cli_data
= uno::Any::VOID
;
1567 case typelib_TypeClass_ENUM
:
1569 if (info
!= nullptr)
1571 OSL_ASSERT(info
->IsByRef
);
1572 info
= info
->GetElementType();
1573 *cli_data
= System::Enum::ToObject(info
, *(System::Int32
*) uno_data
);
1576 *cli_data
= System::Enum::ToObject(
1577 mapUnoType(type
), *(System::Int32
*) uno_data
);
1580 case typelib_TypeClass_STRUCT
:
1581 case typelib_TypeClass_EXCEPTION
:
1583 TypeDescr
td( type
);
1584 typelib_CompoundTypeDescription
* comp_td
=
1585 (typelib_CompoundTypeDescription
*) td
.get();
1586 if ( ! ((typelib_TypeDescription
*) comp_td
)->bComplete
)
1587 ::typelib_typedescription_complete(
1588 (typelib_TypeDescription
**) & comp_td
);
1592 System::Type
^ cliType
= loadCliType(td
.get()->pTypeName
);
1593 //detect if we recursivly convert inherited structures
1594 //If this point is reached because of a recursive call during convering a
1595 //struct then we must not create a new object rather we use the one in
1596 // cli_data argument.
1597 System::Object
^ cliObj
;
1599 cliObj
= *cli_data
; // recursive call
1602 //Special handling for Exception conversion. We must call constructor System::Exception
1603 //to pass the message string
1604 if (ucss::uno::Exception::typeid->IsAssignableFrom(cliType
))
1606 //We need to get the Message field. Therefore we must obtain the offset from
1607 //the typedescription. The base interface of all exceptions is
1608 //com::sun::star::uno::Exception which contains the message
1609 typelib_CompoundTypeDescription
* pCTD
= comp_td
;
1610 while (pCTD
->pBaseTypeDescription
)
1611 pCTD
= pCTD
->pBaseTypeDescription
;
1614 OUString
usMessageMember("Message");
1615 for (int i
= 0; i
< pCTD
->nMembers
; i
++)
1617 #if OSL_DEBUG_LEVEL >= 2
1618 System::String
* sMember
;
1619 sMember
= mapUnoString(pCTD
->ppMemberNames
[i
]);
1621 if (usMessageMember
.equals(pCTD
->ppMemberNames
[i
]))
1627 OSL_ASSERT (nPos
!= -1);
1628 int offset
= pCTD
->pMemberOffsets
[nPos
];
1629 //With the offset within the exception we can get the message string
1630 System::String
^ sMessage
= mapUnoString(*(rtl_uString
**)
1631 ((char*) uno_data
+ offset
));
1632 //We need to find a constructor for the exception that takes the message string
1633 //We assume that the first argument is the message string
1634 array
<sr::ConstructorInfo
^>^ arCtorInfo
= cliType
->GetConstructors();
1635 sr::ConstructorInfo
^ ctorInfo
= nullptr;
1636 int numCtors
= arCtorInfo
->Length
;
1637 //Constructor must at least have 2 params for the base
1638 //unoidl.com.sun.star.uno.Exception (String, Object);
1639 array
<sr::ParameterInfo
^>^ arParamInfo
;
1640 for (int i
= 0; i
< numCtors
; i
++)
1642 arParamInfo
= arCtorInfo
[i
]->GetParameters();
1643 if (arParamInfo
->Length
< 2)
1645 ctorInfo
= arCtorInfo
[i
];
1648 OSL_ASSERT(arParamInfo
[0]->ParameterType
->Equals(System::String::typeid)
1649 && arParamInfo
[1]->ParameterType
->Equals(System::Object::typeid)
1650 && arParamInfo
[0]->Position
== 0
1651 && arParamInfo
[1]->Position
== 1);
1652 //Prepare parameters for constructor
1653 int numArgs
= arParamInfo
->Length
;
1654 array
<System::Object
^>^ args
= gcnew array
<System::Object
^>(numArgs
);
1655 //only initialize the first argument with the message
1657 cliObj
= ctorInfo
->Invoke(args
);
1660 cliObj
= System::Activator::CreateInstance(cliType
);
1662 sal_Int32
* pMemberOffsets
= comp_td
->pMemberOffsets
;
1664 if (comp_td
->pBaseTypeDescription
)
1666 //convert inherited struct
1667 //cliObj is passed inout (args in_param, out_param are true), hence the passed
1668 // cliObj is used by the callee instead of a newly created struct
1671 ((typelib_TypeDescription
*)comp_td
->pBaseTypeDescription
)->pWeakRef
, nullptr,
1674 OUString
usUnoException("com.sun.star.uno.Exception");
1675 for (sal_Int32 nPos
= comp_td
->nMembers
; nPos
--; )
1677 typelib_TypeDescriptionReference
* member_type
= comp_td
->ppTypeRefs
[ nPos
];
1678 System::String
^ sMemberName
= mapUnoString(comp_td
->ppMemberNames
[nPos
]);
1679 sr::FieldInfo
^ aField
= cliType
->GetField(sMemberName
);
1680 // special case for Exception.Message. The field has already been
1681 // set while constructing cli object
1682 if ( ! aField
&& usUnoException
.equals(td
.get()->pTypeName
))
1686 void const * p
= (char const *)uno_data
+ pMemberOffsets
[ nPos
];
1687 switch (member_type
->eTypeClass
)
1689 case typelib_TypeClass_CHAR
:
1690 aField
->SetValue(cliObj
, *(System::Char
*) p
);
1692 case typelib_TypeClass_BOOLEAN
:
1693 aField
->SetValue(cliObj
, *(System::Boolean
*) p
);
1695 case typelib_TypeClass_BYTE
:
1696 aField
->SetValue(cliObj
, *(System::Byte
*) p
);
1698 case typelib_TypeClass_SHORT
:
1699 aField
->SetValue(cliObj
, *(System::Int16
*) p
);
1701 case typelib_TypeClass_UNSIGNED_SHORT
:
1702 aField
->SetValue(cliObj
, *(System::UInt16
*) p
);
1704 case typelib_TypeClass_LONG
:
1705 aField
->SetValue(cliObj
, *(System::Int32
*) p
);
1707 case typelib_TypeClass_UNSIGNED_LONG
:
1708 aField
->SetValue(cliObj
, *(System::UInt32
*) p
);
1710 case typelib_TypeClass_HYPER
:
1711 aField
->SetValue(cliObj
, *(System::Int64
*) p
);
1713 case typelib_TypeClass_UNSIGNED_HYPER
:
1714 aField
->SetValue(cliObj
, *(System::UInt64
*) p
);
1716 case typelib_TypeClass_FLOAT
:
1717 aField
->SetValue(cliObj
, *(System::Single
*) p
);
1719 case typelib_TypeClass_DOUBLE
:
1720 aField
->SetValue(cliObj
, *(System::Double
*) p
);
1724 System::Object
^ cli_val
;
1726 &cli_val
, p
, member_type
, nullptr,
1728 aField
->SetValue(cliObj
, cli_val
);
1736 case typelib_TypeClass_SEQUENCE
:
1738 sal_Int32 nElements
;
1739 uno_Sequence
const * seq
= 0;
1740 seq
= *(uno_Sequence
* const *)uno_data
;
1741 nElements
= seq
->nElements
;
1743 TypeDescr
td( type
);
1744 typelib_TypeDescriptionReference
* element_type
=
1745 ((typelib_IndirectTypeDescription
*)td
.get())->pType
;
1747 switch (element_type
->eTypeClass
)
1749 case typelib_TypeClass_CHAR
:
1751 array
<System::Char
>^ arChar
= gcnew array
<System::Char
>(nElements
);
1752 sri::Marshal::Copy( IntPtr((void*) &seq
->elements
), arChar
, 0, nElements
);
1756 case typelib_TypeClass_BOOLEAN
:
1758 array
<System::Byte
>^ arBool
= gcnew array
<System::Byte
>(nElements
);
1759 sri::Marshal::Copy( IntPtr((void*) &seq
->elements
), arBool
, 0, nElements
);
1760 *cli_data
= dynamic_cast<array
<System::Boolean
>^>(arBool
);
1763 case typelib_TypeClass_BYTE
:
1765 array
<System::Byte
>^ arByte
= gcnew array
<System::Byte
>(nElements
);
1766 sri::Marshal::Copy( IntPtr((void*) &seq
->elements
), arByte
, 0, nElements
);
1770 case typelib_TypeClass_SHORT
:
1772 array
<System::Int16
>^ arShort
= gcnew array
<System::Int16
>(nElements
);
1773 sri::Marshal::Copy( IntPtr((void*) &seq
->elements
), arShort
, 0, nElements
);
1777 case typelib_TypeClass_UNSIGNED_SHORT
:
1779 array
<System::UInt16
>^ arUInt16
= gcnew array
<System::UInt16
>(nElements
);
1780 sri::Marshal::Copy( IntPtr((void*) &seq
->elements
), dynamic_cast<array
<System::Int16
>^>(arUInt16
),
1782 *cli_data
= arUInt16
;
1785 case typelib_TypeClass_LONG
:
1787 array
<System::Int32
>^ arInt32
= gcnew array
<System::Int32
>(nElements
);
1788 sri::Marshal::Copy( IntPtr((void*) &seq
->elements
), arInt32
, 0, nElements
);
1792 case typelib_TypeClass_UNSIGNED_LONG
:
1794 array
<System::UInt32
>^ arUInt32
= gcnew array
<System::UInt32
>(nElements
);
1795 sri::Marshal::Copy( IntPtr((void*) &seq
->elements
), dynamic_cast<array
<System::Int32
>^>(arUInt32
),
1797 *cli_data
= arUInt32
;
1800 case typelib_TypeClass_HYPER
:
1802 array
<System::Int64
>^ arInt64
= gcnew array
<System::Int64
>(nElements
);
1803 sri::Marshal::Copy( IntPtr((void*) &seq
->elements
), arInt64
, 0, nElements
);
1807 //FIXME: Marshal::Copy of UInt64?
1808 case typelib_TypeClass_UNSIGNED_HYPER
:
1810 array
<System::IntPtr
>^ arUInt64
= gcnew array
<System::IntPtr
>(nElements
);
1811 sri::Marshal::Copy( IntPtr((void*) &seq
->elements
), arUInt64
, 0, nElements
);
1812 *cli_data
= dynamic_cast<array
<System::UInt64
>^>(arUInt64
);
1815 case typelib_TypeClass_FLOAT
:
1817 array
<System::Single
>^ arSingle
= gcnew array
<System::Single
>(nElements
);
1818 sri::Marshal::Copy( IntPtr((void*) &seq
->elements
), arSingle
, 0, nElements
);
1819 *cli_data
= arSingle
;
1822 case typelib_TypeClass_DOUBLE
:
1824 array
<System::Double
>^ arDouble
= gcnew array
<System::Double
>(nElements
);
1825 sri::Marshal::Copy( IntPtr((void*) &seq
->elements
), arDouble
, 0, nElements
);
1826 *cli_data
= arDouble
;
1829 case typelib_TypeClass_STRING
:
1831 array
<System::String
^>^ arString
= gcnew array
<System::String
^>(nElements
);
1832 for (int i
= 0; i
< nElements
; i
++)
1834 rtl_uString
*aStr
= ((rtl_uString
**)(&seq
->elements
))[i
];
1835 arString
[i
]= gcnew
System::String( (__wchar_t
*) &aStr
->buffer
, 0, aStr
->length
);
1837 *cli_data
= arString
;
1840 case typelib_TypeClass_TYPE
:
1842 array
<System::Type
^>^ arType
= gcnew array
<System::Type
^>(nElements
);
1843 for (int i
= 0; i
< nElements
; i
++)
1846 mapUnoType( ((typelib_TypeDescriptionReference
**) seq
->elements
)[i
]);
1851 case typelib_TypeClass_ANY
:
1853 array
<uno::Any
>^ arCli
= gcnew array
<uno::Any
>(nElements
);
1854 uno_Any
const * p
= (uno_Any
const *)seq
->elements
;
1855 for (sal_Int32 nPos
= 0; nPos
< nElements
; ++nPos
)
1857 System::Object
^ cli_obj
= nullptr;
1859 &cli_obj
, &p
[ nPos
], element_type
, nullptr, false);
1860 arCli
[nPos
]= *safe_cast
<uno::Any
^>(cli_obj
);
1865 case typelib_TypeClass_ENUM
:
1868 System::Type
^ enumType
= nullptr;
1869 if (info
!= nullptr)
1871 //info is EnumType[]&, remove &
1872 OSL_ASSERT(info
->IsByRef
);
1873 enumType
= info
->GetElementType();
1874 //enumType is EnumType[], remove []
1875 enumType
= enumType
->GetElementType();
1878 enumType
= mapUnoType(element_type
);
1880 System::Array
^ arEnum
= System::Array::CreateInstance(
1881 enumType
, nElements
);
1882 for (int i
= 0; i
< nElements
; i
++)
1884 arEnum
->SetValue(System::Enum::ToObject(enumType
,
1885 ((sal_Int32
*) seq
->elements
)[i
]), i
);
1890 case typelib_TypeClass_STRUCT
:
1891 case typelib_TypeClass_EXCEPTION
:
1893 TypeDescr
element_td( element_type
);
1894 System::Array
^ ar
= System::Array::CreateInstance(
1895 mapUnoType(element_type
),nElements
);
1899 char * p
= (char *) &seq
->elements
;
1900 sal_Int32 nSize
= element_td
.get()->nSize
;
1901 for ( sal_Int32 nPos
= 0; nPos
< nElements
; ++nPos
)
1903 System::Object
^ val
;
1905 &val
, p
+ (nSize
* nPos
), element_type
, nullptr, false);
1906 ar
->SetValue(val
, nPos
);
1913 case typelib_TypeClass_SEQUENCE
:
1915 System::Array
^ar
= System::Array::CreateInstance(
1916 mapUnoType(element_type
), nElements
);
1919 TypeDescr
element_td( element_type
);
1920 uno_Sequence
** elements
= (uno_Sequence
**) seq
->elements
;
1921 for ( sal_Int32 nPos
= 0; nPos
< nElements
; ++nPos
)
1923 System::Object
^ val
;
1925 &val
, &elements
[nPos
], element_type
, nullptr, false);
1926 ar
->SetValue(val
, nPos
);
1932 case typelib_TypeClass_INTERFACE
:
1934 TypeDescr
element_td( element_type
);
1935 System::Type
^ ifaceType
= mapUnoType(element_type
);
1936 System::Array
^ ar
= System::Array::CreateInstance(ifaceType
, nElements
);
1938 char * p
= (char *)seq
->elements
;
1939 sal_Int32 nSize
= element_td
.get()->nSize
;
1940 for ( sal_Int32 nPos
= 0; nPos
< nElements
; ++nPos
)
1942 System::Object
^ val
;
1944 &val
, p
+ (nSize
* nPos
), element_type
, nullptr, false);
1946 ar
->SetValue(val
, nPos
);
1953 OUStringBuffer
buf( 128 );
1954 buf
.append( "[map_to_cli():" );
1955 buf
.append( *reinterpret_cast< OUString
const * >( &type
->pTypeName
) );
1956 buf
.append( "] unsupported element type: " );
1957 buf
.append( *reinterpret_cast< OUString
const * >( &element_type
->pTypeName
) );
1958 throw BridgeRuntimeError( buf
.makeStringAndClear() );
1963 case typelib_TypeClass_INTERFACE
:
1965 uno_Interface
* pUnoI
= *(uno_Interface
* const *)uno_data
;
1968 TypeDescr
td( type
);
1969 *cli_data
= map_uno2cli( pUnoI
, reinterpret_cast<
1970 typelib_InterfaceTypeDescription
*>(td
.get())) ;
1978 //ToDo check this exception. The String is probably crippled
1979 OUStringBuffer
buf( 128 );
1980 buf
.append( "[map_to_cli():" );
1981 buf
.append( *reinterpret_cast< OUString
const * >( &type
->pTypeName
) );
1982 buf
.append( "] unsupported type!" );
1983 throw BridgeRuntimeError( buf
.makeStringAndClear() );
1989 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */