xref: /AOO41X/main/cli_ure/source/uno_bridge/cli_data.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
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.
14  *
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).
20  *
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.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_cli_ure.hxx"
30 
31 #pragma warning(push, 1)
32 #include "windows.h"
33 #pragma warning(pop)
34 
35 #include <memory>
36 
37 
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"
45 
46 #using <cli_uretypes.dll>
47 
48 
49 #undef VOID
50 
51 namespace css = com::sun::star;
52 
53 namespace sri = System::Runtime::InteropServices;
54 namespace sr = System::Reflection;
55 namespace st = System::Text;
56 namespace ucss = unoidl::com::sun::star;
57 
58 using namespace rtl;
59 using namespace std;
60 
61 
62 namespace cli_uno
63 {
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);
68 
69 inline auto_ptr< rtl_mem > seq_allocate( sal_Int32 nElements, sal_Int32 nSize )
70 {
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;
77 }
78 
79 
80 System::Object* Bridge::map_uno2cli(uno_Interface * pUnoI, typelib_InterfaceTypeDescription *pTD) const
81 {
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);
88 
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);
92 
93 	System::Threading::Monitor::Enter( CliEnvHolder::g_cli_env );
94     try
95     {
96 		retVal = CliEnvHolder::g_cli_env->getRegisteredInterface(sOid, ifaceType);
97         if (retVal)
98         {
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))
104             {
105                 UnoInterfaceProxy* p = static_cast<UnoInterfaceProxy*>(
106                     srr::RemotingServices::GetRealProxy(retVal));
107                 p->addUnoInterface(pUnoI, pTD);
108             }
109         }
110         else
111         {
112             retVal = UnoInterfaceProxy::create(
113                 (Bridge *) this, pUnoI, pTD, oid );
114         }
115     }
116     __finally
117     {
118 		System::Threading::Monitor::Exit( CliEnvHolder::g_cli_env );
119     }
120 
121     return retVal;
122 }
123 
124 uno_Interface* Bridge::map_cli2uno(System::Object* cliObj, typelib_TypeDescription *pTD) const
125 {
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)
134     {
135         System::Threading::Monitor::Enter(__typeof(Cli_environment));
136         try
137         {
138             m_uno_env->getRegisteredInterface(m_uno_env, (void**) &retIface, ousOid.pData,
139                                                (typelib_InterfaceTypeDescription*) pTD);
140             if ( ! retIface)
141             {
142                 retIface = CliProxy::create((Bridge*)this, cliObj, pTD, ousOid);
143             }
144         }
145         __finally
146         {
147             System::Threading::Monitor::Exit(__typeof(Cli_environment));
148         }
149     }
150     return retIface;
151 }
152 
153 inline System::Type* loadCliType(rtl_uString * unoName)
154 {
155      return loadCliType(mapUnoTypeName(unoName));
156 }
157 
158 System::Type* loadCliType(System::String * unoName)
159 {
160     System::Type* retVal= NULL;
161     try
162     {
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;
166 
167         System::String * loadName = unoName;
168         int index = unoName->IndexOf('<');
169         if (index != -1)
170         {
171             loadName = unoName->Substring(0, index);
172             bIsPolymorphic = true;
173         }
174         System::AppDomain*  currentDomain = System::AppDomain::CurrentDomain;
175         sr::Assembly*  assems[] = currentDomain->GetAssemblies();
176         for (int i = 0; i < assems->Length; i++)
177         {
178             retVal = assems[i]->GetType(loadName, false);
179             if (retVal)
180                 break;
181         }
182 
183 		if (retVal == NULL)
184 		{
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));
188 		}
189 
190         if (bIsPolymorphic)
191         {
192             retVal = uno::PolymorphicType::GetType(retVal, unoName);
193         }
194     }
195     catch( System::Exception * e)
196     {
197         rtl::OUString ouMessage(mapCliString(e->get_Message()));
198         throw BridgeRuntimeError(ouMessage);
199     }
200     return retVal;
201 }
202 
203 
204 System::Type* mapUnoType(typelib_TypeDescription const * pTD)
205 {
206     return mapUnoType(pTD->pWeakRef);
207 }
208 
209 System::Type* mapUnoType(typelib_TypeDescriptionReference const * pTD)
210 {
211     System::Type * retVal = 0;
212     switch (pTD->eTypeClass)
213     {
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:
249     {
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;
257     }
258     case typelib_TypeClass_SEQUENCE:
259     {
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)
265         {
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:
310         {
311             retVal= loadCliType(pTD->pTypeName);
312             break;
313         }
314         default:
315             //All cases should be handled by the case statements above
316             OSL_ASSERT(0);
317             break;
318         }
319         break;
320     }
321     default:
322         OSL_ASSERT(false);
323         break;
324     }
325     return retVal;
326 }
327 
328 /** Returns an acquired td.
329  */
330 typelib_TypeDescriptionReference* mapCliType(System::Type* cliType)
331 {
332     typelib_TypeDescriptionReference* retVal= NULL;
333     if (cliType == NULL)
334     {
335         retVal = * typelib_static_type_getByTypeClass(
336             typelib_TypeClass_VOID );
337         typelib_typedescriptionreference_acquire( retVal );
338         return retVal;
339     }
340     //check for Enum first,
341     //because otherwise case System::TypeCode::Int32 applies
342     if (cliType->get_IsEnum())
343     {
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);
348     }
349     else
350     {
351         switch (System::Type::GetTypeCode(cliType))
352         {
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;
415         }
416     }
417     if (retVal == NULL)
418     {
419         System::String* cliTypeName= cliType->get_FullName();
420         // Void
421         if (const_cast<System::String*>(Constants::sVoid)->Equals(
422                 cliTypeName))
423         {
424             retVal = * typelib_static_type_getByTypeClass(
425                 typelib_TypeClass_VOID );
426             typelib_typedescriptionreference_acquire( retVal );
427         }
428         // Type
429         else if (const_cast<System::String*>(Constants::sType)->Equals(
430                      cliTypeName))
431         {
432             retVal = * typelib_static_type_getByTypeClass(
433                 typelib_TypeClass_TYPE );
434             typelib_typedescriptionreference_acquire( retVal );
435         }
436         // Any
437         else if (const_cast<System::String*>(Constants::sAny)->Equals(
438                      cliTypeName))
439         {
440             retVal = * typelib_static_type_getByTypeClass(
441                 typelib_TypeClass_ANY );
442             typelib_typedescriptionreference_acquire( retVal );
443         }
444         //struct, interfaces, sequences
445         else
446         {
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)
456             {
457                 retVal = td->pWeakRef;
458                 typelib_typedescriptionreference_acquire(retVal);
459                 typelib_typedescription_release(td);
460             }
461         }
462     }
463     if (retVal == NULL)
464     {
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() );
471     }
472     return retVal;
473 }
474 
475 /**
476     Otherwise a leading "unoidl." is removed.
477  */
478 System::String* mapUnoTypeName(rtl_uString const * typeName)
479 {
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] == '[')
485     {
486         sal_Int32 index= 1;
487         while (true)
488         {
489             if (usUnoName[index++] == ']')
490                 dims++;
491             if (usUnoName[index++] != '[')
492                 break;
493         }
494         usUnoName = usUnoName.copy(index - 1);
495     }
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)))
528     {
529         buf->Append(const_cast<System::String*>(Constants::sAny));
530     }
531     else
532     {
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);
538     }
539     // apend []
540     for (;dims--;)
541         buf->Append(const_cast<System::String*>(Constants::sBrackets));
542 
543     return buf->ToString();
544 }
545 
546 
547 
548 
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.
555  */
556 inline System::String* mapUnoPolymorphicName(System::String* unoName)
557 {
558        return mapPolymorphicName(unoName, false);
559 }
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.
566  */
567 inline System::String* mapCliPolymorphicName(System::String* unoName)
568 {
569     return mapPolymorphicName(unoName, true);
570 }
571 
572 System::String* mapPolymorphicName(System::String* unoName, bool bCliToUno)
573 {
574     int index = unoName->IndexOf('<');
575     if (index == -1)
576         return unoName;
577 
578     System::Text::StringBuilder * builder = new System::Text::StringBuilder(256);
579     builder->Append(unoName->Substring(0, index +1 ));
580 
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)
590 	{
591 		System::Char c = unoName->Chars[cur];
592 		if (c == ',' || c == '>')
593 		{
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)
604             {
605                 builder->Append(mapCliTypeName(sParam));
606             }
607             else
608             {
609                 OUString s = mapCliString(sParam);
610                 builder->Append(mapUnoTypeName(s.pData));
611             }
612 		}
613 		else if (c == '<')
614 		{
615 			cur++;
616 			//continue until the matching '>'
617 			int numNested = 0;
618 			for (;;cur++)
619 			{
620 				System::Char curChar = unoName->Chars[cur];
621 				if (curChar == '<')
622 				{
623 					numNested ++;
624 				}
625 				else if (curChar == '>')
626 				{
627 					if (numNested > 0)
628 						numNested--;
629 					else
630 						break;
631 				}
632 			}
633 		}
634 		cur++;
635 	}
636 
637     builder->Append((System::Char) '>');
638     return builder->ToString();
639 }
640 
641 OUString mapCliTypeName(System::String* typeName)
642 {
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)
651 	{
652 		System::Char c = typeName->Chars[cur];
653 		if (c == ']')
654 		{
655             bRightBracket = true;
656 		}
657         else if (c == '[')
658         {
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 ++;
665         }
666         else
667         {
668             if (bRightBracket)
669                 throw BridgeRuntimeError(
670                     OUSTR("Typename is wrong. No matching brackets for sequence. Name is: ") +
671                     mapCliString(typeName));
672             break;
673         }
674         cur--;
675 	}
676 
677     if (bRightBracket || cur < 0)
678         throw BridgeRuntimeError(
679             OUSTR("Typename is wrong. ") +
680             mapCliString(typeName));
681 
682     typeName = typeName->Substring(0, cur + 1);
683 
684 	System::Text::StringBuilder * buf = new System::Text::StringBuilder(512);
685 
686     //Put the "[]" at the beginning of the uno type name
687     for (;dims--;)
688 		buf->Append(const_cast<System::String*>(Constants::usBrackets));
689 
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
723     {
724         System::String * sName = mapCliPolymorphicName(typeName);
725         int i= sName->IndexOf(L'.');
726         buf->Append(sName->Substring(i + 1));
727     }
728     return mapCliString(buf->ToString());
729 }
730 /** Maps uno types to dot net types.
731  *  If uno_data is null then the type description is converted to System::Type
732  */
733 inline System::String* mapUnoString( rtl_uString const * data)
734 {
735     OSL_ASSERT(data);
736     return new System::String((__wchar_t*) data->buffer, 0, data->length);
737 }
738 
739 OUString mapCliString(System::String const * data)
740 {
741 
742     if (data != NULL)
743     {
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());
747     }
748     else
749     {
750         return OUString();
751     }
752 }
753 
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
760 {
761     try{
762         switch (type->eTypeClass)
763         {
764         case typelib_TypeClass_VOID:
765             break;
766         case typelib_TypeClass_CHAR:
767         {
768             System::Char aChar= *__try_cast<System::Char*>(cli_data);
769             *(sal_Unicode*) uno_data= aChar;
770             break;
771         }
772         case typelib_TypeClass_BOOLEAN:
773         {
774             System::Boolean aBool= *__try_cast<System::Boolean*>(cli_data);
775             *(sal_Bool*)uno_data= aBool == true ? sal_True : sal_False;
776             break;
777         }
778         case typelib_TypeClass_BYTE:
779         {
780             System::Byte aByte= *__try_cast<System::Byte*>(cli_data);
781             *(sal_Int8*) uno_data= aByte;
782             break;
783         }
784         case typelib_TypeClass_SHORT:
785         {
786             System::Int16 aShort= *__try_cast<System::Int16*>(cli_data);
787             *(sal_Int16*) uno_data= aShort;
788             break;
789         }
790         case typelib_TypeClass_UNSIGNED_SHORT:
791         {
792             System::UInt16 aUShort= *__try_cast<System::UInt16*>(cli_data);
793             *(sal_uInt16*) uno_data= aUShort;
794             break;
795         }
796         case typelib_TypeClass_LONG:
797         {
798             System::Int32 aLong= *__try_cast<System::Int32*>(cli_data);
799             *(sal_Int32*) uno_data= aLong;
800             break;
801         }
802         case typelib_TypeClass_UNSIGNED_LONG:
803         {
804             System::UInt32 aULong= *__try_cast<System::UInt32*>(cli_data);
805             *(sal_uInt32*) uno_data= aULong;
806             break;
807         }
808         case typelib_TypeClass_HYPER:
809         {
810             System::Int64 aHyper= *__try_cast<System::Int64*>(cli_data);
811             *(sal_Int64*) uno_data= aHyper;
812             break;
813         }
814         case typelib_TypeClass_UNSIGNED_HYPER:
815         {
816             System::UInt64 aLong= *__try_cast<System::UInt64*>(cli_data);
817             *(sal_uInt64*) uno_data= aLong;
818             break;
819         }
820         case typelib_TypeClass_FLOAT:
821         {
822             System::Single aFloat= *__try_cast<System::Single*>(cli_data);
823             *(float*) uno_data= aFloat;
824             break;
825         }
826         case typelib_TypeClass_DOUBLE:
827         {
828             System::Double aDouble= *__try_cast<System::Double*>(cli_data);
829             *(double*) uno_data= aDouble;
830             break;
831         }
832         case typelib_TypeClass_STRING:
833         {
834             if (assign && *(rtl_uString**) uno_data)
835                 rtl_uString_release(*(rtl_uString**) uno_data);
836 
837             *(rtl_uString **)uno_data = 0;
838             if (cli_data == NULL)
839             {
840                  rtl_uString_new((rtl_uString**) uno_data);
841             }
842             else
843             {
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() );
848             }
849             break;
850         }
851         case typelib_TypeClass_TYPE:
852         {
853             typelib_TypeDescriptionReference* td= mapCliType(__try_cast<System::Type*>(
854                                                                     cli_data));
855             if (assign)
856             {
857                 typelib_typedescriptionreference_release(
858                     *(typelib_TypeDescriptionReference **)uno_data );
859             }
860             *(typelib_TypeDescriptionReference **)uno_data = td;
861             break;
862         }
863         case typelib_TypeClass_ANY:
864         {
865             uno_Any * pAny = (uno_Any *)uno_data;
866             if (cli_data == NULL) // null-ref or uninitialized any maps to empty any
867             {
868                 if (assign)
869                     uno_any_destruct( pAny, 0 );
870                 uno_any_construct( pAny, 0, 0, 0 );
871                 break;
872             }
873             uno::Any aAny= *__try_cast<uno::Any*>(cli_data);
874             css::uno::Type  value_td( mapCliType(aAny.Type), SAL_NO_ACQUIRE);
875 
876             if (assign)
877                 uno_any_destruct( pAny, 0 );
878 
879             try
880             {
881                 switch (value_td.getTypeClass())
882                 {
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 *))
916                     {
917                         pAny->pData = &pAny->pReserved;
918                         *(sal_Int64*) &pAny->pReserved = *__try_cast<System::Int64*>(aAny.Value);
919                     }
920                     else
921                     {
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();
925                     }
926                     break;
927                 case typelib_TypeClass_UNSIGNED_HYPER:
928                     if (sizeof (sal_uInt64) <= sizeof (void *))
929                     {
930                         pAny->pData = &pAny->pReserved;
931                         *(sal_uInt64*) &pAny->pReserved = *__try_cast<System::UInt64*>(aAny.Value);
932                     }
933                     else
934                     {
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();
938                     }
939                     break;
940                 case typelib_TypeClass_FLOAT:
941                     if (sizeof (float) <= sizeof (void *))
942                     {
943                         pAny->pData = &pAny->pReserved;
944                         *(float*) &pAny->pReserved = *__try_cast<System::Single*>(aAny.Value);
945                     }
946                     else
947                     {
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();
951                     }
952                     break;
953                 case typelib_TypeClass_DOUBLE:
954                     if (sizeof (double) <= sizeof (void *))
955                     {
956                         pAny->pData = &pAny->pReserved;
957                         *(double*) &pAny->pReserved= *__try_cast<System::Double*>(aAny.Value);
958                     }
959                     else
960                     {
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();
964                     }
965                     break;
966                 case typelib_TypeClass_STRING: // anies often contain strings; copy string directly
967                 {
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;
973                 }
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:
986                 {
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;
997                 }
998                 default:
999                 {
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() );
1005                 }
1006                 }
1007             }
1008             catch(System::InvalidCastException* )
1009             {
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)
1021                 {
1022                     css::uno::Type td(mapCliType(aAny.Value->GetType()), SAL_NO_ACQUIRE);
1023                     buf.append(td.getTypeName());
1024                 }
1025                 if (assign)
1026                     uno_any_construct( pAny, 0, 0, 0 ); // restore some valid any
1027                 throw BridgeRuntimeError( buf.makeStringAndClear() );
1028             }
1029             catch (BridgeRuntimeError& )
1030             {
1031                 if (assign)
1032                     uno_any_construct( pAny, 0, 0, 0 ); // restore some valid any
1033                 throw;
1034             }
1035             catch (...)
1036             {
1037                 if (assign)
1038                     uno_any_construct( pAny, 0, 0, 0 ); // restore some valid any
1039                 throw;
1040             }
1041 
1042             pAny->pType = value_td.getTypeLibType();
1043             typelib_typedescriptionreference_acquire(pAny->pType);
1044             break;
1045         }
1046         case typelib_TypeClass_ENUM:
1047         {
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;
1052         }
1053         case typelib_TypeClass_STRUCT:
1054         case typelib_TypeClass_EXCEPTION:
1055         {
1056             css::uno::TypeDescription td(type);
1057             typelib_CompoundTypeDescription * comp_td =
1058                 (typelib_CompoundTypeDescription*) td.get();
1059 
1060             typelib_StructTypeDescription * struct_td = NULL;
1061             if (type->eTypeClass == typelib_TypeClass_STRUCT)
1062                 struct_td = (typelib_StructTypeDescription*) td.get();
1063 
1064             if ( ! ((typelib_TypeDescription*) comp_td)->bComplete)
1065                 ::typelib_typedescription_complete(
1066                     (typelib_TypeDescription**) & comp_td );
1067 
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();
1073 
1074             if (0 != comp_td->pBaseTypeDescription)
1075             {
1076                 map_to_uno(
1077                     uno_data, cli_data,
1078                     ((typelib_TypeDescription *)comp_td->pBaseTypeDescription)->pWeakRef,
1079                     assign);
1080             }
1081             sal_Int32 nPos = 0;
1082             try
1083             {
1084                 typelib_TypeDescriptionReference * member_type= NULL;
1085 
1086 				rtl::OUString usUnoException(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.Exception"));
1087                 for (; nPos < nMembers; ++nPos)
1088                 {
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)
1098                     {
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]))
1108                             {
1109                                 sr::PropertyInfo* pi= cliType->GetProperty(
1110                                     mapUnoString(comp_td->ppMemberNames[nPos]));
1111                                 val= pi->GetValue(cli_data, NULL);
1112                             }
1113                             else
1114                             {
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());
1119                             }
1120                         }
1121                         else
1122                         {
1123                             val= aField->GetValue(cli_data);
1124                         }
1125                     }
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)
1135                     {
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;
1206                     }
1207                     }
1208                 }
1209             }
1210             catch (BridgeRuntimeError& e)
1211             {
1212                 bException= true;
1213                 OUStringBuffer buf(512);
1214                 buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("[map_to_uno():"));
1215                 if (cliType)
1216                 {
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(" "));
1221                 }
1222                 buf.append(e.m_message);
1223                 throw BridgeRuntimeError(buf.makeStringAndClear());
1224             }
1225             catch (System::InvalidCastException* )
1226             {
1227                 bException= true;
1228                 OUStringBuffer buf( 256 );
1229                 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
1230                 if (cliType)
1231                 {
1232                     buf.append(mapCliString(cliType->get_FullName()));
1233                     buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("."));
1234                     buf.append(comp_td->ppMemberNames[nPos]);
1235                 }
1236                 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] Value has not the required type."));
1237                 throw BridgeRuntimeError(buf.makeStringAndClear());
1238             }
1239             catch (...)
1240             {
1241                 OSL_ASSERT(0);
1242                 bException= true;
1243                 throw;
1244             }
1245             __finally
1246             {
1247                 if (bException && !assign) // if assign then caller cleans up
1248                 {
1249                     // cleanup the members which we have converted so far
1250                     for ( sal_Int32 nCleanup = 0; nCleanup < nPos; ++nCleanup )
1251                     {
1252                         uno_type_destructData(
1253                             uno_data, comp_td->ppTypeRefs[ nCleanup ], 0 );
1254                     }
1255                     if (0 != comp_td->pBaseTypeDescription)
1256                     {
1257                         uno_destructData(
1258                             uno_data, (typelib_TypeDescription *)comp_td->pBaseTypeDescription, 0 );
1259                     }
1260                 }
1261             }
1262             break;
1263         }
1264         case typelib_TypeClass_SEQUENCE:
1265         {
1266             TypeDescr td( type );
1267             typelib_TypeDescriptionReference * element_type =
1268                 ((typelib_IndirectTypeDescription *)td.get())->pType;
1269 
1270             auto_ptr< rtl_mem > seq;
1271 
1272             System::Array* ar = NULL;
1273             if (cli_data != NULL)
1274             {
1275                 ar = __try_cast<System::Array*>(cli_data);
1276                 sal_Int32 nElements = ar->GetLength(0);
1277 
1278                 try
1279                 {
1280                     switch (element_type->eTypeClass)
1281                     {
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:
1341                     {
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++)
1345                         {
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());
1352                         }
1353                         break;
1354                     }
1355                     case typelib_TypeClass_ENUM:
1356                         seq = seq_allocate(nElements, sizeof (sal_Int32));
1357                         for (int i= 0; i < nElements; i++)
1358                         {
1359                             ((sal_Int32*) &((uno_Sequence*) seq.get())->elements)[i]=
1360                                 System::Convert::ToInt32(ar->GetValue(i));
1361                         }
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:
1369                     {
1370                         TypeDescr element_td( element_type );
1371                         seq = seq_allocate( nElements, element_td.get()->nSize );
1372 
1373                         for (sal_Int32 nPos = 0; nPos < nElements; ++nPos)
1374                         {
1375                             try
1376                             {
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 */);
1383                             }
1384                             catch (...)
1385                             {
1386                                 // cleanup
1387                                 for ( sal_Int32 nCleanPos = 0; nCleanPos < nPos; ++nCleanPos )
1388                                 {
1389                                     void * p =
1390                                         ((uno_Sequence *)seq.get())->elements +
1391                                         (nCleanPos * element_td.get()->nSize);
1392                                     uno_destructData( p, element_td.get(), 0 );
1393                                 }
1394                                 throw;
1395                             }
1396                         }
1397                         break;
1398                     }
1399                     default:
1400                     {
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() );
1407                     }
1408                     }
1409                 }
1410                 catch (BridgeRuntimeError& e)
1411                 {
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());
1418                 }
1419                 catch (System::InvalidCastException* )
1420                 {
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() );
1428                 }
1429                 catch (...)
1430                 {
1431                     OSL_ASSERT(0);
1432                     throw;
1433                 }
1434                 __finally
1435                     {
1436                         if (assign)
1437                             uno_destructData( uno_data, td.get(), 0 );
1438                     }
1439             }
1440             else
1441             {
1442                 seq = seq_allocate(0, sizeof (sal_Int32));
1443             }
1444             *(uno_Sequence **)uno_data = (uno_Sequence *)seq.release();
1445             break;
1446         }
1447         case typelib_TypeClass_INTERFACE:
1448         {
1449             if (assign)
1450             {
1451                 uno_Interface * p = *(uno_Interface **)uno_data;
1452                 if (0 != p)
1453                     (*p->release)( p );
1454             }
1455             if (0 == cli_data) // null-ref
1456             {
1457                 *(uno_Interface **)uno_data = 0;
1458             }
1459             else
1460             {
1461                 TypeDescr td( type );
1462                 uno_Interface * pUnoI = map_cli2uno(cli_data, td.get());
1463                 *(uno_Interface **)uno_data = pUnoI;
1464             }
1465             break;
1466         }
1467         default:
1468         {
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() );
1475         }
1476         }
1477     }
1478     // BridgeRuntimeError are allowed to be thrown
1479     catch (System::InvalidCastException* )
1480     {
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() );
1487     }
1488     catch (System::NullReferenceException * e)
1489     {
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() );
1495     }
1496     catch (BridgeRuntimeError& )
1497     {
1498         throw;
1499     }
1500     catch (...)
1501     {
1502         OSL_ASSERT(0);
1503         throw;
1504     }
1505 
1506 }
1507 
1508 /**
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.
1520  */
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
1525 {
1526     switch (type->eTypeClass)
1527     {
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:
1562     {
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;
1567     }
1568     case typelib_TypeClass_TYPE:
1569      {
1570          *cli_data= mapUnoType( *(typelib_TypeDescriptionReference * const *)uno_data );
1571          break;
1572      }
1573     case typelib_TypeClass_ANY:
1574     {
1575         uno_Any const * pAny = (uno_Any const *)uno_data;
1576         if (typelib_TypeClass_VOID != pAny->pType->eTypeClass)
1577         {
1578             System::Object* objCli= NULL;
1579             map_to_cli(
1580                 &objCli, pAny->pData, pAny->pType, 0,
1581                 false);
1582 
1583             uno::Any anyVal(mapUnoType(pAny->pType), objCli);
1584             *cli_data= __box(anyVal);
1585         }
1586         else
1587         { // void any
1588             *cli_data= __box(uno::Any::VOID);
1589         }
1590         break;
1591     }
1592     case typelib_TypeClass_ENUM:
1593      {
1594          if (info != NULL)
1595          {
1596              OSL_ASSERT(info->get_IsByRef());
1597              info= info->GetElementType();
1598              *cli_data= System::Enum::ToObject(info, *(System::Int32*) uno_data);
1599          }
1600          else
1601              *cli_data= System::Enum::ToObject(
1602                  mapUnoType(type), *(System::Int32*) uno_data);
1603         break;
1604     }
1605     case typelib_TypeClass_STRUCT:
1606     case typelib_TypeClass_EXCEPTION:
1607     {
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 );
1614 
1615 
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
1626         {
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))
1630             {
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;
1638 
1639 				rtl::OUString usMessageMember(RTL_CONSTASCII_USTRINGPARAM("Message"));
1640                 for (int i = 0; i < pCTD->nMembers; i ++)
1641                 {
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]))
1647                     {
1648                         nPos = i;
1649                         break;
1650                     }
1651                 }
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++)
1666                 {
1667                     arParamInfo = arCtorInfo[i]->GetParameters();
1668                     if (arParamInfo->get_Length() < 2)
1669                         continue;
1670                     ctorInfo = arCtorInfo[i];
1671                     break;
1672                 }
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);
1683             }
1684             else
1685                 cliObj = System::Activator::CreateInstance(cliType);
1686         }
1687         sal_Int32 * pMemberOffsets = comp_td->pMemberOffsets;
1688 
1689         if (comp_td->pBaseTypeDescription)
1690         {
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);
1698         }
1699 		rtl::OUString usUnoException(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.Exception"));
1700         for (sal_Int32 nPos = comp_td->nMembers; nPos--; )
1701         {
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))
1708             {
1709                 continue;
1710             }
1711             void const * p = (char const *)uno_data + pMemberOffsets[ nPos ];
1712             switch (member_type->eTypeClass)
1713             {
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:
1748             {
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;
1755             }
1756             }
1757         }
1758         *cli_data= cliObj;
1759         break;
1760     }
1761     case typelib_TypeClass_SEQUENCE:
1762     {
1763         sal_Int32 nElements;
1764         uno_Sequence const * seq = 0;
1765         seq = *(uno_Sequence * const *)uno_data;
1766         nElements = seq->nElements;
1767 
1768         TypeDescr td( type );
1769         typelib_TypeDescriptionReference * element_type =
1770             ((typelib_IndirectTypeDescription *)td.get())->pType;
1771 
1772         switch (element_type->eTypeClass)
1773         {
1774         case typelib_TypeClass_CHAR:
1775         {
1776             System::Char arChar[]= new System::Char[nElements];
1777             sri::Marshal::Copy( (void*) &seq->elements, arChar, 0, nElements);
1778             *cli_data= arChar;
1779             break;
1780         }
1781         case typelib_TypeClass_BOOLEAN:
1782         {
1783             System::Boolean arBool[]= new System::Boolean[nElements];
1784             sri::Marshal::Copy( (void*) &seq->elements, arBool, 0, nElements);
1785             *cli_data= arBool;
1786             break;
1787         }
1788         case typelib_TypeClass_BYTE:
1789         {
1790             System::Byte arByte[]= new System::Byte[nElements];
1791             sri::Marshal::Copy( (void*) &seq->elements, arByte, 0, nElements);
1792             *cli_data= arByte;
1793             break;
1794         }
1795         case typelib_TypeClass_SHORT:
1796         {
1797             System::Int16 arShort[]= new System::Int16[nElements];
1798             sri::Marshal::Copy( (void*) &seq->elements, arShort, 0, nElements);
1799             *cli_data= arShort;
1800             break;
1801         }
1802         case typelib_TypeClass_UNSIGNED_SHORT:
1803         {
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;
1809         }
1810         case typelib_TypeClass_LONG:
1811         {
1812             System::Int32 arInt32[]= new System::Int32[nElements];
1813             sri::Marshal::Copy( (void*) &seq->elements, arInt32, 0, nElements);
1814             *cli_data= arInt32;
1815             break;
1816         }
1817         case typelib_TypeClass_UNSIGNED_LONG:
1818         {
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;
1824         }
1825         case typelib_TypeClass_HYPER:
1826         {
1827             System::Int64 arInt64[]= new System::Int64[nElements];
1828             sri::Marshal::Copy( (void*) &seq->elements, arInt64, 0, nElements);
1829             *cli_data= arInt64;
1830             break;
1831         }
1832         case typelib_TypeClass_UNSIGNED_HYPER:
1833         {
1834             System::UInt64 arUInt64[]= new System::UInt64[nElements];
1835             sri::Marshal::Copy( (void*) &seq->elements, arUInt64, 0, nElements);
1836             *cli_data= arUInt64;
1837             break;
1838         }
1839         case typelib_TypeClass_FLOAT:
1840         {
1841             System::Single arSingle[]= new System::Single[nElements];
1842             sri::Marshal::Copy( (void*) &seq->elements, arSingle, 0, nElements);
1843             *cli_data= arSingle;
1844             break;
1845         }
1846         case typelib_TypeClass_DOUBLE:
1847         {
1848             System::Double arDouble[]= new System::Double[nElements];
1849             sri::Marshal::Copy( (void*) &seq->elements, arDouble, 0, nElements);
1850             *cli_data= arDouble;
1851             break;
1852         }
1853         case typelib_TypeClass_STRING:
1854         {
1855             System::String* arString[]= new System::String*[nElements];
1856             for (int i= 0; i < nElements; i++)
1857             {
1858                 rtl_uString *aStr= ((rtl_uString**)(&seq->elements))[i];
1859                 arString[i]= new System::String( (__wchar_t *) &aStr->buffer, 0, aStr->length);
1860             }
1861             *cli_data= arString;
1862             break;
1863         }
1864         case typelib_TypeClass_TYPE:
1865         {
1866             System::Type* arType[]= new System::Type*[nElements];
1867             for (int i= 0; i < nElements; i++)
1868             {
1869                 arType[i]=
1870                     mapUnoType( ((typelib_TypeDescriptionReference**) seq->elements)[i]);
1871             }
1872             *cli_data= arType;
1873             break;
1874         }
1875         case typelib_TypeClass_ANY:
1876         {
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 )
1880             {
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);
1885             }
1886             *cli_data= arCli;
1887             break;
1888         }
1889         case typelib_TypeClass_ENUM:
1890         {
1891             //get the Enum type
1892             System::Type* enumType= NULL;
1893             if (info != NULL)
1894             {
1895                 //info is EnumType[]&, remove &
1896                 OSL_ASSERT(info->IsByRef);
1897                 enumType = info->GetElementType();
1898                 //enumType is EnumType[], remove []
1899                 enumType = enumType->GetElementType();
1900             }
1901             else
1902                 enumType= mapUnoType(element_type);
1903 
1904             System::Array* arEnum = System::Array::CreateInstance(
1905                 enumType, nElements);
1906             for (int i= 0; i < nElements; i++)
1907             {
1908                 arEnum->SetValue(System::Enum::ToObject(enumType,
1909                    ((sal_Int32*) seq->elements)[i]), i);
1910             }
1911             *cli_data = arEnum;
1912             break;
1913         }
1914         case typelib_TypeClass_STRUCT:
1915         case typelib_TypeClass_EXCEPTION:
1916         {
1917             TypeDescr element_td( element_type );
1918             System::Array* ar= System::Array::CreateInstance(
1919                 mapUnoType(element_type),nElements);
1920             if (0 < nElements)
1921             {
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 )
1926                 {
1927                     System::Object* val;
1928                     map_to_cli(
1929                         &val, p + (nSize * nPos), element_type, 0, false);
1930                     ar->SetValue(val, nPos);
1931                 }
1932             }
1933 			*cli_data = ar;
1934             break;
1935         }
1936 // ToDo, verify
1937         case typelib_TypeClass_SEQUENCE:
1938         {
1939             System::Array *ar= System::Array::CreateInstance(
1940                 mapUnoType(element_type), nElements);
1941             if (0 < nElements)
1942             {
1943                 TypeDescr element_td( element_type );
1944                 uno_Sequence ** elements = (uno_Sequence**) seq->elements;
1945                 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
1946                 {
1947                     System::Object* val;
1948                     map_to_cli(
1949                         &val, &elements[nPos], element_type, 0, false);
1950                     ar->SetValue(val, nPos);
1951                 }
1952             }
1953             *cli_data = ar;
1954             break;
1955         }
1956         case typelib_TypeClass_INTERFACE:
1957         {
1958             TypeDescr element_td( element_type );
1959             System::Type * ifaceType= mapUnoType(element_type);
1960             System::Array* ar= System::Array::CreateInstance(ifaceType, nElements);
1961 
1962             char * p = (char *)seq->elements;
1963             sal_Int32 nSize = element_td.get()->nSize;
1964             for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
1965             {
1966                 System::Object* val;
1967                 map_to_cli(
1968                     &val, p + (nSize * nPos), element_type, NULL, false);
1969 
1970                 ar->SetValue(val, nPos);
1971             }
1972             *cli_data= ar;
1973             break;
1974         }
1975         default:
1976         {
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() );
1983         }
1984         }
1985         break;
1986     }
1987     case typelib_TypeClass_INTERFACE:
1988     {
1989         uno_Interface * pUnoI = *(uno_Interface * const *)uno_data;
1990         if (0 != pUnoI)
1991         {
1992             TypeDescr td( type );
1993             *cli_data= map_uno2cli( pUnoI, reinterpret_cast<
1994                                           typelib_InterfaceTypeDescription*>(td.get())) ;
1995         }
1996 		else
1997 			*cli_data= NULL;
1998         break;
1999     }
2000     default:
2001     {
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() );
2008     }
2009     }
2010 }
2011 }
2012