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