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