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 0 : inline static Sequence< OUString > getSupportedServiceNames()
77 : {
78 0 : OUString aName( SERVICENAME );
79 0 : return Sequence< OUString >( &aName, 1 );
80 : }
81 :
82 0 : static bool check( bool b , char const * message )
83 : {
84 0 : if ( ! b )
85 0 : fprintf( stderr, "%s failed\n" , message );
86 0 : return b;
87 : }
88 :
89 : namespace {
90 :
91 0 : bool checkEmpty(OUString const & string, char const * message) {
92 0 : bool ok = string.isEmpty();
93 0 : if (!ok) {
94 : fprintf(
95 : stderr, "%s failed: %s\n", message,
96 0 : OUStringToOString(string, RTL_TEXTENCODING_UTF8).getStr());
97 : }
98 0 : 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 0 : TestBridgeImpl( const Reference< XComponentContext > & xContext )
111 0 : : m_xContext( xContext )
112 0 : {}
113 0 : virtual ~TestBridgeImpl()
114 0 : {
115 0 : }
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 0 : static sal_Bool equals( const TestElement & rData1, const TestElement & rData2 )
128 : {
129 0 : check( rData1.Bool == rData2.Bool, "### bool does not match!" );
130 0 : check( rData1.Char == rData2.Char, "### char does not match!" );
131 0 : check( rData1.Byte == rData2.Byte, "### byte does not match!" );
132 0 : check( rData1.Short == rData2.Short, "### short does not match!" );
133 0 : check( rData1.UShort == rData2.UShort, "### unsigned short does not match!" );
134 0 : check( rData1.Long == rData2.Long, "### long does not match!" );
135 0 : check( rData1.ULong == rData2.ULong, "### unsigned long does not match!" );
136 0 : check( rData1.Hyper == rData2.Hyper, "### hyper does not match!" );
137 0 : check( rData1.UHyper == rData2.UHyper, "### unsigned hyper does not match!" );
138 0 : check( rData1.Float == rData2.Float, "### float does not match!" );
139 0 : check( rData1.Double == rData2.Double, "### double does not match!" );
140 0 : check( rData1.Enum == rData2.Enum, "### enum does not match!" );
141 0 : check( rData1.String == rData2.String, "### string does not match!" );
142 0 : check( rData1.Interface == rData2.Interface, "### interface does not match!" );
143 0 : check( rData1.Any == rData2.Any, "### any does not match!" );
144 :
145 0 : return (rData1.Bool == rData2.Bool &&
146 0 : rData1.Char == rData2.Char &&
147 0 : rData1.Byte == rData2.Byte &&
148 0 : rData1.Short == rData2.Short &&
149 0 : rData1.UShort == rData2.UShort &&
150 0 : rData1.Long == rData2.Long &&
151 0 : rData1.ULong == rData2.ULong &&
152 0 : rData1.Hyper == rData2.Hyper &&
153 0 : rData1.UHyper == rData2.UHyper &&
154 0 : rData1.Float == rData2.Float &&
155 0 : rData1.Double == rData2.Double &&
156 0 : rData1.Enum == rData2.Enum &&
157 0 : rData1.String == rData2.String &&
158 0 : rData1.Interface == rData2.Interface &&
159 0 : rData1.Any == rData2.Any);
160 : }
161 :
162 0 : static sal_Bool equals( const TestData & rData1, const TestData & rData2 )
163 : {
164 : sal_Int32 nLen;
165 :
166 0 : if ((rData1.Sequence == rData2.Sequence) &&
167 0 : equals( (const TestElement &)rData1, (const TestElement &)rData2 ) &&
168 0 : (nLen = rData1.Sequence.getLength()) == rData2.Sequence.getLength())
169 : {
170 : // once again by hand sequence ==
171 0 : const TestElement * pElements1 = rData1.Sequence.getConstArray();
172 0 : const TestElement * pElements2 = rData2.Sequence.getConstArray();
173 0 : for ( ; nLen--; )
174 : {
175 0 : if (! equals( pElements1[nLen], pElements2[nLen] ))
176 : {
177 0 : check( false, "### sequence element did not match!" );
178 0 : return sal_False;
179 : }
180 : }
181 0 : return sal_True;
182 : }
183 0 : return sal_False;
184 : }
185 :
186 0 : 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 0 : rData.Bool = bBool;
197 0 : rData.Char = cChar;
198 0 : rData.Byte = nByte;
199 0 : rData.Short = nShort;
200 0 : rData.UShort = nUShort;
201 0 : rData.Long = nLong;
202 0 : rData.ULong = nULong;
203 0 : rData.Hyper = nHyper;
204 0 : rData.UHyper = nUHyper;
205 0 : rData.Float = fFloat;
206 0 : rData.Double = fDouble;
207 0 : rData.Enum = eEnum;
208 0 : rData.String = rStr;
209 0 : rData.Interface = xTest;
210 0 : rData.Any = rAny;
211 0 : }
212 :
213 : namespace {
214 :
215 : template < typename T >
216 0 : bool testAny(
217 : T const & value, Reference< XBridgeTest > const & xLBT,
218 : char const * typeName = 0)
219 : {
220 0 : Any any;
221 0 : any <<= value;
222 0 : Any any2 = xLBT->transportAny(any);
223 0 : bool success = true;
224 0 : 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 0 : if (typeName != 0
236 0 : && !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 0 : return success;
247 : }
248 :
249 : }
250 :
251 0 : static sal_Bool performAnyTest( const Reference< XBridgeTest > &xLBT, const TestData &data)
252 : {
253 0 : bool bReturn = true;
254 0 : bReturn = testAny( data.Byte ,xLBT ) && bReturn;
255 0 : bReturn = testAny( data.Short,xLBT ) && bReturn;
256 0 : bReturn = testAny( data.UShort,xLBT ) && bReturn;
257 0 : bReturn = testAny( data.Long,xLBT ) && bReturn;
258 0 : bReturn = testAny( data.ULong,xLBT ) && bReturn;
259 0 : bReturn = testAny( data.Hyper,xLBT ) && bReturn;
260 0 : bReturn = testAny( data.UHyper,xLBT ) && bReturn;
261 0 : bReturn = testAny( data.Float,xLBT ) && bReturn;
262 0 : bReturn = testAny( data.Double,xLBT ) && bReturn;
263 0 : bReturn = testAny( data.Enum,xLBT ) && bReturn;
264 0 : bReturn = testAny( data.String,xLBT ) && bReturn;
265 0 : bReturn = testAny( data.Interface,xLBT ) && bReturn;
266 0 : bReturn = testAny( data, xLBT ) && bReturn;
267 : bReturn &= testAny(
268 : TestPolyStruct< sal_Unicode >(' '), xLBT,
269 0 : "test.testtools.bridgetest.TestPolyStruct<char>");
270 :
271 0 : Any a;
272 : {
273 0 : a.setValue( &(data.Bool) , getCppuBooleanType() );
274 : OSL_ASSERT( xLBT->transportAny( a ) == a );
275 : }
276 :
277 : {
278 0 : a.setValue( &(data.Char) , getCppuCharType() );
279 : OSL_ASSERT( xLBT->transportAny( a ) == a );
280 : }
281 :
282 0 : return bReturn;
283 : }
284 :
285 :
286 0 : static sal_Bool performSequenceOfCallTest( const Reference < XBridgeTest > &xLBT )
287 : {
288 : sal_Int32 i,nRounds;
289 0 : sal_Int32 nGlobalIndex = 0;
290 0 : const sal_Int32 nWaitTimeSpanMUSec = 10000;
291 0 : for( nRounds = 0 ; nRounds < 10 ; nRounds ++ )
292 : {
293 0 : for( i = 0 ; i < nRounds ; i ++ )
294 : {
295 : // fire oneways
296 0 : xLBT->callOneway( nGlobalIndex , nWaitTimeSpanMUSec );
297 0 : nGlobalIndex ++;
298 : }
299 :
300 : // call synchron
301 0 : xLBT->call( nGlobalIndex , nWaitTimeSpanMUSec );
302 0 : nGlobalIndex ++;
303 : }
304 :
305 0 : return xLBT->sequenceOfCallTestPassed();
306 : }
307 :
308 0 : class ORecursiveCall : public WeakImplHelper1< XRecursiveCall >
309 : {
310 : private:
311 : Mutex m_mutex;
312 :
313 : public:
314 0 : 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 0 : MutexGuard guard( m_mutex );
320 0 : if( nToCall )
321 : {
322 0 : nToCall --;
323 0 : xCall->callRecursivly( this , nToCall );
324 0 : }
325 :
326 0 : }
327 : };
328 :
329 :
330 :
331 0 : static sal_Bool performRecursiveCallTest( const Reference < XBridgeTest > & xLBT )
332 : {
333 0 : xLBT->startRecursiveCall( new ORecursiveCall , 50 );
334 : // on failure, the test would lock up or crash
335 0 : 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 0 : MyClass::MyClass()
349 : {
350 0 : }
351 :
352 0 : MyClass::~MyClass()
353 : {
354 0 : }
355 :
356 0 : void MyClass::acquire() throw ()
357 : {
358 0 : OWeakObject::acquire();
359 0 : }
360 :
361 0 : void MyClass::release() throw ()
362 : {
363 0 : OWeakObject::release();
364 0 : }
365 :
366 :
367 0 : static sal_Bool performTest(
368 : const Reference<XComponentContext> & xContext,
369 : const Reference<XBridgeTest > & xLBT,
370 : bool noCurrentContext )
371 : {
372 0 : check(xLBT.is(), "### no test interface!");
373 0 : bool bRet = true;
374 0 : if (xLBT.is()) {
375 : // this data is never ever granted access to by calls other than
376 : // equals(), assign()!
377 0 : TestData aData; // test against this data
378 0 : 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 0 : Any(&xI, getCppuType((Reference< XInterface > const *) 0)));
385 0 : bRet &= check(aData.Any == xI, "### unexpected any!");
386 0 : bRet &= check(!(aData.Any != xI), "### unexpected any!");
387 0 : aData.Sequence.realloc(2);
388 0 : aData.Sequence[0] = *(TestElement const *) &aData;
389 : // aData.Sequence[1] is empty
390 : // aSetData is a manually copy of aData for first setting:
391 0 : 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 0 : xI, Any(&xI, getCppuType((Reference< XInterface > const *) 0)));
397 0 : aSetData.Sequence.realloc(2);
398 0 : aSetData.Sequence[0] = *(TestElement const *) &aSetData;
399 : // aSetData.Sequence[1] is empty
400 0 : 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 0 : aSetData.Sequence, aSetData);
406 : {
407 0 : TestData aRet;
408 0 : TestData aRet2;
409 0 : 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 0 : aRet.Sequence, aRet2);
414 : bRet &= check(
415 0 : equals(aData, aRet) && equals(aData, aRet2), "getValues test");
416 : // Set last retrieved values:
417 : TestData aSV2ret(
418 0 : 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 0 : aRet.Any, aRet.Sequence, aRet2));
423 : // Check inout sequence order (=> inout sequence parameter was
424 : // switched by test objects):
425 0 : TestElement temp(aRet.Sequence[0]);
426 0 : aRet.Sequence[0] = aRet.Sequence[1];
427 0 : aRet.Sequence[1] = temp;
428 : bRet &= check(
429 0 : equals(aData, aSV2ret) && equals(aData, aRet2),
430 0 : "getValues2 test");
431 : }
432 : {
433 0 : TwoFloats aIn(1.1f, 2.2f);
434 0 : TwoFloats aOut = xLBT->echoTwoFloats(aIn);
435 0 : bRet = check( memcmp(&aIn, &aOut, sizeof(TwoFloats)) == 0, "two floats struct test" ) && bRet;
436 : }
437 : {
438 0 : FourFloats aIn(3.3f, 4.4f, 5.5f, 6.6f);
439 0 : FourFloats aOut = xLBT->echoFourFloats(aIn);
440 0 : bRet = check( memcmp(&aIn, &aOut, sizeof(FourFloats)) == 0, "four floats struct test" ) && bRet;
441 : }
442 : {
443 0 : MixedFloatAndInteger aIn(7.7f, 8);
444 0 : MixedFloatAndInteger aOut = xLBT->echoMixedFloatAndInteger(aIn);
445 0 : bRet = check( memcmp(&aIn, &aOut, sizeof(MixedFloatAndInteger)) == 0, "mixed float and integer struct test" ) && bRet;
446 : }
447 : {
448 0 : ThreeByteStruct aIn(9, 10, 11);
449 0 : ThreeByteStruct aOut = xLBT->echoThreeByteStruct(aIn);
450 0 : bRet = check( memcmp(&aIn, &aOut, sizeof(ThreeByteStruct)) == 0, "three byte struct test" ) && bRet;
451 : }
452 : {
453 0 : TestData aRet;
454 0 : TestData aRet2;
455 : TestData aGVret(
456 0 : 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 0 : aRet.Any, aRet.Sequence, aRet2));
461 : bRet &= check(
462 0 : (equals(aData, aRet) && equals(aData, aRet2) &&
463 0 : equals(aData, aGVret)),
464 0 : "getValues test");
465 : // Set last retrieved values:
466 0 : xLBT->setBool(aRet.Bool);
467 0 : xLBT->setChar(aRet.Char);
468 0 : xLBT->setByte(aRet.Byte);
469 0 : xLBT->setShort(aRet.Short);
470 0 : xLBT->setUShort(aRet.UShort);
471 0 : xLBT->setLong(aRet.Long);
472 0 : xLBT->setULong(aRet.ULong);
473 0 : xLBT->setHyper(aRet.Hyper);
474 0 : xLBT->setUHyper(aRet.UHyper);
475 0 : xLBT->setFloat(aRet.Float);
476 0 : xLBT->setDouble(aRet.Double);
477 0 : xLBT->setEnum(aRet.Enum);
478 0 : xLBT->setString(aRet.String);
479 0 : xLBT->setInterface(aRet.Interface);
480 0 : xLBT->setAny(aRet.Any);
481 0 : xLBT->setSequence(aRet.Sequence);
482 0 : xLBT->setStruct(aRet2);
483 : }
484 : {
485 0 : TestData aRet;
486 0 : aRet.Hyper = xLBT->getHyper();
487 0 : aRet.UHyper = xLBT->getUHyper();
488 0 : aRet.Float = xLBT->getFloat();
489 0 : aRet.Double = xLBT->getDouble();
490 0 : aRet.Byte = xLBT->getByte();
491 0 : aRet.Char = xLBT->getChar();
492 0 : aRet.Bool = xLBT->getBool();
493 0 : aRet.Short = xLBT->getShort();
494 0 : aRet.UShort = xLBT->getUShort();
495 0 : aRet.Long = xLBT->getLong();
496 0 : aRet.ULong = xLBT->getULong();
497 0 : aRet.Enum = xLBT->getEnum();
498 0 : aRet.String = xLBT->getString();
499 0 : aRet.Interface = xLBT->getInterface();
500 0 : aRet.Any = xLBT->getAny();
501 0 : aRet.Sequence = xLBT->getSequence();
502 0 : TestData aRet2(xLBT->getStruct());
503 : bRet &= check(
504 0 : equals(aData, aRet) && equals(aData, aRet2),
505 0 : "struct comparison test");
506 : {
507 0 : SmallStruct aIn(1, 2);
508 0 : SmallStruct aOut(xLBT->echoSmallStruct(aIn));
509 : bRet &= check(
510 0 : memcmp(&aIn, &aOut, sizeof(SmallStruct)) == 0,
511 0 : "small struct test");
512 : }
513 : {
514 0 : MediumStruct aIn(1, 2, 3, 4);
515 0 : MediumStruct aOut(xLBT->echoMediumStruct(aIn));
516 : bRet &= check(
517 0 : memcmp(&aIn, &aOut, sizeof(MediumStruct)) == 0,
518 0 : "medium struct test");
519 : }
520 : {
521 0 : BigStruct aIn(1, 2, 3, 4, 5, 6, 7, 8);
522 0 : BigStruct aOut(xLBT->echoBigStruct(aIn));
523 : bRet &= check(
524 0 : memcmp(&aIn, &aOut, sizeof(BigStruct)) == 0,
525 0 : "big struct test");
526 : }
527 : {
528 0 : sal_Int32 i2 = xLBT->testPPCAlignment(0, 0, 0, 0, 0xBEAF);
529 0 : bRet &= check(i2 == 0xBEAF, "ppc-style alignment test");
530 : }
531 : {
532 0 : double d1 = xLBT->testTenDoubles(0.1, 0.2, 0.3, 0.4, 0.5,
533 0 : 0.6, 0.7, 0.8, 0.9, 1.0);
534 0 : bRet &= check(d1 == 5.5, "armhf doubles test");
535 : }
536 : // Test extended attributes that raise exceptions:
537 : try {
538 0 : xLBT->getRaiseAttr1();
539 0 : bRet &= check(false, "getRaiseAttr1 did not throw");
540 0 : } catch (const RuntimeException &) {
541 0 : } catch (...) {
542 0 : bRet &= check(false, "getRaiseAttr1 threw wrong type");
543 : }
544 : try {
545 0 : xLBT->setRaiseAttr1(0);
546 0 : bRet &= check(false, "setRaiseAttr1 did not throw");
547 0 : } catch (const IllegalArgumentException &) {
548 0 : } catch (...) {
549 0 : bRet &= check(false, "setRaiseAttr1 threw wrong type");
550 : }
551 : try {
552 0 : xLBT->getRaiseAttr2();
553 0 : bRet &= check(false, "getRaiseAttr2 did not throw");
554 0 : } 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 0 : (xLBT->transportPolyBoolean(
562 0 : TestPolyStruct< sal_Bool >(true)).
563 : member),
564 0 : "transportPolyBoolean");
565 0 : TestPolyStruct< sal_Int64 > tps1(12345);
566 0 : xLBT->transportPolyHyper(tps1);
567 0 : bRet &= check(tps1.member == 12345, "transportPolyHyper");
568 0 : Sequence< Any > seq(2);
569 0 : seq[0] <<= static_cast< sal_uInt32 >(33);
570 0 : seq[1] <<= OUString("ABC");
571 0 : TestPolyStruct< Sequence< Any > > tps2(seq);
572 0 : TestPolyStruct< Sequence< Any > > tps3;
573 0 : xLBT->transportPolySequence(tps2, tps3);
574 : bRet &= check(
575 0 : tps3.member.getLength() == 2,
576 0 : "transportPolySequence, length");
577 0 : sal_uInt32 v0 = sal_uInt32();
578 0 : tps3.member[0] >>= v0;
579 0 : bRet &= check(v0 == 33, "transportPolySequence, element 0");
580 0 : OUString v1;
581 0 : tps3.member[1] >>= v1;
582 0 : bRet &= check( v1 == "ABC", "transportPolySequence, element 1" );
583 : bRet &= check(
584 0 : xLBT->getNullPolyLong().member == 0, "getNullPolyLong");
585 : bRet &= check(
586 0 : xLBT->getNullPolyString().member.isEmpty(),
587 0 : "getNullPolyString");
588 : bRet &= check(
589 0 : xLBT->getNullPolyType().member == Type(),
590 0 : "getNullPolyType");
591 0 : Any nullAny(xLBT->getNullPolyAny().member);
592 : bRet &= check(
593 0 : (((nullAny.getValueTypeName() ==
594 : OUString(
595 0 : "com.sun.star.uno.XInterface")) &&
596 : !static_cast< Reference< XInterface > const * >(
597 0 : nullAny.getValue())->is())
598 0 : || nullAny == Any()),
599 0 : "getNullPolyAny");
600 : bRet &= check(
601 0 : xLBT->getNullPolySequence().member.getLength() == 0,
602 0 : "getNullPolySequence");
603 : bRet &= check(
604 0 : xLBT->getNullPolyEnum().member == TestEnum_TEST,
605 0 : "getNullPolyEnum");
606 : bRet &= check(
607 0 : xLBT->getNullPolyBadEnum().member == TestBadEnum_M,
608 0 : "getNullPolyBadEnum");
609 : bRet &= check(
610 0 : xLBT->getNullPolyStruct().member.member == 0,
611 0 : "getNullPolyStruct");
612 : bRet &= check(
613 0 : !xLBT->getNullPolyInterface().member.is(),
614 0 : "getNullPolyInterface");
615 : }
616 : // Any test:
617 0 : bRet &= check(performAnyTest(xLBT , aData), "any test");
618 : // Sequence of call test:
619 : bRet &= check(
620 0 : performSequenceOfCallTest(xLBT), "sequence of call test");
621 : // Recursive call test:
622 0 : bRet &= check(performRecursiveCallTest(xLBT), "recursive test");
623 : bRet &= check(
624 0 : equals(aData, aRet) && equals(aData, aRet2),
625 0 : "recursive test results");
626 : // Multiple inheritance test:
627 : bRet &= checkEmpty(
628 0 : testtools::bridgetest::testMulti(xLBT->getMulti()),
629 0 : "remote multi");
630 : bRet &= checkEmpty(
631 0 : xLBT->testMulti(new testtools::bridgetest::Multi),
632 0 : "local multi");
633 0 : }
634 : }
635 : {
636 0 : Reference< XBridgeTest2 > xBT2(xLBT, UNO_QUERY);
637 0 : if (!xBT2.is()) {
638 0 : return bRet;
639 : }
640 : // Perform sequence tests (XBridgeTest2); create the sequence which is
641 : // compared with the results:
642 0 : sal_Bool _arBool[] = { true, false, true };
643 0 : sal_Unicode _arChar[] = { 0x0065, 0x0066, 0x0067 };
644 0 : sal_Int8 _arByte[] = { 1, 2, -1 };
645 0 : sal_Int16 _arShort[] = { -0x8000, 1, 0x7FFF };
646 0 : sal_uInt16 _arUShort[] = { 0 , 1, 0xFFFF };
647 : sal_Int32 _arLong[] = {
648 0 : static_cast< sal_Int32 >(0x80000000), 1, 0x7FFFFFFF };
649 0 : sal_uInt32 _arULong[] = { 0, 1, 0xFFFFFFFF };
650 : sal_Int64 _arHyper[] = {
651 : static_cast< sal_Int64 >(SAL_CONST_INT64(0x8000000000000000)), 1,
652 0 : SAL_CONST_INT64(0x7FFFFFFFFFFFFFFF) };
653 0 : sal_uInt64 _arUHyper[] = { 0, 1, SAL_CONST_UINT64(0xFFFFFFFFFFFFFFFF) };
654 0 : float _arFloat[] = { 1.1f, 2.2f, 3.3f };
655 0 : double _arDouble[] = { 1.11, 2.22, 3.33 };
656 : OUString _arString[] = {
657 : OUString("String 1"),
658 : OUString("String 2"),
659 0 : OUString("String 3") };
660 0 : sal_Bool _aBool = true;
661 0 : sal_Int32 _aInt = 0xBABEBABE;
662 0 : float _aFloat = 3.14f;
663 0 : Any _any1(&_aBool, getCppuBooleanType());
664 0 : Any _any2(&_aInt, getCppuType((sal_Int32 *) 0));
665 0 : Any _any3(&_aFloat, getCppuType((float *) 0));
666 0 : Any _arAny[] = { _any1, _any2, _any3 };
667 0 : Reference< XInterface > _arObj[3];
668 0 : _arObj[0] = new OWeakObject();
669 0 : _arObj[1] = new OWeakObject();
670 0 : _arObj[2] = new OWeakObject();
671 0 : TestEnum _arEnum[] = { TestEnum_ONE, TestEnum_TWO, TestEnum_CHECK };
672 0 : 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 0 : 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 0 : 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 0 : Any(&_arObj[2], getCppuType((Reference< XInterface > const *) 0)));
691 : {
692 0 : Sequence<sal_Bool> arBool(_arBool, 3);
693 0 : Sequence<sal_Unicode> arChar( _arChar, 3);
694 0 : Sequence<sal_Int8> arByte(_arByte, 3);
695 0 : Sequence<sal_Int16> arShort(_arShort, 3);
696 0 : Sequence<sal_uInt16> arUShort(_arUShort, 3);
697 0 : Sequence<sal_Int32> arLong(_arLong, 3);
698 0 : Sequence<sal_uInt32> arULong(_arULong, 3);
699 0 : Sequence<sal_Int64> arHyper(_arHyper, 3);
700 0 : Sequence<sal_uInt64> arUHyper(_arUHyper, 3);
701 0 : Sequence<float> arFloat(_arFloat, 3);
702 0 : Sequence<double> arDouble(_arDouble, 3);
703 0 : Sequence<OUString> arString(_arString, 3);
704 0 : Sequence<Any> arAny(_arAny, 3);
705 0 : Sequence<Reference<XInterface> > arObject(_arObj, 3);
706 0 : Sequence<TestEnum> arEnum(_arEnum, 3);
707 0 : Sequence<TestElement> arStruct(_arStruct, 3);
708 0 : Sequence<Sequence<sal_Int32> > _arSeqLong2[3];
709 0 : for (int j = 0; j != 3; ++j) {
710 0 : Sequence< sal_Int32 > _arSeqLong[3];
711 0 : for (int i = 0; i != 3; ++i) {
712 0 : _arSeqLong[i] = Sequence< sal_Int32 >(_arLong, 3);
713 : }
714 0 : _arSeqLong2[j] = Sequence< Sequence< sal_Int32 > >(
715 0 : _arSeqLong, 3);
716 0 : }
717 : Sequence< Sequence< Sequence< sal_Int32> > > arLong3(
718 0 : _arSeqLong2, 3);
719 : Sequence< Sequence< sal_Int32 > > seqSeqRet(
720 0 : xBT2->setDim2(arLong3[0]));
721 0 : bRet &= check(seqSeqRet == arLong3[0], "sequence test");
722 : Sequence< Sequence< Sequence< sal_Int32 > > > seqSeqRet2(
723 0 : xBT2->setDim3(arLong3));
724 0 : bRet &= check(seqSeqRet2 == arLong3, "sequence test");
725 0 : Sequence< Any > seqAnyRet(xBT2->setSequenceAny(arAny));
726 0 : bRet &= check(seqAnyRet == arAny, "sequence test");
727 0 : Sequence< sal_Bool > seqBoolRet(xBT2->setSequenceBool(arBool));
728 0 : bRet &= check(seqBoolRet == arBool, "sequence test");
729 0 : Sequence< sal_Int8 > seqByteRet(xBT2->setSequenceByte(arByte));
730 0 : bRet &= check(seqByteRet == arByte, "sequence test");
731 0 : Sequence< sal_Unicode > seqCharRet(xBT2->setSequenceChar(arChar));
732 0 : bRet &= check(seqCharRet == arChar, "sequence test");
733 0 : Sequence< sal_Int16 > seqShortRet(xBT2->setSequenceShort(arShort));
734 0 : bRet &= check(seqShortRet == arShort, "sequence test");
735 0 : Sequence< sal_Int32 > seqLongRet(xBT2->setSequenceLong(arLong));
736 0 : bRet &= check(seqLongRet == arLong, "sequence test");
737 0 : Sequence< sal_Int64 > seqHyperRet(xBT2->setSequenceHyper(arHyper));
738 0 : bRet &= check(seqHyperRet == arHyper, "sequence test");
739 0 : Sequence< float > seqFloatRet(xBT2->setSequenceFloat(arFloat));
740 0 : bRet &= check(seqFloatRet == arFloat, "sequence test");
741 0 : Sequence< double > seqDoubleRet(xBT2->setSequenceDouble(arDouble));
742 0 : bRet &= check(seqDoubleRet == arDouble, "sequence test");
743 0 : Sequence< TestEnum > seqEnumRet(xBT2->setSequenceEnum(arEnum));
744 0 : bRet &= check(seqEnumRet == arEnum, "sequence test");
745 : Sequence< sal_uInt16 > seqUShortRet(
746 0 : xBT2->setSequenceUShort(arUShort));
747 0 : bRet &= check(seqUShortRet == arUShort, "sequence test");
748 0 : Sequence< sal_uInt32 > seqULongRet(xBT2->setSequenceULong(arULong));
749 0 : bRet &= check(seqULongRet == arULong, "sequence test");
750 : Sequence< sal_uInt64 > seqUHyperRet(
751 0 : xBT2->setSequenceUHyper(arUHyper));
752 0 : bRet &= check(seqUHyperRet == arUHyper, "sequence test");
753 : Sequence< Reference< XInterface > > seqObjectRet(
754 0 : xBT2->setSequenceXInterface(arObject));
755 0 : bRet &= check(seqObjectRet == arObject, "sequence test");
756 : Sequence< OUString > seqStringRet(
757 0 : xBT2->setSequenceString(arString));
758 0 : bRet &= check(seqStringRet == arString, "sequence test");
759 : Sequence< TestElement > seqStructRet(
760 0 : xBT2->setSequenceStruct(arStruct));
761 0 : bRet &= check(seqStructRet == arStruct, "sequence test");
762 0 : Sequence< sal_Bool > arBoolTemp(cloneSequence(arBool));
763 0 : Sequence< sal_Unicode > arCharTemp(cloneSequence(arChar));
764 0 : Sequence< sal_Int8 > arByteTemp(cloneSequence(arByte));
765 0 : Sequence< sal_Int16 > arShortTemp(cloneSequence(arShort));
766 0 : Sequence< sal_uInt16 > arUShortTemp(cloneSequence(arUShort));
767 0 : Sequence< sal_Int32 > arLongTemp(cloneSequence(arLong));
768 0 : Sequence< sal_uInt32 > arULongTemp(cloneSequence(arULong));
769 0 : Sequence< sal_Int64 > arHyperTemp(cloneSequence(arHyper));
770 0 : Sequence< sal_uInt64 > arUHyperTemp(cloneSequence(arUHyper));
771 0 : Sequence< float > arFloatTemp(cloneSequence(arFloat));
772 0 : Sequence< double > arDoubleTemp(cloneSequence(arDouble));
773 0 : Sequence< TestEnum > arEnumTemp(cloneSequence(arEnum));
774 0 : Sequence< OUString > arStringTemp(cloneSequence(arString));
775 : Sequence< Reference< XInterface > > arObjectTemp(
776 0 : cloneSequence(arObject));
777 0 : Sequence< Any > arAnyTemp(cloneSequence(arAny));
778 0 : Sequence< Sequence< sal_Int32 > > arLong2Temp(arLong3[0]);
779 0 : Sequence< Sequence< Sequence< sal_Int32 > > > arLong3Temp(arLong3);
780 0 : xBT2->setSequencesInOut(
781 : arBoolTemp, arCharTemp, arByteTemp, arShortTemp, arUShortTemp,
782 : arLongTemp,arULongTemp, arHyperTemp, arUHyperTemp, arFloatTemp,
783 : arDoubleTemp, arEnumTemp, arStringTemp, arObjectTemp, arAnyTemp,
784 0 : arLong2Temp, arLong3Temp);
785 : bRet &= check(
786 0 : (arBoolTemp == arBool && arCharTemp == arChar &&
787 0 : arByteTemp == arByte && arShortTemp == arShort &&
788 0 : arUShortTemp == arUShort && arLongTemp == arLong &&
789 0 : arULongTemp == arULong && arHyperTemp == arHyper &&
790 0 : arUHyperTemp == arUHyper && arFloatTemp == arFloat &&
791 0 : arDoubleTemp == arDouble && arEnumTemp == arEnum &&
792 0 : arStringTemp == arString && arObjectTemp == arObject &&
793 0 : arAnyTemp == arAny && arLong2Temp == arLong3[0] &&
794 0 : arLong3Temp == arLong3),
795 0 : "sequence test");
796 0 : Sequence< sal_Bool > arBoolOut;
797 0 : Sequence< sal_Unicode > arCharOut;
798 0 : Sequence< sal_Int8 > arByteOut;
799 0 : Sequence< sal_Int16 > arShortOut;
800 0 : Sequence< sal_uInt16 > arUShortOut;
801 0 : Sequence< sal_Int32 > arLongOut;
802 0 : Sequence< sal_uInt32 > arULongOut;
803 0 : Sequence< sal_Int64 > arHyperOut;
804 0 : Sequence< sal_uInt64 > arUHyperOut;
805 0 : Sequence< float > arFloatOut;
806 0 : Sequence< double > arDoubleOut;
807 0 : Sequence< TestEnum > arEnumOut;
808 0 : Sequence< OUString > arStringOut;
809 0 : Sequence< Reference< XInterface > > arObjectOut;
810 0 : Sequence< Any > arAnyOut;
811 0 : Sequence< Sequence< sal_Int32 > > arLong2Out;
812 0 : Sequence< Sequence< Sequence< sal_Int32 > > > arLong3Out;
813 0 : xBT2->setSequencesOut(
814 : arBoolOut, arCharOut, arByteOut, arShortOut, arUShortOut,
815 : arLongOut,arULongOut, arHyperOut, arUHyperOut, arFloatOut,
816 : arDoubleOut, arEnumOut, arStringOut, arObjectOut, arAnyOut,
817 0 : arLong2Out, arLong3Out);
818 : bRet &= check(
819 0 : (arBoolOut == arBool && arCharOut == arChar &&
820 0 : arByteOut == arByte && arShortOut == arShort &&
821 0 : arUShortOut == arUShort && arLongOut == arLong &&
822 0 : arULongOut == arULong && arHyperOut == arHyper &&
823 0 : arUHyperOut == arUHyper && arFloatOut == arFloat &&
824 0 : arDoubleOut == arDouble && arEnumOut == arEnum &&
825 0 : arStringOut == arString && arObjectOut == arObject &&
826 0 : arAnyOut == arAny && arLong2Out == arLong3[0] &&
827 0 : arLong3Out == arLong3),
828 0 : "sequence test");
829 : }
830 : {
831 : // Test with empty sequences:
832 0 : Sequence< Sequence< sal_Int32 > > arLong2;
833 0 : Sequence< Sequence< sal_Int32 > > seqSeqRet(xBT2->setDim2(arLong2));
834 0 : bRet &= check(seqSeqRet == arLong2, "sequence test");
835 0 : Sequence< Sequence< Sequence< sal_Int32 > > > arLong3;
836 : Sequence< Sequence< Sequence< sal_Int32 > > > seqSeqRet2(
837 0 : xBT2->setDim3(arLong3));
838 0 : bRet &= check(seqSeqRet2 == arLong3, "sequence test");
839 0 : Sequence< Any > arAny;
840 0 : Sequence< Any > seqAnyRet(xBT2->setSequenceAny(arAny));
841 0 : bRet &= check(seqAnyRet == arAny, "sequence test");
842 0 : Sequence< sal_Bool > arBool;
843 0 : Sequence< sal_Bool > seqBoolRet(xBT2->setSequenceBool(arBool));
844 0 : bRet &= check(seqBoolRet == arBool, "sequence test");
845 0 : Sequence< sal_Int8 > arByte;
846 0 : Sequence< sal_Int8 > seqByteRet(xBT2->setSequenceByte(arByte));
847 0 : bRet &= check(seqByteRet == arByte, "sequence test");
848 0 : Sequence< sal_Unicode > arChar;
849 0 : Sequence< sal_Unicode > seqCharRet(xBT2->setSequenceChar(arChar));
850 0 : bRet &= check(seqCharRet == arChar, "sequence test");
851 0 : Sequence< sal_Int16 > arShort;
852 0 : Sequence< sal_Int16 > seqShortRet(xBT2->setSequenceShort(arShort));
853 0 : bRet &= check(seqShortRet == arShort, "sequence test");
854 0 : Sequence< sal_Int32 > arLong;
855 0 : Sequence< sal_Int32 > seqLongRet(xBT2->setSequenceLong(arLong));
856 0 : bRet &= check(seqLongRet == arLong, "sequence test");
857 0 : Sequence< sal_Int64 > arHyper;
858 0 : Sequence< sal_Int64 > seqHyperRet(xBT2->setSequenceHyper(arHyper));
859 0 : bRet &= check(seqHyperRet == arHyper, "sequence test");
860 0 : Sequence< float > arFloat;
861 0 : Sequence< float > seqFloatRet(xBT2->setSequenceFloat(arFloat));
862 0 : bRet &= check(seqFloatRet == arFloat, "sequence test");
863 0 : Sequence< double > arDouble;
864 0 : Sequence< double > seqDoubleRet(xBT2->setSequenceDouble(arDouble));
865 0 : bRet &= check(seqDoubleRet == arDouble, "sequence test");
866 0 : Sequence< TestEnum > arEnum;
867 0 : Sequence< TestEnum > seqEnumRet(xBT2->setSequenceEnum(arEnum));
868 0 : bRet &= check(seqEnumRet == arEnum, "sequence test");
869 0 : Sequence< sal_uInt16 > arUShort;
870 : Sequence< sal_uInt16 > seqUShortRet(
871 0 : xBT2->setSequenceUShort(arUShort));
872 0 : bRet &= check(seqUShortRet == arUShort, "sequence test");
873 0 : Sequence< sal_uInt32 > arULong;
874 0 : Sequence< sal_uInt32 > seqULongRet(xBT2->setSequenceULong(arULong));
875 0 : bRet &= check(seqULongRet == arULong, "sequence test");
876 0 : Sequence< sal_uInt64 > arUHyper;
877 : Sequence< sal_uInt64 > seqUHyperRet(
878 0 : xBT2->setSequenceUHyper(arUHyper));
879 0 : bRet &= check(seqUHyperRet == arUHyper, "sequence test");
880 0 : Sequence< Reference< XInterface > > arObject;
881 : Sequence< Reference< XInterface > > seqObjectRet(
882 0 : xBT2->setSequenceXInterface(arObject));
883 0 : bRet &= check(seqObjectRet == arObject, "sequence test");
884 0 : Sequence< OUString > arString;
885 : Sequence< OUString > seqStringRet(
886 0 : xBT2->setSequenceString(arString));
887 0 : bRet &= check(seqStringRet == arString, "sequence test");
888 0 : Sequence< TestElement > arStruct;
889 : Sequence< TestElement > seqStructRet(
890 0 : xBT2->setSequenceStruct(arStruct));
891 0 : 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 0 : xBT2->testConstructorsService(xContext);
898 0 : } catch (const BadConstructorArguments &) {
899 0 : bRet = false;
900 : }
901 0 : if (!noCurrentContext) {
902 0 : if (!(new testtools::bridgetest::CurrentContextChecker)->perform(
903 0 : xBT2->getCurrentContextChecker(), 0, 1))
904 : {
905 0 : bRet = false;
906 : }
907 0 : if (!(new testtools::bridgetest::CurrentContextChecker)->perform(
908 0 : xBT2->getCurrentContextChecker(), 0, 2))
909 : {
910 0 : bRet = false;
911 : }
912 0 : if (!(new testtools::bridgetest::CurrentContextChecker)->perform(
913 0 : xBT2->getCurrentContextChecker(), 1, 2))
914 : {
915 0 : bRet = false;
916 : }
917 0 : if (!(new testtools::bridgetest::CurrentContextChecker)->perform(
918 0 : xBT2->getCurrentContextChecker(), 1, 3))
919 : {
920 0 : bRet = false;
921 : }
922 0 : }
923 : }
924 0 : return bRet;
925 : }
926 :
927 0 : static sal_Bool raiseOnewayException( const Reference < XBridgeTest > & xLBT )
928 : {
929 0 : sal_Bool bReturn = sal_True;
930 0 : OUString sCompare = STRING_TEST_CONSTANT;
931 0 : 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 0 : xLBT->raiseRuntimeExceptionOneway( sCompare, x );
937 : }
938 0 : catch( const RuntimeException & e )
939 : {
940 : bReturn = (
941 : #if OSL_DEBUG_LEVEL == 0
942 : // java stack traces trash Message
943 0 : e.Message == sCompare &&
944 : #endif
945 0 : xLBT->getInterface() == e.Context &&
946 0 : x == e.Context );
947 : }
948 0 : return bReturn;
949 : }
950 :
951 :
952 0 : static sal_Bool raiseException( const Reference< XBridgeTest > & xLBT )
953 : {
954 0 : sal_Int32 nCount = 0;
955 : try
956 : {
957 : try
958 : {
959 : try
960 : {
961 0 : TestData aRet, aRet2;
962 0 : xLBT->raiseException(
963 : 5, STRING_TEST_CONSTANT,
964 0 : xLBT->getInterface() );
965 : }
966 0 : catch (const IllegalArgumentException &rExc)
967 : {
968 0 : if (rExc.ArgumentPosition == 5 &&
969 : #if OSL_DEBUG_LEVEL == 0
970 : // java stack traces trash Message
971 0 : rExc.Message.equalsAscii( STRING_TEST_CONSTANT ) &&
972 : #endif
973 0 : 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 0 : ++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 0 : xLBT->getRuntimeException();
991 : }
992 : }
993 0 : catch (const RuntimeException & rExc)
994 : {
995 0 : if (rExc.Context == xLBT->getInterface()
996 : #if OSL_DEBUG_LEVEL == 0
997 : // java stack traces trash Message
998 0 : && rExc.Message.equalsAscii( STRING_TEST_CONSTANT )
999 : #endif
1000 : )
1001 : {
1002 0 : ++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 0 : xLBT->setRuntimeException( 0xcafebabe );
1011 : }
1012 : }
1013 0 : catch (const Exception & rExc)
1014 : {
1015 0 : if (rExc.Context == xLBT->getInterface()
1016 : #if OSL_DEBUG_LEVEL == 0
1017 : // java stack traces trash Message
1018 0 : && rExc.Message.equalsAscii( STRING_TEST_CONSTANT )
1019 : #endif
1020 : )
1021 : {
1022 0 : ++nCount;
1023 : }
1024 : else
1025 : {
1026 0 : check( false, "### unexpected exception content!" );
1027 : }
1028 0 : return (nCount == 3);
1029 : }
1030 0 : return sal_False;
1031 : }
1032 :
1033 : /* Returns an acquired sequence
1034 : */
1035 0 : uno_Sequence* cloneSequence(const uno_Sequence* val, const Type& type)
1036 : {
1037 0 : TypeDescription td(type);
1038 0 : td.makeComplete();
1039 0 : typelib_TypeDescription* pTdRaw = td.get();
1040 : typelib_IndirectTypeDescription* pIndirectTd =
1041 0 : (typelib_IndirectTypeDescription*) pTdRaw;
1042 :
1043 0 : typelib_TypeDescription* pTdElem = pIndirectTd->pType->pType;
1044 0 : sal_Int8* buf = new sal_Int8[pTdElem->nSize * val->nElements];
1045 0 : sal_Int8* pBufCur = buf;
1046 :
1047 0 : uno_Sequence* retSeq = NULL;
1048 0 : 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 0 : val->nElements, reinterpret_cast< uno_AcquireFunc >(cpp_acquire));
1069 0 : break;
1070 : }
1071 0 : delete[] buf;
1072 0 : return retSeq;
1073 : }
1074 :
1075 : template< class T>
1076 0 : Sequence<T> cloneSequence(const Sequence<T>& val)
1077 : {
1078 0 : Sequence<T> seq( cloneSequence(val.get(), getCppuType(&val)), SAL_NO_ACQUIRE);
1079 0 : return seq;
1080 : }
1081 :
1082 : template< class T >
1083 0 : inline bool makeSurrogate(
1084 : Reference< T > & rOut, Reference< T > const & rOriginal )
1085 : {
1086 0 : rOut.clear();
1087 0 : if (! rOriginal.is())
1088 0 : return false;
1089 :
1090 0 : Environment aCppEnv_official;
1091 0 : Environment aUnoEnv_ano;
1092 0 : Environment aCppEnv_ano;
1093 :
1094 : OUString aCppEnvTypeName(
1095 0 : CPPU_CURRENT_LANGUAGE_BINDING_NAME );
1096 : OUString aUnoEnvTypeName(
1097 0 : UNO_LB_UNO );
1098 : // official:
1099 0 : uno_getEnvironment(
1100 : reinterpret_cast< uno_Environment ** >( &aCppEnv_official ),
1101 0 : aCppEnvTypeName.pData, 0 );
1102 : // anonymous:
1103 0 : uno_createEnvironment(
1104 : reinterpret_cast< uno_Environment ** >( &aCppEnv_ano ),
1105 0 : aCppEnvTypeName.pData, 0 );
1106 0 : uno_createEnvironment(
1107 : reinterpret_cast< uno_Environment ** >( &aUnoEnv_ano ),
1108 0 : aUnoEnvTypeName.pData, 0 );
1109 :
1110 0 : UnoInterfaceReference unoI;
1111 0 : Mapping cpp2uno( aCppEnv_official.get(), aUnoEnv_ano.get() );
1112 0 : Mapping uno2cpp( aUnoEnv_ano.get(), aCppEnv_ano.get() );
1113 0 : if (!cpp2uno.is() || !uno2cpp.is())
1114 : {
1115 0 : throw RuntimeException(
1116 : "cannot get C++-UNO mappings!",
1117 0 : Reference< XInterface >() );
1118 : }
1119 0 : cpp2uno.mapInterface(
1120 : reinterpret_cast< void ** >( &unoI.m_pUnoI ),
1121 0 : rOriginal.get(), ::getCppuType( &rOriginal ) );
1122 0 : if (! unoI.is())
1123 : {
1124 0 : throw RuntimeException(
1125 : "mapping C++ to binary UNO failed!",
1126 0 : Reference< XInterface >() );
1127 : }
1128 0 : uno2cpp.mapInterface(
1129 : reinterpret_cast< void ** >( &rOut ),
1130 0 : unoI.get(), ::getCppuType( &rOriginal ) );
1131 0 : if (! rOut.is())
1132 : {
1133 0 : throw RuntimeException(
1134 : "mapping binary UNO to C++ failed!",
1135 0 : Reference< XInterface >() );
1136 : }
1137 :
1138 0 : return rOut.is();
1139 : }
1140 :
1141 :
1142 0 : sal_Int32 TestBridgeImpl::run( const Sequence< OUString > & rArgs )
1143 : throw (RuntimeException, std::exception)
1144 : {
1145 0 : bool bRet = false;
1146 : try
1147 : {
1148 0 : 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 0 : Reference< XInterface > xOriginal;
1157 : bool remote;
1158 : sal_Int32 i;
1159 0 : if( rArgs.getLength() > 1 && rArgs[0].equalsAscii( "-u" ) )
1160 : {
1161 0 : remote = true;
1162 0 : i = 2;
1163 : }
1164 : else
1165 : {
1166 0 : remote = false;
1167 0 : i = 1;
1168 : }
1169 0 : bool noCurrentContext = false;
1170 0 : if ( i < rArgs.getLength() && rArgs[i] == "noCurrentContext" )
1171 : {
1172 0 : noCurrentContext = true;
1173 0 : ++i;
1174 : }
1175 0 : bool stress = false;
1176 0 : if ( i < rArgs.getLength() && rArgs[i] == "stress" )
1177 : {
1178 0 : stress = true;
1179 0 : ++i;
1180 : }
1181 :
1182 : for (;;) {
1183 0 : Reference< XInterface > o;
1184 0 : if (remote) {
1185 0 : o = UnoUrlResolver::create(m_xContext)->resolve(rArgs[1]);
1186 : } else {
1187 0 : o = m_xContext->getServiceManager()->createInstanceWithContext(
1188 0 : rArgs[0], m_xContext);
1189 : }
1190 0 : if (!stress) {
1191 0 : xOriginal = o;
1192 0 : break;
1193 : }
1194 0 : }
1195 :
1196 0 : if (! xOriginal.is())
1197 : {
1198 : throw RuntimeException(
1199 : OUString(
1200 : "cannot get test object!"),
1201 0 : Reference< XInterface >() );
1202 : }
1203 0 : Reference< XBridgeTest > xTest( xOriginal, UNO_QUERY );
1204 0 : if (! xTest.is())
1205 : {
1206 : throw RuntimeException(
1207 : OUString("test object does not implement XBridgeTest!"),
1208 0 : Reference< XInterface >() );
1209 : }
1210 :
1211 0 : Reference<XBridgeTest > xLBT;
1212 0 : bRet = check( makeSurrogate( xLBT, xTest ), "makeSurrogate" );
1213 : bRet = check(
1214 0 : performTest( m_xContext, xLBT, noCurrentContext ), "standard test" )
1215 0 : && bRet;
1216 0 : bRet = check( raiseException( xLBT ) , "exception test" )&& bRet;
1217 0 : bRet = check( raiseOnewayException( xLBT ),
1218 0 : "oneway exception test" ) && bRet;
1219 0 : if (! bRet)
1220 : {
1221 : throw RuntimeException(
1222 : OUString("error: test failed!"),
1223 0 : Reference< XInterface >() );
1224 0 : }
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 0 : 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 0 : static Reference< XInterface > SAL_CALL TestBridgeImpl_create(
1260 : const Reference< XComponentContext > & xContext )
1261 : {
1262 : return Reference< XInterface >(
1263 0 : static_cast< OWeakObject * >( new TestBridgeImpl( xContext ) ) );
1264 : }
1265 :
1266 : }
1267 :
1268 : extern "C"
1269 : {
1270 :
1271 0 : SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory(
1272 : const sal_Char * pImplName, void * pServiceManager,
1273 : SAL_UNUSED_PARAMETER void * )
1274 : {
1275 0 : void * pRet = 0;
1276 :
1277 0 : if (pServiceManager && rtl_str_compare( pImplName, IMPLNAME ) == 0)
1278 : {
1279 : Reference< XInterface > xFactory(
1280 : createSingleComponentFactory(
1281 : bridge_test::TestBridgeImpl_create,
1282 : OUString( IMPLNAME ),
1283 0 : bridge_test::getSupportedServiceNames() ) );
1284 :
1285 0 : if (xFactory.is())
1286 : {
1287 0 : xFactory->acquire();
1288 0 : pRet = xFactory.get();
1289 0 : }
1290 : }
1291 :
1292 0 : return pRet;
1293 : }
1294 : }
1295 :
1296 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|