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