1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
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>
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"
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
;
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
)
89 fprintf( stderr
, "%s failed\n" , message
);
95 bool checkEmpty(std::u16string_view string
, char const * message
) {
96 bool ok
= string
.empty();
99 stderr
, "%s failed: %s\n", message
,
100 OUStringToOString(string
, RTL_TEXTENCODING_UTF8
).getStr());
105 class TestBridgeImpl
: public osl::DebugBase
<TestBridgeImpl
>,
106 public WeakImplHelper
< XMain
, XServiceInfo
>
108 Reference
< XComponentContext
> m_xContext
;
111 explicit TestBridgeImpl( const Reference
< XComponentContext
> & xContext
)
112 : m_xContext( xContext
)
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
;
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
)
169 if (rData1
.Sequence
!= rData2
.Sequence
)
171 if (!equals( static_cast<const TestElement
&>(rData1
), static_cast<const TestElement
&>(rData2
) ))
173 nLen
= rData1
.Sequence
.getLength();
174 if (nLen
== rData2
.Sequence
.getLength())
176 // once again by hand sequence ==
179 if (!equals(rData1
.Sequence
[nLen
], rData2
.Sequence
[nLen
]))
181 check( false, "### sequence element did not match!" );
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
)
204 rData
.Short
= nShort
;
205 rData
.UShort
= nUShort
;
207 rData
.ULong
= nULong
;
208 rData
.Hyper
= nHyper
;
209 rData
.UHyper
= nUHyper
;
210 rData
.Float
= fFloat
;
211 rData
.Double
= fDouble
;
214 rData
.Byte2
= nByte2
;
215 rData
.Short2
= nShort2
;
216 rData
.Interface
= xTest
;
222 template < typename T
>
224 T
const & value
, Reference
< XBridgeTest
> const & xLBT
,
225 char const * typeName
= nullptr)
229 Any any2
= xLBT
->transportAny(any
);
233 stderr
, "any is different after roundtrip: in %s, out %s\n",
235 any
.getValueTypeName(),
236 RTL_TEXTENCODING_ASCII_US
).getStr(),
238 any2
.getValueTypeName(),
239 RTL_TEXTENCODING_ASCII_US
).getStr());
242 if (typeName
!= nullptr
243 && !any2
.getValueTypeName().equalsAscii(typeName
))
246 stderr
, "any has wrong type after roundtrip: %s instead of %s\n",
248 any2
.getValueTypeName(),
249 RTL_TEXTENCODING_ASCII_US
).getStr(),
258 static bool performAnyTest( const Reference
< XBridgeTest
> &xLBT
, const TestData
&data
)
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
;
277 TestPolyStruct
< sal_Unicode
>(' '), xLBT
,
278 "test.testtools.bridgetest.TestPolyStruct<char>");
283 OSL_ASSERT( xLBT
->transportAny( a
) == a
);
288 OSL_ASSERT( xLBT
->transportAny( a
) == a
);
295 static bool performSequenceOfCallTest( const Reference
< XBridgeTest
> &xLBT
)
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
++ )
305 xLBT
->callOneway( nGlobalIndex
, nWaitTimeSpanMUSec
);
310 xLBT
->call( nGlobalIndex
, nWaitTimeSpanMUSec
);
314 return xLBT
->sequenceOfCallTestPassed();
319 class ORecursiveCall
: public WeakImplHelper
< XRecursiveCall
>
325 void SAL_CALL
callRecursivly(
326 const css::uno::Reference
< XRecursiveCall
>& xCall
,
327 sal_Int32 nToCall
) override
329 MutexGuard
guard( m_mutex
);
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
350 class MyClass
: public osl::DebugBase
<MyClass
>, public OWeakObject
362 static bool performTest(
363 const Reference
<XComponentContext
> & xContext
,
364 const Reference
<XBridgeTest
> & xLBT
,
365 bool noCurrentContext
)
367 check(xLBT
.is(), "### no test interface!");
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
);
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:
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
439 equals(aData
, aRet
) && equals(aData
, aRet2
), "getValues test");
440 // Set last retrieved values:
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]);
467 equals(aData
, aSV2ret
) && equals(aData
, aRet2
),
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
;
535 (equals(aData
, aRet
) && equals(aData
, aRet2
) &&
536 equals(aData
, aGVret
)),
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
);
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());
581 equals(aData
, aRet
) && equals(aData
, aRet2
),
582 "struct comparison test");
584 SmallStruct
aIn(1, 2);
585 SmallStruct
aOut(xLBT
->echoSmallStruct(aIn
));
587 memcmp(&aIn
, &aOut
, sizeof(SmallStruct
)) == 0,
588 "small struct test");
591 MediumStruct
aIn(1, 2, 3, 4);
592 MediumStruct
aOut(xLBT
->echoMediumStruct(aIn
));
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
));
601 memcmp(&aIn
, &aOut
, sizeof(BigStruct
)) == 0,
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:
619 xLBT
->getRaiseAttr1();
620 bRet
&= check(false, "getRaiseAttr1 did not throw");
621 } catch (const RuntimeException
&) {
623 bRet
&= check(false, "getRaiseAttr1 threw wrong type");
626 xLBT
->setRaiseAttr1(0);
627 bRet
&= check(false, "setRaiseAttr1 did not throw");
628 } catch (const IllegalArgumentException
&) {
630 bRet
&= check(false, "setRaiseAttr1 threw wrong type");
633 xLBT
->getRaiseAttr2();
634 bRet
&= check(false, "getRaiseAttr2 did not throw");
635 } catch (const IllegalArgumentException
&) {
637 bRet
&= check(false, "getRaiseAttr2 threw wrong type");
639 // Test instantiated polymorphic struct types:
642 (xLBT
->transportPolyBoolean(
643 TestPolyStruct
< sal_Bool
>(true)).
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
);
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");
660 tps3
.member
[1] >>= v1
;
661 bRet
&= check( v1
== "ABC", "transportPolySequence, element 1" );
663 xLBT
->getNullPolyLong().member
== 0, "getNullPolyLong");
665 xLBT
->getNullPolyString().member
.isEmpty(),
666 "getNullPolyString");
668 xLBT
->getNullPolyType().member
== Type(),
670 Any
nullAny(xLBT
->getNullPolyAny().member
);
671 auto ifc
= o3tl::tryAccess
<Reference
<XInterface
>>(nullAny
);
673 !nullAny
.hasValue() || (ifc
&& !ifc
->is()),
676 !xLBT
->getNullPolySequence().member
.hasElements(),
677 "getNullPolySequence");
679 xLBT
->getNullPolyEnum().member
== TestEnum_TEST
,
682 xLBT
->getNullPolyBadEnum().member
== TestBadEnum_M
,
683 "getNullPolyBadEnum");
685 xLBT
->getNullPolyStruct().member
.member
== 0,
686 "getNullPolyStruct");
688 !xLBT
->getNullPolyInterface().member
.is(),
689 "getNullPolyInterface");
692 bRet
&= check(performAnyTest(xLBT
, aData
), "any test");
693 // Sequence of call test:
695 performSequenceOfCallTest(xLBT
), "sequence of call test");
696 // Recursive call test:
697 bRet
&= check(performRecursiveCallTest(xLBT
), "recursive test");
699 equals(aData
, aRet
) && equals(aData
, aRet2
),
700 "recursive test results");
701 // Multiple inheritance test:
703 testtools::bridgetest::testMulti(xLBT
->getMulti()),
706 xLBT
->testMulti(new testtools::bridgetest::Multi
),
711 Reference
< XBridgeTest2
> xBT2(xLBT
, UNO_QUERY
);
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
;
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];
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()));
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()));
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
,
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
> >(
782 Sequence
< Sequence
< Sequence
< sal_Int32
> > > arLong3(
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
);
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
),
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
);
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
),
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:
962 xBT2
->testConstructorsService(xContext
);
963 } catch (const BadConstructorArguments
&) {
966 if (!noCurrentContext
) {
967 if (!(new testtools::bridgetest::CurrentContextChecker
)->perform(
968 xBT2
->getCurrentContextChecker(), 0, 1))
972 if (!(new testtools::bridgetest::CurrentContextChecker
)->perform(
973 xBT2
->getCurrentContextChecker(), 0, 2))
977 if (!(new testtools::bridgetest::CurrentContextChecker
)->perform(
978 xBT2
->getCurrentContextChecker(), 1, 2))
982 if (!(new testtools::bridgetest::CurrentContextChecker
)->perform(
983 xBT2
->getCurrentContextChecker(), 1, 3))
992 static bool raiseOnewayException( const Reference
< XBridgeTest
> & xLBT
)
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
)
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 &&
1010 xLBT
->getInterface() == e
.Context
&&
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
) &&
1037 rExc
.Context
== xLBT
->getInterface())
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.
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
)
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
)
1090 check( false, "### unexpected exception content!" );
1092 return (nCount
== 3);
1097 /* Returns an acquired sequence
1099 static uno_Sequence
* cloneSequence(const uno_Sequence
* val
, const Type
& type
)
1101 TypeDescription
td(type
);
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
),
1124 *reinterpret_cast<uno_Sequence
**>(pBufCur
) = seq
;
1125 pBufCur
+= pTdElem
->nSize
;
1130 uno_type_sequence_construct(
1131 &retSeq
, type
.getTypeLibType(), const_cast<char *>(val
->elements
),
1132 val
->nElements
, reinterpret_cast< uno_AcquireFunc
>(cpp_acquire
));
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
);
1146 static bool makeSurrogate(
1147 Reference
< T
> & rOut
, Reference
< T
> const & rOriginal
)
1150 if (! rOriginal
.is())
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
);
1163 reinterpret_cast< uno_Environment
** >( &aCppEnv_official
),
1164 aCppEnvTypeName
.pData
, nullptr );
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() );
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() );
1193 throw RuntimeException(
1194 u
"mapping binary UNO to C++ failed!"_ustr
);
1201 sal_Int32
TestBridgeImpl::run( const Sequence
< OUString
> & rArgs
)
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
;
1215 if( rArgs
.getLength() > 1 && rArgs
[0] == "-u" )
1225 bool noCurrentContext
= false;
1226 if ( i
< rArgs
.getLength() && rArgs
[i
] == "noCurrentContext" )
1228 noCurrentContext
= true;
1231 bool stress
= false;
1232 if ( i
< rArgs
.getLength() && rArgs
[i
] == "stress" )
1238 // coverity[loop_top] - deliberate 'infinite' loop when 'stress' is set
1240 Reference
< XInterface
> o
;
1242 o
= UnoUrlResolver::create(m_xContext
)->resolve(rArgs
[1]);
1244 o
= m_xContext
->getServiceManager()->createInstanceWithContext(
1245 rArgs
[0], m_xContext
);
1248 xOriginal
= std::move(o
);
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" );
1262 performTest( m_xContext
, xLBT
, noCurrentContext
), "standard test" )
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
;
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() );
1283 return bRet
? 0 : 1;
1288 OUString
TestBridgeImpl::getImplementationName()
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
) );
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
,
1327 bridge_test::getSupportedServiceNames() ) );
1331 xFactory
->acquire();
1332 pRet
= xFactory
.get();
1340 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */