fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / cli_ure / source / uno_bridge / cli_data.cxx
blobf8b5d4b7c348a2dcda23bbd037b7b6f1ceaca9fe
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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)
21 #include "windows.h"
22 #pragma warning(pop)
24 #include <memory>
27 #include "rtl/ustring.hxx"
28 #include "rtl/ustrbuf.hxx"
29 #include "uno/sequence2.h"
30 #include "typelib/typedescription.hxx"
31 #include "cli_proxy.h"
32 #include "cli_base.h"
33 #include "cli_bridge.h"
35 #using <cli_uretypes.dll>
38 #undef VOID
40 namespace sri = System::Runtime::InteropServices;
41 namespace sr = System::Reflection;
42 namespace st = System::Text;
43 namespace ucss = unoidl::com::sun::star;
45 using namespace std;
49 namespace cli_uno
51 System::String^ mapUnoPolymorphicName(System::String^ unoName);
52 OUString mapCliTypeName(System::String^ typeName);
53 System::String^ mapCliPolymorphicName(System::String^ unoName);
54 System::String^ mapPolymorphicName(System::String^ unoName, bool bCliToUno);
56 inline auto_ptr< rtl_mem > seq_allocate( sal_Int32 nElements, sal_Int32 nSize )
58 auto_ptr< rtl_mem > seq(
59 rtl_mem::allocate( SAL_SEQUENCE_HEADER_SIZE + (nElements * nSize) ) );
60 uno_Sequence * p = (uno_Sequence *)seq.get();
61 p->nRefCount = 1;
62 p->nElements = nElements;
63 return seq;
67 System::Object^ Bridge::map_uno2cli(uno_Interface * pUnoI, typelib_InterfaceTypeDescription *pTD) const
69 System::Object^ retVal= nullptr;
70 // get oid
71 rtl_uString * pOid = 0;
72 (*m_uno_env->getObjectIdentifier)( m_uno_env, &pOid, pUnoI );
73 OSL_ASSERT( 0 != pOid );
74 OUString oid(pOid, SAL_NO_ACQUIRE);
76 //see if the interface was already mapped
77 System::Type^ ifaceType= mapUnoType(reinterpret_cast<typelib_TypeDescription*>(pTD));
78 System::String^ sOid= mapUnoString(oid.pData);
80 System::Threading::Monitor::Enter( CliEnvHolder::g_cli_env );
81 try
83 retVal = CliEnvHolder::g_cli_env->getRegisteredInterface(sOid, ifaceType);
84 if (retVal)
86 // There is already an registered object. It can either be a proxy
87 // for the UNO object or a real cli object. In the first case we
88 // tell the proxy that it shall also represent the current UNO
89 // interface. If it already does that, then it does nothing
90 if (srr::RemotingServices::IsTransparentProxy(retVal))
92 UnoInterfaceProxy^ p = static_cast<UnoInterfaceProxy^>(
93 srr::RemotingServices::GetRealProxy(retVal));
94 p->addUnoInterface(pUnoI, pTD);
97 else
99 retVal = UnoInterfaceProxy::create(
100 (Bridge *) this, pUnoI, pTD, oid );
103 __finally
105 System::Threading::Monitor::Exit( CliEnvHolder::g_cli_env );
108 return retVal;
111 uno_Interface* Bridge::map_cli2uno(System::Object^ cliObj, typelib_TypeDescription *pTD) const
113 uno_Interface* retIface = NULL;
114 // get oid from dot net environment
115 System::String^ ds_oid = CliEnvHolder::g_cli_env->getObjectIdentifier( cliObj);
116 OUString ousOid = mapCliString(ds_oid);
117 // look if interface is already mapped
118 m_uno_env->getRegisteredInterface(m_uno_env, (void**) &retIface, ousOid.pData,
119 (typelib_InterfaceTypeDescription*) pTD);
120 if ( ! retIface)
122 System::Threading::Monitor::Enter(Cli_environment::typeid);
125 m_uno_env->getRegisteredInterface(m_uno_env, (void**) &retIface, ousOid.pData,
126 (typelib_InterfaceTypeDescription*) pTD);
127 if ( ! retIface)
129 retIface = CliProxy::create((Bridge*)this, cliObj, pTD, ousOid);
132 __finally
134 System::Threading::Monitor::Exit(Cli_environment::typeid);
137 return retIface;
140 inline System::Type^ loadCliType(rtl_uString * unoName)
142 return loadCliType(mapUnoTypeName(unoName));
145 System::Type^ loadCliType(System::String ^ unoName)
147 System::Type^ retVal= nullptr;
150 //If unoName denotes a polymorphic type, e.g com.sun.star.beans.Defaulted<System.Char>
151 //then we remove the type list, otherwise the type could not be loaded.
152 bool bIsPolymorphic = false;
154 System::String ^ loadName = unoName;
155 int index = unoName->IndexOf('<');
156 if (index != -1)
158 loadName = unoName->Substring(0, index);
159 bIsPolymorphic = true;
161 System::AppDomain^ currentDomain = System::AppDomain::CurrentDomain;
162 array<sr::Assembly^>^ assems = currentDomain->GetAssemblies();
163 for (int i = 0; i < assems->Length; i++)
165 retVal = assems[i]->GetType(loadName, false);
166 if (retVal)
167 break;
170 if (retVal == nullptr)
172 System::String ^ msg = gcnew System::String("A type could not be loaded: ");
173 msg = System::String::Concat(msg, loadName);
174 throw BridgeRuntimeError(mapCliString(msg));
177 if (bIsPolymorphic)
179 retVal = uno::PolymorphicType::GetType(retVal, unoName);
182 catch( System::Exception ^ e)
184 OUString ouMessage(mapCliString(e->Message));
185 throw BridgeRuntimeError(ouMessage);
187 return retVal;
191 System::Type^ mapUnoType(typelib_TypeDescription const * pTD)
193 return mapUnoType(pTD->pWeakRef);
196 System::Type^ mapUnoType(typelib_TypeDescriptionReference const * pTD)
198 System::Type ^ retVal = nullptr;
199 switch (pTD->eTypeClass)
201 case typelib_TypeClass_VOID:
202 retVal= void::typeid; break;
203 case typelib_TypeClass_CHAR:
204 retVal= System::Char::typeid; break;
205 case typelib_TypeClass_BOOLEAN:
206 retVal= System::Boolean::typeid; break;
207 case typelib_TypeClass_BYTE:
208 retVal= System::Byte::typeid; break;
209 case typelib_TypeClass_SHORT:
210 retVal= System::Int16::typeid; break;
211 case typelib_TypeClass_UNSIGNED_SHORT:
212 retVal= System::UInt16::typeid; break;
213 case typelib_TypeClass_LONG:
214 retVal= System::Int32::typeid; break;
215 case typelib_TypeClass_UNSIGNED_LONG:
216 retVal= System::UInt32::typeid; break;
217 case typelib_TypeClass_HYPER:
218 retVal= System::Int64::typeid; break;
219 case typelib_TypeClass_UNSIGNED_HYPER:
220 retVal= System::UInt64::typeid; break;
221 case typelib_TypeClass_FLOAT:
222 retVal= System::Single::typeid; break;
223 case typelib_TypeClass_DOUBLE:
224 retVal= System::Double::typeid; break;
225 case typelib_TypeClass_STRING:
226 retVal= System::String::typeid; break;
227 case typelib_TypeClass_TYPE:
228 retVal= System::Type::typeid; break;
229 case typelib_TypeClass_ANY:
230 retVal= uno::Any::typeid; break;
231 case typelib_TypeClass_ENUM:
232 case typelib_TypeClass_STRUCT:
233 case typelib_TypeClass_EXCEPTION:
234 retVal= loadCliType(pTD->pTypeName); break;
235 case typelib_TypeClass_INTERFACE:
237 //special handling for XInterface, since it does not exist in cli.
238 OUString usXInterface("com.sun.star.uno.XInterface");
239 if (usXInterface.equals(pTD->pTypeName))
240 retVal= System::Object::typeid;
241 else
242 retVal= loadCliType(pTD->pTypeName);
243 break;
245 case typelib_TypeClass_SEQUENCE:
247 css::uno::TypeDescription seqType(
248 const_cast<typelib_TypeDescriptionReference*>(pTD));
249 typelib_TypeDescriptionReference* pElementTDRef=
250 reinterpret_cast<typelib_IndirectTypeDescription*>(seqType.get())->pType;
251 switch (pElementTDRef->eTypeClass)
253 case typelib_TypeClass_CHAR:
254 retVal= System::Type::GetType(const_cast<System::String^>(Constants::sArChar)); break;
255 case typelib_TypeClass_BOOLEAN:
256 retVal= System::Type::GetType(const_cast<System::String^>(Constants::sArBoolean));
257 break;
258 case typelib_TypeClass_BYTE:
259 retVal= System::Type::GetType(const_cast<System::String^>(Constants::sArByte));
260 break;
261 case typelib_TypeClass_SHORT:
262 retVal= System::Type::GetType(const_cast<System::String^>(Constants::sArInt16));
263 break;
264 case typelib_TypeClass_UNSIGNED_SHORT:
265 retVal= System::Type::GetType(const_cast<System::String^>(Constants::sArUInt16));
266 break;
267 case typelib_TypeClass_LONG:
268 retVal= System::Type::GetType(const_cast<System::String^>(Constants::sArInt32));
269 break;
270 case typelib_TypeClass_UNSIGNED_LONG:
271 retVal= System::Type::GetType(const_cast<System::String^>(Constants::sArUInt32));
272 break;
273 case typelib_TypeClass_HYPER:
274 retVal= System::Type::GetType(const_cast<System::String^>(Constants::sArInt64));
275 break;
276 case typelib_TypeClass_UNSIGNED_HYPER:
277 retVal= System::Type::GetType(const_cast<System::String^>(Constants::sArUInt64));
278 break;
279 case typelib_TypeClass_FLOAT:
280 retVal= System::Type::GetType(const_cast<System::String^>(Constants::sArSingle));
281 break;
282 case typelib_TypeClass_DOUBLE:
283 retVal= System::Type::GetType(const_cast<System::String^>(Constants::sArDouble));
284 break;
285 case typelib_TypeClass_STRING:
286 retVal= System::Type::GetType(const_cast<System::String^>(Constants::sArString));
287 break;
288 case typelib_TypeClass_TYPE:
289 retVal= System::Type::GetType(const_cast<System::String^>(Constants::sArType));
290 break;
291 case typelib_TypeClass_ANY:
292 case typelib_TypeClass_ENUM:
293 case typelib_TypeClass_EXCEPTION:
294 case typelib_TypeClass_STRUCT:
295 case typelib_TypeClass_INTERFACE:
296 case typelib_TypeClass_SEQUENCE:
298 retVal= loadCliType(pTD->pTypeName);
299 break;
301 default:
302 //All cases should be handled by the case statements above
303 OSL_ASSERT(0);
304 break;
306 break;
308 default:
309 OSL_ASSERT(false);
310 break;
312 return retVal;
315 /** Returns an acquired td.
317 typelib_TypeDescriptionReference* mapCliType(System::Type^ cliType)
319 typelib_TypeDescriptionReference* retVal= NULL;
320 if (cliType == nullptr)
322 retVal = * typelib_static_type_getByTypeClass(
323 typelib_TypeClass_VOID );
324 typelib_typedescriptionreference_acquire( retVal );
325 return retVal;
327 //check for Enum first,
328 //because otherwise case System::TypeCode::Int32 applies
329 if (cliType->IsEnum)
331 OUString usTypeName= mapCliTypeName(cliType->FullName);
332 css::uno::Type unoType(css::uno::TypeClass_ENUM, usTypeName);
333 retVal= unoType.getTypeLibType();
334 typelib_typedescriptionreference_acquire(retVal);
336 else
338 switch (System::Type::GetTypeCode(cliType))
340 case System::TypeCode::Boolean:
341 retVal = * typelib_static_type_getByTypeClass(
342 typelib_TypeClass_BOOLEAN );
343 typelib_typedescriptionreference_acquire( retVal );
344 break;
345 case System::TypeCode::Char:
346 retVal = * typelib_static_type_getByTypeClass(
347 typelib_TypeClass_CHAR );
348 typelib_typedescriptionreference_acquire( retVal );
349 break;
350 case System::TypeCode::Byte:
351 retVal = * typelib_static_type_getByTypeClass(
352 typelib_TypeClass_BYTE );
353 typelib_typedescriptionreference_acquire( retVal );
354 break;
355 case System::TypeCode::Int16:
356 retVal = * typelib_static_type_getByTypeClass(
357 typelib_TypeClass_SHORT );
358 typelib_typedescriptionreference_acquire( retVal );
359 break;
360 case System::TypeCode::Int32:
361 retVal = * typelib_static_type_getByTypeClass(
362 typelib_TypeClass_LONG );
363 typelib_typedescriptionreference_acquire( retVal );
364 break;
365 case System::TypeCode::Int64:
366 retVal = * typelib_static_type_getByTypeClass(
367 typelib_TypeClass_HYPER );
368 typelib_typedescriptionreference_acquire( retVal );
369 break;
370 case System::TypeCode::UInt16:
371 retVal = * typelib_static_type_getByTypeClass(
372 typelib_TypeClass_UNSIGNED_SHORT );
373 typelib_typedescriptionreference_acquire( retVal );
374 break;
375 case System::TypeCode::UInt32:
376 retVal = * typelib_static_type_getByTypeClass(
377 typelib_TypeClass_UNSIGNED_LONG );
378 typelib_typedescriptionreference_acquire( retVal );
379 break;
380 case System::TypeCode::UInt64:
381 retVal = * typelib_static_type_getByTypeClass(
382 typelib_TypeClass_UNSIGNED_HYPER );
383 typelib_typedescriptionreference_acquire( retVal );
384 break;
385 case System::TypeCode::Single:
386 retVal = * typelib_static_type_getByTypeClass(
387 typelib_TypeClass_FLOAT );
388 typelib_typedescriptionreference_acquire( retVal );
389 break;
390 case System::TypeCode::Double:
391 retVal = * typelib_static_type_getByTypeClass(
392 typelib_TypeClass_DOUBLE );
393 typelib_typedescriptionreference_acquire( retVal );
394 break;
395 case System::TypeCode::String:
396 retVal = * typelib_static_type_getByTypeClass(
397 typelib_TypeClass_STRING );
398 typelib_typedescriptionreference_acquire( retVal );
399 break;
400 default:
401 break;
404 if (retVal == NULL)
406 System::String^ cliTypeName= cliType->FullName;
407 // Void
408 if (const_cast<System::String^>(Constants::sVoid)->Equals(
409 cliTypeName))
411 retVal = * typelib_static_type_getByTypeClass(
412 typelib_TypeClass_VOID );
413 typelib_typedescriptionreference_acquire( retVal );
415 // Type
416 else if (const_cast<System::String^>(Constants::sType)->Equals(
417 cliTypeName))
419 retVal = * typelib_static_type_getByTypeClass(
420 typelib_TypeClass_TYPE );
421 typelib_typedescriptionreference_acquire( retVal );
423 // Any
424 else if (const_cast<System::String^>(Constants::sAny)->Equals(
425 cliTypeName))
427 retVal = * typelib_static_type_getByTypeClass(
428 typelib_TypeClass_ANY );
429 typelib_typedescriptionreference_acquire( retVal );
431 //struct, interfaces, sequences
432 else
434 OUString usTypeName;
435 uno::PolymorphicType ^ poly = dynamic_cast<uno::PolymorphicType^>(cliType);
436 if (poly != nullptr)
437 usTypeName = mapCliTypeName( poly->PolymorphicName);
438 else
439 usTypeName = mapCliTypeName(cliTypeName);
440 typelib_TypeDescription* td = NULL;
441 typelib_typedescription_getByName(&td, usTypeName.pData);
442 if (td)
444 retVal = td->pWeakRef;
445 typelib_typedescriptionreference_acquire(retVal);
446 typelib_typedescription_release(td);
450 if (retVal == NULL)
452 OUStringBuffer buf( 128 );
453 buf.appendAscii(
454 RTL_CONSTASCII_STRINGPARAM("[cli_uno bridge] mapCliType():"
455 "could not map type: ") );
456 buf.append(mapCliString(cliType->FullName));
457 throw BridgeRuntimeError( buf.makeStringAndClear() );
459 return retVal;
463 Otherwise a leading "unoidl." is removed.
465 System::String^ mapUnoTypeName(rtl_uString const * typeName)
467 OUString usUnoName( const_cast< rtl_uString * >( typeName ) );
468 st::StringBuilder^ buf= gcnew st::StringBuilder();
469 //determine if the type is a sequence and its dimensions
470 int dims= 0;
471 if (usUnoName[0] == '[')
473 sal_Int32 index= 1;
474 while (true)
476 if (usUnoName[index++] == ']')
477 dims++;
478 if (usUnoName[index++] != '[')
479 break;
481 usUnoName = usUnoName.copy(index - 1);
483 System::String ^ sUnoName = mapUnoString(usUnoName.pData);
484 if (sUnoName->Equals(const_cast<System::String^>(Constants::usBool)))
485 buf->Append(const_cast<System::String^>(Constants::sBoolean));
486 else if (sUnoName->Equals(const_cast<System::String^>(Constants::usChar)))
487 buf->Append(const_cast<System::String^>(Constants::sChar));
488 else if (sUnoName->Equals(const_cast<System::String^>(Constants::usByte)))
489 buf->Append(const_cast<System::String^>(Constants::sByte));
490 else if (sUnoName->Equals(const_cast<System::String^>(Constants::usShort)))
491 buf->Append(const_cast<System::String^>(Constants::sInt16));
492 else if (sUnoName->Equals(const_cast<System::String^>(Constants::usUShort)))
493 buf->Append(const_cast<System::String^>(Constants::sUInt16));
494 else if (sUnoName->Equals(const_cast<System::String^>(Constants::usLong)))
495 buf->Append(const_cast<System::String^>(Constants::sInt32));
496 else if (sUnoName->Equals(const_cast<System::String^>(Constants::usULong)))
497 buf->Append(const_cast<System::String^>(Constants::sUInt32));
498 else if (sUnoName->Equals(const_cast<System::String^>(Constants::usHyper)))
499 buf->Append(const_cast<System::String^>(Constants::sInt64));
500 else if (sUnoName->Equals(const_cast<System::String^>(Constants::usUHyper)))
501 buf->Append(const_cast<System::String^>(Constants::sUInt64));
502 else if (sUnoName->Equals(const_cast<System::String^>(Constants::usFloat)))
503 buf->Append(const_cast<System::String^>(Constants::sSingle));
504 else if (sUnoName->Equals(const_cast<System::String^>(Constants::usDouble)))
505 buf->Append(const_cast<System::String^>(Constants::sDouble));
506 else if (sUnoName->Equals(const_cast<System::String^>(Constants::usString)))
507 buf->Append(const_cast<System::String^>(Constants::sString));
508 else if (sUnoName->Equals(const_cast<System::String^>(Constants::usVoid)))
509 buf->Append(const_cast<System::String^>(Constants::sVoid));
510 else if (sUnoName->Equals(const_cast<System::String^>(Constants::usType)))
511 buf->Append(const_cast<System::String^>(Constants::sType));
512 else if (sUnoName->Equals(const_cast<System::String^>(Constants::usXInterface)))
513 buf->Append(const_cast<System::String^>(Constants::sObject));
514 else if (sUnoName->Equals(const_cast<System::String^>(Constants::usAny)))
516 buf->Append(const_cast<System::String^>(Constants::sAny));
518 else
520 //put "unoidl." at the beginning
521 buf->Append(const_cast<System::String^>(Constants::sUnoidl));
522 //for polymorphic struct types remove the brackets, e.g mystruct<bool> -> mystruct
523 System::String ^ sName = mapUnoPolymorphicName(sUnoName);
524 buf->Append(sName);
526 // apend []
527 for (;dims--;)
528 buf->Append(const_cast<System::String^>(Constants::sBrackets));
530 return buf->ToString();
536 /** For example, there is a uno type
537 com.sun.star.Foo<char, long>.
538 The values in the type list
539 are uno types and are replaced by cli types, such as System.Char,
540 System.Int32, etc.
541 The präfix unoidl is not added.
543 inline System::String^ mapUnoPolymorphicName(System::String^ unoName)
545 return mapPolymorphicName(unoName, false);
547 /** For example, there is a type name such as
548 com.sun.star.Foo<System.Char, System.Int32>.
549 The values in the type list
550 are CLI types and are replaced by uno types, such as char,
551 long, etc.
552 The präfix unoidl remains.
554 inline System::String^ mapCliPolymorphicName(System::String^ unoName)
556 return mapPolymorphicName(unoName, true);
559 System::String^ mapPolymorphicName(System::String^ unoName, bool bCliToUno)
561 int index = unoName->IndexOf('<');
562 if (index == -1)
563 return unoName;
565 System::Text::StringBuilder ^ builder = gcnew System::Text::StringBuilder(256);
566 builder->Append(unoName->Substring(0, index +1 ));
568 //Find the first occurrence of ','
569 //If the parameter is a polymorphic struct then we neede to ignore everything
570 //between the brackets because it can also contain commas
571 //get the type list within < and >
572 int endIndex = unoName->Length - 1;
573 index++;
574 int cur = index;
575 int countParams = 0;
576 while (cur <= endIndex)
578 System::Char c = unoName[cur];
579 if (c == ',' || c == '>')
581 //insert a comma if needed
582 if (countParams != 0)
583 builder->Append(",");
584 countParams++;
585 System::String ^ sParam = unoName->Substring(index, cur - index);
586 //skip the comma
587 cur++;
588 //the the index to the beginning of the next param
589 index = cur;
590 if (bCliToUno)
592 builder->Append(mapCliTypeName(sParam).getStr());
594 else
596 OUString s = mapCliString(sParam);
597 builder->Append(mapUnoTypeName(s.pData));
600 else if (c == '<')
602 cur++;
603 //continue until the matching '>'
604 int numNested = 0;
605 for (;;cur++)
607 System::Char curChar = unoName[cur];
608 if (curChar == '<')
610 numNested ++;
612 else if (curChar == '>')
614 if (numNested > 0)
615 numNested--;
616 else
617 break;
621 cur++;
624 builder->Append((System::Char) '>');
625 return builder->ToString();
628 OUString mapCliTypeName(System::String^ typeName)
630 int dims= 0;
631 // Array? determine the "rank" (number of "[]")
632 // move from the rightmost end to the left, for example
633 // unoidl.PolymorphicStruct<System.Char[]>[]
634 // has only a "dimension" of 1
635 int cur = typeName->Length - 1;
636 bool bRightBracket = false;
637 while (cur >= 0)
639 System::Char c = typeName[cur];
640 if (c == ']')
642 bRightBracket = true;
644 else if (c == '[')
646 if (!bRightBracket)
647 throw BridgeRuntimeError(
648 "Typename is wrong. No matching brackets for sequence. Name is: " +
649 mapCliString(typeName));
650 bRightBracket = false;
651 dims ++;
653 else
655 if (bRightBracket)
656 throw BridgeRuntimeError(
657 "Typename is wrong. No matching brackets for sequence. Name is: " +
658 mapCliString(typeName));
659 break;
661 cur--;
664 if (bRightBracket || cur < 0)
665 throw BridgeRuntimeError(
666 "Typename is wrong. " +
667 mapCliString(typeName));
669 typeName = typeName->Substring(0, cur + 1);
671 System::Text::StringBuilder ^ buf = gcnew System::Text::StringBuilder(512);
673 //Put the "[]" at the beginning of the uno type name
674 for (;dims--;)
675 buf->Append(const_cast<System::String^>(Constants::usBrackets));
677 if (typeName->Equals(const_cast<System::String^>(Constants::sBoolean)))
678 buf->Append(const_cast<System::String^>(Constants::usBool));
679 else if (typeName->Equals(const_cast<System::String^>(Constants::sChar)))
680 buf->Append(const_cast<System::String^>(Constants::usChar));
681 else if (typeName->Equals(const_cast<System::String^>(Constants::sByte)))
682 buf->Append(const_cast<System::String^>(Constants::usByte));
683 else if (typeName->Equals(const_cast<System::String^>(Constants::sInt16)))
684 buf->Append(const_cast<System::String^>(Constants::usShort));
685 else if (typeName->Equals(const_cast<System::String^>(Constants::sUInt16)))
686 buf->Append(const_cast<System::String^>(Constants::usUShort));
687 else if (typeName->Equals(const_cast<System::String^>(Constants::sInt32)))
688 buf->Append(const_cast<System::String^>(Constants::usLong));
689 else if (typeName->Equals(const_cast<System::String^>(Constants::sUInt32)))
690 buf->Append(const_cast<System::String^>(Constants::usULong));
691 else if (typeName->Equals(const_cast<System::String^>(Constants::sInt64)))
692 buf->Append(const_cast<System::String^>(Constants::usHyper));
693 else if (typeName->Equals(const_cast<System::String^>(Constants::sUInt64)))
694 buf->Append(const_cast<System::String^>(Constants::usUHyper));
695 else if (typeName->Equals(const_cast<System::String^>(Constants::sSingle)))
696 buf->Append(const_cast<System::String^>(Constants::usFloat));
697 else if (typeName->Equals(const_cast<System::String^>(Constants::sDouble)))
698 buf->Append(const_cast<System::String^>(Constants::usDouble));
699 else if (typeName->Equals(const_cast<System::String^>(Constants::sString)))
700 buf->Append(const_cast<System::String^>(Constants::usString));
701 else if (typeName->Equals(const_cast<System::String^>(Constants::sVoid)))
702 buf->Append(const_cast<System::String^>(Constants::usVoid));
703 else if (typeName->Equals(const_cast<System::String^>(Constants::sType)))
704 buf->Append(const_cast<System::String^>(Constants::usType));
705 else if (typeName->Equals(const_cast<System::String^>(Constants::sObject)))
706 buf->Append(const_cast<System::String^>(Constants::usXInterface));
707 else if (typeName->Equals(const_cast<System::String^>(Constants::sAny)))
708 buf->Append(const_cast<System::String^>(Constants::usAny));
709 else
711 System::String ^ sName = mapCliPolymorphicName(typeName);
712 int i= sName->IndexOf(L'.');
713 buf->Append(sName->Substring(i + 1));
715 return mapCliString(buf->ToString());
717 /** Maps uno types to dot net types.
718 * If uno_data is null then the type description is converted to System::Type
720 inline System::String^ mapUnoString( rtl_uString const * data)
722 OSL_ASSERT(data);
723 return gcnew System::String((__wchar_t*) data->buffer, 0, data->length);
726 OUString mapCliString(System::String ^ data)
729 if (data != nullptr)
731 OSL_ASSERT(sizeof(wchar_t) == sizeof(sal_Unicode));
732 pin_ptr<wchar_t const> pdata= PtrToStringChars(data);
733 return OUString(pdata, const_cast<System::String^>(data)->Length);
735 else
737 return OUString();
741 // ToDo convert cli types to expected types, e.g a long to a short where the uno type
742 // is a sal_Int16. This could be necessary if a scripting language (typeless) is used
743 // @param assign the uno_data has to be destructed (in/out args)
744 void Bridge::map_to_uno(void * uno_data, System::Object^ cli_data,
745 typelib_TypeDescriptionReference * type,
746 bool assign) const
748 try{
749 switch (type->eTypeClass)
751 case typelib_TypeClass_VOID:
752 break;
753 case typelib_TypeClass_CHAR:
755 System::Char aChar= *safe_cast<System::Char^>(cli_data);
756 *(sal_Unicode*) uno_data= aChar;
757 break;
759 case typelib_TypeClass_BOOLEAN:
761 System::Boolean aBool= *safe_cast<System::Boolean^>(cli_data);
762 *(sal_Bool*)uno_data= aBool == true ? sal_True : sal_False;
763 break;
765 case typelib_TypeClass_BYTE:
767 System::Byte aByte= *safe_cast<System::Byte^>(cli_data);
768 *(sal_Int8*) uno_data= aByte;
769 break;
771 case typelib_TypeClass_SHORT:
773 System::Int16 aShort= *safe_cast<System::Int16^>(cli_data);
774 *(sal_Int16*) uno_data= aShort;
775 break;
777 case typelib_TypeClass_UNSIGNED_SHORT:
779 System::UInt16 aUShort= *safe_cast<System::UInt16^>(cli_data);
780 *(sal_uInt16*) uno_data= aUShort;
781 break;
783 case typelib_TypeClass_LONG:
785 System::Int32 aLong= *safe_cast<System::Int32^>(cli_data);
786 *(sal_Int32*) uno_data= aLong;
787 break;
789 case typelib_TypeClass_UNSIGNED_LONG:
791 System::UInt32 aULong= *safe_cast<System::UInt32^>(cli_data);
792 *(sal_uInt32*) uno_data= aULong;
793 break;
795 case typelib_TypeClass_HYPER:
797 System::Int64 aHyper= *safe_cast<System::Int64^>(cli_data);
798 *(sal_Int64*) uno_data= aHyper;
799 break;
801 case typelib_TypeClass_UNSIGNED_HYPER:
803 System::UInt64 aLong= *safe_cast<System::UInt64^>(cli_data);
804 *(sal_uInt64*) uno_data= aLong;
805 break;
807 case typelib_TypeClass_FLOAT:
809 System::Single aFloat= *safe_cast<System::Single^>(cli_data);
810 *(float*) uno_data= aFloat;
811 break;
813 case typelib_TypeClass_DOUBLE:
815 System::Double aDouble= *safe_cast<System::Double^>(cli_data);
816 *(double*) uno_data= aDouble;
817 break;
819 case typelib_TypeClass_STRING:
821 if (assign && *(rtl_uString**) uno_data)
822 rtl_uString_release(*(rtl_uString**) uno_data);
824 *(rtl_uString **)uno_data = 0;
825 if (cli_data == nullptr)
827 rtl_uString_new((rtl_uString**) uno_data);
829 else
831 System::String ^s= safe_cast<System::String^>(cli_data);
832 pin_ptr<const wchar_t> pdata= PtrToStringChars(s);
833 rtl_uString_newFromStr_WithLength( (rtl_uString**) uno_data,
834 pdata, s->Length );
836 break;
838 case typelib_TypeClass_TYPE:
840 typelib_TypeDescriptionReference* td= mapCliType(safe_cast<System::Type^>(
841 cli_data));
842 if (assign)
844 typelib_typedescriptionreference_release(
845 *(typelib_TypeDescriptionReference **)uno_data );
847 *(typelib_TypeDescriptionReference **)uno_data = td;
848 break;
850 case typelib_TypeClass_ANY:
852 uno_Any * pAny = (uno_Any *)uno_data;
853 if (cli_data == nullptr) // null-ref or uninitialized any maps to empty any
855 if (assign)
856 uno_any_destruct( pAny, 0 );
857 uno_any_construct( pAny, 0, 0, 0 );
858 break;
860 uno::Any aAny= *safe_cast<uno::Any^>(cli_data);
861 css::uno::Type value_td( mapCliType(aAny.Type), SAL_NO_ACQUIRE);
863 if (assign)
864 uno_any_destruct( pAny, 0 );
868 switch (value_td.getTypeClass())
870 case typelib_TypeClass_VOID:
871 pAny->pData = &pAny->pReserved;
872 break;
873 case typelib_TypeClass_CHAR:
874 pAny->pData = &pAny->pReserved;
875 *(sal_Unicode*) &pAny->pReserved = *safe_cast<System::Char^>(aAny.Value);
876 break;
877 case typelib_TypeClass_BOOLEAN:
878 pAny->pData = &pAny->pReserved;
879 *(sal_Bool *) &pAny->pReserved = *safe_cast<System::Boolean^>(aAny.Value);
880 break;
881 case typelib_TypeClass_BYTE:
882 pAny->pData = &pAny->pReserved;
883 *(sal_Int8*) &pAny->pReserved = *safe_cast<System::Byte^>(aAny.Value);
884 break;
885 case typelib_TypeClass_SHORT:
886 pAny->pData = &pAny->pReserved;
887 *(sal_Int16*) &pAny->pReserved = *safe_cast<System::Int16^>(aAny.Value);
888 break;
889 case typelib_TypeClass_UNSIGNED_SHORT:
890 pAny->pData = &pAny->pReserved;
891 *(sal_uInt16*) &pAny->pReserved = *safe_cast<System::UInt16^>(aAny.Value);
892 break;
893 case typelib_TypeClass_LONG:
894 pAny->pData = &pAny->pReserved;
895 *(sal_Int32*) &pAny->pReserved = *safe_cast<System::Int32^>(aAny.Value);
896 break;
897 case typelib_TypeClass_UNSIGNED_LONG:
898 pAny->pData = &pAny->pReserved;
899 *(sal_uInt32*) &pAny->pReserved = *safe_cast<System::UInt32^>(aAny.Value);
900 break;
901 case typelib_TypeClass_HYPER:
902 if (sizeof (sal_Int64) <= sizeof (void *))
904 pAny->pData = &pAny->pReserved;
905 *(sal_Int64*) &pAny->pReserved = *safe_cast<System::Int64^>(aAny.Value);
907 else
909 auto_ptr< rtl_mem > mem( rtl_mem::allocate( sizeof (sal_Int64) ) );
910 *(sal_Int64 *) mem.get()= *safe_cast<System::Int64^>(aAny.Value);
911 pAny->pData = mem.release();
913 break;
914 case typelib_TypeClass_UNSIGNED_HYPER:
915 if (sizeof (sal_uInt64) <= sizeof (void *))
917 pAny->pData = &pAny->pReserved;
918 *(sal_uInt64*) &pAny->pReserved = *safe_cast<System::UInt64^>(aAny.Value);
920 else
922 auto_ptr< rtl_mem > mem( rtl_mem::allocate( sizeof (sal_uInt64) ) );
923 *(sal_uInt64 *) mem.get()= *safe_cast<System::UInt64^>(aAny.Value);
924 pAny->pData = mem.release();
926 break;
927 case typelib_TypeClass_FLOAT:
928 if (sizeof (float) <= sizeof (void *))
930 pAny->pData = &pAny->pReserved;
931 *(float*) &pAny->pReserved = *safe_cast<System::Single^>(aAny.Value);
933 else
935 auto_ptr< rtl_mem > mem( rtl_mem::allocate( sizeof (float) ) );
936 *(float*) mem.get() = *safe_cast<System::Single^>(aAny.Value);
937 pAny->pData = mem.release();
939 break;
940 case typelib_TypeClass_DOUBLE:
941 if (sizeof (double) <= sizeof (void *))
943 pAny->pData = &pAny->pReserved;
944 *(double*) &pAny->pReserved= *safe_cast<System::Double^>(aAny.Value);
946 else
948 auto_ptr< rtl_mem > mem( rtl_mem::allocate( sizeof (double) ) );
949 *(double*) mem.get()= *safe_cast<System::Double^>(aAny.Value);
950 pAny->pData= mem.release();
952 break;
953 case typelib_TypeClass_STRING: // anies often contain strings; copy string directly
955 pAny->pData= &pAny->pReserved;
956 OUString _s = mapCliString(static_cast<System::String^>(aAny.Value));
957 pAny->pReserved= _s.pData;
958 rtl_uString_acquire(_s.pData);
959 break;
961 case typelib_TypeClass_TYPE:
962 case typelib_TypeClass_ENUM: //ToDo copy enum direct
963 case typelib_TypeClass_SEQUENCE:
964 case typelib_TypeClass_INTERFACE:
965 pAny->pData = &pAny->pReserved;
966 pAny->pReserved = 0;
967 map_to_uno(
968 &pAny->pReserved, aAny.Value, value_td.getTypeLibType(),
969 false /* no assign */);
970 break;
971 case typelib_TypeClass_STRUCT:
972 case typelib_TypeClass_EXCEPTION:
974 css::uno::Type anyType(value_td);
975 typelib_TypeDescription* td= NULL;
976 anyType.getDescription(&td);
977 auto_ptr< rtl_mem > mem(rtl_mem::allocate(td->nSize));
978 typelib_typedescription_release(td);
979 map_to_uno(
980 mem.get(), aAny.Value, value_td.getTypeLibType(),
981 false /* no assign */);
982 pAny->pData = mem.release();
983 break;
985 default:
987 OUStringBuffer buf( 128 );
988 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
989 buf.append(value_td.getTypeName());
990 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] unsupported value type of any!") );
991 throw BridgeRuntimeError( buf.makeStringAndClear() );
995 catch(System::InvalidCastException^ )
997 // ToDo check this
998 if (assign)
999 uno_any_construct( pAny, 0, 0, 0 ); // restore some valid any
1000 OUStringBuffer buf( 256 );
1001 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():Any") );
1002 buf.append(value_td.getTypeName());
1003 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("]The Any type "));
1004 buf.append(value_td.getTypeName());
1005 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" does not correspont "
1006 "to its value type: ") );
1007 if(aAny.Value != nullptr)
1009 css::uno::Type td(mapCliType(aAny.Value->GetType()), SAL_NO_ACQUIRE);
1010 buf.append(td.getTypeName());
1012 if (assign)
1013 uno_any_construct( pAny, 0, 0, 0 ); // restore some valid any
1014 throw BridgeRuntimeError( buf.makeStringAndClear() );
1016 catch (BridgeRuntimeError& )
1018 if (assign)
1019 uno_any_construct( pAny, 0, 0, 0 ); // restore some valid any
1020 throw;
1022 catch (...)
1024 if (assign)
1025 uno_any_construct( pAny, 0, 0, 0 ); // restore some valid any
1026 throw;
1029 pAny->pType = value_td.getTypeLibType();
1030 typelib_typedescriptionreference_acquire(pAny->pType);
1031 break;
1033 case typelib_TypeClass_ENUM:
1035 // InvalidCastException is caught at the end of this method
1036 System::Int32 aEnum= System::Convert::ToInt32((cli_data));
1037 *(sal_Int32*) uno_data = aEnum;
1038 break;
1040 case typelib_TypeClass_STRUCT:
1041 case typelib_TypeClass_EXCEPTION:
1043 css::uno::TypeDescription td(type);
1044 typelib_CompoundTypeDescription * comp_td =
1045 (typelib_CompoundTypeDescription*) td.get();
1047 typelib_StructTypeDescription * struct_td = NULL;
1048 if (type->eTypeClass == typelib_TypeClass_STRUCT)
1049 struct_td = (typelib_StructTypeDescription*) td.get();
1051 if ( ! ((typelib_TypeDescription*) comp_td)->bComplete)
1052 ::typelib_typedescription_complete(
1053 (typelib_TypeDescription**) & comp_td );
1055 sal_Int32 nMembers = comp_td->nMembers;
1056 boolean bException= false;
1057 System::Type^ cliType = nullptr;
1058 if (cli_data)
1059 cliType = cli_data->GetType();
1061 if (0 != comp_td->pBaseTypeDescription)
1063 map_to_uno(
1064 uno_data, cli_data,
1065 ((typelib_TypeDescription *)comp_td->pBaseTypeDescription)->pWeakRef,
1066 assign);
1068 sal_Int32 nPos = 0;
1071 typelib_TypeDescriptionReference * member_type= NULL;
1073 OUString usUnoException("com.sun.star.uno.Exception");
1074 for (; nPos < nMembers; ++nPos)
1076 member_type= comp_td->ppTypeRefs[nPos];
1077 #if OSL_DEBUG_LEVEL >= 2
1078 System::String* __s;
1079 sr::FieldInfo* arFields[];
1080 __s = mapUnoString(comp_td->ppMemberNames[nPos]);
1081 arFields = cliType != NULL ? cliType->GetFields() : NULL;
1082 #endif
1083 System::Object^ val= nullptr;
1084 if (cli_data != nullptr)
1086 sr::FieldInfo^ aField= cliType->GetField(
1087 mapUnoString(comp_td->ppMemberNames[nPos]));
1088 // special case for Exception.Message property
1089 // The com.sun.star.uno.Exception.Message field is mapped to the
1090 // System.Exception property. Type.GetField("Message") returns null
1091 if ( ! aField && usUnoException.equals(td.get()->pTypeName))
1092 {// get Exception.Message property
1093 OUString usMessageMember("Message");
1094 if (usMessageMember.equals(comp_td->ppMemberNames[nPos]))
1096 sr::PropertyInfo^ pi= cliType->GetProperty(
1097 mapUnoString(comp_td->ppMemberNames[nPos]));
1098 val= pi->GetValue(cli_data, nullptr);
1100 else
1102 OUStringBuffer buf(512);
1103 buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("[map_to_uno(): Member: "));
1104 buf.append(comp_td->ppMemberNames[nPos]);
1105 throw BridgeRuntimeError(buf.makeStringAndClear());
1108 else
1110 val= aField->GetValue(cli_data);
1113 void * p = (char *) uno_data + comp_td->pMemberOffsets[ nPos ];
1114 //When using polymorphic structs then the parameterized members can be null.
1115 //Then we set a default value.
1116 bool bDefault = ((struct_td != NULL
1117 && struct_td->pParameterizedTypes != NULL
1118 && struct_td->pParameterizedTypes[nPos] == sal_True
1119 && val == nullptr)
1120 || cli_data == nullptr) ? true : false;
1121 switch (member_type->eTypeClass)
1123 case typelib_TypeClass_CHAR:
1124 if (bDefault)
1125 *(sal_Unicode*) p = 0;
1126 else
1127 *(sal_Unicode*) p = *safe_cast<System::Char^>(val);
1128 break;
1129 case typelib_TypeClass_BOOLEAN:
1130 if (bDefault)
1131 *(sal_Bool*) p = sal_False;
1132 else
1133 *(sal_Bool*) p = *safe_cast<System::Boolean^>(val);
1134 break;
1135 case typelib_TypeClass_BYTE:
1136 if (bDefault)
1137 *(sal_Int8*) p = 0;
1138 else
1139 *(sal_Int8*) p = *safe_cast<System::Byte^>(val);
1140 break;
1141 case typelib_TypeClass_SHORT:
1142 if (bDefault)
1143 *(sal_Int16*) p = 0;
1144 else
1145 *(sal_Int16*) p = *safe_cast<System::Int16^>(val);
1146 break;
1147 case typelib_TypeClass_UNSIGNED_SHORT:
1148 if (bDefault)
1149 *(sal_uInt16*) p = 0;
1150 else
1151 *(sal_uInt16*) p = *safe_cast<System::UInt16^>(val);
1152 break;
1153 case typelib_TypeClass_LONG:
1154 if (bDefault)
1155 *(sal_Int32*) p = 0;
1156 else
1157 *(sal_Int32*) p = *safe_cast<System::Int32^>(val);
1158 break;
1159 case typelib_TypeClass_UNSIGNED_LONG:
1160 if (bDefault)
1161 *(sal_uInt32*) p = 0;
1162 else
1163 *(sal_uInt32*) p = *safe_cast<System::UInt32^>(val);
1164 break;
1165 case typelib_TypeClass_HYPER:
1166 if (bDefault)
1167 *(sal_Int64*) p = 0;
1168 else
1169 *(sal_Int64*) p = *safe_cast<System::Int64^>(val);
1170 break;
1171 case typelib_TypeClass_UNSIGNED_HYPER:
1172 if (bDefault)
1173 *(sal_uInt64*) p = 0;
1174 else
1175 *(sal_uInt64*) p= *safe_cast<System::UInt64^>(val);
1176 break;
1177 case typelib_TypeClass_FLOAT:
1178 if (bDefault)
1179 *(float*) p = 0.;
1180 else
1181 *(float*) p = *safe_cast<System::Single^>(val);
1182 break;
1183 case typelib_TypeClass_DOUBLE:
1184 if (bDefault)
1185 *(double*) p = 0.;
1186 else
1187 *(double*) p = *safe_cast<System::Double^>(val);
1188 break;
1189 default:
1190 { // ToDo enum, should be converted here
1191 map_to_uno(p, val, member_type, assign);
1192 break;
1197 catch (BridgeRuntimeError& e)
1199 bException= true;
1200 OUStringBuffer buf(512);
1201 buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("[map_to_uno():"));
1202 if (cliType)
1204 buf.append(mapCliString(cliType->FullName));
1205 buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("."));
1206 buf.append(comp_td->ppMemberNames[nPos]);
1207 buf.appendAscii(RTL_CONSTASCII_STRINGPARAM(" "));
1209 buf.append(e.m_message);
1210 throw BridgeRuntimeError(buf.makeStringAndClear());
1212 catch (System::InvalidCastException^ )
1214 bException= true;
1215 OUStringBuffer buf( 256 );
1216 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
1217 if (cliType)
1219 buf.append(mapCliString(cliType->FullName));
1220 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("."));
1221 buf.append(comp_td->ppMemberNames[nPos]);
1223 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] Value has not the required type."));
1224 throw BridgeRuntimeError(buf.makeStringAndClear());
1226 catch (...)
1228 OSL_ASSERT(0);
1229 bException= true;
1230 throw;
1232 __finally
1234 if (bException && !assign) // if assign then caller cleans up
1236 // cleanup the members which we have converted so far
1237 for ( sal_Int32 nCleanup = 0; nCleanup < nPos; ++nCleanup )
1239 uno_type_destructData(
1240 uno_data, comp_td->ppTypeRefs[ nCleanup ], 0 );
1242 if (0 != comp_td->pBaseTypeDescription)
1244 uno_destructData(
1245 uno_data, (typelib_TypeDescription *)comp_td->pBaseTypeDescription, 0 );
1249 break;
1251 case typelib_TypeClass_SEQUENCE:
1253 TypeDescr td( type );
1254 typelib_TypeDescriptionReference * element_type =
1255 ((typelib_IndirectTypeDescription *)td.get())->pType;
1257 auto_ptr< rtl_mem > seq;
1259 System::Array^ ar = nullptr;
1260 if (cli_data != nullptr)
1262 ar = safe_cast<System::Array^>(cli_data);
1263 sal_Int32 nElements = ar->GetLength(0);
1267 switch (element_type->eTypeClass)
1269 case typelib_TypeClass_CHAR:
1270 seq = seq_allocate(nElements, sizeof (sal_Unicode));
1271 sri::Marshal::Copy(safe_cast<array<System::Char>^>(cli_data), 0,
1272 IntPtr(& ((uno_Sequence*) seq.get())->elements), nElements);
1273 break;
1274 case typelib_TypeClass_BOOLEAN:
1275 seq = seq_allocate(nElements, sizeof (sal_Bool));
1276 sri::Marshal::Copy(safe_cast<array<System::Char>^>(cli_data), 0,
1277 IntPtr(& ((uno_Sequence*) seq.get())->elements), nElements);
1278 break;
1279 case typelib_TypeClass_BYTE:
1280 seq = seq_allocate( nElements, sizeof (sal_Int8) );
1281 sri::Marshal::Copy(safe_cast<array<System::Byte>^>(cli_data), 0,
1282 IntPtr(& ((uno_Sequence*) seq.get())->elements), nElements);
1283 break;
1284 case typelib_TypeClass_SHORT:
1285 seq = seq_allocate(nElements, sizeof (sal_Int16));
1286 sri::Marshal::Copy(safe_cast<array<System::Int16>^>(cli_data), 0,
1287 IntPtr(& ((uno_Sequence*) seq.get())->elements), nElements);
1288 break;
1289 case typelib_TypeClass_UNSIGNED_SHORT:
1290 seq = seq_allocate( nElements, sizeof (sal_uInt16) );
1291 sri::Marshal::Copy(dynamic_cast<array<System::Int16>^>(
1292 safe_cast<array<System::UInt16>^>(cli_data)), 0,
1293 IntPtr(& ((uno_Sequence*) seq.get())->elements), nElements);
1294 break;
1295 case typelib_TypeClass_LONG:
1296 seq = seq_allocate(nElements, sizeof (sal_Int32));
1297 sri::Marshal::Copy(safe_cast<array<System::Int32>^>(cli_data), 0,
1298 IntPtr(& ((uno_Sequence*) seq.get())->elements), nElements);
1299 break;
1300 case typelib_TypeClass_UNSIGNED_LONG:
1301 seq = seq_allocate( nElements, sizeof (sal_uInt32) );
1302 sri::Marshal::Copy(dynamic_cast<array<System::Int32>^>(
1303 safe_cast<array<System::UInt32>^>(cli_data)), 0,
1304 IntPtr(& ((uno_Sequence*) seq.get())->elements), nElements);
1305 break;
1306 case typelib_TypeClass_HYPER:
1307 seq = seq_allocate(nElements, sizeof (sal_Int64));
1308 sri::Marshal::Copy(safe_cast<array<System::Int64>^>(cli_data), 0,
1309 IntPtr(& ((uno_Sequence*) seq.get())->elements), nElements);
1310 break;
1311 case typelib_TypeClass_UNSIGNED_HYPER:
1312 seq = seq_allocate(nElements, sizeof (sal_uInt64));
1313 sri::Marshal::Copy(dynamic_cast<array<System::Int64>^>(
1314 safe_cast<array<System::UInt64>^>(cli_data)), 0,
1315 IntPtr(& ((uno_Sequence*) seq.get())->elements), nElements);
1316 break;
1317 case typelib_TypeClass_FLOAT:
1318 seq = seq_allocate(nElements, sizeof (float));
1319 sri::Marshal::Copy(safe_cast<array<System::Single>^>(cli_data), 0,
1320 IntPtr(& ((uno_Sequence*) seq.get())->elements), nElements);
1321 break;
1322 case typelib_TypeClass_DOUBLE:
1323 seq = seq_allocate(nElements, sizeof (double));
1324 sri::Marshal::Copy(safe_cast<array<System::Double>^>(cli_data), 0,
1325 IntPtr(& ((uno_Sequence*) seq.get())->elements), nElements);
1326 break;
1327 case typelib_TypeClass_STRING:
1329 seq = seq_allocate(nElements, sizeof (rtl_uString*));
1330 array<System::String^>^ arStr= safe_cast<array<System::String^>^>(cli_data);
1331 for (int i= 0; i < nElements; i++)
1333 pin_ptr<const wchar_t> pdata= PtrToStringChars(arStr[i]);
1334 rtl_uString** pStr= & ((rtl_uString**) &
1335 ((uno_Sequence*) seq.get())->elements)[i];
1336 *pStr= NULL;
1337 rtl_uString_newFromStr_WithLength( pStr, pdata,
1338 arStr[i]->Length);
1340 break;
1342 case typelib_TypeClass_ENUM:
1343 seq = seq_allocate(nElements, sizeof (sal_Int32));
1344 for (int i= 0; i < nElements; i++)
1346 ((sal_Int32*) &((uno_Sequence*) seq.get())->elements)[i]=
1347 System::Convert::ToInt32(ar->GetValue(i));
1349 break;
1350 case typelib_TypeClass_TYPE:
1351 case typelib_TypeClass_ANY:
1352 case typelib_TypeClass_STRUCT:
1353 case typelib_TypeClass_EXCEPTION:
1354 case typelib_TypeClass_SEQUENCE:
1355 case typelib_TypeClass_INTERFACE:
1357 TypeDescr element_td( element_type );
1358 seq = seq_allocate( nElements, element_td.get()->nSize );
1360 for (sal_Int32 nPos = 0; nPos < nElements; ++nPos)
1364 void * p= ((uno_Sequence *) seq.get())->elements +
1365 (nPos * element_td.get()->nSize);
1366 System::Object^ elemData= dynamic_cast<System::Array^>(cli_data)->GetValue(nPos);
1367 map_to_uno(
1368 p, elemData, element_td.get()->pWeakRef,
1369 false /* no assign */);
1371 catch (...)
1373 // cleanup
1374 for ( sal_Int32 nCleanPos = 0; nCleanPos < nPos; ++nCleanPos )
1376 void * p =
1377 ((uno_Sequence *)seq.get())->elements +
1378 (nCleanPos * element_td.get()->nSize);
1379 uno_destructData( p, element_td.get(), 0 );
1381 throw;
1384 break;
1386 default:
1388 OUStringBuffer buf( 128 );
1389 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
1390 buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName ) );
1391 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] unsupported sequence element type: ") );
1392 buf.append( *reinterpret_cast< OUString const * >( &element_type->pTypeName ) );
1393 throw BridgeRuntimeError( buf.makeStringAndClear() );
1397 catch (BridgeRuntimeError& e)
1399 OUStringBuffer buf( 128 );
1400 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
1401 buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName ));
1402 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] conversion failed\n "));
1403 buf.append(e.m_message);
1404 throw BridgeRuntimeError(buf.makeStringAndClear());
1406 catch (System::InvalidCastException^ )
1408 // Ok, checked
1409 OUStringBuffer buf( 128 );
1410 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
1411 buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName) );
1412 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] could not convert sequence element type: ") );
1413 buf.append( *reinterpret_cast< OUString const * >( &element_type->pTypeName ) );
1414 throw BridgeRuntimeError( buf.makeStringAndClear() );
1416 catch (...)
1418 OSL_ASSERT(0);
1419 throw;
1421 __finally
1423 if (assign)
1424 uno_destructData( uno_data, td.get(), 0 );
1427 else
1429 seq = seq_allocate(0, sizeof (sal_Int32));
1431 *(uno_Sequence **)uno_data = (uno_Sequence *)seq.release();
1432 break;
1434 case typelib_TypeClass_INTERFACE:
1436 if (assign)
1438 uno_Interface * p = *(uno_Interface **)uno_data;
1439 if (0 != p)
1440 (*p->release)( p );
1442 if (nullptr == cli_data) // null-ref
1444 *(uno_Interface **)uno_data = 0;
1446 else
1448 TypeDescr td( type );
1449 uno_Interface * pUnoI = map_cli2uno(cli_data, td.get());
1450 *(uno_Interface **)uno_data = pUnoI;
1452 break;
1454 default:
1456 //ToDo check
1457 OUStringBuffer buf( 128 );
1458 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
1459 buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName ) );
1460 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] unsupported type!") );
1461 throw BridgeRuntimeError( buf.makeStringAndClear() );
1465 // BridgeRuntimeError are allowed to be thrown
1466 catch (System::InvalidCastException^ )
1468 //ToDo check
1469 OUStringBuffer buf( 128 );
1470 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
1471 buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName ) );
1472 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] could not convert type!") );
1473 throw BridgeRuntimeError( buf.makeStringAndClear() );
1475 catch (System::NullReferenceException ^ e)
1477 OUStringBuffer buf(512);
1478 buf.appendAscii(RTL_CONSTASCII_STRINGPARAM(
1479 "[map_to_uno()] Illegal null reference passed!\n"));
1480 buf.append(mapCliString(e->StackTrace));
1481 throw BridgeRuntimeError( buf.makeStringAndClear() );
1483 catch (BridgeRuntimeError& )
1485 throw;
1487 catch (...)
1489 OSL_ASSERT(0);
1490 throw;
1496 @param info
1497 The expected target type. Currently info is provdided when this method is called
1498 to convert the in/out and out parameters of a call from cli to uno. Then info
1499 is always a byref type, e.g. "System.String&". info is used for Any and Enum conversion.
1500 @param bDontCreateObj
1501 false - a new object is created which holds the mapped uno value and is assigned to
1502 cli_data.
1503 true - cli_data already contains the newly constructed object. This is the case if
1504 a struct is converted then on the first call to map_to_cli the new object is created.
1505 If the struct inherits another struct then this function is called recursivly while the
1506 newly created object is passed in cli_data.
1508 void Bridge::map_to_cli(
1509 System::Object^ *cli_data, void const * uno_data,
1510 typelib_TypeDescriptionReference * type, System::Type^ info,
1511 bool bDontCreateObj) const
1513 switch (type->eTypeClass)
1515 case typelib_TypeClass_CHAR:
1516 *cli_data= *(__wchar_t const*)uno_data;
1517 break;
1518 case typelib_TypeClass_BOOLEAN:
1519 *cli_data = (*(bool const*)uno_data) == sal_True ? true : false;
1520 break;
1521 case typelib_TypeClass_BYTE:
1522 *cli_data = *(unsigned char const*) uno_data;
1523 break;
1524 case typelib_TypeClass_SHORT:
1525 *cli_data= *(short const*) uno_data;
1526 break;
1527 case typelib_TypeClass_UNSIGNED_SHORT:
1528 *cli_data= *(unsigned short const*) uno_data;
1529 break;
1530 case typelib_TypeClass_LONG:
1531 *cli_data= *(int const*) uno_data;
1532 break;
1533 case typelib_TypeClass_UNSIGNED_LONG:
1534 *cli_data= *(unsigned int const*) uno_data;
1535 break;
1536 case typelib_TypeClass_HYPER:
1537 *cli_data= *(__int64 const*) uno_data;
1538 break;
1539 case typelib_TypeClass_UNSIGNED_HYPER:
1540 *cli_data= *(unsigned __int64 const*) uno_data;
1541 break;
1542 case typelib_TypeClass_FLOAT:
1543 *cli_data= *(float const*) uno_data;
1544 break;
1545 case typelib_TypeClass_DOUBLE:
1546 *cli_data= *(double const*) uno_data;
1547 break;
1548 case typelib_TypeClass_STRING:
1550 rtl_uString const* sVal= NULL;
1551 sVal= *(rtl_uString* const*) uno_data;
1552 *cli_data= gcnew System::String((__wchar_t*) sVal->buffer,0, sVal->length);
1553 break;
1555 case typelib_TypeClass_TYPE:
1557 *cli_data= mapUnoType( *(typelib_TypeDescriptionReference * const *)uno_data );
1558 break;
1560 case typelib_TypeClass_ANY:
1562 uno_Any const * pAny = (uno_Any const *)uno_data;
1563 if (typelib_TypeClass_VOID != pAny->pType->eTypeClass)
1565 System::Object^ objCli= nullptr;
1566 map_to_cli(
1567 &objCli, pAny->pData, pAny->pType, nullptr,
1568 false);
1570 uno::Any anyVal(mapUnoType(pAny->pType), objCli);
1571 *cli_data= anyVal;
1573 else
1574 { // void any
1575 *cli_data= uno::Any::VOID;
1577 break;
1579 case typelib_TypeClass_ENUM:
1581 if (info != nullptr)
1583 OSL_ASSERT(info->IsByRef);
1584 info= info->GetElementType();
1585 *cli_data= System::Enum::ToObject(info, *(System::Int32*) uno_data);
1587 else
1588 *cli_data= System::Enum::ToObject(
1589 mapUnoType(type), *(System::Int32*) uno_data);
1590 break;
1592 case typelib_TypeClass_STRUCT:
1593 case typelib_TypeClass_EXCEPTION:
1595 TypeDescr td( type );
1596 typelib_CompoundTypeDescription * comp_td =
1597 (typelib_CompoundTypeDescription *) td.get();
1598 if ( ! ((typelib_TypeDescription*) comp_td)->bComplete)
1599 ::typelib_typedescription_complete(
1600 (typelib_TypeDescription**) & comp_td );
1603 //create the type
1604 System::Type^ cliType= loadCliType(td.get()->pTypeName);
1605 //detect if we recursivly convert inherited structures
1606 //If this point is reached because of a recursive call during convering a
1607 //struct then we must not create a new object rather we use the one in
1608 // cli_data argument.
1609 System::Object^ cliObj;
1610 if (bDontCreateObj)
1611 cliObj = *cli_data; // recursive call
1612 else
1614 //Special handling for Exception conversion. We must call constructor System::Exception
1615 //to pass the message string
1616 if (ucss::uno::Exception::typeid->IsAssignableFrom(cliType))
1618 //We need to get the Message field. Therefore we must obtain the offset from
1619 //the typedescription. The base interface of all exceptions is
1620 //com::sun::star::uno::Exception which contains the message
1621 typelib_CompoundTypeDescription* pCTD = comp_td;
1622 while (pCTD->pBaseTypeDescription)
1623 pCTD = pCTD->pBaseTypeDescription;
1624 int nPos = -1;
1626 OUString usMessageMember("Message");
1627 for (int i = 0; i < pCTD->nMembers; i ++)
1629 #if OSL_DEBUG_LEVEL >= 2
1630 System::String* sMember;
1631 sMember = mapUnoString(pCTD->ppMemberNames[i]);
1632 #endif
1633 if (usMessageMember.equals(pCTD->ppMemberNames[i]))
1635 nPos = i;
1636 break;
1639 OSL_ASSERT (nPos != -1);
1640 int offset = pCTD->pMemberOffsets[nPos];
1641 //With the offset within the exception we can get the message string
1642 System::String^ sMessage = mapUnoString(*(rtl_uString**)
1643 ((char*) uno_data + offset));
1644 //We need to find a constructor for the exception that takes the message string
1645 //We assume that the first argument is the message string
1646 array<sr::ConstructorInfo^>^ arCtorInfo = cliType->GetConstructors();
1647 sr::ConstructorInfo^ ctorInfo = nullptr;
1648 int numCtors = arCtorInfo->Length;
1649 //Constructor must at least have 2 params for the base
1650 //unoidl.com.sun.star.uno.Exception (String, Object);
1651 array<sr::ParameterInfo^>^ arParamInfo;
1652 for (int i = 0; i < numCtors; i++)
1654 arParamInfo = arCtorInfo[i]->GetParameters();
1655 if (arParamInfo->Length < 2)
1656 continue;
1657 ctorInfo = arCtorInfo[i];
1658 break;
1660 OSL_ASSERT(arParamInfo[0]->ParameterType->Equals(System::String::typeid)
1661 && arParamInfo[1]->ParameterType->Equals(System::Object::typeid)
1662 && arParamInfo[0]->Position == 0
1663 && arParamInfo[1]->Position == 1);
1664 //Prepare parameters for constructor
1665 int numArgs = arParamInfo->Length;
1666 array<System::Object^>^ args = gcnew array<System::Object^>(numArgs);
1667 //only initialize the first argument with the message
1668 args[0] = sMessage;
1669 cliObj = ctorInfo->Invoke(args);
1671 else
1672 cliObj = System::Activator::CreateInstance(cliType);
1674 sal_Int32 * pMemberOffsets = comp_td->pMemberOffsets;
1676 if (comp_td->pBaseTypeDescription)
1678 //convert inherited struct
1679 //cliObj is passed inout (args in_param, out_param are true), hence the passed
1680 // cliObj is used by the callee instead of a newly created struct
1681 map_to_cli(
1682 &cliObj, uno_data,
1683 ((typelib_TypeDescription *)comp_td->pBaseTypeDescription)->pWeakRef, nullptr,
1684 true);
1686 OUString usUnoException("com.sun.star.uno.Exception");
1687 for (sal_Int32 nPos = comp_td->nMembers; nPos--; )
1689 typelib_TypeDescriptionReference * member_type = comp_td->ppTypeRefs[ nPos ];
1690 System::String^ sMemberName= mapUnoString(comp_td->ppMemberNames[nPos]);
1691 sr::FieldInfo^ aField= cliType->GetField(sMemberName);
1692 // special case for Exception.Message. The field has already been
1693 // set while constructing cli object
1694 if ( ! aField && usUnoException.equals(td.get()->pTypeName))
1696 continue;
1698 void const * p = (char const *)uno_data + pMemberOffsets[ nPos ];
1699 switch (member_type->eTypeClass)
1701 case typelib_TypeClass_CHAR:
1702 aField->SetValue(cliObj, *(System::Char*) p);
1703 break;
1704 case typelib_TypeClass_BOOLEAN:
1705 aField->SetValue(cliObj, *(System::Boolean*) p);
1706 break;
1707 case typelib_TypeClass_BYTE:
1708 aField->SetValue(cliObj, *(System::Byte*) p);
1709 break;
1710 case typelib_TypeClass_SHORT:
1711 aField->SetValue(cliObj, *(System::Int16*) p);
1712 break;
1713 case typelib_TypeClass_UNSIGNED_SHORT:
1714 aField->SetValue(cliObj, *(System::UInt16*) p);
1715 break;
1716 case typelib_TypeClass_LONG:
1717 aField->SetValue(cliObj, *(System::Int32*) p);
1718 break;
1719 case typelib_TypeClass_UNSIGNED_LONG:
1720 aField->SetValue(cliObj, *(System::UInt32*) p);
1721 break;
1722 case typelib_TypeClass_HYPER:
1723 aField->SetValue(cliObj, *(System::Int64*) p);
1724 break;
1725 case typelib_TypeClass_UNSIGNED_HYPER:
1726 aField->SetValue(cliObj, *(System::UInt64*) p);
1727 break;
1728 case typelib_TypeClass_FLOAT:
1729 aField->SetValue(cliObj, *(System::Single*) p);
1730 break;
1731 case typelib_TypeClass_DOUBLE:
1732 aField->SetValue(cliObj, *(System::Double*) p);
1733 break;
1734 default:
1736 System::Object^ cli_val;
1737 map_to_cli(
1738 &cli_val, p, member_type, nullptr,
1739 false);
1740 aField->SetValue(cliObj, cli_val);
1741 break;
1745 *cli_data= cliObj;
1746 break;
1748 case typelib_TypeClass_SEQUENCE:
1750 sal_Int32 nElements;
1751 uno_Sequence const * seq = 0;
1752 seq = *(uno_Sequence * const *)uno_data;
1753 nElements = seq->nElements;
1755 TypeDescr td( type );
1756 typelib_TypeDescriptionReference * element_type =
1757 ((typelib_IndirectTypeDescription *)td.get())->pType;
1759 switch (element_type->eTypeClass)
1761 case typelib_TypeClass_CHAR:
1763 array<System::Char>^ arChar= gcnew array<System::Char>(nElements);
1764 sri::Marshal::Copy( IntPtr((void*) &seq->elements), arChar, 0, nElements);
1765 *cli_data= arChar;
1766 break;
1768 case typelib_TypeClass_BOOLEAN:
1770 array<System::Byte>^ arBool= gcnew array<System::Byte>(nElements);
1771 sri::Marshal::Copy( IntPtr((void*) &seq->elements), arBool, 0, nElements);
1772 *cli_data= dynamic_cast<array<System::Boolean>^>(arBool);
1773 break;
1775 case typelib_TypeClass_BYTE:
1777 array<System::Byte>^ arByte= gcnew array<System::Byte>(nElements);
1778 sri::Marshal::Copy( IntPtr((void*) &seq->elements), arByte, 0, nElements);
1779 *cli_data= arByte;
1780 break;
1782 case typelib_TypeClass_SHORT:
1784 array<System::Int16>^ arShort= gcnew array<System::Int16>(nElements);
1785 sri::Marshal::Copy( IntPtr((void*) &seq->elements), arShort, 0, nElements);
1786 *cli_data= arShort;
1787 break;
1789 case typelib_TypeClass_UNSIGNED_SHORT:
1791 array<System::UInt16>^ arUInt16= gcnew array<System::UInt16>(nElements);
1792 sri::Marshal::Copy( IntPtr((void*) &seq->elements), dynamic_cast<array<System::Int16>^>(arUInt16),
1793 0, nElements);
1794 *cli_data= arUInt16;
1795 break;
1797 case typelib_TypeClass_LONG:
1799 array<System::Int32>^ arInt32= gcnew array<System::Int32>(nElements);
1800 sri::Marshal::Copy( IntPtr((void*) &seq->elements), arInt32, 0, nElements);
1801 *cli_data= arInt32;
1802 break;
1804 case typelib_TypeClass_UNSIGNED_LONG:
1806 array<System::UInt32>^ arUInt32= gcnew array<System::UInt32>(nElements);
1807 sri::Marshal::Copy( IntPtr((void*) &seq->elements), dynamic_cast<array<System::Int32>^>(arUInt32),
1808 0, nElements);
1809 *cli_data= arUInt32;
1810 break;
1812 case typelib_TypeClass_HYPER:
1814 array<System::Int64>^ arInt64= gcnew array<System::Int64>(nElements);
1815 sri::Marshal::Copy( IntPtr((void*) &seq->elements), arInt64, 0, nElements);
1816 *cli_data= arInt64;
1817 break;
1819 //FIXME: Marshal::Copy of UInt64?
1820 case typelib_TypeClass_UNSIGNED_HYPER:
1822 array<System::IntPtr>^ arUInt64= gcnew array<System::IntPtr>(nElements);
1823 sri::Marshal::Copy( IntPtr((void*) &seq->elements), arUInt64, 0, nElements);
1824 *cli_data= dynamic_cast<array<System::UInt64>^>(arUInt64);
1825 break;
1827 case typelib_TypeClass_FLOAT:
1829 array<System::Single>^ arSingle= gcnew array<System::Single>(nElements);
1830 sri::Marshal::Copy( IntPtr((void*) &seq->elements), arSingle, 0, nElements);
1831 *cli_data= arSingle;
1832 break;
1834 case typelib_TypeClass_DOUBLE:
1836 array<System::Double>^ arDouble= gcnew array<System::Double>(nElements);
1837 sri::Marshal::Copy( IntPtr((void*) &seq->elements), arDouble, 0, nElements);
1838 *cli_data= arDouble;
1839 break;
1841 case typelib_TypeClass_STRING:
1843 array<System::String^>^ arString= gcnew array<System::String^>(nElements);
1844 for (int i= 0; i < nElements; i++)
1846 rtl_uString *aStr= ((rtl_uString**)(&seq->elements))[i];
1847 arString[i]= gcnew System::String( (__wchar_t *) &aStr->buffer, 0, aStr->length);
1849 *cli_data= arString;
1850 break;
1852 case typelib_TypeClass_TYPE:
1854 array<System::Type^>^ arType= gcnew array<System::Type^>(nElements);
1855 for (int i= 0; i < nElements; i++)
1857 arType[i]=
1858 mapUnoType( ((typelib_TypeDescriptionReference**) seq->elements)[i]);
1860 *cli_data= arType;
1861 break;
1863 case typelib_TypeClass_ANY:
1865 array<uno::Any>^ arCli= gcnew array<uno::Any>(nElements);
1866 uno_Any const * p = (uno_Any const *)seq->elements;
1867 for (sal_Int32 nPos = 0; nPos < nElements; ++nPos )
1869 System::Object^ cli_obj = nullptr;
1870 map_to_cli(
1871 &cli_obj, &p[ nPos ], element_type, nullptr, false);
1872 arCli[nPos]= *safe_cast<uno::Any^>(cli_obj);
1874 *cli_data= arCli;
1875 break;
1877 case typelib_TypeClass_ENUM:
1879 //get the Enum type
1880 System::Type^ enumType= nullptr;
1881 if (info != nullptr)
1883 //info is EnumType[]&, remove &
1884 OSL_ASSERT(info->IsByRef);
1885 enumType = info->GetElementType();
1886 //enumType is EnumType[], remove []
1887 enumType = enumType->GetElementType();
1889 else
1890 enumType= mapUnoType(element_type);
1892 System::Array^ arEnum = System::Array::CreateInstance(
1893 enumType, nElements);
1894 for (int i= 0; i < nElements; i++)
1896 arEnum->SetValue(System::Enum::ToObject(enumType,
1897 ((sal_Int32*) seq->elements)[i]), i);
1899 *cli_data = arEnum;
1900 break;
1902 case typelib_TypeClass_STRUCT:
1903 case typelib_TypeClass_EXCEPTION:
1905 TypeDescr element_td( element_type );
1906 System::Array^ ar= System::Array::CreateInstance(
1907 mapUnoType(element_type),nElements);
1908 if (0 < nElements)
1910 // ToDo check this
1911 char * p = (char *) &seq->elements;
1912 sal_Int32 nSize = element_td.get()->nSize;
1913 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
1915 System::Object^ val;
1916 map_to_cli(
1917 &val, p + (nSize * nPos), element_type, nullptr, false);
1918 ar->SetValue(val, nPos);
1921 *cli_data = ar;
1922 break;
1924 // ToDo, verify
1925 case typelib_TypeClass_SEQUENCE:
1927 System::Array ^ar= System::Array::CreateInstance(
1928 mapUnoType(element_type), nElements);
1929 if (0 < nElements)
1931 TypeDescr element_td( element_type );
1932 uno_Sequence ** elements = (uno_Sequence**) seq->elements;
1933 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
1935 System::Object^ val;
1936 map_to_cli(
1937 &val, &elements[nPos], element_type, nullptr, false);
1938 ar->SetValue(val, nPos);
1941 *cli_data = ar;
1942 break;
1944 case typelib_TypeClass_INTERFACE:
1946 TypeDescr element_td( element_type );
1947 System::Type ^ ifaceType= mapUnoType(element_type);
1948 System::Array^ ar= System::Array::CreateInstance(ifaceType, nElements);
1950 char * p = (char *)seq->elements;
1951 sal_Int32 nSize = element_td.get()->nSize;
1952 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
1954 System::Object^ val;
1955 map_to_cli(
1956 &val, p + (nSize * nPos), element_type, nullptr, false);
1958 ar->SetValue(val, nPos);
1960 *cli_data= ar;
1961 break;
1963 default:
1965 OUStringBuffer buf( 128 );
1966 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_cli():") );
1967 buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName ) );
1968 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] unsupported element type: ") );
1969 buf.append( *reinterpret_cast< OUString const * >( &element_type->pTypeName ) );
1970 throw BridgeRuntimeError( buf.makeStringAndClear() );
1973 break;
1975 case typelib_TypeClass_INTERFACE:
1977 uno_Interface * pUnoI = *(uno_Interface * const *)uno_data;
1978 if (0 != pUnoI)
1980 TypeDescr td( type );
1981 *cli_data= map_uno2cli( pUnoI, reinterpret_cast<
1982 typelib_InterfaceTypeDescription*>(td.get())) ;
1984 else
1985 *cli_data= nullptr;
1986 break;
1988 default:
1990 //ToDo check this exception. The String is probably crippled
1991 OUStringBuffer buf( 128 );
1992 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_cli():") );
1993 buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName ) );
1994 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] unsupported type!") );
1995 throw BridgeRuntimeError( buf.makeStringAndClear() );
2001 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */