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