1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_cli_ure.hxx"
26
27 #pragma warning(push, 1)
28 #include "windows.h"
29 #pragma warning(pop)
30
31 #include <memory>
32
33
34 #include "rtl/ustring.hxx"
35 #include "rtl/ustrbuf.hxx"
36 #include "uno/sequence2.h"
37 #include "typelib/typedescription.hxx"
38 #include "cli_proxy.h"
39 #include "cli_base.h"
40 #include "cli_bridge.h"
41
42 #using <cli_uretypes.dll>
43
44
45 #undef VOID
46
47 namespace css = com::sun::star;
48
49 namespace sri = System::Runtime::InteropServices;
50 namespace sr = System::Reflection;
51 namespace st = System::Text;
52 namespace ucss = unoidl::com::sun::star;
53
54 using namespace rtl;
55 using namespace std;
56
57
58 namespace cli_uno
59 {
60 System::String* mapUnoPolymorphicName(System::String* unoName);
61 OUString mapCliTypeName(System::String* typeName);
62 System::String* mapCliPolymorphicName(System::String* unoName);
63 System::String* mapPolymorphicName(System::String* unoName, bool bCliToUno);
64
seq_allocate(sal_Int32 nElements,sal_Int32 nSize)65 inline auto_ptr< rtl_mem > seq_allocate( sal_Int32 nElements, sal_Int32 nSize )
66 {
67 auto_ptr< rtl_mem > seq(
68 rtl_mem::allocate( SAL_SEQUENCE_HEADER_SIZE + (nElements * nSize) ) );
69 uno_Sequence * p = (uno_Sequence *)seq.get();
70 p->nRefCount = 1;
71 p->nElements = nElements;
72 return seq;
73 }
74
75
map_uno2cli(uno_Interface * pUnoI,typelib_InterfaceTypeDescription * pTD) const76 System::Object* Bridge::map_uno2cli(uno_Interface * pUnoI, typelib_InterfaceTypeDescription *pTD) const
77 {
78 System::Object* retVal= NULL;
79 // get oid
80 rtl_uString * pOid = 0;
81 (*m_uno_env->getObjectIdentifier)( m_uno_env, &pOid, pUnoI );
82 OSL_ASSERT( 0 != pOid );
83 OUString oid(pOid, SAL_NO_ACQUIRE);
84
85 //see if the interface was already mapped
86 System::Type* ifaceType= mapUnoType(reinterpret_cast<typelib_TypeDescription*>(pTD));
87 System::String* sOid= mapUnoString(oid.pData);
88
89 System::Threading::Monitor::Enter( CliEnvHolder::g_cli_env );
90 try
91 {
92 retVal = CliEnvHolder::g_cli_env->getRegisteredInterface(sOid, ifaceType);
93 if (retVal)
94 {
95 // There is already an registered object. It can either be a proxy
96 // for the UNO object or a real cli object. In the first case we
97 // tell the proxy that it shall also represent the current UNO
98 // interface. If it already does that, then it does nothing
99 if (srr::RemotingServices::IsTransparentProxy(retVal))
100 {
101 UnoInterfaceProxy* p = static_cast<UnoInterfaceProxy*>(
102 srr::RemotingServices::GetRealProxy(retVal));
103 p->addUnoInterface(pUnoI, pTD);
104 }
105 }
106 else
107 {
108 retVal = UnoInterfaceProxy::create(
109 (Bridge *) this, pUnoI, pTD, oid );
110 }
111 }
112 __finally
113 {
114 System::Threading::Monitor::Exit( CliEnvHolder::g_cli_env );
115 }
116
117 return retVal;
118 }
119
map_cli2uno(System::Object * cliObj,typelib_TypeDescription * pTD) const120 uno_Interface* Bridge::map_cli2uno(System::Object* cliObj, typelib_TypeDescription *pTD) const
121 {
122 uno_Interface* retIface = NULL;
123 // get oid from dot net environment
124 System::String* ds_oid = CliEnvHolder::g_cli_env->getObjectIdentifier( cliObj);
125 OUString ousOid = mapCliString(ds_oid);
126 // look if interface is already mapped
127 m_uno_env->getRegisteredInterface(m_uno_env, (void**) &retIface, ousOid.pData,
128 (typelib_InterfaceTypeDescription*) pTD);
129 if ( ! retIface)
130 {
131 System::Threading::Monitor::Enter(__typeof(Cli_environment));
132 try
133 {
134 m_uno_env->getRegisteredInterface(m_uno_env, (void**) &retIface, ousOid.pData,
135 (typelib_InterfaceTypeDescription*) pTD);
136 if ( ! retIface)
137 {
138 retIface = CliProxy::create((Bridge*)this, cliObj, pTD, ousOid);
139 }
140 }
141 __finally
142 {
143 System::Threading::Monitor::Exit(__typeof(Cli_environment));
144 }
145 }
146 return retIface;
147 }
148
loadCliType(rtl_uString * unoName)149 inline System::Type* loadCliType(rtl_uString * unoName)
150 {
151 return loadCliType(mapUnoTypeName(unoName));
152 }
153
loadCliType(System::String * unoName)154 System::Type* loadCliType(System::String * unoName)
155 {
156 System::Type* retVal= NULL;
157 try
158 {
159 //If unoName denotes a polymorphic type, e.g com.sun.star.beans.Defaulted<System.Char>
160 //then we remove the type list, otherwise the type could not be loaded.
161 bool bIsPolymorphic = false;
162
163 System::String * loadName = unoName;
164 int index = unoName->IndexOf('<');
165 if (index != -1)
166 {
167 loadName = unoName->Substring(0, index);
168 bIsPolymorphic = true;
169 }
170 System::AppDomain* currentDomain = System::AppDomain::CurrentDomain;
171 sr::Assembly* assems[] = currentDomain->GetAssemblies();
172 for (int i = 0; i < assems->Length; i++)
173 {
174 retVal = assems[i]->GetType(loadName, false);
175 if (retVal)
176 break;
177 }
178
179 if (retVal == NULL)
180 {
181 System::String * msg = new System::String(S"A type could not be loaded: ");
182 msg = System::String::Concat(msg, loadName);
183 throw BridgeRuntimeError(mapCliString(msg));
184 }
185
186 if (bIsPolymorphic)
187 {
188 retVal = uno::PolymorphicType::GetType(retVal, unoName);
189 }
190 }
191 catch( System::Exception * e)
192 {
193 rtl::OUString ouMessage(mapCliString(e->get_Message()));
194 throw BridgeRuntimeError(ouMessage);
195 }
196 return retVal;
197 }
198
199
mapUnoType(typelib_TypeDescription const * pTD)200 System::Type* mapUnoType(typelib_TypeDescription const * pTD)
201 {
202 return mapUnoType(pTD->pWeakRef);
203 }
204
mapUnoType(typelib_TypeDescriptionReference const * pTD)205 System::Type* mapUnoType(typelib_TypeDescriptionReference const * pTD)
206 {
207 System::Type * retVal = 0;
208 switch (pTD->eTypeClass)
209 {
210 case typelib_TypeClass_VOID:
211 retVal= __typeof(void); break;
212 case typelib_TypeClass_CHAR:
213 retVal= __typeof(System::Char); break;
214 case typelib_TypeClass_BOOLEAN:
215 retVal= __typeof(System::Boolean); break;
216 case typelib_TypeClass_BYTE:
217 retVal= __typeof(System::Byte); break;
218 case typelib_TypeClass_SHORT:
219 retVal= __typeof(System::Int16); break;
220 case typelib_TypeClass_UNSIGNED_SHORT:
221 retVal= __typeof(System::UInt16); break;
222 case typelib_TypeClass_LONG:
223 retVal= __typeof(System::Int32); break;
224 case typelib_TypeClass_UNSIGNED_LONG:
225 retVal= __typeof(System::UInt32); break;
226 case typelib_TypeClass_HYPER:
227 retVal= __typeof(System::Int64); break;
228 case typelib_TypeClass_UNSIGNED_HYPER:
229 retVal= __typeof(System::UInt64); break;
230 case typelib_TypeClass_FLOAT:
231 retVal= __typeof(System::Single); break;
232 case typelib_TypeClass_DOUBLE:
233 retVal= __typeof(System::Double); break;
234 case typelib_TypeClass_STRING:
235 retVal= __typeof(System::String); break;
236 case typelib_TypeClass_TYPE:
237 retVal= __typeof(System::Type); break;
238 case typelib_TypeClass_ANY:
239 retVal= __typeof(uno::Any); break;
240 case typelib_TypeClass_ENUM:
241 case typelib_TypeClass_STRUCT:
242 case typelib_TypeClass_EXCEPTION:
243 retVal= loadCliType(pTD->pTypeName); break;
244 case typelib_TypeClass_INTERFACE:
245 {
246 //special handling for XInterface, since it does not exist in cli.
247 rtl::OUString usXInterface(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.XInterface"));
248 if (usXInterface.equals(pTD->pTypeName))
249 retVal= __typeof(System::Object);
250 else
251 retVal= loadCliType(pTD->pTypeName);
252 break;
253 }
254 case typelib_TypeClass_SEQUENCE:
255 {
256 css::uno::TypeDescription seqType(
257 const_cast<typelib_TypeDescriptionReference*>(pTD));
258 typelib_TypeDescriptionReference* pElementTDRef=
259 reinterpret_cast<typelib_IndirectTypeDescription*>(seqType.get())->pType;
260 switch (pElementTDRef->eTypeClass)
261 {
262 case typelib_TypeClass_CHAR:
263 retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArChar)); break;
264 case typelib_TypeClass_BOOLEAN:
265 retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArBoolean));
266 break;
267 case typelib_TypeClass_BYTE:
268 retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArByte));
269 break;
270 case typelib_TypeClass_SHORT:
271 retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArInt16));
272 break;
273 case typelib_TypeClass_UNSIGNED_SHORT:
274 retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArUInt16));
275 break;
276 case typelib_TypeClass_LONG:
277 retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArInt32));
278 break;
279 case typelib_TypeClass_UNSIGNED_LONG:
280 retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArUInt32));
281 break;
282 case typelib_TypeClass_HYPER:
283 retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArInt64));
284 break;
285 case typelib_TypeClass_UNSIGNED_HYPER:
286 retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArUInt64));
287 break;
288 case typelib_TypeClass_FLOAT:
289 retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArSingle));
290 break;
291 case typelib_TypeClass_DOUBLE:
292 retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArDouble));
293 break;
294 case typelib_TypeClass_STRING:
295 retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArString));
296 break;
297 case typelib_TypeClass_TYPE:
298 retVal= System::Type::GetType(const_cast<System::String*>(Constants::sArType));
299 break;
300 case typelib_TypeClass_ANY:
301 case typelib_TypeClass_ENUM:
302 case typelib_TypeClass_EXCEPTION:
303 case typelib_TypeClass_STRUCT:
304 case typelib_TypeClass_INTERFACE:
305 case typelib_TypeClass_SEQUENCE:
306 {
307 retVal= loadCliType(pTD->pTypeName);
308 break;
309 }
310 default:
311 //All cases should be handled by the case statements above
312 OSL_ASSERT(0);
313 break;
314 }
315 break;
316 }
317 default:
318 OSL_ASSERT(false);
319 break;
320 }
321 return retVal;
322 }
323
324 /** Returns an acquired td.
325 */
mapCliType(System::Type * cliType)326 typelib_TypeDescriptionReference* mapCliType(System::Type* cliType)
327 {
328 typelib_TypeDescriptionReference* retVal= NULL;
329 if (cliType == NULL)
330 {
331 retVal = * typelib_static_type_getByTypeClass(
332 typelib_TypeClass_VOID );
333 typelib_typedescriptionreference_acquire( retVal );
334 return retVal;
335 }
336 //check for Enum first,
337 //because otherwise case System::TypeCode::Int32 applies
338 if (cliType->get_IsEnum())
339 {
340 OUString usTypeName= mapCliTypeName(cliType->get_FullName());
341 css::uno::Type unoType(css::uno::TypeClass_ENUM, usTypeName);
342 retVal= unoType.getTypeLibType();
343 typelib_typedescriptionreference_acquire(retVal);
344 }
345 else
346 {
347 switch (System::Type::GetTypeCode(cliType))
348 {
349 case System::TypeCode::Boolean:
350 retVal = * typelib_static_type_getByTypeClass(
351 typelib_TypeClass_BOOLEAN );
352 typelib_typedescriptionreference_acquire( retVal );
353 break;
354 case System::TypeCode::Char:
355 retVal = * typelib_static_type_getByTypeClass(
356 typelib_TypeClass_CHAR );
357 typelib_typedescriptionreference_acquire( retVal );
358 break;
359 case System::TypeCode::Byte:
360 retVal = * typelib_static_type_getByTypeClass(
361 typelib_TypeClass_BYTE );
362 typelib_typedescriptionreference_acquire( retVal );
363 break;
364 case System::TypeCode::Int16:
365 retVal = * typelib_static_type_getByTypeClass(
366 typelib_TypeClass_SHORT );
367 typelib_typedescriptionreference_acquire( retVal );
368 break;
369 case System::TypeCode::Int32:
370 retVal = * typelib_static_type_getByTypeClass(
371 typelib_TypeClass_LONG );
372 typelib_typedescriptionreference_acquire( retVal );
373 break;
374 case System::TypeCode::Int64:
375 retVal = * typelib_static_type_getByTypeClass(
376 typelib_TypeClass_HYPER );
377 typelib_typedescriptionreference_acquire( retVal );
378 break;
379 case System::TypeCode::UInt16:
380 retVal = * typelib_static_type_getByTypeClass(
381 typelib_TypeClass_UNSIGNED_SHORT );
382 typelib_typedescriptionreference_acquire( retVal );
383 break;
384 case System::TypeCode::UInt32:
385 retVal = * typelib_static_type_getByTypeClass(
386 typelib_TypeClass_UNSIGNED_LONG );
387 typelib_typedescriptionreference_acquire( retVal );
388 break;
389 case System::TypeCode::UInt64:
390 retVal = * typelib_static_type_getByTypeClass(
391 typelib_TypeClass_UNSIGNED_HYPER );
392 typelib_typedescriptionreference_acquire( retVal );
393 break;
394 case System::TypeCode::Single:
395 retVal = * typelib_static_type_getByTypeClass(
396 typelib_TypeClass_FLOAT );
397 typelib_typedescriptionreference_acquire( retVal );
398 break;
399 case System::TypeCode::Double:
400 retVal = * typelib_static_type_getByTypeClass(
401 typelib_TypeClass_DOUBLE );
402 typelib_typedescriptionreference_acquire( retVal );
403 break;
404 case System::TypeCode::String:
405 retVal = * typelib_static_type_getByTypeClass(
406 typelib_TypeClass_STRING );
407 typelib_typedescriptionreference_acquire( retVal );
408 break;
409 default:
410 break;
411 }
412 }
413 if (retVal == NULL)
414 {
415 System::String* cliTypeName= cliType->get_FullName();
416 // Void
417 if (const_cast<System::String*>(Constants::sVoid)->Equals(
418 cliTypeName))
419 {
420 retVal = * typelib_static_type_getByTypeClass(
421 typelib_TypeClass_VOID );
422 typelib_typedescriptionreference_acquire( retVal );
423 }
424 // Type
425 else if (const_cast<System::String*>(Constants::sType)->Equals(
426 cliTypeName))
427 {
428 retVal = * typelib_static_type_getByTypeClass(
429 typelib_TypeClass_TYPE );
430 typelib_typedescriptionreference_acquire( retVal );
431 }
432 // Any
433 else if (const_cast<System::String*>(Constants::sAny)->Equals(
434 cliTypeName))
435 {
436 retVal = * typelib_static_type_getByTypeClass(
437 typelib_TypeClass_ANY );
438 typelib_typedescriptionreference_acquire( retVal );
439 }
440 //struct, interfaces, sequences
441 else
442 {
443 OUString usTypeName;
444 uno::PolymorphicType * poly = dynamic_cast<uno::PolymorphicType*>(cliType);
445 if (poly != NULL)
446 usTypeName = mapCliTypeName( poly->PolymorphicName);
447 else
448 usTypeName = mapCliTypeName(cliTypeName);
449 typelib_TypeDescription* td = NULL;
450 typelib_typedescription_getByName(&td, usTypeName.pData);
451 if (td)
452 {
453 retVal = td->pWeakRef;
454 typelib_typedescriptionreference_acquire(retVal);
455 typelib_typedescription_release(td);
456 }
457 }
458 }
459 if (retVal == NULL)
460 {
461 OUStringBuffer buf( 128 );
462 buf.appendAscii(
463 RTL_CONSTASCII_STRINGPARAM("[cli_uno bridge] mapCliType():"
464 "could not map type: ") );
465 buf.append(mapCliString(cliType->get_FullName()));
466 throw BridgeRuntimeError( buf.makeStringAndClear() );
467 }
468 return retVal;
469 }
470
471 /**
472 Otherwise a leading "unoidl." is removed.
473 */
mapUnoTypeName(rtl_uString const * typeName)474 System::String* mapUnoTypeName(rtl_uString const * typeName)
475 {
476 OUString usUnoName( const_cast< rtl_uString * >( typeName ) );
477 st::StringBuilder* buf= new st::StringBuilder();
478 //determine if the type is a sequence and its dimensions
479 int dims= 0;
480 if (usUnoName[0] == '[')
481 {
482 sal_Int32 index= 1;
483 while (true)
484 {
485 if (usUnoName[index++] == ']')
486 dims++;
487 if (usUnoName[index++] != '[')
488 break;
489 }
490 usUnoName = usUnoName.copy(index - 1);
491 }
492 System::String * sUnoName = mapUnoString(usUnoName.pData);
493 if (sUnoName->Equals(const_cast<System::String*>(Constants::usBool)))
494 buf->Append(const_cast<System::String*>(Constants::sBoolean));
495 else if (sUnoName->Equals(const_cast<System::String*>(Constants::usChar)))
496 buf->Append(const_cast<System::String*>(Constants::sChar));
497 else if (sUnoName->Equals(const_cast<System::String*>(Constants::usByte)))
498 buf->Append(const_cast<System::String*>(Constants::sByte));
499 else if (sUnoName->Equals(const_cast<System::String*>(Constants::usShort)))
500 buf->Append(const_cast<System::String*>(Constants::sInt16));
501 else if (sUnoName->Equals(const_cast<System::String*>(Constants::usUShort)))
502 buf->Append(const_cast<System::String*>(Constants::sUInt16));
503 else if (sUnoName->Equals(const_cast<System::String*>(Constants::usLong)))
504 buf->Append(const_cast<System::String*>(Constants::sInt32));
505 else if (sUnoName->Equals(const_cast<System::String*>(Constants::usULong)))
506 buf->Append(const_cast<System::String*>(Constants::sUInt32));
507 else if (sUnoName->Equals(const_cast<System::String*>(Constants::usHyper)))
508 buf->Append(const_cast<System::String*>(Constants::sInt64));
509 else if (sUnoName->Equals(const_cast<System::String*>(Constants::usUHyper)))
510 buf->Append(const_cast<System::String*>(Constants::sUInt64));
511 else if (sUnoName->Equals(const_cast<System::String*>(Constants::usFloat)))
512 buf->Append(const_cast<System::String*>(Constants::sSingle));
513 else if (sUnoName->Equals(const_cast<System::String*>(Constants::usDouble)))
514 buf->Append(const_cast<System::String*>(Constants::sDouble));
515 else if (sUnoName->Equals(const_cast<System::String*>(Constants::usString)))
516 buf->Append(const_cast<System::String*>(Constants::sString));
517 else if (sUnoName->Equals(const_cast<System::String*>(Constants::usVoid)))
518 buf->Append(const_cast<System::String*>(Constants::sVoid));
519 else if (sUnoName->Equals(const_cast<System::String*>(Constants::usType)))
520 buf->Append(const_cast<System::String*>(Constants::sType));
521 else if (sUnoName->Equals(const_cast<System::String*>(Constants::usXInterface)))
522 buf->Append(const_cast<System::String*>(Constants::sObject));
523 else if (sUnoName->Equals(const_cast<System::String*>(Constants::usAny)))
524 {
525 buf->Append(const_cast<System::String*>(Constants::sAny));
526 }
527 else
528 {
529 //put "unoidl." at the beginning
530 buf->Append(const_cast<System::String*>(Constants::sUnoidl));
531 //for polymorphic struct types remove the brackets, e.g mystruct<bool> -> mystruct
532 System::String * sName = mapUnoPolymorphicName(sUnoName);
533 buf->Append(sName);
534 }
535 // apend []
536 for (;dims--;)
537 buf->Append(const_cast<System::String*>(Constants::sBrackets));
538
539 return buf->ToString();
540 }
541
542
543
544
545 /** For example, there is a uno type
546 com.sun.star.Foo<char, long>.
547 The values in the type list
548 are uno types and are replaced by cli types, such as System.Char,
549 System.Int32, etc.
550 The pr�fix unoidl is not added.
551 */
mapUnoPolymorphicName(System::String * unoName)552 inline System::String* mapUnoPolymorphicName(System::String* unoName)
553 {
554 return mapPolymorphicName(unoName, false);
555 }
556 /** For example, there is a type name such as
557 com.sun.star.Foo<System.Char, System.Int32>.
558 The values in the type list
559 are CLI types and are replaced by uno types, such as char,
560 long, etc.
561 The pr�fix unoidl remains.
562 */
mapCliPolymorphicName(System::String * unoName)563 inline System::String* mapCliPolymorphicName(System::String* unoName)
564 {
565 return mapPolymorphicName(unoName, true);
566 }
567
mapPolymorphicName(System::String * unoName,bool bCliToUno)568 System::String* mapPolymorphicName(System::String* unoName, bool bCliToUno)
569 {
570 int index = unoName->IndexOf('<');
571 if (index == -1)
572 return unoName;
573
574 System::Text::StringBuilder * builder = new System::Text::StringBuilder(256);
575 builder->Append(unoName->Substring(0, index +1 ));
576
577 //Find the first occurrence of ','
578 //If the parameter is a polymorphic struct then we neede to ignore everything
579 //between the brackets because it can also contain commas
580 //get the type list within < and >
581 int endIndex = unoName->Length - 1;
582 index++;
583 int cur = index;
584 int countParams = 0;
585 while (cur <= endIndex)
586 {
587 System::Char c = unoName->Chars[cur];
588 if (c == ',' || c == '>')
589 {
590 //insert a comma if needed
591 if (countParams != 0)
592 builder->Append(S",");
593 countParams++;
594 System::String * sParam = unoName->Substring(index, cur - index);
595 //skip the comma
596 cur++;
597 //the the index to the beginning of the next param
598 index = cur;
599 if (bCliToUno)
600 {
601 builder->Append( mapCliTypeName(sParam).getStr());
602 }
603 else
604 {
605 OUString s = mapCliString(sParam);
606 builder->Append(mapUnoTypeName(s.pData));
607 }
608 }
609 else if (c == '<')
610 {
611 cur++;
612 //continue until the matching '>'
613 int numNested = 0;
614 for (;;cur++)
615 {
616 System::Char curChar = unoName->Chars[cur];
617 if (curChar == '<')
618 {
619 numNested ++;
620 }
621 else if (curChar == '>')
622 {
623 if (numNested > 0)
624 numNested--;
625 else
626 break;
627 }
628 }
629 }
630 cur++;
631 }
632
633 builder->Append((System::Char) '>');
634 return builder->ToString();
635 }
636
mapCliTypeName(System::String * typeName)637 OUString mapCliTypeName(System::String* typeName)
638 {
639 int dims= 0;
640 // Array? determine the "rank" (number of "[]")
641 // move from the rightmost end to the left, for example
642 // unoidl.PolymorphicStruct<System.Char[]>[]
643 // has only a "dimension" of 1
644 int cur = typeName->Length - 1;
645 bool bRightBracket = false;
646 while (cur >= 0)
647 {
648 System::Char c = typeName->Chars[cur];
649 if (c == ']')
650 {
651 bRightBracket = true;
652 }
653 else if (c == '[')
654 {
655 if (!bRightBracket)
656 throw BridgeRuntimeError(
657 OUSTR("Typename is wrong. No matching brackets for sequence. Name is: ") +
658 mapCliString(typeName));
659 bRightBracket = false;
660 dims ++;
661 }
662 else
663 {
664 if (bRightBracket)
665 throw BridgeRuntimeError(
666 OUSTR("Typename is wrong. No matching brackets for sequence. Name is: ") +
667 mapCliString(typeName));
668 break;
669 }
670 cur--;
671 }
672
673 if (bRightBracket || cur < 0)
674 throw BridgeRuntimeError(
675 OUSTR("Typename is wrong. ") +
676 mapCliString(typeName));
677
678 typeName = typeName->Substring(0, cur + 1);
679
680 System::Text::StringBuilder * buf = new System::Text::StringBuilder(512);
681
682 //Put the "[]" at the beginning of the uno type name
683 for (;dims--;)
684 buf->Append(const_cast<System::String*>(Constants::usBrackets));
685
686 if (typeName->Equals(const_cast<System::String*>(Constants::sBoolean)))
687 buf->Append(const_cast<System::String*>(Constants::usBool));
688 else if (typeName->Equals(const_cast<System::String*>(Constants::sChar)))
689 buf->Append(const_cast<System::String*>(Constants::usChar));
690 else if (typeName->Equals(const_cast<System::String*>(Constants::sByte)))
691 buf->Append(const_cast<System::String*>(Constants::usByte));
692 else if (typeName->Equals(const_cast<System::String*>(Constants::sInt16)))
693 buf->Append(const_cast<System::String*>(Constants::usShort));
694 else if (typeName->Equals(const_cast<System::String*>(Constants::sUInt16)))
695 buf->Append(const_cast<System::String*>(Constants::usUShort));
696 else if (typeName->Equals(const_cast<System::String*>(Constants::sInt32)))
697 buf->Append(const_cast<System::String*>(Constants::usLong));
698 else if (typeName->Equals(const_cast<System::String*>(Constants::sUInt32)))
699 buf->Append(const_cast<System::String*>(Constants::usULong));
700 else if (typeName->Equals(const_cast<System::String*>(Constants::sInt64)))
701 buf->Append(const_cast<System::String*>(Constants::usHyper));
702 else if (typeName->Equals(const_cast<System::String*>(Constants::sUInt64)))
703 buf->Append(const_cast<System::String*>(Constants::usUHyper));
704 else if (typeName->Equals(const_cast<System::String*>(Constants::sSingle)))
705 buf->Append(const_cast<System::String*>(Constants::usFloat));
706 else if (typeName->Equals(const_cast<System::String*>(Constants::sDouble)))
707 buf->Append(const_cast<System::String*>(Constants::usDouble));
708 else if (typeName->Equals(const_cast<System::String*>(Constants::sString)))
709 buf->Append(const_cast<System::String*>(Constants::usString));
710 else if (typeName->Equals(const_cast<System::String*>(Constants::sVoid)))
711 buf->Append(const_cast<System::String*>(Constants::usVoid));
712 else if (typeName->Equals(const_cast<System::String*>(Constants::sType)))
713 buf->Append(const_cast<System::String*>(Constants::usType));
714 else if (typeName->Equals(const_cast<System::String*>(Constants::sObject)))
715 buf->Append(const_cast<System::String*>(Constants::usXInterface));
716 else if (typeName->Equals(const_cast<System::String*>(Constants::sAny)))
717 buf->Append(const_cast<System::String*>(Constants::usAny));
718 else
719 {
720 System::String * sName = mapCliPolymorphicName(typeName);
721 int i= sName->IndexOf(L'.');
722 buf->Append(sName->Substring(i + 1));
723 }
724 return mapCliString(buf->ToString());
725 }
726 /** Maps uno types to dot net types.
727 * If uno_data is null then the type description is converted to System::Type
728 */
mapUnoString(rtl_uString const * data)729 inline System::String* mapUnoString( rtl_uString const * data)
730 {
731 OSL_ASSERT(data);
732 return new System::String((__wchar_t*) data->buffer, 0, data->length);
733 }
734
mapCliString(System::String const * data)735 OUString mapCliString(System::String const * data)
736 {
737
738 if (data != NULL)
739 {
740 OSL_ASSERT(sizeof(wchar_t) == sizeof(sal_Unicode));
741 wchar_t const __pin * pdata= PtrToStringChars(data);
742 return OUString(pdata, const_cast<System::String*>(data)->get_Length());
743 }
744 else
745 {
746 return OUString();
747 }
748 }
749
750 // ToDo convert cli types to expected types, e.g a long to a short where the uno type
751 // is a sal_Int16. This could be necessary if a scripting language (typeless) is used
752 // @param assign the uno_data has to be destructed (in/out args)
map_to_uno(void * uno_data,System::Object * cli_data,typelib_TypeDescriptionReference * type,bool assign) const753 void Bridge::map_to_uno(void * uno_data, System::Object* cli_data,
754 typelib_TypeDescriptionReference * type,
755 bool assign) const
756 {
757 try{
758 switch (type->eTypeClass)
759 {
760 case typelib_TypeClass_VOID:
761 break;
762 case typelib_TypeClass_CHAR:
763 {
764 System::Char aChar= *__try_cast<System::Char*>(cli_data);
765 *(sal_Unicode*) uno_data= aChar;
766 break;
767 }
768 case typelib_TypeClass_BOOLEAN:
769 {
770 System::Boolean aBool= *__try_cast<System::Boolean*>(cli_data);
771 *(sal_Bool*)uno_data= aBool == true ? sal_True : sal_False;
772 break;
773 }
774 case typelib_TypeClass_BYTE:
775 {
776 System::Byte aByte= *__try_cast<System::Byte*>(cli_data);
777 *(sal_Int8*) uno_data= aByte;
778 break;
779 }
780 case typelib_TypeClass_SHORT:
781 {
782 System::Int16 aShort= *__try_cast<System::Int16*>(cli_data);
783 *(sal_Int16*) uno_data= aShort;
784 break;
785 }
786 case typelib_TypeClass_UNSIGNED_SHORT:
787 {
788 System::UInt16 aUShort= *__try_cast<System::UInt16*>(cli_data);
789 *(sal_uInt16*) uno_data= aUShort;
790 break;
791 }
792 case typelib_TypeClass_LONG:
793 {
794 System::Int32 aLong= *__try_cast<System::Int32*>(cli_data);
795 *(sal_Int32*) uno_data= aLong;
796 break;
797 }
798 case typelib_TypeClass_UNSIGNED_LONG:
799 {
800 System::UInt32 aULong= *__try_cast<System::UInt32*>(cli_data);
801 *(sal_uInt32*) uno_data= aULong;
802 break;
803 }
804 case typelib_TypeClass_HYPER:
805 {
806 System::Int64 aHyper= *__try_cast<System::Int64*>(cli_data);
807 *(sal_Int64*) uno_data= aHyper;
808 break;
809 }
810 case typelib_TypeClass_UNSIGNED_HYPER:
811 {
812 System::UInt64 aLong= *__try_cast<System::UInt64*>(cli_data);
813 *(sal_uInt64*) uno_data= aLong;
814 break;
815 }
816 case typelib_TypeClass_FLOAT:
817 {
818 System::Single aFloat= *__try_cast<System::Single*>(cli_data);
819 *(float*) uno_data= aFloat;
820 break;
821 }
822 case typelib_TypeClass_DOUBLE:
823 {
824 System::Double aDouble= *__try_cast<System::Double*>(cli_data);
825 *(double*) uno_data= aDouble;
826 break;
827 }
828 case typelib_TypeClass_STRING:
829 {
830 if (assign && *(rtl_uString**) uno_data)
831 rtl_uString_release(*(rtl_uString**) uno_data);
832
833 *(rtl_uString **)uno_data = 0;
834 if (cli_data == NULL)
835 {
836 rtl_uString_new((rtl_uString**) uno_data);
837 }
838 else
839 {
840 System::String *s= __try_cast<System::String*>(cli_data);
841 wchar_t const __pin * pdata= PtrToStringChars(s);
842 rtl_uString_newFromStr_WithLength( (rtl_uString**) uno_data,
843 pdata, s->get_Length() );
844 }
845 break;
846 }
847 case typelib_TypeClass_TYPE:
848 {
849 typelib_TypeDescriptionReference* td= mapCliType(__try_cast<System::Type*>(
850 cli_data));
851 if (assign)
852 {
853 typelib_typedescriptionreference_release(
854 *(typelib_TypeDescriptionReference **)uno_data );
855 }
856 *(typelib_TypeDescriptionReference **)uno_data = td;
857 break;
858 }
859 case typelib_TypeClass_ANY:
860 {
861 uno_Any * pAny = (uno_Any *)uno_data;
862 if (cli_data == NULL) // null-ref or uninitialized any maps to empty any
863 {
864 if (assign)
865 uno_any_destruct( pAny, 0 );
866 uno_any_construct( pAny, 0, 0, 0 );
867 break;
868 }
869 uno::Any aAny= *__try_cast<uno::Any*>(cli_data);
870 css::uno::Type value_td( mapCliType(aAny.Type), SAL_NO_ACQUIRE);
871
872 if (assign)
873 uno_any_destruct( pAny, 0 );
874
875 try
876 {
877 switch (value_td.getTypeClass())
878 {
879 case typelib_TypeClass_VOID:
880 pAny->pData = &pAny->pReserved;
881 break;
882 case typelib_TypeClass_CHAR:
883 pAny->pData = &pAny->pReserved;
884 *(sal_Unicode*) &pAny->pReserved = *__try_cast<System::Char*>(aAny.Value);
885 break;
886 case typelib_TypeClass_BOOLEAN:
887 pAny->pData = &pAny->pReserved;
888 *(sal_Bool *) &pAny->pReserved = *__try_cast<System::Boolean*>(aAny.Value);
889 break;
890 case typelib_TypeClass_BYTE:
891 pAny->pData = &pAny->pReserved;
892 *(sal_Int8*) &pAny->pReserved = *__try_cast<System::Byte*>(aAny.Value);
893 break;
894 case typelib_TypeClass_SHORT:
895 pAny->pData = &pAny->pReserved;
896 *(sal_Int16*) &pAny->pReserved = *__try_cast<System::Int16*>(aAny.Value);
897 break;
898 case typelib_TypeClass_UNSIGNED_SHORT:
899 pAny->pData = &pAny->pReserved;
900 *(sal_uInt16*) &pAny->pReserved = *__try_cast<System::UInt16*>(aAny.Value);
901 break;
902 case typelib_TypeClass_LONG:
903 pAny->pData = &pAny->pReserved;
904 *(sal_Int32*) &pAny->pReserved = *__try_cast<System::Int32*>(aAny.Value);
905 break;
906 case typelib_TypeClass_UNSIGNED_LONG:
907 pAny->pData = &pAny->pReserved;
908 *(sal_uInt32*) &pAny->pReserved = *__try_cast<System::UInt32*>(aAny.Value);
909 break;
910 case typelib_TypeClass_HYPER:
911 if (sizeof (sal_Int64) <= sizeof (void *))
912 {
913 pAny->pData = &pAny->pReserved;
914 *(sal_Int64*) &pAny->pReserved = *__try_cast<System::Int64*>(aAny.Value);
915 }
916 else
917 {
918 auto_ptr< rtl_mem > mem( rtl_mem::allocate( sizeof (sal_Int64) ) );
919 *(sal_Int64 *) mem.get()= *__try_cast<System::Int64*>(aAny.Value);
920 pAny->pData = mem.release();
921 }
922 break;
923 case typelib_TypeClass_UNSIGNED_HYPER:
924 if (sizeof (sal_uInt64) <= sizeof (void *))
925 {
926 pAny->pData = &pAny->pReserved;
927 *(sal_uInt64*) &pAny->pReserved = *__try_cast<System::UInt64*>(aAny.Value);
928 }
929 else
930 {
931 auto_ptr< rtl_mem > mem( rtl_mem::allocate( sizeof (sal_uInt64) ) );
932 *(sal_uInt64 *) mem.get()= *__try_cast<System::UInt64*>(aAny.Value);
933 pAny->pData = mem.release();
934 }
935 break;
936 case typelib_TypeClass_FLOAT:
937 if (sizeof (float) <= sizeof (void *))
938 {
939 pAny->pData = &pAny->pReserved;
940 *(float*) &pAny->pReserved = *__try_cast<System::Single*>(aAny.Value);
941 }
942 else
943 {
944 auto_ptr< rtl_mem > mem( rtl_mem::allocate( sizeof (float) ) );
945 *(float*) mem.get() = *__try_cast<System::Single*>(aAny.Value);
946 pAny->pData = mem.release();
947 }
948 break;
949 case typelib_TypeClass_DOUBLE:
950 if (sizeof (double) <= sizeof (void *))
951 {
952 pAny->pData = &pAny->pReserved;
953 *(double*) &pAny->pReserved= *__try_cast<System::Double*>(aAny.Value);
954 }
955 else
956 {
957 auto_ptr< rtl_mem > mem( rtl_mem::allocate( sizeof (double) ) );
958 *(double*) mem.get()= *__try_cast<System::Double*>(aAny.Value);
959 pAny->pData= mem.release();
960 }
961 break;
962 case typelib_TypeClass_STRING: // anies often contain strings; copy string directly
963 {
964 pAny->pData= &pAny->pReserved;
965 OUString _s = mapCliString(static_cast<System::String*>(aAny.Value));
966 pAny->pReserved= _s.pData;
967 rtl_uString_acquire(_s.pData);
968 break;
969 }
970 case typelib_TypeClass_TYPE:
971 case typelib_TypeClass_ENUM: //ToDo copy enum direct
972 case typelib_TypeClass_SEQUENCE:
973 case typelib_TypeClass_INTERFACE:
974 pAny->pData = &pAny->pReserved;
975 pAny->pReserved = 0;
976 map_to_uno(
977 &pAny->pReserved, aAny.Value, value_td.getTypeLibType(),
978 false /* no assign */);
979 break;
980 case typelib_TypeClass_STRUCT:
981 case typelib_TypeClass_EXCEPTION:
982 {
983 css::uno::Type anyType(value_td);
984 typelib_TypeDescription* td= NULL;
985 anyType.getDescription(&td);
986 auto_ptr< rtl_mem > mem(rtl_mem::allocate(td->nSize));
987 typelib_typedescription_release(td);
988 map_to_uno(
989 mem.get(), aAny.Value, value_td.getTypeLibType(),
990 false /* no assign */);
991 pAny->pData = mem.release();
992 break;
993 }
994 default:
995 {
996 OUStringBuffer buf( 128 );
997 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
998 buf.append(value_td.getTypeName());
999 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] unsupported value type of any!") );
1000 throw BridgeRuntimeError( buf.makeStringAndClear() );
1001 }
1002 }
1003 }
1004 catch(System::InvalidCastException* )
1005 {
1006 // ToDo check this
1007 if (assign)
1008 uno_any_construct( pAny, 0, 0, 0 ); // restore some valid any
1009 OUStringBuffer buf( 256 );
1010 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():Any") );
1011 buf.append(value_td.getTypeName());
1012 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("]The Any type "));
1013 buf.append(value_td.getTypeName());
1014 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" does not correspont "
1015 "to its value type: ") );
1016 if(aAny.Value != NULL)
1017 {
1018 css::uno::Type td(mapCliType(aAny.Value->GetType()), SAL_NO_ACQUIRE);
1019 buf.append(td.getTypeName());
1020 }
1021 if (assign)
1022 uno_any_construct( pAny, 0, 0, 0 ); // restore some valid any
1023 throw BridgeRuntimeError( buf.makeStringAndClear() );
1024 }
1025 catch (BridgeRuntimeError& )
1026 {
1027 if (assign)
1028 uno_any_construct( pAny, 0, 0, 0 ); // restore some valid any
1029 throw;
1030 }
1031 catch (...)
1032 {
1033 if (assign)
1034 uno_any_construct( pAny, 0, 0, 0 ); // restore some valid any
1035 throw;
1036 }
1037
1038 pAny->pType = value_td.getTypeLibType();
1039 typelib_typedescriptionreference_acquire(pAny->pType);
1040 break;
1041 }
1042 case typelib_TypeClass_ENUM:
1043 {
1044 // InvalidCastException is caught at the end of this method
1045 System::Int32 aEnum= System::Convert::ToInt32((cli_data));
1046 *(sal_Int32*) uno_data = aEnum;
1047 break;
1048 }
1049 case typelib_TypeClass_STRUCT:
1050 case typelib_TypeClass_EXCEPTION:
1051 {
1052 css::uno::TypeDescription td(type);
1053 typelib_CompoundTypeDescription * comp_td =
1054 (typelib_CompoundTypeDescription*) td.get();
1055
1056 typelib_StructTypeDescription * struct_td = NULL;
1057 if (type->eTypeClass == typelib_TypeClass_STRUCT)
1058 struct_td = (typelib_StructTypeDescription*) td.get();
1059
1060 if ( ! ((typelib_TypeDescription*) comp_td)->bComplete)
1061 ::typelib_typedescription_complete(
1062 (typelib_TypeDescription**) & comp_td );
1063
1064 sal_Int32 nMembers = comp_td->nMembers;
1065 boolean bException= false;
1066 System::Type* cliType = NULL;
1067 if (cli_data)
1068 cliType = cli_data->GetType();
1069
1070 if (0 != comp_td->pBaseTypeDescription)
1071 {
1072 map_to_uno(
1073 uno_data, cli_data,
1074 ((typelib_TypeDescription *)comp_td->pBaseTypeDescription)->pWeakRef,
1075 assign);
1076 }
1077 sal_Int32 nPos = 0;
1078 try
1079 {
1080 typelib_TypeDescriptionReference * member_type= NULL;
1081
1082 rtl::OUString usUnoException(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.Exception"));
1083 for (; nPos < nMembers; ++nPos)
1084 {
1085 member_type= comp_td->ppTypeRefs[nPos];
1086 #if OSL_DEBUG_LEVEL >= 2
1087 System::String* __s;
1088 sr::FieldInfo* arFields[];
1089 __s = mapUnoString(comp_td->ppMemberNames[nPos]);
1090 arFields = cliType != NULL ? cliType->GetFields() : NULL;
1091 #endif
1092 System::Object* val= NULL;
1093 if (cli_data != NULL)
1094 {
1095 sr::FieldInfo* aField= cliType->GetField(
1096 mapUnoString(comp_td->ppMemberNames[nPos]));
1097 // special case for Exception.Message property
1098 // The com.sun.star.uno.Exception.Message field is mapped to the
1099 // System.Exception property. Type.GetField("Message") returns null
1100 if ( ! aField && usUnoException.equals(td.get()->pTypeName))
1101 {// get Exception.Message property
1102 rtl::OUString usMessageMember(RTL_CONSTASCII_USTRINGPARAM("Message"));
1103 if (usMessageMember.equals(comp_td->ppMemberNames[nPos]))
1104 {
1105 sr::PropertyInfo* pi= cliType->GetProperty(
1106 mapUnoString(comp_td->ppMemberNames[nPos]));
1107 val= pi->GetValue(cli_data, NULL);
1108 }
1109 else
1110 {
1111 OUStringBuffer buf(512);
1112 buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("[map_to_uno(): Member: "));
1113 buf.append(comp_td->ppMemberNames[nPos]);
1114 throw BridgeRuntimeError(buf.makeStringAndClear());
1115 }
1116 }
1117 else
1118 {
1119 val= aField->GetValue(cli_data);
1120 }
1121 }
1122 void * p = (char *) uno_data + comp_td->pMemberOffsets[ nPos ];
1123 //When using polymorphic structs then the parameterized members can be null.
1124 //Then we set a default value.
1125 bool bDefault = ((struct_td != NULL
1126 && struct_td->pParameterizedTypes != NULL
1127 && struct_td->pParameterizedTypes[nPos] == sal_True
1128 && val == NULL)
1129 || cli_data == NULL) ? true : false;
1130 switch (member_type->eTypeClass)
1131 {
1132 case typelib_TypeClass_CHAR:
1133 if (bDefault)
1134 *(sal_Unicode*) p = 0;
1135 else
1136 *(sal_Unicode*) p = *__try_cast<System::Char*>(val);
1137 break;
1138 case typelib_TypeClass_BOOLEAN:
1139 if (bDefault)
1140 *(sal_Bool*) p = sal_False;
1141 else
1142 *(sal_Bool*) p = *__try_cast<System::Boolean*>(val);
1143 break;
1144 case typelib_TypeClass_BYTE:
1145 if (bDefault)
1146 *(sal_Int8*) p = 0;
1147 else
1148 *(sal_Int8*) p = *__try_cast<System::Byte*>(val);
1149 break;
1150 case typelib_TypeClass_SHORT:
1151 if (bDefault)
1152 *(sal_Int16*) p = 0;
1153 else
1154 *(sal_Int16*) p = *__try_cast<System::Int16*>(val);
1155 break;
1156 case typelib_TypeClass_UNSIGNED_SHORT:
1157 if (bDefault)
1158 *(sal_uInt16*) p = 0;
1159 else
1160 *(sal_uInt16*) p = *__try_cast<System::UInt16*>(val);
1161 break;
1162 case typelib_TypeClass_LONG:
1163 if (bDefault)
1164 *(sal_Int32*) p = 0;
1165 else
1166 *(sal_Int32*) p = *__try_cast<System::Int32*>(val);
1167 break;
1168 case typelib_TypeClass_UNSIGNED_LONG:
1169 if (bDefault)
1170 *(sal_uInt32*) p = 0;
1171 else
1172 *(sal_uInt32*) p = *__try_cast<System::UInt32*>(val);
1173 break;
1174 case typelib_TypeClass_HYPER:
1175 if (bDefault)
1176 *(sal_Int64*) p = 0;
1177 else
1178 *(sal_Int64*) p = *__try_cast<System::Int64*>(val);
1179 break;
1180 case typelib_TypeClass_UNSIGNED_HYPER:
1181 if (bDefault)
1182 *(sal_uInt64*) p = 0;
1183 else
1184 *(sal_uInt64*) p= *__try_cast<System::UInt64*>(val);
1185 break;
1186 case typelib_TypeClass_FLOAT:
1187 if (bDefault)
1188 *(float*) p = 0.;
1189 else
1190 *(float*) p = *__try_cast<System::Single*>(val);
1191 break;
1192 case typelib_TypeClass_DOUBLE:
1193 if (bDefault)
1194 *(double*) p = 0.;
1195 else
1196 *(double*) p = *__try_cast<System::Double*>(val);
1197 break;
1198 default:
1199 { // ToDo enum, should be converted here
1200 map_to_uno(p, val, member_type, assign);
1201 break;
1202 }
1203 }
1204 }
1205 }
1206 catch (BridgeRuntimeError& e)
1207 {
1208 bException= true;
1209 OUStringBuffer buf(512);
1210 buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("[map_to_uno():"));
1211 if (cliType)
1212 {
1213 buf.append(mapCliString(cliType->get_FullName()));
1214 buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("."));
1215 buf.append(comp_td->ppMemberNames[nPos]);
1216 buf.appendAscii(RTL_CONSTASCII_STRINGPARAM(" "));
1217 }
1218 buf.append(e.m_message);
1219 throw BridgeRuntimeError(buf.makeStringAndClear());
1220 }
1221 catch (System::InvalidCastException* )
1222 {
1223 bException= true;
1224 OUStringBuffer buf( 256 );
1225 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
1226 if (cliType)
1227 {
1228 buf.append(mapCliString(cliType->get_FullName()));
1229 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("."));
1230 buf.append(comp_td->ppMemberNames[nPos]);
1231 }
1232 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] Value has not the required type."));
1233 throw BridgeRuntimeError(buf.makeStringAndClear());
1234 }
1235 catch (...)
1236 {
1237 OSL_ASSERT(0);
1238 bException= true;
1239 throw;
1240 }
1241 __finally
1242 {
1243 if (bException && !assign) // if assign then caller cleans up
1244 {
1245 // cleanup the members which we have converted so far
1246 for ( sal_Int32 nCleanup = 0; nCleanup < nPos; ++nCleanup )
1247 {
1248 uno_type_destructData(
1249 uno_data, comp_td->ppTypeRefs[ nCleanup ], 0 );
1250 }
1251 if (0 != comp_td->pBaseTypeDescription)
1252 {
1253 uno_destructData(
1254 uno_data, (typelib_TypeDescription *)comp_td->pBaseTypeDescription, 0 );
1255 }
1256 }
1257 }
1258 break;
1259 }
1260 case typelib_TypeClass_SEQUENCE:
1261 {
1262 TypeDescr td( type );
1263 typelib_TypeDescriptionReference * element_type =
1264 ((typelib_IndirectTypeDescription *)td.get())->pType;
1265
1266 auto_ptr< rtl_mem > seq;
1267
1268 System::Array* ar = NULL;
1269 if (cli_data != NULL)
1270 {
1271 ar = __try_cast<System::Array*>(cli_data);
1272 sal_Int32 nElements = ar->GetLength(0);
1273
1274 try
1275 {
1276 switch (element_type->eTypeClass)
1277 {
1278 case typelib_TypeClass_CHAR:
1279 seq = seq_allocate(nElements, sizeof (sal_Unicode));
1280 sri::Marshal::Copy(__try_cast<System::Char[]>(cli_data), 0,
1281 & ((uno_Sequence*) seq.get())->elements, nElements);
1282 break;
1283 case typelib_TypeClass_BOOLEAN:
1284 seq = seq_allocate(nElements, sizeof (sal_Bool));
1285 sri::Marshal::Copy(__try_cast<System::Boolean[]>(cli_data), 0,
1286 & ((uno_Sequence*) seq.get())->elements, nElements);
1287 break;
1288 case typelib_TypeClass_BYTE:
1289 seq = seq_allocate( nElements, sizeof (sal_Int8) );
1290 sri::Marshal::Copy(__try_cast<System::Byte[]>(cli_data), 0,
1291 & ((uno_Sequence*) seq.get())->elements, nElements);
1292 break;
1293 case typelib_TypeClass_SHORT:
1294 seq = seq_allocate(nElements, sizeof (sal_Int16));
1295 sri::Marshal::Copy(__try_cast<System::Int16[]>(cli_data), 0,
1296 & ((uno_Sequence*) seq.get())->elements, nElements);
1297 break;
1298 case typelib_TypeClass_UNSIGNED_SHORT:
1299 seq = seq_allocate( nElements, sizeof (sal_uInt16) );
1300 sri::Marshal::Copy(static_cast<System::Int16[]>(
1301 __try_cast<System::UInt16[]>(cli_data)), 0,
1302 & ((uno_Sequence*) seq.get())->elements, nElements);
1303 break;
1304 case typelib_TypeClass_LONG:
1305 seq = seq_allocate(nElements, sizeof (sal_Int32));
1306 sri::Marshal::Copy(__try_cast<System::Int32[]>(cli_data), 0,
1307 & ((uno_Sequence*) seq.get())->elements, nElements);
1308 break;
1309 case typelib_TypeClass_UNSIGNED_LONG:
1310 seq = seq_allocate( nElements, sizeof (sal_uInt32) );
1311 sri::Marshal::Copy(static_cast<System::Int32[]>(
1312 __try_cast<System::UInt32[]>(cli_data)), 0,
1313 & ((uno_Sequence*) seq.get())->elements, nElements);
1314 break;
1315 case typelib_TypeClass_HYPER:
1316 seq = seq_allocate(nElements, sizeof (sal_Int64));
1317 sri::Marshal::Copy(__try_cast<System::Int64[]>(cli_data), 0,
1318 & ((uno_Sequence*) seq.get())->elements, nElements);
1319 break;
1320 case typelib_TypeClass_UNSIGNED_HYPER:
1321 seq = seq_allocate(nElements, sizeof (sal_uInt64));
1322 sri::Marshal::Copy(static_cast<System::Int64[]>(
1323 __try_cast<System::UInt64[]>(cli_data)), 0,
1324 & ((uno_Sequence*) seq.get())->elements, nElements);
1325 break;
1326 case typelib_TypeClass_FLOAT:
1327 seq = seq_allocate(nElements, sizeof (float));
1328 sri::Marshal::Copy(__try_cast<System::Single[]>(cli_data), 0,
1329 & ((uno_Sequence*) seq.get())->elements, nElements);
1330 break;
1331 case typelib_TypeClass_DOUBLE:
1332 seq = seq_allocate(nElements, sizeof (double));
1333 sri::Marshal::Copy(__try_cast<System::Double[]>(cli_data), 0,
1334 & ((uno_Sequence*) seq.get())->elements, nElements);
1335 break;
1336 case typelib_TypeClass_STRING:
1337 {
1338 seq = seq_allocate(nElements, sizeof (rtl_uString*));
1339 System::String* arStr[]= __try_cast<System::String*[]>(cli_data);
1340 for (int i= 0; i < nElements; i++)
1341 {
1342 wchar_t const __pin * pdata= PtrToStringChars(arStr[i]);
1343 rtl_uString** pStr= & ((rtl_uString**) &
1344 ((uno_Sequence*) seq.get())->elements)[i];
1345 *pStr= NULL;
1346 rtl_uString_newFromStr_WithLength( pStr, pdata,
1347 arStr[i]->get_Length());
1348 }
1349 break;
1350 }
1351 case typelib_TypeClass_ENUM:
1352 seq = seq_allocate(nElements, sizeof (sal_Int32));
1353 for (int i= 0; i < nElements; i++)
1354 {
1355 ((sal_Int32*) &((uno_Sequence*) seq.get())->elements)[i]=
1356 System::Convert::ToInt32(ar->GetValue(i));
1357 }
1358 break;
1359 case typelib_TypeClass_TYPE:
1360 case typelib_TypeClass_ANY:
1361 case typelib_TypeClass_STRUCT:
1362 case typelib_TypeClass_EXCEPTION:
1363 case typelib_TypeClass_SEQUENCE:
1364 case typelib_TypeClass_INTERFACE:
1365 {
1366 TypeDescr element_td( element_type );
1367 seq = seq_allocate( nElements, element_td.get()->nSize );
1368
1369 for (sal_Int32 nPos = 0; nPos < nElements; ++nPos)
1370 {
1371 try
1372 {
1373 void * p= ((uno_Sequence *) seq.get())->elements +
1374 (nPos * element_td.get()->nSize);
1375 System::Object* elemData= dynamic_cast<System::Array*>(cli_data)->GetValue(nPos);
1376 map_to_uno(
1377 p, elemData, element_td.get()->pWeakRef,
1378 false /* no assign */);
1379 }
1380 catch (...)
1381 {
1382 // cleanup
1383 for ( sal_Int32 nCleanPos = 0; nCleanPos < nPos; ++nCleanPos )
1384 {
1385 void * p =
1386 ((uno_Sequence *)seq.get())->elements +
1387 (nCleanPos * element_td.get()->nSize);
1388 uno_destructData( p, element_td.get(), 0 );
1389 }
1390 throw;
1391 }
1392 }
1393 break;
1394 }
1395 default:
1396 {
1397 OUStringBuffer buf( 128 );
1398 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
1399 buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName ) );
1400 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] unsupported sequence element type: ") );
1401 buf.append( *reinterpret_cast< OUString const * >( &element_type->pTypeName ) );
1402 throw BridgeRuntimeError( buf.makeStringAndClear() );
1403 }
1404 }
1405 }
1406 catch (BridgeRuntimeError& e)
1407 {
1408 OUStringBuffer buf( 128 );
1409 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
1410 buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName ));
1411 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] conversion failed\n "));
1412 buf.append(e.m_message);
1413 throw BridgeRuntimeError(buf.makeStringAndClear());
1414 }
1415 catch (System::InvalidCastException* )
1416 {
1417 // Ok, checked
1418 OUStringBuffer buf( 128 );
1419 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
1420 buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName) );
1421 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] could not convert sequence element type: ") );
1422 buf.append( *reinterpret_cast< OUString const * >( &element_type->pTypeName ) );
1423 throw BridgeRuntimeError( buf.makeStringAndClear() );
1424 }
1425 catch (...)
1426 {
1427 OSL_ASSERT(0);
1428 throw;
1429 }
1430 __finally
1431 {
1432 if (assign)
1433 uno_destructData( uno_data, td.get(), 0 );
1434 }
1435 }
1436 else
1437 {
1438 seq = seq_allocate(0, sizeof (sal_Int32));
1439 }
1440 *(uno_Sequence **)uno_data = (uno_Sequence *)seq.release();
1441 break;
1442 }
1443 case typelib_TypeClass_INTERFACE:
1444 {
1445 if (assign)
1446 {
1447 uno_Interface * p = *(uno_Interface **)uno_data;
1448 if (0 != p)
1449 (*p->release)( p );
1450 }
1451 if (0 == cli_data) // null-ref
1452 {
1453 *(uno_Interface **)uno_data = 0;
1454 }
1455 else
1456 {
1457 TypeDescr td( type );
1458 uno_Interface * pUnoI = map_cli2uno(cli_data, td.get());
1459 *(uno_Interface **)uno_data = pUnoI;
1460 }
1461 break;
1462 }
1463 default:
1464 {
1465 //ToDo check
1466 OUStringBuffer buf( 128 );
1467 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
1468 buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName ) );
1469 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] unsupported type!") );
1470 throw BridgeRuntimeError( buf.makeStringAndClear() );
1471 }
1472 }
1473 }
1474 // BridgeRuntimeError are allowed to be thrown
1475 catch (System::InvalidCastException* )
1476 {
1477 //ToDo check
1478 OUStringBuffer buf( 128 );
1479 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
1480 buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName ) );
1481 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] could not convert type!") );
1482 throw BridgeRuntimeError( buf.makeStringAndClear() );
1483 }
1484 catch (System::NullReferenceException * e)
1485 {
1486 OUStringBuffer buf(512);
1487 buf.appendAscii(RTL_CONSTASCII_STRINGPARAM(
1488 "[map_to_uno()] Illegal null reference passed!\n"));
1489 buf.append(mapCliString(e->get_StackTrace()));
1490 throw BridgeRuntimeError( buf.makeStringAndClear() );
1491 }
1492 catch (BridgeRuntimeError& )
1493 {
1494 throw;
1495 }
1496 catch (...)
1497 {
1498 OSL_ASSERT(0);
1499 throw;
1500 }
1501
1502 }
1503
1504 /**
1505 @param info
1506 The expected target type. Currently info is provdided when this method is called
1507 to convert the in/out and out parameters of a call from cli to uno. Then info
1508 is always a byref type, e.g. "System.String&". info is used for Any and Enum conversion.
1509 @param bDontCreateObj
1510 false - a new object is created which holds the mapped uno value and is assigned to
1511 cli_data.
1512 true - cli_data already contains the newly constructed object. This is the case if
1513 a struct is converted then on the first call to map_to_cli the new object is created.
1514 If the struct inherits another struct then this function is called recursivly while the
1515 newly created object is passed in cli_data.
1516 */
map_to_cli(System::Object ** cli_data,void const * uno_data,typelib_TypeDescriptionReference * type,System::Type * info,bool bDontCreateObj) const1517 void Bridge::map_to_cli(
1518 System::Object* *cli_data, void const * uno_data,
1519 typelib_TypeDescriptionReference * type, System::Type* info,
1520 bool bDontCreateObj) const
1521 {
1522 switch (type->eTypeClass)
1523 {
1524 case typelib_TypeClass_CHAR:
1525 *cli_data= __box(*(__wchar_t const*)uno_data);
1526 break;
1527 case typelib_TypeClass_BOOLEAN:
1528 *cli_data = __box((*(bool const*)uno_data) == sal_True ? true : false);
1529 break;
1530 case typelib_TypeClass_BYTE:
1531 *cli_data = __box(*(unsigned char const*) uno_data);
1532 break;
1533 case typelib_TypeClass_SHORT:
1534 *cli_data= __box(*(short const*) uno_data);
1535 break;
1536 case typelib_TypeClass_UNSIGNED_SHORT:
1537 *cli_data= __box(*(unsigned short const*) uno_data);
1538 break;
1539 case typelib_TypeClass_LONG:
1540 *cli_data= __box(*(int const*) uno_data);
1541 break;
1542 case typelib_TypeClass_UNSIGNED_LONG:
1543 *cli_data= __box(*(unsigned int const*) uno_data);
1544 break;
1545 case typelib_TypeClass_HYPER:
1546 *cli_data= __box(*(__int64 const*) uno_data);
1547 break;
1548 case typelib_TypeClass_UNSIGNED_HYPER:
1549 *cli_data= __box(*(unsigned __int64 const*) uno_data);
1550 break;
1551 case typelib_TypeClass_FLOAT:
1552 *cli_data= __box(*(float const*) uno_data);
1553 break;
1554 case typelib_TypeClass_DOUBLE:
1555 *cli_data= __box(*(double const*) uno_data);
1556 break;
1557 case typelib_TypeClass_STRING:
1558 {
1559 rtl_uString const* sVal= NULL;
1560 sVal= *(rtl_uString* const*) uno_data;
1561 *cli_data= new System::String((__wchar_t*) sVal->buffer,0, sVal->length);
1562 break;
1563 }
1564 case typelib_TypeClass_TYPE:
1565 {
1566 *cli_data= mapUnoType( *(typelib_TypeDescriptionReference * const *)uno_data );
1567 break;
1568 }
1569 case typelib_TypeClass_ANY:
1570 {
1571 uno_Any const * pAny = (uno_Any const *)uno_data;
1572 if (typelib_TypeClass_VOID != pAny->pType->eTypeClass)
1573 {
1574 System::Object* objCli= NULL;
1575 map_to_cli(
1576 &objCli, pAny->pData, pAny->pType, 0,
1577 false);
1578
1579 uno::Any anyVal(mapUnoType(pAny->pType), objCli);
1580 *cli_data= __box(anyVal);
1581 }
1582 else
1583 { // void any
1584 *cli_data= __box(uno::Any::VOID);
1585 }
1586 break;
1587 }
1588 case typelib_TypeClass_ENUM:
1589 {
1590 if (info != NULL)
1591 {
1592 OSL_ASSERT(info->get_IsByRef());
1593 info= info->GetElementType();
1594 *cli_data= System::Enum::ToObject(info, *(System::Int32*) uno_data);
1595 }
1596 else
1597 *cli_data= System::Enum::ToObject(
1598 mapUnoType(type), *(System::Int32*) uno_data);
1599 break;
1600 }
1601 case typelib_TypeClass_STRUCT:
1602 case typelib_TypeClass_EXCEPTION:
1603 {
1604 TypeDescr td( type );
1605 typelib_CompoundTypeDescription * comp_td =
1606 (typelib_CompoundTypeDescription *) td.get();
1607 if ( ! ((typelib_TypeDescription*) comp_td)->bComplete)
1608 ::typelib_typedescription_complete(
1609 (typelib_TypeDescription**) & comp_td );
1610
1611
1612 //create the type
1613 System::Type* cliType= loadCliType(td.get()->pTypeName);
1614 //detect if we recursivly convert inherited structures
1615 //If this point is reached because of a recursive call during convering a
1616 //struct then we must not create a new object rather we use the one in
1617 // cli_data argument.
1618 System::Object* cliObj;
1619 if (bDontCreateObj)
1620 cliObj = *cli_data; // recursive call
1621 else
1622 {
1623 //Special handling for Exception conversion. We must call constructor System::Exception
1624 //to pass the message string
1625 if (__typeof(ucss::uno::Exception)->IsAssignableFrom(cliType))
1626 {
1627 //We need to get the Message field. Therefore we must obtain the offset from
1628 //the typedescription. The base interface of all exceptions is
1629 //com::sun::star::uno::Exception which contains the message
1630 typelib_CompoundTypeDescription* pCTD = comp_td;
1631 while (pCTD->pBaseTypeDescription)
1632 pCTD = pCTD->pBaseTypeDescription;
1633 int nPos = -1;
1634
1635 rtl::OUString usMessageMember(RTL_CONSTASCII_USTRINGPARAM("Message"));
1636 for (int i = 0; i < pCTD->nMembers; i ++)
1637 {
1638 #if OSL_DEBUG_LEVEL >= 2
1639 System::String* sMember;
1640 sMember = mapUnoString(pCTD->ppMemberNames[i]);
1641 #endif
1642 if (usMessageMember.equals(pCTD->ppMemberNames[i]))
1643 {
1644 nPos = i;
1645 break;
1646 }
1647 }
1648 OSL_ASSERT (nPos != -1);
1649 int offset = pCTD->pMemberOffsets[nPos];
1650 //Whith the offset within the exception we can get the message string
1651 System::String* sMessage = mapUnoString(*(rtl_uString**)
1652 ((char*) uno_data + offset));
1653 //We need to find a constructor for the exception that takes the message string
1654 //We assume that the first argument is the message string
1655 sr::ConstructorInfo* arCtorInfo[] = cliType->GetConstructors();
1656 sr::ConstructorInfo* ctorInfo = NULL;
1657 int numCtors = arCtorInfo->get_Length();
1658 //Constructor must at least have 2 params for the base
1659 //unoidl.com.sun.star.uno.Exception (String, Object);
1660 sr::ParameterInfo * arParamInfo[];
1661 for (int i = 0; i < numCtors; i++)
1662 {
1663 arParamInfo = arCtorInfo[i]->GetParameters();
1664 if (arParamInfo->get_Length() < 2)
1665 continue;
1666 ctorInfo = arCtorInfo[i];
1667 break;
1668 }
1669 OSL_ASSERT(arParamInfo[0]->get_ParameterType()->Equals(__typeof(System::String))
1670 && arParamInfo[1]->get_ParameterType()->Equals(__typeof(System::Object))
1671 && arParamInfo[0]->get_Position() == 0
1672 && arParamInfo[1]->get_Position() == 1);
1673 //Prepare parameters for constructor
1674 int numArgs = arParamInfo->get_Length();
1675 System::Object * args[] = new System::Object*[numArgs];
1676 //only initialize the first argument with the message
1677 args[0] = sMessage;
1678 cliObj = ctorInfo->Invoke(args);
1679 }
1680 else
1681 cliObj = System::Activator::CreateInstance(cliType);
1682 }
1683 sal_Int32 * pMemberOffsets = comp_td->pMemberOffsets;
1684
1685 if (comp_td->pBaseTypeDescription)
1686 {
1687 //convert inherited struct
1688 //cliObj is passed inout (args in_param, out_param are true), hence the passed
1689 // cliObj is used by the callee instead of a newly created struct
1690 map_to_cli(
1691 &cliObj, uno_data,
1692 ((typelib_TypeDescription *)comp_td->pBaseTypeDescription)->pWeakRef, 0,
1693 true);
1694 }
1695 rtl::OUString usUnoException(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.Exception"));
1696 for (sal_Int32 nPos = comp_td->nMembers; nPos--; )
1697 {
1698 typelib_TypeDescriptionReference * member_type = comp_td->ppTypeRefs[ nPos ];
1699 System::String* sMemberName= mapUnoString(comp_td->ppMemberNames[nPos]);
1700 sr::FieldInfo* aField= cliType->GetField(sMemberName);
1701 // special case for Exception.Message. The field has already been
1702 // set while constructing cli object
1703 if ( ! aField && usUnoException.equals(td.get()->pTypeName))
1704 {
1705 continue;
1706 }
1707 void const * p = (char const *)uno_data + pMemberOffsets[ nPos ];
1708 switch (member_type->eTypeClass)
1709 {
1710 case typelib_TypeClass_CHAR:
1711 aField->SetValue(cliObj, __box(*(System::Char*) p));
1712 break;
1713 case typelib_TypeClass_BOOLEAN:
1714 aField->SetValue(cliObj, __box(*(System::Boolean*) p));
1715 break;
1716 case typelib_TypeClass_BYTE:
1717 aField->SetValue(cliObj, __box(*(System::Byte*) p));
1718 break;
1719 case typelib_TypeClass_SHORT:
1720 aField->SetValue(cliObj, __box(*(System::Int16*) p));
1721 break;
1722 case typelib_TypeClass_UNSIGNED_SHORT:
1723 aField->SetValue(cliObj, __box(*(System::UInt16*) p));
1724 break;
1725 case typelib_TypeClass_LONG:
1726 aField->SetValue(cliObj, __box(*(System::Int32*) p));
1727 break;
1728 case typelib_TypeClass_UNSIGNED_LONG:
1729 aField->SetValue(cliObj, __box(*(System::UInt32*) p));
1730 break;
1731 case typelib_TypeClass_HYPER:
1732 aField->SetValue(cliObj, __box(*(System::Int64*) p));
1733 break;
1734 case typelib_TypeClass_UNSIGNED_HYPER:
1735 aField->SetValue(cliObj, __box(*(System::UInt64*) p));
1736 break;
1737 case typelib_TypeClass_FLOAT:
1738 aField->SetValue(cliObj, __box(*(System::Single*) p));
1739 break;
1740 case typelib_TypeClass_DOUBLE:
1741 aField->SetValue(cliObj, __box(*(System::Double*) p));
1742 break;
1743 default:
1744 {
1745 System::Object* cli_val;
1746 map_to_cli(
1747 &cli_val, p, member_type, 0,
1748 false);
1749 aField->SetValue(cliObj, cli_val);
1750 break;
1751 }
1752 }
1753 }
1754 *cli_data= cliObj;
1755 break;
1756 }
1757 case typelib_TypeClass_SEQUENCE:
1758 {
1759 sal_Int32 nElements;
1760 uno_Sequence const * seq = 0;
1761 seq = *(uno_Sequence * const *)uno_data;
1762 nElements = seq->nElements;
1763
1764 TypeDescr td( type );
1765 typelib_TypeDescriptionReference * element_type =
1766 ((typelib_IndirectTypeDescription *)td.get())->pType;
1767
1768 switch (element_type->eTypeClass)
1769 {
1770 case typelib_TypeClass_CHAR:
1771 {
1772 System::Char arChar[]= new System::Char[nElements];
1773 sri::Marshal::Copy( (void*) &seq->elements, arChar, 0, nElements);
1774 *cli_data= arChar;
1775 break;
1776 }
1777 case typelib_TypeClass_BOOLEAN:
1778 {
1779 System::Boolean arBool[]= new System::Boolean[nElements];
1780 sri::Marshal::Copy( (void*) &seq->elements, arBool, 0, nElements);
1781 *cli_data= arBool;
1782 break;
1783 }
1784 case typelib_TypeClass_BYTE:
1785 {
1786 System::Byte arByte[]= new System::Byte[nElements];
1787 sri::Marshal::Copy( (void*) &seq->elements, arByte, 0, nElements);
1788 *cli_data= arByte;
1789 break;
1790 }
1791 case typelib_TypeClass_SHORT:
1792 {
1793 System::Int16 arShort[]= new System::Int16[nElements];
1794 sri::Marshal::Copy( (void*) &seq->elements, arShort, 0, nElements);
1795 *cli_data= arShort;
1796 break;
1797 }
1798 case typelib_TypeClass_UNSIGNED_SHORT:
1799 {
1800 System::UInt16 arUInt16[]= new System::UInt16[nElements];
1801 sri::Marshal::Copy( (void*) &seq->elements, static_cast<System::Int16[]>(arUInt16),
1802 0, nElements);
1803 *cli_data= arUInt16;
1804 break;
1805 }
1806 case typelib_TypeClass_LONG:
1807 {
1808 System::Int32 arInt32[]= new System::Int32[nElements];
1809 sri::Marshal::Copy( (void*) &seq->elements, arInt32, 0, nElements);
1810 *cli_data= arInt32;
1811 break;
1812 }
1813 case typelib_TypeClass_UNSIGNED_LONG:
1814 {
1815 System::UInt32 arUInt32[]= new System::UInt32[nElements];
1816 sri::Marshal::Copy( (void*) &seq->elements, static_cast<System::Int32[]>(arUInt32),
1817 0, nElements);
1818 *cli_data= arUInt32;
1819 break;
1820 }
1821 case typelib_TypeClass_HYPER:
1822 {
1823 System::Int64 arInt64[]= new System::Int64[nElements];
1824 sri::Marshal::Copy( (void*) &seq->elements, arInt64, 0, nElements);
1825 *cli_data= arInt64;
1826 break;
1827 }
1828 case typelib_TypeClass_UNSIGNED_HYPER:
1829 {
1830 System::UInt64 arUInt64[]= new System::UInt64[nElements];
1831 sri::Marshal::Copy( (void*) &seq->elements, arUInt64, 0, nElements);
1832 *cli_data= arUInt64;
1833 break;
1834 }
1835 case typelib_TypeClass_FLOAT:
1836 {
1837 System::Single arSingle[]= new System::Single[nElements];
1838 sri::Marshal::Copy( (void*) &seq->elements, arSingle, 0, nElements);
1839 *cli_data= arSingle;
1840 break;
1841 }
1842 case typelib_TypeClass_DOUBLE:
1843 {
1844 System::Double arDouble[]= new System::Double[nElements];
1845 sri::Marshal::Copy( (void*) &seq->elements, arDouble, 0, nElements);
1846 *cli_data= arDouble;
1847 break;
1848 }
1849 case typelib_TypeClass_STRING:
1850 {
1851 System::String* arString[]= new System::String*[nElements];
1852 for (int i= 0; i < nElements; i++)
1853 {
1854 rtl_uString *aStr= ((rtl_uString**)(&seq->elements))[i];
1855 arString[i]= new System::String( (__wchar_t *) &aStr->buffer, 0, aStr->length);
1856 }
1857 *cli_data= arString;
1858 break;
1859 }
1860 case typelib_TypeClass_TYPE:
1861 {
1862 System::Type* arType[]= new System::Type*[nElements];
1863 for (int i= 0; i < nElements; i++)
1864 {
1865 arType[i]=
1866 mapUnoType( ((typelib_TypeDescriptionReference**) seq->elements)[i]);
1867 }
1868 *cli_data= arType;
1869 break;
1870 }
1871 case typelib_TypeClass_ANY:
1872 {
1873 uno::Any arCli[]= new uno::Any[nElements];
1874 uno_Any const * p = (uno_Any const *)seq->elements;
1875 for (sal_Int32 nPos = 0; nPos < nElements; ++nPos )
1876 {
1877 System::Object* cli_obj = NULL;
1878 map_to_cli(
1879 &cli_obj, &p[ nPos ], element_type, 0, false);
1880 arCli[nPos]= *__try_cast<__box uno::Any*>(cli_obj);
1881 }
1882 *cli_data= arCli;
1883 break;
1884 }
1885 case typelib_TypeClass_ENUM:
1886 {
1887 //get the Enum type
1888 System::Type* enumType= NULL;
1889 if (info != NULL)
1890 {
1891 //info is EnumType[]&, remove &
1892 OSL_ASSERT(info->IsByRef);
1893 enumType = info->GetElementType();
1894 //enumType is EnumType[], remove []
1895 enumType = enumType->GetElementType();
1896 }
1897 else
1898 enumType= mapUnoType(element_type);
1899
1900 System::Array* arEnum = System::Array::CreateInstance(
1901 enumType, nElements);
1902 for (int i= 0; i < nElements; i++)
1903 {
1904 arEnum->SetValue(System::Enum::ToObject(enumType,
1905 ((sal_Int32*) seq->elements)[i]), i);
1906 }
1907 *cli_data = arEnum;
1908 break;
1909 }
1910 case typelib_TypeClass_STRUCT:
1911 case typelib_TypeClass_EXCEPTION:
1912 {
1913 TypeDescr element_td( element_type );
1914 System::Array* ar= System::Array::CreateInstance(
1915 mapUnoType(element_type),nElements);
1916 if (0 < nElements)
1917 {
1918 // ToDo check this
1919 char * p = (char *) &seq->elements;
1920 sal_Int32 nSize = element_td.get()->nSize;
1921 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
1922 {
1923 System::Object* val;
1924 map_to_cli(
1925 &val, p + (nSize * nPos), element_type, 0, false);
1926 ar->SetValue(val, nPos);
1927 }
1928 }
1929 *cli_data = ar;
1930 break;
1931 }
1932 // ToDo, verify
1933 case typelib_TypeClass_SEQUENCE:
1934 {
1935 System::Array *ar= System::Array::CreateInstance(
1936 mapUnoType(element_type), nElements);
1937 if (0 < nElements)
1938 {
1939 TypeDescr element_td( element_type );
1940 uno_Sequence ** elements = (uno_Sequence**) seq->elements;
1941 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
1942 {
1943 System::Object* val;
1944 map_to_cli(
1945 &val, &elements[nPos], element_type, 0, false);
1946 ar->SetValue(val, nPos);
1947 }
1948 }
1949 *cli_data = ar;
1950 break;
1951 }
1952 case typelib_TypeClass_INTERFACE:
1953 {
1954 TypeDescr element_td( element_type );
1955 System::Type * ifaceType= mapUnoType(element_type);
1956 System::Array* ar= System::Array::CreateInstance(ifaceType, nElements);
1957
1958 char * p = (char *)seq->elements;
1959 sal_Int32 nSize = element_td.get()->nSize;
1960 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
1961 {
1962 System::Object* val;
1963 map_to_cli(
1964 &val, p + (nSize * nPos), element_type, NULL, false);
1965
1966 ar->SetValue(val, nPos);
1967 }
1968 *cli_data= ar;
1969 break;
1970 }
1971 default:
1972 {
1973 OUStringBuffer buf( 128 );
1974 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_cli():") );
1975 buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName ) );
1976 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] unsupported element type: ") );
1977 buf.append( *reinterpret_cast< OUString const * >( &element_type->pTypeName ) );
1978 throw BridgeRuntimeError( buf.makeStringAndClear() );
1979 }
1980 }
1981 break;
1982 }
1983 case typelib_TypeClass_INTERFACE:
1984 {
1985 uno_Interface * pUnoI = *(uno_Interface * const *)uno_data;
1986 if (0 != pUnoI)
1987 {
1988 TypeDescr td( type );
1989 *cli_data= map_uno2cli( pUnoI, reinterpret_cast<
1990 typelib_InterfaceTypeDescription*>(td.get())) ;
1991 }
1992 else
1993 *cli_data= NULL;
1994 break;
1995 }
1996 default:
1997 {
1998 //ToDo check this exception. The String is probably crippled
1999 OUStringBuffer buf( 128 );
2000 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_cli():") );
2001 buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName ) );
2002 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] unsupported type!") );
2003 throw BridgeRuntimeError( buf.makeStringAndClear() );
2004 }
2005 }
2006 }
2007 }
2008