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_testtools.hxx" 26 27 #using <mscorlib.dll> 28 #using <System.dll> 29 #using <cli_basetypes.dll> 30 #using <cli_uretypes.dll> 31 #using <cli_ure.dll> 32 #using <cli_types_bridgetest.dll> 33 34 using namespace System; 35 using namespace System::Diagnostics; 36 using namespace System::Reflection; 37 using namespace System::Threading; 38 using namespace uno; 39 using namespace uno::util; 40 using namespace unoidl::com::sun::star::uno; 41 using namespace unoidl::com::sun::star::lang; 42 //using namespace unoidl::com::sun::star::test::bridge; 43 using namespace unoidl::test::testtools::bridgetest; 44 namespace foo 45 { 46 public interface class MyInterface 47 { 48 }; 49 } 50 51 namespace cpp_bridgetest 52 { 53 ref class ORecursiveCall: public WeakBase, public XRecursiveCall 54 { 55 public: 56 // Implementing an interface method needs an explicit virtual in 57 // C++/CLI; MC++ inferred it from the base list. 58 virtual void callRecursivly(XRecursiveCall ^ xCall, int nToCall) 59 { 60 Monitor::Enter(this); 61 try 62 { 63 { 64 if (nToCall > 0) 65 { 66 nToCall --; 67 xCall->callRecursivly(this, nToCall); 68 } 69 } 70 } 71 __finally 72 { 73 Monitor::Exit(this); 74 } 75 76 } 77 }; 78 79 public ref class Constants 80 { 81 public: 82 static String ^ STRING_TEST_CONSTANT = gcnew String("\" paco\' chorizo\\\' \"\'"); 83 }; 84 85 public ref class BridgeTest : public WeakBase, public XMain 86 { 87 static bool compareData(Object ^ val1, Object ^ val2) 88 { 89 if (val1 == nullptr && val2 == nullptr || val1 == val2) 90 return true; 91 if ((val1 == nullptr && val2 != nullptr) || 92 (val1 != nullptr && val2 == nullptr) || val1->GetType() != val2->GetType()) 93 return false; 94 95 bool ret = false; 96 Type ^ t1 = val1->GetType(); 97 //Sequence 98 if (t1->IsArray) 99 { 100 ret = compareSequence(static_cast<Array ^>(val1), 101 static_cast<Array ^>(val2)); 102 } 103 //String 104 else if (t1 == String::typeid) 105 { 106 ret = val1->Equals(val2); 107 } 108 // Interface implementation 109 else if (t1->GetInterfaces()->Length > 0 && ! t1->IsValueType) 110 { 111 ret = val1 == val2; 112 } 113 // Struct 114 else if ( ! t1->IsValueType) 115 { 116 ret = compareStruct(val1, val2); 117 } 118 else if (t1 == Any::typeid) 119 { 120 Any a1 = (Any) val1; 121 Any a2 = (Any) val2; 122 ret = a1.Type == a2.Type && compareData(a1.Value, a2.Value); 123 } 124 else if (t1->IsValueType) 125 { 126 //Any, enum, int, bool char, float, double etc. 127 ret = val1->Equals(val2); 128 } 129 else 130 { 131 Debug::Assert(false); 132 } 133 return ret; 134 } 135 136 // Arrays have only one dimension 137 static bool compareSequence(Array ^ ar1, Array ^ ar2) 138 { 139 Debug::Assert(ar1 != nullptr && ar2 != nullptr); 140 Type ^ t1 = ar1->GetType(); 141 Type ^ t2 = ar2->GetType(); 142 143 if (!(ar1->Rank == 1 && ar2->Rank == 1 144 && ar1->Length == ar2->Length && t1->GetElementType() == t2->GetElementType())) 145 return false; 146 147 //arrays have same rank and size and element type. 148 int len = ar1->Length; 149 bool ret = true; 150 for (int i = 0; i < len; i++) 151 { 152 if (compareData(ar1->GetValue(i), ar2->GetValue(i)) == false) 153 { 154 ret = false; 155 break; 156 } 157 } 158 return ret; 159 } 160 161 static bool compareStruct(Object ^ val1, Object ^ val2) 162 { 163 Debug::Assert(val1 != nullptr && val2 != nullptr); 164 Type ^ t1 = val1->GetType(); 165 Type ^ t2 = val2->GetType(); 166 if (t1 != t2) 167 return false; 168 cli::array< FieldInfo ^ > ^ fields = t1->GetFields(); 169 int cFields = fields->Length; 170 bool ret = true; 171 for (int i = 0; i < cFields; i++) 172 { 173 Object ^ fieldVal1 = fields[i]->GetValue(val1); 174 Object ^ fieldVal2 = fields[i]->GetValue(val2); 175 if ( ! compareData(fieldVal1, fieldVal2)) 176 { 177 ret = false; 178 break; 179 } 180 } 181 return ret; 182 } 183 184 static bool check( bool b , String ^ message ) 185 { 186 if ( ! b) 187 Console::WriteLine("{0} failed\n" , message); 188 return b; 189 } 190 191 static bool equals(TestElement ^ rData1, TestElement ^ rData2) 192 { 193 check( rData1->Bool == rData2->Bool, "### bool does not match!" ); 194 check( rData1->Char == rData2->Char, "### char does not match!" ); 195 check( rData1->Byte == rData2->Byte, "### byte does not match!" ); 196 check( rData1->Short == rData2->Short, "### short does not match!" ); 197 check( rData1->UShort == rData2->UShort, "### unsigned short does not match!" ); 198 check( rData1->Long == rData2->Long, "### long does not match!" ); 199 check( rData1->ULong == rData2->ULong, "### unsigned long does not match!" ); 200 check( rData1->Hyper == rData2->Hyper, "### hyper does not match!" ); 201 check( rData1->UHyper == rData2->UHyper, "### unsigned hyper does not match!" ); 202 check( rData1->Float == rData2->Float, "### float does not match!" ); 203 check( rData1->Double == rData2->Double, "### double does not match!" ); 204 check( rData1->Enum == rData2->Enum, "### enum does not match!" ); 205 check( rData1->String == rData2->String, "### string does not match!" ); 206 check( rData1->Interface == rData2->Interface, "### interface does not match!" ); 207 check( compareData((::System::Object ^)(rData1->Any), (::System::Object ^)(rData2->Any)), "### any does not match!" ); 208 209 return (rData1->Bool == rData2->Bool && 210 rData1->Char == rData2->Char && 211 rData1->Byte == rData2->Byte && 212 rData1->Short == rData2->Short && 213 rData1->UShort == rData2->UShort && 214 rData1->Long == rData2->Long && 215 rData1->ULong == rData2->ULong && 216 rData1->Hyper == rData2->Hyper && 217 rData1->UHyper == rData2->UHyper && 218 rData1->Float == rData2->Float && 219 rData1->Double == rData2->Double && 220 rData1->Enum == rData2->Enum && 221 rData1->String == rData2->String && 222 rData1->Interface == rData2->Interface && 223 compareData((::System::Object ^)(rData1->Any), (::System::Object ^)(rData2->Any))); 224 } 225 226 static void assign( TestElement ^ rData, 227 bool bBool, Char cChar, Byte nByte, 228 Int16 nShort, UInt16 nUShort, 229 Int32 nLong, UInt32 nULong, 230 Int64 nHyper, UInt64 nUHyper, 231 float fFloat, double fDouble, 232 TestEnum eEnum, String ^ rStr, 233 Object ^ xTest, 234 uno::Any rAny ) 235 { 236 rData->Bool = bBool; 237 rData->Char = cChar; 238 rData->Byte = nByte; 239 rData->Short = nShort; 240 rData->UShort = nUShort; 241 rData->Long = nLong; 242 rData->ULong = nULong; 243 rData->Hyper = nHyper; 244 rData->UHyper = nUHyper; 245 rData->Float = fFloat; 246 rData->Double = fDouble; 247 rData->Enum = eEnum; 248 rData->String = rStr; 249 rData->Interface = xTest; 250 rData->Any = rAny; 251 } 252 253 static void assign( TestDataElements ^ rData, 254 bool bBool, Char cChar, Byte nByte, 255 Int16 nShort, UInt16 nUShort, 256 Int32 nLong, UInt32 nULong, 257 Int64 nHyper, UInt64 nUHyper, 258 float fFloat, double fDouble, 259 TestEnum eEnum, String ^ rStr, 260 Object ^ xTest, 261 Any rAny, 262 cli::array< TestElement ^ > ^ rSequence) 263 { 264 assign( static_cast<TestElement ^>(rData), 265 bBool, cChar, nByte, nShort, nUShort, nLong, nULong, nHyper, nUHyper, fFloat, fDouble, 266 eEnum, rStr, xTest, rAny ); 267 rData->Sequence = rSequence; 268 } 269 270 static bool testAny(Type ^ typ, Object ^ value, XBridgeTest ^ xLBT ) 271 { 272 Any any; 273 if (typ == nullptr) 274 any = Any(value->GetType(), value); 275 else 276 any = Any(typ, value); 277 278 Any any2 = xLBT->transportAny(any); 279 bool ret = compareData((::System::Object ^)(any), (::System::Object ^)(any2)); 280 if (!ret) 281 { 282 Console::WriteLine("any is different after roundtrip: in {0}, out {1}\n", 283 any.Type->FullName, any2.Type->FullName); 284 } 285 return ret; 286 } 287 288 289 290 static bool performAnyTest(XBridgeTest ^ xLBT, TestDataElements ^ data) 291 { 292 bool bReturn = true; 293 bReturn = testAny( nullptr, (::System::Object ^)(data->Byte), xLBT ) && bReturn; 294 bReturn = testAny( nullptr, (::System::Object ^)(data->Short), xLBT ) && bReturn; 295 bReturn = testAny( nullptr, (::System::Object ^)(data->UShort), xLBT ) && bReturn; 296 bReturn = testAny( nullptr, (::System::Object ^)(data->Long), xLBT ) && bReturn; 297 bReturn = testAny( nullptr, (::System::Object ^)(data->ULong), xLBT ) && bReturn; 298 bReturn = testAny( nullptr, (::System::Object ^)(data->Hyper), xLBT ) && bReturn; 299 bReturn = testAny( nullptr, (::System::Object ^)(data->UHyper), xLBT ) && bReturn; 300 bReturn = testAny( nullptr, (::System::Object ^)(data->Float), xLBT ) && bReturn; 301 bReturn = testAny( nullptr, (::System::Object ^)(data->Double),xLBT ) && bReturn; 302 bReturn = testAny( nullptr, (::System::Object ^)(data->Enum), xLBT ) && bReturn; 303 bReturn = testAny( nullptr, data->String,xLBT ) && bReturn; 304 bReturn = testAny(XWeak::typeid, data->Interface,xLBT ) && bReturn; 305 bReturn = testAny(nullptr, data, xLBT ) && bReturn; 306 307 { 308 Any a1(true); 309 Any a2 = xLBT->transportAny( a1 ); 310 bReturn = compareData((::System::Object ^)(a2), (::System::Object ^)(a1)) && bReturn; 311 } 312 313 { 314 Any a1('A'); 315 Any a2 = xLBT->transportAny(a1); 316 bReturn = compareData( (::System::Object ^)(a2), (::System::Object ^)(a1)) && bReturn; 317 } 318 return bReturn; 319 } 320 321 static bool performSequenceOfCallTest(XBridgeTest ^ xLBT) 322 { 323 int i,nRounds; 324 int nGlobalIndex = 0; 325 const int nWaitTimeSpanMUSec = 10000; 326 for( nRounds = 0 ; nRounds < 10 ; nRounds ++ ) 327 { 328 for( i = 0 ; i < nRounds ; i ++ ) 329 { 330 // fire oneways 331 xLBT->callOneway(nGlobalIndex, nWaitTimeSpanMUSec); 332 nGlobalIndex++; 333 } 334 335 // call synchron 336 xLBT->call(nGlobalIndex, nWaitTimeSpanMUSec); 337 nGlobalIndex++; 338 } 339 return xLBT->sequenceOfCallTestPassed(); 340 } 341 342 343 344 345 static bool performRecursiveCallTest(XBridgeTest ^ xLBT) 346 { 347 xLBT->startRecursiveCall(gcnew ORecursiveCall(), 50); 348 // on failure, the test would lock up or crash 349 return true; 350 } 351 352 static bool performQueryForUnknownType(XBridgeTest ^ xLBT) 353 { 354 bool bRet = false; 355 // test queryInterface for an unknown type 356 try 357 { 358 safe_cast< foo::MyInterface ^ >(xLBT); 359 } 360 catch( System::InvalidCastException ^) 361 { 362 bRet = true; 363 } 364 365 return bRet; 366 } 367 368 // //================================================================================================== 369 static bool performTest(XBridgeTest ^ xLBT) 370 { 371 check( xLBT != nullptr, "### no test interface!" ); 372 bool bRet = true; 373 if (xLBT != nullptr) 374 { 375 // this data is never ever granted access to by calls other than equals(), assign()! 376 TestDataElements ^ aData = gcnew TestDataElements(); // test against this data 377 378 Object ^ xI= gcnew WeakBase(); 379 380 Any aAny( Object::typeid, xI); 381 assign( static_cast<TestElement ^>(aData), 382 true, '@', 17, 0x1234, 0xfedc, 0x12345678, 0xfedcba98, 383 0x123456789abcdef0, 0xfedcba9876543210, 384 17.0815f, 3.1415926359, TestEnum::LOLA, 385 Constants::STRING_TEST_CONSTANT, xI, 386 aAny); 387 388 bRet = check( aData->Any.Value == xI, "### unexpected any!" ) && bRet; 389 bRet = check( !(aData->Any.Value != xI), "### unexpected any!" ) && bRet; 390 391 aData->Sequence = gcnew cli::array< TestElement ^ >(2); 392 aData->Sequence[0] = gcnew TestElement( 393 aData->Bool, aData->Char, aData->Byte, aData->Short, 394 aData->UShort, aData->Long, aData->ULong, 395 aData->Hyper, aData->UHyper, aData->Float, 396 aData->Double, aData->Enum, aData->String, 397 aData->Interface, aData->Any); //(TestElement) aData; 398 aData->Sequence[1] = gcnew TestElement(); //is empty 399 400 // aData complete 401 // 402 // this is a manually copy of aData for first setting... 403 TestDataElements ^ aSetData = gcnew TestDataElements(); 404 Any aAnySet(Object::typeid, xI); 405 assign( static_cast<TestElement ^>(aSetData), 406 aData->Bool, 407 aData->Char, 408 aData->Byte, 409 aData->Short, 410 aData->UShort, 411 aData->Long, aData->ULong, aData->Hyper, aData->UHyper, aData->Float, aData->Double, 412 aData->Enum, 413 aData->String, 414 xI, 415 aAnySet); 416 417 aSetData->Sequence = gcnew cli::array< TestElement ^ >(2); 418 aSetData->Sequence[0] = gcnew TestElement( 419 aSetData->Bool, aSetData->Char, aSetData->Byte, aSetData->Short, 420 aSetData->UShort, aSetData->Long, aSetData->ULong, 421 aSetData->Hyper, aSetData->UHyper, aSetData->Float, 422 aSetData->Double, aSetData->Enum, aSetData->String, 423 aSetData->Interface, aSetData->Any); //TestElement) aSetData; 424 aSetData->Sequence[1] = gcnew TestElement(); // empty struct 425 426 xLBT->setValues( 427 aSetData->Bool, aSetData->Char, aSetData->Byte, aSetData->Short, aSetData->UShort, 428 aSetData->Long, aSetData->ULong, aSetData->Hyper, aSetData->UHyper, aSetData->Float, aSetData->Double, 429 aSetData->Enum, aSetData->String, aSetData->Interface, aSetData->Any, aSetData->Sequence, aSetData ); 430 431 { 432 TestDataElements ^ aRet = gcnew TestDataElements(); 433 TestDataElements ^ aRet2 = gcnew TestDataElements(); 434 xLBT->getValues( 435 aRet->Bool, aRet->Char, aRet->Byte, aRet->Short, aRet->UShort, 436 aRet->Long, aRet->ULong, aRet->Hyper, aRet->UHyper, 437 aRet->Float, aRet->Double, aRet->Enum, aRet->String, 438 aRet->Interface, aRet->Any, aRet->Sequence, aRet2 ); 439 440 bRet = check( compareData( aData, aRet ) && compareData( aData, aRet2 ) , "getValues test") && bRet; 441 442 // set last retrieved values 443 TestDataElements ^ aSV2ret = xLBT->setValues2( 444 aRet->Bool, aRet->Char, aRet->Byte, aRet->Short, aRet->UShort, 445 aRet->Long, aRet->ULong, aRet->Hyper, aRet->UHyper, aRet->Float, 446 aRet->Double, aRet->Enum, aRet->String, aRet->Interface, aRet->Any, 447 aRet->Sequence, aRet2 ); 448 449 // check inout sequence order 450 // => inout sequence parameter was switched by test objects 451 TestElement ^ temp = aRet->Sequence[ 0 ]; 452 aRet->Sequence[ 0 ] = aRet->Sequence[ 1 ]; 453 aRet->Sequence[ 1 ] = temp; 454 455 bRet = check( 456 compareData( aData, aSV2ret ) && compareData( aData, aRet2 ), 457 "getValues2 test") && bRet; 458 } 459 { 460 TestDataElements ^ aRet = gcnew TestDataElements(); 461 TestDataElements ^ aRet2 = gcnew TestDataElements(); 462 TestDataElements ^ aGVret = xLBT->getValues( 463 aRet->Bool, aRet->Char, aRet->Byte, aRet->Short, 464 aRet->UShort, aRet->Long, aRet->ULong, aRet->Hyper, 465 aRet->UHyper, aRet->Float, aRet->Double, aRet->Enum, 466 aRet->String, aRet->Interface, aRet->Any, aRet->Sequence, 467 aRet2 ); 468 469 bRet = check( compareData( aData, aRet ) && compareData( aData, aRet2 ) && compareData( aData, aGVret ), "getValues test" ) && bRet; 470 471 // set last retrieved values 472 xLBT->Bool = aRet->Bool; 473 xLBT->Char = aRet->Char; 474 xLBT->Byte = aRet->Byte; 475 xLBT->Short = aRet->Short; 476 xLBT->UShort = aRet->UShort; 477 xLBT->Long = aRet->Long; 478 xLBT->ULong = aRet->ULong; 479 xLBT->Hyper = aRet->Hyper; 480 xLBT->UHyper = aRet->UHyper; 481 xLBT->Float = aRet->Float; 482 xLBT->Double = aRet->Double; 483 xLBT->Enum = aRet->Enum; 484 xLBT->String = aRet->String; 485 xLBT->Interface = aRet->Interface; 486 xLBT->Any = aRet->Any; 487 xLBT->Sequence = aRet->Sequence; 488 xLBT->Struct = aRet2; 489 } 490 { 491 TestDataElements ^ aRet = gcnew TestDataElements(); 492 TestDataElements ^ aRet2 = gcnew TestDataElements(); 493 aRet->Hyper = xLBT->Hyper; 494 aRet->UHyper = xLBT->UHyper; 495 aRet->Float = xLBT->Float; 496 aRet->Double = xLBT->Double; 497 aRet->Byte = xLBT->Byte; 498 aRet->Char = xLBT->Char; 499 aRet->Bool = xLBT->Bool; 500 aRet->Short = xLBT->Short; 501 aRet->UShort = xLBT->UShort; 502 aRet->Long = xLBT->Long; 503 aRet->ULong = xLBT->ULong; 504 aRet->Enum = xLBT->Enum; 505 aRet->String = xLBT->String; 506 aRet->Interface = xLBT->Interface; 507 aRet->Any = xLBT->Any; 508 aRet->Sequence = xLBT->Sequence; 509 aRet2 = xLBT->Struct; 510 511 bRet = check( compareData( aData, aRet ) && compareData( aData, aRet2 ) , "struct comparison test") && bRet; 512 513 bRet = check(performSequenceTest(xLBT), "sequence test") && bRet; 514 515 // any test 516 bRet = check( performAnyTest( xLBT , aData ) , "any test" ) && bRet; 517 518 // sequence of call test 519 bRet = check( performSequenceOfCallTest( xLBT ) , "sequence of call test" ) && bRet; 520 521 // recursive call test 522 bRet = check( performRecursiveCallTest( xLBT ) , "recursive test" ) && bRet; 523 524 bRet = (compareData( aData, aRet ) && compareData( aData, aRet2 )) && bRet ; 525 526 // check setting of null reference. XInterface maps to Object^, and 527 // "= 0" on one BOXES the literal into an Int32 instead of storing 528 // null -- so the property ends up non-null and the comparison below 529 // is false whatever happens. Neither has a check() message, which is 530 // why this failed as a bare "standard test failed". 531 xLBT->Interface = nullptr; 532 aRet->Interface = xLBT->Interface; 533 bRet = (aRet->Interface == nullptr) && bRet; 534 535 } 536 537 538 } 539 return bRet; 540 } 541 static bool performSequenceTest(XBridgeTest ^ xBT) 542 { 543 bool bRet = true; 544 XBridgeTest2 ^ xBT2 = dynamic_cast<XBridgeTest2 ^>(xBT); 545 if ( xBT2 == nullptr) 546 return false; 547 548 // perform sequence tests (XBridgeTest2) 549 // create the sequence which are compared with the results 550 cli::array< bool > ^ arBool = gcnew cli::array< bool >(3); 551 arBool[0] = true; arBool[1] = false; arBool[2] = true; 552 cli::array< Char > ^ arChar = gcnew cli::array< Char >(3); 553 arChar[0] = 'A'; arChar[1] = 'B'; arChar[2] = 'C'; 554 cli::array< Byte > ^ arByte = gcnew cli::array< Byte >(3); 555 arByte[0] = 1; arByte[1] = 2; arByte[2] = 0xff; 556 cli::array< Int16 > ^ arShort = gcnew cli::array< Int16 >(3); 557 arShort[0] = Int16::MinValue; arShort[1] = 1; arShort[2] = Int16::MaxValue; 558 cli::array< UInt16 > ^ arUShort = gcnew cli::array< UInt16 >(3); 559 arUShort[0] = UInt16::MinValue; arUShort[1] = 1; arUShort[2] = UInt16::MaxValue; 560 cli::array< Int32 > ^ arLong = gcnew cli::array< Int32 >(3); 561 arLong[0] = Int32::MinValue; arLong[1] = 1; arLong[2] = Int32::MaxValue; 562 cli::array< UInt32 > ^ arULong = gcnew cli::array< UInt32 >(3); 563 arULong[0] = UInt32::MinValue; arULong[1] = 1; arULong[2] = UInt32::MaxValue; 564 cli::array< Int64 > ^ arHyper = gcnew cli::array< Int64 >(3); 565 arHyper[0] = Int64::MinValue; arHyper[1] = 1; arHyper[2] = Int64::MaxValue; 566 cli::array< UInt64 > ^ arUHyper = gcnew cli::array< UInt64 >(3); 567 arUHyper[0] = UInt64::MinValue; arUHyper[1] = 1; 568 arUHyper[2] = UInt64::MaxValue; 569 cli::array< Single > ^ arFloat = gcnew cli::array< Single >(3); 570 arFloat[0] = 1.1f; arFloat[1] = 2.2f; arFloat[2] = 3.3f; 571 cli::array< Double > ^ arDouble = gcnew cli::array< Double >(3); 572 arDouble[0] = 1.11; arDouble[1] = 2.22; arDouble[2] = 3.33; 573 cli::array< String ^ > ^ arString = gcnew cli::array< String ^ >( 3 ); 574 arString[0] = gcnew String("String 1"); 575 arString[1] = gcnew String("String 2"); 576 arString[2] = gcnew String("String 3"); 577 578 cli::array< Any > ^ arAny = gcnew cli::array< Any >( 3 ); 579 arAny[0] = Any(true); arAny[1] = Any(11111); arAny[2] = Any(3.14); 580 cli::array< Object ^ > ^ arObject = gcnew cli::array< Object ^ >( 3 ); 581 arObject[0] = gcnew WeakBase(); arObject[1] = gcnew WeakBase(); 582 arObject[1] = gcnew WeakBase(); 583 584 //TestEnum arEnum[] = new TestEnum[3]; 585 //arEnum[0] = TestEnum::ONE; arEnum[1] = TestEnum::TWO; 586 //arEnum[2] = TestEnum::CHECK; 587 Console::WriteLine(gcnew String("cli_cpp_bridgetest: Workaround for C++ compiler bug:" 588 " using Array of Int32 instead of Array of enums w")); 589 cli::array< Int32 > ^ arEnum = gcnew cli::array< Int32 >(3); 590 arEnum[0] = static_cast<Int32>(TestEnum::ONE); 591 arEnum[1] = static_cast<Int32>(TestEnum::TWO); 592 arEnum[2] = static_cast<Int32>(TestEnum::CHECK); 593 594 cli::array< TestElement ^ > ^ arStruct = gcnew cli::array< TestElement ^ >(3); 595 arStruct[0] = gcnew TestElement(); arStruct[1] = gcnew TestElement(); 596 arStruct[2] = gcnew TestElement(); 597 assign( arStruct[0], true, '@', 17, 0x1234, 0xfedc, 0x12345678, 0xfedcba98, 598 0x123456789abcdef0, 0xfedcba9876543210, 17.0815f, 3.1415926359, 599 TestEnum::LOLA, Constants::STRING_TEST_CONSTANT, arObject[0], 600 Any( Object::typeid, arObject[0]) ); 601 assign( arStruct[1], true, 'A', 17, 0x1234, 0xfedc, 0x12345678, 0xfedcba98, 602 0x123456789abcdef0, 0xfedcba9876543210, 17.0815f, 3.1415926359, 603 TestEnum::TWO, Constants::STRING_TEST_CONSTANT, arObject[1], 604 Any( Object::typeid, arObject[1]) ); 605 assign( arStruct[2], true, 'B', 17, 0x1234, 0xfedc, 0x12345678, 0xfedcba98, 606 0x123456789abcdef0, 0xfedcba9876543210, 17.0815f, 3.1415926359, 607 TestEnum::CHECK, Constants::STRING_TEST_CONSTANT, arObject[2], 608 Any( Object::typeid, arObject[2] ) ); 609 610 611 // int[][][] arLong3 = new int[][][]{ 612 // new int[][]{new int[]{1,2,3},new int[]{4,5,6}, new int[]{7,8,9} }, 613 // new int [][]{new int[]{1,2,3},new int[]{4,5,6}, new int[]{7,8,9}}, 614 // new int[][]{new int[]{1,2,3},new int[]{4,5,6}, new int[]{7,8,9}}}; 615 616 { 617 618 // Console::WriteLine(gcnew String("cli_cpp_bridgetest: 619 // int[][] seqSeqRet = xBT2->setDim2(arLong3[0]); 620 // bRet = check( compareData(seqSeqRet, arLong3[0]), "sequence test") && bRet; 621 // int[][][] seqSeqRet2 = xBT2->setDim3(arLong3); 622 // bRet = check( compareData(seqSeqRet2, arLong3), "sequence test") && bRet; 623 624 cli::array< Any > ^ seqAnyRet = xBT2->setSequenceAny(arAny); 625 bRet = check( compareData(seqAnyRet, arAny), "sequence test") && bRet; 626 cli::array< Boolean > ^ seqBoolRet = xBT2->setSequenceBool(arBool); 627 bRet = check( compareData(seqBoolRet, arBool), "sequence test") && bRet; 628 cli::array< Byte > ^ seqByteRet = xBT2->setSequenceByte(arByte); 629 bRet = check( compareData(seqByteRet, arByte), "sequence test") && bRet; 630 cli::array< Char > ^ seqCharRet = xBT2->setSequenceChar(arChar); 631 bRet = check( compareData(seqCharRet, arChar), "sequence test") && bRet; 632 cli::array< Int16 > ^ seqShortRet = xBT2->setSequenceShort(arShort); 633 bRet = check( compareData(seqShortRet, arShort), "sequence test") && bRet; 634 cli::array< Int32 > ^ seqLongRet = xBT2->setSequenceLong(arLong); 635 bRet = check( compareData(seqLongRet, arLong), "sequence test") && bRet; 636 cli::array< Int64 > ^ seqHyperRet = xBT2->setSequenceHyper(arHyper); 637 bRet = check( compareData(seqHyperRet,arHyper), "sequence test") && bRet; 638 cli::array< Single > ^ seqFloatRet = xBT2->setSequenceFloat(arFloat); 639 bRet = check( compareData(seqFloatRet, arFloat), "sequence test") && bRet; 640 cli::array< Double > ^ seqDoubleRet = xBT2->setSequenceDouble(arDouble); 641 bRet = check( compareData(seqDoubleRet, arDouble), "sequence test") && bRet; 642 xBT2->setSequenceEnum( 643 safe_cast< cli::array< TestEnum > ^ >( (Object ^) arEnum ) ); 644 //comparing seqEnumRet with arEnum will fail since they are of different 645 //types because of workaround. arEnum is Int32[]. 646 Console::WriteLine(gcnew String("cli_cpp_bridgetest: Test omitted because " 647 "of C++ compiler bug. XBridgeTest2::setSequenceEnum(sequence<TestEnum>)")); 648 // bRet = check( compareData(seqEnumRet, arEnum), "sequence test") && bRet; 649 cli::array< UInt16 > ^ seqUShortRet = xBT2->setSequenceUShort(arUShort); 650 bRet = check( compareData(seqUShortRet, arUShort), "sequence test") && bRet; 651 cli::array< UInt32 > ^ seqULongRet = xBT2->setSequenceULong(arULong); 652 bRet = check( compareData(seqULongRet, arULong), "sequence test") && bRet; 653 cli::array< UInt64 > ^ seqUHyperRet = xBT2->setSequenceUHyper(arUHyper); 654 bRet = check( compareData(seqUHyperRet, arUHyper), "sequence test") && bRet; 655 cli::array< Object ^ > ^ seqObjectRet = xBT2->setSequenceXInterface(arObject); 656 bRet = check( compareData(seqObjectRet, arObject), "sequence test") && bRet; 657 cli::array< String ^ > ^ seqStringRet = xBT2->setSequenceString(arString); 658 bRet = check( compareData(seqStringRet, arString), "sequence test") && bRet; 659 cli::array< TestElement ^ > ^ seqStructRet = xBT2->setSequenceStruct(arStruct); 660 bRet = check( compareData(seqStructRet, arStruct), "sequence test") && bRet; 661 } 662 { 663 // Boolean arBoolTemp[] = static_cast<Boolean[]>( arBool->Clone()); 664 // Char arCharTemp[] = static_cast<Char[]>(arChar->Clone()); 665 // Byte arByteTemp[] = static_cast<Byte[]>(arByte->Clone()); 666 // Int16 arShortTemp[] = static_cast<Int16[]>(arShort->Clone()); 667 // UInt16 arUShortTemp[] = static_cast<UInt16[]>(arUShort->Clone()); 668 // Int32 arLongTemp[] = static_cast<Int32[]>(arLong->Clone()); 669 // UInt32 arULongTemp[] = static_cast<UInt32[]>(arULong->Clone()); 670 // Int64 arHyperTemp[] = static_cast<Int64[]>(arHyper->Clone()); 671 // UInt64 arUHyperTemp[] = static_cast<UInt64[]>(arUHyper->Clone()); 672 // Single arFloatTemp[] = static_cast<Single[]>(arFloat->Clone()); 673 // Double arDoubleTemp[] = static_cast<Double[]>(arDouble->Clone()); 674 // TestEnum arEnumTemp[] = static_cast<TestEnum[]>(arEnum->Clone()); 675 // cli::array< String ^ > ^ arStringTemp = static_cast<String ^[]>(arString->Clone()); 676 // Object ^ arObjectTemp = static_cast<Object ^[]>(arObject->Clone()); 677 // cli::array< Any > ^ arAnyTemp = static_cast<Any[]>(arAny->Clone()); 678 // // make sure this are has the same contents as arLong3[0] 679 // int[][] arLong2Temp = new int[][]{new int[]{1,2,3},new int[]{4,5,6}, new int[]{7,8,9} }; 680 // // make sure this are has the same contents as arLong3 681 // int[][][] arLong3Temp = new int[][][]{ 682 // new int[][]{new int[]{1,2,3},new int[]{4,5,6}, new int[]{7,8,9} }, 683 // new int [][]{new int[]{1,2,3},new int[]{4,5,6}, new int[]{7,8,9}}, 684 // new int[][]{new int[]{1,2,3},new int[]{4,5,6}, new int[]{7,8,9}}}; 685 Console::WriteLine(gcnew String("cli_cpp_bridgetest: no test of " 686 "XBridgeTest2::setSequencesInOut and XBridgeTest2.setSequencesOut " 687 "because jagged arrays are not supported by C++ compiler")); 688 // xBT2->setSequencesInOut(& arBoolTemp, & arCharTemp, & arByteTemp, 689 // & arShortTemp, & arUShortTemp, & arLongTemp, 690 // & arULongTemp,& arHyperTemp, & arUHyperTemp, 691 // & arFloatTemp,& arDoubleTemp, & arEnumTemp, 692 // & arStringTemp, & arObjectTemp, 693 // & arAnyTemp, & arLong2Temp, & arLong3Temp); 694 // bRet = check( 695 // compareData(arBoolTemp, arBool) && 696 // compareData(arCharTemp , arChar) && 697 // compareData(arByteTemp , arByte) && 698 // compareData(arShortTemp , arShort) && 699 // compareData(arUShortTemp , arUShort) && 700 // compareData(arLongTemp , arLong) && 701 // compareData(arULongTemp , arULong) && 702 // compareData(arHyperTemp , arHyper) && 703 // compareData(arUHyperTemp , arUHyper) && 704 // compareData(arFloatTemp , arFloat) && 705 // compareData(arDoubleTemp , arDouble) && 706 // compareData(arEnumTemp , arEnum) && 707 // compareData(arStringTemp , arString) && 708 // compareData(arObjectTemp , arObject) && 709 // compareData(arAnyTemp , arAny) && 710 // compareData(arLong2Temp , arLong3[0]) && 711 // compareData(arLong3Temp , arLong3), "sequence test") && bRet; 712 713 //Boolean arBoolOut[]; 714 //Char arCharOut[]; 715 //Byte arByteOut[]; 716 //Int16 arShortOut[]; 717 //UInt16 arUShortOut[]; 718 //Int32 arLongOut[]; 719 //UInt32 arULongOut[]; 720 //Int64 arHyperOut[]; 721 //UInt64 arUHyperOut[]; 722 //Single arFloatOut[]; 723 //Double arDoubleOut[]; 724 //TestEnum arEnumOut[]; 725 //cli::array< String ^ > ^ arStringOut; 726 //cli::array< Object ^ > ^ arObjectOut; 727 //cli::array< Any > ^ arAnyOut; 728 // int[][] arLong2Out; 729 // int[][][] arLong3Out; 730 731 // xBT2->setSequencesOut(out arBoolOut, out arCharOut, out arByteOut, 732 // out arShortOut, out arUShortOut, out arLongOut, 733 // out arULongOut, out arHyperOut, out arUHyperOut, 734 // out arFloatOut, out arDoubleOut, out arEnumOut, 735 // out arStringOut, out arObjectOut, out arAnyOut, 736 // out arLong2Out, out arLong3Out); 737 // bRet = check( 738 // compareData(arBoolOut, arBool) && 739 // compareData(arCharOut, arChar) && 740 // compareData(arByteOut, arByte) && 741 // compareData(arShortOut, arShort) && 742 // compareData(arUShortOut, arUShort) && 743 // compareData(arLongOut, arLong) && 744 // compareData(arULongOut, arULong) && 745 // compareData(arHyperOut, arHyper) && 746 // compareData(arUHyperOut, arUHyper) && 747 // compareData(arFloatOut, arFloat) && 748 // compareData(arDoubleOut, arDouble) && 749 // compareData(arEnumOut, arEnum) && 750 // compareData(arStringOut, arString) && 751 // compareData(arObjectOut, arObject) && 752 // compareData(arAnyOut, arAny) && 753 // compareData(arLong2Out, arLong3[0]) && 754 // compareData(arLong3Out, arLong3), "sequence test") && bRet; 755 } 756 { 757 //test with empty sequences 758 // int[][] _arLong2 = new int[0][]; 759 // int[][] seqSeqRet = xBT2->setDim2(_arLong2); 760 // bRet = check( compareData(seqSeqRet, _arLong2), "sequence test") && bRet; 761 // int[][][] _arLong3 = new int[0][][]; 762 // int[][][] seqSeqRet2 = xBT2->setDim3(_arLong3); 763 // bRet = check( compareData(seqSeqRet2, _arLong3), "sequence test") && bRet; 764 cli::array< Any > ^ _arAny = gcnew cli::array< Any >( 0 ); 765 cli::array< Any > ^ seqAnyRet = xBT2->setSequenceAny(_arAny); 766 bRet = check( compareData(seqAnyRet, _arAny), "sequence test") && bRet; 767 cli::array< Boolean > ^ _arBool = gcnew cli::array< Boolean >(0); 768 cli::array< Boolean > ^ seqBoolRet = xBT2->setSequenceBool(_arBool); 769 bRet = check( compareData(seqBoolRet, _arBool), "sequence test") && bRet; 770 cli::array< Byte > ^ _arByte = gcnew cli::array< Byte >(0); 771 cli::array< Byte > ^ seqByteRet = xBT2->setSequenceByte(_arByte); 772 bRet = check( compareData(seqByteRet, _arByte), "sequence test") && bRet; 773 cli::array< Char > ^ _arChar = gcnew cli::array< Char >(0); 774 cli::array< Char > ^ seqCharRet = xBT2->setSequenceChar(_arChar); 775 bRet = check( compareData(seqCharRet, _arChar), "sequence test") && bRet; 776 cli::array< Int16 > ^ _arShort = gcnew cli::array< Int16 >(0); 777 cli::array< Int16 > ^ seqShortRet = xBT2->setSequenceShort(_arShort); 778 bRet = check( compareData(seqShortRet, _arShort), "sequence test") && bRet; 779 cli::array< Int32 > ^ _arLong = gcnew cli::array< Int32 >(0); 780 cli::array< Int32 > ^ seqLongRet = xBT2->setSequenceLong(_arLong); 781 bRet = check( compareData(seqLongRet, _arLong), "sequence test") && bRet; 782 cli::array< Int64 > ^ _arHyper = gcnew cli::array< Int64 >(0); 783 cli::array< Int64 > ^ seqHyperRet = xBT2->setSequenceHyper(_arHyper); 784 bRet = check( compareData(seqHyperRet, _arHyper), "sequence test") && bRet; 785 cli::array< Single > ^ _arFloat = gcnew cli::array< Single >(0); 786 cli::array< Single > ^ seqFloatRet = xBT2->setSequenceFloat(_arFloat); 787 bRet = check( compareData(seqFloatRet, _arFloat), "sequence test") && bRet; 788 cli::array< Double > ^ _arDouble = gcnew cli::array< Double >(0); 789 cli::array< Double > ^ seqDoubleRet = xBT2->setSequenceDouble(_arDouble); 790 bRet = check( compareData(seqDoubleRet, _arDouble), "sequence test") && bRet; 791 cli::array< TestEnum > ^ _arEnum = gcnew cli::array< TestEnum >(0); 792 xBT2->setSequenceEnum(_arEnum); 793 // compiler bug: _arEnum has type System.Enum and not TestEnum 794 // bRet = check( compareData(seqEnumRet, _arEnum), "sequence test") && bRet; 795 cli::array< UInt16 > ^ _arUShort = gcnew cli::array< UInt16 >(0); 796 cli::array< UInt16 > ^ seqUShortRet = xBT2->setSequenceUShort(_arUShort); 797 bRet = check( compareData(seqUShortRet, _arUShort), "sequence test") && bRet; 798 cli::array< UInt32 > ^ _arULong = gcnew cli::array< UInt32 >(0); 799 cli::array< UInt32 > ^ seqULongRet = xBT2->setSequenceULong(_arULong); 800 bRet = check( compareData(seqULongRet, _arULong), "sequence test") && bRet; 801 cli::array< UInt64 > ^ _arUHyper = gcnew cli::array< UInt64 >(0); 802 cli::array< UInt64 > ^ seqUHyperRet = xBT2->setSequenceUHyper(_arUHyper); 803 bRet = check( compareData(seqUHyperRet, _arUHyper), "sequence test") && bRet; 804 cli::array< Object ^ > ^ _arObject = gcnew cli::array< Object ^ >( 0 ); 805 cli::array< Object ^ > ^ seqObjectRet = xBT2->setSequenceXInterface(_arObject); 806 bRet = check( compareData(seqObjectRet, _arObject), "sequence test") && bRet; 807 cli::array< String ^ > ^ _arString = gcnew cli::array< String ^ >( 0 ); 808 cli::array< String ^ > ^ seqStringRet = xBT2->setSequenceString(_arString); 809 bRet = check( compareData(seqStringRet, _arString), "sequence test") && bRet; 810 cli::array< TestElement ^ > ^ _arStruct = gcnew cli::array< TestElement ^ >(0); 811 cli::array< TestElement ^ > ^ seqStructRet = xBT2->setSequenceStruct(_arStruct); 812 bRet = check( compareData(seqStructRet, _arStruct), "sequence test") && bRet; 813 814 } 815 return bRet; 816 } 817 /** Test the System::Object method on the proxy object 818 */ 819 static bool testObjectMethodsImplemention(XBridgeTest ^ xLBT) 820 { 821 bool ret = false; 822 Object ^ obj = gcnew Object(); 823 XBridgeTestBase ^ xBase = dynamic_cast<XBridgeTestBase ^>(xLBT); 824 if (xBase == nullptr) 825 return false; 826 // Object.Equals 827 ret = xLBT->Equals(obj) == false; 828 ret = xLBT->Equals(xLBT) && ret; 829 ret = Object::Equals(obj, obj) && ret; 830 ret = Object::Equals(xLBT, xBase) && ret; 831 //Object.GetHashCode 832 // Don't know how to verify this. Currently it is not possible to get the object id from a proxy 833 int nHash = xLBT->GetHashCode(); 834 ret = nHash == xBase->GetHashCode() && ret; 835 836 //Object.ToString 837 // Don't know how to verify this automatically. 838 String ^ s = xLBT->ToString(); 839 ret = (s->Length > 0) && ret; 840 return ret; 841 } 842 843 844 static bool raiseOnewayException(XBridgeTest ^ xLBT) 845 { 846 bool bReturn = true; 847 String ^ sCompare = Constants::STRING_TEST_CONSTANT; 848 try 849 { 850 // Note : the exception may fly or not (e.g. remote scenario). 851 // When it flies, it must contain the correct elements. 852 xLBT->raiseRuntimeExceptionOneway(sCompare, xLBT->Interface ); 853 } 854 catch (RuntimeException ^ e ) 855 { 856 bReturn = ( xLBT->Interface == e->Context ); 857 } 858 return bReturn; 859 } 860 861 // //================================================================================================== 862 static bool raiseException(XBridgeTest ^ xLBT ) 863 { 864 int nCount = 0; 865 try 866 { 867 try 868 { 869 try 870 { 871 xLBT->raiseException( 872 5, Constants::STRING_TEST_CONSTANT, xLBT->Interface ); 873 } 874 catch (unoidl::com::sun::star::lang::IllegalArgumentException ^ aExc) 875 { 876 if (aExc->ArgumentPosition == 5 && 877 aExc->Context == xLBT->Interface) 878 { 879 ++nCount; 880 } 881 else 882 { 883 check( false, "### unexpected exception content!" ); 884 } 885 886 /** it is certain, that the RuntimeException testing will fail, 887 if no */ 888 xLBT->RuntimeException = 0; 889 } 890 } 891 catch (unoidl::com::sun::star::uno::RuntimeException ^ rExc) 892 { 893 if (rExc->Context == xLBT->Interface ) 894 { 895 ++nCount; 896 } 897 else 898 { 899 check( false, "### unexpected exception content!" ); 900 } 901 902 /** it is certain, that the RuntimeException testing will fail, if no */ 903 xLBT->RuntimeException = (int) 0xcafebabe; 904 } 905 } 906 catch (unoidl::com::sun::star::uno::Exception ^ rExc) 907 { 908 if (rExc->Context == xLBT->Interface) 909 { 910 ++nCount; 911 } 912 else 913 914 { 915 check( false, "### unexpected exception content!" ); 916 } 917 return (nCount == 3); 918 } 919 return false; 920 } 921 922 static private void perform_test( XBridgeTest ^ xLBT ) 923 { 924 bool bRet= true; 925 bRet = check( performTest( xLBT ), "standard test" ) && bRet; 926 bRet = check( raiseException( xLBT ) , "exception test" )&& bRet; 927 bRet = check( raiseOnewayException( xLBT ), "oneway exception test" ) && bRet; 928 bRet = check( testObjectMethodsImplemention(xLBT), "object methods test") && bRet; 929 bRet = performQueryForUnknownType( xLBT ) && bRet; 930 if (! bRet) 931 { 932 throw gcnew unoidl::com::sun::star::uno::RuntimeException( 933 gcnew String("error: test failed!"), nullptr); 934 } 935 } 936 XComponentContext ^ m_xContext; 937 938 public: 939 BridgeTest( XComponentContext ^ xContext ) 940 { 941 m_xContext = xContext; 942 } 943 944 945 946 virtual int run( cli::array< String ^ > ^ args ) 947 { 948 try 949 { 950 if (args->Length < 1) 951 { 952 throw gcnew RuntimeException( 953 "missing argument for bridgetest!", this ); 954 } 955 Object ^ test_obj = 956 m_xContext->getServiceManager()->createInstanceWithContext( 957 args[ 0 ], m_xContext ); 958 if (test_obj == nullptr) 959 test_obj = m_xContext->getValueByName( args[ 0 ] ).Value; 960 961 Console::WriteLine( 962 "cli target bridgetest obj: {0}", test_obj->ToString() ); 963 XBridgeTest ^ xTest = safe_cast< XBridgeTest ^ >(test_obj) ; 964 perform_test( xTest ); 965 Console::WriteLine( "\n### cli_uno C++ bridgetest succeeded." ); 966 return 0; 967 } 968 catch (unoidl::com::sun::star::uno::RuntimeException ^ ) 969 { 970 throw; 971 } 972 catch (System::Exception ^ exc) 973 { 974 System::Text::StringBuilder ^ s = gcnew System::Text::StringBuilder(); 975 s->Append("cli_cpp_bridgetest: unexpected exception occurred in XMain::run. Original exception: "); 976 s->Append(exc->GetType()->Name); 977 s->Append("\n Message: "); 978 s->Append(exc->Message); 979 throw gcnew unoidl::com::sun::star::uno::RuntimeException( 980 s->ToString(), nullptr); 981 } 982 } 983 }; 984 985 } 986