merged tag ooo/DEV300_m102
[LibreOffice.git] / cli_ure / source / uno_bridge / cli_data.cxx
blob99f4bda82563893dc182d368beee7b9b98f1bc53
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_cli_ure.hxx"
31 #pragma warning(push, 1)
32 #include "windows.h"
33 #pragma warning(pop)
35 #include <memory>
38 #include "rtl/ustring.hxx"
39 #include "rtl/ustrbuf.hxx"
40 #include "uno/sequence2.h"
41 #include "typelib/typedescription.hxx"
42 #include "cli_proxy.h"
43 #include "cli_base.h"
44 #include "cli_bridge.h"
46 #using <cli_uretypes.dll>
49 #undef VOID
51 namespace css = com::sun::star;
53 namespace sri = System::Runtime::InteropServices;
54 namespace sr = System::Reflection;
55 namespace st = System::Text;
56 namespace ucss = unoidl::com::sun::star;
58 using namespace rtl;
59 using namespace std;
62 namespace cli_uno
64 System::String* mapUnoPolymorphicName(System::String* unoName);
65 OUString mapCliTypeName(System::String* typeName);
66 System::String* mapCliPolymorphicName(System::String* unoName);
67 System::String* mapPolymorphicName(System::String* unoName, bool bCliToUno);
69 inline auto_ptr< rtl_mem > seq_allocate( sal_Int32 nElements, sal_Int32 nSize )
71 auto_ptr< rtl_mem > seq(
72 rtl_mem::allocate( SAL_SEQUENCE_HEADER_SIZE + (nElements * nSize) ) );
73 uno_Sequence * p = (uno_Sequence *)seq.get();
74 p->nRefCount = 1;
75 p->nElements = nElements;
76 return seq;
80 System::Object* Bridge::map_uno2cli(uno_Interface * pUnoI, typelib_InterfaceTypeDescription *pTD) const
82 System::Object* retVal= NULL;
83 // get oid
84 rtl_uString * pOid = 0;
85 (*m_uno_env->getObjectIdentifier)( m_uno_env, &pOid, pUnoI );
86 OSL_ASSERT( 0 != pOid );
87 OUString oid(pOid, SAL_NO_ACQUIRE);
89 //see if the interface was already mapped
90 System::Type* ifaceType= mapUnoType(reinterpret_cast<typelib_TypeDescription*>(pTD));
91 System::String* sOid= mapUnoString(oid.pData);
93 System::Threading::Monitor::Enter( CliEnvHolder::g_cli_env );
94 try
96 retVal = CliEnvHolder::g_cli_env->getRegisteredInterface(sOid, ifaceType);
97 if (retVal)
99 // There is already an registered object. It can either be a proxy
100 // for the UNO object or a real cli object. In the first case we
101 // tell the proxy that it shall also represent the current UNO
102 // interface. If it already does that, then it does nothing
103 if (srr::RemotingServices::IsTransparentProxy(retVal))
105 UnoInterfaceProxy* p = static_cast<UnoInterfaceProxy*>(
106 srr::RemotingServices::GetRealProxy(retVal));
107 p->addUnoInterface(pUnoI, pTD);
110 else
112 retVal = UnoInterfaceProxy::create(
113 (Bridge *) this, pUnoI, pTD, oid );
116 __finally
118 System::Threading::Monitor::Exit( CliEnvHolder::g_cli_env );
121 return retVal;
124 uno_Interface* Bridge::map_cli2uno(System::Object* cliObj, typelib_TypeDescription *pTD) const
126 uno_Interface* retIface = NULL;
127 // get oid from dot net environment
128 System::String* ds_oid = CliEnvHolder::g_cli_env->getObjectIdentifier( cliObj);
129 OUString ousOid = mapCliString(ds_oid);
130 // look if interface is already mapped
131 m_uno_env->getRegisteredInterface(m_uno_env, (void**) &retIface, ousOid.pData,
132 (typelib_InterfaceTypeDescription*) pTD);
133 if ( ! retIface)
135 System::Threading::Monitor::Enter(__typeof(Cli_environment));
138 m_uno_env->getRegisteredInterface(m_uno_env, (void**) &retIface, ousOid.pData,
139 (typelib_InterfaceTypeDescription*) pTD);
140 if ( ! retIface)
142 retIface = CliProxy::create((Bridge*)this, cliObj, pTD, ousOid);
145 __finally
147 System::Threading::Monitor::Exit(__typeof(Cli_environment));
150 return retIface;
153 inline System::Type* loadCliType(rtl_uString * unoName)
155 return loadCliType(mapUnoTypeName(unoName));
158 System::Type* loadCliType(System::String * unoName)
160 System::Type* retVal= NULL;
163 //If unoName denotes a polymorphic type, e.g com.sun.star.beans.Defaulted<System.Char>
164 //then we remove the type list, otherwise the type could not be loaded.
165 bool bIsPolymorphic = false;
167 System::String * loadName = unoName;
168 int index = unoName->IndexOf('<');
169 if (index != -1)
171 loadName = unoName->Substring(0, index);
172 bIsPolymorphic = true;
174 System::AppDomain* currentDomain = System::AppDomain::CurrentDomain;
175 sr::Assembly* assems[] = currentDomain->GetAssemblies();
176 for (int i = 0; i < assems->Length; i++)
178 retVal = assems[i]->GetType(loadName, false);
179 if (retVal)
180 break;
183 if (retVal == NULL)
185 System::String * msg = new System::String(S"A type could not be loaded: ");
186 msg = System::String::Concat(msg, loadName);
187 throw BridgeRuntimeError(mapCliString(msg));
190 if (bIsPolymorphic)
192 retVal = uno::PolymorphicType::GetType(retVal, unoName);
195 catch( System::Exception * e)
197 rtl::OUString ouMessage(mapCliString(e->get_Message()));
198 throw BridgeRuntimeError(ouMessage);
200 return retVal;
204 System::Type* mapUnoType(typelib_TypeDescription const * pTD)
206 return mapUnoType(pTD->pWeakRef);
209 System::Type* mapUnoType(typelib_TypeDescriptionReference const * pTD)
211 System::Type * retVal = 0;
212 switch (pTD->eTypeClass)
214 case typelib_TypeClass_VOID:
215 retVal= __typeof(void); break;
216 case typelib_TypeClass_CHAR:
217 retVal= __typeof(System::Char); break;
218 case typelib_TypeClass_BOOLEAN:
219 retVal= __typeof(System::Boolean); break;
220 case typelib_TypeClass_BYTE:
221 retVal= __typeof(System::Byte); break;
222 case typelib_TypeClass_SHORT:
223 retVal= __typeof(System::Int16); break;
224 case typelib_TypeClass_UNSIGNED_SHORT:
225 retVal= __typeof(System::UInt16); break;
226 case typelib_TypeClass_LONG:
227 retVal= __typeof(System::Int32); break;
228 case typelib_TypeClass_UNSIGNED_LONG:
229 retVal= __typeof(System::UInt32); break;
230 case typelib_TypeClass_HYPER:
231 retVal= __typeof(System::Int64); break;
232 case typelib_TypeClass_UNSIGNED_HYPER:
233 retVal= __typeof(System::UInt64); break;
234 case typelib_TypeClass_FLOAT:
235 retVal= __typeof(System::Single); break;
236 case typelib_TypeClass_DOUBLE:
237 retVal= __typeof(System::Double); break;
238 case typelib_TypeClass_STRING:
239 retVal= __typeof(System::String); break;
240 case typelib_TypeClass_TYPE:
241 retVal= __typeof(System::Type); break;
242 case typelib_TypeClass_ANY:
243 retVal= __typeof(uno::Any); break;
244 case typelib_TypeClass_ENUM:
245 case typelib_TypeClass_STRUCT:
246 case typelib_TypeClass_EXCEPTION:
247 retVal= loadCliType(pTD->pTypeName); break;
248 case typelib_TypeClass_INTERFACE:
250 //special handling for XInterface, since it does not exist in cli.
251 rtl::OUString usXInterface(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.XInterface"));
252 if (usXInterface.equals(pTD->pTypeName))
253 retVal= __typeof(System::Object);
254 else
255 retVal= loadCliType(pTD->pTypeName);
256 break;
258 case typelib_TypeClass_SEQUENCE:
260 css::uno::TypeDescription seqType(
261 const_cast<typelib_TypeDescriptionReference*>(pTD));
262 typelib_TypeDescriptionReference* pElementTDRef=
263 reinterpret_cast<typelib_IndirectTypeDescription*>(seqType.get())->pType;
264 switch (pElementTDRef->eTypeClass)
266 case typelib_TypeClass_CHAR:
267 retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArChar)); break;
268 case typelib_TypeClass_BOOLEAN:
269 retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArBoolean));
270 break;
271 case typelib_TypeClass_BYTE:
272 retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArByte));
273 break;
274 case typelib_TypeClass_SHORT:
275 retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArInt16));
276 break;
277 case typelib_TypeClass_UNSIGNED_SHORT:
278 retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArUInt16));
279 break;
280 case typelib_TypeClass_LONG:
281 retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArInt32));
282 break;
283 case typelib_TypeClass_UNSIGNED_LONG:
284 retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArUInt32));
285 break;
286 case typelib_TypeClass_HYPER:
287 retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArInt64));
288 break;
289 case typelib_TypeClass_UNSIGNED_HYPER:
290 retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArUInt64));
291 break;
292 case typelib_TypeClass_FLOAT:
293 retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArSingle));
294 break;
295 case typelib_TypeClass_DOUBLE:
296 retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArDouble));
297 break;
298 case typelib_TypeClass_STRING:
299 retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArString));
300 break;
301 case typelib_TypeClass_TYPE:
302 retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArType));
303 break;
304 case typelib_TypeClass_ANY:
305 case typelib_TypeClass_ENUM:
306 case typelib_TypeClass_EXCEPTION:
307 case typelib_TypeClass_STRUCT:
308 case typelib_TypeClass_INTERFACE:
309 case typelib_TypeClass_SEQUENCE:
311 retVal= loadCliType(pTD->pTypeName);
312 break;
314 default:
315 //All cases should be handled by the case statements above
316 OSL_ASSERT(0);
317 break;
319 break;
321 default:
322 OSL_ASSERT(false);
323 break;
325 return retVal;
328 /** Returns an acquired td.
330 typelib_TypeDescriptionReference* mapCliType(System::Type* cliType)
332 typelib_TypeDescriptionReference* retVal= NULL;
333 if (cliType == NULL)
335 retVal = * typelib_static_type_getByTypeClass(
336 typelib_TypeClass_VOID );
337 typelib_typedescriptionreference_acquire( retVal );
338 return retVal;
340 //check for Enum first,
341 //because otherwise case System::TypeCode::Int32 applies
342 if (cliType->get_IsEnum())
344 OUString usTypeName= mapCliTypeName(cliType->get_FullName());
345 css::uno::Type unoType(css::uno::TypeClass_ENUM, usTypeName);
346 retVal= unoType.getTypeLibType();
347 typelib_typedescriptionreference_acquire(retVal);
349 else
351 switch (System::Type::GetTypeCode(cliType))
353 case System::TypeCode::Boolean:
354 retVal = * typelib_static_type_getByTypeClass(
355 typelib_TypeClass_BOOLEAN );
356 typelib_typedescriptionreference_acquire( retVal );
357 break;
358 case System::TypeCode::Char:
359 retVal = * typelib_static_type_getByTypeClass(
360 typelib_TypeClass_CHAR );
361 typelib_typedescriptionreference_acquire( retVal );
362 break;
363 case System::TypeCode::Byte:
364 retVal = * typelib_static_type_getByTypeClass(
365 typelib_TypeClass_BYTE );
366 typelib_typedescriptionreference_acquire( retVal );
367 break;
368 case System::TypeCode::Int16:
369 retVal = * typelib_static_type_getByTypeClass(
370 typelib_TypeClass_SHORT );
371 typelib_typedescriptionreference_acquire( retVal );
372 break;
373 case System::TypeCode::Int32:
374 retVal = * typelib_static_type_getByTypeClass(
375 typelib_TypeClass_LONG );
376 typelib_typedescriptionreference_acquire( retVal );
377 break;
378 case System::TypeCode::Int64:
379 retVal = * typelib_static_type_getByTypeClass(
380 typelib_TypeClass_HYPER );
381 typelib_typedescriptionreference_acquire( retVal );
382 break;
383 case System::TypeCode::UInt16:
384 retVal = * typelib_static_type_getByTypeClass(
385 typelib_TypeClass_UNSIGNED_SHORT );
386 typelib_typedescriptionreference_acquire( retVal );
387 break;
388 case System::TypeCode::UInt32:
389 retVal = * typelib_static_type_getByTypeClass(
390 typelib_TypeClass_UNSIGNED_LONG );
391 typelib_typedescriptionreference_acquire( retVal );
392 break;
393 case System::TypeCode::UInt64:
394 retVal = * typelib_static_type_getByTypeClass(
395 typelib_TypeClass_UNSIGNED_HYPER );
396 typelib_typedescriptionreference_acquire( retVal );
397 break;
398 case System::TypeCode::Single:
399 retVal = * typelib_static_type_getByTypeClass(
400 typelib_TypeClass_FLOAT );
401 typelib_typedescriptionreference_acquire( retVal );
402 break;
403 case System::TypeCode::Double:
404 retVal = * typelib_static_type_getByTypeClass(
405 typelib_TypeClass_DOUBLE );
406 typelib_typedescriptionreference_acquire( retVal );
407 break;
408 case System::TypeCode::String:
409 retVal = * typelib_static_type_getByTypeClass(
410 typelib_TypeClass_STRING );
411 typelib_typedescriptionreference_acquire( retVal );
412 break;
413 default:
414 break;
417 if (retVal == NULL)
419 System::String* cliTypeName= cliType->get_FullName();
420 // Void
421 if (const_cast<System::String*>(Constants::sVoid)->Equals(
422 cliTypeName))
424 retVal = * typelib_static_type_getByTypeClass(
425 typelib_TypeClass_VOID );
426 typelib_typedescriptionreference_acquire( retVal );
428 // Type
429 else if (const_cast<System::String*>(Constants::sType)->Equals(
430 cliTypeName))
432 retVal = * typelib_static_type_getByTypeClass(
433 typelib_TypeClass_TYPE );
434 typelib_typedescriptionreference_acquire( retVal );
436 // Any
437 else if (const_cast<System::String*>(Constants::sAny)->Equals(
438 cliTypeName))
440 retVal = * typelib_static_type_getByTypeClass(
441 typelib_TypeClass_ANY );
442 typelib_typedescriptionreference_acquire( retVal );
444 //struct, interfaces, sequences
445 else
447 OUString usTypeName;
448 uno::PolymorphicType * poly = dynamic_cast<uno::PolymorphicType*>(cliType);
449 if (poly != NULL)
450 usTypeName = mapCliTypeName( poly->PolymorphicName);
451 else
452 usTypeName = mapCliTypeName(cliTypeName);
453 typelib_TypeDescription* td = NULL;
454 typelib_typedescription_getByName(&td, usTypeName.pData);
455 if (td)
457 retVal = td->pWeakRef;
458 typelib_typedescriptionreference_acquire(retVal);
459 typelib_typedescription_release(td);
463 if (retVal == NULL)
465 OUStringBuffer buf( 128 );
466 buf.appendAscii(
467 RTL_CONSTASCII_STRINGPARAM("[cli_uno bridge] mapCliType():"
468 "could not map type: ") );
469 buf.append(mapCliString(cliType->get_FullName()));
470 throw BridgeRuntimeError( buf.makeStringAndClear() );
472 return retVal;
476 Otherwise a leading "unoidl." is removed.
478 System::String* mapUnoTypeName(rtl_uString const * typeName)
480 OUString usUnoName( const_cast< rtl_uString * >( typeName ) );
481 st::StringBuilder* buf= new st::StringBuilder();
482 //determine if the type is a sequence and its dimensions
483 int dims= 0;
484 if (usUnoName[0] == '[')
486 sal_Int32 index= 1;
487 while (true)
489 if (usUnoName[index++] == ']')
490 dims++;
491 if (usUnoName[index++] != '[')
492 break;
494 usUnoName = usUnoName.copy(index - 1);
496 System::String * sUnoName = mapUnoString(usUnoName.pData);
497 if (sUnoName->Equals(const_cast<System::String*>(Constants::usBool)))
498 buf->Append(const_cast<System::String*>(Constants::sBoolean));
499 else if (sUnoName->Equals(const_cast<System::String*>(Constants::usChar)))
500 buf->Append(const_cast<System::String*>(Constants::sChar));
501 else if (sUnoName->Equals(const_cast<System::String*>(Constants::usByte)))
502 buf->Append(const_cast<System::String*>(Constants::sByte));
503 else if (sUnoName->Equals(const_cast<System::String*>(Constants::usShort)))
504 buf->Append(const_cast<System::String*>(Constants::sInt16));
505 else if (sUnoName->Equals(const_cast<System::String*>(Constants::usUShort)))
506 buf->Append(const_cast<System::String*>(Constants::sUInt16));
507 else if (sUnoName->Equals(const_cast<System::String*>(Constants::usLong)))
508 buf->Append(const_cast<System::String*>(Constants::sInt32));
509 else if (sUnoName->Equals(const_cast<System::String*>(Constants::usULong)))
510 buf->Append(const_cast<System::String*>(Constants::sUInt32));
511 else if (sUnoName->Equals(const_cast<System::String*>(Constants::usHyper)))
512 buf->Append(const_cast<System::String*>(Constants::sInt64));
513 else if (sUnoName->Equals(const_cast<System::String*>(Constants::usUHyper)))
514 buf->Append(const_cast<System::String*>(Constants::sUInt64));
515 else if (sUnoName->Equals(const_cast<System::String*>(Constants::usFloat)))
516 buf->Append(const_cast<System::String*>(Constants::sSingle));
517 else if (sUnoName->Equals(const_cast<System::String*>(Constants::usDouble)))
518 buf->Append(const_cast<System::String*>(Constants::sDouble));
519 else if (sUnoName->Equals(const_cast<System::String*>(Constants::usString)))
520 buf->Append(const_cast<System::String*>(Constants::sString));
521 else if (sUnoName->Equals(const_cast<System::String*>(Constants::usVoid)))
522 buf->Append(const_cast<System::String*>(Constants::sVoid));
523 else if (sUnoName->Equals(const_cast<System::String*>(Constants::usType)))
524 buf->Append(const_cast<System::String*>(Constants::sType));
525 else if (sUnoName->Equals(const_cast<System::String*>(Constants::usXInterface)))
526 buf->Append(const_cast<System::String*>(Constants::sObject));
527 else if (sUnoName->Equals(const_cast<System::String*>(Constants::usAny)))
529 buf->Append(const_cast<System::String*>(Constants::sAny));
531 else
533 //put "unoidl." at the beginning
534 buf->Append(const_cast<System::String*>(Constants::sUnoidl));
535 //for polymorphic struct types remove the brackets, e.g mystruct<bool> -> mystruct
536 System::String * sName = mapUnoPolymorphicName(sUnoName);
537 buf->Append(sName);
539 // apend []
540 for (;dims--;)
541 buf->Append(const_cast<System::String*>(Constants::sBrackets));
543 return buf->ToString();
549 /** For example, there is a uno type
550 com.sun.star.Foo<char, long>.
551 The values in the type list
552 are uno types and are replaced by cli types, such as System.Char,
553 System.Int32, etc.
554 The präfix unoidl is not added.
556 inline System::String* mapUnoPolymorphicName(System::String* unoName)
558 return mapPolymorphicName(unoName, false);
560 /** For example, there is a type name such as
561 com.sun.star.Foo<System.Char, System.Int32>.
562 The values in the type list
563 are CLI types and are replaced by uno types, such as char,
564 long, etc.
565 The präfix unoidl remains.
567 inline System::String* mapCliPolymorphicName(System::String* unoName)
569 return mapPolymorphicName(unoName, true);
572 System::String* mapPolymorphicName(System::String* unoName, bool bCliToUno)
574 int index = unoName->IndexOf('<');
575 if (index == -1)
576 return unoName;
578 System::Text::StringBuilder * builder = new System::Text::StringBuilder(256);
579 builder->Append(unoName->Substring(0, index +1 ));
581 //Find the first occurrence of ','
582 //If the parameter is a polymorphic struct then we neede to ignore everything
583 //between the brackets because it can also contain commas
584 //get the type list within < and >
585 int endIndex = unoName->Length - 1;
586 index++;
587 int cur = index;
588 int countParams = 0;
589 while (cur <= endIndex)
591 System::Char c = unoName->Chars[cur];
592 if (c == ',' || c == '>')
594 //insert a comma if needed
595 if (countParams != 0)
596 builder->Append(S",");
597 countParams++;
598 System::String * sParam = unoName->Substring(index, cur - index);
599 //skip the comma
600 cur++;
601 //the the index to the beginning of the next param
602 index = cur;
603 if (bCliToUno)
605 builder->Append(mapCliTypeName(sParam));
607 else
609 OUString s = mapCliString(sParam);
610 builder->Append(mapUnoTypeName(s.pData));
613 else if (c == '<')
615 cur++;
616 //continue until the matching '>'
617 int numNested = 0;
618 for (;;cur++)
620 System::Char curChar = unoName->Chars[cur];
621 if (curChar == '<')
623 numNested ++;
625 else if (curChar == '>')
627 if (numNested > 0)
628 numNested--;
629 else
630 break;
634 cur++;
637 builder->Append((System::Char) '>');
638 return builder->ToString();
641 OUString mapCliTypeName(System::String* typeName)
643 int dims= 0;
644 // Array? determine the "rank" (number of "[]")
645 // move from the rightmost end to the left, for example
646 // unoidl.PolymorphicStruct<System.Char[]>[]
647 // has only a "dimension" of 1
648 int cur = typeName->Length - 1;
649 bool bRightBracket = false;
650 while (cur >= 0)
652 System::Char c = typeName->Chars[cur];
653 if (c == ']')
655 bRightBracket = true;
657 else if (c == '[')
659 if (!bRightBracket)
660 throw BridgeRuntimeError(
661 OUSTR("Typename is wrong. No matching brackets for sequence. Name is: ") +
662 mapCliString(typeName));
663 bRightBracket = false;
664 dims ++;
666 else
668 if (bRightBracket)
669 throw BridgeRuntimeError(
670 OUSTR("Typename is wrong. No matching brackets for sequence. Name is: ") +
671 mapCliString(typeName));
672 break;
674 cur--;
677 if (bRightBracket || cur < 0)
678 throw BridgeRuntimeError(
679 OUSTR("Typename is wrong. ") +
680 mapCliString(typeName));
682 typeName = typeName->Substring(0, cur + 1);
684 System::Text::StringBuilder * buf = new System::Text::StringBuilder(512);
686 //Put the "[]" at the beginning of the uno type name
687 for (;dims--;)
688 buf->Append(const_cast<System::String*>(Constants::usBrackets));
690 if (typeName->Equals(const_cast<System::String*>(Constants::sBoolean)))
691 buf->Append(const_cast<System::String*>(Constants::usBool));
692 else if (typeName->Equals(const_cast<System::String*>(Constants::sChar)))
693 buf->Append(const_cast<System::String*>(Constants::usChar));
694 else if (typeName->Equals(const_cast<System::String*>(Constants::sByte)))
695 buf->Append(const_cast<System::String*>(Constants::usByte));
696 else if (typeName->Equals(const_cast<System::String*>(Constants::sInt16)))
697 buf->Append(const_cast<System::String*>(Constants::usShort));
698 else if (typeName->Equals(const_cast<System::String*>(Constants::sUInt16)))
699 buf->Append(const_cast<System::String*>(Constants::usUShort));
700 else if (typeName->Equals(const_cast<System::String*>(Constants::sInt32)))
701 buf->Append(const_cast<System::String*>(Constants::usLong));
702 else if (typeName->Equals(const_cast<System::String*>(Constants::sUInt32)))
703 buf->Append(const_cast<System::String*>(Constants::usULong));
704 else if (typeName->Equals(const_cast<System::String*>(Constants::sInt64)))
705 buf->Append(const_cast<System::String*>(Constants::usHyper));
706 else if (typeName->Equals(const_cast<System::String*>(Constants::sUInt64)))
707 buf->Append(const_cast<System::String*>(Constants::usUHyper));
708 else if (typeName->Equals(const_cast<System::String*>(Constants::sSingle)))
709 buf->Append(const_cast<System::String*>(Constants::usFloat));
710 else if (typeName->Equals(const_cast<System::String*>(Constants::sDouble)))
711 buf->Append(const_cast<System::String*>(Constants::usDouble));
712 else if (typeName->Equals(const_cast<System::String*>(Constants::sString)))
713 buf->Append(const_cast<System::String*>(Constants::usString));
714 else if (typeName->Equals(const_cast<System::String*>(Constants::sVoid)))
715 buf->Append(const_cast<System::String*>(Constants::usVoid));
716 else if (typeName->Equals(const_cast<System::String*>(Constants::sType)))
717 buf->Append(const_cast<System::String*>(Constants::usType));
718 else if (typeName->Equals(const_cast<System::String*>(Constants::sObject)))
719 buf->Append(const_cast<System::String*>(Constants::usXInterface));
720 else if (typeName->Equals(const_cast<System::String*>(Constants::sAny)))
721 buf->Append(const_cast<System::String*>(Constants::usAny));
722 else
724 System::String * sName = mapCliPolymorphicName(typeName);
725 int i= sName->IndexOf(L'.');
726 buf->Append(sName->Substring(i + 1));
728 return mapCliString(buf->ToString());
730 /** Maps uno types to dot net types.
731 * If uno_data is null then the type description is converted to System::Type
733 inline System::String* mapUnoString( rtl_uString const * data)
735 OSL_ASSERT(data);
736 return new System::String((__wchar_t*) data->buffer, 0, data->length);
739 OUString mapCliString(System::String const * data)
742 if (data != NULL)
744 OSL_ASSERT(sizeof(wchar_t) == sizeof(sal_Unicode));
745 wchar_t const __pin * pdata= PtrToStringChars(data);
746 return OUString(pdata, const_cast<System::String*>(data)->get_Length());
748 else
750 return OUString();
754 // ToDo convert cli types to expected types, e.g a long to a short where the uno type
755 // is a sal_Int16. This could be necessary if a scripting language (typeless) is used
756 // @param assign the uno_data has to be destructed (in/out args)
757 void Bridge::map_to_uno(void * uno_data, System::Object* cli_data,
758 typelib_TypeDescriptionReference * type,
759 bool assign) const
761 try{
762 switch (type->eTypeClass)
764 case typelib_TypeClass_VOID:
765 break;
766 case typelib_TypeClass_CHAR:
768 System::Char aChar= *__try_cast<System::Char*>(cli_data);
769 *(sal_Unicode*) uno_data= aChar;
770 break;
772 case typelib_TypeClass_BOOLEAN:
774 System::Boolean aBool= *__try_cast<System::Boolean*>(cli_data);
775 *(sal_Bool*)uno_data= aBool == true ? sal_True : sal_False;
776 break;
778 case typelib_TypeClass_BYTE:
780 System::Byte aByte= *__try_cast<System::Byte*>(cli_data);
781 *(sal_Int8*) uno_data= aByte;
782 break;
784 case typelib_TypeClass_SHORT:
786 System::Int16 aShort= *__try_cast<System::Int16*>(cli_data);
787 *(sal_Int16*) uno_data= aShort;
788 break;
790 case typelib_TypeClass_UNSIGNED_SHORT:
792 System::UInt16 aUShort= *__try_cast<System::UInt16*>(cli_data);
793 *(sal_uInt16*) uno_data= aUShort;
794 break;
796 case typelib_TypeClass_LONG:
798 System::Int32 aLong= *__try_cast<System::Int32*>(cli_data);
799 *(sal_Int32*) uno_data= aLong;
800 break;
802 case typelib_TypeClass_UNSIGNED_LONG:
804 System::UInt32 aULong= *__try_cast<System::UInt32*>(cli_data);
805 *(sal_uInt32*) uno_data= aULong;
806 break;
808 case typelib_TypeClass_HYPER:
810 System::Int64 aHyper= *__try_cast<System::Int64*>(cli_data);
811 *(sal_Int64*) uno_data= aHyper;
812 break;
814 case typelib_TypeClass_UNSIGNED_HYPER:
816 System::UInt64 aLong= *__try_cast<System::UInt64*>(cli_data);
817 *(sal_uInt64*) uno_data= aLong;
818 break;
820 case typelib_TypeClass_FLOAT:
822 System::Single aFloat= *__try_cast<System::Single*>(cli_data);
823 *(float*) uno_data= aFloat;
824 break;
826 case typelib_TypeClass_DOUBLE:
828 System::Double aDouble= *__try_cast<System::Double*>(cli_data);
829 *(double*) uno_data= aDouble;
830 break;
832 case typelib_TypeClass_STRING:
834 if (assign && *(rtl_uString**) uno_data)
835 rtl_uString_release(*(rtl_uString**) uno_data);
837 *(rtl_uString **)uno_data = 0;
838 if (cli_data == NULL)
840 rtl_uString_new((rtl_uString**) uno_data);
842 else
844 System::String *s= __try_cast<System::String*>(cli_data);
845 wchar_t const __pin * pdata= PtrToStringChars(s);
846 rtl_uString_newFromStr_WithLength( (rtl_uString**) uno_data,
847 pdata, s->get_Length() );
849 break;
851 case typelib_TypeClass_TYPE:
853 typelib_TypeDescriptionReference* td= mapCliType(__try_cast<System::Type*>(
854 cli_data));
855 if (assign)
857 typelib_typedescriptionreference_release(
858 *(typelib_TypeDescriptionReference **)uno_data );
860 *(typelib_TypeDescriptionReference **)uno_data = td;
861 break;
863 case typelib_TypeClass_ANY:
865 uno_Any * pAny = (uno_Any *)uno_data;
866 if (cli_data == NULL) // null-ref or uninitialized any maps to empty any
868 if (assign)
869 uno_any_destruct( pAny, 0 );
870 uno_any_construct( pAny, 0, 0, 0 );
871 break;
873 uno::Any aAny= *__try_cast<uno::Any*>(cli_data);
874 css::uno::Type value_td( mapCliType(aAny.Type), SAL_NO_ACQUIRE);
876 if (assign)
877 uno_any_destruct( pAny, 0 );
881 switch (value_td.getTypeClass())
883 case typelib_TypeClass_VOID:
884 pAny->pData = &pAny->pReserved;
885 break;
886 case typelib_TypeClass_CHAR:
887 pAny->pData = &pAny->pReserved;
888 *(sal_Unicode*) &pAny->pReserved = *__try_cast<System::Char*>(aAny.Value);
889 break;
890 case typelib_TypeClass_BOOLEAN:
891 pAny->pData = &pAny->pReserved;
892 *(sal_Bool *) &pAny->pReserved = *__try_cast<System::Boolean*>(aAny.Value);
893 break;
894 case typelib_TypeClass_BYTE:
895 pAny->pData = &pAny->pReserved;
896 *(sal_Int8*) &pAny->pReserved = *__try_cast<System::Byte*>(aAny.Value);
897 break;
898 case typelib_TypeClass_SHORT:
899 pAny->pData = &pAny->pReserved;
900 *(sal_Int16*) &pAny->pReserved = *__try_cast<System::Int16*>(aAny.Value);
901 break;
902 case typelib_TypeClass_UNSIGNED_SHORT:
903 pAny->pData = &pAny->pReserved;
904 *(sal_uInt16*) &pAny->pReserved = *__try_cast<System::UInt16*>(aAny.Value);
905 break;
906 case typelib_TypeClass_LONG:
907 pAny->pData = &pAny->pReserved;
908 *(sal_Int32*) &pAny->pReserved = *__try_cast<System::Int32*>(aAny.Value);
909 break;
910 case typelib_TypeClass_UNSIGNED_LONG:
911 pAny->pData = &pAny->pReserved;
912 *(sal_uInt32*) &pAny->pReserved = *__try_cast<System::UInt32*>(aAny.Value);
913 break;
914 case typelib_TypeClass_HYPER:
915 if (sizeof (sal_Int64) <= sizeof (void *))
917 pAny->pData = &pAny->pReserved;
918 *(sal_Int64*) &pAny->pReserved = *__try_cast<System::Int64*>(aAny.Value);
920 else
922 auto_ptr< rtl_mem > mem( rtl_mem::allocate( sizeof (sal_Int64) ) );
923 *(sal_Int64 *) mem.get()= *__try_cast<System::Int64*>(aAny.Value);
924 pAny->pData = mem.release();
926 break;
927 case typelib_TypeClass_UNSIGNED_HYPER:
928 if (sizeof (sal_uInt64) <= sizeof (void *))
930 pAny->pData = &pAny->pReserved;
931 *(sal_uInt64*) &pAny->pReserved = *__try_cast<System::UInt64*>(aAny.Value);
933 else
935 auto_ptr< rtl_mem > mem( rtl_mem::allocate( sizeof (sal_uInt64) ) );
936 *(sal_uInt64 *) mem.get()= *__try_cast<System::UInt64*>(aAny.Value);
937 pAny->pData = mem.release();
939 break;
940 case typelib_TypeClass_FLOAT:
941 if (sizeof (float) <= sizeof (void *))
943 pAny->pData = &pAny->pReserved;
944 *(float*) &pAny->pReserved = *__try_cast<System::Single*>(aAny.Value);
946 else
948 auto_ptr< rtl_mem > mem( rtl_mem::allocate( sizeof (float) ) );
949 *(float*) mem.get() = *__try_cast<System::Single*>(aAny.Value);
950 pAny->pData = mem.release();
952 break;
953 case typelib_TypeClass_DOUBLE:
954 if (sizeof (double) <= sizeof (void *))
956 pAny->pData = &pAny->pReserved;
957 *(double*) &pAny->pReserved= *__try_cast<System::Double*>(aAny.Value);
959 else
961 auto_ptr< rtl_mem > mem( rtl_mem::allocate( sizeof (double) ) );
962 *(double*) mem.get()= *__try_cast<System::Double*>(aAny.Value);
963 pAny->pData= mem.release();
965 break;
966 case typelib_TypeClass_STRING: // anies often contain strings; copy string directly
968 pAny->pData= &pAny->pReserved;
969 OUString _s = mapCliString(static_cast<System::String*>(aAny.Value));
970 pAny->pReserved= _s.pData;
971 rtl_uString_acquire(_s.pData);
972 break;
974 case typelib_TypeClass_TYPE:
975 case typelib_TypeClass_ENUM: //ToDo copy enum direct
976 case typelib_TypeClass_SEQUENCE:
977 case typelib_TypeClass_INTERFACE:
978 pAny->pData = &pAny->pReserved;
979 pAny->pReserved = 0;
980 map_to_uno(
981 &pAny->pReserved, aAny.Value, value_td.getTypeLibType(),
982 false /* no assign */);
983 break;
984 case typelib_TypeClass_STRUCT:
985 case typelib_TypeClass_EXCEPTION:
987 css::uno::Type anyType(value_td);
988 typelib_TypeDescription* td= NULL;
989 anyType.getDescription(&td);
990 auto_ptr< rtl_mem > mem(rtl_mem::allocate(td->nSize));
991 typelib_typedescription_release(td);
992 map_to_uno(
993 mem.get(), aAny.Value, value_td.getTypeLibType(),
994 false /* no assign */);
995 pAny->pData = mem.release();
996 break;
998 default:
1000 OUStringBuffer buf( 128 );
1001 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
1002 buf.append(value_td.getTypeName());
1003 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] unsupported value type of any!") );
1004 throw BridgeRuntimeError( buf.makeStringAndClear() );
1008 catch(System::InvalidCastException* )
1010 // ToDo check this
1011 if (assign)
1012 uno_any_construct( pAny, 0, 0, 0 ); // restore some valid any
1013 OUStringBuffer buf( 256 );
1014 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():Any") );
1015 buf.append(value_td.getTypeName());
1016 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("]The Any type "));
1017 buf.append(value_td.getTypeName());
1018 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" does not correspont "
1019 "to its value type: ") );
1020 if(aAny.Value != NULL)
1022 css::uno::Type td(mapCliType(aAny.Value->GetType()), SAL_NO_ACQUIRE);
1023 buf.append(td.getTypeName());
1025 if (assign)
1026 uno_any_construct( pAny, 0, 0, 0 ); // restore some valid any
1027 throw BridgeRuntimeError( buf.makeStringAndClear() );
1029 catch (BridgeRuntimeError& )
1031 if (assign)
1032 uno_any_construct( pAny, 0, 0, 0 ); // restore some valid any
1033 throw;
1035 catch (...)
1037 if (assign)
1038 uno_any_construct( pAny, 0, 0, 0 ); // restore some valid any
1039 throw;
1042 pAny->pType = value_td.getTypeLibType();
1043 typelib_typedescriptionreference_acquire(pAny->pType);
1044 break;
1046 case typelib_TypeClass_ENUM:
1048 // InvalidCastException is caught at the end of this method
1049 System::Int32 aEnum= System::Convert::ToInt32((cli_data));
1050 *(sal_Int32*) uno_data = aEnum;
1051 break;
1053 case typelib_TypeClass_STRUCT:
1054 case typelib_TypeClass_EXCEPTION:
1056 css::uno::TypeDescription td(type);
1057 typelib_CompoundTypeDescription * comp_td =
1058 (typelib_CompoundTypeDescription*) td.get();
1060 typelib_StructTypeDescription * struct_td = NULL;
1061 if (type->eTypeClass == typelib_TypeClass_STRUCT)
1062 struct_td = (typelib_StructTypeDescription*) td.get();
1064 if ( ! ((typelib_TypeDescription*) comp_td)->bComplete)
1065 ::typelib_typedescription_complete(
1066 (typelib_TypeDescription**) & comp_td );
1068 sal_Int32 nMembers = comp_td->nMembers;
1069 boolean bException= false;
1070 System::Type* cliType = NULL;
1071 if (cli_data)
1072 cliType = cli_data->GetType();
1074 if (0 != comp_td->pBaseTypeDescription)
1076 map_to_uno(
1077 uno_data, cli_data,
1078 ((typelib_TypeDescription *)comp_td->pBaseTypeDescription)->pWeakRef,
1079 assign);
1081 sal_Int32 nPos = 0;
1084 typelib_TypeDescriptionReference * member_type= NULL;
1086 rtl::OUString usUnoException(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.Exception"));
1087 for (; nPos < nMembers; ++nPos)
1089 member_type= comp_td->ppTypeRefs[nPos];
1090 #if OSL_DEBUG_LEVEL >= 2
1091 System::String* __s;
1092 sr::FieldInfo* arFields[];
1093 __s = mapUnoString(comp_td->ppMemberNames[nPos]);
1094 arFields = cliType != NULL ? cliType->GetFields() : NULL;
1095 #endif
1096 System::Object* val= NULL;
1097 if (cli_data != NULL)
1099 sr::FieldInfo* aField= cliType->GetField(
1100 mapUnoString(comp_td->ppMemberNames[nPos]));
1101 // special case for Exception.Message property
1102 // The com.sun.star.uno.Exception.Message field is mapped to the
1103 // System.Exception property. Type.GetField("Message") returns null
1104 if ( ! aField && usUnoException.equals(td.get()->pTypeName))
1105 {// get Exception.Message property
1106 rtl::OUString usMessageMember(RTL_CONSTASCII_USTRINGPARAM("Message"));
1107 if (usMessageMember.equals(comp_td->ppMemberNames[nPos]))
1109 sr::PropertyInfo* pi= cliType->GetProperty(
1110 mapUnoString(comp_td->ppMemberNames[nPos]));
1111 val= pi->GetValue(cli_data, NULL);
1113 else
1115 OUStringBuffer buf(512);
1116 buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("[map_to_uno(): Member: "));
1117 buf.append(comp_td->ppMemberNames[nPos]);
1118 throw BridgeRuntimeError(buf.makeStringAndClear());
1121 else
1123 val= aField->GetValue(cli_data);
1126 void * p = (char *) uno_data + comp_td->pMemberOffsets[ nPos ];
1127 //When using polymorphic structs then the parameterized members can be null.
1128 //Then we set a default value.
1129 bool bDefault = ((struct_td != NULL
1130 && struct_td->pParameterizedTypes != NULL
1131 && struct_td->pParameterizedTypes[nPos] == sal_True
1132 && val == NULL)
1133 || cli_data == NULL) ? true : false;
1134 switch (member_type->eTypeClass)
1136 case typelib_TypeClass_CHAR:
1137 if (bDefault)
1138 *(sal_Unicode*) p = 0;
1139 else
1140 *(sal_Unicode*) p = *__try_cast<System::Char*>(val);
1141 break;
1142 case typelib_TypeClass_BOOLEAN:
1143 if (bDefault)
1144 *(sal_Bool*) p = sal_False;
1145 else
1146 *(sal_Bool*) p = *__try_cast<System::Boolean*>(val);
1147 break;
1148 case typelib_TypeClass_BYTE:
1149 if (bDefault)
1150 *(sal_Int8*) p = 0;
1151 else
1152 *(sal_Int8*) p = *__try_cast<System::Byte*>(val);
1153 break;
1154 case typelib_TypeClass_SHORT:
1155 if (bDefault)
1156 *(sal_Int16*) p = 0;
1157 else
1158 *(sal_Int16*) p = *__try_cast<System::Int16*>(val);
1159 break;
1160 case typelib_TypeClass_UNSIGNED_SHORT:
1161 if (bDefault)
1162 *(sal_uInt16*) p = 0;
1163 else
1164 *(sal_uInt16*) p = *__try_cast<System::UInt16*>(val);
1165 break;
1166 case typelib_TypeClass_LONG:
1167 if (bDefault)
1168 *(sal_Int32*) p = 0;
1169 else
1170 *(sal_Int32*) p = *__try_cast<System::Int32*>(val);
1171 break;
1172 case typelib_TypeClass_UNSIGNED_LONG:
1173 if (bDefault)
1174 *(sal_uInt32*) p = 0;
1175 else
1176 *(sal_uInt32*) p = *__try_cast<System::UInt32*>(val);
1177 break;
1178 case typelib_TypeClass_HYPER:
1179 if (bDefault)
1180 *(sal_Int64*) p = 0;
1181 else
1182 *(sal_Int64*) p = *__try_cast<System::Int64*>(val);
1183 break;
1184 case typelib_TypeClass_UNSIGNED_HYPER:
1185 if (bDefault)
1186 *(sal_uInt64*) p = 0;
1187 else
1188 *(sal_uInt64*) p= *__try_cast<System::UInt64*>(val);
1189 break;
1190 case typelib_TypeClass_FLOAT:
1191 if (bDefault)
1192 *(float*) p = 0.;
1193 else
1194 *(float*) p = *__try_cast<System::Single*>(val);
1195 break;
1196 case typelib_TypeClass_DOUBLE:
1197 if (bDefault)
1198 *(double*) p = 0.;
1199 else
1200 *(double*) p = *__try_cast<System::Double*>(val);
1201 break;
1202 default:
1203 { // ToDo enum, should be converted here
1204 map_to_uno(p, val, member_type, assign);
1205 break;
1210 catch (BridgeRuntimeError& e)
1212 bException= true;
1213 OUStringBuffer buf(512);
1214 buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("[map_to_uno():"));
1215 if (cliType)
1217 buf.append(mapCliString(cliType->get_FullName()));
1218 buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("."));
1219 buf.append(comp_td->ppMemberNames[nPos]);
1220 buf.appendAscii(RTL_CONSTASCII_STRINGPARAM(" "));
1222 buf.append(e.m_message);
1223 throw BridgeRuntimeError(buf.makeStringAndClear());
1225 catch (System::InvalidCastException* )
1227 bException= true;
1228 OUStringBuffer buf( 256 );
1229 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
1230 if (cliType)
1232 buf.append(mapCliString(cliType->get_FullName()));
1233 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("."));
1234 buf.append(comp_td->ppMemberNames[nPos]);
1236 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] Value has not the required type."));
1237 throw BridgeRuntimeError(buf.makeStringAndClear());
1239 catch (...)
1241 OSL_ASSERT(0);
1242 bException= true;
1243 throw;
1245 __finally
1247 if (bException && !assign) // if assign then caller cleans up
1249 // cleanup the members which we have converted so far
1250 for ( sal_Int32 nCleanup = 0; nCleanup < nPos; ++nCleanup )
1252 uno_type_destructData(
1253 uno_data, comp_td->ppTypeRefs[ nCleanup ], 0 );
1255 if (0 != comp_td->pBaseTypeDescription)
1257 uno_destructData(
1258 uno_data, (typelib_TypeDescription *)comp_td->pBaseTypeDescription, 0 );
1262 break;
1264 case typelib_TypeClass_SEQUENCE:
1266 TypeDescr td( type );
1267 typelib_TypeDescriptionReference * element_type =
1268 ((typelib_IndirectTypeDescription *)td.get())->pType;
1270 auto_ptr< rtl_mem > seq;
1272 System::Array* ar = NULL;
1273 if (cli_data != NULL)
1275 ar = __try_cast<System::Array*>(cli_data);
1276 sal_Int32 nElements = ar->GetLength(0);
1280 switch (element_type->eTypeClass)
1282 case typelib_TypeClass_CHAR:
1283 seq = seq_allocate(nElements, sizeof (sal_Unicode));
1284 sri::Marshal::Copy(__try_cast<System::Char[]>(cli_data), 0,
1285 & ((uno_Sequence*) seq.get())->elements, nElements);
1286 break;
1287 case typelib_TypeClass_BOOLEAN:
1288 seq = seq_allocate(nElements, sizeof (sal_Bool));
1289 sri::Marshal::Copy(__try_cast<System::Boolean[]>(cli_data), 0,
1290 & ((uno_Sequence*) seq.get())->elements, nElements);
1291 break;
1292 case typelib_TypeClass_BYTE:
1293 seq = seq_allocate( nElements, sizeof (sal_Int8) );
1294 sri::Marshal::Copy(__try_cast<System::Byte[]>(cli_data), 0,
1295 & ((uno_Sequence*) seq.get())->elements, nElements);
1296 break;
1297 case typelib_TypeClass_SHORT:
1298 seq = seq_allocate(nElements, sizeof (sal_Int16));
1299 sri::Marshal::Copy(__try_cast<System::Int16[]>(cli_data), 0,
1300 & ((uno_Sequence*) seq.get())->elements, nElements);
1301 break;
1302 case typelib_TypeClass_UNSIGNED_SHORT:
1303 seq = seq_allocate( nElements, sizeof (sal_uInt16) );
1304 sri::Marshal::Copy(static_cast<System::Int16[]>(
1305 __try_cast<System::UInt16[]>(cli_data)), 0,
1306 & ((uno_Sequence*) seq.get())->elements, nElements);
1307 break;
1308 case typelib_TypeClass_LONG:
1309 seq = seq_allocate(nElements, sizeof (sal_Int32));
1310 sri::Marshal::Copy(__try_cast<System::Int32[]>(cli_data), 0,
1311 & ((uno_Sequence*) seq.get())->elements, nElements);
1312 break;
1313 case typelib_TypeClass_UNSIGNED_LONG:
1314 seq = seq_allocate( nElements, sizeof (sal_uInt32) );
1315 sri::Marshal::Copy(static_cast<System::Int32[]>(
1316 __try_cast<System::UInt32[]>(cli_data)), 0,
1317 & ((uno_Sequence*) seq.get())->elements, nElements);
1318 break;
1319 case typelib_TypeClass_HYPER:
1320 seq = seq_allocate(nElements, sizeof (sal_Int64));
1321 sri::Marshal::Copy(__try_cast<System::Int64[]>(cli_data), 0,
1322 & ((uno_Sequence*) seq.get())->elements, nElements);
1323 break;
1324 case typelib_TypeClass_UNSIGNED_HYPER:
1325 seq = seq_allocate(nElements, sizeof (sal_uInt64));
1326 sri::Marshal::Copy(static_cast<System::Int64[]>(
1327 __try_cast<System::UInt64[]>(cli_data)), 0,
1328 & ((uno_Sequence*) seq.get())->elements, nElements);
1329 break;
1330 case typelib_TypeClass_FLOAT:
1331 seq = seq_allocate(nElements, sizeof (float));
1332 sri::Marshal::Copy(__try_cast<System::Single[]>(cli_data), 0,
1333 & ((uno_Sequence*) seq.get())->elements, nElements);
1334 break;
1335 case typelib_TypeClass_DOUBLE:
1336 seq = seq_allocate(nElements, sizeof (double));
1337 sri::Marshal::Copy(__try_cast<System::Double[]>(cli_data), 0,
1338 & ((uno_Sequence*) seq.get())->elements, nElements);
1339 break;
1340 case typelib_TypeClass_STRING:
1342 seq = seq_allocate(nElements, sizeof (rtl_uString*));
1343 System::String* arStr[]= __try_cast<System::String*[]>(cli_data);
1344 for (int i= 0; i < nElements; i++)
1346 wchar_t const __pin * pdata= PtrToStringChars(arStr[i]);
1347 rtl_uString** pStr= & ((rtl_uString**) &
1348 ((uno_Sequence*) seq.get())->elements)[i];
1349 *pStr= NULL;
1350 rtl_uString_newFromStr_WithLength( pStr, pdata,
1351 arStr[i]->get_Length());
1353 break;
1355 case typelib_TypeClass_ENUM:
1356 seq = seq_allocate(nElements, sizeof (sal_Int32));
1357 for (int i= 0; i < nElements; i++)
1359 ((sal_Int32*) &((uno_Sequence*) seq.get())->elements)[i]=
1360 System::Convert::ToInt32(ar->GetValue(i));
1362 break;
1363 case typelib_TypeClass_TYPE:
1364 case typelib_TypeClass_ANY:
1365 case typelib_TypeClass_STRUCT:
1366 case typelib_TypeClass_EXCEPTION:
1367 case typelib_TypeClass_SEQUENCE:
1368 case typelib_TypeClass_INTERFACE:
1370 TypeDescr element_td( element_type );
1371 seq = seq_allocate( nElements, element_td.get()->nSize );
1373 for (sal_Int32 nPos = 0; nPos < nElements; ++nPos)
1377 void * p= ((uno_Sequence *) seq.get())->elements +
1378 (nPos * element_td.get()->nSize);
1379 System::Object* elemData= dynamic_cast<System::Array*>(cli_data)->GetValue(nPos);
1380 map_to_uno(
1381 p, elemData, element_td.get()->pWeakRef,
1382 false /* no assign */);
1384 catch (...)
1386 // cleanup
1387 for ( sal_Int32 nCleanPos = 0; nCleanPos < nPos; ++nCleanPos )
1389 void * p =
1390 ((uno_Sequence *)seq.get())->elements +
1391 (nCleanPos * element_td.get()->nSize);
1392 uno_destructData( p, element_td.get(), 0 );
1394 throw;
1397 break;
1399 default:
1401 OUStringBuffer buf( 128 );
1402 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
1403 buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName ) );
1404 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] unsupported sequence element type: ") );
1405 buf.append( *reinterpret_cast< OUString const * >( &element_type->pTypeName ) );
1406 throw BridgeRuntimeError( buf.makeStringAndClear() );
1410 catch (BridgeRuntimeError& e)
1412 OUStringBuffer buf( 128 );
1413 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
1414 buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName ));
1415 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] conversion failed\n "));
1416 buf.append(e.m_message);
1417 throw BridgeRuntimeError(buf.makeStringAndClear());
1419 catch (System::InvalidCastException* )
1421 // Ok, checked
1422 OUStringBuffer buf( 128 );
1423 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
1424 buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName) );
1425 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] could not convert sequence element type: ") );
1426 buf.append( *reinterpret_cast< OUString const * >( &element_type->pTypeName ) );
1427 throw BridgeRuntimeError( buf.makeStringAndClear() );
1429 catch (...)
1431 OSL_ASSERT(0);
1432 throw;
1434 __finally
1436 if (assign)
1437 uno_destructData( uno_data, td.get(), 0 );
1440 else
1442 seq = seq_allocate(0, sizeof (sal_Int32));
1444 *(uno_Sequence **)uno_data = (uno_Sequence *)seq.release();
1445 break;
1447 case typelib_TypeClass_INTERFACE:
1449 if (assign)
1451 uno_Interface * p = *(uno_Interface **)uno_data;
1452 if (0 != p)
1453 (*p->release)( p );
1455 if (0 == cli_data) // null-ref
1457 *(uno_Interface **)uno_data = 0;
1459 else
1461 TypeDescr td( type );
1462 uno_Interface * pUnoI = map_cli2uno(cli_data, td.get());
1463 *(uno_Interface **)uno_data = pUnoI;
1465 break;
1467 default:
1469 //ToDo check
1470 OUStringBuffer buf( 128 );
1471 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
1472 buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName ) );
1473 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] unsupported type!") );
1474 throw BridgeRuntimeError( buf.makeStringAndClear() );
1478 // BridgeRuntimeError are allowed to be thrown
1479 catch (System::InvalidCastException* )
1481 //ToDo check
1482 OUStringBuffer buf( 128 );
1483 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
1484 buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName ) );
1485 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] could not convert type!") );
1486 throw BridgeRuntimeError( buf.makeStringAndClear() );
1488 catch (System::NullReferenceException * e)
1490 OUStringBuffer buf(512);
1491 buf.appendAscii(RTL_CONSTASCII_STRINGPARAM(
1492 "[map_to_uno()] Illegal null reference passed!\n"));
1493 buf.append(mapCliString(e->get_StackTrace()));
1494 throw BridgeRuntimeError( buf.makeStringAndClear() );
1496 catch (BridgeRuntimeError& )
1498 throw;
1500 catch (...)
1502 OSL_ASSERT(0);
1503 throw;
1509 @param info
1510 The expected target type. Currently info is provdided when this method is called
1511 to convert the in/out and out parameters of a call from cli to uno. Then info
1512 is always a byref type, e.g. "System.String&". info is used for Any and Enum conversion.
1513 @param bDontCreateObj
1514 false - a new object is created which holds the mapped uno value and is assigned to
1515 cli_data.
1516 true - cli_data already contains the newly constructed object. This is the case if
1517 a struct is converted then on the first call to map_to_cli the new object is created.
1518 If the struct inherits another struct then this function is called recursivly while the
1519 newly created object is passed in cli_data.
1521 void Bridge::map_to_cli(
1522 System::Object* *cli_data, void const * uno_data,
1523 typelib_TypeDescriptionReference * type, System::Type* info,
1524 bool bDontCreateObj) const
1526 switch (type->eTypeClass)
1528 case typelib_TypeClass_CHAR:
1529 *cli_data= __box(*(__wchar_t const*)uno_data);
1530 break;
1531 case typelib_TypeClass_BOOLEAN:
1532 *cli_data = __box((*(bool const*)uno_data) == sal_True ? true : false);
1533 break;
1534 case typelib_TypeClass_BYTE:
1535 *cli_data = __box(*(unsigned char const*) uno_data);
1536 break;
1537 case typelib_TypeClass_SHORT:
1538 *cli_data= __box(*(short const*) uno_data);
1539 break;
1540 case typelib_TypeClass_UNSIGNED_SHORT:
1541 *cli_data= __box(*(unsigned short const*) uno_data);
1542 break;
1543 case typelib_TypeClass_LONG:
1544 *cli_data= __box(*(int const*) uno_data);
1545 break;
1546 case typelib_TypeClass_UNSIGNED_LONG:
1547 *cli_data= __box(*(unsigned int const*) uno_data);
1548 break;
1549 case typelib_TypeClass_HYPER:
1550 *cli_data= __box(*(__int64 const*) uno_data);
1551 break;
1552 case typelib_TypeClass_UNSIGNED_HYPER:
1553 *cli_data= __box(*(unsigned __int64 const*) uno_data);
1554 break;
1555 case typelib_TypeClass_FLOAT:
1556 *cli_data= __box(*(float const*) uno_data);
1557 break;
1558 case typelib_TypeClass_DOUBLE:
1559 *cli_data= __box(*(double const*) uno_data);
1560 break;
1561 case typelib_TypeClass_STRING:
1563 rtl_uString const* sVal= NULL;
1564 sVal= *(rtl_uString* const*) uno_data;
1565 *cli_data= new System::String((__wchar_t*) sVal->buffer,0, sVal->length);
1566 break;
1568 case typelib_TypeClass_TYPE:
1570 *cli_data= mapUnoType( *(typelib_TypeDescriptionReference * const *)uno_data );
1571 break;
1573 case typelib_TypeClass_ANY:
1575 uno_Any const * pAny = (uno_Any const *)uno_data;
1576 if (typelib_TypeClass_VOID != pAny->pType->eTypeClass)
1578 System::Object* objCli= NULL;
1579 map_to_cli(
1580 &objCli, pAny->pData, pAny->pType, 0,
1581 false);
1583 uno::Any anyVal(mapUnoType(pAny->pType), objCli);
1584 *cli_data= __box(anyVal);
1586 else
1587 { // void any
1588 *cli_data= __box(uno::Any::VOID);
1590 break;
1592 case typelib_TypeClass_ENUM:
1594 if (info != NULL)
1596 OSL_ASSERT(info->get_IsByRef());
1597 info= info->GetElementType();
1598 *cli_data= System::Enum::ToObject(info, *(System::Int32*) uno_data);
1600 else
1601 *cli_data= System::Enum::ToObject(
1602 mapUnoType(type), *(System::Int32*) uno_data);
1603 break;
1605 case typelib_TypeClass_STRUCT:
1606 case typelib_TypeClass_EXCEPTION:
1608 TypeDescr td( type );
1609 typelib_CompoundTypeDescription * comp_td =
1610 (typelib_CompoundTypeDescription *) td.get();
1611 if ( ! ((typelib_TypeDescription*) comp_td)->bComplete)
1612 ::typelib_typedescription_complete(
1613 (typelib_TypeDescription**) & comp_td );
1616 //create the type
1617 System::Type* cliType= loadCliType(td.get()->pTypeName);
1618 //detect if we recursivly convert inherited structures
1619 //If this point is reached because of a recursive call during convering a
1620 //struct then we must not create a new object rather we use the one in
1621 // cli_data argument.
1622 System::Object* cliObj;
1623 if (bDontCreateObj)
1624 cliObj = *cli_data; // recursive call
1625 else
1627 //Special handling for Exception conversion. We must call constructor System::Exception
1628 //to pass the message string
1629 if (__typeof(ucss::uno::Exception)->IsAssignableFrom(cliType))
1631 //We need to get the Message field. Therefore we must obtain the offset from
1632 //the typedescription. The base interface of all exceptions is
1633 //com::sun::star::uno::Exception which contains the message
1634 typelib_CompoundTypeDescription* pCTD = comp_td;
1635 while (pCTD->pBaseTypeDescription)
1636 pCTD = pCTD->pBaseTypeDescription;
1637 int nPos = -1;
1639 rtl::OUString usMessageMember(RTL_CONSTASCII_USTRINGPARAM("Message"));
1640 for (int i = 0; i < pCTD->nMembers; i ++)
1642 #if OSL_DEBUG_LEVEL >= 2
1643 System::String* sMember;
1644 sMember = mapUnoString(pCTD->ppMemberNames[i]);
1645 #endif
1646 if (usMessageMember.equals(pCTD->ppMemberNames[i]))
1648 nPos = i;
1649 break;
1652 OSL_ASSERT (nPos != -1);
1653 int offset = pCTD->pMemberOffsets[nPos];
1654 //Whith the offset within the exception we can get the message string
1655 System::String* sMessage = mapUnoString(*(rtl_uString**)
1656 ((char*) uno_data + offset));
1657 //We need to find a constructor for the exception that takes the message string
1658 //We assume that the first argument is the message string
1659 sr::ConstructorInfo* arCtorInfo[] = cliType->GetConstructors();
1660 sr::ConstructorInfo* ctorInfo = NULL;
1661 int numCtors = arCtorInfo->get_Length();
1662 //Constructor must at least have 2 params for the base
1663 //unoidl.com.sun.star.uno.Exception (String, Object);
1664 sr::ParameterInfo * arParamInfo[];
1665 for (int i = 0; i < numCtors; i++)
1667 arParamInfo = arCtorInfo[i]->GetParameters();
1668 if (arParamInfo->get_Length() < 2)
1669 continue;
1670 ctorInfo = arCtorInfo[i];
1671 break;
1673 OSL_ASSERT(arParamInfo[0]->get_ParameterType()->Equals(__typeof(System::String))
1674 && arParamInfo[1]->get_ParameterType()->Equals(__typeof(System::Object))
1675 && arParamInfo[0]->get_Position() == 0
1676 && arParamInfo[1]->get_Position() == 1);
1677 //Prepare parameters for constructor
1678 int numArgs = arParamInfo->get_Length();
1679 System::Object * args[] = new System::Object*[numArgs];
1680 //only initialize the first argument with the message
1681 args[0] = sMessage;
1682 cliObj = ctorInfo->Invoke(args);
1684 else
1685 cliObj = System::Activator::CreateInstance(cliType);
1687 sal_Int32 * pMemberOffsets = comp_td->pMemberOffsets;
1689 if (comp_td->pBaseTypeDescription)
1691 //convert inherited struct
1692 //cliObj is passed inout (args in_param, out_param are true), hence the passed
1693 // cliObj is used by the callee instead of a newly created struct
1694 map_to_cli(
1695 &cliObj, uno_data,
1696 ((typelib_TypeDescription *)comp_td->pBaseTypeDescription)->pWeakRef, 0,
1697 true);
1699 rtl::OUString usUnoException(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.Exception"));
1700 for (sal_Int32 nPos = comp_td->nMembers; nPos--; )
1702 typelib_TypeDescriptionReference * member_type = comp_td->ppTypeRefs[ nPos ];
1703 System::String* sMemberName= mapUnoString(comp_td->ppMemberNames[nPos]);
1704 sr::FieldInfo* aField= cliType->GetField(sMemberName);
1705 // special case for Exception.Message. The field has already been
1706 // set while constructing cli object
1707 if ( ! aField && usUnoException.equals(td.get()->pTypeName))
1709 continue;
1711 void const * p = (char const *)uno_data + pMemberOffsets[ nPos ];
1712 switch (member_type->eTypeClass)
1714 case typelib_TypeClass_CHAR:
1715 aField->SetValue(cliObj, __box(*(System::Char*) p));
1716 break;
1717 case typelib_TypeClass_BOOLEAN:
1718 aField->SetValue(cliObj, __box(*(System::Boolean*) p));
1719 break;
1720 case typelib_TypeClass_BYTE:
1721 aField->SetValue(cliObj, __box(*(System::Byte*) p));
1722 break;
1723 case typelib_TypeClass_SHORT:
1724 aField->SetValue(cliObj, __box(*(System::Int16*) p));
1725 break;
1726 case typelib_TypeClass_UNSIGNED_SHORT:
1727 aField->SetValue(cliObj, __box(*(System::UInt16*) p));
1728 break;
1729 case typelib_TypeClass_LONG:
1730 aField->SetValue(cliObj, __box(*(System::Int32*) p));
1731 break;
1732 case typelib_TypeClass_UNSIGNED_LONG:
1733 aField->SetValue(cliObj, __box(*(System::UInt32*) p));
1734 break;
1735 case typelib_TypeClass_HYPER:
1736 aField->SetValue(cliObj, __box(*(System::Int64*) p));
1737 break;
1738 case typelib_TypeClass_UNSIGNED_HYPER:
1739 aField->SetValue(cliObj, __box(*(System::UInt64*) p));
1740 break;
1741 case typelib_TypeClass_FLOAT:
1742 aField->SetValue(cliObj, __box(*(System::Single*) p));
1743 break;
1744 case typelib_TypeClass_DOUBLE:
1745 aField->SetValue(cliObj, __box(*(System::Double*) p));
1746 break;
1747 default:
1749 System::Object* cli_val;
1750 map_to_cli(
1751 &cli_val, p, member_type, 0,
1752 false);
1753 aField->SetValue(cliObj, cli_val);
1754 break;
1758 *cli_data= cliObj;
1759 break;
1761 case typelib_TypeClass_SEQUENCE:
1763 sal_Int32 nElements;
1764 uno_Sequence const * seq = 0;
1765 seq = *(uno_Sequence * const *)uno_data;
1766 nElements = seq->nElements;
1768 TypeDescr td( type );
1769 typelib_TypeDescriptionReference * element_type =
1770 ((typelib_IndirectTypeDescription *)td.get())->pType;
1772 switch (element_type->eTypeClass)
1774 case typelib_TypeClass_CHAR:
1776 System::Char arChar[]= new System::Char[nElements];
1777 sri::Marshal::Copy( (void*) &seq->elements, arChar, 0, nElements);
1778 *cli_data= arChar;
1779 break;
1781 case typelib_TypeClass_BOOLEAN:
1783 System::Boolean arBool[]= new System::Boolean[nElements];
1784 sri::Marshal::Copy( (void*) &seq->elements, arBool, 0, nElements);
1785 *cli_data= arBool;
1786 break;
1788 case typelib_TypeClass_BYTE:
1790 System::Byte arByte[]= new System::Byte[nElements];
1791 sri::Marshal::Copy( (void*) &seq->elements, arByte, 0, nElements);
1792 *cli_data= arByte;
1793 break;
1795 case typelib_TypeClass_SHORT:
1797 System::Int16 arShort[]= new System::Int16[nElements];
1798 sri::Marshal::Copy( (void*) &seq->elements, arShort, 0, nElements);
1799 *cli_data= arShort;
1800 break;
1802 case typelib_TypeClass_UNSIGNED_SHORT:
1804 System::UInt16 arUInt16[]= new System::UInt16[nElements];
1805 sri::Marshal::Copy( (void*) &seq->elements, static_cast<System::Int16[]>(arUInt16),
1806 0, nElements);
1807 *cli_data= arUInt16;
1808 break;
1810 case typelib_TypeClass_LONG:
1812 System::Int32 arInt32[]= new System::Int32[nElements];
1813 sri::Marshal::Copy( (void*) &seq->elements, arInt32, 0, nElements);
1814 *cli_data= arInt32;
1815 break;
1817 case typelib_TypeClass_UNSIGNED_LONG:
1819 System::UInt32 arUInt32[]= new System::UInt32[nElements];
1820 sri::Marshal::Copy( (void*) &seq->elements, static_cast<System::Int32[]>(arUInt32),
1821 0, nElements);
1822 *cli_data= arUInt32;
1823 break;
1825 case typelib_TypeClass_HYPER:
1827 System::Int64 arInt64[]= new System::Int64[nElements];
1828 sri::Marshal::Copy( (void*) &seq->elements, arInt64, 0, nElements);
1829 *cli_data= arInt64;
1830 break;
1832 case typelib_TypeClass_UNSIGNED_HYPER:
1834 System::UInt64 arUInt64[]= new System::UInt64[nElements];
1835 sri::Marshal::Copy( (void*) &seq->elements, arUInt64, 0, nElements);
1836 *cli_data= arUInt64;
1837 break;
1839 case typelib_TypeClass_FLOAT:
1841 System::Single arSingle[]= new System::Single[nElements];
1842 sri::Marshal::Copy( (void*) &seq->elements, arSingle, 0, nElements);
1843 *cli_data= arSingle;
1844 break;
1846 case typelib_TypeClass_DOUBLE:
1848 System::Double arDouble[]= new System::Double[nElements];
1849 sri::Marshal::Copy( (void*) &seq->elements, arDouble, 0, nElements);
1850 *cli_data= arDouble;
1851 break;
1853 case typelib_TypeClass_STRING:
1855 System::String* arString[]= new System::String*[nElements];
1856 for (int i= 0; i < nElements; i++)
1858 rtl_uString *aStr= ((rtl_uString**)(&seq->elements))[i];
1859 arString[i]= new System::String( (__wchar_t *) &aStr->buffer, 0, aStr->length);
1861 *cli_data= arString;
1862 break;
1864 case typelib_TypeClass_TYPE:
1866 System::Type* arType[]= new System::Type*[nElements];
1867 for (int i= 0; i < nElements; i++)
1869 arType[i]=
1870 mapUnoType( ((typelib_TypeDescriptionReference**) seq->elements)[i]);
1872 *cli_data= arType;
1873 break;
1875 case typelib_TypeClass_ANY:
1877 uno::Any arCli[]= new uno::Any[nElements];
1878 uno_Any const * p = (uno_Any const *)seq->elements;
1879 for (sal_Int32 nPos = 0; nPos < nElements; ++nPos )
1881 System::Object* cli_obj = NULL;
1882 map_to_cli(
1883 &cli_obj, &p[ nPos ], element_type, 0, false);
1884 arCli[nPos]= *__try_cast<__box uno::Any*>(cli_obj);
1886 *cli_data= arCli;
1887 break;
1889 case typelib_TypeClass_ENUM:
1891 //get the Enum type
1892 System::Type* enumType= NULL;
1893 if (info != NULL)
1895 //info is EnumType[]&, remove &
1896 OSL_ASSERT(info->IsByRef);
1897 enumType = info->GetElementType();
1898 //enumType is EnumType[], remove []
1899 enumType = enumType->GetElementType();
1901 else
1902 enumType= mapUnoType(element_type);
1904 System::Array* arEnum = System::Array::CreateInstance(
1905 enumType, nElements);
1906 for (int i= 0; i < nElements; i++)
1908 arEnum->SetValue(System::Enum::ToObject(enumType,
1909 ((sal_Int32*) seq->elements)[i]), i);
1911 *cli_data = arEnum;
1912 break;
1914 case typelib_TypeClass_STRUCT:
1915 case typelib_TypeClass_EXCEPTION:
1917 TypeDescr element_td( element_type );
1918 System::Array* ar= System::Array::CreateInstance(
1919 mapUnoType(element_type),nElements);
1920 if (0 < nElements)
1922 // ToDo check this
1923 char * p = (char *) &seq->elements;
1924 sal_Int32 nSize = element_td.get()->nSize;
1925 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
1927 System::Object* val;
1928 map_to_cli(
1929 &val, p + (nSize * nPos), element_type, 0, false);
1930 ar->SetValue(val, nPos);
1933 *cli_data = ar;
1934 break;
1936 // ToDo, verify
1937 case typelib_TypeClass_SEQUENCE:
1939 System::Array *ar= System::Array::CreateInstance(
1940 mapUnoType(element_type), nElements);
1941 if (0 < nElements)
1943 TypeDescr element_td( element_type );
1944 uno_Sequence ** elements = (uno_Sequence**) seq->elements;
1945 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
1947 System::Object* val;
1948 map_to_cli(
1949 &val, &elements[nPos], element_type, 0, false);
1950 ar->SetValue(val, nPos);
1953 *cli_data = ar;
1954 break;
1956 case typelib_TypeClass_INTERFACE:
1958 TypeDescr element_td( element_type );
1959 System::Type * ifaceType= mapUnoType(element_type);
1960 System::Array* ar= System::Array::CreateInstance(ifaceType, nElements);
1962 char * p = (char *)seq->elements;
1963 sal_Int32 nSize = element_td.get()->nSize;
1964 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
1966 System::Object* val;
1967 map_to_cli(
1968 &val, p + (nSize * nPos), element_type, NULL, false);
1970 ar->SetValue(val, nPos);
1972 *cli_data= ar;
1973 break;
1975 default:
1977 OUStringBuffer buf( 128 );
1978 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_cli():") );
1979 buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName ) );
1980 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] unsupported element type: ") );
1981 buf.append( *reinterpret_cast< OUString const * >( &element_type->pTypeName ) );
1982 throw BridgeRuntimeError( buf.makeStringAndClear() );
1985 break;
1987 case typelib_TypeClass_INTERFACE:
1989 uno_Interface * pUnoI = *(uno_Interface * const *)uno_data;
1990 if (0 != pUnoI)
1992 TypeDescr td( type );
1993 *cli_data= map_uno2cli( pUnoI, reinterpret_cast<
1994 typelib_InterfaceTypeDescription*>(td.get())) ;
1996 else
1997 *cli_data= NULL;
1998 break;
2000 default:
2002 //ToDo check this exception. The String is probably crippled
2003 OUStringBuffer buf( 128 );
2004 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_cli():") );
2005 buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName ) );
2006 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] unsupported type!") );
2007 throw BridgeRuntimeError( buf.makeStringAndClear() );