xref: /trunk/main/testtools/source/bridgetest/cli/cli_cpp_bridgetest.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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