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