xref: /trunk/main/testtools/source/bridgetest/bridgetest.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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 #include <stdio.h>
28 #include <string.h>
29 #include <osl/diagnose.h>
30 #include "osl/diagnose.hxx"
31 #include <osl/time.h>
32 #include <sal/types.h>
33 #include "typelib/typedescription.hxx"
34 #include <uno/dispatcher.hxx>
35 #include "uno/mapping.hxx"
36 #include <uno/data.h>
37 #include "uno/environment.hxx"
38 
39 #include <cppuhelper/factory.hxx>
40 #include <cppuhelper/implbase2.hxx>
41 #include <cppuhelper/implbase1.hxx>
42 
43 #include <com/sun/star/lang/XServiceInfo.hpp>
44 #include <com/sun/star/lang/XComponent.hpp>
45 #include <com/sun/star/lang/XMain.hpp>
46 #include <com/sun/star/bridge/UnoUrlResolver.hpp>
47 #include <com/sun/star/bridge/XUnoUrlResolver.hpp>
48 #include "com/sun/star/uno/RuntimeException.hpp"
49 #include "com/sun/star/uno/Type.hxx"
50 
51 #include "test/testtools/bridgetest/BadConstructorArguments.hpp"
52 #include "test/testtools/bridgetest/TestPolyStruct.hpp"
53 #include "test/testtools/bridgetest/XBridgeTest.hpp"
54 #include "test/testtools/bridgetest/XBridgeTest2.hpp"
55 #include "test/testtools/bridgetest/XMulti.hpp"
56 
57 #include "currentcontextchecker.hxx"
58 #include "multi.hxx"
59 
60 using namespace rtl;
61 using namespace osl;
62 using namespace cppu;
63 using namespace com::sun::star::uno;
64 using namespace com::sun::star::lang;
65 using namespace com::sun::star::registry;
66 using namespace com::sun::star::bridge;
67 using namespace test::testtools::bridgetest;
68 
69 #define SERVICENAME     "com.sun.star.test.bridge.BridgeTest"
70 #define IMPLNAME        "com.sun.star.comp.bridge.BridgeTest"
71 
72 #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
73 #define STRING_TEST_CONSTANT "\" paco\' chorizo\\\' \"\'"
74 
75 namespace bridge_test
76 {
77 template< class T>
78 Sequence<T> cloneSequence(const Sequence<T>& val);
79 
80 //--------------------------------------------------------------------------------------------------
getSupportedServiceNames()81 inline static Sequence< OUString > getSupportedServiceNames()
82 {
83     OUString aName( RTL_CONSTASCII_USTRINGPARAM(SERVICENAME) );
84     return Sequence< OUString >( &aName, 1 );
85 }
86 
check(bool b,char const * message)87 static bool check( bool b , char const * message )
88 {
89     if ( ! b )
90         fprintf( stderr, "%s failed\n" , message );
91     return b;
92 }
93 
94 namespace {
95 
checkEmpty(rtl::OUString const & string,char const * message)96 bool checkEmpty(rtl::OUString const & string, char const * message) {
97     bool ok = string.getLength() == 0;
98     if (!ok) {
99         fprintf(
100             stderr, "%s failed: %s\n", message,
101             rtl::OUStringToOString(string, RTL_TEXTENCODING_UTF8).getStr());
102     }
103     return ok;
104 }
105 
106 }
107 
108 //==================================================================================================
109 class TestBridgeImpl : public osl::DebugBase<TestBridgeImpl>,
110                        public WeakImplHelper2< XMain, XServiceInfo >
111 {
112     Reference< XComponentContext > m_xContext;
113 
114 public:
TestBridgeImpl(const Reference<XComponentContext> & xContext)115     TestBridgeImpl( const Reference< XComponentContext > & xContext )
116         : m_xContext( xContext )
117         {}
~TestBridgeImpl()118     virtual ~TestBridgeImpl()
119     {
120     }
121 
122     // XServiceInfo
123     virtual OUString SAL_CALL getImplementationName();
124     virtual sal_Bool SAL_CALL supportsService( const OUString & rServiceName );
125     virtual Sequence< OUString > SAL_CALL getSupportedServiceNames();
126 
127     // XMain
128     virtual sal_Int32 SAL_CALL run( const Sequence< OUString > & rArgs );
129 };
130 
131 //==================================================================================================
equals(const TestElement & rData1,const TestElement & rData2)132 static sal_Bool equals( const TestElement & rData1, const TestElement & rData2 )
133 {
134     check( rData1.Bool == rData2.Bool, "### bool does not match!" );
135     check( rData1.Char == rData2.Char, "### char does not match!" );
136     check( rData1.Byte == rData2.Byte, "### byte does not match!" );
137     check( rData1.Short == rData2.Short, "### short does not match!" );
138     check( rData1.UShort == rData2.UShort, "### unsigned short does not match!" );
139     check( rData1.Long == rData2.Long, "### long does not match!" );
140     check( rData1.ULong == rData2.ULong, "### unsigned long does not match!" );
141     check( rData1.Hyper == rData2.Hyper, "### hyper does not match!" );
142     check( rData1.UHyper == rData2.UHyper, "### unsigned hyper does not match!" );
143     check( rData1.Float == rData2.Float, "### float does not match!" );
144     check( rData1.Double == rData2.Double, "### double does not match!" );
145     check( rData1.Enum == rData2.Enum, "### enum does not match!" );
146     check( rData1.String == rData2.String, "### string does not match!" );
147     check( rData1.Interface == rData2.Interface, "### interface does not match!" );
148     check( rData1.Any == rData2.Any, "### any does not match!" );
149 
150     return (rData1.Bool == rData2.Bool &&
151             rData1.Char == rData2.Char &&
152             rData1.Byte == rData2.Byte &&
153             rData1.Short == rData2.Short &&
154             rData1.UShort == rData2.UShort &&
155             rData1.Long == rData2.Long &&
156             rData1.ULong == rData2.ULong &&
157             rData1.Hyper == rData2.Hyper &&
158             rData1.UHyper == rData2.UHyper &&
159             rData1.Float == rData2.Float &&
160             rData1.Double == rData2.Double &&
161             rData1.Enum == rData2.Enum &&
162             rData1.String == rData2.String &&
163             rData1.Interface == rData2.Interface &&
164             rData1.Any == rData2.Any);
165 }
166 //==================================================================================================
equals(const TestData & rData1,const TestData & rData2)167 static sal_Bool equals( const TestData & rData1, const TestData & rData2 )
168 {
169     sal_Int32 nLen;
170 
171     if ((rData1.Sequence == rData2.Sequence) &&
172         equals( (const TestElement &)rData1, (const TestElement &)rData2 ) &&
173         (nLen = rData1.Sequence.getLength()) == rData2.Sequence.getLength())
174     {
175         // once again by hand sequence ==
176         const TestElement * pElements1 = rData1.Sequence.getConstArray();
177         const TestElement * pElements2 = rData2.Sequence.getConstArray();
178         for ( ; nLen--; )
179         {
180             if (! equals( pElements1[nLen], pElements2[nLen] ))
181             {
182                 check( sal_False, "### sequence element did not match!" );
183                 return sal_False;
184             }
185         }
186         return sal_True;
187     }
188     return sal_False;
189 }
190 //==================================================================================================
assign(TestElement & rData,sal_Bool bBool,sal_Unicode cChar,sal_Int8 nByte,sal_Int16 nShort,sal_uInt16 nUShort,sal_Int32 nLong,sal_uInt32 nULong,sal_Int64 nHyper,sal_uInt64 nUHyper,float fFloat,double fDouble,TestEnum eEnum,const::rtl::OUString & rStr,const::com::sun::star::uno::Reference<::com::sun::star::uno::XInterface> & xTest,const::com::sun::star::uno::Any & rAny)191 static void assign( TestElement & rData,
192                     sal_Bool bBool, sal_Unicode cChar, sal_Int8 nByte,
193                     sal_Int16 nShort, sal_uInt16 nUShort,
194                     sal_Int32 nLong, sal_uInt32 nULong,
195                     sal_Int64 nHyper, sal_uInt64 nUHyper,
196                     float fFloat, double fDouble,
197                     TestEnum eEnum, const ::rtl::OUString& rStr,
198                     const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& xTest,
199                     const ::com::sun::star::uno::Any& rAny )
200 {
201     rData.Bool = bBool;
202     rData.Char = cChar;
203     rData.Byte = nByte;
204     rData.Short = nShort;
205     rData.UShort = nUShort;
206     rData.Long = nLong;
207     rData.ULong = nULong;
208     rData.Hyper = nHyper;
209     rData.UHyper = nUHyper;
210     rData.Float = fFloat;
211     rData.Double = fDouble;
212     rData.Enum = eEnum;
213     rData.String = rStr;
214     rData.Interface = xTest;
215     rData.Any = rAny;
216 }
217 
218 namespace {
219 
220 template < typename T >
testAny(T const & value,Reference<XBridgeTest> const & xLBT,char const * typeName=0)221 bool testAny(
222     T const & value, Reference< XBridgeTest > const & xLBT,
223     char const * typeName = 0)
224 {
225     Any any;
226     any <<=  value;
227     Any any2 = xLBT->transportAny(any);
228     bool success = true;
229     if (any != any2) {
230         fprintf(
231             stderr, "any is different after roundtrip: in %s, out %s\n",
232             OUStringToOString(
233                 any.getValueType().getTypeName(),
234                 RTL_TEXTENCODING_ASCII_US).getStr(),
235             OUStringToOString(
236                 any2.getValueType().getTypeName(),
237                 RTL_TEXTENCODING_ASCII_US).getStr());
238         success = false;
239     }
240     if (typeName != 0
241         && !any2.getValueType().getTypeName().equalsAscii(typeName))
242     {
243         fprintf(
244             stderr, "any has wrong type after roundtrip: %s instead of %s\n",
245             OUStringToOString(
246                 any2.getValueType().getTypeName(),
247                 RTL_TEXTENCODING_ASCII_US).getStr(),
248             typeName);
249         success = false;
250     }
251     return success;
252 }
253 
254 }
255 
performAnyTest(const Reference<XBridgeTest> & xLBT,const TestData & data)256 static sal_Bool performAnyTest( const Reference< XBridgeTest > &xLBT, const TestData &data)
257 {
258     bool bReturn = true;
259     bReturn = testAny( data.Byte ,xLBT ) && bReturn;
260     bReturn = testAny( data.Short,xLBT ) && bReturn;
261     bReturn = testAny( data.UShort,xLBT ) && bReturn;
262     bReturn = testAny( data.Long,xLBT ) && bReturn;
263     bReturn = testAny( data.ULong,xLBT ) && bReturn;
264     bReturn = testAny( data.Hyper,xLBT ) && bReturn;
265     bReturn = testAny( data.UHyper,xLBT ) && bReturn;
266     bReturn = testAny( data.Float,xLBT ) && bReturn;
267     bReturn = testAny( data.Double,xLBT ) && bReturn;
268     bReturn = testAny( data.Enum,xLBT ) && bReturn;
269     bReturn = testAny( data.String,xLBT ) && bReturn;
270     bReturn = testAny( data.Interface,xLBT ) && bReturn;
271     bReturn = testAny( data, xLBT ) && bReturn;
272     bReturn &= testAny(
273         TestPolyStruct< sal_Unicode >(' '), xLBT,
274         "test.testtools.bridgetest.TestPolyStruct<char>");
275 
276     Any a;
277     {
278         a.setValue( &(data.Bool) , getCppuBooleanType() );
279         Any a2 = xLBT->transportAny( a );
280         OSL_ASSERT( a2 == a );
281     }
282 
283     {
284         a.setValue( &(data.Char) , getCppuCharType() );
285         Any a2 = xLBT->transportAny( a );
286         OSL_ASSERT( a2 == a );
287     }
288 
289     return bReturn;
290 }
291 
292 //_______________________________________________________________________________________
performSequenceOfCallTest(const Reference<XBridgeTest> & xLBT)293 static sal_Bool performSequenceOfCallTest( const Reference < XBridgeTest > &xLBT )
294 {
295     sal_Int32 i,nRounds;
296     sal_Int32 nGlobalIndex = 0;
297     const sal_Int32 nWaitTimeSpanMUSec = 10000;
298     for( nRounds = 0 ; nRounds < 10 ; nRounds ++ )
299     {
300         for( i = 0 ; i < nRounds ; i ++ )
301         {
302             // fire oneways
303             xLBT->callOneway( nGlobalIndex , nWaitTimeSpanMUSec );
304             nGlobalIndex ++;
305         }
306 
307         // call synchron
308         xLBT->call( nGlobalIndex , nWaitTimeSpanMUSec );
309         nGlobalIndex ++;
310     }
311 
312     return xLBT->sequenceOfCallTestPassed();
313 }
314 
315 class ORecursiveCall : public WeakImplHelper1< XRecursiveCall >
316 {
317 private:
318     Mutex m_mutex;
319 
320 public:
callRecursivly(const::com::sun::star::uno::Reference<XRecursiveCall> & xCall,sal_Int32 nToCall)321     void SAL_CALL callRecursivly(
322         const ::com::sun::star::uno::Reference< XRecursiveCall >& xCall,
323         sal_Int32 nToCall )
324         {
325             MutexGuard guard( m_mutex );
326             if( nToCall )
327             {
328                 nToCall --;
329                 xCall->callRecursivly( this , nToCall );
330             }
331 
332         }
333 };
334 
335 
336 //_______________________________________________________________________________________
performRecursiveCallTest(const Reference<XBridgeTest> & xLBT)337 static sal_Bool performRecursiveCallTest( const Reference < XBridgeTest > & xLBT )
338 {
339     xLBT->startRecursiveCall( new ORecursiveCall , 50 );
340     // on failure, the test would lock up or crash
341     return sal_True;
342 }
343 
344 class MyClass : public osl::DebugBase<MyClass>, public OWeakObject
345 {
346 public:
347     MyClass();
348     virtual ~MyClass();
349     virtual void SAL_CALL acquire() throw ();
350     virtual void SAL_CALL release() throw ();
351 };
352 
353 //______________________________________________________________________________
MyClass()354 MyClass::MyClass()
355 {
356 }
357 //______________________________________________________________________________
~MyClass()358 MyClass::~MyClass()
359 {
360 }
361 //______________________________________________________________________________
acquire()362 void MyClass::acquire() throw ()
363 {
364     OWeakObject::acquire();
365 }
366 //______________________________________________________________________________
release()367 void MyClass::release() throw ()
368 {
369     OWeakObject::release();
370 }
371 
372 //==================================================================================================
performTest(const Reference<XComponentContext> & xContext,const Reference<XBridgeTest> & xLBT,bool noCurrentContext)373 static sal_Bool performTest(
374     const Reference<XComponentContext> & xContext,
375     const Reference<XBridgeTest > & xLBT,
376     bool noCurrentContext )
377 {
378     check(xLBT.is(), "### no test interface!");
379     bool bRet = true;
380     if (xLBT.is()) {
381         // this data is never ever granted access to by calls other than
382         // equals(), assign()!
383         TestData aData; // test against this data
384         Reference< XInterface > xI(new MyClass);
385         assign(
386             (TestElement &) aData, true, '@', 17, 0x1234, 0xFEDC, 0x12345678,
387             0xFEDCBA98, SAL_CONST_INT64(0x123456789ABCDEF0),
388             SAL_CONST_UINT64(0xFEDCBA9876543210), 17.0815f, 3.1415926359,
389             TestEnum_LOLA, OUSTR(STRING_TEST_CONSTANT), xI,
390             Any(&xI, getCppuType((Reference< XInterface > const *) 0)));
391         bRet &= check(aData.Any == xI, "### unexpected any!");
392         bRet &= check(!(aData.Any != xI), "### unexpected any!");
393         aData.Sequence.realloc(2);
394         aData.Sequence[0] = *(TestElement const *) &aData;
395         // aData.Sequence[1] is empty
396         // aSetData is a manually copy of aData for first setting:
397         TestData aSetData;
398         assign(
399             (TestElement &) aSetData, aData.Bool, aData.Char, aData.Byte,
400             aData.Short, aData.UShort, aData.Long, aData.ULong, aData.Hyper,
401             aData.UHyper, aData.Float, aData.Double, aData.Enum, aData.String,
402             xI, Any(&xI, getCppuType((Reference< XInterface > const *) 0)));
403         aSetData.Sequence.realloc(2);
404         aSetData.Sequence[0] = *(TestElement const *) &aSetData;
405         // aSetData.Sequence[1] is empty
406         xLBT->setValues(
407             aSetData.Bool, aSetData.Char, aSetData.Byte, aSetData.Short,
408             aSetData.UShort, aSetData.Long, aSetData.ULong, aSetData.Hyper,
409             aSetData.UHyper, aSetData.Float, aSetData.Double, aSetData.Enum,
410             aSetData.String, aSetData.Interface, aSetData.Any,
411             aSetData.Sequence, aSetData);
412         {
413             TestData aRet;
414             TestData aRet2;
415             xLBT->getValues(
416                 aRet.Bool, aRet.Char, aRet.Byte, aRet.Short, aRet.UShort,
417                 aRet.Long, aRet.ULong, aRet.Hyper, aRet.UHyper, aRet.Float,
418                 aRet.Double, aRet.Enum, aRet.String, aRet.Interface, aRet.Any,
419                 aRet.Sequence, aRet2);
420             bRet &= check(
421                 equals(aData, aRet) && equals(aData, aRet2), "getValues test");
422             // Set last retrieved values:
423             TestData aSV2ret(
424                 xLBT->setValues2(
425                     aRet.Bool, aRet.Char, aRet.Byte, aRet.Short, aRet.UShort,
426                     aRet.Long, aRet.ULong, aRet.Hyper, aRet.UHyper, aRet.Float,
427                     aRet.Double, aRet.Enum, aRet.String, aRet.Interface,
428                     aRet.Any, aRet.Sequence, aRet2));
429             // Check inout sequence order (=> inout sequence parameter was
430             // switched by test objects):
431             TestElement temp(aRet.Sequence[0]);
432             aRet.Sequence[0] = aRet.Sequence[1];
433             aRet.Sequence[1] = temp;
434             bRet &= check(
435                 equals(aData, aSV2ret) && equals(aData, aRet2),
436                 "getValues2 test");
437         }
438         {
439             TestData aRet;
440             TestData aRet2;
441             TestData aGVret(
442                 xLBT->getValues(
443                     aRet.Bool, aRet.Char, aRet.Byte, aRet.Short, aRet.UShort,
444                     aRet.Long, aRet.ULong, aRet.Hyper, aRet.UHyper, aRet.Float,
445                     aRet.Double, aRet.Enum, aRet.String, aRet.Interface,
446                     aRet.Any, aRet.Sequence, aRet2));
447             bRet &= check(
448                 (equals(aData, aRet) && equals(aData, aRet2) &&
449                  equals(aData, aGVret)),
450                 "getValues test");
451             // Set last retrieved values:
452             xLBT->setBool(aRet.Bool);
453             xLBT->setChar(aRet.Char);
454             xLBT->setByte(aRet.Byte);
455             xLBT->setShort(aRet.Short);
456             xLBT->setUShort(aRet.UShort);
457             xLBT->setLong(aRet.Long);
458             xLBT->setULong(aRet.ULong);
459             xLBT->setHyper(aRet.Hyper);
460             xLBT->setUHyper(aRet.UHyper);
461             xLBT->setFloat(aRet.Float);
462             xLBT->setDouble(aRet.Double);
463             xLBT->setEnum(aRet.Enum);
464             xLBT->setString(aRet.String);
465             xLBT->setInterface(aRet.Interface);
466             xLBT->setAny(aRet.Any);
467             xLBT->setSequence(aRet.Sequence);
468             xLBT->setStruct(aRet2);
469         }
470         {
471             TestData aRet;
472             aRet.Hyper = xLBT->getHyper();
473             aRet.UHyper = xLBT->getUHyper();
474             aRet.Float = xLBT->getFloat();
475             aRet.Double = xLBT->getDouble();
476             aRet.Byte = xLBT->getByte();
477             aRet.Char = xLBT->getChar();
478             aRet.Bool = xLBT->getBool();
479             aRet.Short = xLBT->getShort();
480             aRet.UShort = xLBT->getUShort();
481             aRet.Long = xLBT->getLong();
482             aRet.ULong = xLBT->getULong();
483             aRet.Enum = xLBT->getEnum();
484             aRet.String = xLBT->getString();
485             aRet.Interface = xLBT->getInterface();
486             aRet.Any = xLBT->getAny();
487             aRet.Sequence = xLBT->getSequence();
488             TestData aRet2(xLBT->getStruct());
489             bRet &= check(
490                 equals(aData, aRet) && equals(aData, aRet2),
491                 "struct comparison test");
492             {
493                 SmallStruct aIn(1, 2);
494                 SmallStruct aOut(xLBT->echoSmallStruct(aIn));
495                 bRet &= check(
496                     memcmp(&aIn, &aOut, sizeof(SmallStruct)) == 0,
497                     "small struct test");
498             }
499             {
500                 MediumStruct aIn(1, 2, 3, 4);
501                 MediumStruct aOut(xLBT->echoMediumStruct(aIn));
502                 bRet &= check(
503                     memcmp(&aIn, &aOut, sizeof(MediumStruct)) == 0,
504                     "medium struct test");
505             }
506             {
507                 BigStruct aIn(1, 2, 3, 4, 5, 6, 7, 8);
508                 BigStruct aOut(xLBT->echoBigStruct(aIn));
509                 bRet &= check(
510                     memcmp(&aIn, &aOut, sizeof(BigStruct)) == 0,
511                     "big struct test");
512             }
513             {
514                 AllFloats aIn(1.1f, 2.2f, 3.3f, 4.4f);
515                 AllFloats aOut(xLBT->echoAllFloats(aIn));
516                 bRet &= check(
517                     memcmp(&aIn, &aOut, sizeof(AllFloats)) == 0,
518                     "all floats struct test");
519             }
520             {
521                 TwoFloats aIn(1.25f, -2.5f);
522                 TwoFloats aOut(xLBT->echoTwoFloats(aIn));
523                 bRet &= check(aOut.a == aIn.a && aOut.b == aIn.b,
524                     "two-float HFA test");
525             }
526             {
527                 ThreeDoubles aIn(1.25, -2.5, 9.75);
528                 ThreeDoubles aOut(xLBT->echoThreeDoubles(aIn));
529                 bRet &= check(
530                     aOut.a == aIn.a && aOut.b == aIn.b && aOut.c == aIn.c,
531                     "three-double HFA test");
532             }
533             {
534                 MixedFloatLong aIn(1.25f, -123456);
535                 MixedFloatLong aOut(xLBT->echoMixedFloatLong(aIn));
536                 bRet &= check(aOut.a == aIn.a && aOut.b == aIn.b,
537                     "mixed float-long struct test");
538             }
539             {
540                 OneByte aIn(-7);
541                 OneByte aOut(xLBT->echoOneByte(aIn));
542                 bRet &= check(aOut.value == aIn.value, "one-byte struct test");
543             }
544             {
545                 ThreeLongs aIn(0x11223344, -7, 0x55667788);
546                 ThreeLongs aOut(xLBT->echoThreeLongs(aIn));
547                 bRet &= check(
548                     aOut.a == aIn.a && aOut.b == aIn.b && aOut.c == aIn.c,
549                     "three-long struct test");
550             }
551             {
552                 sal_Int32 i2 = xLBT->testPPCAlignment(0, 0, 0, 0, 0xBEAF);
553                 bRet &= check(i2 == 0xBEAF, "ppc-style alignment test");
554             }
555             {
556                 sal_Int8 b = -2;
557                 sal_Int8 c = 0x35;
558                 sal_Int16 s = -1234;
559                 sal_Int32 l = 0x11223344;
560                 sal_Int8 d = -7;
561                 sal_Int64 h = SAL_CONST_INT64(0x0102030405060708);
562                 sal_Int64 expected = ((static_cast<sal_Int64>(b) << 56) |
563                     (static_cast<sal_uInt64>(static_cast<sal_uInt8>(c)) << 48) |
564                     (static_cast<sal_uInt64>(static_cast<sal_uInt16>(s)) << 32) |
565                     static_cast<sal_uInt32>(l)) ^
566                     (static_cast<sal_Int64>(d) << 24) ^ h;
567                 bRet &= check(
568                     xLBT->testPackedStack(0, 1, 2, 3, 4, 5, 6, b, c, s, l, d, h)
569                         == expected,
570                     "packed stack argument test");
571             }
572             {
573                 double result = xLBT->testFpStack(
574                     0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0,
575                     -3.25f, 9.5);
576                 bRet &= check(result == 6.25, "fp stack argument test");
577             }
578             // Test extended attributes that raise exceptions:
579             try {
580                 xLBT->getRaiseAttr1();
581                 bRet &= check(false, "getRaiseAttr1 did not throw");
582             } catch (RuntimeException &) {
583             } catch (...) {
584                 bRet &= check(false, "getRaiseAttr1 threw wrong type");
585             }
586             try {
587                 xLBT->setRaiseAttr1(0);
588                 bRet &= check(false, "setRaiseAttr1 did not throw");
589             } catch (IllegalArgumentException &) {
590             } catch (...) {
591                 bRet &= check(false, "setRaiseAttr1 threw wrong type");
592             }
593             try {
594                 xLBT->getRaiseAttr2();
595                 bRet &= check(false, "getRaiseAttr2 did not throw");
596             } catch (IllegalArgumentException &) {
597             } catch (...) {
598                 bRet &= check(false, "getRaiseAttr2 threw wrong type");
599             }
600 #if !defined(OS2) && !(defined(FREEBSD) && defined(INTEL))
601 // see i120310 for OS2 details
602 // FreeBSD i386 coredumps on this test in cpp_vtable_call():
603 //  pTypeDescr appears to point to garbage, pMapFunctionIndexToMemberIndex
604 //  points to unreadable memory, as does abase.pTypeName.  Refcounts
605 //  don't look reasonable, etc.
606             // Test instantiated polymorphic struct types:
607             {
608                 bRet &= check(
609                     (xLBT->transportPolyBoolean(
610                         TestPolyStruct< sal_Bool >(true)).
611                      member),
612                     "transportPolyBoolean");
613                 TestPolyStruct< sal_Int64 > tps1(12345);
614                 xLBT->transportPolyHyper(tps1);
615                 bRet &= check(tps1.member == 12345, "transportPolyHyper");
616                 Sequence< Any > seq(2);
617                 seq[0] <<= static_cast< sal_uInt32 >(33);
618                 seq[1] <<= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ABC"));
619                 TestPolyStruct< Sequence< Any > > tps2(seq);
620                 TestPolyStruct< Sequence< Any > > tps3;
621                 xLBT->transportPolySequence(tps2, tps3);
622                 bRet &= check(
623                     tps3.member.getLength() == 2,
624                     "transportPolySequence, length");
625                 sal_uInt32 v0 = sal_uInt32();
626                 tps3.member[0] >>= v0;
627                 bRet &= check(v0 == 33, "transportPolySequence, element 0");
628                 rtl::OUString v1;
629                 tps3.member[1] >>= v1;
630                 bRet &= check(
631                     v1.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("ABC")),
632                     "transportPolySequence, element 1");
633                 bRet &= check(
634                     xLBT->getNullPolyLong().member == 0, "getNullPolyLong");
635                 bRet &= check(
636                     xLBT->getNullPolyString().member.getLength() == 0,
637                     "getNullPolyString");
638                 bRet &= check(
639                     xLBT->getNullPolyType().member == Type(),
640                     "getNullPolyType");
641                 Any nullAny(xLBT->getNullPolyAny().member);
642                 bRet &= check(
643                     (((nullAny.getValueTypeName() ==
644                        rtl::OUString(
645                            RTL_CONSTASCII_USTRINGPARAM(
646                                "com.sun.star.uno.XInterface"))) &&
647                       !static_cast< Reference< XInterface > const * >(
648                           nullAny.getValue())->is())
649                      || nullAny == Any()),
650                     "getNullPolyAny");
651                 bRet &= check(
652                     xLBT->getNullPolySequence().member.getLength() == 0,
653                     "getNullPolySequence");
654                 bRet &= check(
655                     xLBT->getNullPolyEnum().member == TestEnum_TEST,
656                     "getNullPolyEnum");
657                 bRet &= check(
658                     xLBT->getNullPolyBadEnum().member == TestBadEnum_M,
659                     "getNullPolyBadEnum");
660                 bRet &= check(
661                     xLBT->getNullPolyStruct().member.member == 0,
662                     "getNullPolyStruct");
663                 bRet &= check(
664                     !xLBT->getNullPolyInterface().member.is(),
665                     "getNullPolyInterface");
666             }
667 #endif // OS2
668 
669             // Any test:
670             bRet &= check(performAnyTest(xLBT , aData), "any test");
671             // Sequence of call test:
672             bRet &= check(
673                 performSequenceOfCallTest(xLBT), "sequence of call test");
674             // Recursive call test:
675             bRet &= check(performRecursiveCallTest(xLBT), "recursive test");
676             bRet &= check(
677                 equals(aData, aRet) && equals(aData, aRet2),
678                 "recursive test results");
679             // Multiple inheritance test:
680             bRet &= checkEmpty(
681                 testtools::bridgetest::testMulti(xLBT->getMulti()),
682                 "remote multi");
683             bRet &= checkEmpty(
684                 xLBT->testMulti(new testtools::bridgetest::Multi),
685                 "local multi");
686         }
687     }
688     {
689         Reference< XBridgeTest2 > xBT2(xLBT, UNO_QUERY);
690         if (!xBT2.is()) {
691             return bRet;
692         }
693         // Perform sequence tests (XBridgeTest2); create the sequence which is
694         // compared with the results:
695         sal_Bool _arBool[] = { true, false, true };
696         sal_Unicode _arChar[] = { 0x0065, 0x0066, 0x0067 };
697         sal_Int8 _arByte[] = { 1, 2, -1 };
698         sal_Int16 _arShort[] = { -0x8000, 1, 0x7FFF };
699         sal_uInt16 _arUShort[] = { 0 , 1, 0xFFFF };
700         sal_Int32 _arLong[] = { -0x7FFFFFFF, 1, 0x7FFFFFFF };
701         sal_uInt32 _arULong[] = { 0, 1, 0xFFFFFFFF };
702         sal_Int64 _arHyper[] = {
703             SAL_CONST_INT64(-0x7FFFFFFFFFFFFFFF), 1,
704             SAL_CONST_INT64(+0x7FFFFFFFFFFFFFFF) };
705         sal_uInt64 _arUHyper[] = { 0, 1, SAL_CONST_UINT64(0xFFFFFFFFFFFFFFFF) };
706         float _arFloat[] = { 1.1f, 2.2f, 3.3f };
707         double _arDouble[] = { 1.11, 2.22, 3.33 };
708         OUString _arString[] = {
709             OUString(RTL_CONSTASCII_USTRINGPARAM("String 1")),
710             OUString(RTL_CONSTASCII_USTRINGPARAM("String 2")),
711             OUString(RTL_CONSTASCII_USTRINGPARAM("String 3")) };
712         sal_Bool _aBool = true;
713         sal_Int32 _aInt = 0xBABEBABE;
714         float _aFloat = 3.14f;
715         Any _any1(&_aBool, getCppuBooleanType());
716         Any _any2(&_aInt, getCppuType((sal_Int32 *) 0));
717         Any _any3(&_aFloat, getCppuType((float *) 0));
718         Any _arAny[] = { _any1, _any2, _any3 };
719         Reference< XInterface > _arObj[3];
720         _arObj[0] = new OWeakObject();
721         _arObj[1] = new OWeakObject();
722         _arObj[2] = new OWeakObject();
723         TestEnum _arEnum[] = { TestEnum_ONE, TestEnum_TWO, TestEnum_CHECK };
724         TestElement _arStruct[3];
725         assign(
726             _arStruct[0], true, '@', 17, 0x1234, 0xFEDC, 0x12345678, 0xFEDCBA98,
727             SAL_CONST_INT64(0x123456789ABCDEF0),
728             SAL_CONST_UINT64(0xFEDCBA9876543210), 17.0815f, 3.1415926359,
729             TestEnum_LOLA, OUSTR(STRING_TEST_CONSTANT), _arObj[0],
730             Any(&_arObj[0], getCppuType((Reference< XInterface > const *) 0)));
731         assign(
732             _arStruct[1], true, 'A', 17, 0x1234, 0xFEDC, 0x12345678, 0xFEDCBA98,
733             SAL_CONST_INT64(0x123456789ABCDEF0),
734             SAL_CONST_UINT64(0xFEDCBA9876543210), 17.0815f, 3.1415926359,
735             TestEnum_TWO, OUSTR(STRING_TEST_CONSTANT), _arObj[1],
736             Any(&_arObj[1], getCppuType((Reference< XInterface > const *) 0)));
737         assign(
738             _arStruct[2], true, 'B', 17, 0x1234, 0xFEDC, 0x12345678, 0xFEDCBA98,
739             SAL_CONST_INT64(0x123456789ABCDEF0),
740             SAL_CONST_UINT64(0xFEDCBA9876543210), 17.0815f, 3.1415926359,
741             TestEnum_CHECK, OUSTR(STRING_TEST_CONSTANT), _arObj[2],
742             Any(&_arObj[2], getCppuType((Reference< XInterface > const *) 0)));
743         {
744             Sequence<sal_Bool> arBool(_arBool, 3);
745             Sequence<sal_Unicode> arChar( _arChar, 3);
746             Sequence<sal_Int8> arByte(_arByte, 3);
747             Sequence<sal_Int16> arShort(_arShort, 3);
748             Sequence<sal_uInt16> arUShort(_arUShort, 3);
749             Sequence<sal_Int32> arLong(_arLong, 3);
750             Sequence<sal_uInt32> arULong(_arULong, 3);
751             Sequence<sal_Int64> arHyper(_arHyper, 3);
752             Sequence<sal_uInt64> arUHyper(_arUHyper, 3);
753             Sequence<float> arFloat(_arFloat, 3);
754             Sequence<double> arDouble(_arDouble, 3);
755             Sequence<OUString> arString(_arString, 3);
756             Sequence<Any> arAny(_arAny, 3);
757             Sequence<Reference<XInterface> > arObject(_arObj, 3);
758             Sequence<TestEnum> arEnum(_arEnum, 3);
759             Sequence<TestElement> arStruct(_arStruct, 3);
760             Sequence<Sequence<sal_Int32> > _arSeqLong2[3];
761             for (int j = 0; j != 3; ++j) {
762                 Sequence< sal_Int32 > _arSeqLong[3];
763                 for (int i = 0; i != 3; ++i) {
764                     _arSeqLong[i] = Sequence< sal_Int32 >(_arLong, 3);
765                 }
766                 _arSeqLong2[j] = Sequence< Sequence< sal_Int32 > >(
767                     _arSeqLong, 3);
768             }
769             Sequence< Sequence< Sequence< sal_Int32> > > arLong3(
770                 _arSeqLong2, 3);
771             Sequence< Sequence< sal_Int32 > > seqSeqRet(
772                 xBT2->setDim2(arLong3[0]));
773             bRet &= check(seqSeqRet == arLong3[0], "sequence test");
774             Sequence< Sequence< Sequence< sal_Int32 > > > seqSeqRet2(
775                 xBT2->setDim3(arLong3));
776             bRet &= check(seqSeqRet2 == arLong3, "sequence test");
777             Sequence< Any > seqAnyRet(xBT2->setSequenceAny(arAny));
778             bRet &= check(seqAnyRet == arAny, "sequence test");
779             Sequence< sal_Bool > seqBoolRet(xBT2->setSequenceBool(arBool));
780             bRet &= check(seqBoolRet == arBool, "sequence test");
781             Sequence< sal_Int8 > seqByteRet(xBT2->setSequenceByte(arByte));
782             bRet &= check(seqByteRet == arByte, "sequence test");
783             Sequence< sal_Unicode > seqCharRet(xBT2->setSequenceChar(arChar));
784             bRet &= check(seqCharRet == arChar, "sequence test");
785             Sequence< sal_Int16 > seqShortRet(xBT2->setSequenceShort(arShort));
786             bRet &= check(seqShortRet == arShort, "sequence test");
787             Sequence< sal_Int32 > seqLongRet(xBT2->setSequenceLong(arLong));
788             bRet &= check(seqLongRet == arLong, "sequence test");
789             Sequence< sal_Int64 > seqHyperRet(xBT2->setSequenceHyper(arHyper));
790             bRet &= check(seqHyperRet == arHyper, "sequence test");
791             Sequence< float > seqFloatRet(xBT2->setSequenceFloat(arFloat));
792             bRet &= check(seqFloatRet == arFloat, "sequence test");
793             Sequence< double > seqDoubleRet(xBT2->setSequenceDouble(arDouble));
794             bRet &= check(seqDoubleRet == arDouble, "sequence test");
795             Sequence< TestEnum > seqEnumRet(xBT2->setSequenceEnum(arEnum));
796             bRet &= check(seqEnumRet == arEnum, "sequence test");
797             Sequence< sal_uInt16 > seqUShortRet(
798                 xBT2->setSequenceUShort(arUShort));
799             bRet &= check(seqUShortRet == arUShort, "sequence test");
800             Sequence< sal_uInt32 > seqULongRet(xBT2->setSequenceULong(arULong));
801             bRet &= check(seqULongRet == arULong, "sequence test");
802             Sequence< sal_uInt64 > seqUHyperRet(
803                 xBT2->setSequenceUHyper(arUHyper));
804             bRet &= check(seqUHyperRet == arUHyper, "sequence test");
805             Sequence< Reference< XInterface > > seqObjectRet(
806                 xBT2->setSequenceXInterface(arObject));
807             bRet &= check(seqObjectRet == arObject, "sequence test");
808             Sequence< OUString > seqStringRet(
809                 xBT2->setSequenceString(arString));
810             bRet &= check(seqStringRet == arString, "sequence test");
811             Sequence< TestElement > seqStructRet(
812                 xBT2->setSequenceStruct(arStruct));
813             bRet &= check(seqStructRet == arStruct, "sequence test");
814             Sequence< sal_Bool > arBoolTemp(cloneSequence(arBool));
815             Sequence< sal_Unicode > arCharTemp(cloneSequence(arChar));
816             Sequence< sal_Int8 > arByteTemp(cloneSequence(arByte));
817             Sequence< sal_Int16 > arShortTemp(cloneSequence(arShort));
818             Sequence< sal_uInt16 > arUShortTemp(cloneSequence(arUShort));
819             Sequence< sal_Int32 > arLongTemp(cloneSequence(arLong));
820             Sequence< sal_uInt32 > arULongTemp(cloneSequence(arULong));
821             Sequence< sal_Int64 > arHyperTemp(cloneSequence(arHyper));
822             Sequence< sal_uInt64 > arUHyperTemp(cloneSequence(arUHyper));
823             Sequence< float > arFloatTemp(cloneSequence(arFloat));
824             Sequence< double > arDoubleTemp(cloneSequence(arDouble));
825             Sequence< TestEnum > arEnumTemp(cloneSequence(arEnum));
826             Sequence< OUString > arStringTemp(cloneSequence(arString));
827             Sequence< Reference< XInterface > > arObjectTemp(
828                 cloneSequence(arObject));
829             Sequence< Any > arAnyTemp(cloneSequence(arAny));
830             Sequence< Sequence< sal_Int32 > > arLong2Temp(arLong3[0]);
831             Sequence< Sequence< Sequence< sal_Int32 > > > arLong3Temp(arLong3);
832             xBT2->setSequencesInOut(
833                 arBoolTemp, arCharTemp, arByteTemp, arShortTemp, arUShortTemp,
834                 arLongTemp,arULongTemp, arHyperTemp, arUHyperTemp, arFloatTemp,
835                 arDoubleTemp, arEnumTemp, arStringTemp, arObjectTemp, arAnyTemp,
836                 arLong2Temp, arLong3Temp);
837             bRet &= check(
838                 (arBoolTemp == arBool && arCharTemp == arChar &&
839                  arByteTemp == arByte && arShortTemp == arShort &&
840                  arUShortTemp == arUShort && arLongTemp == arLong &&
841                  arULongTemp == arULong && arHyperTemp == arHyper &&
842                  arUHyperTemp == arUHyper && arFloatTemp == arFloat &&
843                  arDoubleTemp == arDouble && arEnumTemp == arEnum &&
844                  arStringTemp == arString && arObjectTemp == arObject &&
845                  arAnyTemp == arAny && arLong2Temp == arLong3[0] &&
846                  arLong3Temp == arLong3),
847                 "sequence test");
848             Sequence< sal_Bool > arBoolOut;
849             Sequence< sal_Unicode > arCharOut;
850             Sequence< sal_Int8 > arByteOut;
851             Sequence< sal_Int16 > arShortOut;
852             Sequence< sal_uInt16 > arUShortOut;
853             Sequence< sal_Int32 > arLongOut;
854             Sequence< sal_uInt32 > arULongOut;
855             Sequence< sal_Int64 > arHyperOut;
856             Sequence< sal_uInt64 > arUHyperOut;
857             Sequence< float > arFloatOut;
858             Sequence< double > arDoubleOut;
859             Sequence< TestEnum > arEnumOut;
860             Sequence< OUString > arStringOut;
861             Sequence< Reference< XInterface > > arObjectOut;
862             Sequence< Any > arAnyOut;
863             Sequence< Sequence< sal_Int32 > > arLong2Out;
864             Sequence< Sequence< Sequence< sal_Int32 > > > arLong3Out;
865             xBT2->setSequencesOut(
866                 arBoolOut, arCharOut, arByteOut, arShortOut, arUShortOut,
867                 arLongOut,arULongOut, arHyperOut, arUHyperOut, arFloatOut,
868                 arDoubleOut, arEnumOut, arStringOut, arObjectOut, arAnyOut,
869                 arLong2Out, arLong3Out);
870             bRet &= check(
871                 (arBoolOut == arBool && arCharOut == arChar &&
872                  arByteOut == arByte && arShortOut == arShort &&
873                  arUShortOut == arUShort && arLongOut == arLong &&
874                  arULongOut == arULong && arHyperOut == arHyper &&
875                  arUHyperOut == arUHyper && arFloatOut == arFloat &&
876                  arDoubleOut == arDouble && arEnumOut == arEnum &&
877                  arStringOut == arString && arObjectOut == arObject &&
878                  arAnyOut == arAny && arLong2Out == arLong3[0] &&
879                  arLong3Out == arLong3),
880                 "sequence test");
881         }
882         {
883             // Test with empty sequences:
884             Sequence< Sequence< sal_Int32 > > arLong2;
885             Sequence< Sequence< sal_Int32 > > seqSeqRet(xBT2->setDim2(arLong2));
886             bRet &= check(seqSeqRet == arLong2, "sequence test");
887             Sequence< Sequence< Sequence< sal_Int32 > > > arLong3;
888             Sequence< Sequence< Sequence< sal_Int32 > > > seqSeqRet2(
889                 xBT2->setDim3(arLong3));
890             bRet &= check(seqSeqRet2 == arLong3, "sequence test");
891             Sequence< Any > arAny;
892             Sequence< Any > seqAnyRet(xBT2->setSequenceAny(arAny));
893             bRet &= check(seqAnyRet == arAny, "sequence test");
894             Sequence< sal_Bool > arBool;
895             Sequence< sal_Bool > seqBoolRet(xBT2->setSequenceBool(arBool));
896             bRet &= check(seqBoolRet == arBool, "sequence test");
897             Sequence< sal_Int8 > arByte;
898             Sequence< sal_Int8 > seqByteRet(xBT2->setSequenceByte(arByte));
899             bRet &= check(seqByteRet == arByte, "sequence test");
900             Sequence< sal_Unicode > arChar;
901             Sequence< sal_Unicode > seqCharRet(xBT2->setSequenceChar(arChar));
902             bRet &= check(seqCharRet == arChar, "sequence test");
903             Sequence< sal_Int16 > arShort;
904             Sequence< sal_Int16 > seqShortRet(xBT2->setSequenceShort(arShort));
905             bRet &= check(seqShortRet == arShort, "sequence test");
906             Sequence< sal_Int32 > arLong;
907             Sequence< sal_Int32 > seqLongRet(xBT2->setSequenceLong(arLong));
908             bRet &= check(seqLongRet == arLong, "sequence test");
909             Sequence< sal_Int64 > arHyper;
910             Sequence< sal_Int64 > seqHyperRet(xBT2->setSequenceHyper(arHyper));
911             bRet &= check(seqHyperRet == arHyper, "sequence test");
912             Sequence< float > arFloat;
913             Sequence< float > seqFloatRet(xBT2->setSequenceFloat(arFloat));
914             bRet &= check(seqFloatRet == arFloat, "sequence test");
915             Sequence< double > arDouble;
916             Sequence< double > seqDoubleRet(xBT2->setSequenceDouble(arDouble));
917             bRet &= check(seqDoubleRet == arDouble, "sequence test");
918             Sequence< TestEnum > arEnum;
919             Sequence< TestEnum > seqEnumRet(xBT2->setSequenceEnum(arEnum));
920             bRet &= check(seqEnumRet == arEnum, "sequence test");
921             Sequence< sal_uInt16 > arUShort;
922             Sequence< sal_uInt16 > seqUShortRet(
923                 xBT2->setSequenceUShort(arUShort));
924             bRet &= check(seqUShortRet == arUShort, "sequence test");
925             Sequence< sal_uInt32 > arULong;
926             Sequence< sal_uInt32 > seqULongRet(xBT2->setSequenceULong(arULong));
927             bRet &= check(seqULongRet == arULong, "sequence test");
928             Sequence< sal_uInt64 > arUHyper;
929             Sequence< sal_uInt64 > seqUHyperRet(
930                 xBT2->setSequenceUHyper(arUHyper));
931             bRet &= check(seqUHyperRet == arUHyper, "sequence test");
932             Sequence< Reference< XInterface > > arObject;
933             Sequence< Reference< XInterface > > seqObjectRet(
934                 xBT2->setSequenceXInterface(arObject));
935             bRet &= check(seqObjectRet == arObject, "sequence test");
936             Sequence< OUString > arString;
937             Sequence< OUString > seqStringRet(
938                 xBT2->setSequenceString(arString));
939             bRet &= check(seqStringRet == arString, "sequence test");
940             Sequence< TestElement > arStruct;
941             Sequence< TestElement > seqStructRet(
942                 xBT2->setSequenceStruct(arStruct));
943             bRet &= check(seqStructRet == arStruct, "sequence test");
944         }
945         // Issue #i60341# shows that the most interesting case is were Java
946         // calls the constructors; however, since this client is currently not
947         // available in Java, while the server is, the logic is reversed here:
948         try {
949             xBT2->testConstructorsService(xContext);
950         } catch (BadConstructorArguments &) {
951             bRet = false;
952         }
953         if (!noCurrentContext) {
954             if (!(new testtools::bridgetest::CurrentContextChecker)->perform(
955                     xBT2->getCurrentContextChecker(), 0, 1))
956             {
957                 bRet = false;
958             }
959             if (!(new testtools::bridgetest::CurrentContextChecker)->perform(
960                     xBT2->getCurrentContextChecker(), 0, 2))
961             {
962                 bRet = false;
963             }
964             if (!(new testtools::bridgetest::CurrentContextChecker)->perform(
965                     xBT2->getCurrentContextChecker(), 1, 2))
966             {
967                 bRet = false;
968             }
969             if (!(new testtools::bridgetest::CurrentContextChecker)->perform(
970                     xBT2->getCurrentContextChecker(), 1, 3))
971             {
972                 bRet = false;
973             }
974         }
975     }
976     return bRet;
977 }
978 
raiseOnewayException(const Reference<XBridgeTest> & xLBT)979 static sal_Bool raiseOnewayException( const Reference < XBridgeTest > & xLBT )
980 {
981     sal_Bool bReturn = sal_True;
982     OUString sCompare = OUSTR(STRING_TEST_CONSTANT);
983     Reference<XInterface> const x(xLBT->getInterface());
984     try
985     {
986         // Note : the exception may fly or not (e.g. remote scenario).
987         //        When it flies, it must contain the correct elements.
988         xLBT->raiseRuntimeExceptionOneway( sCompare, x );
989     }
990     catch( RuntimeException & e )
991     {
992         bReturn = (
993 #if OSL_DEBUG_LEVEL == 0
994             // java stack traces trash Message
995             e.Message == sCompare &&
996 #endif
997             xLBT->getInterface() == e.Context &&
998             x == e.Context );
999     }
1000     return bReturn;
1001 }
1002 
1003 //==================================================================================================
raiseException(const Reference<XBridgeTest> & xLBT)1004 static sal_Bool raiseException( const Reference< XBridgeTest > & xLBT )
1005 {
1006     sal_Int32 nCount = 0;
1007     try
1008     {
1009         try
1010         {
1011             try
1012             {
1013                 TestData aRet, aRet2;
1014                 xLBT->raiseException(
1015                     5, OUSTR(STRING_TEST_CONSTANT),
1016                     xLBT->getInterface() );
1017             }
1018             catch (IllegalArgumentException aExc)
1019             {
1020                 if (aExc.ArgumentPosition == 5 &&
1021 #if OSL_DEBUG_LEVEL == 0
1022                     // java stack traces trash Message
1023                     aExc.Message.compareToAscii( STRING_TEST_CONSTANT ) == 0 &&
1024 #endif
1025                     aExc.Context == xLBT->getInterface())
1026                 {
1027 #ifdef COMPCHECK
1028                     //When we check if a new compiler still works then we must not call
1029                     //getRuntimeException because it uses cppu::getCaughtException which
1030                     //does only work if all libs are build with the same runtime.
1031                     return true;
1032 #else
1033                     ++nCount;
1034 #endif
1035                 }
1036                 else
1037                 {
1038                     check( sal_False, "### unexpected exception content!" );
1039                 }
1040 
1041                 /** it is certain, that the RuntimeException testing will fail, if no */
1042                 xLBT->getRuntimeException();
1043             }
1044         }
1045         catch (const RuntimeException & rExc)
1046         {
1047             if (rExc.Context == xLBT->getInterface()
1048 #if OSL_DEBUG_LEVEL == 0
1049                     // java stack traces trash Message
1050                 && rExc.Message.compareToAscii( STRING_TEST_CONSTANT ) == 0
1051 #endif
1052                 )
1053             {
1054                 ++nCount;
1055             }
1056             else
1057             {
1058                 check( sal_False, "### unexpected exception content!" );
1059             }
1060 
1061             /** it is certain, that the RuntimeException testing will fail, if no */
1062             xLBT->setRuntimeException( 0xcafebabe );
1063         }
1064     }
1065     catch (Exception & rExc)
1066     {
1067         if (rExc.Context == xLBT->getInterface()
1068 #if OSL_DEBUG_LEVEL == 0
1069             // java stack traces trash Message
1070             && rExc.Message.compareToAscii( STRING_TEST_CONSTANT ) == 0
1071 #endif
1072             )
1073         {
1074             ++nCount;
1075         }
1076         else
1077         {
1078             check( sal_False, "### unexpected exception content!" );
1079         }
1080         return (nCount == 3);
1081     }
1082     return sal_False;
1083 }
1084 
1085 /* Returns an acquired sequence
1086  */
cloneSequence(const uno_Sequence * val,const Type & type)1087 uno_Sequence* cloneSequence(const uno_Sequence* val, const Type& type)
1088 {
1089     TypeDescription td(type);
1090     td.makeComplete();
1091     typelib_TypeDescription* pTdRaw = td.get();
1092     typelib_IndirectTypeDescription* pIndirectTd =
1093         (typelib_IndirectTypeDescription*) pTdRaw;
1094 
1095     typelib_TypeDescription* pTdElem = pIndirectTd->pType->pType;
1096     sal_Int8* buf = new sal_Int8[pTdElem->nSize * val->nElements];
1097     sal_Int8* pBufCur = buf;
1098 
1099     uno_Sequence* retSeq = NULL;
1100     switch (pTdElem->eTypeClass)
1101     {
1102     case TypeClass_SEQUENCE:
1103     {
1104         Type _tElem(pTdElem->pWeakRef);
1105         for (int i = 0; i < val->nElements; i++)
1106         {
1107             uno_Sequence* seq = cloneSequence(
1108                 *(uno_Sequence**) (&val->elements + i * pTdElem->nSize),
1109                 _tElem);
1110             *((uno_Sequence**) pBufCur) = seq;
1111             pBufCur += pTdElem->nSize;
1112         }
1113         break;
1114     }
1115     default:
1116         uno_type_sequence_construct(
1117             &retSeq, type.getTypeLibType(), (void*) val->elements,
1118             val->nElements, reinterpret_cast< uno_AcquireFunc >(cpp_acquire));
1119         break;
1120     }
1121     delete[] buf;
1122     return retSeq;
1123 }
1124 
1125 template< class T>
cloneSequence(const Sequence<T> & val)1126 Sequence<T> cloneSequence(const Sequence<T>& val)
1127 {
1128     Sequence<T> seq( cloneSequence(val.get(), getCppuType(&val)), SAL_NO_ACQUIRE);
1129     return seq;
1130 }
1131 
1132 template< class T >
makeSurrogate(Reference<T> & rOut,Reference<T> const & rOriginal)1133 inline bool makeSurrogate(
1134     Reference< T > & rOut, Reference< T > const & rOriginal )
1135 {
1136     rOut.clear();
1137     if (! rOriginal.is())
1138         return false;
1139 
1140     Environment aCppEnv_official;
1141     Environment aUnoEnv_ano;
1142     Environment aCppEnv_ano;
1143 
1144     OUString aCppEnvTypeName(
1145         RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME) );
1146     OUString aUnoEnvTypeName(
1147         RTL_CONSTASCII_USTRINGPARAM(UNO_LB_UNO) );
1148     // official:
1149     uno_getEnvironment(
1150         reinterpret_cast< uno_Environment ** >( &aCppEnv_official ),
1151         aCppEnvTypeName.pData, 0 );
1152     // anonymous:
1153     uno_createEnvironment(
1154         reinterpret_cast< uno_Environment ** >( &aCppEnv_ano ),
1155         aCppEnvTypeName.pData, 0 );
1156     uno_createEnvironment(
1157         reinterpret_cast< uno_Environment ** >( &aUnoEnv_ano ),
1158         aUnoEnvTypeName.pData, 0 );
1159 
1160     UnoInterfaceReference unoI;
1161     Mapping cpp2uno( aCppEnv_official.get(), aUnoEnv_ano.get() );
1162     Mapping uno2cpp( aUnoEnv_ano.get(), aCppEnv_ano.get() );
1163     if (!cpp2uno.is() || !uno2cpp.is())
1164     {
1165         throw RuntimeException(
1166             OUSTR("cannot get C++-UNO mappings!"),
1167             Reference< XInterface >() );
1168     }
1169     cpp2uno.mapInterface(
1170         reinterpret_cast< void ** >( &unoI.m_pUnoI ),
1171         rOriginal.get(), ::getCppuType( &rOriginal ) );
1172     if (! unoI.is())
1173     {
1174         throw RuntimeException(
1175             OUSTR("mapping C++ to binary UNO failed!"),
1176             Reference< XInterface >() );
1177     }
1178     uno2cpp.mapInterface(
1179         reinterpret_cast< void ** >( &rOut ),
1180         unoI.get(), ::getCppuType( &rOriginal ) );
1181     if (! rOut.is())
1182     {
1183         throw RuntimeException(
1184             OUSTR("mapping binary UNO to C++ failed!"),
1185             Reference< XInterface >() );
1186     }
1187 
1188     return rOut.is();
1189 }
1190 
1191 //==================================================================================================
run(const Sequence<OUString> & rArgs)1192 sal_Int32 TestBridgeImpl::run( const Sequence< OUString > & rArgs )
1193 {
1194     bool bRet = false;
1195     try
1196     {
1197         if (! rArgs.getLength())
1198         {
1199             throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM(
1200                                                   "no test object specified!\n"
1201                                                   "usage : ServiceName of test object | -u unourl of test object\n" ) ),
1202                                     Reference< XInterface >() );
1203         }
1204 
1205         Reference< XInterface > xOriginal;
1206         bool remote;
1207         sal_Int32 i;
1208         if( rArgs.getLength() > 1 && 0 == rArgs[0].compareToAscii( "-u" ) )
1209         {
1210             remote = true;
1211             i = 2;
1212         }
1213         else
1214         {
1215             remote = false;
1216             i = 1;
1217         }
1218         bool noCurrentContext = false;
1219         if (i < rArgs.getLength()
1220             && rArgs[i].equalsAsciiL(
1221                 RTL_CONSTASCII_STRINGPARAM("noCurrentContext")))
1222         {
1223             noCurrentContext = true;
1224             ++i;
1225         }
1226         bool stress = false;
1227         if (i < rArgs.getLength()
1228             && rArgs[i].equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("stress")))
1229         {
1230             stress = true;
1231             ++i;
1232         }
1233 
1234         for (;;) {
1235             Reference< XInterface > o;
1236             if (remote) {
1237                 o = UnoUrlResolver::create(m_xContext)->resolve(rArgs[1]);
1238             } else {
1239                 o = m_xContext->getServiceManager()->createInstanceWithContext(
1240                     rArgs[0], m_xContext);
1241             }
1242             if (!stress) {
1243                 xOriginal = o;
1244                 break;
1245             }
1246         }
1247 
1248         if (! xOriginal.is())
1249         {
1250             throw RuntimeException(
1251                 OUString( RTL_CONSTASCII_USTRINGPARAM(
1252                               "cannot get test object!") ),
1253                 Reference< XInterface >() );
1254         }
1255         Reference< XBridgeTest > xTest( xOriginal, UNO_QUERY );
1256         if (! xTest.is())
1257         {
1258             throw RuntimeException(
1259                 OUString( RTL_CONSTASCII_USTRINGPARAM("test object does not implement XBridgeTest!") ),
1260                 Reference< XInterface >() );
1261         }
1262 
1263         Reference<XBridgeTest > xLBT;
1264         bRet = check( makeSurrogate( xLBT, xTest ), "makeSurrogate" );
1265         bRet = check(
1266             performTest( m_xContext, xLBT, noCurrentContext ), "standard test" )
1267             && bRet;
1268         bRet = check( raiseException( xLBT ) , "exception test" )&& bRet;
1269         bRet = check( raiseOnewayException( xLBT ),
1270                       "oneway exception test" ) && bRet;
1271         if (! bRet)
1272         {
1273             throw RuntimeException(
1274                 OUString( RTL_CONSTASCII_USTRINGPARAM("error: test failed!") ),
1275                 Reference< XInterface >() );
1276         }
1277     }
1278     catch (Exception & exc)
1279     {
1280         OString cstr( OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) );
1281         fprintf( stderr, "exception occurred: %s\n", cstr.getStr() );
1282         throw;
1283     }
1284 
1285     if( bRet )
1286     {
1287         printf( "\n\n ### test succeeded!\n" );
1288     }
1289     else
1290     {
1291         printf( "\n> ### test failed!\n" );
1292     }
1293 
1294     return 0;
1295 }
1296 
1297 // XServiceInfo
1298 //__________________________________________________________________________________________________
getImplementationName()1299 OUString TestBridgeImpl::getImplementationName()
1300 {
1301     return OUString( RTL_CONSTASCII_USTRINGPARAM(IMPLNAME) );
1302 }
1303 //__________________________________________________________________________________________________
supportsService(const OUString & rServiceName)1304 sal_Bool TestBridgeImpl::supportsService( const OUString & rServiceName )
1305 {
1306     const Sequence< OUString > & rSNL = getSupportedServiceNames();
1307     const OUString * pArray = rSNL.getConstArray();
1308     for ( sal_Int32 nPos = rSNL.getLength(); nPos--; )
1309     {
1310         if (pArray[nPos] == rServiceName)
1311             return sal_True;
1312     }
1313     return sal_False;
1314 }
1315 //__________________________________________________________________________________________________
getSupportedServiceNames()1316 Sequence< OUString > TestBridgeImpl::getSupportedServiceNames()
1317 {
1318     return bridge_test::getSupportedServiceNames();
1319 }
1320 
1321 // ...
1322 
1323 //==================================================================================================
TestBridgeImpl_create(const Reference<XComponentContext> & xContext)1324 static Reference< XInterface > SAL_CALL TestBridgeImpl_create(
1325     const Reference< XComponentContext > & xContext )
1326 {
1327     return Reference< XInterface >(
1328         static_cast< OWeakObject * >( new TestBridgeImpl( xContext ) ) );
1329 }
1330 
1331 }
1332 
1333 extern "C"
1334 {
1335 //==================================================================================================
component_getImplementationEnvironment(const sal_Char ** ppEnvTypeName,uno_Environment **)1336 void SAL_CALL component_getImplementationEnvironment(
1337     const sal_Char ** ppEnvTypeName, uno_Environment ** )
1338 {
1339     *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
1340 }
1341 //==================================================================================================
component_getFactory(const sal_Char * pImplName,void * pServiceManager,void *)1342 void * SAL_CALL component_getFactory(
1343     const sal_Char * pImplName, void * pServiceManager, void * )
1344 {
1345     void * pRet = 0;
1346 
1347     if (pServiceManager && rtl_str_compare( pImplName, IMPLNAME ) == 0)
1348     {
1349         Reference< XInterface > xFactory(
1350             createSingleComponentFactory(
1351                 bridge_test::TestBridgeImpl_create,
1352                 OUString( RTL_CONSTASCII_USTRINGPARAM(IMPLNAME) ),
1353                 bridge_test::getSupportedServiceNames() ) );
1354 
1355         if (xFactory.is())
1356         {
1357             xFactory->acquire();
1358             pRet = xFactory.get();
1359         }
1360     }
1361 
1362     return pRet;
1363 }
1364 }
1365