diff options
Diffstat (limited to 'testtools/source/bridgetest/bridgetest.cxx')
-rw-r--r-- | testtools/source/bridgetest/bridgetest.cxx | 1369 |
1 files changed, 1369 insertions, 0 deletions
diff --git a/testtools/source/bridgetest/bridgetest.cxx b/testtools/source/bridgetest/bridgetest.cxx new file mode 100644 index 000000000000..46204319966d --- /dev/null +++ b/testtools/source/bridgetest/bridgetest.cxx @@ -0,0 +1,1369 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_testtools.hxx" + +#include <stdio.h> +#include <string.h> +#include <osl/diagnose.h> +#include "osl/diagnose.hxx" +#include <osl/time.h> +#include <sal/types.h> +#include "typelib/typedescription.hxx" +#include <uno/dispatcher.hxx> +#include "uno/mapping.hxx" +#include <uno/data.h> +#include "uno/environment.hxx" + +#include <cppuhelper/factory.hxx> +#include <cppuhelper/implbase2.hxx> +#include <cppuhelper/implbase1.hxx> + +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/lang/XMain.hpp> +#include <com/sun/star/registry/XRegistryKey.hpp> +#include <com/sun/star/bridge/UnoUrlResolver.hpp> +#include <com/sun/star/bridge/XUnoUrlResolver.hpp> +#include "com/sun/star/uno/RuntimeException.hpp" +#include "com/sun/star/uno/Type.hxx" + +#include "test/testtools/bridgetest/BadConstructorArguments.hpp" +#include "test/testtools/bridgetest/TestPolyStruct.hpp" +#include "test/testtools/bridgetest/XBridgeTest.hpp" +#include "test/testtools/bridgetest/XBridgeTest2.hpp" +#include "test/testtools/bridgetest/XMulti.hpp" + +#include "currentcontextchecker.hxx" +#include "multi.hxx" + +using namespace rtl; +using namespace osl; +using namespace cppu; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::registry; +using namespace com::sun::star::bridge; +using namespace test::testtools::bridgetest; + +#define SERVICENAME "com.sun.star.test.bridge.BridgeTest" +#define IMPLNAME "com.sun.star.comp.bridge.BridgeTest" + +#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) ) +#define STRING_TEST_CONSTANT "\" paco\' chorizo\\\' \"\'" + +namespace bridge_test +{ +template< class T> +Sequence<T> cloneSequence(const Sequence<T>& val); + +//-------------------------------------------------------------------------------------------------- +inline static Sequence< OUString > getSupportedServiceNames() +{ + OUString aName( RTL_CONSTASCII_USTRINGPARAM(SERVICENAME) ); + return Sequence< OUString >( &aName, 1 ); +} + +static bool check( bool b , char const * message ) +{ + if ( ! b ) + fprintf( stderr, "%s failed\n" , message ); + return b; +} + +namespace { + +bool checkEmpty(rtl::OUString const & string, char const * message) { + bool ok = string.getLength() == 0; + if (!ok) { + fprintf( + stderr, "%s failed: %s\n", message, + rtl::OUStringToOString(string, RTL_TEXTENCODING_UTF8).getStr()); + } + return ok; +} + +} + +//================================================================================================== +class TestBridgeImpl : protected osl::DebugBase<TestBridgeImpl>, + public WeakImplHelper2< XMain, XServiceInfo > +{ + Reference< XComponentContext > m_xContext; + +public: + TestBridgeImpl( const Reference< XComponentContext > & xContext ) + : m_xContext( xContext ) + {} + virtual ~TestBridgeImpl() + { + } + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() throw (RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const OUString & rServiceName ) throw (RuntimeException); + virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw (RuntimeException); + + // XMain + virtual sal_Int32 SAL_CALL run( const Sequence< OUString > & rArgs ) throw (RuntimeException); +}; + +//================================================================================================== +static sal_Bool equals( const TestElement & rData1, const TestElement & rData2 ) +{ + check( rData1.Bool == rData2.Bool, "### bool does not match!" ); + check( rData1.Char == rData2.Char, "### char does not match!" ); + check( rData1.Byte == rData2.Byte, "### byte does not match!" ); + check( rData1.Short == rData2.Short, "### short does not match!" ); + check( rData1.UShort == rData2.UShort, "### unsigned short does not match!" ); + check( rData1.Long == rData2.Long, "### long does not match!" ); + check( rData1.ULong == rData2.ULong, "### unsigned long does not match!" ); + check( rData1.Hyper == rData2.Hyper, "### hyper does not match!" ); + check( rData1.UHyper == rData2.UHyper, "### unsigned hyper does not match!" ); + check( rData1.Float == rData2.Float, "### float does not match!" ); + check( rData1.Double == rData2.Double, "### double does not match!" ); + check( rData1.Enum == rData2.Enum, "### enum does not match!" ); + check( rData1.String == rData2.String, "### string does not match!" ); + check( rData1.Interface == rData2.Interface, "### interface does not match!" ); + check( rData1.Any == rData2.Any, "### any does not match!" ); + + return (rData1.Bool == rData2.Bool && + rData1.Char == rData2.Char && + rData1.Byte == rData2.Byte && + rData1.Short == rData2.Short && + rData1.UShort == rData2.UShort && + rData1.Long == rData2.Long && + rData1.ULong == rData2.ULong && + rData1.Hyper == rData2.Hyper && + rData1.UHyper == rData2.UHyper && + rData1.Float == rData2.Float && + rData1.Double == rData2.Double && + rData1.Enum == rData2.Enum && + rData1.String == rData2.String && + rData1.Interface == rData2.Interface && + rData1.Any == rData2.Any); +} +//================================================================================================== +static sal_Bool equals( const TestData & rData1, const TestData & rData2 ) +{ + sal_Int32 nLen; + + if ((rData1.Sequence == rData2.Sequence) && + equals( (const TestElement &)rData1, (const TestElement &)rData2 ) && + (nLen = rData1.Sequence.getLength()) == rData2.Sequence.getLength()) + { + // once again by hand sequence == + const TestElement * pElements1 = rData1.Sequence.getConstArray(); + const TestElement * pElements2 = rData2.Sequence.getConstArray(); + for ( ; nLen--; ) + { + if (! equals( pElements1[nLen], pElements2[nLen] )) + { + check( sal_False, "### sequence element did not match!" ); + return sal_False; + } + } + return sal_True; + } + return sal_False; +} +//================================================================================================== +static void assign( TestElement & rData, + sal_Bool bBool, sal_Unicode cChar, sal_Int8 nByte, + sal_Int16 nShort, sal_uInt16 nUShort, + sal_Int32 nLong, sal_uInt32 nULong, + sal_Int64 nHyper, sal_uInt64 nUHyper, + float fFloat, double fDouble, + TestEnum eEnum, const ::rtl::OUString& rStr, + const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& xTest, + const ::com::sun::star::uno::Any& rAny ) +{ + rData.Bool = bBool; + rData.Char = cChar; + rData.Byte = nByte; + rData.Short = nShort; + rData.UShort = nUShort; + rData.Long = nLong; + rData.ULong = nULong; + rData.Hyper = nHyper; + rData.UHyper = nUHyper; + rData.Float = fFloat; + rData.Double = fDouble; + rData.Enum = eEnum; + rData.String = rStr; + rData.Interface = xTest; + rData.Any = rAny; +} + +namespace { + +template < typename T > +bool testAny( + T const & value, Reference< XBridgeTest > const & xLBT, + char const * typeName = 0) +{ + Any any; + any <<= value; + Any any2 = xLBT->transportAny(any); + bool success = true; + if (any != any2) { + fprintf( + stderr, "any is different after roundtrip: in %s, out %s\n", + OUStringToOString( + any.getValueType().getTypeName(), + RTL_TEXTENCODING_ASCII_US).getStr(), + OUStringToOString( + any2.getValueType().getTypeName(), + RTL_TEXTENCODING_ASCII_US).getStr()); + success = false; + } + if (typeName != 0 + && !any2.getValueType().getTypeName().equalsAscii(typeName)) + { + fprintf( + stderr, "any has wrong type after roundtrip: %s instead of %s\n", + OUStringToOString( + any2.getValueType().getTypeName(), + RTL_TEXTENCODING_ASCII_US).getStr(), + typeName); + success = false; + } + return success; +} + +} + +static sal_Bool performAnyTest( const Reference< XBridgeTest > &xLBT, const TestData &data) +{ + bool bReturn = true; + bReturn = testAny( data.Byte ,xLBT ) && bReturn; + bReturn = testAny( data.Short,xLBT ) && bReturn; + bReturn = testAny( data.UShort,xLBT ) && bReturn; + bReturn = testAny( data.Long,xLBT ) && bReturn; + bReturn = testAny( data.ULong,xLBT ) && bReturn; + bReturn = testAny( data.Hyper,xLBT ) && bReturn; + bReturn = testAny( data.UHyper,xLBT ) && bReturn; + bReturn = testAny( data.Float,xLBT ) && bReturn; + bReturn = testAny( data.Double,xLBT ) && bReturn; + bReturn = testAny( data.Enum,xLBT ) && bReturn; + bReturn = testAny( data.String,xLBT ) && bReturn; + bReturn = testAny( data.Interface,xLBT ) && bReturn; + bReturn = testAny( data, xLBT ) && bReturn; + bReturn &= testAny( + TestPolyStruct< sal_Unicode >(' '), xLBT, + "test.testtools.bridgetest.TestPolyStruct<char>"); + + Any a; + { + a.setValue( &(data.Bool) , getCppuBooleanType() ); + Any a2 = xLBT->transportAny( a ); + OSL_ASSERT( a2 == a ); + } + + { + a.setValue( &(data.Char) , getCppuCharType() ); + Any a2 = xLBT->transportAny( a ); + OSL_ASSERT( a2 == a ); + } + + return bReturn; +} + +//_______________________________________________________________________________________ +static sal_Bool performSequenceOfCallTest( const Reference < XBridgeTest > &xLBT ) +{ + sal_Int32 i,nRounds; + sal_Int32 nGlobalIndex = 0; + const sal_Int32 nWaitTimeSpanMUSec = 10000; + for( nRounds = 0 ; nRounds < 10 ; nRounds ++ ) + { + for( i = 0 ; i < nRounds ; i ++ ) + { + // fire oneways + xLBT->callOneway( nGlobalIndex , nWaitTimeSpanMUSec ); + nGlobalIndex ++; + } + + // call synchron + xLBT->call( nGlobalIndex , nWaitTimeSpanMUSec ); + nGlobalIndex ++; + } + + return xLBT->sequenceOfCallTestPassed(); +} + +class ORecursiveCall : public WeakImplHelper1< XRecursiveCall > +{ +private: + Mutex m_mutex; + +public: + void SAL_CALL callRecursivly( + const ::com::sun::star::uno::Reference< XRecursiveCall >& xCall, + sal_Int32 nToCall ) + throw(::com::sun::star::uno::RuntimeException) + { + MutexGuard guard( m_mutex ); + if( nToCall ) + { + nToCall --; + xCall->callRecursivly( this , nToCall ); + } + + } +}; + + +//_______________________________________________________________________________________ +static sal_Bool performRecursiveCallTest( const Reference < XBridgeTest > & xLBT ) +{ + xLBT->startRecursiveCall( new ORecursiveCall , 50 ); + // on failure, the test would lock up or crash + return sal_True; +} + +static sal_Bool performQueryForUnknownType( const Reference< XBridgeTest > & xLBT ) +{ + sal_Bool bRet = sal_True; + // use this when you want to test querying for unknown types + // currently (not supported by the java remote bridge ) + { + // test queryInterface for an unknown type + typelib_TypeDescriptionReference *pTypeRef = 0; + OUString aName( RTL_CONSTASCII_USTRINGPARAM( "foo.MyInterface" ) ); + typelib_typedescriptionreference_new( + &pTypeRef, typelib_TypeClass_INTERFACE, aName.pData); + try + { + Any a = xLBT->queryInterface( Type( pTypeRef ) ); + bRet = check( a == Any( ), "got an foo.MyInterface, but didn't expect to get one" ); + } + catch( com::sun::star::uno::RuntimeException & ) + { + fprintf( + stderr, + "tried to query for an interface reference of an unknown type " + "but got a runtime exception. This should work for native bridges " + "but isn't implemented for Java remote bridge\n" + "Note: All subsequent tests may fail now as the remote bridge is broken\n" + "QueryForUnknownType" ); + } + typelib_typedescriptionreference_release( pTypeRef ); + } + return bRet; +} + +class MyClass : public osl::DebugBase<MyClass>, public OWeakObject +{ +public: + MyClass(); + virtual ~MyClass(); + virtual void SAL_CALL acquire() throw (); + virtual void SAL_CALL release() throw (); +}; + +//______________________________________________________________________________ +MyClass::MyClass() +{ +} +//______________________________________________________________________________ +MyClass::~MyClass() +{ +} +//______________________________________________________________________________ +void MyClass::acquire() throw () +{ + OWeakObject::acquire(); +} +//______________________________________________________________________________ +void MyClass::release() throw () +{ + OWeakObject::release(); +} + +//================================================================================================== +static sal_Bool performTest( + const Reference<XComponentContext> & xContext, + const Reference<XBridgeTest > & xLBT, + bool noCurrentContext ) +{ + check( xLBT.is(), "### no test interface!" ); + bool bRet = true; + if (xLBT.is()) + { + // this data is never ever granted access to by calls other than equals(), assign()! + TestData aData; // test against this data + + Reference<XInterface > xI( new MyClass ); + + assign( (TestElement &)aData, + sal_True, '@', 17, 0x1234, 0xfedc, 0x12345678, 0xfedcba98, + SAL_CONST_INT64(0x123456789abcdef0), + SAL_CONST_UINT64(0xfedcba9876543210), + (float)17.0815, 3.1415926359, TestEnum_LOLA, + OUSTR(STRING_TEST_CONSTANT), xI, + Any( &xI, ::getCppuType( (const Reference<XInterface > *)0 ) ) ); + + bRet = check( aData.Any == xI, "### unexpected any!" ) && bRet; + bRet = check( !(aData.Any != xI), "### unexpected any!" ) && bRet; + + aData.Sequence.realloc( 2 ); + aData.Sequence[ 0 ] = *(const TestElement *)&aData; + // aData.Sequence[ 1 ] is empty + + // aData complete + //================================================================================ + + // this is a manually copy of aData for first setting... + TestData aSetData; + + assign( (TestElement &)aSetData, + aData.Bool, aData.Char, aData.Byte, aData.Short, aData.UShort, + aData.Long, aData.ULong, aData.Hyper, aData.UHyper, aData.Float, aData.Double, + aData.Enum, aData.String, xI, + Any( &xI, ::getCppuType( (const Reference<XInterface > *)0 ) ) ); + + aSetData.Sequence.realloc( 2 ); + aSetData.Sequence[ 0 ] = *(const TestElement *)&aSetData; + // aSetData.Sequence[ 1 ] is empty + + xLBT->setValues( + aSetData.Bool, aSetData.Char, aSetData.Byte, aSetData.Short, aSetData.UShort, + aSetData.Long, aSetData.ULong, aSetData.Hyper, aSetData.UHyper, aSetData.Float, aSetData.Double, + aSetData.Enum, aSetData.String, aSetData.Interface, aSetData.Any, aSetData.Sequence, aSetData ); + + { + TestData aRet, aRet2; + xLBT->getValues( + aRet.Bool, aRet.Char, aRet.Byte, aRet.Short, aRet.UShort, + aRet.Long, aRet.ULong, aRet.Hyper, aRet.UHyper, aRet.Float, aRet.Double, + aRet.Enum, aRet.String, aRet.Interface, aRet.Any, aRet.Sequence, aRet2 ); + + bRet = check( equals( aData, aRet ) && equals( aData, aRet2 ) , "getValues test") && bRet; + + // set last retrieved values + TestData aSV2ret = xLBT->setValues2( + aRet.Bool, aRet.Char, aRet.Byte, aRet.Short, aRet.UShort, + aRet.Long, aRet.ULong, aRet.Hyper, aRet.UHyper, aRet.Float, aRet.Double, + aRet.Enum, aRet.String, aRet.Interface, aRet.Any, aRet.Sequence, aRet2 ); + // check inout sequence order + // => inout sequence parameter was switched by test objects + TestElement temp = aRet.Sequence[ 0 ]; + aRet.Sequence[ 0 ] = aRet.Sequence[ 1 ]; + aRet.Sequence[ 1 ] = temp; + + bRet = check( + equals( aData, aSV2ret ) && equals( aData, aRet2 ), + "getValues2 test") && bRet; + } + { + TestData aRet, aRet2; + TestData aGVret = xLBT->getValues( + aRet.Bool, aRet.Char, aRet.Byte, aRet.Short, aRet.UShort, + aRet.Long, aRet.ULong, aRet.Hyper, aRet.UHyper, aRet.Float, aRet.Double, + aRet.Enum, aRet.String, aRet.Interface, aRet.Any, aRet.Sequence, aRet2 ); + + bRet = check( equals( aData, aRet ) && equals( aData, aRet2 ) && equals( aData, aGVret ), "getValues test" ) && bRet; + + // set last retrieved values + xLBT->setBool( aRet.Bool ); + xLBT->setChar( aRet.Char ); + xLBT->setByte( aRet.Byte ); + xLBT->setShort( aRet.Short ); + xLBT->setUShort( aRet.UShort ); + xLBT->setLong( aRet.Long ); + xLBT->setULong( aRet.ULong ); + xLBT->setHyper( aRet.Hyper ); + xLBT->setUHyper( aRet.UHyper ); + xLBT->setFloat( aRet.Float ); + xLBT->setDouble( aRet.Double ); + xLBT->setEnum( aRet.Enum ); + xLBT->setString( aRet.String ); + xLBT->setInterface( aRet.Interface ); + xLBT->setAny( aRet.Any ); + xLBT->setSequence( aRet.Sequence ); + xLBT->setStruct( aRet2 ); + } + { + TestData aRet, aRet2; + aRet.Hyper = xLBT->getHyper(); + aRet.UHyper = xLBT->getUHyper(); + aRet.Float = xLBT->getFloat(); + aRet.Double = xLBT->getDouble(); + aRet.Byte = xLBT->getByte(); + aRet.Char = xLBT->getChar(); + aRet.Bool = xLBT->getBool(); + aRet.Short = xLBT->getShort(); + aRet.UShort = xLBT->getUShort(); + aRet.Long = xLBT->getLong(); + aRet.ULong = xLBT->getULong(); + aRet.Enum = xLBT->getEnum(); + aRet.String = xLBT->getString(); + aRet.Interface = xLBT->getInterface(); + aRet.Any = xLBT->getAny(); + aRet.Sequence = xLBT->getSequence(); + aRet2 = xLBT->getStruct(); + + bRet = check( equals( aData, aRet ) && equals( aData, aRet2 ) , "struct comparison test") && bRet; + + { + SmallStruct aIn(1, 2); + SmallStruct aOut = xLBT->echoSmallStruct(aIn); + bRet = check( memcmp(&aIn, &aOut, sizeof(SmallStruct)) == 0, "small struct test" ) && bRet; + } + { + MediumStruct aIn(1, 2, 3, 4); + MediumStruct aOut = xLBT->echoMediumStruct(aIn); + bRet = check( memcmp(&aIn, &aOut, sizeof(MediumStruct)) == 0, "medium struct test" ) && bRet; + } + { + BigStruct aIn(1, 2, 3, 4, 5, 6, 7, 8); + BigStruct aOut = xLBT->echoBigStruct(aIn); + bRet = check( memcmp(&aIn, &aOut, sizeof(BigStruct)) == 0, "big struct test" ) && bRet; + } + { + AllFloats aIn(1.1f, 2.2f, 3.3f, 4.4f); + AllFloats aOut = xLBT->echoAllFloats(aIn); + bRet = check( memcmp(&aIn, &aOut, sizeof(AllFloats)) == 0, "all floats struct test" ) && bRet; + } + { + sal_Int32 i2 = xLBT->testPPCAlignment( 0, 0, 0, 0, 0xbeaf ); + bRet = check( i2 == 0xbeaf, "ppc-style alignment test" ) && bRet; + } + + // Test extended attributes that raise exceptions: + try { + xLBT->getRaiseAttr1(); + bRet &= check(false, "getRaiseAttr1 did not throw"); + } catch (RuntimeException &) { + } catch (...) { + bRet &= check(false, "getRaiseAttr1 threw wrong type"); + } + try { + xLBT->setRaiseAttr1(0); + bRet &= check(false, "setRaiseAttr1 did not throw"); + } catch (IllegalArgumentException &) { + } catch (...) { + bRet &= check(false, "setRaiseAttr1 threw wrong type"); + } + try { + xLBT->getRaiseAttr2(); + bRet &= check(false, "getRaiseAttr2 did not throw"); + } catch (IllegalArgumentException &) { + } catch (...) { + bRet &= check(false, "getRaiseAttr2 threw wrong type"); + } + + // Test instantiated polymorphic struct types: + { + bRet &= check( + xLBT->transportPolyBoolean(TestPolyStruct< sal_Bool >(true)).member, + "transportPolyBoolean"); + TestPolyStruct< sal_Int64 > tps1(12345); + xLBT->transportPolyHyper(tps1); + bRet &= check(tps1.member == 12345, "transportPolyHyper"); + Sequence< Any > seq(2); + seq[0] <<= static_cast< sal_uInt32 >(33); + seq[1] <<= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ABC")); + TestPolyStruct< Sequence< Any > > tps2(seq); + TestPolyStruct< Sequence< Any > > tps3; + xLBT->transportPolySequence(tps2, tps3); + bRet &= check( + tps3.member.getLength() == 2, "transportPolySequence, length"); + sal_uInt32 v0 = sal_uInt32(); + tps3.member[0] >>= v0; + bRet &= check(v0 == 33, "transportPolySequence, element 0"); + rtl::OUString v1; + tps3.member[1] >>= v1; + bRet &= check( + v1.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("ABC")), + "transportPolySequence, element 1"); + bRet &= check(xLBT->getNullPolyLong().member == 0, "getNullPolyLong"); + bRet &= check( + xLBT->getNullPolyString().member.getLength() == 0, + "getNullPolyString"); + bRet &= check( + xLBT->getNullPolyType().member == Type(), "getNullPolyType"); + Any nullAny(xLBT->getNullPolyAny().member); + bRet &= check( + (((nullAny.getValueTypeName() + == rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.XInterface"))) + && !static_cast< Reference< XInterface > const * >( + nullAny.getValue())->is()) + || nullAny == Any()), + "getNullPolyAny"); + bRet &= check( + xLBT->getNullPolySequence().member.getLength() == 0, + "getNullPolySequence"); + bRet &= check( + xLBT->getNullPolyEnum().member == TestEnum_TEST, "getNullPolyEnum"); + bRet &= check( + xLBT->getNullPolyBadEnum().member == TestBadEnum_M, + "getNullPolyBadEnum"); + bRet &= check( + xLBT->getNullPolyStruct().member.member == 0, "getNullPolyStruct"); + bRet &= check( + !xLBT->getNullPolyInterface().member.is(), "getNullPolyInterface"); + } + + // any test + bRet = check( performAnyTest( xLBT , aData ) , "any test" ) && bRet; + + // sequence of call test + bRet = check( performSequenceOfCallTest( xLBT ) , "sequence of call test" ) && bRet; + + // recursive call test + bRet = check( performRecursiveCallTest( xLBT ) , "recursive test" ) && bRet; + + bRet = (equals( aData, aRet ) && equals( aData, aRet2 )) && bRet ; + + // multiple inheritance test + bRet &= checkEmpty( + testtools::bridgetest::testMulti(xLBT->getMulti()), "remote multi"); + bRet &= checkEmpty( + xLBT->testMulti(new testtools::bridgetest::Multi), "local multi"); + } + + } + { + Reference<XBridgeTest2> xBT2(xLBT, UNO_QUERY); + if ( ! xBT2.is()) + return bRet; + + // perform sequence tests (XBridgeTest2) + // create the sequence which are compared with the results + sal_Bool _arBool[] = {sal_True, sal_False, sal_True}; + sal_Unicode _arChar[] = {0x0065, 0x0066, 0x0067}; + sal_Int8 _arByte[] = { 1, 2, -1 }; + sal_Int16 _arShort[] = { -0x8000, 1, 0x7fff }; + sal_uInt16 _arUShort[] = {0 , 1, 0xffff}; + sal_Int32 _arLong[] = {0x80000000, 1, 0x7fffffff}; + sal_uInt32 _arULong[] = {0, 1, 0xffffffff}; + sal_Int64 _arHyper[] = { + SAL_CONST_INT64(0x8000000000000000), 1, + SAL_CONST_INT64(0x7fffffffffffffff)}; + sal_uInt64 _arUHyper[] = {0, 1, SAL_CONST_UINT64(0xffffffffffffffff)}; + float _arFloat[] = {1.1f, 2.2f, 3.3f}; + double _arDouble[] = {1.11, 2.22, 3.33}; + OUString _arString[] = { + OUString(RTL_CONSTASCII_USTRINGPARAM("String 1")), + OUString(RTL_CONSTASCII_USTRINGPARAM("String 2")), + OUString(RTL_CONSTASCII_USTRINGPARAM("String 3")) + }; + + sal_Bool _aBool = sal_True; + sal_Int32 _aInt = 0xbabebabe; + float _aFloat = 3.14f; + Any _any1(&_aBool, getCppuBooleanType()); + Any _any2(&_aInt, getCppuType((sal_Int32*) 0)); + Any _any3(&_aFloat, getCppuType((float*) 0)); + Any _arAny[] = { _any1, _any2, _any3}; + + Reference<XInterface> _arObj[3]; + _arObj[0] = new OWeakObject(); + _arObj[1] = new OWeakObject(); + _arObj[2] = new OWeakObject(); + + TestEnum _arEnum[] = {TestEnum_ONE, TestEnum_TWO, TestEnum_CHECK}; + + TestElement _arStruct[3]; + assign( _arStruct[0], sal_True, '@', 17, 0x1234, 0xfedc, 0x12345678, 0xfedcba98, + SAL_CONST_INT64(0x123456789abcdef0), + SAL_CONST_UINT64(0xfedcba9876543210), + 17.0815f, 3.1415926359, + TestEnum_LOLA, OUSTR(STRING_TEST_CONSTANT), _arObj[0], + Any( &_arObj[0], ::getCppuType( (const Reference<XInterface > *)0 ) ) ); + assign( _arStruct[1], sal_True, 'A', 17, 0x1234, 0xfedc, 0x12345678, 0xfedcba98, + SAL_CONST_INT64(0x123456789abcdef0), + SAL_CONST_UINT64(0xfedcba9876543210), + 17.0815f, 3.1415926359, + TestEnum_TWO, OUSTR(STRING_TEST_CONSTANT), _arObj[1], + Any( &_arObj[1], ::getCppuType( (const Reference<XInterface > *)0 ) ) ); + assign( _arStruct[2], sal_True, 'B', 17, 0x1234, 0xfedc, 0x12345678, 0xfedcba98, + SAL_CONST_INT64(0x123456789abcdef0), + SAL_CONST_UINT64(0xfedcba9876543210), + 17.0815f, 3.1415926359, + TestEnum_CHECK, OUSTR(STRING_TEST_CONSTANT), _arObj[2], + Any( &_arObj[2], ::getCppuType( (const Reference<XInterface > *)0 ) ) ); + + { + Sequence<sal_Bool> arBool(_arBool, 3); + Sequence<sal_Unicode> arChar( _arChar, 3); + Sequence<sal_Int8> arByte(_arByte, 3); + Sequence<sal_Int16> arShort(_arShort, 3); + Sequence<sal_uInt16> arUShort(_arUShort, 3); + Sequence<sal_Int32> arLong(_arLong, 3); + Sequence<sal_uInt32> arULong(_arULong, 3); + Sequence<sal_Int64> arHyper(_arHyper, 3); + Sequence<sal_uInt64> arUHyper(_arUHyper, 3); + Sequence<float> arFloat(_arFloat, 3); + Sequence<double> arDouble(_arDouble, 3); + Sequence<OUString> arString(_arString, 3); + Sequence<Any> arAny(_arAny, 3); + Sequence<Reference<XInterface> > arObject(_arObj, 3); + Sequence<TestEnum> arEnum(_arEnum, 3); + Sequence<TestElement> arStruct(_arStruct, 3); + Sequence<Sequence<sal_Int32> > _arSeqLong2[3]; + for (int j = 0; j < 3; j++) + { + Sequence<sal_Int32> _arSeqLong[3]; + for (int i = 0; i < 3; i++) + { + _arSeqLong[i] = Sequence<sal_Int32>(_arLong, 3); + } + + _arSeqLong2[j] = Sequence< Sequence<sal_Int32> > (_arSeqLong, 3); + } + + Sequence<Sequence<Sequence<sal_Int32> > > arLong3( _arSeqLong2, 3); + Sequence<Sequence<sal_Int32> > seqSeqRet = xBT2->setDim2(arLong3[0]); + bRet = check( seqSeqRet == arLong3[0], "sequence test") && bRet; + Sequence<Sequence<Sequence<sal_Int32> > > seqSeqRet2 = xBT2->setDim3(arLong3); + bRet = check( seqSeqRet2 == arLong3, "sequence test") && bRet; + Sequence<Any> seqAnyRet = xBT2->setSequenceAny(arAny); + bRet = check( seqAnyRet == arAny, "sequence test") && bRet; + Sequence<sal_Bool> seqBoolRet = xBT2->setSequenceBool(arBool); + bRet = check( seqBoolRet == arBool, "sequence test") && bRet; + Sequence<sal_Int8> seqByteRet = xBT2->setSequenceByte(arByte); + bRet = check( seqByteRet == arByte, "sequence test") && bRet; + Sequence<sal_Unicode> seqCharRet = xBT2->setSequenceChar(arChar); + bRet = check( seqCharRet == arChar, "sequence test") && bRet; + Sequence<sal_Int16> seqShortRet = xBT2->setSequenceShort(arShort); + bRet = check( seqShortRet == arShort, "sequence test") && bRet; + Sequence<sal_Int32> seqLongRet = xBT2->setSequenceLong(arLong); + bRet = check( seqLongRet == arLong, "sequence test") && bRet; + Sequence<sal_Int64> seqHyperRet = xBT2->setSequenceHyper(arHyper); + bRet = check( seqHyperRet == arHyper, "sequence test") && bRet; + Sequence<float> seqFloatRet = xBT2->setSequenceFloat(arFloat); + bRet = check( seqFloatRet == arFloat, "sequence test") && bRet; + Sequence<double> seqDoubleRet = xBT2->setSequenceDouble(arDouble); + bRet = check( seqDoubleRet == arDouble, "sequence test") && bRet; + Sequence<TestEnum> seqEnumRet = xBT2->setSequenceEnum(arEnum); + bRet = check( seqEnumRet == arEnum, "sequence test") && bRet; + Sequence<sal_uInt16> seqUShortRet = xBT2->setSequenceUShort(arUShort); + bRet = check( seqUShortRet == arUShort, "sequence test") && bRet; + Sequence<sal_uInt32> seqULongRet = xBT2->setSequenceULong(arULong); + bRet = check( seqULongRet == arULong, "sequence test") && bRet; + Sequence<sal_uInt64> seqUHyperRet = xBT2->setSequenceUHyper(arUHyper); + bRet = check( seqUHyperRet == arUHyper, "sequence test") && bRet; + Sequence<Reference<XInterface> > seqObjectRet = xBT2->setSequenceXInterface(arObject); + bRet = check( seqObjectRet == arObject, "sequence test") && bRet; + Sequence<OUString> seqStringRet = xBT2->setSequenceString(arString); + bRet = check( seqStringRet == arString, "sequence test") && bRet; + Sequence<TestElement> seqStructRet = xBT2->setSequenceStruct(arStruct); + bRet = check( seqStructRet == arStruct, "sequence test") && bRet; + + Sequence<sal_Bool> arBoolTemp = cloneSequence(arBool); + Sequence<sal_Unicode> arCharTemp = cloneSequence(arChar); + Sequence<sal_Int8> arByteTemp = cloneSequence(arByte); + Sequence<sal_Int16> arShortTemp = cloneSequence(arShort); + Sequence<sal_uInt16> arUShortTemp = cloneSequence(arUShort); + Sequence<sal_Int32> arLongTemp = cloneSequence(arLong); + Sequence<sal_uInt32> arULongTemp = cloneSequence(arULong); + Sequence<sal_Int64> arHyperTemp = cloneSequence(arHyper); + Sequence<sal_uInt64> arUHyperTemp = cloneSequence(arUHyper); + Sequence<float> arFloatTemp = cloneSequence(arFloat); + Sequence<double> arDoubleTemp = cloneSequence(arDouble); + Sequence<TestEnum> arEnumTemp = cloneSequence(arEnum); + Sequence<OUString> arStringTemp = cloneSequence(arString); + Reference<XInterface> _xint; + Sequence<Reference<XInterface> > arObjectTemp = cloneSequence(arObject); + Sequence<Any> arAnyTemp = cloneSequence(arAny); + Sequence<Sequence<sal_Int32> > arLong2Temp(arLong3[0]); + Sequence<Sequence<Sequence<sal_Int32> > > arLong3Temp(arLong3); + + xBT2->setSequencesInOut(arBoolTemp, arCharTemp, arByteTemp, arShortTemp, + arUShortTemp, arLongTemp,arULongTemp, arHyperTemp, + arUHyperTemp, arFloatTemp, arDoubleTemp, + arEnumTemp, arStringTemp, arObjectTemp, arAnyTemp, + arLong2Temp, arLong3Temp); + bRet = check( + arBoolTemp == arBool && + arCharTemp == arChar && + arByteTemp == arByte && + arShortTemp == arShort && + arUShortTemp == arUShort && + arLongTemp == arLong && + arULongTemp == arULong && + arHyperTemp == arHyper && + arUHyperTemp == arUHyper && + arFloatTemp == arFloat && + arDoubleTemp == arDouble && + arEnumTemp == arEnum && + arStringTemp == arString && + arObjectTemp == arObject && + arAnyTemp == arAny && + arLong2Temp == arLong3[0] && + arLong3Temp == arLong3, "sequence test") && bRet; + + Sequence<sal_Bool> arBoolOut; + Sequence<sal_Unicode> arCharOut; + Sequence<sal_Int8> arByteOut; + Sequence<sal_Int16> arShortOut; + Sequence<sal_uInt16> arUShortOut; + Sequence<sal_Int32> arLongOut; + Sequence<sal_uInt32> arULongOut; + Sequence<sal_Int64> arHyperOut; + Sequence<sal_uInt64> arUHyperOut; + Sequence<float> arFloatOut; + Sequence<double> arDoubleOut; + Sequence<TestEnum> arEnumOut; + Sequence<OUString> arStringOut; + Sequence<Reference<XInterface> > arObjectOut; + Sequence<Any> arAnyOut; + Sequence<Sequence<sal_Int32> > arLong2Out; + Sequence<Sequence<Sequence<sal_Int32> > > arLong3Out; + xBT2->setSequencesOut(arBoolOut, arCharOut, arByteOut, arShortOut, + arUShortOut, arLongOut,arULongOut, arHyperOut, + arUHyperOut, arFloatOut, arDoubleOut, + arEnumOut, arStringOut, arObjectOut, arAnyOut, + arLong2Out, arLong3Out); + bRet = check( + arBoolOut == arBool && + arCharOut == arChar && + arByteOut == arByte && + arShortOut == arShort && + arUShortOut == arUShort && + arLongOut == arLong && + arULongOut == arULong && + arHyperOut == arHyper && + arUHyperOut == arUHyper && + arFloatOut == arFloat && + arDoubleOut == arDouble && + arEnumOut == arEnum && + arStringOut == arString && + arObjectOut == arObject && + arAnyOut == arAny && + arLong2Out == arLong3[0] && + arLong3Out == arLong3, "sequence test") && bRet; + } + { + //test with empty sequences + Sequence<Sequence<sal_Int32> > arLong2; + Sequence<Sequence<sal_Int32> > seqSeqRet = xBT2->setDim2(arLong2); + bRet = check( seqSeqRet == arLong2, "sequence test") && bRet; + Sequence<Sequence<Sequence<sal_Int32> > > arLong3; + Sequence<Sequence<Sequence<sal_Int32> > > seqSeqRet2 = xBT2->setDim3( + arLong3); + bRet = check( seqSeqRet2 == arLong3, "sequence test") && bRet; + Sequence<Any> arAny; + Sequence<Any> seqAnyRet = xBT2->setSequenceAny(arAny); + bRet = check( seqAnyRet == arAny, "sequence test") && bRet; + Sequence<sal_Bool> arBool; + Sequence<sal_Bool> seqBoolRet = xBT2->setSequenceBool(arBool); + bRet = check( seqBoolRet == arBool, "sequence test") && bRet; + Sequence<sal_Int8> arByte; + Sequence<sal_Int8> seqByteRet = xBT2->setSequenceByte(arByte); + bRet = check( seqByteRet == arByte, "sequence test") && bRet; + Sequence<sal_Unicode> arChar; + Sequence<sal_Unicode> seqCharRet = xBT2->setSequenceChar(arChar); + bRet = check( seqCharRet == arChar, "sequence test") && bRet; + Sequence<sal_Int16> arShort; + Sequence<sal_Int16> seqShortRet = xBT2->setSequenceShort(arShort); + bRet = check( seqShortRet == arShort, "sequence test") && bRet; + Sequence<sal_Int32> arLong; + Sequence<sal_Int32> seqLongRet = xBT2->setSequenceLong(arLong); + bRet = check( seqLongRet == arLong, "sequence test") && bRet; + Sequence<sal_Int64> arHyper; + Sequence<sal_Int64> seqHyperRet = xBT2->setSequenceHyper(arHyper); + bRet = check( seqHyperRet == arHyper, "sequence test") && bRet; + Sequence<float> arFloat; + Sequence<float> seqFloatRet = xBT2->setSequenceFloat(arFloat); + bRet = check( seqFloatRet == arFloat, "sequence test") && bRet; + Sequence<double> arDouble; + Sequence<double> seqDoubleRet = xBT2->setSequenceDouble(arDouble); + bRet = check( seqDoubleRet == arDouble, "sequence test") && bRet; + Sequence<TestEnum> arEnum; + Sequence<TestEnum> seqEnumRet = xBT2->setSequenceEnum(arEnum); + bRet = check( seqEnumRet == arEnum, "sequence test") && bRet; + Sequence<sal_uInt16> arUShort; + Sequence<sal_uInt16> seqUShortRet = xBT2->setSequenceUShort(arUShort); + bRet = check( seqUShortRet == arUShort, "sequence test") && bRet; + Sequence<sal_uInt32> arULong; + Sequence<sal_uInt32> seqULongRet = xBT2->setSequenceULong(arULong); + bRet = check( seqULongRet == arULong, "sequence test") && bRet; + Sequence<sal_uInt64> arUHyper; + Sequence<sal_uInt64> seqUHyperRet = xBT2->setSequenceUHyper(arUHyper); + bRet = check( seqUHyperRet == arUHyper, "sequence test") && bRet; + Sequence<Reference<XInterface> > arObject; + Sequence<Reference<XInterface> > seqObjectRet = + xBT2->setSequenceXInterface(arObject); + bRet = check( seqObjectRet == arObject, "sequence test") && bRet; + Sequence<OUString> arString; + Sequence<OUString> seqStringRet = xBT2->setSequenceString(arString); + bRet = check( seqStringRet == arString, "sequence test") && bRet; + Sequence<TestElement> arStruct; + Sequence<TestElement> seqStructRet = xBT2->setSequenceStruct(arStruct); + bRet = check( seqStructRet == arStruct, "sequence test") && bRet; + } + // Issue #i60341# shows that the most interesting case is were Java calls + // the constructors; however, since this client is currently not available + // in Java, while the server is, the logic is reversed here: + try { + xBT2->testConstructorsService(xContext); + } catch (BadConstructorArguments &) { + bRet = false; + } + if (!noCurrentContext) { + if (!(new testtools::bridgetest::CurrentContextChecker)->perform( + xBT2->getCurrentContextChecker(), 0, 1)) + { + bRet = false; + } + if (!(new testtools::bridgetest::CurrentContextChecker)->perform( + xBT2->getCurrentContextChecker(), 0, 2)) + { + bRet = false; + } + if (!(new testtools::bridgetest::CurrentContextChecker)->perform( + xBT2->getCurrentContextChecker(), 1, 2)) + { + bRet = false; + } + if (!(new testtools::bridgetest::CurrentContextChecker)->perform( + xBT2->getCurrentContextChecker(), 1, 3)) + { + bRet = false; + } + } + } + return bRet; +} +static sal_Bool raiseOnewayException( const Reference < XBridgeTest > & xLBT ) +{ + sal_Bool bReturn = sal_True; + OUString sCompare = OUSTR(STRING_TEST_CONSTANT); + Reference<XInterface> const x(xLBT->getInterface()); + try + { + // Note : the exception may fly or not (e.g. remote scenario). + // When it flies, it must contain the correct elements. + xLBT->raiseRuntimeExceptionOneway( sCompare, x ); + } + catch( RuntimeException & e ) + { + bReturn = ( +#if OSL_DEBUG_LEVEL == 0 + // java stack traces trash Message + e.Message == sCompare && +#endif + xLBT->getInterface() == e.Context && + x == e.Context ); + } + return bReturn; +} + +//================================================================================================== +static sal_Bool raiseException( const Reference< XBridgeTest > & xLBT ) +{ + sal_Int32 nCount = 0; + try + { + try + { + try + { + TestData aRet, aRet2; + xLBT->raiseException( + 5, OUSTR(STRING_TEST_CONSTANT), + xLBT->getInterface() ); + } + catch (IllegalArgumentException aExc) + { + if (aExc.ArgumentPosition == 5 && +#if OSL_DEBUG_LEVEL == 0 + // java stack traces trash Message + aExc.Message.compareToAscii( STRING_TEST_CONSTANT ) == 0 && +#endif + aExc.Context == xLBT->getInterface()) + { +#ifdef COMPCHECK + //When we check if a new compiler still works then we must not call + //getRuntimeException because it uses cppu::getCaughtException which + //does only work if all libs are build with the same runtime. + return true; +#else + ++nCount; +#endif + } + else + { + check( sal_False, "### unexpected exception content!" ); + } + + /** it is certain, that the RuntimeException testing will fail, if no */ + xLBT->getRuntimeException(); + } + } + catch (const RuntimeException & rExc) + { + if (rExc.Context == xLBT->getInterface() +#if OSL_DEBUG_LEVEL == 0 + // java stack traces trash Message + && rExc.Message.compareToAscii( STRING_TEST_CONSTANT ) == 0 +#endif + ) + { + ++nCount; + } + else + { + check( sal_False, "### unexpected exception content!" ); + } + + /** it is certain, that the RuntimeException testing will fail, if no */ + xLBT->setRuntimeException( 0xcafebabe ); + } + } + catch (Exception & rExc) + { + if (rExc.Context == xLBT->getInterface() +#if OSL_DEBUG_LEVEL == 0 + // java stack traces trash Message + && rExc.Message.compareToAscii( STRING_TEST_CONSTANT ) == 0 +#endif + ) + { + ++nCount; + } + else + { + check( sal_False, "### unexpected exception content!" ); + } + return (nCount == 3); + } + return sal_False; +} + +/* Returns an acquired sequence + */ +uno_Sequence* cloneSequence(const uno_Sequence* val, const Type& type) +{ + TypeDescription td(type); + td.makeComplete(); + typelib_TypeDescription* pTdRaw = td.get(); + typelib_IndirectTypeDescription* pIndirectTd = + (typelib_IndirectTypeDescription*) pTdRaw; + + typelib_TypeDescription* pTdElem = pIndirectTd->pType->pType; + sal_Int8* buf = new sal_Int8[pTdElem->nSize * val->nElements]; + sal_Int8* pBufCur = buf; + + uno_Sequence* retSeq = NULL; + switch (pTdElem->eTypeClass) + { + case TypeClass_SEQUENCE: + { + Type _tElem(pTdElem->pWeakRef); + for (int i = 0; i < val->nElements; i++) + { + uno_Sequence* seq = cloneSequence( + *(uno_Sequence**) (&val->elements + i * pTdElem->nSize), + _tElem); + *((uno_Sequence**) pBufCur) = seq; + pBufCur += pTdElem->nSize; + } + break; + } + default: + uno_type_sequence_construct( + &retSeq, type.getTypeLibType(), (void*) val->elements, + val->nElements, reinterpret_cast< uno_AcquireFunc >(cpp_acquire)); + break; + } + delete[] buf; + return retSeq; +} + +template< class T> +Sequence<T> cloneSequence(const Sequence<T>& val) +{ + Sequence<T> seq( cloneSequence(val.get(), getCppuType(&val)), SAL_NO_ACQUIRE); + return seq; +} + +template< class T > +inline bool makeSurrogate( + Reference< T > & rOut, Reference< T > const & rOriginal ) +{ + rOut.clear(); + if (! rOriginal.is()) + return false; + + Environment aCppEnv_official; + Environment aUnoEnv_ano; + Environment aCppEnv_ano; + + OUString aCppEnvTypeName( + RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME) ); + OUString aUnoEnvTypeName( + RTL_CONSTASCII_USTRINGPARAM(UNO_LB_UNO) ); + // official: + uno_getEnvironment( + reinterpret_cast< uno_Environment ** >( &aCppEnv_official ), + aCppEnvTypeName.pData, 0 ); + // anonymous: + uno_createEnvironment( + reinterpret_cast< uno_Environment ** >( &aCppEnv_ano ), + aCppEnvTypeName.pData, 0 ); + uno_createEnvironment( + reinterpret_cast< uno_Environment ** >( &aUnoEnv_ano ), + aUnoEnvTypeName.pData, 0 ); + + UnoInterfaceReference unoI; + Mapping cpp2uno( aCppEnv_official.get(), aUnoEnv_ano.get() ); + Mapping uno2cpp( aUnoEnv_ano.get(), aCppEnv_ano.get() ); + if (!cpp2uno.is() || !uno2cpp.is()) + { + throw RuntimeException( + OUSTR("cannot get C++-UNO mappings!"), + Reference< XInterface >() ); + } + cpp2uno.mapInterface( + reinterpret_cast< void ** >( &unoI.m_pUnoI ), + rOriginal.get(), ::getCppuType( &rOriginal ) ); + if (! unoI.is()) + { + throw RuntimeException( + OUSTR("mapping C++ to binary UNO failed!"), + Reference< XInterface >() ); + } + uno2cpp.mapInterface( + reinterpret_cast< void ** >( &rOut ), + unoI.get(), ::getCppuType( &rOriginal ) ); + if (! rOut.is()) + { + throw RuntimeException( + OUSTR("mapping binary UNO to C++ failed!"), + Reference< XInterface >() ); + } + + return rOut.is(); +} + +//================================================================================================== +sal_Int32 TestBridgeImpl::run( const Sequence< OUString > & rArgs ) + throw (RuntimeException) +{ + bool bRet = false; + try + { + if (! rArgs.getLength()) + { + throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM( + "no test object specified!\n" + "usage : ServiceName of test object | -u unourl of test object\n" ) ), + Reference< XInterface >() ); + } + + Reference< XInterface > xOriginal; + bool remote; + sal_Int32 i; + if( rArgs.getLength() > 1 && 0 == rArgs[0].compareToAscii( "-u" ) ) + { + remote = true; + i = 2; + } + else + { + remote = false; + i = 1; + } + bool noCurrentContext = false; + if (i < rArgs.getLength() + && rArgs[i].equalsAsciiL( + RTL_CONSTASCII_STRINGPARAM("noCurrentContext"))) + { + noCurrentContext = true; + ++i; + } + bool stress = false; + if (i < rArgs.getLength() + && rArgs[i].equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("stress"))) + { + stress = true; + ++i; + } + + for (;;) { + Reference< XInterface > o; + if (remote) { + o = UnoUrlResolver::create(m_xContext)->resolve(rArgs[1]); + } else { + o = m_xContext->getServiceManager()->createInstanceWithContext( + rArgs[0], m_xContext); + } + if (!stress) { + xOriginal = o; + break; + } + } + + if (! xOriginal.is()) + { + throw RuntimeException( + OUString( RTL_CONSTASCII_USTRINGPARAM( + "cannot get test object!") ), + Reference< XInterface >() ); + } + Reference< XBridgeTest > xTest( xOriginal, UNO_QUERY ); + if (! xTest.is()) + { + throw RuntimeException( + OUString( RTL_CONSTASCII_USTRINGPARAM("test object does not implement XBridgeTest!") ), + Reference< XInterface >() ); + } + + Reference<XBridgeTest > xLBT; + bRet = check( makeSurrogate( xLBT, xTest ), "makeSurrogate" ); + bRet = check( + performTest( m_xContext, xLBT, noCurrentContext ), "standard test" ) + && bRet; + bRet = check( raiseException( xLBT ) , "exception test" )&& bRet; + bRet = check( raiseOnewayException( xLBT ), + "oneway exception test" ) && bRet; + bRet = performQueryForUnknownType( xLBT ) && bRet; + if (! bRet) + { + throw RuntimeException( + OUString( RTL_CONSTASCII_USTRINGPARAM("error: test failed!") ), + Reference< XInterface >() ); + } + } + catch (Exception & exc) + { + OString cstr( OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) ); + fprintf( stderr, "exception occured: %s\n", cstr.getStr() ); + throw; + } + + if( bRet ) + { + printf( "\n\n ### test succeeded!\n" ); + } + else + { + printf( "\n> ### test failed!\n" ); + } + + return 0; +} + +// XServiceInfo +//__________________________________________________________________________________________________ +OUString TestBridgeImpl::getImplementationName() + throw (RuntimeException) +{ + return OUString( RTL_CONSTASCII_USTRINGPARAM(IMPLNAME) ); +} +//__________________________________________________________________________________________________ +sal_Bool TestBridgeImpl::supportsService( const OUString & rServiceName ) + throw (RuntimeException) +{ + const Sequence< OUString > & rSNL = getSupportedServiceNames(); + const OUString * pArray = rSNL.getConstArray(); + for ( sal_Int32 nPos = rSNL.getLength(); nPos--; ) + { + if (pArray[nPos] == rServiceName) + return sal_True; + } + return sal_False; +} +//__________________________________________________________________________________________________ +Sequence< OUString > TestBridgeImpl::getSupportedServiceNames() + throw (RuntimeException) +{ + return bridge_test::getSupportedServiceNames(); +} + +// ... + +//================================================================================================== +static Reference< XInterface > SAL_CALL TestBridgeImpl_create( + const Reference< XComponentContext > & xContext ) +{ + return Reference< XInterface >( + static_cast< OWeakObject * >( new TestBridgeImpl( xContext ) ) ); +} + +} + +extern "C" +{ +//================================================================================================== +void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** ) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} +//================================================================================================== +sal_Bool SAL_CALL component_writeInfo( void *, void * pRegistryKey ) +{ + if (pRegistryKey) + { + try + { + Reference< XRegistryKey > xNewKey( + reinterpret_cast< XRegistryKey * >( pRegistryKey )->createKey( + OUString( RTL_CONSTASCII_USTRINGPARAM("/" IMPLNAME "/UNO/SERVICES") ) ) ); + xNewKey->createKey( OUString( RTL_CONSTASCII_USTRINGPARAM(SERVICENAME) ) ); + + return sal_True; + } + catch (InvalidRegistryException &) + { + OSL_ENSURE( sal_False, "### InvalidRegistryException!" ); + } + } + return sal_False; +} +//================================================================================================== +void * SAL_CALL component_getFactory( + const sal_Char * pImplName, void * pServiceManager, void * ) +{ + void * pRet = 0; + + if (pServiceManager && rtl_str_compare( pImplName, IMPLNAME ) == 0) + { + Reference< XInterface > xFactory( + createSingleComponentFactory( + bridge_test::TestBridgeImpl_create, + OUString( RTL_CONSTASCII_USTRINGPARAM(IMPLNAME) ), + bridge_test::getSupportedServiceNames() ) ); + + if (xFactory.is()) + { + xFactory->acquire(); + pRet = xFactory.get(); + } + } + + return pRet; +} +} |