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