tdf#130857 qt weld: Implement QtInstanceWidget::get_text_height
[LibreOffice.git] / testtools / source / bridgetest / bridgetest.cxx
blobeedf85f13ded6a1a38ad3f1ede2309faa05b9a0d
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <sal/config.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <string_view>
26 #include <o3tl/any.hxx>
27 #include <o3tl/string_view.hxx>
28 #include <osl/diagnose.h>
29 #include <osl/diagnose.hxx>
30 #include <sal/types.h>
31 #include <typelib/typedescription.hxx>
32 #include <uno/dispatcher.hxx>
33 #include <uno/lbnames.h>
34 #include <uno/mapping.hxx>
35 #include <uno/data.h>
36 #include <uno/environment.hxx>
38 #include <cppuhelper/factory.hxx>
39 #include <cppuhelper/implbase.hxx>
40 #include <cppuhelper/supportsservice.hxx>
42 #include <com/sun/star/lang/XServiceInfo.hpp>
43 #include <com/sun/star/lang/XMain.hpp>
44 #include <com/sun/star/lang/XSingleComponentFactory.hpp>
45 #include <com/sun/star/bridge/UnoUrlResolver.hpp>
46 #include <com/sun/star/bridge/XUnoUrlResolver.hpp>
47 #include <com/sun/star/uno/RuntimeException.hpp>
48 #include <com/sun/star/uno/Type.hxx>
50 #include <test/testtools/bridgetest/BadConstructorArguments.hpp>
51 #include <test/testtools/bridgetest/TestPolyStruct.hpp>
52 #include <test/testtools/bridgetest/XBridgeTest.hpp>
53 #include <test/testtools/bridgetest/XBridgeTest2.hpp>
55 #include "currentcontextchecker.hxx"
56 #include "multi.hxx"
57 #include <memory>
58 #include <utility>
59 #include <cmath>
61 using namespace osl;
62 using namespace cppu;
63 using namespace com::sun::star::uno;
64 using namespace com::sun::star::lang;
65 using namespace com::sun::star::registry;
66 using namespace com::sun::star::bridge;
67 using namespace test::testtools::bridgetest;
70 constexpr OUString SERVICENAME = u"com.sun.star.test.bridge.BridgeTest"_ustr;
71 constexpr OUString IMPLNAME = u"com.sun.star.comp.bridge.BridgeTest"_ustr;
73 constexpr OUString STRING_TEST_CONSTANT = u"\" paco\' chorizo\\\' \"\'"_ustr;
75 namespace bridge_test
77 template<typename T, typename U = T>
78 static Sequence<T> cloneSequence(const Sequence<T>& val);
81 static Sequence< OUString > getSupportedServiceNames()
83 return { SERVICENAME };
86 static bool check( bool b , char const * message )
88 if ( ! b )
89 fprintf( stderr, "%s failed\n" , message );
90 return b;
93 namespace {
95 bool checkEmpty(std::u16string_view string, char const * message) {
96 bool ok = string.empty();
97 if (!ok) {
98 fprintf(
99 stderr, "%s failed: %s\n", message,
100 OUStringToOString(string, RTL_TEXTENCODING_UTF8).getStr());
102 return ok;
105 class TestBridgeImpl : public osl::DebugBase<TestBridgeImpl>,
106 public WeakImplHelper< XMain, XServiceInfo >
108 Reference< XComponentContext > m_xContext;
110 public:
111 explicit TestBridgeImpl( const Reference< XComponentContext > & xContext )
112 : m_xContext( xContext )
115 // XServiceInfo
116 virtual OUString SAL_CALL getImplementationName() override;
117 virtual sal_Bool SAL_CALL supportsService( const OUString & rServiceName ) override;
118 virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
120 // XMain
121 virtual sal_Int32 SAL_CALL run( const Sequence< OUString > & rArgs ) override;
126 static bool equals( const TestElement & rData1, const TestElement & rData2 )
128 check( rData1.Bool == rData2.Bool, "### bool does not match!" );
129 check( rData1.Char == rData2.Char, "### char does not match!" );
130 check( rData1.Byte == rData2.Byte, "### byte does not match!" );
131 check( rData1.Short == rData2.Short, "### short does not match!" );
132 check( rData1.UShort == rData2.UShort, "### unsigned short does not match!" );
133 check( rData1.Long == rData2.Long, "### long does not match!" );
134 check( rData1.ULong == rData2.ULong, "### unsigned long does not match!" );
135 check( rData1.Hyper == rData2.Hyper, "### hyper does not match!" );
136 check( rData1.UHyper == rData2.UHyper, "### unsigned hyper does not match!" );
137 check( rData1.Float == rData2.Float, "### float does not match!" );
138 check( rData1.Double == rData2.Double, "### double does not match!" );
139 check( rData1.Enum == rData2.Enum, "### enum does not match!" );
140 check( rData1.String == rData2.String, "### string does not match!" );
141 check( rData1.Byte2 == rData2.Byte2, "### byte2 does not match!" );
142 check( rData1.Short2 == rData2.Short2, "### short2 does not match!" );
143 check( rData1.Interface == rData2.Interface, "### interface does not match!" );
144 check( rData1.Any == rData2.Any, "### any does not match!" );
146 return (rData1.Bool == rData2.Bool &&
147 rData1.Char == rData2.Char &&
148 rData1.Byte == rData2.Byte &&
149 rData1.Short == rData2.Short &&
150 rData1.UShort == rData2.UShort &&
151 rData1.Long == rData2.Long &&
152 rData1.ULong == rData2.ULong &&
153 rData1.Hyper == rData2.Hyper &&
154 rData1.UHyper == rData2.UHyper &&
155 rData1.Float == rData2.Float &&
156 rData1.Double == rData2.Double &&
157 rData1.Enum == rData2.Enum &&
158 rData1.String == rData2.String &&
159 rData1.Byte2 == rData2.Byte2 &&
160 rData1.Short2 == rData2.Short2 &&
161 rData1.Interface == rData2.Interface &&
162 rData1.Any == rData2.Any);
165 static bool equals( const TestData & rData1, const TestData & rData2 )
167 sal_Int32 nLen;
169 if (rData1.Sequence != rData2.Sequence)
170 return false;
171 if (!equals( static_cast<const TestElement &>(rData1), static_cast<const TestElement &>(rData2) ))
172 return false;
173 nLen = rData1.Sequence.getLength();
174 if (nLen == rData2.Sequence.getLength())
176 // once again by hand sequence ==
177 for ( ; nLen--; )
179 if (!equals(rData1.Sequence[nLen], rData2.Sequence[nLen]))
181 check( false, "### sequence element did not match!" );
182 return false;
185 return true;
187 return false;
190 static void assign( TestElement & rData,
191 bool bBool, sal_Unicode cChar, sal_Int8 nByte,
192 sal_Int16 nShort, sal_uInt16 nUShort,
193 sal_Int32 nLong, sal_uInt32 nULong,
194 sal_Int64 nHyper, sal_uInt64 nUHyper,
195 float fFloat, double fDouble,
196 TestEnum eEnum, const OUString& rStr,
197 sal_Int8 nByte2, sal_Int16 nShort2,
198 const css::uno::Reference< css::uno::XInterface >& xTest,
199 const css::uno::Any& rAny )
201 rData.Bool = bBool;
202 rData.Char = cChar;
203 rData.Byte = nByte;
204 rData.Short = nShort;
205 rData.UShort = nUShort;
206 rData.Long = nLong;
207 rData.ULong = nULong;
208 rData.Hyper = nHyper;
209 rData.UHyper = nUHyper;
210 rData.Float = fFloat;
211 rData.Double = fDouble;
212 rData.Enum = eEnum;
213 rData.String = rStr;
214 rData.Byte2 = nByte2;
215 rData.Short2 = nShort2;
216 rData.Interface = xTest;
217 rData.Any = rAny;
220 namespace {
222 template < typename T >
223 bool testAny(
224 T const & value, Reference< XBridgeTest > const & xLBT,
225 char const * typeName = nullptr)
227 Any any;
228 any <<= value;
229 Any any2 = xLBT->transportAny(any);
230 bool success = true;
231 if (any != any2) {
232 fprintf(
233 stderr, "any is different after roundtrip: in %s, out %s\n",
234 OUStringToOString(
235 any.getValueTypeName(),
236 RTL_TEXTENCODING_ASCII_US).getStr(),
237 OUStringToOString(
238 any2.getValueTypeName(),
239 RTL_TEXTENCODING_ASCII_US).getStr());
240 success = false;
242 if (typeName != nullptr
243 && !any2.getValueTypeName().equalsAscii(typeName))
245 fprintf(
246 stderr, "any has wrong type after roundtrip: %s instead of %s\n",
247 OUStringToOString(
248 any2.getValueTypeName(),
249 RTL_TEXTENCODING_ASCII_US).getStr(),
250 typeName);
251 success = false;
253 return success;
258 static bool performAnyTest( const Reference< XBridgeTest > &xLBT, const TestData &data)
260 bool bReturn = true;
261 bReturn = testAny( data.Byte ,xLBT ) && bReturn;
262 bReturn = testAny( data.Short,xLBT ) && bReturn;
263 bReturn = testAny( data.UShort,xLBT ) && bReturn;
264 bReturn = testAny( data.Long,xLBT ) && bReturn;
265 bReturn = testAny( data.ULong,xLBT ) && bReturn;
266 bReturn = testAny( data.Hyper,xLBT ) && bReturn;
267 bReturn = testAny( data.UHyper,xLBT ) && bReturn;
268 bReturn = testAny( data.Float,xLBT ) && bReturn;
269 bReturn = testAny( data.Double,xLBT ) && bReturn;
270 bReturn = testAny( data.Enum,xLBT ) && bReturn;
271 bReturn = testAny( data.String,xLBT ) && bReturn;
272 bReturn = testAny( data.Byte2 ,xLBT ) && bReturn;
273 bReturn = testAny( data.Short2,xLBT ) && bReturn;
274 bReturn = testAny( data.Interface,xLBT ) && bReturn;
275 bReturn = testAny( data, xLBT ) && bReturn;
276 bReturn &= testAny(
277 TestPolyStruct< sal_Unicode >(' '), xLBT,
278 "test.testtools.bridgetest.TestPolyStruct<char>");
280 Any a;
282 a <<= data.Bool;
283 OSL_ASSERT( xLBT->transportAny( a ) == a );
287 a <<= data.Char;
288 OSL_ASSERT( xLBT->transportAny( a ) == a );
291 return bReturn;
295 static bool performSequenceOfCallTest( const Reference < XBridgeTest > &xLBT )
297 sal_Int32 i,nRounds;
298 sal_Int32 nGlobalIndex = 0;
299 const sal_Int32 nWaitTimeSpanMUSec = 10000;
300 for( nRounds = 0 ; nRounds < 10 ; nRounds ++ )
302 for( i = 0 ; i < nRounds ; i ++ )
304 // fire oneways
305 xLBT->callOneway( nGlobalIndex , nWaitTimeSpanMUSec );
306 nGlobalIndex ++;
309 // call synchron
310 xLBT->call( nGlobalIndex , nWaitTimeSpanMUSec );
311 nGlobalIndex ++;
314 return xLBT->sequenceOfCallTestPassed();
317 namespace {
319 class ORecursiveCall : public WeakImplHelper< XRecursiveCall >
321 private:
322 Mutex m_mutex;
324 public:
325 void SAL_CALL callRecursivly(
326 const css::uno::Reference< XRecursiveCall >& xCall,
327 sal_Int32 nToCall ) override
329 MutexGuard guard( m_mutex );
330 if( nToCall )
332 nToCall --;
333 xCall->callRecursivly( this , nToCall );
341 static bool performRecursiveCallTest( const Reference < XBridgeTest > & xLBT )
343 xLBT->startRecursiveCall( new ORecursiveCall , 50 );
344 // on failure, the test would lock up or crash
345 return true;
348 namespace {
350 class MyClass : public osl::DebugBase<MyClass>, public OWeakObject
352 public:
353 MyClass();
358 MyClass::MyClass()
362 static bool performTest(
363 const Reference<XComponentContext> & xContext,
364 const Reference<XBridgeTest > & xLBT,
365 bool noCurrentContext )
367 check(xLBT.is(), "### no test interface!");
368 bool bRet = true;
369 if (xLBT.is()) {
370 // this data is never ever granted access to by calls other than
371 // equals(), assign()!
372 TestData aData; // test against this data
373 Reference< XInterface > xI(new MyClass);
374 assign(
375 static_cast<TestElement &>(aData), true, '@', 17, 0x1234, 0xFEDC,
376 0x12345678, 0xFEDCBA98, SAL_CONST_INT64(0x123456789ABCDEF0),
377 SAL_CONST_UINT64(0xFEDCBA9876543210), 17.03125f, M_PI,
378 TestEnum_LOLA, STRING_TEST_CONSTANT, 18, 0x5678, xI,
379 Any(&xI, cppu::UnoType<XInterface>::get()));
380 bRet &= check(aData.Any == xI, "### unexpected any!");
381 bRet &= check(!(aData.Any != xI), "### unexpected any!");
382 aData.Sequence.realloc(2);
383 aData.Sequence.getArray()[0] = *static_cast<TestElement const *>(&aData);
384 // aData.Sequence[1] is empty
385 // aSetData is a manually copy of aData for first setting:
386 TestData aSetData;
387 assign(
388 static_cast<TestElement &>(aSetData), aData.Bool, aData.Char,
389 aData.Byte, aData.Short, aData.UShort, aData.Long, aData.ULong,
390 aData.Hyper, aData.UHyper, aData.Float, aData.Double, aData.Enum,
391 aData.String, aData.Byte2, aData.Short2, xI, Any(&xI, cppu::UnoType<XInterface>::get()));
392 aSetData.Sequence.realloc(2);
393 aSetData.Sequence.getArray()[0] = *static_cast<TestElement const *>(&aSetData);
394 // aSetData.Sequence[1] is empty
395 xLBT->setValues(
396 aSetData.Bool,
397 aSetData.Char,
398 aSetData.Byte,
399 aSetData.Short,
400 aSetData.UShort,
401 aSetData.Long,
402 aSetData.ULong,
403 aSetData.Hyper,
404 aSetData.UHyper,
405 aSetData.Float,
406 aSetData.Double,
407 aSetData.Enum,
408 aSetData.String,
409 aSetData.Byte2,
410 aSetData.Short2,
411 aSetData.Interface,
412 aSetData.Any,
413 aSetData.Sequence,
414 aSetData);
416 TestData aRet;
417 TestData aRet2;
418 xLBT->getValues(
419 aRet.Bool,
420 aRet.Char,
421 aRet.Byte,
422 aRet.Short,
423 aRet.UShort,
424 aRet.Long,
425 aRet.ULong,
426 aRet.Hyper,
427 aRet.UHyper,
428 aRet.Float,
429 aRet.Double,
430 aRet.Enum,
431 aRet.String,
432 aRet.Byte2,
433 aRet.Short2,
434 aRet.Interface,
435 aRet.Any,
436 aRet.Sequence,
437 aRet2);
438 bRet &= check(
439 equals(aData, aRet) && equals(aData, aRet2), "getValues test");
440 // Set last retrieved values:
441 TestData aSV2ret(
442 xLBT->setValues2(
443 aRet.Bool,
444 aRet.Char,
445 aRet.Byte,
446 aRet.Short,
447 aRet.UShort,
448 aRet.Long,
449 aRet.ULong,
450 aRet.Hyper,
451 aRet.UHyper,
452 aRet.Float,
453 aRet.Double,
454 aRet.Enum,
455 aRet.String,
456 aRet.Byte2,
457 aRet.Short2,
458 aRet.Interface,
459 aRet.Any,
460 aRet.Sequence,
461 aRet2));
462 // Check inout sequence order (=> inout sequence parameter was
463 // switched by test objects):
464 auto pRetSequence = aRet.Sequence.getArray();
465 std::swap(pRetSequence[0], pRetSequence[1]);
466 bRet &= check(
467 equals(aData, aSV2ret) && equals(aData, aRet2),
468 "getValues2 test");
471 TwoFloats aIn(1.1f, 2.2f);
472 TwoFloats aOut = xLBT->echoTwoFloats(aIn);
473 bRet = check( memcmp(&aIn, &aOut, sizeof(TwoFloats)) == 0, "two floats struct test" ) && bRet;
476 FourFloats aIn(3.3f, 4.4f, 5.5f, 6.6f);
477 FourFloats aOut = xLBT->echoFourFloats(aIn);
478 bRet = check( memcmp(&aIn, &aOut, sizeof(FourFloats)) == 0, "four floats struct test" ) && bRet;
481 MixedFloatAndInteger aIn(7.7f, 8);
482 MixedFloatAndInteger aOut = xLBT->echoMixedFloatAndInteger(aIn);
483 bRet = check( memcmp(&aIn, &aOut, sizeof(MixedFloatAndInteger)) == 0, "mixed float and integer struct test" ) && bRet;
486 DoubleHyper in(10.0, 11);
487 DoubleHyper out = xLBT->echoDoubleHyper(in);
488 bRet &= check(out.a == in.a, "double and hyper struct test: double")
489 && check(out.b == in.b, "double and hyper struct test: hyper");
492 HyperDouble in(12, 13.0);
493 HyperDouble out = xLBT->echoHyperDouble(in);
494 bRet &= check(out.a == in.a, "hyper and double struct test: hyper")
495 && check(out.b == in.b, "hyper and double struct test: double");
498 FloatFloatLongByte in(20.0f, 21.0f, 22, '3');
499 FloatFloatLongByte out = xLBT->echoFloatFloatLongByte(in);
500 bRet &= check(out.a == in.a, "double and hyper struct test: first float")
501 && check(out.b == in.b, "double and hyper struct test: second float")
502 && check(out.c == in.c, "double and hyper struct test: long")
503 && check(out.d == in.d, "double and hyper struct test: byte");
506 ThreeByteStruct aIn(9, 10, 11);
507 ThreeByteStruct aOut = xLBT->echoThreeByteStruct(aIn);
508 bRet = check( memcmp(&aIn, &aOut, sizeof(ThreeByteStruct)) == 0, "three byte struct test" ) && bRet;
511 TestData aRet;
512 TestData aRet2;
513 TestData aGVret(
514 xLBT->getValues(
515 aRet.Bool,
516 aRet.Char,
517 aRet.Byte,
518 aRet.Short,
519 aRet.UShort,
520 aRet.Long,
521 aRet.ULong,
522 aRet.Hyper,
523 aRet.UHyper,
524 aRet.Float,
525 aRet.Double,
526 aRet.Enum,
527 aRet.String,
528 aRet.Byte2,
529 aRet.Short2,
530 aRet.Interface,
531 aRet.Any,
532 aRet.Sequence,
533 aRet2));
534 bRet &= check(
535 (equals(aData, aRet) && equals(aData, aRet2) &&
536 equals(aData, aGVret)),
537 "getValues test");
538 // Set last retrieved values:
539 xLBT->setBool(aRet.Bool);
540 xLBT->setChar(aRet.Char);
541 xLBT->setByte(aRet.Byte);
542 xLBT->setShort(aRet.Short);
543 xLBT->setUShort(aRet.UShort);
544 xLBT->setLong(aRet.Long);
545 xLBT->setULong(aRet.ULong);
546 xLBT->setHyper(aRet.Hyper);
547 xLBT->setUHyper(aRet.UHyper);
548 xLBT->setFloat(aRet.Float);
549 xLBT->setDouble(aRet.Double);
550 xLBT->setEnum(aRet.Enum);
551 xLBT->setString(aRet.String);
552 xLBT->setByte2(aRet.Byte2);
553 xLBT->setShort2(aRet.Short2);
554 xLBT->setInterface(aRet.Interface);
555 xLBT->setAny(aRet.Any);
556 xLBT->setSequence(aRet.Sequence);
557 xLBT->setStruct(aRet2);
560 TestData aRet;
561 aRet.Hyper = xLBT->getHyper();
562 aRet.UHyper = xLBT->getUHyper();
563 aRet.Float = xLBT->getFloat();
564 aRet.Double = xLBT->getDouble();
565 aRet.Byte = xLBT->getByte();
566 aRet.Char = xLBT->getChar();
567 aRet.Bool = xLBT->getBool();
568 aRet.Short = xLBT->getShort();
569 aRet.UShort = xLBT->getUShort();
570 aRet.Long = xLBT->getLong();
571 aRet.ULong = xLBT->getULong();
572 aRet.Enum = xLBT->getEnum();
573 aRet.String = xLBT->getString();
574 aRet.Byte2 = xLBT->getByte2();
575 aRet.Short2 = xLBT->getShort2();
576 aRet.Interface = xLBT->getInterface();
577 aRet.Any = xLBT->getAny();
578 aRet.Sequence = xLBT->getSequence();
579 TestData aRet2(xLBT->getStruct());
580 bRet &= check(
581 equals(aData, aRet) && equals(aData, aRet2),
582 "struct comparison test");
584 SmallStruct aIn(1, 2);
585 SmallStruct aOut(xLBT->echoSmallStruct(aIn));
586 bRet &= check(
587 memcmp(&aIn, &aOut, sizeof(SmallStruct)) == 0,
588 "small struct test");
591 MediumStruct aIn(1, 2, 3, 4);
592 MediumStruct aOut(xLBT->echoMediumStruct(aIn));
593 bRet &= check(
594 memcmp(&aIn, &aOut, sizeof(MediumStruct)) == 0,
595 "medium struct test");
598 BigStruct aIn(1, 2, 3, 4, 5, 6, 7, 8);
599 BigStruct aOut(xLBT->echoBigStruct(aIn));
600 bRet &= check(
601 memcmp(&aIn, &aOut, sizeof(BigStruct)) == 0,
602 "big struct test");
605 sal_Int32 i2 = xLBT->testPPCAlignment(0, 0, 0, 0, 0xBEAF);
606 bRet &= check(i2 == 0xBEAF, "ppc-style alignment test");
609 sal_Int32 i1 = xLBT->testPPC64Alignment(1.0, 2.0, 3.0, 0xBEAF);
610 bRet &= check(i1 == 0xBEAF, "ppc64-style alignment test");
613 double d1 = xLBT->testTenDoubles(0.1, 0.2, 0.3, 0.4, 0.5,
614 0.6, 0.7, 0.8, 0.9, 1.0);
615 bRet &= check(d1 == 5.5, "armhf doubles test");
617 // Test extended attributes that raise exceptions:
618 try {
619 xLBT->getRaiseAttr1();
620 bRet &= check(false, "getRaiseAttr1 did not throw");
621 } catch (const RuntimeException &) {
622 } catch (...) {
623 bRet &= check(false, "getRaiseAttr1 threw wrong type");
625 try {
626 xLBT->setRaiseAttr1(0);
627 bRet &= check(false, "setRaiseAttr1 did not throw");
628 } catch (const IllegalArgumentException &) {
629 } catch (...) {
630 bRet &= check(false, "setRaiseAttr1 threw wrong type");
632 try {
633 xLBT->getRaiseAttr2();
634 bRet &= check(false, "getRaiseAttr2 did not throw");
635 } catch (const IllegalArgumentException &) {
636 } catch (...) {
637 bRet &= check(false, "getRaiseAttr2 threw wrong type");
639 // Test instantiated polymorphic struct types:
641 bRet &= check(
642 (xLBT->transportPolyBoolean(
643 TestPolyStruct< sal_Bool >(true)).
644 member),
645 "transportPolyBoolean");
646 TestPolyStruct< sal_Int64 > tps1(12345);
647 xLBT->transportPolyHyper(tps1);
648 bRet &= check(tps1.member == 12345, "transportPolyHyper");
649 Sequence< Any > seq{ Any(static_cast< sal_uInt32 >(33)), Any(u"ABC"_ustr) };
650 TestPolyStruct< Sequence< Any > > tps2(seq);
651 TestPolyStruct< Sequence< Any > > tps3;
652 xLBT->transportPolySequence(tps2, tps3);
653 bRet &= check(
654 tps3.member.getLength() == 2,
655 "transportPolySequence, length");
656 sal_uInt32 v0 = sal_uInt32();
657 tps3.member[0] >>= v0;
658 bRet &= check(v0 == 33, "transportPolySequence, element 0");
659 OUString v1;
660 tps3.member[1] >>= v1;
661 bRet &= check( v1 == "ABC", "transportPolySequence, element 1" );
662 bRet &= check(
663 xLBT->getNullPolyLong().member == 0, "getNullPolyLong");
664 bRet &= check(
665 xLBT->getNullPolyString().member.isEmpty(),
666 "getNullPolyString");
667 bRet &= check(
668 xLBT->getNullPolyType().member == Type(),
669 "getNullPolyType");
670 Any nullAny(xLBT->getNullPolyAny().member);
671 auto ifc = o3tl::tryAccess<Reference<XInterface>>(nullAny);
672 bRet &= check(
673 !nullAny.hasValue() || (ifc && !ifc->is()),
674 "getNullPolyAny");
675 bRet &= check(
676 !xLBT->getNullPolySequence().member.hasElements(),
677 "getNullPolySequence");
678 bRet &= check(
679 xLBT->getNullPolyEnum().member == TestEnum_TEST,
680 "getNullPolyEnum");
681 bRet &= check(
682 xLBT->getNullPolyBadEnum().member == TestBadEnum_M,
683 "getNullPolyBadEnum");
684 bRet &= check(
685 xLBT->getNullPolyStruct().member.member == 0,
686 "getNullPolyStruct");
687 bRet &= check(
688 !xLBT->getNullPolyInterface().member.is(),
689 "getNullPolyInterface");
691 // Any test:
692 bRet &= check(performAnyTest(xLBT , aData), "any test");
693 // Sequence of call test:
694 bRet &= check(
695 performSequenceOfCallTest(xLBT), "sequence of call test");
696 // Recursive call test:
697 bRet &= check(performRecursiveCallTest(xLBT), "recursive test");
698 bRet &= check(
699 equals(aData, aRet) && equals(aData, aRet2),
700 "recursive test results");
701 // Multiple inheritance test:
702 bRet &= checkEmpty(
703 testtools::bridgetest::testMulti(xLBT->getMulti()),
704 "remote multi");
705 bRet &= checkEmpty(
706 xLBT->testMulti(new testtools::bridgetest::Multi),
707 "local multi");
711 Reference< XBridgeTest2 > xBT2(xLBT, UNO_QUERY);
712 if (!xBT2.is()) {
713 return bRet;
715 // Perform sequence tests (XBridgeTest2); create the sequence which is
716 // compared with the results:
717 sal_Int32 _arLong[] = {
718 static_cast< sal_Int32 >(0x80000000), 1, 0x7FFFFFFF };
719 sal_Int32 _aInt = 0xBABEBABE;
720 float _aFloat = 3.14f;
721 Any _arAny[] = {
722 Any(true),
723 Any(&_aInt, cppu::UnoType<sal_Int32>::get()),
724 Any(&_aFloat, cppu::UnoType<float>::get())
726 Reference< XInterface > _arObj[3];
727 _arObj[0] = new OWeakObject();
728 _arObj[1] = new OWeakObject();
729 _arObj[2] = new OWeakObject();
730 TestElement _arStruct[3];
731 assign(
732 _arStruct[0], true, '@', 17, 0x1234, 0xFEDC, 0x12345678, 0xFEDCBA98,
733 SAL_CONST_INT64(0x123456789ABCDEF0),
734 SAL_CONST_UINT64(0xFEDCBA9876543210), 17.03125f, M_PI,
735 TestEnum_LOLA, STRING_TEST_CONSTANT, 18, 0x5678, _arObj[0],
736 Any(&_arObj[0], cppu::UnoType<XInterface>::get()));
737 assign(
738 _arStruct[1], true, 'A', 17, 0x1234, 0xFEDC, 0x12345678, 0xFEDCBA98,
739 SAL_CONST_INT64(0x123456789ABCDEF0),
740 SAL_CONST_UINT64(0xFEDCBA9876543210), 17.03125f, M_PI,
741 TestEnum_TWO, STRING_TEST_CONSTANT, 18, 0x5678, _arObj[1],
742 Any(&_arObj[1], cppu::UnoType<XInterface>::get()));
743 assign(
744 _arStruct[2], true, 'B', 17, 0x1234, 0xFEDC, 0x12345678, 0xFEDCBA98,
745 SAL_CONST_INT64(0x123456789ABCDEF0),
746 SAL_CONST_UINT64(0xFEDCBA9876543210), 17.03125f, M_PI,
747 TestEnum_CHECK, STRING_TEST_CONSTANT, 18, 0x5678, _arObj[2],
748 Any(&_arObj[2], cppu::UnoType<XInterface>::get()));
750 Sequence<sal_Bool> arBool({true, false, true});
751 Sequence<sal_Unicode> arChar({0x0065, 0x0066, 0x0067});
752 Sequence<sal_Int8> arByte({1, 2, -1});
753 Sequence<sal_Int16> arShort({-0x8000, 1, 0x7FFF});
754 Sequence<sal_uInt16> arUShort({0 , 1, 0xFFFF});
755 Sequence<sal_Int32> arLong(_arLong, 3);
756 Sequence<sal_uInt32> arULong({0, 1, 0xFFFFFFFF});
757 Sequence<sal_Int64> arHyper({
758 static_cast<sal_Int64>(SAL_CONST_INT64(0x8000000000000000)), 1,
759 SAL_CONST_INT64(0x7FFFFFFFFFFFFFFF)});
760 Sequence<sal_uInt64> arUHyper({
761 0, 1, SAL_CONST_UINT64(0xFFFFFFFFFFFFFFFF)});
762 Sequence<float> arFloat({1.1f, 2.2f, 3.3f});
763 Sequence<double> arDouble({1.11, 2.22, 3.33});
764 Sequence<OUString> arString({
765 u"String 1"_ustr, u"String 2"_ustr,
766 u"String 3"_ustr});
767 Sequence<Any> arAny(_arAny, 3);
768 Sequence<Reference<XInterface> > arObject(_arObj, 3);
769 Sequence<TestEnum> arEnum({
770 TestEnum_ONE, TestEnum_TWO, TestEnum_CHECK});
771 Sequence<TestElement> arStruct(_arStruct, 3);
772 Sequence<Sequence<sal_Int32> > _arSeqLong2[3];
773 for (int j = 0; j != 3; ++j) {
774 Sequence< sal_Int32 > _arSeqLong[3];
775 for (int i = 0; i != 3; ++i) {
776 // coverity[overrun-buffer-arg : FALSE] - coverity has difficulty with css::uno::Sequence
777 _arSeqLong[i] = Sequence< sal_Int32 >(_arLong, 3);
779 _arSeqLong2[j] = Sequence< Sequence< sal_Int32 > >(
780 _arSeqLong, 3);
782 Sequence< Sequence< Sequence< sal_Int32> > > arLong3(
783 _arSeqLong2, 3);
784 Sequence< Sequence< sal_Int32 > > seqSeqRet(
785 xBT2->setDim2(arLong3[0]));
786 bRet &= check(seqSeqRet == arLong3[0], "sequence test");
787 Sequence< Sequence< Sequence< sal_Int32 > > > seqSeqRet2(
788 xBT2->setDim3(arLong3));
789 bRet &= check(seqSeqRet2 == arLong3, "sequence test");
790 Sequence< Any > seqAnyRet(xBT2->setSequenceAny(arAny));
791 bRet &= check(seqAnyRet == arAny, "sequence test");
792 Sequence< sal_Bool > seqBoolRet(xBT2->setSequenceBool(arBool));
793 bRet &= check(seqBoolRet == arBool, "sequence test");
794 Sequence< sal_Int8 > seqByteRet(xBT2->setSequenceByte(arByte));
795 bRet &= check(seqByteRet == arByte, "sequence test");
796 Sequence< sal_Unicode > seqCharRet(xBT2->setSequenceChar(arChar));
797 bRet &= check(seqCharRet == arChar, "sequence test");
798 Sequence< sal_Int16 > seqShortRet(xBT2->setSequenceShort(arShort));
799 bRet &= check(seqShortRet == arShort, "sequence test");
800 Sequence< sal_Int32 > seqLongRet(xBT2->setSequenceLong(arLong));
801 bRet &= check(seqLongRet == arLong, "sequence test");
802 Sequence< sal_Int64 > seqHyperRet(xBT2->setSequenceHyper(arHyper));
803 bRet &= check(seqHyperRet == arHyper, "sequence test");
804 Sequence< float > seqFloatRet(xBT2->setSequenceFloat(arFloat));
805 bRet &= check(seqFloatRet == arFloat, "sequence test");
806 Sequence< double > seqDoubleRet(xBT2->setSequenceDouble(arDouble));
807 bRet &= check(seqDoubleRet == arDouble, "sequence test");
808 Sequence< TestEnum > seqEnumRet(xBT2->setSequenceEnum(arEnum));
809 bRet &= check(seqEnumRet == arEnum, "sequence test");
810 Sequence< sal_uInt16 > seqUShortRet(
811 xBT2->setSequenceUShort(arUShort));
812 bRet &= check(seqUShortRet == arUShort, "sequence test");
813 Sequence< sal_uInt32 > seqULongRet(xBT2->setSequenceULong(arULong));
814 bRet &= check(seqULongRet == arULong, "sequence test");
815 Sequence< sal_uInt64 > seqUHyperRet(
816 xBT2->setSequenceUHyper(arUHyper));
817 bRet &= check(seqUHyperRet == arUHyper, "sequence test");
818 Sequence< Reference< XInterface > > seqObjectRet(
819 xBT2->setSequenceXInterface(arObject));
820 bRet &= check(seqObjectRet == arObject, "sequence test");
821 Sequence< OUString > seqStringRet(
822 xBT2->setSequenceString(arString));
823 bRet &= check(seqStringRet == arString, "sequence test");
824 Sequence< TestElement > seqStructRet(
825 xBT2->setSequenceStruct(arStruct));
826 bRet &= check(seqStructRet == arStruct, "sequence test");
827 Sequence< sal_Bool > arBoolTemp(cloneSequence(arBool));
828 Sequence< sal_Unicode > arCharTemp(cloneSequence<sal_Unicode, cppu::UnoCharType>(arChar));
829 Sequence< sal_Int8 > arByteTemp(cloneSequence(arByte));
830 Sequence< sal_Int16 > arShortTemp(cloneSequence(arShort));
831 Sequence< sal_uInt16 > arUShortTemp(cloneSequence<sal_uInt16, cppu::UnoUnsignedShortType>(arUShort));
832 Sequence< sal_Int32 > arLongTemp(cloneSequence(arLong));
833 Sequence< sal_uInt32 > arULongTemp(cloneSequence(arULong));
834 Sequence< sal_Int64 > arHyperTemp(cloneSequence(arHyper));
835 Sequence< sal_uInt64 > arUHyperTemp(cloneSequence(arUHyper));
836 Sequence< float > arFloatTemp(cloneSequence(arFloat));
837 Sequence< double > arDoubleTemp(cloneSequence(arDouble));
838 Sequence< TestEnum > arEnumTemp(cloneSequence(arEnum));
839 Sequence< OUString > arStringTemp(cloneSequence(arString));
840 Sequence< Reference< XInterface > > arObjectTemp(
841 cloneSequence(arObject));
842 Sequence< Any > arAnyTemp(cloneSequence(arAny));
843 Sequence< Sequence< sal_Int32 > > arLong2Temp(arLong3[0]);
844 Sequence< Sequence< Sequence< sal_Int32 > > > arLong3Temp(arLong3);
845 xBT2->setSequencesInOut(
846 arBoolTemp, arCharTemp, arByteTemp, arShortTemp, arUShortTemp,
847 arLongTemp,arULongTemp, arHyperTemp, arUHyperTemp, arFloatTemp,
848 arDoubleTemp, arEnumTemp, arStringTemp, arObjectTemp, arAnyTemp,
849 arLong2Temp, arLong3Temp);
850 bRet &= check(
851 (arBoolTemp == arBool && arCharTemp == arChar &&
852 arByteTemp == arByte && arShortTemp == arShort &&
853 arUShortTemp == arUShort && arLongTemp == arLong &&
854 arULongTemp == arULong && arHyperTemp == arHyper &&
855 arUHyperTemp == arUHyper && arFloatTemp == arFloat &&
856 arDoubleTemp == arDouble && arEnumTemp == arEnum &&
857 arStringTemp == arString && arObjectTemp == arObject &&
858 arAnyTemp == arAny && arLong2Temp == arLong3[0] &&
859 arLong3Temp == arLong3),
860 "sequence test");
861 Sequence< sal_Bool > arBoolOut;
862 Sequence< sal_Unicode > arCharOut;
863 Sequence< sal_Int8 > arByteOut;
864 Sequence< sal_Int16 > arShortOut;
865 Sequence< sal_uInt16 > arUShortOut;
866 Sequence< sal_Int32 > arLongOut;
867 Sequence< sal_uInt32 > arULongOut;
868 Sequence< sal_Int64 > arHyperOut;
869 Sequence< sal_uInt64 > arUHyperOut;
870 Sequence< float > arFloatOut;
871 Sequence< double > arDoubleOut;
872 Sequence< TestEnum > arEnumOut;
873 Sequence< OUString > arStringOut;
874 Sequence< Reference< XInterface > > arObjectOut;
875 Sequence< Any > arAnyOut;
876 Sequence< Sequence< sal_Int32 > > arLong2Out;
877 Sequence< Sequence< Sequence< sal_Int32 > > > arLong3Out;
878 xBT2->setSequencesOut(
879 arBoolOut, arCharOut, arByteOut, arShortOut, arUShortOut,
880 arLongOut,arULongOut, arHyperOut, arUHyperOut, arFloatOut,
881 arDoubleOut, arEnumOut, arStringOut, arObjectOut, arAnyOut,
882 arLong2Out, arLong3Out);
883 bRet &= check(
884 (arBoolOut == arBool && arCharOut == arChar &&
885 arByteOut == arByte && arShortOut == arShort &&
886 arUShortOut == arUShort && arLongOut == arLong &&
887 arULongOut == arULong && arHyperOut == arHyper &&
888 arUHyperOut == arUHyper && arFloatOut == arFloat &&
889 arDoubleOut == arDouble && arEnumOut == arEnum &&
890 arStringOut == arString && arObjectOut == arObject &&
891 arAnyOut == arAny && arLong2Out == arLong3[0] &&
892 arLong3Out == arLong3),
893 "sequence test");
896 // Test with empty sequences:
897 Sequence< Sequence< sal_Int32 > > arLong2;
898 Sequence< Sequence< sal_Int32 > > seqSeqRet(xBT2->setDim2(arLong2));
899 bRet &= check(seqSeqRet == arLong2, "sequence test");
900 Sequence< Sequence< Sequence< sal_Int32 > > > arLong3;
901 Sequence< Sequence< Sequence< sal_Int32 > > > seqSeqRet2(
902 xBT2->setDim3(arLong3));
903 bRet &= check(seqSeqRet2 == arLong3, "sequence test");
904 Sequence< Any > arAny;
905 Sequence< Any > seqAnyRet(xBT2->setSequenceAny(arAny));
906 bRet &= check(seqAnyRet == arAny, "sequence test");
907 Sequence< sal_Bool > arBool;
908 Sequence< sal_Bool > seqBoolRet(xBT2->setSequenceBool(arBool));
909 bRet &= check(seqBoolRet == arBool, "sequence test");
910 Sequence< sal_Int8 > arByte;
911 Sequence< sal_Int8 > seqByteRet(xBT2->setSequenceByte(arByte));
912 bRet &= check(seqByteRet == arByte, "sequence test");
913 Sequence< sal_Unicode > arChar;
914 Sequence< sal_Unicode > seqCharRet(xBT2->setSequenceChar(arChar));
915 bRet &= check(seqCharRet == arChar, "sequence test");
916 Sequence< sal_Int16 > arShort;
917 Sequence< sal_Int16 > seqShortRet(xBT2->setSequenceShort(arShort));
918 bRet &= check(seqShortRet == arShort, "sequence test");
919 Sequence< sal_Int32 > arLong;
920 Sequence< sal_Int32 > seqLongRet(xBT2->setSequenceLong(arLong));
921 bRet &= check(seqLongRet == arLong, "sequence test");
922 Sequence< sal_Int64 > arHyper;
923 Sequence< sal_Int64 > seqHyperRet(xBT2->setSequenceHyper(arHyper));
924 bRet &= check(seqHyperRet == arHyper, "sequence test");
925 Sequence< float > arFloat;
926 Sequence< float > seqFloatRet(xBT2->setSequenceFloat(arFloat));
927 bRet &= check(seqFloatRet == arFloat, "sequence test");
928 Sequence< double > arDouble;
929 Sequence< double > seqDoubleRet(xBT2->setSequenceDouble(arDouble));
930 bRet &= check(seqDoubleRet == arDouble, "sequence test");
931 Sequence< TestEnum > arEnum;
932 Sequence< TestEnum > seqEnumRet(xBT2->setSequenceEnum(arEnum));
933 bRet &= check(seqEnumRet == arEnum, "sequence test");
934 Sequence< sal_uInt16 > arUShort;
935 Sequence< sal_uInt16 > seqUShortRet(
936 xBT2->setSequenceUShort(arUShort));
937 bRet &= check(seqUShortRet == arUShort, "sequence test");
938 Sequence< sal_uInt32 > arULong;
939 Sequence< sal_uInt32 > seqULongRet(xBT2->setSequenceULong(arULong));
940 bRet &= check(seqULongRet == arULong, "sequence test");
941 Sequence< sal_uInt64 > arUHyper;
942 Sequence< sal_uInt64 > seqUHyperRet(
943 xBT2->setSequenceUHyper(arUHyper));
944 bRet &= check(seqUHyperRet == arUHyper, "sequence test");
945 Sequence< Reference< XInterface > > arObject;
946 Sequence< Reference< XInterface > > seqObjectRet(
947 xBT2->setSequenceXInterface(arObject));
948 bRet &= check(seqObjectRet == arObject, "sequence test");
949 Sequence< OUString > arString;
950 Sequence< OUString > seqStringRet(
951 xBT2->setSequenceString(arString));
952 bRet &= check(seqStringRet == arString, "sequence test");
953 Sequence< TestElement > arStruct;
954 Sequence< TestElement > seqStructRet(
955 xBT2->setSequenceStruct(arStruct));
956 bRet &= check(seqStructRet == arStruct, "sequence test");
958 // Issue #i60341# shows that the most interesting case is were Java
959 // calls the constructors; however, since this client is currently not
960 // available in Java, while the server is, the logic is reversed here:
961 try {
962 xBT2->testConstructorsService(xContext);
963 } catch (const BadConstructorArguments &) {
964 bRet = false;
966 if (!noCurrentContext) {
967 if (!(new testtools::bridgetest::CurrentContextChecker)->perform(
968 xBT2->getCurrentContextChecker(), 0, 1))
970 bRet = false;
972 if (!(new testtools::bridgetest::CurrentContextChecker)->perform(
973 xBT2->getCurrentContextChecker(), 0, 2))
975 bRet = false;
977 if (!(new testtools::bridgetest::CurrentContextChecker)->perform(
978 xBT2->getCurrentContextChecker(), 1, 2))
980 bRet = false;
982 if (!(new testtools::bridgetest::CurrentContextChecker)->perform(
983 xBT2->getCurrentContextChecker(), 1, 3))
985 bRet = false;
989 return bRet;
992 static bool raiseOnewayException( const Reference < XBridgeTest > & xLBT )
994 bool bReturn = true;
995 Reference<XInterface> const x(xLBT->getInterface());
998 // Note : the exception may fly or not (e.g. remote scenario).
999 // When it flies, it must contain the correct elements.
1000 xLBT->raiseRuntimeExceptionOneway( STRING_TEST_CONSTANT, x );
1002 catch( const RuntimeException & e )
1004 bReturn = (
1005 #if OSL_DEBUG_LEVEL == 0
1006 // java stack traces trash Message
1007 // The message might also contain source location
1008 e.Message.indexOf(STRING_TEST_CONSTANT) >= 0 &&
1009 #endif
1010 xLBT->getInterface() == e.Context &&
1011 x == e.Context );
1013 return bReturn;
1017 static bool raiseException( const Reference< XBridgeTest > & xLBT )
1019 sal_Int32 nCount = 0;
1026 xLBT->raiseException(
1027 5, STRING_TEST_CONSTANT,
1028 xLBT->getInterface() );
1030 catch (const IllegalArgumentException &rExc)
1032 if (rExc.ArgumentPosition == 5 &&
1033 #if OSL_DEBUG_LEVEL == 0
1034 // java stack traces trash Message
1035 rExc.Message.startsWith(STRING_TEST_CONSTANT) &&
1036 #endif
1037 rExc.Context == xLBT->getInterface())
1039 #ifdef COMPCHECK
1040 //When we check if a new compiler still works then we must not call
1041 //getRuntimeException because it uses cppu::getCaughtException which
1042 //does only work if all libs are build with the same runtime.
1043 return true;
1044 #else
1045 ++nCount;
1046 #endif
1048 else
1050 check( false, "### unexpected exception content!" );
1053 /** it is certain, that the RuntimeException testing will fail, if no */
1054 xLBT->getRuntimeException();
1057 catch (const RuntimeException & rExc)
1059 if (rExc.Context == xLBT->getInterface()
1060 #if OSL_DEBUG_LEVEL == 0
1061 // java stack traces trash Message
1062 && rExc.Message.startsWith(STRING_TEST_CONSTANT)
1063 #endif
1066 ++nCount;
1068 else
1070 check( false, "### unexpected exception content!" );
1073 /** it is certain, that the RuntimeException testing will fail, if no */
1074 xLBT->setRuntimeException( 0xcafebabe );
1077 catch (const Exception & rExc)
1079 if (rExc.Context == xLBT->getInterface()
1080 #if OSL_DEBUG_LEVEL == 0
1081 // java stack traces trash Message
1082 && rExc.Message.startsWith(STRING_TEST_CONSTANT)
1083 #endif
1086 ++nCount;
1088 else
1090 check( false, "### unexpected exception content!" );
1092 return (nCount == 3);
1094 return false;
1097 /* Returns an acquired sequence
1099 static uno_Sequence* cloneSequence(const uno_Sequence* val, const Type& type)
1101 TypeDescription td(type);
1102 td.makeComplete();
1103 typelib_TypeDescription* pTdRaw = td.get();
1104 typelib_IndirectTypeDescription* pIndirectTd =
1105 reinterpret_cast<typelib_IndirectTypeDescription*>(pTdRaw);
1107 typelib_TypeDescription* pTdElem = pIndirectTd->pType->pType;
1108 std::unique_ptr<sal_Int8[]> buf(new sal_Int8[pTdElem->nSize * val->nElements]);
1109 sal_Int8* pBufCur = buf.get();
1111 uno_Sequence* retSeq = nullptr;
1112 switch (static_cast<TypeClass>(pTdElem->eTypeClass))
1114 case TypeClass_SEQUENCE:
1116 Type _tElem(pTdElem->pWeakRef);
1117 for (int i = 0; i < val->nElements; i++)
1119 sal_Int8 const *pValBuf = reinterpret_cast<sal_Int8 const *>(&val->elements + i * pTdElem->nSize);
1121 uno_Sequence* seq = cloneSequence(
1122 reinterpret_cast<uno_Sequence const *>(pValBuf),
1123 _tElem);
1124 *reinterpret_cast<uno_Sequence**>(pBufCur) = seq;
1125 pBufCur += pTdElem->nSize;
1127 break;
1129 default:
1130 uno_type_sequence_construct(
1131 &retSeq, type.getTypeLibType(), const_cast<char *>(val->elements),
1132 val->nElements, reinterpret_cast< uno_AcquireFunc >(cpp_acquire));
1133 break;
1135 return retSeq;
1138 template<typename T, typename U>
1139 Sequence<T> cloneSequence(const Sequence<T>& val)
1141 Sequence<T> seq( cloneSequence(val.get(), cppu::UnoType<cppu::UnoSequenceType<U>>::get()), SAL_NO_ACQUIRE);
1142 return seq;
1145 template< class T >
1146 static bool makeSurrogate(
1147 Reference< T > & rOut, Reference< T > const & rOriginal )
1149 rOut.clear();
1150 if (! rOriginal.is())
1151 return false;
1153 Environment aCppEnv_official;
1154 Environment aUnoEnv_ano;
1155 Environment aCppEnv_ano;
1157 OUString aCppEnvTypeName(
1158 CPPU_CURRENT_LANGUAGE_BINDING_NAME );
1159 OUString aUnoEnvTypeName(
1160 u"" UNO_LB_UNO ""_ustr );
1161 // official:
1162 uno_getEnvironment(
1163 reinterpret_cast< uno_Environment ** >( &aCppEnv_official ),
1164 aCppEnvTypeName.pData, nullptr );
1165 // anonymous:
1166 uno_createEnvironment(
1167 reinterpret_cast< uno_Environment ** >( &aCppEnv_ano ),
1168 aCppEnvTypeName.pData, nullptr );
1169 uno_createEnvironment(
1170 reinterpret_cast< uno_Environment ** >( &aUnoEnv_ano ),
1171 aUnoEnvTypeName.pData, nullptr );
1173 UnoInterfaceReference unoI;
1174 Mapping cpp2uno( aCppEnv_official.get(), aUnoEnv_ano.get() );
1175 Mapping uno2cpp( aUnoEnv_ano.get(), aCppEnv_ano.get() );
1176 if (!cpp2uno.is() || !uno2cpp.is())
1178 throw RuntimeException(u"cannot get C++-UNO mappings!"_ustr );
1180 cpp2uno.mapInterface(
1181 reinterpret_cast< void ** >( &unoI.m_pUnoI ),
1182 rOriginal.get(), cppu::UnoType<decltype(rOriginal)>::get() );
1183 if (! unoI.is())
1185 throw RuntimeException(
1186 u"mapping C++ to binary UNO failed!"_ustr );
1188 uno2cpp.mapInterface(
1189 reinterpret_cast< void ** >( &rOut ),
1190 unoI.get(), cppu::UnoType<decltype(rOriginal)>::get() );
1191 if (! rOut.is())
1193 throw RuntimeException(
1194 u"mapping binary UNO to C++ failed!"_ustr );
1197 return rOut.is();
1201 sal_Int32 TestBridgeImpl::run( const Sequence< OUString > & rArgs )
1203 bool bRet = false;
1206 if (! rArgs.hasElements())
1208 throw RuntimeException( u"no test object specified!\n"
1209 "usage : ServiceName of test object | -u unourl of test object"_ustr );
1212 Reference< XInterface > xOriginal;
1213 bool remote;
1214 sal_Int32 i;
1215 if( rArgs.getLength() > 1 && rArgs[0] == "-u" )
1217 remote = true;
1218 i = 2;
1220 else
1222 remote = false;
1223 i = 1;
1225 bool noCurrentContext = false;
1226 if ( i < rArgs.getLength() && rArgs[i] == "noCurrentContext" )
1228 noCurrentContext = true;
1229 ++i;
1231 bool stress = false;
1232 if ( i < rArgs.getLength() && rArgs[i] == "stress" )
1234 stress = true;
1235 ++i;
1238 // coverity[loop_top] - deliberate 'infinite' loop when 'stress' is set
1239 for (;;) {
1240 Reference< XInterface > o;
1241 if (remote) {
1242 o = UnoUrlResolver::create(m_xContext)->resolve(rArgs[1]);
1243 } else {
1244 o = m_xContext->getServiceManager()->createInstanceWithContext(
1245 rArgs[0], m_xContext);
1247 if (!stress) {
1248 xOriginal = std::move(o);
1249 break;
1253 if (! xOriginal.is())
1255 throw RuntimeException( u"cannot get test object!"_ustr );
1257 Reference< XBridgeTest > xTest( xOriginal, UNO_QUERY_THROW );
1259 Reference<XBridgeTest > xLBT;
1260 bRet = check( makeSurrogate( xLBT, xTest ), "makeSurrogate" );
1261 bRet = check(
1262 performTest( m_xContext, xLBT, noCurrentContext ), "standard test" )
1263 && bRet;
1264 bRet = check( raiseException( xLBT ) , "exception test" )&& bRet;
1265 bRet = check( raiseOnewayException( xLBT ),
1266 "oneway exception test" ) && bRet;
1267 // Check that a dynamic_cast from what is potentially a proxy object does not cause a crash
1268 // (and the choice of TestBridgeImpl as target is rather arbitrary, it is just some type for
1269 // which the dynamic_cast is known to be null):
1270 bRet = (dynamic_cast<TestBridgeImpl *>(xOriginal.get()) == nullptr) && bRet;
1271 if (! bRet)
1273 throw RuntimeException( u"error: test failed!"_ustr );
1276 catch (const Exception & exc)
1278 OString cstr( OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) );
1279 fprintf( stderr, "exception occurred: %s\n", cstr.getStr() );
1280 throw;
1283 return bRet ? 0 : 1;
1286 // XServiceInfo
1288 OUString TestBridgeImpl::getImplementationName()
1290 return IMPLNAME;
1293 sal_Bool TestBridgeImpl::supportsService( const OUString & rServiceName )
1295 return cppu::supportsService(this, rServiceName);
1298 Sequence< OUString > TestBridgeImpl::getSupportedServiceNames()
1300 return bridge_test::getSupportedServiceNames();
1304 static Reference< XInterface > TestBridgeImpl_create(
1305 const Reference< XComponentContext > & xContext )
1307 return getXWeak( new TestBridgeImpl( xContext ) );
1312 extern "C"
1315 SAL_DLLPUBLIC_EXPORT void * component_getFactory(
1316 const char * pImplName, void * pServiceManager,
1317 SAL_UNUSED_PARAMETER void * )
1319 void * pRet = nullptr;
1321 if (pServiceManager && o3tl::equalsAscii(IMPLNAME, pImplName))
1323 Reference< XInterface > xFactory(
1324 createSingleComponentFactory(
1325 bridge_test::TestBridgeImpl_create,
1326 IMPLNAME,
1327 bridge_test::getSupportedServiceNames() ) );
1329 if (xFactory.is())
1331 xFactory->acquire();
1332 pRet = xFactory.get();
1336 return pRet;
1340 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */