merge the formfield patch from ooo-build
[ooovba.git] / cli_ure / source / uno_bridge / cli_data.cxx
blob3e3eba33c460f943c6550c87e1880cfcecb747c5
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: cli_data.cxx,v $
10 * $Revision: 1.4 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_cli_ure.hxx"
34 #pragma warning(push, 1)
35 #include "windows.h"
36 #pragma warning(pop)
38 #include <memory>
41 #include "rtl/ustring.hxx"
42 #include "rtl/ustrbuf.hxx"
43 #include "uno/sequence2.h"
44 #include "typelib/typedescription.hxx"
45 #include "cli_proxy.h"
46 #include "cli_base.h"
47 #include "cli_bridge.h"
49 #using <cli_uretypes.dll>
52 #undef VOID
54 namespace css = com::sun::star;
56 namespace sri = System::Runtime::InteropServices;
57 namespace sr = System::Reflection;
58 namespace st = System::Text;
59 namespace ucss = unoidl::com::sun::star;
61 using namespace rtl;
62 using namespace std;
65 namespace cli_uno
67 System::String* mapUnoPolymorphicName(System::String* unoName);
68 OUString mapCliTypeName(System::String* typeName);
69 System::String* mapCliPolymorphicName(System::String* unoName);
70 System::String* mapPolymorphicName(System::String* unoName, bool bCliToUno);
72 inline auto_ptr< rtl_mem > seq_allocate( sal_Int32 nElements, sal_Int32 nSize )
74 auto_ptr< rtl_mem > seq(
75 rtl_mem::allocate( SAL_SEQUENCE_HEADER_SIZE + (nElements * nSize) ) );
76 uno_Sequence * p = (uno_Sequence *)seq.get();
77 p->nRefCount = 1;
78 p->nElements = nElements;
79 return seq;
83 System::Object* Bridge::map_uno2cli(uno_Interface * pUnoI, typelib_InterfaceTypeDescription *pTD) const
85 System::Object* retVal= NULL;
86 // get oid
87 rtl_uString * pOid = 0;
88 (*m_uno_env->getObjectIdentifier)( m_uno_env, &pOid, pUnoI );
89 OSL_ASSERT( 0 != pOid );
90 OUString oid(pOid, SAL_NO_ACQUIRE);
92 //see if the interface was already mapped
93 System::Type* ifaceType= mapUnoType(reinterpret_cast<typelib_TypeDescription*>(pTD));
94 System::String* sOid= mapUnoString(oid.pData);
96 System::Threading::Monitor::Enter( CliEnvHolder::g_cli_env );
97 try
99 retVal = CliEnvHolder::g_cli_env->getRegisteredInterface(sOid, ifaceType);
100 if (retVal)
102 // There is already an registered object. It can either be a proxy
103 // for the UNO object or a real cli object. In the first case we
104 // tell the proxy that it shall also represent the current UNO
105 // interface. If it already does that, then it does nothing
106 if (srr::RemotingServices::IsTransparentProxy(retVal))
108 UnoInterfaceProxy* p = static_cast<UnoInterfaceProxy*>(
109 srr::RemotingServices::GetRealProxy(retVal));
110 p->addUnoInterface(pUnoI, pTD);
113 else
115 retVal = UnoInterfaceProxy::create(
116 (Bridge *) this, pUnoI, pTD, oid );
119 __finally
121 System::Threading::Monitor::Exit( CliEnvHolder::g_cli_env );
124 return retVal;
127 uno_Interface* Bridge::map_cli2uno(System::Object* cliObj, typelib_TypeDescription *pTD) const
129 uno_Interface* retIface = NULL;
130 // get oid from dot net environment
131 System::String* ds_oid = CliEnvHolder::g_cli_env->getObjectIdentifier( cliObj);
132 OUString ousOid = mapCliString(ds_oid);
133 // look if interface is already mapped
134 m_uno_env->getRegisteredInterface(m_uno_env, (void**) &retIface, ousOid.pData,
135 (typelib_InterfaceTypeDescription*) pTD);
136 if ( ! retIface)
138 System::Threading::Monitor::Enter(__typeof(Cli_environment));
141 m_uno_env->getRegisteredInterface(m_uno_env, (void**) &retIface, ousOid.pData,
142 (typelib_InterfaceTypeDescription*) pTD);
143 if ( ! retIface)
145 retIface = CliProxy::create((Bridge*)this, cliObj, pTD, ousOid);
148 __finally
150 System::Threading::Monitor::Exit(__typeof(Cli_environment));
153 return retIface;
156 inline System::Type* loadCliType(rtl_uString * unoName)
158 return loadCliType(mapUnoTypeName(unoName));
161 System::Type* loadCliType(System::String * unoName)
163 System::Type* retVal= NULL;
166 //If unoName denotes a polymorphic type, e.g com.sun.star.beans.Defaulted<System.Char>
167 //then we remove the type list, otherwise the type could not be loaded.
168 bool bIsPolymorphic = false;
170 System::String * loadName = unoName;
171 int index = unoName->IndexOf('<');
172 if (index != -1)
174 loadName = unoName->Substring(0, index);
175 bIsPolymorphic = true;
177 System::AppDomain* currentDomain = System::AppDomain::CurrentDomain;
178 sr::Assembly* assems[] = currentDomain->GetAssemblies();
179 for (int i = 0; i < assems->Length; i++)
181 retVal = assems[i]->GetType(loadName, false);
182 if (retVal)
183 break;
186 if (retVal == NULL)
188 System::String * msg = new System::String(S"A type could not be loaded: ");
189 msg = System::String::Concat(msg, loadName);
190 throw BridgeRuntimeError(mapCliString(msg));
193 if (bIsPolymorphic)
195 retVal = uno::PolymorphicType::GetType(retVal, unoName);
198 catch( System::Exception * e)
200 rtl::OUString ouMessage(mapCliString(e->get_Message()));
201 throw BridgeRuntimeError(ouMessage);
203 return retVal;
207 System::Type* mapUnoType(typelib_TypeDescription const * pTD)
209 return mapUnoType(pTD->pWeakRef);
212 System::Type* mapUnoType(typelib_TypeDescriptionReference const * pTD)
214 System::Type * retVal = 0;
215 switch (pTD->eTypeClass)
217 case typelib_TypeClass_VOID:
218 retVal= __typeof(void); break;
219 case typelib_TypeClass_CHAR:
220 retVal= __typeof(System::Char); break;
221 case typelib_TypeClass_BOOLEAN:
222 retVal= __typeof(System::Boolean); break;
223 case typelib_TypeClass_BYTE:
224 retVal= __typeof(System::Byte); break;
225 case typelib_TypeClass_SHORT:
226 retVal= __typeof(System::Int16); break;
227 case typelib_TypeClass_UNSIGNED_SHORT:
228 retVal= __typeof(System::UInt16); break;
229 case typelib_TypeClass_LONG:
230 retVal= __typeof(System::Int32); break;
231 case typelib_TypeClass_UNSIGNED_LONG:
232 retVal= __typeof(System::UInt32); break;
233 case typelib_TypeClass_HYPER:
234 retVal= __typeof(System::Int64); break;
235 case typelib_TypeClass_UNSIGNED_HYPER:
236 retVal= __typeof(System::UInt64); break;
237 case typelib_TypeClass_FLOAT:
238 retVal= __typeof(System::Single); break;
239 case typelib_TypeClass_DOUBLE:
240 retVal= __typeof(System::Double); break;
241 case typelib_TypeClass_STRING:
242 retVal= __typeof(System::String); break;
243 case typelib_TypeClass_TYPE:
244 retVal= __typeof(System::Type); break;
245 case typelib_TypeClass_ANY:
246 retVal= __typeof(uno::Any); break;
247 case typelib_TypeClass_ENUM:
248 case typelib_TypeClass_STRUCT:
249 case typelib_TypeClass_EXCEPTION:
250 retVal= loadCliType(pTD->pTypeName); break;
251 case typelib_TypeClass_INTERFACE:
253 //special handling for XInterface, since it does not exist in cli.
254 rtl::OUString usXInterface(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.XInterface"));
255 if (usXInterface.equals(pTD->pTypeName))
256 retVal= __typeof(System::Object);
257 else
258 retVal= loadCliType(pTD->pTypeName);
259 break;
261 case typelib_TypeClass_SEQUENCE:
263 css::uno::TypeDescription seqType(
264 const_cast<typelib_TypeDescriptionReference*>(pTD));
265 typelib_TypeDescriptionReference* pElementTDRef=
266 reinterpret_cast<typelib_IndirectTypeDescription*>(seqType.get())->pType;
267 switch (pElementTDRef->eTypeClass)
269 case typelib_TypeClass_CHAR:
270 retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArChar)); break;
271 case typelib_TypeClass_BOOLEAN:
272 retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArBoolean));
273 break;
274 case typelib_TypeClass_BYTE:
275 retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArByte));
276 break;
277 case typelib_TypeClass_SHORT:
278 retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArInt16));
279 break;
280 case typelib_TypeClass_UNSIGNED_SHORT:
281 retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArUInt16));
282 break;
283 case typelib_TypeClass_LONG:
284 retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArInt32));
285 break;
286 case typelib_TypeClass_UNSIGNED_LONG:
287 retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArUInt32));
288 break;
289 case typelib_TypeClass_HYPER:
290 retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArInt64));
291 break;
292 case typelib_TypeClass_UNSIGNED_HYPER:
293 retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArUInt64));
294 break;
295 case typelib_TypeClass_FLOAT:
296 retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArSingle));
297 break;
298 case typelib_TypeClass_DOUBLE:
299 retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArDouble));
300 break;
301 case typelib_TypeClass_STRING:
302 retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArString));
303 break;
304 case typelib_TypeClass_TYPE:
305 retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArType));
306 break;
307 case typelib_TypeClass_ANY:
308 case typelib_TypeClass_ENUM:
309 case typelib_TypeClass_EXCEPTION:
310 case typelib_TypeClass_STRUCT:
311 case typelib_TypeClass_INTERFACE:
312 case typelib_TypeClass_SEQUENCE:
314 retVal= loadCliType(pTD->pTypeName);
315 break;
317 default:
318 //All cases should be handled by the case statements above
319 OSL_ASSERT(0);
320 break;
322 break;
324 default:
325 OSL_ASSERT(false);
326 break;
328 return retVal;
331 /** Returns an acquired td.
333 typelib_TypeDescriptionReference* mapCliType(System::Type* cliType)
335 typelib_TypeDescriptionReference* retVal= NULL;
336 if (cliType == NULL)
338 retVal = * typelib_static_type_getByTypeClass(
339 typelib_TypeClass_VOID );
340 typelib_typedescriptionreference_acquire( retVal );
341 return retVal;
343 //check for Enum first,
344 //because otherwise case System::TypeCode::Int32 applies
345 if (cliType->get_IsEnum())
347 OUString usTypeName= mapCliTypeName(cliType->get_FullName());
348 css::uno::Type unoType(css::uno::TypeClass_ENUM, usTypeName);
349 retVal= unoType.getTypeLibType();
350 typelib_typedescriptionreference_acquire(retVal);
352 else
354 switch (System::Type::GetTypeCode(cliType))
356 case System::TypeCode::Boolean:
357 retVal = * typelib_static_type_getByTypeClass(
358 typelib_TypeClass_BOOLEAN );
359 typelib_typedescriptionreference_acquire( retVal );
360 break;
361 case System::TypeCode::Char:
362 retVal = * typelib_static_type_getByTypeClass(
363 typelib_TypeClass_CHAR );
364 typelib_typedescriptionreference_acquire( retVal );
365 break;
366 case System::TypeCode::Byte:
367 retVal = * typelib_static_type_getByTypeClass(
368 typelib_TypeClass_BYTE );
369 typelib_typedescriptionreference_acquire( retVal );
370 break;
371 case System::TypeCode::Int16:
372 retVal = * typelib_static_type_getByTypeClass(
373 typelib_TypeClass_SHORT );
374 typelib_typedescriptionreference_acquire( retVal );
375 break;
376 case System::TypeCode::Int32:
377 retVal = * typelib_static_type_getByTypeClass(
378 typelib_TypeClass_LONG );
379 typelib_typedescriptionreference_acquire( retVal );
380 break;
381 case System::TypeCode::Int64:
382 retVal = * typelib_static_type_getByTypeClass(
383 typelib_TypeClass_HYPER );
384 typelib_typedescriptionreference_acquire( retVal );
385 break;
386 case System::TypeCode::UInt16:
387 retVal = * typelib_static_type_getByTypeClass(
388 typelib_TypeClass_UNSIGNED_SHORT );
389 typelib_typedescriptionreference_acquire( retVal );
390 break;
391 case System::TypeCode::UInt32:
392 retVal = * typelib_static_type_getByTypeClass(
393 typelib_TypeClass_UNSIGNED_LONG );
394 typelib_typedescriptionreference_acquire( retVal );
395 break;
396 case System::TypeCode::UInt64:
397 retVal = * typelib_static_type_getByTypeClass(
398 typelib_TypeClass_UNSIGNED_HYPER );
399 typelib_typedescriptionreference_acquire( retVal );
400 break;
401 case System::TypeCode::Single:
402 retVal = * typelib_static_type_getByTypeClass(
403 typelib_TypeClass_FLOAT );
404 typelib_typedescriptionreference_acquire( retVal );
405 break;
406 case System::TypeCode::Double:
407 retVal = * typelib_static_type_getByTypeClass(
408 typelib_TypeClass_DOUBLE );
409 typelib_typedescriptionreference_acquire( retVal );
410 break;
411 case System::TypeCode::String:
412 retVal = * typelib_static_type_getByTypeClass(
413 typelib_TypeClass_STRING );
414 typelib_typedescriptionreference_acquire( retVal );
415 break;
416 default:
417 break;
420 if (retVal == NULL)
422 System::String* cliTypeName= cliType->get_FullName();
423 // Void
424 if (const_cast<System::String*>(Constants::sVoid)->Equals(
425 cliTypeName))
427 retVal = * typelib_static_type_getByTypeClass(
428 typelib_TypeClass_VOID );
429 typelib_typedescriptionreference_acquire( retVal );
431 // Type
432 else if (const_cast<System::String*>(Constants::sType)->Equals(
433 cliTypeName))
435 retVal = * typelib_static_type_getByTypeClass(
436 typelib_TypeClass_TYPE );
437 typelib_typedescriptionreference_acquire( retVal );
439 // Any
440 else if (const_cast<System::String*>(Constants::sAny)->Equals(
441 cliTypeName))
443 retVal = * typelib_static_type_getByTypeClass(
444 typelib_TypeClass_ANY );
445 typelib_typedescriptionreference_acquire( retVal );
447 //struct, interfaces, sequences
448 else
450 OUString usTypeName;
451 uno::PolymorphicType * poly = dynamic_cast<uno::PolymorphicType*>(cliType);
452 if (poly != NULL)
453 usTypeName = mapCliTypeName( poly->PolymorphicName);
454 else
455 usTypeName = mapCliTypeName(cliTypeName);
456 typelib_TypeDescription* td = NULL;
457 typelib_typedescription_getByName(&td, usTypeName.pData);
458 if (td)
460 retVal = td->pWeakRef;
461 typelib_typedescriptionreference_acquire(retVal);
462 typelib_typedescription_release(td);
466 if (retVal == NULL)
468 OUStringBuffer buf( 128 );
469 buf.appendAscii(
470 RTL_CONSTASCII_STRINGPARAM("[cli_uno bridge] mapCliType():"
471 "could not map type: ") );
472 buf.append(mapCliString(cliType->get_FullName()));
473 throw BridgeRuntimeError( buf.makeStringAndClear() );
475 return retVal;
478 /**
479 Otherwise a leading "unoidl." is removed.
481 System::String* mapUnoTypeName(rtl_uString const * typeName)
483 OUString usUnoName( const_cast< rtl_uString * >( typeName ) );
484 st::StringBuilder* buf= new st::StringBuilder();
485 //determine if the type is a sequence and its dimensions
486 int dims= 0;
487 if (usUnoName[0] == '[')
489 sal_Int32 index= 1;
490 while (true)
492 if (usUnoName[index++] == ']')
493 dims++;
494 if (usUnoName[index++] != '[')
495 break;
497 usUnoName = usUnoName.copy(index - 1);
499 System::String * sUnoName = mapUnoString(usUnoName.pData);
500 if (sUnoName->Equals(const_cast<System::String*>(Constants::usBool)))
501 buf->Append(const_cast<System::String*>(Constants::sBoolean));
502 else if (sUnoName->Equals(const_cast<System::String*>(Constants::usChar)))
503 buf->Append(const_cast<System::String*>(Constants::sChar));
504 else if (sUnoName->Equals(const_cast<System::String*>(Constants::usByte)))
505 buf->Append(const_cast<System::String*>(Constants::sByte));
506 else if (sUnoName->Equals(const_cast<System::String*>(Constants::usShort)))
507 buf->Append(const_cast<System::String*>(Constants::sInt16));
508 else if (sUnoName->Equals(const_cast<System::String*>(Constants::usUShort)))
509 buf->Append(const_cast<System::String*>(Constants::sUInt16));
510 else if (sUnoName->Equals(const_cast<System::String*>(Constants::usLong)))
511 buf->Append(const_cast<System::String*>(Constants::sInt32));
512 else if (sUnoName->Equals(const_cast<System::String*>(Constants::usULong)))
513 buf->Append(const_cast<System::String*>(Constants::sUInt32));
514 else if (sUnoName->Equals(const_cast<System::String*>(Constants::usHyper)))
515 buf->Append(const_cast<System::String*>(Constants::sInt64));
516 else if (sUnoName->Equals(const_cast<System::String*>(Constants::usUHyper)))
517 buf->Append(const_cast<System::String*>(Constants::sUInt64));
518 else if (sUnoName->Equals(const_cast<System::String*>(Constants::usFloat)))
519 buf->Append(const_cast<System::String*>(Constants::sSingle));
520 else if (sUnoName->Equals(const_cast<System::String*>(Constants::usDouble)))
521 buf->Append(const_cast<System::String*>(Constants::sDouble));
522 else if (sUnoName->Equals(const_cast<System::String*>(Constants::usString)))
523 buf->Append(const_cast<System::String*>(Constants::sString));
524 else if (sUnoName->Equals(const_cast<System::String*>(Constants::usVoid)))
525 buf->Append(const_cast<System::String*>(Constants::sVoid));
526 else if (sUnoName->Equals(const_cast<System::String*>(Constants::usType)))
527 buf->Append(const_cast<System::String*>(Constants::sType));
528 else if (sUnoName->Equals(const_cast<System::String*>(Constants::usXInterface)))
529 buf->Append(const_cast<System::String*>(Constants::sObject));
530 else if (sUnoName->Equals(const_cast<System::String*>(Constants::usAny)))
532 buf->Append(const_cast<System::String*>(Constants::sAny));
534 else
536 //put "unoidl." at the beginning
537 buf->Append(const_cast<System::String*>(Constants::sUnoidl));
538 //for polymorphic struct types remove the brackets, e.g mystruct<bool> -> mystruct
539 System::String * sName = mapUnoPolymorphicName(sUnoName);
540 buf->Append(sName);
542 // apend []
543 for (;dims--;)
544 buf->Append(const_cast<System::String*>(Constants::sBrackets));
546 return buf->ToString();
552 /** For example, there is a uno type
553 com.sun.star.Foo<char, long>.
554 The values in the type list
555 are uno types and are replaced by cli types, such as System.Char,
556 System.Int32, etc.
557 The präfix unoidl is not added.
559 inline System::String* mapUnoPolymorphicName(System::String* unoName)
561 return mapPolymorphicName(unoName, false);
563 /** For example, there is a type name such as
564 com.sun.star.Foo<System.Char, System.Int32>.
565 The values in the type list
566 are CLI types and are replaced by uno types, such as char,
567 long, etc.
568 The präfix unoidl remains.
570 inline System::String* mapCliPolymorphicName(System::String* unoName)
572 return mapPolymorphicName(unoName, true);
575 System::String* mapPolymorphicName(System::String* unoName, bool bCliToUno)
577 int index = unoName->IndexOf('<');
578 if (index == -1)
579 return unoName;
581 System::Text::StringBuilder * builder = new System::Text::StringBuilder(256);
582 builder->Append(unoName->Substring(0, index +1 ));
584 //Find the first occurrence of ','
585 //If the parameter is a polymorphic struct then we neede to ignore everything
586 //between the brackets because it can also contain commas
587 //get the type list within < and >
588 int endIndex = unoName->Length - 1;
589 index++;
590 int cur = index;
591 int countParams = 0;
592 while (cur <= endIndex)
594 System::Char c = unoName->Chars[cur];
595 if (c == ',' || c == '>')
597 //insert a comma if needed
598 if (countParams != 0)
599 builder->Append(S",");
600 countParams++;
601 System::String * sParam = unoName->Substring(index, cur - index);
602 //skip the comma
603 cur++;
604 //the the index to the beginning of the next param
605 index = cur;
606 if (bCliToUno)
608 builder->Append(mapCliTypeName(sParam));
610 else
612 OUString s = mapCliString(sParam);
613 builder->Append(mapUnoTypeName(s.pData));
616 else if (c == '<')
618 cur++;
619 //continue until the matching '>'
620 int numNested = 0;
621 for (;;cur++)
623 System::Char curChar = unoName->Chars[cur];
624 if (curChar == '<')
626 numNested ++;
628 else if (curChar == '>')
630 if (numNested > 0)
631 numNested--;
632 else
633 break;
637 cur++;
640 builder->Append((System::Char) '>');
641 return builder->ToString();
644 OUString mapCliTypeName(System::String* typeName)
646 int dims= 0;
647 // Array? determine the "rank" (number of "[]")
648 // move from the rightmost end to the left, for example
649 // unoidl.PolymorphicStruct<System.Char[]>[]
650 // has only a "dimension" of 1
651 int cur = typeName->Length - 1;
652 bool bRightBracket = false;
653 while (cur >= 0)
655 System::Char c = typeName->Chars[cur];
656 if (c == ']')
658 bRightBracket = true;
660 else if (c == '[')
662 if (!bRightBracket)
663 throw BridgeRuntimeError(
664 OUSTR("Typename is wrong. No matching brackets for sequence. Name is: ") +
665 mapCliString(typeName));
666 bRightBracket = false;
667 dims ++;
669 else
671 if (bRightBracket)
672 throw BridgeRuntimeError(
673 OUSTR("Typename is wrong. No matching brackets for sequence. Name is: ") +
674 mapCliString(typeName));
675 break;
677 cur--;
680 if (bRightBracket || cur < 0)
681 throw BridgeRuntimeError(
682 OUSTR("Typename is wrong. ") +
683 mapCliString(typeName));
685 typeName = typeName->Substring(0, cur + 1);
687 System::Text::StringBuilder * buf = new System::Text::StringBuilder(512);
689 //Put the "[]" at the beginning of the uno type name
690 for (;dims--;)
691 buf->Append(const_cast<System::String*>(Constants::usBrackets));
693 if (typeName->Equals(const_cast<System::String*>(Constants::sBoolean)))
694 buf->Append(const_cast<System::String*>(Constants::usBool));
695 else if (typeName->Equals(const_cast<System::String*>(Constants::sChar)))
696 buf->Append(const_cast<System::String*>(Constants::usChar));
697 else if (typeName->Equals(const_cast<System::String*>(Constants::sByte)))
698 buf->Append(const_cast<System::String*>(Constants::usByte));
699 else if (typeName->Equals(const_cast<System::String*>(Constants::sInt16)))
700 buf->Append(const_cast<System::String*>(Constants::usShort));
701 else if (typeName->Equals(const_cast<System::String*>(Constants::sUInt16)))
702 buf->Append(const_cast<System::String*>(Constants::usUShort));
703 else if (typeName->Equals(const_cast<System::String*>(Constants::sInt32)))
704 buf->Append(const_cast<System::String*>(Constants::usLong));
705 else if (typeName->Equals(const_cast<System::String*>(Constants::sUInt32)))
706 buf->Append(const_cast<System::String*>(Constants::usULong));
707 else if (typeName->Equals(const_cast<System::String*>(Constants::sInt64)))
708 buf->Append(const_cast<System::String*>(Constants::usHyper));
709 else if (typeName->Equals(const_cast<System::String*>(Constants::sUInt64)))
710 buf->Append(const_cast<System::String*>(Constants::usUHyper));
711 else if (typeName->Equals(const_cast<System::String*>(Constants::sSingle)))
712 buf->Append(const_cast<System::String*>(Constants::usFloat));
713 else if (typeName->Equals(const_cast<System::String*>(Constants::sDouble)))
714 buf->Append(const_cast<System::String*>(Constants::usDouble));
715 else if (typeName->Equals(const_cast<System::String*>(Constants::sString)))
716 buf->Append(const_cast<System::String*>(Constants::usString));
717 else if (typeName->Equals(const_cast<System::String*>(Constants::sVoid)))
718 buf->Append(const_cast<System::String*>(Constants::usVoid));
719 else if (typeName->Equals(const_cast<System::String*>(Constants::sType)))
720 buf->Append(const_cast<System::String*>(Constants::usType));
721 else if (typeName->Equals(const_cast<System::String*>(Constants::sObject)))
722 buf->Append(const_cast<System::String*>(Constants::usXInterface));
723 else if (typeName->Equals(const_cast<System::String*>(Constants::sAny)))
724 buf->Append(const_cast<System::String*>(Constants::usAny));
725 else
727 System::String * sName = mapCliPolymorphicName(typeName);
728 int i= sName->IndexOf(L'.');
729 buf->Append(sName->Substring(i + 1));
731 return mapCliString(buf->ToString());
733 /** Maps uno types to dot net types.
734 * If uno_data is null then the type description is converted to System::Type
736 inline System::String* mapUnoString( rtl_uString const * data)
738 OSL_ASSERT(data);
739 return new System::String((__wchar_t*) data->buffer, 0, data->length);
742 OUString mapCliString(System::String const * data)
745 if (data != NULL)
747 OSL_ASSERT(sizeof(wchar_t) == sizeof(sal_Unicode));
748 wchar_t const __pin * pdata= PtrToStringChars(data);
749 return OUString(pdata, const_cast<System::String*>(data)->get_Length());
751 else
753 return OUString();
757 // ToDo convert cli types to expected types, e.g a long to a short where the uno type
758 // is a sal_Int16. This could be necessary if a scripting language (typeless) is used
759 // @param assign the uno_data has to be destructed (in/out args)
760 void Bridge::map_to_uno(void * uno_data, System::Object* cli_data,
761 typelib_TypeDescriptionReference * type,
762 bool assign) const
764 try{
765 switch (type->eTypeClass)
767 case typelib_TypeClass_VOID:
768 break;
769 case typelib_TypeClass_CHAR:
771 System::Char aChar= *__try_cast<System::Char*>(cli_data);
772 *(sal_Unicode*) uno_data= aChar;
773 break;
775 case typelib_TypeClass_BOOLEAN:
777 System::Boolean aBool= *__try_cast<System::Boolean*>(cli_data);
778 *(sal_Bool*)uno_data= aBool == true ? sal_True : sal_False;
779 break;
781 case typelib_TypeClass_BYTE:
783 System::Byte aByte= *__try_cast<System::Byte*>(cli_data);
784 *(sal_Int8*) uno_data= aByte;
785 break;
787 case typelib_TypeClass_SHORT:
789 System::Int16 aShort= *__try_cast<System::Int16*>(cli_data);
790 *(sal_Int16*) uno_data= aShort;
791 break;
793 case typelib_TypeClass_UNSIGNED_SHORT:
795 System::UInt16 aUShort= *__try_cast<System::UInt16*>(cli_data);
796 *(sal_uInt16*) uno_data= aUShort;
797 break;
799 case typelib_TypeClass_LONG:
801 System::Int32 aLong= *__try_cast<System::Int32*>(cli_data);
802 *(sal_Int32*) uno_data= aLong;
803 break;
805 case typelib_TypeClass_UNSIGNED_LONG:
807 System::UInt32 aULong= *__try_cast<System::UInt32*>(cli_data);
808 *(sal_uInt32*) uno_data= aULong;
809 break;
811 case typelib_TypeClass_HYPER:
813 System::Int64 aHyper= *__try_cast<System::Int64*>(cli_data);
814 *(sal_Int64*) uno_data= aHyper;
815 break;
817 case typelib_TypeClass_UNSIGNED_HYPER:
819 System::UInt64 aLong= *__try_cast<System::UInt64*>(cli_data);
820 *(sal_uInt64*) uno_data= aLong;
821 break;
823 case typelib_TypeClass_FLOAT:
825 System::Single aFloat= *__try_cast<System::Single*>(cli_data);
826 *(float*) uno_data= aFloat;
827 break;
829 case typelib_TypeClass_DOUBLE:
831 System::Double aDouble= *__try_cast<System::Double*>(cli_data);
832 *(double*) uno_data= aDouble;
833 break;
835 case typelib_TypeClass_STRING:
837 if (assign && *(rtl_uString**) uno_data)
838 rtl_uString_release(*(rtl_uString**) uno_data);
840 *(rtl_uString **)uno_data = 0;
841 if (cli_data == NULL)
843 rtl_uString_new((rtl_uString**) uno_data);
845 else
847 System::String *s= __try_cast<System::String*>(cli_data);
848 wchar_t const __pin * pdata= PtrToStringChars(s);
849 rtl_uString_newFromStr_WithLength( (rtl_uString**) uno_data,
850 pdata, s->get_Length() );
852 break;
854 case typelib_TypeClass_TYPE:
856 typelib_TypeDescriptionReference* td= mapCliType(__try_cast<System::Type*>(
857 cli_data));
858 if (assign)
860 typelib_typedescriptionreference_release(
861 *(typelib_TypeDescriptionReference **)uno_data );
863 *(typelib_TypeDescriptionReference **)uno_data = td;
864 break;
866 case typelib_TypeClass_ANY:
868 uno_Any * pAny = (uno_Any *)uno_data;
869 if (cli_data == NULL) // null-ref or uninitialized any maps to empty any
871 if (assign)
872 uno_any_destruct( pAny, 0 );
873 uno_any_construct( pAny, 0, 0, 0 );
874 break;
876 uno::Any aAny= *__try_cast<uno::Any*>(cli_data);
877 css::uno::Type value_td( mapCliType(aAny.Type), SAL_NO_ACQUIRE);
879 if (assign)
880 uno_any_destruct( pAny, 0 );
884 switch (value_td.getTypeClass())
886 case typelib_TypeClass_VOID:
887 pAny->pData = &pAny->pReserved;
888 break;
889 case typelib_TypeClass_CHAR:
890 pAny->pData = &pAny->pReserved;
891 *(sal_Unicode*) &pAny->pReserved = *__try_cast<System::Char*>(aAny.Value);
892 break;
893 case typelib_TypeClass_BOOLEAN:
894 pAny->pData = &pAny->pReserved;
895 *(sal_Bool *) &pAny->pReserved = *__try_cast<System::Boolean*>(aAny.Value);
896 break;
897 case typelib_TypeClass_BYTE:
898 pAny->pData = &pAny->pReserved;
899 *(sal_Int8*) &pAny->pReserved = *__try_cast<System::Byte*>(aAny.Value);
900 break;
901 case typelib_TypeClass_SHORT:
902 pAny->pData = &pAny->pReserved;
903 *(sal_Int16*) &pAny->pReserved = *__try_cast<System::Int16*>(aAny.Value);
904 break;
905 case typelib_TypeClass_UNSIGNED_SHORT:
906 pAny->pData = &pAny->pReserved;
907 *(sal_uInt16*) &pAny->pReserved = *__try_cast<System::UInt16*>(aAny.Value);
908 break;
909 case typelib_TypeClass_LONG:
910 pAny->pData = &pAny->pReserved;
911 *(sal_Int32*) &pAny->pReserved = *__try_cast<System::Int32*>(aAny.Value);
912 break;
913 case typelib_TypeClass_UNSIGNED_LONG:
914 pAny->pData = &pAny->pReserved;
915 *(sal_uInt32*) &pAny->pReserved = *__try_cast<System::UInt32*>(aAny.Value);
916 break;
917 case typelib_TypeClass_HYPER:
918 if (sizeof (sal_Int64) <= sizeof (void *))
920 pAny->pData = &pAny->pReserved;
921 *(sal_Int64*) &pAny->pReserved = *__try_cast<System::Int64*>(aAny.Value);
923 else
925 auto_ptr< rtl_mem > mem( rtl_mem::allocate( sizeof (sal_Int64) ) );
926 *(sal_Int64 *) mem.get()= *__try_cast<System::Int64*>(aAny.Value);
927 pAny->pData = mem.release();
929 break;
930 case typelib_TypeClass_UNSIGNED_HYPER:
931 if (sizeof (sal_uInt64) <= sizeof (void *))
933 pAny->pData = &pAny->pReserved;
934 *(sal_uInt64*) &pAny->pReserved = *__try_cast<System::UInt64*>(aAny.Value);
936 else
938 auto_ptr< rtl_mem > mem( rtl_mem::allocate( sizeof (sal_uInt64) ) );
939 *(sal_uInt64 *) mem.get()= *__try_cast<System::UInt64*>(aAny.Value);
940 pAny->pData = mem.release();
942 break;
943 case typelib_TypeClass_FLOAT:
944 if (sizeof (float) <= sizeof (void *))
946 pAny->pData = &pAny->pReserved;
947 *(float*) &pAny->pReserved = *__try_cast<System::Single*>(aAny.Value);
949 else
951 auto_ptr< rtl_mem > mem( rtl_mem::allocate( sizeof (float) ) );
952 *(float*) mem.get() = *__try_cast<System::Single*>(aAny.Value);
953 pAny->pData = mem.release();
955 break;
956 case typelib_TypeClass_DOUBLE:
957 if (sizeof (double) <= sizeof (void *))
959 pAny->pData = &pAny->pReserved;
960 *(double*) &pAny->pReserved= *__try_cast<System::Double*>(aAny.Value);
962 else
964 auto_ptr< rtl_mem > mem( rtl_mem::allocate( sizeof (double) ) );
965 *(double*) mem.get()= *__try_cast<System::Double*>(aAny.Value);
966 pAny->pData= mem.release();
968 break;
969 case typelib_TypeClass_STRING: // anies often contain strings; copy string directly
971 pAny->pData= &pAny->pReserved;
972 OUString _s = mapCliString(static_cast<System::String*>(aAny.Value));
973 pAny->pReserved= _s.pData;
974 rtl_uString_acquire(_s.pData);
975 break;
977 case typelib_TypeClass_TYPE:
978 case typelib_TypeClass_ENUM: //ToDo copy enum direct
979 case typelib_TypeClass_SEQUENCE:
980 case typelib_TypeClass_INTERFACE:
981 pAny->pData = &pAny->pReserved;
982 pAny->pReserved = 0;
983 map_to_uno(
984 &pAny->pReserved, aAny.Value, value_td.getTypeLibType(),
985 false /* no assign */);
986 break;
987 case typelib_TypeClass_STRUCT:
988 case typelib_TypeClass_EXCEPTION:
990 css::uno::Type anyType(value_td);
991 typelib_TypeDescription* td= NULL;
992 anyType.getDescription(&td);
993 auto_ptr< rtl_mem > mem(rtl_mem::allocate(td->nSize));
994 typelib_typedescription_release(td);
995 map_to_uno(
996 mem.get(), aAny.Value, value_td.getTypeLibType(),
997 false /* no assign */);
998 pAny->pData = mem.release();
999 break;
1001 default:
1003 OUStringBuffer buf( 128 );
1004 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
1005 buf.append(value_td.getTypeName());
1006 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] unsupported value type of any!") );
1007 throw BridgeRuntimeError( buf.makeStringAndClear() );
1011 catch(System::InvalidCastException* )
1013 // ToDo check this
1014 if (assign)
1015 uno_any_construct( pAny, 0, 0, 0 ); // restore some valid any
1016 OUStringBuffer buf( 256 );
1017 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():Any") );
1018 buf.append(value_td.getTypeName());
1019 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("]The Any type "));
1020 buf.append(value_td.getTypeName());
1021 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" does not correspont "
1022 "to its value type: ") );
1023 if(aAny.Value != NULL)
1025 css::uno::Type td(mapCliType(aAny.Value->GetType()), SAL_NO_ACQUIRE);
1026 buf.append(td.getTypeName());
1028 if (assign)
1029 uno_any_construct( pAny, 0, 0, 0 ); // restore some valid any
1030 throw BridgeRuntimeError( buf.makeStringAndClear() );
1032 catch (BridgeRuntimeError& )
1034 if (assign)
1035 uno_any_construct( pAny, 0, 0, 0 ); // restore some valid any
1036 throw;
1038 catch (...)
1040 if (assign)
1041 uno_any_construct( pAny, 0, 0, 0 ); // restore some valid any
1042 throw;
1045 pAny->pType = value_td.getTypeLibType();
1046 typelib_typedescriptionreference_acquire(pAny->pType);
1047 break;
1049 case typelib_TypeClass_ENUM:
1051 // InvalidCastException is caught at the end of this method
1052 System::Int32 aEnum= System::Convert::ToInt32((cli_data));
1053 *(sal_Int32*) uno_data = aEnum;
1054 break;
1056 case typelib_TypeClass_STRUCT:
1057 case typelib_TypeClass_EXCEPTION:
1059 css::uno::TypeDescription td(type);
1060 typelib_CompoundTypeDescription * comp_td =
1061 (typelib_CompoundTypeDescription*) td.get();
1063 typelib_StructTypeDescription * struct_td = NULL;
1064 if (type->eTypeClass == typelib_TypeClass_STRUCT)
1065 struct_td = (typelib_StructTypeDescription*) td.get();
1067 if ( ! ((typelib_TypeDescription*) comp_td)->bComplete)
1068 ::typelib_typedescription_complete(
1069 (typelib_TypeDescription**) & comp_td );
1071 sal_Int32 nMembers = comp_td->nMembers;
1072 boolean bException= false;
1073 System::Type* cliType = NULL;
1074 if (cli_data)
1075 cliType = cli_data->GetType();
1077 if (0 != comp_td->pBaseTypeDescription)
1079 map_to_uno(
1080 uno_data, cli_data,
1081 ((typelib_TypeDescription *)comp_td->pBaseTypeDescription)->pWeakRef,
1082 assign);
1084 sal_Int32 nPos = 0;
1087 typelib_TypeDescriptionReference * member_type= NULL;
1089 rtl::OUString usUnoException(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.Exception"));
1090 for (; nPos < nMembers; ++nPos)
1092 member_type= comp_td->ppTypeRefs[nPos];
1093 #if OSL_DEBUG_LEVEL >= 2
1094 System::String* __s;
1095 sr::FieldInfo* arFields[];
1096 __s = mapUnoString(comp_td->ppMemberNames[nPos]);
1097 arFields = cliType != NULL ? cliType->GetFields() : NULL;
1098 #endif
1099 System::Object* val= NULL;
1100 if (cli_data != NULL)
1102 sr::FieldInfo* aField= cliType->GetField(
1103 mapUnoString(comp_td->ppMemberNames[nPos]));
1104 // special case for Exception.Message property
1105 // The com.sun.star.uno.Exception.Message field is mapped to the
1106 // System.Exception property. Type.GetField("Message") returns null
1107 if ( ! aField && usUnoException.equals(td.get()->pTypeName))
1108 {// get Exception.Message property
1109 rtl::OUString usMessageMember(RTL_CONSTASCII_USTRINGPARAM("Message"));
1110 if (usMessageMember.equals(comp_td->ppMemberNames[nPos]))
1112 sr::PropertyInfo* pi= cliType->GetProperty(
1113 mapUnoString(comp_td->ppMemberNames[nPos]));
1114 val= pi->GetValue(cli_data, NULL);
1116 else
1118 OUStringBuffer buf(512);
1119 buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("[map_to_uno(): Member: "));
1120 buf.append(comp_td->ppMemberNames[nPos]);
1121 throw BridgeRuntimeError(buf.makeStringAndClear());
1124 else
1126 val= aField->GetValue(cli_data);
1129 void * p = (char *) uno_data + comp_td->pMemberOffsets[ nPos ];
1130 //When using polymorphic structs then the parameterized members can be null.
1131 //Then we set a default value.
1132 bool bDefault = ((struct_td != NULL
1133 && struct_td->pParameterizedTypes != NULL
1134 && struct_td->pParameterizedTypes[nPos] == sal_True
1135 && val == NULL)
1136 || cli_data == NULL) ? true : false;
1137 switch (member_type->eTypeClass)
1139 case typelib_TypeClass_CHAR:
1140 if (bDefault)
1141 *(sal_Unicode*) p = 0;
1142 else
1143 *(sal_Unicode*) p = *__try_cast<System::Char*>(val);
1144 break;
1145 case typelib_TypeClass_BOOLEAN:
1146 if (bDefault)
1147 *(sal_Bool*) p = sal_False;
1148 else
1149 *(sal_Bool*) p = *__try_cast<System::Boolean*>(val);
1150 break;
1151 case typelib_TypeClass_BYTE:
1152 if (bDefault)
1153 *(sal_Int8*) p = 0;
1154 else
1155 *(sal_Int8*) p = *__try_cast<System::Byte*>(val);
1156 break;
1157 case typelib_TypeClass_SHORT:
1158 if (bDefault)
1159 *(sal_Int16*) p = 0;
1160 else
1161 *(sal_Int16*) p = *__try_cast<System::Int16*>(val);
1162 break;
1163 case typelib_TypeClass_UNSIGNED_SHORT:
1164 if (bDefault)
1165 *(sal_uInt16*) p = 0;
1166 else
1167 *(sal_uInt16*) p = *__try_cast<System::UInt16*>(val);
1168 break;
1169 case typelib_TypeClass_LONG:
1170 if (bDefault)
1171 *(sal_Int32*) p = 0;
1172 else
1173 *(sal_Int32*) p = *__try_cast<System::Int32*>(val);
1174 break;
1175 case typelib_TypeClass_UNSIGNED_LONG:
1176 if (bDefault)
1177 *(sal_uInt32*) p = 0;
1178 else
1179 *(sal_uInt32*) p = *__try_cast<System::UInt32*>(val);
1180 break;
1181 case typelib_TypeClass_HYPER:
1182 if (bDefault)
1183 *(sal_Int64*) p = 0;
1184 else
1185 *(sal_Int64*) p = *__try_cast<System::Int64*>(val);
1186 break;
1187 case typelib_TypeClass_UNSIGNED_HYPER:
1188 if (bDefault)
1189 *(sal_uInt64*) p = 0;
1190 else
1191 *(sal_uInt64*) p= *__try_cast<System::UInt64*>(val);
1192 break;
1193 case typelib_TypeClass_FLOAT:
1194 if (bDefault)
1195 *(float*) p = 0.;
1196 else
1197 *(float*) p = *__try_cast<System::Single*>(val);
1198 break;
1199 case typelib_TypeClass_DOUBLE:
1200 if (bDefault)
1201 *(double*) p = 0.;
1202 else
1203 *(double*) p = *__try_cast<System::Double*>(val);
1204 break;
1205 default:
1206 { // ToDo enum, should be converted here
1207 map_to_uno(p, val, member_type, assign);
1208 break;
1213 catch (BridgeRuntimeError& e)
1215 bException= true;
1216 OUStringBuffer buf(512);
1217 buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("[map_to_uno():"));
1218 if (cliType)
1220 buf.append(mapCliString(cliType->get_FullName()));
1221 buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("."));
1222 buf.append(comp_td->ppMemberNames[nPos]);
1223 buf.appendAscii(RTL_CONSTASCII_STRINGPARAM(" "));
1225 buf.append(e.m_message);
1226 throw BridgeRuntimeError(buf.makeStringAndClear());
1228 catch (System::InvalidCastException* )
1230 bException= true;
1231 OUStringBuffer buf( 256 );
1232 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
1233 if (cliType)
1235 buf.append(mapCliString(cliType->get_FullName()));
1236 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("."));
1237 buf.append(comp_td->ppMemberNames[nPos]);
1239 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] Value has not the required type."));
1240 throw BridgeRuntimeError(buf.makeStringAndClear());
1242 catch (...)
1244 OSL_ASSERT(0);
1245 bException= true;
1246 throw;
1248 __finally
1250 if (bException && !assign) // if assign then caller cleans up
1252 // cleanup the members which we have converted so far
1253 for ( sal_Int32 nCleanup = 0; nCleanup < nPos; ++nCleanup )
1255 uno_type_destructData(
1256 uno_data, comp_td->ppTypeRefs[ nCleanup ], 0 );
1258 if (0 != comp_td->pBaseTypeDescription)
1260 uno_destructData(
1261 uno_data, (typelib_TypeDescription *)comp_td->pBaseTypeDescription, 0 );
1265 break;
1267 case typelib_TypeClass_SEQUENCE:
1269 TypeDescr td( type );
1270 typelib_TypeDescriptionReference * element_type =
1271 ((typelib_IndirectTypeDescription *)td.get())->pType;
1273 auto_ptr< rtl_mem > seq;
1275 System::Array* ar = NULL;
1276 if (cli_data != NULL)
1278 ar = __try_cast<System::Array*>(cli_data);
1279 sal_Int32 nElements = ar->GetLength(0);
1283 switch (element_type->eTypeClass)
1285 case typelib_TypeClass_CHAR:
1286 seq = seq_allocate(nElements, sizeof (sal_Unicode));
1287 sri::Marshal::Copy(__try_cast<System::Char[]>(cli_data), 0,
1288 & ((uno_Sequence*) seq.get())->elements, nElements);
1289 break;
1290 case typelib_TypeClass_BOOLEAN:
1291 seq = seq_allocate(nElements, sizeof (sal_Bool));
1292 sri::Marshal::Copy(__try_cast<System::Boolean[]>(cli_data), 0,
1293 & ((uno_Sequence*) seq.get())->elements, nElements);
1294 break;
1295 case typelib_TypeClass_BYTE:
1296 seq = seq_allocate( nElements, sizeof (sal_Int8) );
1297 sri::Marshal::Copy(__try_cast<System::Byte[]>(cli_data), 0,
1298 & ((uno_Sequence*) seq.get())->elements, nElements);
1299 break;
1300 case typelib_TypeClass_SHORT:
1301 seq = seq_allocate(nElements, sizeof (sal_Int16));
1302 sri::Marshal::Copy(__try_cast<System::Int16[]>(cli_data), 0,
1303 & ((uno_Sequence*) seq.get())->elements, nElements);
1304 break;
1305 case typelib_TypeClass_UNSIGNED_SHORT:
1306 seq = seq_allocate( nElements, sizeof (sal_uInt16) );
1307 sri::Marshal::Copy(static_cast<System::Int16[]>(
1308 __try_cast<System::UInt16[]>(cli_data)), 0,
1309 & ((uno_Sequence*) seq.get())->elements, nElements);
1310 break;
1311 case typelib_TypeClass_LONG:
1312 seq = seq_allocate(nElements, sizeof (sal_Int32));
1313 sri::Marshal::Copy(__try_cast<System::Int32[]>(cli_data), 0,
1314 & ((uno_Sequence*) seq.get())->elements, nElements);
1315 break;
1316 case typelib_TypeClass_UNSIGNED_LONG:
1317 seq = seq_allocate( nElements, sizeof (sal_uInt32) );
1318 sri::Marshal::Copy(static_cast<System::Int32[]>(
1319 __try_cast<System::UInt32[]>(cli_data)), 0,
1320 & ((uno_Sequence*) seq.get())->elements, nElements);
1321 break;
1322 case typelib_TypeClass_HYPER:
1323 seq = seq_allocate(nElements, sizeof (sal_Int64));
1324 sri::Marshal::Copy(__try_cast<System::Int64[]>(cli_data), 0,
1325 & ((uno_Sequence*) seq.get())->elements, nElements);
1326 break;
1327 case typelib_TypeClass_UNSIGNED_HYPER:
1328 seq = seq_allocate(nElements, sizeof (sal_uInt64));
1329 sri::Marshal::Copy(static_cast<System::Int64[]>(
1330 __try_cast<System::UInt64[]>(cli_data)), 0,
1331 & ((uno_Sequence*) seq.get())->elements, nElements);
1332 break;
1333 case typelib_TypeClass_FLOAT:
1334 seq = seq_allocate(nElements, sizeof (float));
1335 sri::Marshal::Copy(__try_cast<System::Single[]>(cli_data), 0,
1336 & ((uno_Sequence*) seq.get())->elements, nElements);
1337 break;
1338 case typelib_TypeClass_DOUBLE:
1339 seq = seq_allocate(nElements, sizeof (double));
1340 sri::Marshal::Copy(__try_cast<System::Double[]>(cli_data), 0,
1341 & ((uno_Sequence*) seq.get())->elements, nElements);
1342 break;
1343 case typelib_TypeClass_STRING:
1345 seq = seq_allocate(nElements, sizeof (rtl_uString*));
1346 System::String* arStr[]= __try_cast<System::String*[]>(cli_data);
1347 for (int i= 0; i < nElements; i++)
1349 wchar_t const __pin * pdata= PtrToStringChars(arStr[i]);
1350 rtl_uString** pStr= & ((rtl_uString**) &
1351 ((uno_Sequence*) seq.get())->elements)[i];
1352 *pStr= NULL;
1353 rtl_uString_newFromStr_WithLength( pStr, pdata,
1354 arStr[i]->get_Length());
1356 break;
1358 case typelib_TypeClass_ENUM:
1359 seq = seq_allocate(nElements, sizeof (sal_Int32));
1360 for (int i= 0; i < nElements; i++)
1362 ((sal_Int32*) &((uno_Sequence*) seq.get())->elements)[i]=
1363 System::Convert::ToInt32(ar->GetValue(i));
1365 break;
1366 case typelib_TypeClass_TYPE:
1367 case typelib_TypeClass_ANY:
1368 case typelib_TypeClass_STRUCT:
1369 case typelib_TypeClass_EXCEPTION:
1370 case typelib_TypeClass_SEQUENCE:
1371 case typelib_TypeClass_INTERFACE:
1373 TypeDescr element_td( element_type );
1374 seq = seq_allocate( nElements, element_td.get()->nSize );
1376 for (sal_Int32 nPos = 0; nPos < nElements; ++nPos)
1380 void * p= ((uno_Sequence *) seq.get())->elements +
1381 (nPos * element_td.get()->nSize);
1382 System::Object* elemData= dynamic_cast<System::Array*>(cli_data)->GetValue(nPos);
1383 map_to_uno(
1384 p, elemData, element_td.get()->pWeakRef,
1385 false /* no assign */);
1387 catch (...)
1389 // cleanup
1390 for ( sal_Int32 nCleanPos = 0; nCleanPos < nPos; ++nCleanPos )
1392 void * p =
1393 ((uno_Sequence *)seq.get())->elements +
1394 (nCleanPos * element_td.get()->nSize);
1395 uno_destructData( p, element_td.get(), 0 );
1397 throw;
1400 break;
1402 default:
1404 OUStringBuffer buf( 128 );
1405 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
1406 buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName ) );
1407 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] unsupported sequence element type: ") );
1408 buf.append( *reinterpret_cast< OUString const * >( &element_type->pTypeName ) );
1409 throw BridgeRuntimeError( buf.makeStringAndClear() );
1413 catch (BridgeRuntimeError& e)
1415 OUStringBuffer buf( 128 );
1416 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
1417 buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName ));
1418 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] conversion failed\n "));
1419 buf.append(e.m_message);
1420 throw BridgeRuntimeError(buf.makeStringAndClear());
1422 catch (System::InvalidCastException* )
1424 // Ok, checked
1425 OUStringBuffer buf( 128 );
1426 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
1427 buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName) );
1428 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] could not convert sequence element type: ") );
1429 buf.append( *reinterpret_cast< OUString const * >( &element_type->pTypeName ) );
1430 throw BridgeRuntimeError( buf.makeStringAndClear() );
1432 catch (...)
1434 OSL_ASSERT(0);
1435 throw;
1437 __finally
1439 if (assign)
1440 uno_destructData( uno_data, td.get(), 0 );
1443 else
1445 seq = seq_allocate(0, sizeof (sal_Int32));
1447 *(uno_Sequence **)uno_data = (uno_Sequence *)seq.release();
1448 break;
1450 case typelib_TypeClass_INTERFACE:
1452 if (assign)
1454 uno_Interface * p = *(uno_Interface **)uno_data;
1455 if (0 != p)
1456 (*p->release)( p );
1458 if (0 == cli_data) // null-ref
1460 *(uno_Interface **)uno_data = 0;
1462 else
1464 TypeDescr td( type );
1465 uno_Interface * pUnoI = map_cli2uno(cli_data, td.get());
1466 *(uno_Interface **)uno_data = pUnoI;
1468 break;
1470 default:
1472 //ToDo check
1473 OUStringBuffer buf( 128 );
1474 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
1475 buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName ) );
1476 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] unsupported type!") );
1477 throw BridgeRuntimeError( buf.makeStringAndClear() );
1481 // BridgeRuntimeError are allowed to be thrown
1482 catch (System::InvalidCastException* )
1484 //ToDo check
1485 OUStringBuffer buf( 128 );
1486 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
1487 buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName ) );
1488 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] could not convert type!") );
1489 throw BridgeRuntimeError( buf.makeStringAndClear() );
1491 catch (System::NullReferenceException * e)
1493 OUStringBuffer buf(512);
1494 buf.appendAscii(RTL_CONSTASCII_STRINGPARAM(
1495 "[map_to_uno()] Illegal null reference passed!\n"));
1496 buf.append(mapCliString(e->get_StackTrace()));
1497 throw BridgeRuntimeError( buf.makeStringAndClear() );
1499 catch (BridgeRuntimeError& )
1501 throw;
1503 catch (...)
1505 OSL_ASSERT(0);
1506 throw;
1511 /**
1512 @param info
1513 The expected target type. Currently info is provdided when this method is called
1514 to convert the in/out and out parameters of a call from cli to uno. Then info
1515 is always a byref type, e.g. "System.String&". info is used for Any and Enum conversion.
1516 @param bDontCreateObj
1517 false - a new object is created which holds the mapped uno value and is assigned to
1518 cli_data.
1519 true - cli_data already contains the newly constructed object. This is the case if
1520 a struct is converted then on the first call to map_to_cli the new object is created.
1521 If the struct inherits another struct then this function is called recursivly while the
1522 newly created object is passed in cli_data.
1524 void Bridge::map_to_cli(
1525 System::Object* *cli_data, void const * uno_data,
1526 typelib_TypeDescriptionReference * type, System::Type* info,
1527 bool bDontCreateObj) const
1529 switch (type->eTypeClass)
1531 case typelib_TypeClass_CHAR:
1532 *cli_data= __box(*(__wchar_t const*)uno_data);
1533 break;
1534 case typelib_TypeClass_BOOLEAN:
1535 *cli_data = __box((*(bool const*)uno_data) == sal_True ? true : false);
1536 break;
1537 case typelib_TypeClass_BYTE:
1538 *cli_data = __box(*(unsigned char const*) uno_data);
1539 break;
1540 case typelib_TypeClass_SHORT:
1541 *cli_data= __box(*(short const*) uno_data);
1542 break;
1543 case typelib_TypeClass_UNSIGNED_SHORT:
1544 *cli_data= __box(*(unsigned short const*) uno_data);
1545 break;
1546 case typelib_TypeClass_LONG:
1547 *cli_data= __box(*(int const*) uno_data);
1548 break;
1549 case typelib_TypeClass_UNSIGNED_LONG:
1550 *cli_data= __box(*(unsigned int const*) uno_data);
1551 break;
1552 case typelib_TypeClass_HYPER:
1553 *cli_data= __box(*(__int64 const*) uno_data);
1554 break;
1555 case typelib_TypeClass_UNSIGNED_HYPER:
1556 *cli_data= __box(*(unsigned __int64 const*) uno_data);
1557 break;
1558 case typelib_TypeClass_FLOAT:
1559 *cli_data= __box(*(float const*) uno_data);
1560 break;
1561 case typelib_TypeClass_DOUBLE:
1562 *cli_data= __box(*(double const*) uno_data);
1563 break;
1564 case typelib_TypeClass_STRING:
1566 rtl_uString const* sVal= NULL;
1567 sVal= *(rtl_uString* const*) uno_data;
1568 *cli_data= new System::String((__wchar_t*) sVal->buffer,0, sVal->length);
1569 break;
1571 case typelib_TypeClass_TYPE:
1573 *cli_data= mapUnoType( *(typelib_TypeDescriptionReference * const *)uno_data );
1574 break;
1576 case typelib_TypeClass_ANY:
1578 uno_Any const * pAny = (uno_Any const *)uno_data;
1579 if (typelib_TypeClass_VOID != pAny->pType->eTypeClass)
1581 System::Object* objCli= NULL;
1582 map_to_cli(
1583 &objCli, pAny->pData, pAny->pType, 0,
1584 false);
1586 uno::Any anyVal(mapUnoType(pAny->pType), objCli);
1587 *cli_data= __box(anyVal);
1589 else
1590 { // void any
1591 *cli_data= __box(uno::Any::VOID);
1593 break;
1595 case typelib_TypeClass_ENUM:
1597 if (info != NULL)
1599 OSL_ASSERT(info->get_IsByRef());
1600 info= info->GetElementType();
1601 *cli_data= System::Enum::ToObject(info, *(System::Int32*) uno_data);
1603 else
1604 *cli_data= System::Enum::ToObject(
1605 mapUnoType(type), *(System::Int32*) uno_data);
1606 break;
1608 case typelib_TypeClass_STRUCT:
1609 case typelib_TypeClass_EXCEPTION:
1611 TypeDescr td( type );
1612 typelib_CompoundTypeDescription * comp_td =
1613 (typelib_CompoundTypeDescription *) td.get();
1614 if ( ! ((typelib_TypeDescription*) comp_td)->bComplete)
1615 ::typelib_typedescription_complete(
1616 (typelib_TypeDescription**) & comp_td );
1619 //create the type
1620 System::Type* cliType= loadCliType(td.get()->pTypeName);
1621 //detect if we recursivly convert inherited structures
1622 //If this point is reached because of a recursive call during convering a
1623 //struct then we must not create a new object rather we use the one in
1624 // cli_data argument.
1625 System::Object* cliObj;
1626 if (bDontCreateObj)
1627 cliObj = *cli_data; // recursive call
1628 else
1630 //Special handling for Exception conversion. We must call constructor System::Exception
1631 //to pass the message string
1632 if (__typeof(ucss::uno::Exception)->IsAssignableFrom(cliType))
1634 //We need to get the Message field. Therefore we must obtain the offset from
1635 //the typedescription. The base interface of all exceptions is
1636 //com::sun::star::uno::Exception which contains the message
1637 typelib_CompoundTypeDescription* pCTD = comp_td;
1638 while (pCTD->pBaseTypeDescription)
1639 pCTD = pCTD->pBaseTypeDescription;
1640 int nPos = -1;
1642 rtl::OUString usMessageMember(RTL_CONSTASCII_USTRINGPARAM("Message"));
1643 for (int i = 0; i < pCTD->nMembers; i ++)
1645 #if OSL_DEBUG_LEVEL >= 2
1646 System::String* sMember;
1647 sMember = mapUnoString(pCTD->ppMemberNames[i]);
1648 #endif
1649 if (usMessageMember.equals(pCTD->ppMemberNames[i]))
1651 nPos = i;
1652 break;
1655 OSL_ASSERT (nPos != -1);
1656 int offset = pCTD->pMemberOffsets[nPos];
1657 //Whith the offset within the exception we can get the message string
1658 System::String* sMessage = mapUnoString(*(rtl_uString**)
1659 ((char*) uno_data + offset));
1660 //We need to find a constructor for the exception that takes the message string
1661 //We assume that the first argument is the message string
1662 sr::ConstructorInfo* arCtorInfo[] = cliType->GetConstructors();
1663 sr::ConstructorInfo* ctorInfo = NULL;
1664 int numCtors = arCtorInfo->get_Length();
1665 //Constructor must at least have 2 params for the base
1666 //unoidl.com.sun.star.uno.Exception (String, Object);
1667 sr::ParameterInfo * arParamInfo[];
1668 for (int i = 0; i < numCtors; i++)
1670 arParamInfo = arCtorInfo[i]->GetParameters();
1671 if (arParamInfo->get_Length() < 2)
1672 continue;
1673 ctorInfo = arCtorInfo[i];
1674 break;
1676 OSL_ASSERT(arParamInfo[0]->get_ParameterType()->Equals(__typeof(System::String))
1677 && arParamInfo[1]->get_ParameterType()->Equals(__typeof(System::Object))
1678 && arParamInfo[0]->get_Position() == 0
1679 && arParamInfo[1]->get_Position() == 1);
1680 //Prepare parameters for constructor
1681 int numArgs = arParamInfo->get_Length();
1682 System::Object * args[] = new System::Object*[numArgs];
1683 //only initialize the first argument with the message
1684 args[0] = sMessage;
1685 cliObj = ctorInfo->Invoke(args);
1687 else
1688 cliObj = System::Activator::CreateInstance(cliType);
1690 sal_Int32 * pMemberOffsets = comp_td->pMemberOffsets;
1692 if (comp_td->pBaseTypeDescription)
1694 //convert inherited struct
1695 //cliObj is passed inout (args in_param, out_param are true), hence the passed
1696 // cliObj is used by the callee instead of a newly created struct
1697 map_to_cli(
1698 &cliObj, uno_data,
1699 ((typelib_TypeDescription *)comp_td->pBaseTypeDescription)->pWeakRef, 0,
1700 true);
1702 rtl::OUString usUnoException(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.Exception"));
1703 for (sal_Int32 nPos = comp_td->nMembers; nPos--; )
1705 typelib_TypeDescriptionReference * member_type = comp_td->ppTypeRefs[ nPos ];
1706 System::String* sMemberName= mapUnoString(comp_td->ppMemberNames[nPos]);
1707 sr::FieldInfo* aField= cliType->GetField(sMemberName);
1708 // special case for Exception.Message. The field has already been
1709 // set while constructing cli object
1710 if ( ! aField && usUnoException.equals(td.get()->pTypeName))
1712 continue;
1714 void const * p = (char const *)uno_data + pMemberOffsets[ nPos ];
1715 switch (member_type->eTypeClass)
1717 case typelib_TypeClass_CHAR:
1718 aField->SetValue(cliObj, __box(*(System::Char*) p));
1719 break;
1720 case typelib_TypeClass_BOOLEAN:
1721 aField->SetValue(cliObj, __box(*(System::Boolean*) p));
1722 break;
1723 case typelib_TypeClass_BYTE:
1724 aField->SetValue(cliObj, __box(*(System::Byte*) p));
1725 break;
1726 case typelib_TypeClass_SHORT:
1727 aField->SetValue(cliObj, __box(*(System::Int16*) p));
1728 break;
1729 case typelib_TypeClass_UNSIGNED_SHORT:
1730 aField->SetValue(cliObj, __box(*(System::UInt16*) p));
1731 break;
1732 case typelib_TypeClass_LONG:
1733 aField->SetValue(cliObj, __box(*(System::Int32*) p));
1734 break;
1735 case typelib_TypeClass_UNSIGNED_LONG:
1736 aField->SetValue(cliObj, __box(*(System::UInt32*) p));
1737 break;
1738 case typelib_TypeClass_HYPER:
1739 aField->SetValue(cliObj, __box(*(System::Int64*) p));
1740 break;
1741 case typelib_TypeClass_UNSIGNED_HYPER:
1742 aField->SetValue(cliObj, __box(*(System::UInt64*) p));
1743 break;
1744 case typelib_TypeClass_FLOAT:
1745 aField->SetValue(cliObj, __box(*(System::Single*) p));
1746 break;
1747 case typelib_TypeClass_DOUBLE:
1748 aField->SetValue(cliObj, __box(*(System::Double*) p));
1749 break;
1750 default:
1752 System::Object* cli_val;
1753 map_to_cli(
1754 &cli_val, p, member_type, 0,
1755 false);
1756 aField->SetValue(cliObj, cli_val);
1757 break;
1761 *cli_data= cliObj;
1762 break;
1764 case typelib_TypeClass_SEQUENCE:
1766 sal_Int32 nElements;
1767 uno_Sequence const * seq = 0;
1768 seq = *(uno_Sequence * const *)uno_data;
1769 nElements = seq->nElements;
1771 TypeDescr td( type );
1772 typelib_TypeDescriptionReference * element_type =
1773 ((typelib_IndirectTypeDescription *)td.get())->pType;
1775 switch (element_type->eTypeClass)
1777 case typelib_TypeClass_CHAR:
1779 System::Char arChar[]= new System::Char[nElements];
1780 sri::Marshal::Copy( (void*) &seq->elements, arChar, 0, nElements);
1781 *cli_data= arChar;
1782 break;
1784 case typelib_TypeClass_BOOLEAN:
1786 System::Boolean arBool[]= new System::Boolean[nElements];
1787 sri::Marshal::Copy( (void*) &seq->elements, arBool, 0, nElements);
1788 *cli_data= arBool;
1789 break;
1791 case typelib_TypeClass_BYTE:
1793 System::Byte arByte[]= new System::Byte[nElements];
1794 sri::Marshal::Copy( (void*) &seq->elements, arByte, 0, nElements);
1795 *cli_data= arByte;
1796 break;
1798 case typelib_TypeClass_SHORT:
1800 System::Int16 arShort[]= new System::Int16[nElements];
1801 sri::Marshal::Copy( (void*) &seq->elements, arShort, 0, nElements);
1802 *cli_data= arShort;
1803 break;
1805 case typelib_TypeClass_UNSIGNED_SHORT:
1807 System::UInt16 arUInt16[]= new System::UInt16[nElements];
1808 sri::Marshal::Copy( (void*) &seq->elements, static_cast<System::Int16[]>(arUInt16),
1809 0, nElements);
1810 *cli_data= arUInt16;
1811 break;
1813 case typelib_TypeClass_LONG:
1815 System::Int32 arInt32[]= new System::Int32[nElements];
1816 sri::Marshal::Copy( (void*) &seq->elements, arInt32, 0, nElements);
1817 *cli_data= arInt32;
1818 break;
1820 case typelib_TypeClass_UNSIGNED_LONG:
1822 System::UInt32 arUInt32[]= new System::UInt32[nElements];
1823 sri::Marshal::Copy( (void*) &seq->elements, static_cast<System::Int32[]>(arUInt32),
1824 0, nElements);
1825 *cli_data= arUInt32;
1826 break;
1828 case typelib_TypeClass_HYPER:
1830 System::Int64 arInt64[]= new System::Int64[nElements];
1831 sri::Marshal::Copy( (void*) &seq->elements, arInt64, 0, nElements);
1832 *cli_data= arInt64;
1833 break;
1835 case typelib_TypeClass_UNSIGNED_HYPER:
1837 System::UInt64 arUInt64[]= new System::UInt64[nElements];
1838 sri::Marshal::Copy( (void*) &seq->elements, arUInt64, 0, nElements);
1839 *cli_data= arUInt64;
1840 break;
1842 case typelib_TypeClass_FLOAT:
1844 System::Single arSingle[]= new System::Single[nElements];
1845 sri::Marshal::Copy( (void*) &seq->elements, arSingle, 0, nElements);
1846 *cli_data= arSingle;
1847 break;
1849 case typelib_TypeClass_DOUBLE:
1851 System::Double arDouble[]= new System::Double[nElements];
1852 sri::Marshal::Copy( (void*) &seq->elements, arDouble, 0, nElements);
1853 *cli_data= arDouble;
1854 break;
1856 case typelib_TypeClass_STRING:
1858 System::String* arString[]= new System::String*[nElements];
1859 for (int i= 0; i < nElements; i++)
1861 rtl_uString *aStr= ((rtl_uString**)(&seq->elements))[i];
1862 arString[i]= new System::String( (__wchar_t *) &aStr->buffer, 0, aStr->length);
1864 *cli_data= arString;
1865 break;
1867 case typelib_TypeClass_TYPE:
1869 System::Type* arType[]= new System::Type*[nElements];
1870 for (int i= 0; i < nElements; i++)
1872 arType[i]=
1873 mapUnoType( ((typelib_TypeDescriptionReference**) seq->elements)[i]);
1875 *cli_data= arType;
1876 break;
1878 case typelib_TypeClass_ANY:
1880 uno::Any arCli[]= new uno::Any[nElements];
1881 uno_Any const * p = (uno_Any const *)seq->elements;
1882 for (sal_Int32 nPos = 0; nPos < nElements; ++nPos )
1884 System::Object* cli_obj = NULL;
1885 map_to_cli(
1886 &cli_obj, &p[ nPos ], element_type, 0, false);
1887 arCli[nPos]= *__try_cast<__box uno::Any*>(cli_obj);
1889 *cli_data= arCli;
1890 break;
1892 case typelib_TypeClass_ENUM:
1894 //get the Enum type
1895 System::Type* enumType= NULL;
1896 if (info != NULL)
1898 //info is EnumType[]&, remove &
1899 OSL_ASSERT(info->IsByRef);
1900 enumType = info->GetElementType();
1901 //enumType is EnumType[], remove []
1902 enumType = enumType->GetElementType();
1904 else
1905 enumType= mapUnoType(element_type);
1907 System::Array* arEnum = System::Array::CreateInstance(
1908 enumType, nElements);
1909 for (int i= 0; i < nElements; i++)
1911 arEnum->SetValue(System::Enum::ToObject(enumType,
1912 ((sal_Int32*) seq->elements)[i]), i);
1914 *cli_data = arEnum;
1915 break;
1917 case typelib_TypeClass_STRUCT:
1918 case typelib_TypeClass_EXCEPTION:
1920 TypeDescr element_td( element_type );
1921 System::Array* ar= System::Array::CreateInstance(
1922 mapUnoType(element_type),nElements);
1923 if (0 < nElements)
1925 // ToDo check this
1926 char * p = (char *) &seq->elements;
1927 sal_Int32 nSize = element_td.get()->nSize;
1928 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
1930 System::Object* val;
1931 map_to_cli(
1932 &val, p + (nSize * nPos), element_type, 0, false);
1933 ar->SetValue(val, nPos);
1936 *cli_data = ar;
1937 break;
1939 // ToDo, verify
1940 case typelib_TypeClass_SEQUENCE:
1942 System::Array *ar= System::Array::CreateInstance(
1943 mapUnoType(element_type), nElements);
1944 if (0 < nElements)
1946 TypeDescr element_td( element_type );
1947 uno_Sequence ** elements = (uno_Sequence**) seq->elements;
1948 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
1950 System::Object* val;
1951 map_to_cli(
1952 &val, &elements[nPos], element_type, 0, false);
1953 ar->SetValue(val, nPos);
1956 *cli_data = ar;
1957 break;
1959 case typelib_TypeClass_INTERFACE:
1961 TypeDescr element_td( element_type );
1962 System::Type * ifaceType= mapUnoType(element_type);
1963 System::Array* ar= System::Array::CreateInstance(ifaceType, nElements);
1965 char * p = (char *)seq->elements;
1966 sal_Int32 nSize = element_td.get()->nSize;
1967 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
1969 System::Object* val;
1970 map_to_cli(
1971 &val, p + (nSize * nPos), element_type, NULL, false);
1973 ar->SetValue(val, nPos);
1975 *cli_data= ar;
1976 break;
1978 default:
1980 OUStringBuffer buf( 128 );
1981 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_cli():") );
1982 buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName ) );
1983 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] unsupported element type: ") );
1984 buf.append( *reinterpret_cast< OUString const * >( &element_type->pTypeName ) );
1985 throw BridgeRuntimeError( buf.makeStringAndClear() );
1988 break;
1990 case typelib_TypeClass_INTERFACE:
1992 uno_Interface * pUnoI = *(uno_Interface * const *)uno_data;
1993 if (0 != pUnoI)
1995 TypeDescr td( type );
1996 *cli_data= map_uno2cli( pUnoI, reinterpret_cast<
1997 typelib_InterfaceTypeDescription*>(td.get())) ;
1999 else
2000 *cli_data= NULL;
2001 break;
2003 default:
2005 //ToDo check this exception. The String is probably crippled
2006 OUStringBuffer buf( 128 );
2007 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_cli():") );
2008 buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName ) );
2009 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] unsupported type!") );
2010 throw BridgeRuntimeError( buf.makeStringAndClear() );