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