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 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 76 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 120 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 149 inline System::Type* loadCliType(rtl_uString * unoName) 150 { 151 return loadCliType(mapUnoTypeName(unoName)); 152 } 153 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 200 System::Type* mapUnoType(typelib_TypeDescription const * pTD) 201 { 202 return mapUnoType(pTD->pWeakRef); 203 } 204 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 */ 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 */ 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 */ 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 */ 563 inline System::String* mapCliPolymorphicName(System::String* unoName) 564 { 565 return mapPolymorphicName(unoName, true); 566 } 567 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 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 */ 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 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) 753 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 */ 1517 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 //With 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