diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 05:54:39 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 05:54:39 +0000 |
commit | 267c6f2ac71f92999e969232431ba04678e7437e (patch) | |
tree | 358c9467650e1d0a1d7227a21dac2e3d08b622b2 /stoc/test | |
parent | Initial commit. (diff) | |
download | libreoffice-267c6f2ac71f92999e969232431ba04678e7437e.tar.xz libreoffice-267c6f2ac71f92999e969232431ba04678e7437e.zip |
Adding upstream version 4:24.2.0.upstream/4%24.2.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'stoc/test')
43 files changed, 9611 insertions, 0 deletions
diff --git a/stoc/test/dump.cxx b/stoc/test/dump.cxx new file mode 100644 index 0000000000..798e05acc2 --- /dev/null +++ b/stoc/test/dump.cxx @@ -0,0 +1,152 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <sal/config.h> + +#include <com/sun/star/beans/PropertyChangeEvent.hpp> +#include <com/sun/star/reflection/Dump.hpp> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/uno/TypeClass.hpp> +#include <cppuhelper/bootstrap.hxx> +#include <cppunit/TestAssert.h> +#include <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/plugin/TestPlugIn.h> +#include <test/codemaker/cppumaker/ByteBits.hpp> +#include <test/codemaker/cppumaker/Constants.hpp> +#include <test/codemaker/cppumaker/ShortBits.hpp> +#include <test/codemaker/cppumaker/UnsignedHyperBits.hpp> + +namespace +{ +class Dump : public CppUnit::TestFixture +{ +public: + void setUp() override + { + dump_ = css::reflection::Dump::get(cppu::defaultBootstrap_InitialComponentContext()); + } + + void testSequence() + { + CPPUNIT_ASSERT_EQUAL(OUString("[]"), + dump_->dumpValue(css::uno::Any(css::uno::Sequence<sal_Int32>{}))); + CPPUNIT_ASSERT_EQUAL(OUString("[1]"), + dump_->dumpValue(css::uno::Any(css::uno::Sequence<sal_Int32>{ 1 }))); + CPPUNIT_ASSERT_EQUAL(OUString("[1, 2, 3]"), dump_->dumpValue(css::uno::Any( + css::uno::Sequence<sal_Int32>{ 1, 2, 3 }))); + CPPUNIT_ASSERT_EQUAL(OUString("[[long: 1], [string: \"2\"], [[]long: [1, 2]]]"), + (dump_->dumpValue(css::uno::Any(css::uno::Sequence<css::uno::Any>{ + css::uno::Any(sal_Int32(1)), css::uno::Any(OUString("2")), + css::uno::Any(css::uno::Sequence<sal_Int32>{ 1, 2 }) })))); + } + + void testEnum() + { + CPPUNIT_ASSERT_EQUAL(OUString("ENUM"), + dump_->dumpValue(css::uno::Any(css::uno::TypeClass_ENUM))); + CPPUNIT_ASSERT_EQUAL(OUString("-1"), + dump_->dumpValue(css::uno::Any(css::uno::TypeClass(-1)))); + CPPUNIT_ASSERT_EQUAL(OUString("12345"), + dump_->dumpValue(css::uno::Any(css::uno::TypeClass(12345)))); + } + + void testStruct() + { + CPPUNIT_ASSERT_EQUAL( + OUString("[Source: null, PropertyName: \"test\", Further: false, PropertyHandle: 3, " + "OldValue: [void: void], NewValue: [long: 5]]"), + dump_->dumpValue(css::uno::Any(css::beans::PropertyChangeEvent( + {}, "test", false, 3, {}, css::uno::Any(sal_Int32(5)))))); + } + + void testConstantsGroup() + { + CPPUNIT_ASSERT_EQUAL(OUString("byteMin"), + dump_->dumpConstant("test.codemaker.cppumaker.Constants", + css::uno::Any(sal_Int8(-128)))); + CPPUNIT_ASSERT_EQUAL(OUString("byteMax"), + dump_->dumpConstant("test.codemaker.cppumaker.Constants", + css::uno::Any(sal_Int8(127)))); + CPPUNIT_ASSERT_EQUAL(OUString("longMin"), + dump_->dumpConstant("test.codemaker.cppumaker.Constants", + css::uno::Any(sal_Int32(-2147483648)))); + CPPUNIT_ASSERT_EQUAL(OUString("longMax"), + dump_->dumpConstant("test.codemaker.cppumaker.Constants", + css::uno::Any(sal_Int32(2147483647)))); + CPPUNIT_ASSERT_EQUAL(OUString("hyperMin"), + dump_->dumpConstant("test.codemaker.cppumaker.Constants", + css::uno::Any(SAL_MIN_INT64))); + CPPUNIT_ASSERT_EQUAL(OUString("hyperMax"), + dump_->dumpConstant("test.codemaker.cppumaker.Constants", + css::uno::Any(SAL_MAX_INT64))); + CPPUNIT_ASSERT_EQUAL(OUString("17"), + dump_->dumpConstant("test.codemaker.cppumaker.Constants", + css::uno::Any(sal_Int32(17)))); + CPPUNIT_ASSERT_EQUAL(OUString("2147483646"), + dump_->dumpConstant("test.codemaker.cppumaker.Constants", + css::uno::Any(sal_Int32(2147483646)))); + + CPPUNIT_ASSERT_EQUAL(OUString("0"), dump_->dumpConstant("test.codemaker.cppumaker.ByteBits", + css::uno::Any(sal_Int8(0)))); + CPPUNIT_ASSERT_EQUAL( + OUString("BIT0+BIT2"), + dump_->dumpConstant("test.codemaker.cppumaker.ByteBits", css::uno::Any(sal_Int8(5)))); + CPPUNIT_ASSERT_EQUAL( + OUString("BIT4"), + dump_->dumpConstant("test.codemaker.cppumaker.ByteBits", css::uno::Any(sal_Int8(16)))); + CPPUNIT_ASSERT_EQUAL( + OUString("BIT0+BIT4"), + dump_->dumpConstant("test.codemaker.cppumaker.ByteBits", css::uno::Any(sal_Int8(17)))); + CPPUNIT_ASSERT_EQUAL(OUString("BIT7"), + dump_->dumpConstant("test.codemaker.cppumaker.ByteBits", + css::uno::Any(sal_Int8(-128)))); + CPPUNIT_ASSERT_EQUAL( + OUString("ALL"), + dump_->dumpConstant("test.codemaker.cppumaker.ByteBits", css::uno::Any(sal_Int8(-1)))); + + CPPUNIT_ASSERT_EQUAL(OUString("BIT7"), + dump_->dumpConstant("test.codemaker.cppumaker.ShortBits", + css::uno::Any(sal_Int16(128)))); + CPPUNIT_ASSERT_EQUAL(OUString("ALL"), + dump_->dumpConstant("test.codemaker.cppumaker.ShortBits", + css::uno::Any(sal_Int16(-1)))); + + CPPUNIT_ASSERT_EQUAL(OUString("BIT63"), + dump_->dumpConstant("test.codemaker.cppumaker.UnsignedHyperBits", + css::uno::Any(sal_uInt64(9223372036854775808u)))); + CPPUNIT_ASSERT_EQUAL(OUString("BIT0+BIT62"), + dump_->dumpConstant("test.codemaker.cppumaker.UnsignedHyperBits", + css::uno::Any(sal_uInt64(4611686018427387905)))); + CPPUNIT_ASSERT_EQUAL(OUString("BIT0+BIT63"), + dump_->dumpConstant("test.codemaker.cppumaker.UnsignedHyperBits", + css::uno::Any(sal_uInt64(9223372036854775809u)))); + CPPUNIT_ASSERT_EQUAL(OUString("ALL"), + dump_->dumpConstant("test.codemaker.cppumaker.UnsignedHyperBits", + css::uno::Any(SAL_MAX_UINT64))); + } + + CPPUNIT_TEST_SUITE(Dump); + CPPUNIT_TEST(testSequence); + CPPUNIT_TEST(testEnum); + CPPUNIT_TEST(testStruct); + CPPUNIT_TEST(testConstantsGroup); + CPPUNIT_TEST_SUITE_END(); + +private: + css::uno::Reference<css::reflection::XDump> dump_; +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(Dump); +} + +CPPUNIT_PLUGIN_IMPLEMENT(); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/stoc/test/javavm/jvm_interaction/interactionhandler.cxx b/stoc/test/javavm/jvm_interaction/interactionhandler.cxx new file mode 100644 index 0000000000..f1c4baf863 --- /dev/null +++ b/stoc/test/javavm/jvm_interaction/interactionhandler.cxx @@ -0,0 +1,186 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#include <jni.h> + +#include <stdio.h> +#include <sal/main.h> +#include <rtl/process.h> + +#include <cppuhelper/servicefactory.hxx> +#include <cppuhelper/weak.hxx> +#include <cppuhelper/bootstrap.hxx> +#include <osl/thread.h> + +#include <com/sun/star/registry/XSimpleRegistry.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/lang/XMultiComponentFactory.hpp> +#include <com/sun/star/java/XJavaVM.hpp> +#include <com/sun/star/registry/XImplementationRegistration.hpp> +#include <com/sun/star/java/XJavaThreadRegister_11.hpp> + +#include <com/sun/star/uno/XCurrentContext.hpp> +#include <com/sun/star/task/XInteractionHandler.hpp> +#include <com/sun/star/task/XInteractionRequest.hpp> +#include <com/sun/star/task/XInteractionContinuation.hpp> +#include <com/sun/star/task/XInteractionAbort.hpp> +#include <com/sun/star/task/XInteractionRetry.hpp> +#include <com/sun/star/java/JavaNotConfiguredException.hpp> +#include <com/sun/star/java/MissingJavaRuntimeException.hpp> +#include <com/sun/star/java/JavaDisabledException.hpp> +#include <com/sun/star/java/JavaVMCreationFailureException.hpp> +#include <cppuhelper/implbase.hxx> +#include <uno/current_context.hxx> + +using namespace cppu; +using namespace css::uno; +using namespace css::lang; +using namespace css::registry; +using namespace css::java; +using namespace css::task; + + +#define INTERACTION_HANDLER_NAME "java-vm.interaction-handler" + +class Context: public WeakImplHelper<XCurrentContext> +{ + virtual Any SAL_CALL getValueByName( const OUString& Name ) throw (RuntimeException); +}; + +class InteractionHandler: public WeakImplHelper<XInteractionHandler> +{ + virtual void SAL_CALL handle( const Reference< XInteractionRequest >& Request ) + throw (RuntimeException); +}; + +Any SAL_CALL Context::getValueByName( const OUString& Name) throw (RuntimeException) +{ + Any retVal; + if( Name.equals( INTERACTION_HANDLER_NAME)) + { + Reference<XInteractionHandler> handler(new InteractionHandler()); + retVal <<= handler; + } + return retVal; +} + +void SAL_CALL InteractionHandler::handle( const Reference< XInteractionRequest >& Request ) + throw (RuntimeException) +{ + Any anyExc= Request->getRequest(); + Sequence<Reference< XInteractionContinuation> >seqCont= Request->getContinuations(); + + Reference<XInteractionAbort> abort; + Reference<XInteractionRetry> retry; + + for (sal_Int32 i= 0; i < seqCont.getLength(); i++) + { + abort.set( seqCont[i], UNO_QUERY ); + if(abort.is()) + break; + } + for (sal_Int32 i= 0; i < seqCont.getLength(); i++) + { + retry.set( seqCont[i], UNO_QUERY ); + if(retry.is()) + break; + } + + static int cRetry= 0; + + if( cRetry++ == 5) + { + if( abort.is()) + abort->select(); + return; + } + if( retry.is()) + retry->select(); +} + +sal_Bool test1(const Reference< XMultiServiceFactory > & xMgr ) +{ + sal_Bool retVal= sal_True; + setCurrentContext(Reference<XCurrentContext>(new Context()); + + OUString sVMService("com.sun.star.java.JavaVirtualMachine"); + Reference<XInterface> xXInt= xMgr->createInstance(sVMService); + if( ! xXInt.is()) + return sal_False; + Reference<XJavaVM> xVM( xXInt, UNO_QUERY); + if( ! xVM.is()) + return sal_False; + + + sal_Int8 arId[16]; + rtl_getGlobalProcessId((sal_uInt8*) arId); + + Any anyVM; + try + { + anyVM = xVM->getJavaVM( Sequence<sal_Int8>(arId, 16)); + } + catch (const JavaNotConfiguredException& e) + { + OString msg= OUStringToOString(e.Message, osl_getThreadTextEncoding()); + printf("JavaNotConfiguredException: %s\n", msg.getStr()); + } + catch (const JavaVMCreationFailureException& e) + { + OString msg= OUStringToOString(e.Message, osl_getThreadTextEncoding()); + printf("JavaVMCreationFailureException: %s\n", msg.getStr()); + } + catch (const MissingJavaRuntimeException& e) + { + OString msg= OUStringToOString(e.Message, osl_getThreadTextEncoding()); + printf("MissingJavaRuntimeException: %s\n", msg.getStr()); + } + catch (const JavaDisabledException& e) + { + OString msg= OUStringToOString(e.Message, osl_getThreadTextEncoding()); + printf("JavaDisabledException: %s\n", msg.getStr()); + } + catch (const RuntimeException & e) + { + OString msg= OUStringToOString(e.Message, osl_getThreadTextEncoding()); + printf("###RuntimeException: %s\n", msg.getStr()); + retVal= sal_False; + } + return retVal; +} + +SAL_IMPLEMENT_MAIN() +{ + Reference<XSimpleRegistry> xreg= createSimpleRegistry(); + xreg->open( OUString("applicat.rdb"), + sal_False, sal_False ); + + Reference< XComponentContext > context= bootstrap_InitialComponentContext(xreg); + Reference<XMultiComponentFactory> fac= context->getServiceManager(); + Reference<XMultiServiceFactory> xMgr( fac, UNO_QUERY); + + sal_Bool bSucc = test1(xMgr); + Reference< XComponent > xCompContext( context, UNO_QUERY ); + xCompContext->dispose(); + return (bSucc ? 0 : -1); +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/stoc/test/javavm/jvm_interaction/makefile.mk b/stoc/test/javavm/jvm_interaction/makefile.mk new file mode 100644 index 0000000000..c9c1084a52 --- /dev/null +++ b/stoc/test/javavm/jvm_interaction/makefile.mk @@ -0,0 +1,71 @@ +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you under the Apache +# License, Version 2.0 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.apache.org/licenses/LICENSE-2.0 . +# +PRJ=..$/..$/.. +TARGET= jvminteraction +PRJNAME= stoc +TARGET6= $(TARGET) +TARGETTYPE= CUI +LIBTARGET= NO +ENABLE_EXCEPTIONS=TRUE + +UNOUCRDEP= $(SOLARBINDIR)$/udkapi.rdb +UNOUCRRDB= $(SOLARBINDIR)$/udkapi.rdb +UNOUCROUT= $(OUT)$/inc$ +INCPRE+= $(OUT)$/inc$ + + + +# --- Settings ----------------------------------------------------- +.INCLUDE : settings.mk + +# --- Application 6 - testjavavm ------------------------------------ + +UNOTYPES= com.sun.star.lang.XMultiComponentFactory \ + com.sun.star.uno.XWeak \ + com.sun.star.java.XJavaVM \ + com.sun.star.java.XJavaThreadRegister_11 \ + com.sun.star.java.JavaNotConfiguredException \ + com.sun.star.java.MissingJavaRuntimeException \ + com.sun.star.java.JavaDisabledException \ + com.sun.star.java.JavaVMCreationFailureException \ + com.sun.star.registry.XSimpleRegistry \ + com.sun.star.lang.XComponent \ + com.sun.star.registry.XImplementationRegistration \ + com.sun.star.lang.XSingleServiceFactory \ + com.sun.star.uno.TypeClass \ + com.sun.star.lang.XMultiServiceFactory \ + com.sun.star.uno.XCurrentContext \ + com.sun.star.task.XInteractionHandler \ + com.sun.star.task.XInteractionRequest \ + com.sun.star.task.XInteractionContinuation \ + com.sun.star.task.XInteractionAbort \ + com.sun.star.task.XInteractionRetry \ + + +APP6TARGET= $(TARGET6) +APP6OBJS = $(OBJ)$/interactionhandler.obj +APP6STDLIBS= \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(SALHELPERLIB) \ + $(SALLIB) + +# --- Target ------------------------------------------------ + +.INCLUDE : target.mk + diff --git a/stoc/test/javavm/makefile.mk b/stoc/test/javavm/makefile.mk new file mode 100644 index 0000000000..eb0ffb7619 --- /dev/null +++ b/stoc/test/javavm/makefile.mk @@ -0,0 +1,59 @@ +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you under the Apache +# License, Version 2.0 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.apache.org/licenses/LICENSE-2.0 . +# +PRJ=..$/.. +TARGET= testjavavm +PRJNAME= stoc +TARGET6= testjavavm +TARGETTYPE= CUI +LIBTARGET= NO +ENABLE_EXCEPTIONS=TRUE + +UNOUCRDEP= $(SOLARBINDIR)$/udkapi.rdb +UNOUCRRDB= $(SOLARBINDIR)$/udkapi.rdb +UNOUCROUT= $(OUT)$/inc$ +INCPRE+= $(OUT)$/inc$ + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +# --- Application 6 - testjavavm ------------------------------------ + +UNOTYPES= com.sun.star.lang.XMultiComponentFactory \ + com.sun.star.uno.XWeak \ + com.sun.star.java.XJavaVM \ + com.sun.star.java.XJavaThreadRegister_11 \ + com.sun.star.registry.XSimpleRegistry \ + com.sun.star.lang.XComponent \ + com.sun.star.registry.XImplementationRegistration \ + com.sun.star.lang.XSingleServiceFactory \ + com.sun.star.uno.TypeClass \ + com.sun.star.lang.XMultiServiceFactory + +APP6TARGET= $(TARGET6) +APP6OBJS = $(OBJ)$/testjavavm.obj +APP6STDLIBS= \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(SALHELPERLIB) \ + $(SALLIB) + +# --- Target ------------------------------------------------ + +.INCLUDE : target.mk + diff --git a/stoc/test/javavm/testapplet/TestApplet.html b/stoc/test/javavm/testapplet/TestApplet.html new file mode 100644 index 0000000000..e83d2ffe7d --- /dev/null +++ b/stoc/test/javavm/testapplet/TestApplet.html @@ -0,0 +1,19 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> +<HTML> +<HEAD> + <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1252"> + <TITLE>A Clock (1.1)</TITLE> + <META NAME="GENERATOR" CONTENT="StarOffice 6.0 (Win32)"> + <META NAME="CREATED" CONTENT="20011119;12262427"> + <META NAME="CHANGED" CONTENT="16010101;0"> +</HEAD> +<BODY LANG="de-DE"> +<H1>TestApplet</H1> +<HR> +<P> +<APPLET CODE="TestApplet.class" ALIGN=BOTTOM WIDTH=170 HEIGHT=150> +</APPLET> +</P> + +</BODY> +</HTML>
\ No newline at end of file diff --git a/stoc/test/javavm/testapplet/TestApplet.java b/stoc/test/javavm/testapplet/TestApplet.java new file mode 100644 index 0000000000..e271f4dd1f --- /dev/null +++ b/stoc/test/javavm/testapplet/TestApplet.java @@ -0,0 +1,53 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +import java.awt.Color; +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.net.MalformedURLException; + +public class TestApplet extends java.applet.Applet { + + /** Initialization method that will be called after the applet is loaded + * into the browser. + */ + @Override + public void init () { + setBackground( Color.green); + resize( 300, 300); + + // Security tests. + File f= new File("d:\\temp\\javasecurity.txt"); + try { + f.createNewFile(); + + // local connection + URL url= new URL("http://localhost:8080/index.html"); + url.openStream(); + // remote connection + url= new URL("http://www.w3.org/index.html"); + url.openStream(); + }catch( MalformedURLException mue) { + }catch( IOException e) { + String s= e.getMessage(); + System.out.println(s); + } + + } +} diff --git a/stoc/test/javavm/testapplet/makefile.mk b/stoc/test/javavm/testapplet/makefile.mk new file mode 100644 index 0000000000..c2b5a2001f --- /dev/null +++ b/stoc/test/javavm/testapplet/makefile.mk @@ -0,0 +1,43 @@ +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you under the Apache +# License, Version 2.0 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.apache.org/licenses/LICENSE-2.0 . +# + +PRJ=..$/..$/.. + +PRJNAME = testapplet +PACKAGE = +TARGET = TestApplet + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +# Files -------------------------------------------------------- + +JARFILES = ridl.jar jurt.jar unoil.jar + +JAVAFILES= $(subst,$(CLASSDIR)$/$(PACKAGE)$/, $(subst,.class,.java $(JAVACLASSFILES))) + + +JAVACLASSFILES= \ + $(CLASSDIR)$/$(PACKAGE)$/TestApplet.class + +JARCLASSDIRS= . + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/stoc/test/javavm/testcomponent/TestComponent.java b/stoc/test/javavm/testcomponent/TestComponent.java new file mode 100644 index 0000000000..d976323c5f --- /dev/null +++ b/stoc/test/javavm/testcomponent/TestComponent.java @@ -0,0 +1,129 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +import com.sun.star.comp.loader.FactoryHelper; +import com.sun.star.lang.*; +import com.sun.star.uno.*; +import com.sun.star.registry.XRegistryKey; +import java.io.*; +import java.net.*; + + +/** This component implements XTypeProvider for use with StarBasic. + * The XServiceInfo is implemented to have an interface in which we can put some + * code just for the sake of debugging. + * + * To debug with JPDA (jdk 1.3), put these lines in the java.ini within the [Java] section: + * -Xdebug + * -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=y + * + * When the Virtual Machine service is instantiated it will block until the debugger + * attaches to it on port 8000. You can chose a different port. You attach to the VM using + * jdb by + * + * jdb -connect com.sun.jdi.SocketAttach:hostname=myhost,port=8000 + * + * myhost is the hostname where the VM is running. +*/ +public class TestComponent implements XServiceInfo, XTypeProvider +{ + public static final String __serviceName="JavaTestComponent"; + + // XTypeProvider + public com.sun.star.uno.Type[] getTypes( ) + { + Type[] retValue= new Type[2]; + retValue[0]= new Type( XServiceInfo.class); + retValue[1]= new Type( XTypeProvider.class); + return retValue; + } + // XTypeProvider + public byte[] getImplementationId( ) + { + return new byte[0]; + } + + + // XServiceName + public String getImplementationName( ) + { + // the functions are for debugging + + // Test security settings + File f= new File("c:/temp/javasecurity.txt"); + try { + f.createNewFile(); + + // local connection + URL url= new URL("http://localhost:8080/index.html"); + url.openStream(); + // remote connection + url= new URL("http://www.w3.org/index.html"); + url.openStream(); + }catch( MalformedURLException mue) { + }catch( IOException e) { + String s= e.getMessage(); + System.out.println(s); + } + + return __serviceName; + } + // XServiceName + public boolean supportsService( /*IN*/String ServiceName ) + { + + return false; + } + + //XServiceName + public String[] getSupportedServiceNames( ) + { + String[] retValue= new String[0]; + return retValue; + } + + public static XSingleServiceFactory __getServiceFactory(String implName, + XMultiServiceFactory multiFactory, + XRegistryKey regKey) + { + XSingleServiceFactory xSingleServiceFactory = null; + + if (implName.equals( TestComponent.class.getName()) ) + xSingleServiceFactory = FactoryHelper.getServiceFactory( TestComponent.class, + TestComponent.__serviceName, + multiFactory, + regKey); + + return xSingleServiceFactory; + } + + /** + * Writes the service information into the given registry key. + * This method is called by the <code>JavaLoader</code> + * <p> + * @return returns true if the operation succeeded + * @param regKey the registryKey + * @see com.sun.star.comp.loader.JavaLoader + */ + public static boolean __writeRegistryServiceInfo(XRegistryKey regKey) + { + return FactoryHelper.writeRegistryServiceInfo( TestComponent.class.getName(), + TestComponent.__serviceName, regKey); + } + +} diff --git a/stoc/test/javavm/testcomponent/makefile.mk b/stoc/test/javavm/testcomponent/makefile.mk new file mode 100644 index 0000000000..89ae042adc --- /dev/null +++ b/stoc/test/javavm/testcomponent/makefile.mk @@ -0,0 +1,45 @@ +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you under the Apache +# License, Version 2.0 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.apache.org/licenses/LICENSE-2.0 . +# + +PRJ=..$/..$/.. + +PRJNAME = testcomponent +PACKAGE = +TARGET = JavaTestComponent + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +# Files -------------------------------------------------------- + +JARFILES = ridl.jar jurt.jar unoil.jar + +CUSTOMMANIFESTFILE= manifest + +JARTARGET = $(TARGET).jar + +JAVAFILES= \ + TestComponent.java + + +JAVACLASSFILES = $(foreach,i,$(JAVAFILES) $(CLASSDIR)$/$(PACKAGE)$/$(i:b).class) + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/stoc/test/javavm/testcomponent/manifest b/stoc/test/javavm/testcomponent/manifest new file mode 100644 index 0000000000..1763d7bb95 --- /dev/null +++ b/stoc/test/javavm/testcomponent/manifest @@ -0,0 +1 @@ +RegistrationClassName: TestComponent diff --git a/stoc/test/javavm/testjavavm.cxx b/stoc/test/javavm/testjavavm.cxx new file mode 100644 index 0000000000..0e243f62d3 --- /dev/null +++ b/stoc/test/javavm/testjavavm.cxx @@ -0,0 +1,151 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#include <jni.h> + +#include <stdio.h> +#include <sal/main.h> +#include <sal/log.hxx> +#include <rtl/process.h> + +#include <cppuhelper/servicefactory.hxx> +#include <cppuhelper/weak.hxx> +#include <cppuhelper/bootstrap.hxx> + +#include <com/sun/star/registry/XSimpleRegistry.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/lang/XMultiComponentFactory.hpp> +#include <com/sun/star/java/XJavaVM.hpp> +#include <com/sun/star/registry/XImplementationRegistration.hpp> +#include <com/sun/star/java/XJavaThreadRegister_11.hpp> + +using namespace cppu; +using namespace css::uno; +using namespace css::lang; +using namespace css::registry; +using namespace css::java; + + +sal_Bool testJavaVM(const Reference< XMultiServiceFactory > & xMgr ) +{ + + OUString sVMService("com.sun.star.java.JavaVirtualMachine"); + Reference<XInterface> xXInt= xMgr->createInstance(sVMService); + if( ! xXInt.is()) + return sal_False; + Reference<XJavaVM> xVM( xXInt, UNO_QUERY); + if( ! xVM.is()) + return sal_False; + Reference<XJavaThreadRegister_11> xreg11(xVM, UNO_QUERY); + if( ! xreg11.is()) + return sal_False; + + + sal_Int8 arId[16]; + rtl_getGlobalProcessId((sal_uInt8*) arId); + Any anyVM = xVM->getJavaVM( Sequence<sal_Int8>(arId, 16)); + if ( ! anyVM.hasValue()) + { + OSL_FAIL("could not get Java VM"); + return sal_False; + } + + sal_Bool b= xreg11->isThreadAttached(); + xreg11->registerThread(); + b= xreg11->isThreadAttached(); + xreg11->revokeThread(); + b= xreg11->isThreadAttached(); + + + b= xVM->isVMEnabled(); + b= xVM->isVMStarted(); + + + b= xVM->isVMEnabled(); + b= xVM->isVMStarted(); + + + JavaVM* _jvm= *(JavaVM**) anyVM.getValue(); + JNIEnv *p_env; + if( _jvm->AttachCurrentThread((void**) &p_env, 0)) + return sal_False; + + jclass cls = p_env->FindClass( "TestJavaVM"); + if (cls == 0) { + SAL_WARN("stoc", "Can't find Prog class"); + exit(1); + } + + jmethodID id = p_env->GetStaticMethodID( cls, "getInt", "()I"); + if( id) + { + p_env->CallStaticIntMethod(cls, id); + } + + if( p_env->ExceptionOccurred()){ + p_env->ExceptionDescribe(); + p_env->ExceptionClear(); + } + + + _jvm->DetachCurrentThread(); + return sal_True; +} + +SAL_IMPLEMENT_MAIN() +{ + Reference<XSimpleRegistry> xreg= createSimpleRegistry(); + xreg->open( OUString("applicat.rdb"), + sal_False, sal_False ); + + Reference< XComponentContext > context= bootstrap_InitialComponentContext(xreg); + Reference<XMultiComponentFactory> fac= context->getServiceManager(); + Reference<XMultiServiceFactory> xMgr( fac, UNO_QUERY); + + sal_Bool bSucc = sal_False; + try + { + OUString sImplReg( + "com.sun.star.registry.ImplementationRegistration"); + Reference<css::registry::XImplementationRegistration> xImplReg( + xMgr->createInstance( sImplReg ), UNO_QUERY ); + OSL_ENSURE( xImplReg.is(), "### no impl reg!" ); + + + OUString sLibLoader("com.sun.star.loader.SharedLibrary"); + OUString sJenLib( "javavm.uno" SAL_DLLEXTENSION ); + xImplReg->registerImplementation( + sLibLoader, sJenLib, Reference< XSimpleRegistry >() ); + + bSucc = testJavaVM( xMgr ); + } + catch (const Exception & rExc) + { + DBG_UNHANDLED_EXCEPTION("stoc", "### exception occurred: " << rExc ); + } + + Reference< XComponent > xCompContext( context, UNO_QUERY ); + xCompContext->dispose(); + printf("javavm %s", bSucc ? "succeeded" : "failed"); + return (bSucc ? 0 : -1); +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/stoc/test/javavm/testjavavm.java b/stoc/test/javavm/testjavavm.java new file mode 100644 index 0000000000..9309843b08 --- /dev/null +++ b/stoc/test/javavm/testjavavm.java @@ -0,0 +1,30 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +class TestJavaVM +{ + public static int getInt() + { + return 100; + } + + public static void main( String args[]) + { + System.out.println("Hello World"); + } +} diff --git a/stoc/test/language_binding.idl b/stoc/test/language_binding.idl new file mode 100644 index 0000000000..db568f077d --- /dev/null +++ b/stoc/test/language_binding.idl @@ -0,0 +1,155 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +module test +{ + +enum TestEnum +{ + TEST, + ONE, + TWO, + CHECK, + LOLA, + PALOO, + ZA +}; + +/** + * simple c++ types + */ +struct TestSimple +{ + boolean Bool; + char Char; + byte Byte; + short Short; + unsigned short UShort; + long Long; + unsigned long ULong; + hyper Hyper; + unsigned hyper UHyper; + float Float; + double Double; + test::TestEnum Enum; +}; +/** + * complex c++ types + */ +struct TestElement : test::TestSimple +{ + string String; + com::sun::star::uno::XInterface Interface; + any Any; +}; +struct TestDataElements : test::TestElement +{ + sequence<test::TestElement > Sequence; +}; + +typedef TestDataElements TestData; + +/** Monster test interface to test language binding calls. */ +interface XLBTestBase : com::sun::star::uno::XInterface +{ + /** + * in parameter test, tests by calls reference also (complex types) + */ + void setValues( [in] boolean bBool, [in] char cChar, [in] byte nByte, + [in] short nShort, [in] unsigned short nUShort, + [in] long nLong, [in] unsigned long nULong, + [in] hyper nHyper, [in] unsigned hyper nUHyper, + [in] float fFloat, [in] double fDouble, + [in] test::TestEnum eEnum, [in] string aString, + [in] com::sun::star::uno::XInterface xInterface, [in] any aAny, + [in] sequence<test::TestElement > aSequence, + [in] test::TestData aStruct ); + /** + * inout parameter test + */ + test::TestData setValues2( [inout] boolean bBool, [inout] char cChar, [inout] byte nByte, + [inout] short nShort, [inout] unsigned short nUShort, + [inout] long nLong, [inout] unsigned long nULong, + [inout] hyper nHyper, [inout] unsigned hyper nUHyper, + [inout] float fFloat, [inout] double fDouble, + [inout] test::TestEnum eEnum, [inout] string aString, + [inout] com::sun::star::uno::XInterface xInterface, [inout] any aAny, + [inout] sequence<test::TestElement > aSequence, + [inout] test::TestData aStruct ); + + /** + * out parameter test + */ + test::TestData getValues( [out] boolean bBool, [out] char cChar, [out] byte nByte, + [out] short nShort, [out] unsigned short nUShort, + [out] long nLong, [out] unsigned long nULong, + [out] hyper nHyper, [out] unsigned hyper nUHyper, + [out] float fFloat, [out] double fDouble, + [out] test::TestEnum eEnum, [out] string aString, + [out] com::sun::star::uno::XInterface xInterface, [out] any aAny, + [out] sequence<test::TestElement > aSequence, + [out] test::TestData aStruct ); + + [attribute] boolean Bool; + [attribute] byte Byte; + [attribute] char Char; + [attribute] short Short; + [attribute] unsigned short UShort; + [attribute] long Long; + [attribute] unsigned long ULong; + [attribute] hyper Hyper; + [attribute] unsigned hyper UHyper; + [attribute] float Float; + [attribute] double Double; + [attribute] test::TestEnum Enum; + [attribute] string String; + [attribute] com::sun::star::uno::XInterface Interface; + [attribute] any Any; + [attribute] sequence<test::TestElement > Sequence; + [attribute] test::TestData Struct; +}; + + +/** Inheriting from monster; adds raiseException(). */ +interface XLanguageBindingTest : test::XLBTestBase +{ + /** + * params are there only for dummy, to test if all temp out params will be released. + */ + test::TestData raiseException( [out] boolean bBool, [out] char cChar, [out] byte nByte, + [out] short nShort, [out] unsigned short nUShort, + [out] long nLong, [out] unsigned long nULong, + [out] hyper nHyper, [out] unsigned hyper nUHyper, + [out] float fFloat, [out] double fDouble, + [out] test::TestEnum eEnum, [out] string aString, + [out] com::sun::star::uno::XInterface xInterface, [out] any aAny, + [out] sequence<test::TestElement > aSequence, + [out] test::TestData aStruct ) + raises( com::sun::star::lang::IllegalArgumentException ); + + /** + * raises runtime exception + */ + [attribute] long RuntimeException; +}; + +}; // test + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/stoc/test/makefile.mk b/stoc/test/makefile.mk new file mode 100644 index 0000000000..97c5950a35 --- /dev/null +++ b/stoc/test/makefile.mk @@ -0,0 +1,213 @@ +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you under the Apache +# License, Version 2.0 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.apache.org/licenses/LICENSE-2.0 . +# + +PRJ=.. + +PRJNAME=stoc +TARGET=stoc +TARGET1=testloader +TARGET2=testregistry +TARGET3=testsmgr +TARGET4=testcorefl +TARGET5=testinvocation +TARGET6=testintrosp +TARGET7=testconv +TARGET8=testproxyfac +TARGET9=testsmgr2 +TARGETTYPE=CUI + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +# --- smgr component ----------------------------------------------- +SHL1OBJS= \ + $(OBJ)$/testsmgr_cpnt.obj + +SHL1STDLIBS= \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(SALHELPERLIB) \ + $(SALLIB) + +SHL1TARGET=testsmgr_component +SHL1DEPN= +SHL1IMPLIB=i$(SHL1TARGET) +SHL1DEF=$(MISC)$/$(SHL1TARGET).def +DEF1NAME=$(SHL1TARGET) +SHL1VERSIONMAP=testsmgr_cpnt.map + +# --- Application 1 ------------------------------------------------ +APP1TARGET= $(TARGET1) +APP1OBJS= $(OBJ)$/testloader.obj + +APP1STDLIBS= \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(SALHELPERLIB) \ + $(SALLIB) + +# --- Application 2 ------------------------------------------------ +APP2TARGET= $(TARGET2) +APP2OBJS= $(OBJ)$/testregistry.obj $(OBJ)$/mergekeys_.obj + +APP2STDLIBS= \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(SALHELPERLIB) \ + $(REGLIB) \ + $(SALLIB) + +# --- Application 3 - testsmgr main ------------------------------------ +APP3TARGET= $(TARGET3) +APP3OBJS = $(OBJ)$/testsmgr.obj +APP3STDLIBS= \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(SALHELPERLIB) \ + $(REGLIB) \ + $(SALLIB) + +.IF "$(OS)"!="WNT" +APP3STDLIBS+= -l$(SHL1TARGET) +.ENDIF +.IF "$(OS)"=="WNT" +APP3STDLIBS+= i$(SHL1TARGET).lib +.ENDIF + +# --- Application 4 - testcorefl main ------------------------------------ +APP4TARGET= $(TARGET4) +APP4OBJS = $(OBJ)$/testcorefl.obj +APP4STDLIBS= \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(SALLIB) + +# --- Application 5 - testinvocation main ------------------------------------ +APP5TARGET= $(TARGET5) +APP5OBJS = $(OBJ)$/testiadapter.obj +APP5STDLIBS= \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(SALLIB) + +# --- Application 6 - testitrosp main ------------------------------------ +APP6TARGET= $(TARGET6) +APP6OBJS = $(OBJ)$/testintrosp.obj +APP6STDLIBS= \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(SALHELPERLIB) \ + $(SALLIB) + +# --- Application 7 - testconv main ------------------------------------ +APP7TARGET= $(TARGET7) +APP7OBJS = $(OBJ)$/testconv.obj +APP7STDLIBS= \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(SALLIB) + +# --- Application 8 - testproxyfac main ------------------------------------ +APP8TARGET= $(TARGET8) +APP8OBJS = $(OBJ)$/testproxyfac.obj +APP8STDLIBS= \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(SALLIB) + +# --- Application 9 - testproxyfac main ------------------------------------ +APP9TARGET= $(TARGET9) +APP9OBJS = $(OBJ)$/testsmgr2.obj +APP9STDLIBS= \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(SALLIB) + + +ALLIDLFILES:= testcorefl.idl language_binding.idl testintrosp.idl + + +# --- Target ------------------------------------------------ + +.IF "$(depend)" == "" +ALL : $(MISC)$/test_types_generated.flag \ + $(BIN)$/test1.rdb \ + $(BIN)$/test2.rdb \ + ALLTAR +.ELSE +ALL: ALLDEP +.ENDIF + +.INCLUDE : target.mk + +CPPUMAKERFLAGS = +.IF "$(COM)" == "MSC" +CPPUMAKERFLAGS = -L +.ENDIF + +FACTORYTYPES:= -T com.sun.star.lang.XSingleComponentFactory \ + -T com.sun.star.uno.XComponentContext \ + -T com.sun.star.uno.XWeak \ + -T com.sun.star.container.XEnumeration \ + -T com.sun.star.lang.XComponent \ + -T com.sun.star.registry.XSimpleRegistry \ + -T com.sun.star.lang.XInitialization \ + -T com.sun.star.lang.XMultiServiceFactory\ + -T com.sun.star.loader.XImplementationLoader \ + -T com.sun.star.registry.XImplementationRegistration \ + -T com.sun.star.container.XSet \ + -T com.sun.star.lang.XSingleServiceFactory\ + -T com.sun.star.lang.XServiceInfo \ + -T com.sun.star.container.XContentEnumerationAccess \ + -T com.sun.star.container.XEnumeration + +TESTCOREFL:=ModuleC;ModuleC.XInterfaceA;ModuleC.XInterfaceB;ModuleA.XInterface1;com.sun.star.reflection.XIdlReflection;com.sun.star.reflection.XIdlField;com.sun.star.reflection.XIdlArray;com.sun.star.reflection.XIdlMethod;com.sun.star.reflection.XIdlClass;com.sun.star.beans.XPropertySet;com.sun.star.lang.XComponent;com.sun.star.container.XHierarchicalNameAccess;com.sun.star.reflection.XIdlField2;com.sun.star.lang.DisposedException +TESTIADAPTER:=com.sun.star.beans.XIntrospection;com.sun.star.beans.MethodConcept;com.sun.star.beans.XExactName;com.sun.star.lang.XTypeProvider;com.sun.star.uno.XAggregation;com.sun.star.script.XInvocationAdapterFactory;com.sun.star.script.XInvocationAdapterFactory2;com.sun.star.script.XInvocation;com.sun.star.lang.XMultiServiceFactory;com.sun.star.registry.XSimpleRegistry;com.sun.star.lang.XInitialization;test.XLanguageBindingTest +TESTINTROSP:=ModuleA;ModuleA.XIntroTest;com.sun.star.beans.XPropertySet;com.sun.star.container.XIndexAccess;com.sun.star.container.XNameAccess;com.sun.star.beans.PropertyAttribute;com.sun.star.beans.PropertyConcept +TESTCONV:=com.sun.star.script.XTypeConverter +TESTPROXYFAC:=com.sun.star.reflection.XProxyFactory +TESTSECURITY:=com.sun.star.security.AllPermission;com.sun.star.security.XPolicy;com.sun.star.security.XAccessController;com.sun.star.io.FilePermission;com.sun.star.connection.SocketPermission;com.sun.star.uno.XCurrentContext + +$(BIN)$/test1.rdb: $(SHL1TARGETN) +.IF "$(OS)"!="WNT" + cp $(SHL1TARGETN) $(BIN) +.ENDIF + cd $(BIN) && regcomp -register -r test1.rdb -c $(SHL1TARGET) + +$(BIN)$/test2.rdb: + cd $(BIN) && regcomp -register -r test2.rdb -c remotebridge.uno$(DLLPOST) + +$(BIN)$/stoctest.rdb: $(ALLIDLFILES) + idlc -I$(PRJ) -I$(SOLARIDLDIR) -O$(BIN) $? + regmerge $@ /UCR $(BIN)$/{$(?:f:s/.idl/.urd/)} + regmerge $@ / $(SOLARBINDIR)$/udkapi.rdb + regcomp -register -r $@ -c reflection.uno$(DLLPOST) + touch $@ + +$(MISC)$/test_types_generated.flag : $(BIN)$/stoctest.rdb makefile.mk + -rm -f $(MISC)$/test_types_generated.flag + cppumaker $(CPPUMAKERFLAGS) -BUCR -O$(UNOUCROUT) $(FACTORYTYPES) -T"$(TESTIADAPTER)" $(BIN)$/stoctest.rdb + cppumaker $(CPPUMAKERFLAGS) -BUCR -O$(UNOUCROUT) -T"$(TESTCOREFL)" $(BIN)$/stoctest.rdb + cppumaker $(CPPUMAKERFLAGS) -BUCR -O$(UNOUCROUT) -T"$(TESTINTROSP)" $(BIN)$/stoctest.rdb + cppumaker $(CPPUMAKERFLAGS) -BUCR -O$(UNOUCROUT) -T"$(TESTCONV)" $(BIN)$/stoctest.rdb + cppumaker $(CPPUMAKERFLAGS) -BUCR -O$(UNOUCROUT) -T"$(TESTPROXYFAC)" $(BIN)$/stoctest.rdb + cppumaker $(CPPUMAKERFLAGS) -BUCR -O$(UNOUCROUT) -T"$(TESTSECURITY)" $(BIN)$/stoctest.rdb + touch $(MISC)$/test_types_generated.flag diff --git a/stoc/test/mergekeys_.cxx b/stoc/test/mergekeys_.cxx new file mode 100644 index 0000000000..079e12670a --- /dev/null +++ b/stoc/test/mergekeys_.cxx @@ -0,0 +1,22 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "../source/implementationregistration/mergekeys.cxx" + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/stoc/test/registry_tdprovider/makefile.mk b/stoc/test/registry_tdprovider/makefile.mk new file mode 100644 index 0000000000..35a7851173 --- /dev/null +++ b/stoc/test/registry_tdprovider/makefile.mk @@ -0,0 +1,54 @@ +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you under the Apache +# License, Version 2.0 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.apache.org/licenses/LICENSE-2.0 . +# + +PRJ := ..$/.. +PRJNAME := stoc + +TARGET := test_registry_tdprovider + +ENABLE_EXCEPTIONS := TRUE + +.INCLUDE: settings.mk + +DLLPRE = # no leading "lib" on .so files + +SLOFILES = $(SLO)$/testregistrytdprovider.obj + +SHL1TARGET = $(ENFORCEDSHLPREFIX)testregistrytdprovider.uno +SHL1OBJS = $(SLOFILES) +SHL1VERSIONMAP = $(SOLARENV)/src/component.map +SHL1STDLIBS = $(CPPULIB) $(CPPUHELPERLIB) $(SALLIB) +SHL1IMPLIB = itestregistrytdprovider +DEF1NAME = $(SHL1TARGET) + +.INCLUDE: target.mk + +ALLTAR: test + +$(MISC)$/$(TARGET)$/all.rdb: types.idl + - rm $@ + - $(MKDIR) $(MISC)$/$(TARGET) + idlc -O$(MISC)$/$(TARGET) -I$(SOLARIDLDIR) -C -cid -we $< + regmerge $@ /UCR $(MISC)$/$(TARGET)$/types.urd + regmerge $@ / $(SOLARBINDIR)$/types.rdb + +$(SLOFILES): $(MISC)$/$(TARGET)$/all.rdb + +test .PHONY: $(SHL1TARGETN) $(MISC)$/$(TARGET)$/all.rdb + uno -c test.registrytdprovider.impl -l $(subst,$/,/ $(SHL1TARGETN)) \ + -ro $(subst,$/,/ $(MISC)$/$(TARGET)$/all.rdb) diff --git a/stoc/test/registry_tdprovider/readme.txt b/stoc/test/registry_tdprovider/readme.txt new file mode 100644 index 0000000000..9267df8582 --- /dev/null +++ b/stoc/test/registry_tdprovider/readme.txt @@ -0,0 +1,4 @@ +This test uses the delivered regtypeprov.uno dynamic library, not the local one. +(It might work to fix this, changing the test from a UNO component started from +the uno executable to a stand-alone application that bootstraps UNO in a special +way.) diff --git a/stoc/test/registry_tdprovider/testregistrytdprovider.cxx b/stoc/test/registry_tdprovider/testregistrytdprovider.cxx new file mode 100644 index 0000000000..46e3d0998b --- /dev/null +++ b/stoc/test/registry_tdprovider/testregistrytdprovider.cxx @@ -0,0 +1,798 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/container/XHierarchicalNameAccess.hpp> +#include <com/sun/star/lang/XMain.hpp> +#include <com/sun/star/lang/XSingleComponentFactory.hpp> +#include <com/sun/star/reflection/XCompoundTypeDescription.hpp> +#include <com/sun/star/reflection/XInterfaceAttributeTypeDescription2.hpp> +#include <com/sun/star/reflection/XInterfaceMemberTypeDescription.hpp> +#include <com/sun/star/reflection/XInterfaceMethodTypeDescription.hpp> +#include <com/sun/star/reflection/XInterfaceTypeDescription2.hpp> +#include <com/sun/star/reflection/XPublished.hpp> +#include <com/sun/star/reflection/XServiceTypeDescription2.hpp> +#include <com/sun/star/reflection/XSingletonTypeDescription2.hpp> +#include <com/sun/star/reflection/XStructTypeDescription.hpp> +#include <com/sun/star/reflection/XTypeDescription.hpp> +#include <com/sun/star/registry/InvalidRegistryException.hpp> +#include <com/sun/star/registry/XRegistryKey.hpp> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Exception.hpp> +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/uno/RuntimeException.hpp> +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/uno/TypeClass.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/uno/XInterface.hpp> +#include <cppuhelper/factory.hxx> +#include <cppuhelper/implbase.hxx> +#include <cppuhelper/weak.hxx> +#include <rtl/textenc.h> +#include <rtl/ustring.h> +#include <rtl/ustring.hxx> +#include <sal/types.h> +#include <uno/environment.h> + +#include /*MSVC trouble: <cstdlib>*/ <stdlib.h> +#include <iostream> +#include <ostream> + +namespace { + +class Service: public cppu::WeakImplHelper< css::lang::XMain > { +public: + virtual sal_Int32 SAL_CALL + run(css::uno::Sequence< OUString > const & arguments) + throw (css::uno::RuntimeException); + + static OUString getImplementationName(); + + static css::uno::Sequence< OUString > getSupportedServiceNames(); + + static css::uno::Reference< css::uno::XInterface > SAL_CALL createInstance( + css::uno::Reference< css::uno::XComponentContext > const & context) + throw (css::uno::Exception); + +private: + explicit Service( + css::uno::Reference< css::uno::XComponentContext > const & context): + m_context(context) + {} + + css::uno::Reference< css::uno::XComponentContext > m_context; +}; + +} + +namespace { + +std::ostream & operator <<(std::ostream & out, OUString const & value) { + return out << OUStringToOString(value, RTL_TEXTENCODING_UTF8).getStr(); +} + +void assertTrue(bool argument) { + if (!argument) { + std::cerr + << "assertTrue(" << argument << ") failed" << std::endl; + /*MSVC trouble: std::*/abort(); + } +} + +void assertFalse(bool argument) { + if (argument) { + std::cerr + << "assertFalse(" << argument << ") failed" << std::endl; + /*MSVC trouble: std::*/abort(); + } +} + +template< typename T > void assertEqual(T const & value, T const & argument) { + if (argument != value) { + std::cerr + << "assertEqual(" << value << ", " << argument << ") failed" + << std::endl; + /*MSVC trouble: std::*/abort(); + } +} + +} + +sal_Int32 Service::run(css::uno::Sequence< OUString > const &) + throw (css::uno::RuntimeException) +{ + css::uno::Reference< css::lang::XMultiComponentFactory > factory( + m_context->getServiceManager()); + assertTrue(factory.is()); + css::uno::Sequence< css::uno::Any > args(1); + args[0] = css::uno::Reference< css::beans::XPropertySet >( + factory, css::uno::UNO_QUERY_THROW)->getPropertyValue( + OUString("Registry")); + css::uno::Reference< css::container::XHierarchicalNameAccess > provider( + factory->createInstanceWithArgumentsAndContext( + "com.sun.star.comp.stoc.RegistryTypeDescriptionProvider", + args, m_context), + css::uno::UNO_QUERY_THROW); + + // The following assumes that interface members are sorted by increasing + // values of XInterfaceMemberTypeDescription.getPosition, the exceptions + // of interface attributes and interface methods, the constructors of + // services, and the exceptions of service constructors are sorted as given + // in the UNOIDL source code: + + assertEqual< bool >( + false, + provider->hasByHierarchicalName( + OUString( "[][]boolean"))); + assertEqual< bool >( + false, + provider->hasByHierarchicalName( + OUString( "test.registrytdprovider.Struct3<boolean,boolean>"))); + assertEqual< bool >( + false, + provider->hasByHierarchicalName( + OUString( "com.sun.star.uno.XComponentContext::getValueByName"))); + + css::uno::Reference< css::reflection::XCompoundTypeDescription > exception; + exception.set( + provider->getByHierarchicalName( + OUString( "com.sun.star.uno.Exception")), + css::uno::UNO_QUERY_THROW); + assertEqual(css::uno::TypeClass_EXCEPTION, exception->getTypeClass()); + assertEqual( OUString( "com.sun.star.uno.Exception"), + exception->getName()); + assertFalse(exception->getBaseType().is()); + exception.set( + provider->getByHierarchicalName( + OUString( "com.sun.star.uno.RuntimeException")), + css::uno::UNO_QUERY_THROW); + assertEqual(css::uno::TypeClass_EXCEPTION, exception->getTypeClass()); + assertEqual( OUString( "com.sun.star.uno.RuntimeException"), + exception->getName()); + assertEqual( OUString( "com.sun.star.uno.Exception"), + exception->getBaseType()->getName()); + + css::uno::Reference< css::reflection::XStructTypeDescription > structure; + + structure.set( + provider->getByHierarchicalName( + OUString( "test.registrytdprovider.Struct2")), + css::uno::UNO_QUERY_THROW); + assertEqual(css::uno::TypeClass_STRUCT, structure->getTypeClass()); + assertEqual( OUString( "test.registrytdprovider.Struct2"), + structure->getName()); + assertFalse(structure->getBaseType().is()); + assertEqual< sal_Int32 >(1, structure->getMemberTypes().getLength()); + assertEqual( + OUString( "test.registrytdprovider.Struct1"), + structure->getMemberTypes()[0]->getName()); + assertEqual< sal_Int32 >(1, structure->getMemberNames().getLength()); + assertEqual( + OUString("s1"), + structure->getMemberNames()[0]); + assertEqual< sal_Int32 >(0, structure->getTypeParameters().getLength()); + assertEqual< sal_Int32 >(0, structure->getTypeArguments().getLength()); + + structure.set( + provider->getByHierarchicalName( + OUString( "test.registrytdprovider.Struct3")), + css::uno::UNO_QUERY_THROW); + assertEqual(css::uno::TypeClass_STRUCT, structure->getTypeClass()); + assertEqual( + OUString( "test.registrytdprovider.Struct3"), + structure->getName()); + assertFalse(structure->getBaseType().is()); + assertEqual< sal_Int32 >(1, structure->getMemberTypes().getLength()); + assertEqual( + css::uno::TypeClass_UNKNOWN, + structure->getMemberTypes()[0]->getTypeClass()); + assertEqual( + OUString("U"), + structure->getMemberTypes()[0]->getName()); + assertEqual< sal_Int32 >(1, structure->getMemberNames().getLength()); + assertEqual( + OUString("s2"), + structure->getMemberNames()[0]); + assertEqual< sal_Int32 >(2, structure->getTypeParameters().getLength()); + assertEqual( + OUString("T"), + structure->getTypeParameters()[0]); + assertEqual( + OUString("U"), + structure->getTypeParameters()[1]); + assertEqual< sal_Int32 >(0, structure->getTypeArguments().getLength()); + + structure.set( + provider->getByHierarchicalName( + OUString( "test.registrytdprovider.Struct4")), + css::uno::UNO_QUERY_THROW); + assertEqual(css::uno::TypeClass_STRUCT, structure->getTypeClass()); + assertEqual( + OUString( "test.registrytdprovider.Struct4"), + structure->getName()); + assertEqual( + OUString( "test.registrytdprovider.Struct2"), + structure->getBaseType()->getName()); + assertEqual< sal_Int32 >(1, structure->getMemberTypes().getLength()); + assertEqual( + OUString( "test.registrytdprovider.Struct3<" + "test.registrytdprovider.Struct2," + "test.registrytdprovider.Struct3<boolean,any>>"), + structure->getMemberTypes()[0]->getName()); + assertEqual< sal_Int32 >(1, structure->getMemberNames().getLength()); + assertEqual( + OUString("s2"), + structure->getMemberNames()[0]); + assertEqual< sal_Int32 >(0, structure->getTypeParameters().getLength()); + assertEqual< sal_Int32 >(0, structure->getTypeArguments().getLength()); + + css::uno::Reference< css::reflection::XInterfaceTypeDescription2 > + interface; + + interface.set( + provider->getByHierarchicalName( + OUString( "test.registrytdprovider.XTest1")), + css::uno::UNO_QUERY_THROW); + assertEqual(css::uno::TypeClass_INTERFACE, interface->getTypeClass()); + assertEqual( + OUString( "test.registrytdprovider.XTest1"), + interface->getName()); + css::uno::Sequence< + css::uno::Reference< css::reflection::XTypeDescription > > bases( + interface->getBaseTypes()); + assertEqual< sal_Int32 >(1, bases.getLength()); + assertEqual( + OUString( "com.sun.star.uno.XInterface"), + bases[0]->getName()); + css::uno::Sequence< + css::uno::Reference< css::reflection::XTypeDescription > > + optionalBases(interface->getOptionalBaseTypes()); + assertEqual< sal_Int32 >(1, optionalBases.getLength()); + assertEqual( + OUString( + "test.registrytdprovider.XBase"), + optionalBases[0]->getName()); + css::uno::Sequence< + css::uno::Reference< + css::reflection::XInterfaceMemberTypeDescription > > members( + interface->getMembers()); + assertEqual< sal_Int32 >(5, members.getLength()); + + css::uno::Reference< css::reflection::XInterfaceAttributeTypeDescription2 > + attribute; + css::uno::Sequence< + css::uno::Reference< css::reflection::XCompoundTypeDescription > > + getExceptions; + css::uno::Sequence< + css::uno::Reference< css::reflection::XCompoundTypeDescription > > + setExceptions; + css::uno::Reference< css::reflection::XInterfaceMethodTypeDescription > + method; + + attribute.set( members[0], css::uno::UNO_QUERY_THROW); + assertEqual( + css::uno::TypeClass_INTERFACE_ATTRIBUTE, attribute->getTypeClass()); + assertEqual( + OUString( "test.registrytdprovider.XTest1::a1"), + attribute->getName()); + assertEqual( + OUString("a1"), + attribute->getMemberName()); + assertEqual< sal_Int32 >(3, attribute->getPosition()); + assertEqual< bool >(false, attribute->isReadOnly()); + assertEqual( + OUString("short"), + attribute->getType()->getName()); + assertEqual< bool >(true, attribute->isBound()); + getExceptions = attribute->getGetExceptions(); + assertEqual< sal_Int32 >(0, getExceptions.getLength()); + setExceptions = attribute->getSetExceptions(); + assertEqual< sal_Int32 >(0, setExceptions.getLength()); + + attribute.set( members[1], css::uno::UNO_QUERY_THROW); + assertEqual( + css::uno::TypeClass_INTERFACE_ATTRIBUTE, attribute->getTypeClass()); + assertEqual( + OUString( "test.registrytdprovider.XTest1::a2"), + attribute->getName()); + assertEqual( + OUString("a2"), + attribute->getMemberName()); + assertEqual< sal_Int32 >(4, attribute->getPosition()); + assertEqual< bool >(false, attribute->isReadOnly()); + assertEqual( + OUString("long"), + attribute->getType()->getName()); + assertEqual< bool >(false, attribute->isBound()); + getExceptions = attribute->getGetExceptions(); + assertEqual< sal_Int32 >(2, getExceptions.getLength()); + assertEqual( + OUString( "com.sun.star.lang.WrappedTargetException"), + getExceptions[0]->getName()); + assertEqual( + OUString( "com.sun.star.uno.RuntimeException"), + getExceptions[1]->getName()); + setExceptions = attribute->getSetExceptions(); + assertEqual< sal_Int32 >(2, setExceptions.getLength()); + assertEqual( + OUString( "com.sun.star.uno.Exception"), + setExceptions[0]->getName()); + assertEqual( + OUString( "com.sun.star.lang.WrappedTargetException"), + setExceptions[1]->getName()); + + attribute.set( members[2], css::uno::UNO_QUERY_THROW); + assertEqual( + css::uno::TypeClass_INTERFACE_ATTRIBUTE, attribute->getTypeClass()); + assertEqual( + OUString( + "test.registrytdprovider.XTest1::a3"), + attribute->getName()); + assertEqual( + OUString("a3"), + attribute->getMemberName()); + assertEqual< sal_Int32 >(5, attribute->getPosition()); + assertEqual< bool >(true, attribute->isReadOnly()); + assertEqual( + OUString("hyper"), + attribute->getType()->getName()); + assertEqual< bool >(true, attribute->isBound()); + getExceptions = attribute->getGetExceptions(); + assertEqual< sal_Int32 >(1, getExceptions.getLength()); + assertEqual( + OUString( "com.sun.star.lang.WrappedTargetException"), + getExceptions[0]->getName()); + setExceptions = attribute->getSetExceptions(); + assertEqual< sal_Int32 >(0, setExceptions.getLength()); + + method.set( members[3], css::uno::UNO_QUERY_THROW); + assertEqual(css::uno::TypeClass_INTERFACE_METHOD, method->getTypeClass()); + assertEqual( + OUString( "test.registrytdprovider.XTest1::f1"), + method->getName()); + assertEqual( + OUString("f1"), + method->getMemberName()); + assertEqual< sal_Int32 >(6, method->getPosition()); + assertEqual< bool >(false, method->isOneway()); + assertEqual< sal_Int32 >(1, method->getParameters().getLength()); + assertEqual( + OUString("p"), + method->getParameters()[0]->getName()); + assertEqual( + OUString("any"), + method->getParameters()[0]->getType()->getName()); + assertEqual< bool >(false, method->getParameters()[0]->isIn()); + assertEqual< bool >(true, method->getParameters()[0]->isOut()); + assertEqual< sal_Int32 >(0, method->getParameters()[0]->getPosition()); + assertEqual< sal_Int32 >(1, method->getExceptions().getLength()); + assertEqual( + OUString( "com.sun.star.uno.RuntimeException"), + method->getExceptions()[0]->getName()); + + method.set( members[4], css::uno::UNO_QUERY_THROW); + assertEqual(css::uno::TypeClass_INTERFACE_METHOD, method->getTypeClass()); + assertEqual( + OUString( "test.registrytdprovider.XTest1::f2"), + method->getName()); + assertEqual( + OUString("f2"), + method->getMemberName()); + assertEqual< sal_Int32 >(7, method->getPosition()); + assertEqual< bool >(true, method->isOneway()); + assertEqual< sal_Int32 >(0, method->getParameters().getLength()); + assertEqual< sal_Int32 >(0, method->getExceptions().getLength()); + + interface.set( + provider->getByHierarchicalName( + OUString( "test.registrytdprovider.XTest2")), + css::uno::UNO_QUERY_THROW); + assertEqual(css::uno::TypeClass_INTERFACE, interface->getTypeClass()); + assertEqual( + OUString( "test.registrytdprovider.XTest2"), + interface->getName()); + assertEqual< sal_Int32 >(1, interface->getBaseTypes().getLength()); + assertEqual( + OUString( "test.registrytdprovider.Typedef2"), + interface->getBaseTypes()[0]->getName()); + assertEqual< sal_Int32 >(0, interface->getOptionalBaseTypes().getLength()); + assertEqual< sal_Int32 >(0, interface->getMembers().getLength()); + + css::uno::Reference< css::reflection::XServiceTypeDescription2 > service; + + service.set( + provider->getByHierarchicalName( + OUString( "test.registrytdprovider.Service1")), + css::uno::UNO_QUERY_THROW); + assertEqual(css::uno::TypeClass_SERVICE, service->getTypeClass()); + assertEqual( + OUString( "test.registrytdprovider.Service1"), + service->getName()); + assertEqual< sal_Int32 >(0, service->getMandatoryServices().getLength()); + assertEqual< sal_Int32 >(0, service->getOptionalServices().getLength()); + assertEqual< sal_Int32 >(0, service->getMandatoryInterfaces().getLength()); + assertEqual< sal_Int32 >(0, service->getOptionalInterfaces().getLength()); + assertEqual< bool >(true, service->isSingleInterfaceBased()); + assertEqual( + OUString( + "test.registrytdprovider.XTest1"), + service->getInterface()->getName()); + assertEqual< sal_Int32 >(2, service->getConstructors().getLength()); + assertEqual( + OUString("c1"), + service->getConstructors()[0]->getName()); + assertEqual< sal_Int32 >( + 0, service->getConstructors()[0]->getParameters().getLength()); + assertEqual< sal_Int32 >( + 0, service->getConstructors()[0]->getExceptions().getLength()); + assertEqual( + OUString("c2"), + service->getConstructors()[1]->getName()); + assertEqual< sal_Int32 >( + 1, service->getConstructors()[1]->getParameters().getLength()); + assertEqual( + OUString("p"), + service->getConstructors()[1]->getParameters()[0]->getName()); + assertEqual( + OUString("any"), + (service->getConstructors()[1]->getParameters()[0]->getType()-> + getName())); + assertEqual< bool >( + true, service->getConstructors()[1]->getParameters()[0]->isIn()); + assertEqual< bool >( + false, service->getConstructors()[1]->getParameters()[0]->isOut()); + assertEqual< sal_Int32 >( + 0, service->getConstructors()[1]->getParameters()[0]->getPosition()); + assertEqual< bool >( + true, + service->getConstructors()[1]->getParameters()[0]->isRestParameter()); + assertEqual< sal_Int32 >( + 1, service->getConstructors()[1]->getExceptions().getLength()); + assertEqual( + OUString( "com.sun.star.uno.RuntimeException"), + service->getConstructors()[1]->getExceptions()[0]->getName()); + + service.set( + provider->getByHierarchicalName( + OUString( "test.registrytdprovider.Service2")), + css::uno::UNO_QUERY_THROW); + assertEqual(css::uno::TypeClass_SERVICE, service->getTypeClass()); + assertEqual( + OUString( "test.registrytdprovider.Service2"), + service->getName()); + assertEqual< sal_Int32 >(0, service->getMandatoryServices().getLength()); + assertEqual< sal_Int32 >(0, service->getOptionalServices().getLength()); + assertEqual< sal_Int32 >(1, service->getMandatoryInterfaces().getLength()); + assertEqual( + OUString( "test.registrytdprovider.XTest1"), + service->getMandatoryInterfaces()[0]->getName()); + assertEqual< sal_Int32 >(1, service->getOptionalInterfaces().getLength()); + assertEqual( + OUString( "test.registrytdprovider.XBase"), + service->getOptionalInterfaces()[0]->getName()); + assertEqual< bool >(false, service->isSingleInterfaceBased()); + assertFalse(service->getInterface().is()); + assertEqual< sal_Int32 >(0, service->getConstructors().getLength()); + + service.set( + provider->getByHierarchicalName( + OUString( "test.registrytdprovider.Service3")), + css::uno::UNO_QUERY_THROW); + assertEqual(css::uno::TypeClass_SERVICE, service->getTypeClass()); + assertEqual( + OUString( + "test.registrytdprovider.Service3"), + service->getName()); + assertEqual< sal_Int32 >(0, service->getMandatoryServices().getLength()); + assertEqual< sal_Int32 >(0, service->getOptionalServices().getLength()); + assertEqual< sal_Int32 >(0, service->getMandatoryInterfaces().getLength()); + assertEqual< sal_Int32 >(0, service->getOptionalInterfaces().getLength()); + assertEqual< bool >(true, service->isSingleInterfaceBased()); + assertEqual( + OUString( + "test.registrytdprovider.Typedef2"), + service->getInterface()->getName()); + assertEqual< sal_Int32 >(0, service->getConstructors().getLength()); + + css::uno::Reference< css::reflection::XSingletonTypeDescription2 > + singleton; + + singleton.set( + provider->getByHierarchicalName( + OUString( "test.registrytdprovider.Singleton1")), + css::uno::UNO_QUERY_THROW); + assertEqual(css::uno::TypeClass_SINGLETON, singleton->getTypeClass()); + assertEqual( + OUString( + "test.registrytdprovider.Singleton1"), + singleton->getName()); + assertFalse(singleton->getService().is()); + assertEqual< bool >(true, singleton->isInterfaceBased()); + assertEqual( + OUString( + "test.registrytdprovider.XTest1"), + singleton->getInterface()->getName()); + + singleton.set( + provider->getByHierarchicalName( + OUString( "test.registrytdprovider.Singleton2")), + css::uno::UNO_QUERY_THROW); + assertEqual(css::uno::TypeClass_SINGLETON, singleton->getTypeClass()); + assertEqual( + OUString( + "test.registrytdprovider.Singleton2"), + singleton->getName()); + assertEqual( + OUString( + "test.registrytdprovider.Service1"), + singleton->getService()->getName()); + assertEqual< bool >(false, singleton->isInterfaceBased()); + assertFalse(singleton->getInterface().is()); + + singleton.set( + provider->getByHierarchicalName( + OUString( "test.registrytdprovider.Singleton3")), + css::uno::UNO_QUERY_THROW); + assertEqual(css::uno::TypeClass_SINGLETON, singleton->getTypeClass()); + assertEqual( + OUString( + "test.registrytdprovider.Singleton3"), + singleton->getName()); + assertFalse(singleton->getService().is()); + assertEqual< bool >(true, singleton->isInterfaceBased()); + assertEqual( + OUString( + "test.registrytdprovider.Typedef2"), + singleton->getInterface()->getName()); + + css::uno::Reference< css::reflection::XPublished > published; + published.set( + css::uno::Reference< css::reflection::XTypeDescription >( + provider->getByHierarchicalName( + OUString( "test.registrytdprovider.Enum1")), + css::uno::UNO_QUERY_THROW), + css::uno::UNO_QUERY); + assertTrue(published.is()); + assertTrue(published->isPublished()); + published.set( + css::uno::Reference< css::reflection::XTypeDescription >( + provider->getByHierarchicalName( + OUString( "test.registrytdprovider.Enum2")), + css::uno::UNO_QUERY_THROW), + css::uno::UNO_QUERY); + assertTrue(published.is()); + assertFalse(published->isPublished()); + published.set( + css::uno::Reference< css::reflection::XTypeDescription >( + provider->getByHierarchicalName( + OUString( "test.registrytdprovider.Struct1")), + css::uno::UNO_QUERY_THROW), + css::uno::UNO_QUERY); + assertTrue(published.is()); + assertTrue(published->isPublished()); + published.set( + css::uno::Reference< css::reflection::XTypeDescription >( + provider->getByHierarchicalName( + OUString( "test.registrytdprovider.Struct2")), + css::uno::UNO_QUERY_THROW), + css::uno::UNO_QUERY); + assertTrue(published.is()); + assertFalse(published->isPublished()); + published.set( + css::uno::Reference< css::reflection::XTypeDescription >( + provider->getByHierarchicalName( + OUString( "test.registrytdprovider.Struct3")), + css::uno::UNO_QUERY_THROW), + css::uno::UNO_QUERY); + assertTrue(published.is()); + assertTrue(published->isPublished()); + published.set( + css::uno::Reference< css::reflection::XStructTypeDescription >( + provider->getByHierarchicalName( + OUString( "test.registrytdprovider.Struct3")), + css::uno::UNO_QUERY_THROW)->getMemberTypes()[0], + css::uno::UNO_QUERY); + assertFalse(published.is()); + published.set( + css::uno::Reference< css::reflection::XTypeDescription >( + provider->getByHierarchicalName( + OUString( "test.registrytdprovider.Struct3a")), + css::uno::UNO_QUERY_THROW), + css::uno::UNO_QUERY); + assertTrue(published.is()); + assertFalse(published->isPublished()); + published.set( + css::uno::Reference< css::reflection::XTypeDescription >( + provider->getByHierarchicalName( + OUString( "test.registrytdprovider.Exception1")), + css::uno::UNO_QUERY_THROW), + css::uno::UNO_QUERY); + assertTrue(published.is()); + assertTrue(published->isPublished()); + published.set( + css::uno::Reference< css::reflection::XTypeDescription >( + provider->getByHierarchicalName( + OUString( "test.registrytdprovider.Exception2")), + css::uno::UNO_QUERY_THROW), + css::uno::UNO_QUERY); + assertTrue(published.is()); + assertFalse(published->isPublished()); + published.set( + css::uno::Reference< css::reflection::XTypeDescription >( + provider->getByHierarchicalName( + OUString( "test.registrytdprovider.XTest1")), + css::uno::UNO_QUERY_THROW), + css::uno::UNO_QUERY); + assertTrue(published.is()); + assertTrue(published->isPublished()); + published.set( + css::uno::Reference< css::reflection::XTypeDescription >( + provider->getByHierarchicalName( + OUString( "test.registrytdprovider.XTest2")), + css::uno::UNO_QUERY_THROW), + css::uno::UNO_QUERY); + assertTrue(published.is()); + assertFalse(published->isPublished()); + published.set( + css::uno::Reference< css::reflection::XTypeDescription >( + provider->getByHierarchicalName( + OUString( "test.registrytdprovider.Typedef1")), + css::uno::UNO_QUERY_THROW), + css::uno::UNO_QUERY); + assertTrue(published.is()); + assertTrue(published->isPublished()); + published.set( + css::uno::Reference< css::reflection::XTypeDescription >( + provider->getByHierarchicalName( + OUString( "test.registrytdprovider.Typedef2")), + css::uno::UNO_QUERY_THROW), + css::uno::UNO_QUERY); + assertTrue(published.is()); + assertFalse(published->isPublished()); + //TODO: check constants test.registrytdprovider.Const1 (published), + // test.registrytdprovider.Const2 (unpublished), and + // test.registrytdprovider.Consts1.C (no XPublished), which are not + // accessible via provider->getByHierarchicalName (see #i31428) + published.set( + css::uno::Reference< css::reflection::XTypeDescription >( + provider->getByHierarchicalName( + OUString( "test.registrytdprovider.Consts1")), + css::uno::UNO_QUERY_THROW), + css::uno::UNO_QUERY); + assertTrue(published.is()); + assertTrue(published->isPublished()); + published.set( + css::uno::Reference< css::reflection::XTypeDescription >( + provider->getByHierarchicalName( + OUString( "test.registrytdprovider.Consts2")), + css::uno::UNO_QUERY_THROW), + css::uno::UNO_QUERY); + assertTrue(published.is()); + assertFalse(published->isPublished()); + published.set( + css::uno::Reference< css::reflection::XTypeDescription >( + provider->getByHierarchicalName( + OUString( "test.registrytdprovider")), + css::uno::UNO_QUERY_THROW), + css::uno::UNO_QUERY); + assertFalse(published.is()); + published.set( + css::uno::Reference< css::reflection::XTypeDescription >( + provider->getByHierarchicalName( + OUString( "test.registrytdprovider.Service1")), + css::uno::UNO_QUERY_THROW), + css::uno::UNO_QUERY); + assertTrue(published.is()); + assertTrue(published->isPublished()); + published.set( + css::uno::Reference< css::reflection::XTypeDescription >( + provider->getByHierarchicalName( + OUString( "test.registrytdprovider.Service2")), + css::uno::UNO_QUERY_THROW), + css::uno::UNO_QUERY); + assertTrue(published.is()); + assertFalse(published->isPublished()); + published.set( + css::uno::Reference< css::reflection::XTypeDescription >( + provider->getByHierarchicalName( + OUString( "test.registrytdprovider.Singleton2")), + css::uno::UNO_QUERY_THROW), + css::uno::UNO_QUERY); + assertTrue(published.is()); + assertTrue(published->isPublished()); + published.set( + css::uno::Reference< css::reflection::XTypeDescription >( + provider->getByHierarchicalName( + OUString( "test.registrytdprovider.Singleton1")), + css::uno::UNO_QUERY_THROW), + css::uno::UNO_QUERY); + assertTrue(published.is()); + assertFalse(published->isPublished()); + + return 0; +} + +OUString Service::getImplementationName() { + return OUString("test.registrytdprovider.impl"); +} + +css::uno::Sequence< OUString > Service::getSupportedServiceNames() { + return css::uno::Sequence< OUString >(); +} + +css::uno::Reference< css::uno::XInterface > Service::createInstance( + css::uno::Reference< css::uno::XComponentContext > const & context) + throw (css::uno::Exception) +{ + return cppu::getXWeak(new Service(context)); +} + +extern "C" SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory(char const * implName, + void * serviceManager, void *) { + void * p = 0; + if (serviceManager != 0) { + css::uno::Reference< css::lang::XSingleComponentFactory > f; + if (Service::getImplementationName().equalsAscii(implName)) { + f = cppu::createSingleComponentFactory( + &Service::createInstance, Service::getImplementationName(), + Service::getSupportedServiceNames()); + } + if (f.is()) { + f->acquire(); + p = f.get(); + } + } + return p; +} + +namespace { + +bool writeInfo(void * registryKey, OUString const & implementationName, + css::uno::Sequence< OUString > const & serviceNames) { + OUString keyName = "/" + implementationName + "/UNO/SERVICES"; + css::uno::Reference< css::registry::XRegistryKey > key; + try { + key = static_cast< css::registry::XRegistryKey * >(registryKey)-> + createKey(keyName); + } catch (css::registry::InvalidRegistryException &) {} + if (!key.is()) { + return false; + } + bool success = true; + for (auto const& rServiceName : serviceNames) { + try { + key->createKey(rServiceName); + } catch (css::registry::InvalidRegistryException &) { + success = false; + break; + } + } + return success; +} + +} + +extern "C" sal_Bool SAL_CALL component_writeInfo(void *, void * registryKey) { + return registryKey + && writeInfo(registryKey, Service::getImplementationName(), + Service::getSupportedServiceNames()); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/stoc/test/registry_tdprovider/types.idl b/stoc/test/registry_tdprovider/types.idl new file mode 100644 index 0000000000..7d37e23221 --- /dev/null +++ b/stoc/test/registry_tdprovider/types.idl @@ -0,0 +1,101 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +module test { module registrytdprovider { + +published enum Enum1 { E1 }; + +enum Enum2 { E1 }; + +published struct Struct1 { long s1; }; + +struct Struct2 { Struct1 s1; }; + +published struct Struct3<T, U> { U s2; }; + +struct Struct3a<T, U> { U s2; }; + +struct Struct4: Struct2 { Struct3< Struct2, Struct3< boolean, any > > s2; }; + +published exception Exception1: com::sun::star::uno::Exception {}; + +exception Exception2: com::sun::star::uno::Exception {}; + +published interface XBase {}; + +published typedef XBase Typedef1; + +typedef Typedef1 Typedef2; + +published interface XTest1 { + [optional] interface XBase; + + void f1([out] any p) raises (com::sun::star::uno::RuntimeException); + + void f2(); + + [attribute, bound] short a1; + + [attribute] long a2 { + get raises + (com::sun::star::lang::WrappedTargetException, + com::sun::star::uno::RuntimeException); + set raises + (com::sun::star::uno::Exception, + com::sun::star::lang::WrappedTargetException); + }; + + [attribute, readonly, bound] hyper a3 { + get raises (com::sun::star::lang::WrappedTargetException); + }; +}; + +interface XTest2: Typedef2 {}; + +published service Service1: XTest1 { + c1(); + + c2([in] any... p) raises (com::sun::star::uno::RuntimeException); +}; + +service Service2 { + [optional] interface XBase; + + interface XTest1; +}; + +service Service3: Typedef2 {}; + +singleton Singleton1: XTest1; + +published singleton Singleton2 { service Service1; }; + +singleton Singleton3: Typedef2; + +published const long Const1 = 0; + +const long Const2 = 0; + +published constants Consts1 { const long C = 0; }; + +constants Consts2 { const long C = 0; }; + +}; }; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/stoc/test/tdmanager/makefile.mk b/stoc/test/tdmanager/makefile.mk new file mode 100644 index 0000000000..47cc135ba7 --- /dev/null +++ b/stoc/test/tdmanager/makefile.mk @@ -0,0 +1,66 @@ +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you under the Apache +# License, Version 2.0 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.apache.org/licenses/LICENSE-2.0 . +# + +PRJ := ..$/.. +PRJNAME := stoc + +TARGET := test_tdmanager + +ENABLE_EXCEPTIONS := TRUE + +.INCLUDE: settings.mk + +DLLPRE = # no leading "lib" on .so files + +SLOFILES = $(SLO)$/testtdmanager.obj + +SHL1TARGET = $(ENFORCEDSHLPREFIX)testtdmanager.uno +SHL1OBJS = $(SLOFILES) +SHL1VERSIONMAP = $(SOLARENV)/src/component.map +SHL1STDLIBS = $(CPPULIB) $(CPPUHELPERLIB) $(SALLIB) +SHL1IMPLIB = itesttdmanager +DEF1NAME = $(SHL1TARGET) + +.INCLUDE: target.mk + +ALLTAR: test + +$(MISC)$/$(TARGET)$/%.rdb : %.idl + - rm $@ + - $(MKDIR) $(MISC)$/$(TARGET) + idlc -O$(MISC)$/$(TARGET) -I$(SOLARIDLDIR) -C -cid -we $< + regmerge $@ /UCR $(subst,.rdb,.urd $@) + +IDL_FILES = \ + types.idl \ + types2_incomp.idl \ + types3_incomp.idl \ + types4_incomp.idl \ + types5_incomp.idl \ + types5.idl \ + types6_incomp.idl + +RDB_FILES = $(foreach,i,$(subst,.idl,.rdb $(IDL_FILES)) $(MISC)$/$(TARGET)$/$i) + +$(SLOFILES): $(RDB_FILES) + +test .PHONY: $(SHL1TARGETN) $(RDB_FILES) + uno -c test.tdmanager.impl -l $(subst,$/,/ $(SHL1TARGETN)) \ + -ro $(subst,$/,/ $(SOLARBINDIR)$/udkapi_doc.rdb) \ + -- $(subst,$/,/ $(SOLARBINDIR)$/types_doc.rdb) \ + $(subst,$/,/ $(RDB_FILES)) diff --git a/stoc/test/tdmanager/readme.txt b/stoc/test/tdmanager/readme.txt new file mode 100644 index 0000000000..f497720496 --- /dev/null +++ b/stoc/test/tdmanager/readme.txt @@ -0,0 +1,4 @@ +This test uses the delivered typemgr.uno dynamic library, not the local one. +(It might work to fix this, changing the test from a UNO component started from +the uno executable to a stand-alone application that bootstraps UNO in a special +way.) diff --git a/stoc/test/tdmanager/testtdmanager.cxx b/stoc/test/tdmanager/testtdmanager.cxx new file mode 100644 index 0000000000..7c9971d6aa --- /dev/null +++ b/stoc/test/tdmanager/testtdmanager.cxx @@ -0,0 +1,332 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#include <com/sun/star/container/XHierarchicalNameAccess.hpp> +#include <com/sun/star/container/XSet.hpp> +#include <com/sun/star/lang/XMain.hpp> +#include <com/sun/star/lang/XSingleComponentFactory.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <com/sun/star/reflection/XIndirectTypeDescription.hpp> +#include <com/sun/star/reflection/XInterfaceMethodTypeDescription.hpp> +#include <com/sun/star/reflection/XPublished.hpp> +#include <com/sun/star/reflection/XStructTypeDescription.hpp> +#include <com/sun/star/reflection/XTypeDescription.hpp> +#include <com/sun/star/registry/InvalidRegistryException.hpp> +#include <com/sun/star/registry/XRegistryKey.hpp> +#include <com/sun/star/registry/XSimpleRegistry.hpp> +#include <com/sun/star/uno/Exception.hpp> +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/uno/RuntimeException.hpp> +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/uno/TypeClass.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/uno/XInterface.hpp> +#include <cppuhelper/factory.hxx> +#include <cppuhelper/implbase.hxx> +#include <cppuhelper/weak.hxx> +#include <osl/file.h> +#include <osl/thread.h> +#include <rtl/textenc.h> +#include <rtl/ustring.h> +#include <rtl/ustring.hxx> +#include <sal/types.h> +#include <uno/environment.h> + +#include /*MSVC trouble: <cstdlib>*/ <stdlib.h> +#include <iostream> +#include <ostream> + +namespace { + +class Service: public cppu::WeakImplHelper< css::lang::XMain > { +public: + virtual sal_Int32 SAL_CALL + run(css::uno::Sequence< OUString > const & arguments) + throw (css::uno::RuntimeException); + + static OUString getImplementationName(); + + static css::uno::Sequence< OUString > getSupportedServiceNames(); + + static css::uno::Reference< css::uno::XInterface > SAL_CALL createInstance( + css::uno::Reference< css::uno::XComponentContext > const & context) + throw (css::uno::Exception); + +private: + explicit Service( + css::uno::Reference< css::uno::XComponentContext > const & context): + m_context(context) + {} + + css::uno::Reference< css::uno::XComponentContext > m_context; +}; + +} + +namespace { + +std::ostream & operator <<(std::ostream & out, OUString const & value) { + return out << OUStringToOString(value, RTL_TEXTENCODING_UTF8).getStr(); +} + +void assertTrue(bool argument) { + if (!argument) { + std::cerr + << "assertTrue(" << argument << ") failed" << std::endl; + /*MSVC trouble: std::*/abort(); + } +} + +void assertFalse(bool argument) { + if (argument) { + std::cerr + << "assertFalse(" << argument << ") failed" << std::endl; + /*MSVC trouble: std::*/abort(); + } +} + +template< typename T > void assertEqual(T const & value, T const & argument) { + if (argument != value) { + std::cerr + << "assertEqual(" << value << ", " << argument << ") failed" + << std::endl; + /*MSVC trouble: std::*/abort(); + } +} + +} + +sal_Int32 Service::run(css::uno::Sequence< OUString > const & arguments) + throw (css::uno::RuntimeException) +{ + css::uno::Reference< css::lang::XMultiComponentFactory > factory( + m_context->getServiceManager()); + assertTrue(factory.is()); + css::uno::Reference< css::container::XHierarchicalNameAccess > manager( + m_context->getValueByName( + OUString( + "/singletons/" + "com.sun.star.reflection.theTypeDescriptionManager")), + css::uno::UNO_QUERY_THROW); + + + // test: add cmd line rdbs to manager + + + OSL_ASSERT( arguments.getLength() > 0 ); + css::uno::Reference<css::container::XSet> xSet( + manager, css::uno::UNO_QUERY_THROW ); + for ( sal_Int32 argPos = 0; argPos < arguments.getLength(); ++argPos ) { + OUString url; + OSL_VERIFY( osl_File_E_None == osl_getFileURLFromSystemPath( + arguments[argPos].pData, &url.pData ) ); + bool supposedToBeCompatible = ! url.endsWithIgnoreAsciiCase("_incomp.rdb"); + + css::uno::Reference<css::registry::XSimpleRegistry> xReg( + m_context->getServiceManager()->createInstanceWithContext( + "com.sun.star.registry.SimpleRegistry", + m_context ), css::uno::UNO_QUERY_THROW ); + xReg->open( url, true /* read-only */, false /* ! create */ ); + css::uno::Any arg( css::uno::makeAny(xReg) ); + css::uno::Reference<css::container::XHierarchicalNameAccess> xTDprov( + m_context->getServiceManager()-> + createInstanceWithArgumentsAndContext( + "com.sun.star.comp.stoc.RegistryTypeDescriptionProvider", + css::uno::Sequence<css::uno::Any>( &arg, 1 ), m_context ), + css::uno::UNO_QUERY_THROW ); + try { + xSet->insert( css::uno::makeAny(xTDprov) ); + if (! supposedToBeCompatible) + std::cerr << "current rdb file: " << + OUStringToOString( + url, osl_getThreadTextEncoding()).getStr() << std::endl; + assertTrue(supposedToBeCompatible); + } catch (css::lang::IllegalArgumentException &) { + if (supposedToBeCompatible) + throw; + assertFalse(supposedToBeCompatible); + } + } + + / + + css::uno::Reference< css::reflection::XIndirectTypeDescription > sequence( + manager->getByHierarchicalName( + OUString("[][]boolean")), + css::uno::UNO_QUERY_THROW); + assertEqual(css::uno::TypeClass_SEQUENCE, sequence->getTypeClass()); + assertEqual( + OUString("[][]boolean"), + sequence->getName()); + assertEqual( + OUString("[]boolean"), + sequence->getReferencedType()->getName()); + + css::uno::Reference< css::reflection::XStructTypeDescription > structure( + manager->getByHierarchicalName( + OUString( "test.tdmanager.Struct<boolean,test.tdmanager.Struct<" + "any,com.sun.star.uno.XInterface>>")), + css::uno::UNO_QUERY_THROW); + assertEqual(css::uno::TypeClass_STRUCT, structure->getTypeClass()); + assertEqual( + OUString( "test.tdmanager.Struct<boolean,test.tdmanager.Struct<" + "any,com.sun.star.uno.XInterface>>"), + structure->getName()); + assertEqual< bool >(false, structure->getBaseType().is()); + assertEqual< sal_Int32 >(1, structure->getMemberTypes().getLength()); + assertEqual( + OUString( "test.tdmanager.Struct<any,com.sun.star.uno.XInterface>"), + structure->getMemberTypes()[0]->getName()); + assertEqual< sal_Int32 >(1, structure->getMemberNames().getLength()); + assertEqual( + OUString("s"), + structure->getMemberNames()[0]); + assertEqual< sal_Int32 >(0, structure->getTypeParameters().getLength()); + assertEqual< sal_Int32 >(2, structure->getTypeArguments().getLength()); + assertEqual( + OUString("boolean"), + structure->getTypeArguments()[0]->getName()); + assertEqual( + OUString( "test.tdmanager.Struct<any,com.sun.star.uno.XInterface>"), + structure->getTypeArguments()[1]->getName()); + + css::uno::Reference< css::reflection::XInterfaceMethodTypeDescription > + method( + manager->getByHierarchicalName( + OUString( "com.sun.star.uno.XComponentContext::getValueByName")), + css::uno::UNO_QUERY_THROW); + assertEqual(css::uno::TypeClass_INTERFACE_METHOD, method->getTypeClass()); + assertEqual( + OUString( "com.sun.star.uno.XComponentContext::getValueByName"), + method->getName()); + assertEqual( + OUString("getValueByName"), + method->getMemberName()); + assertEqual< sal_Int32 >(3, method->getPosition()); + assertEqual( + OUString("any"), + method->getReturnType()->getName()); + assertEqual< bool >(false, method->isOneway()); + assertEqual< sal_Int32 >(1, method->getParameters().getLength()); + assertEqual( + OUString("Name"), + method->getParameters()[0]->getName()); + assertEqual( + OUString("string"), + method->getParameters()[0]->getType()->getName()); + assertEqual< bool >(true, method->getParameters()[0]->isIn()); + assertEqual< bool >(false, method->getParameters()[0]->isOut()); + assertEqual< sal_Int32 >(0, method->getParameters()[0]->getPosition()); + assertEqual< sal_Int32 >(0, method->getExceptions().getLength()); + + assertFalse( + css::uno::Reference< css::reflection::XPublished >( + css::uno::Reference< css::reflection::XTypeDescription >( + manager->getByHierarchicalName( + OUString("[]boolean")), + css::uno::UNO_QUERY_THROW), + css::uno::UNO_QUERY).is()); + assertFalse( + css::uno::Reference< css::reflection::XPublished >( + css::uno::Reference< css::reflection::XTypeDescription >( + manager->getByHierarchicalName( + OUString( "com.sun.star.beans.XIntroTest::ObjectName")), + css::uno::UNO_QUERY_THROW), + css::uno::UNO_QUERY).is()); + assertFalse( + css::uno::Reference< css::reflection::XPublished >( + css::uno::Reference< css::reflection::XTypeDescription >( + manager->getByHierarchicalName( + OUString( "com.sun.star.beans.XIntroTest::writeln")), + css::uno::UNO_QUERY_THROW), + css::uno::UNO_QUERY).is()); + //TODO: check that the reflection of a property of an accumulation-based + // service does not support XPublished + + return 0; +} + +OUString Service::getImplementationName() { + return OUString("test.tdmanager.impl"); +} + +css::uno::Sequence< OUString > Service::getSupportedServiceNames() { + return css::uno::Sequence< OUString >(); +} + +css::uno::Reference< css::uno::XInterface > Service::createInstance( + css::uno::Reference< css::uno::XComponentContext > const & context) + throw (css::uno::Exception) +{ + return cppu::getXWeak(new Service(context)); +} + +extern "C" SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory(char const * implName, + void * serviceManager, void *) { + void * p = 0; + if (serviceManager != 0) { + css::uno::Reference< css::lang::XSingleComponentFactory > f; + if (Service::getImplementationName().equalsAscii(implName)) { + f = cppu::createSingleComponentFactory( + &Service::createInstance, Service::getImplementationName(), + Service::getSupportedServiceNames()); + } + if (f.is()) { + f->acquire(); + p = f.get(); + } + } + return p; +} + +namespace { + +bool writeInfo(void * registryKey, OUString const & implementationName, + css::uno::Sequence< OUString > const & serviceNames) { + OUString keyName = "/" + implementationName + "/UNO/SERVICES"; + css::uno::Reference< css::registry::XRegistryKey > key; + try { + key = static_cast< css::registry::XRegistryKey * >(registryKey)-> + createKey(keyName); + } catch (css::registry::InvalidRegistryException &) {} + if (!key.is()) { + return false; + } + bool success = true; + for (sal_Int32 i = 0; i < serviceNames.getLength(); ++i) { + try { + key->createKey(serviceNames[i]); + } catch (css::registry::InvalidRegistryException &) { + success = false; + break; + } + } + return success; +} + +} + +extern "C" sal_Bool SAL_CALL component_writeInfo(void *, void * registryKey) { + return registryKey + && writeInfo(registryKey, Service::getImplementationName(), + Service::getSupportedServiceNames()); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/stoc/test/tdmanager/types.idl b/stoc/test/tdmanager/types.idl new file mode 100644 index 0000000000..612ad1bac4 --- /dev/null +++ b/stoc/test/tdmanager/types.idl @@ -0,0 +1,37 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +module test { module tdmanager { + +struct Struct<T, U> { U s; }; + +published interface XAnother { + void f(); +}; + +service MyService { + [optional] interface XAnother; + [property, optional] boolean b; +}; + +const long CCC = 5; + +}; }; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/stoc/test/tdmanager/types2_incomp.idl b/stoc/test/tdmanager/types2_incomp.idl new file mode 100644 index 0000000000..cb3b0e02c0 --- /dev/null +++ b/stoc/test/tdmanager/types2_incomp.idl @@ -0,0 +1,32 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +module com { module sun { module star { module text { + +typedef long XTextField; + +}; }; }; }; + +module test { module tdmanager { + +const long CCC = 6; + +}; }; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/stoc/test/tdmanager/types3_incomp.idl b/stoc/test/tdmanager/types3_incomp.idl new file mode 100644 index 0000000000..cb2603f6ff --- /dev/null +++ b/stoc/test/tdmanager/types3_incomp.idl @@ -0,0 +1,27 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +module test { module tdmanager { + +// added member: +struct Struct<T, U> { U s; long n; }; + +}; }; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/stoc/test/tdmanager/types4_incomp.idl b/stoc/test/tdmanager/types4_incomp.idl new file mode 100644 index 0000000000..6711673ba9 --- /dev/null +++ b/stoc/test/tdmanager/types4_incomp.idl @@ -0,0 +1,34 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +module test { module tdmanager { + +published interface XAnother { + // wrong name: + void f2(); +}; + +service MyService { + [optional] interface XAnother; + [property, optional] boolean b; +}; + +}; }; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/stoc/test/tdmanager/types5.idl b/stoc/test/tdmanager/types5.idl new file mode 100644 index 0000000000..21eda7d389 --- /dev/null +++ b/stoc/test/tdmanager/types5.idl @@ -0,0 +1,37 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +module test { module tdmanager { + +published interface XAnother { + void f(); +}; + +service MyService { + [optional] interface XAnother; + // correct order: + [property, optional] boolean b; + [property, optional] boolean b2; +}; + +const long CCC = 5; + +}; }; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/stoc/test/tdmanager/types5_incomp.idl b/stoc/test/tdmanager/types5_incomp.idl new file mode 100644 index 0000000000..8f3b5f83c1 --- /dev/null +++ b/stoc/test/tdmanager/types5_incomp.idl @@ -0,0 +1,35 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +module test { module tdmanager { + +published interface XAnother { + void f(); +}; + +service MyService { + [optional] interface XAnother; + // wrong order: + [property, optional] boolean b2; + [property, optional] boolean b; +}; + +}; }; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/stoc/test/tdmanager/types6_incomp.idl b/stoc/test/tdmanager/types6_incomp.idl new file mode 100644 index 0000000000..898c9b3d2b --- /dev/null +++ b/stoc/test/tdmanager/types6_incomp.idl @@ -0,0 +1,35 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +module test { module tdmanager { + +published interface XAnother { + void f(); +}; + +service MyService { + // made non-optional: + interface XAnother; + [property, optional] boolean b; + [property, optional] boolean b2; +}; + +}; }; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/stoc/test/testconv.cxx b/stoc/test/testconv.cxx new file mode 100644 index 0000000000..5549779db1 --- /dev/null +++ b/stoc/test/testconv.cxx @@ -0,0 +1,682 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#include <sal/main.h> +#include <osl/diagnose.h> +#include <rtl/ustrbuf.hxx> +#include <cppuhelper/servicefactory.hxx> + +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/script/XTypeConverter.hpp> +#include <com/sun/star/reflection/FieldAccessMode.hpp> +#include <com/sun/star/registry/XImplementationRegistration.hpp> + +#include <cmath> +#include <float.h> +#include <stdio.h> + + +using namespace cppu; +using namespace osl; +using namespace css::uno; +using namespace css::lang; +using namespace css::script; +using namespace css::reflection; +using namespace css::registry; + + +const double MIN_DOUBLE = -DBL_MAX; +const double MAX_DOUBLE = DBL_MAX; +const double MIN_FLOAT = -FLT_MAX; +const double MAX_FLOAT = FLT_MAX; + + +static void printValue( const Any & rVal ) +{ + // print value + OString aStr( OUStringToOString( rVal.getValueType().getTypeName(), RTL_TEXTENCODING_ISO_8859_1 ) ); + printf( "(%s)", aStr.getStr() ); + + switch (rVal.getValueTypeClass()) + { + case TypeClass_VOID: + printf( "void" ); + break; + case TypeClass_ANY: + if (rVal.hasValue()) + printValue( *(Any *)rVal.getValue() ); + break; + case TypeClass_BOOLEAN: + printf( "%s", (*(sal_Bool *)rVal.getValue() ? "true" : "false") ); + break; + case TypeClass_CHAR: + { + char ar[2]; + ar[0] = (char)*(sal_Unicode *)rVal.getValue(); + ar[1] = 0; + printf( "%s", ar ); + break; + } + case TypeClass_BYTE: + printf( "%x", (int)*(sal_Int8 *)rVal.getValue() ); + break; + case TypeClass_SHORT: + printf( "%x", *(sal_Int16 *)rVal.getValue() ); + break; + case TypeClass_UNSIGNED_SHORT: + printf( "%x", *(sal_uInt16 *)rVal.getValue() ); + break; + case TypeClass_LONG: + printf( "%lx", static_cast<long>(*(sal_Int32 *)rVal.getValue()) ); + break; + case TypeClass_UNSIGNED_LONG: + printf( "%lx", static_cast<unsigned long>(*(sal_uInt32 *)rVal.getValue()) ); + break; + case TypeClass_HYPER: + printf( "%lx", (long)*(sal_Int64 *)rVal.getValue() ); + break; + case TypeClass_UNSIGNED_HYPER: + printf( "%lx", (unsigned long)*(sal_uInt64 *)rVal.getValue() ); + break; + case TypeClass_FLOAT: + printf( "%f", *(float *)rVal.getValue() ); + break; + case TypeClass_DOUBLE: + printf( "%g", *(double *)rVal.getValue() ); + break; + case TypeClass_STRING: + { + OString aStr2( OUStringToOString( *(OUString *)rVal.getValue(), RTL_TEXTENCODING_ISO_8859_1 ) ); + printf( aStr2.getStr() ); + break; + } + case TypeClass_ENUM: + { + typelib_EnumTypeDescription * pEnumTD = 0; + TYPELIB_DANGER_GET( (typelib_TypeDescription **)&pEnumTD, rVal.getValueTypeRef() ); + + for ( sal_Int32 nPos = pEnumTD->nEnumValues; nPos--; ) + { + if (pEnumTD->pEnumValues[nPos] == *(int *)rVal.getValue()) + { + printf( OUStringToOString(pEnumTD->ppEnumNames[nPos]->buffer, RTL_TEXTENCODING_ASCII_US).getStr() ); + TYPELIB_DANGER_RELEASE( (typelib_TypeDescription *)pEnumTD ); + return; + } + } + TYPELIB_DANGER_RELEASE( (typelib_TypeDescription *)pEnumTD ); + printf( ">ENUM not found!<" ); + break; + } + case TypeClass_SEQUENCE: + { + uno_Sequence * pSeq = *(uno_Sequence **)rVal.getValue(); + typelib_TypeDescription * pSeqTD = 0; + TYPELIB_DANGER_GET( &pSeqTD, rVal.getValueTypeRef() ); + typelib_TypeDescription * pElemTD = 0; + TYPELIB_DANGER_GET( &pElemTD, ((typelib_IndirectTypeDescription *)pSeqTD)->pType ); + + sal_Int32 nLen = pSeq->nElements; + if (nLen) + { + printf( "{ " ); + for ( sal_Int32 nPos = 0; nPos < nLen; ++nPos ) + { + printValue( Any( ((char *)pSeq->elements) + (nPos * pElemTD->nSize), pElemTD ) ); + if (nPos < (nLen-1)) + printf( ", " ); + } + printf( " }" ); + } + + TYPELIB_DANGER_RELEASE( pElemTD ); + TYPELIB_DANGER_RELEASE( pSeqTD ); + break; + } + + default: + printf( ">not printable<" ); + break; + } +} + +static Reference< XTypeConverter > s_xConverter; + + +static sal_Bool convertTo( const Type & rDestType, const Any & rVal, sal_Bool bExpectSuccess ) +{ + sal_Bool bCanConvert = sal_False; + Any aRet; + + OString aExcMsg; + + try + { + aRet = s_xConverter->convertTo( rVal, rDestType ); + bCanConvert = sal_True; + } + catch (const Exception & rExc) + { + aExcMsg = OUStringToOString( rExc.Message, RTL_TEXTENCODING_ASCII_US ); + } + + if (bExpectSuccess && !bCanConvert) + { + printf( "# conversion of " ); + printValue( rVal ); + printf( " to " ); + printf( OUStringToOString(rDestType.getTypeName(), RTL_TEXTENCODING_ASCII_US).getStr() ); + printf( " failed, but success was expected! [" ); + printf( aExcMsg.getStr() ); + printf( "]\n" ); + aRet = s_xConverter->convertTo( rVal, rDestType ); +#if OSL_DEBUG_LEVEL > 0 + // for debugging, to trace again + try + { + aRet = s_xConverter->convertTo( rVal, rDestType ); + } + catch (Exception &) + { + } +#endif + return sal_False; + } + if (!bExpectSuccess && bCanConvert) + { + printf( "# conversion of " ); + printValue( rVal ); + printf( " to " ); + printValue( aRet ); + printf( " was successful, but was not expected to be!\n" ); +#if OSL_DEBUG_LEVEL > 0 + // for debugging, to trace again + aRet = s_xConverter->convertTo( rVal, rDestType ); +#endif + return sal_False; + } + +#ifdef __RECONVERSION_OUTPUT__ +//= re-conversion output = + if (bCanConvert) + { + // re convert to original type + sal_Bool bReConvert = sal_False; + Any aRet2; + + try + { + aRet2 = s_xConverter->convertTo( aRet, rVal.getValueType() ); + bReConvert = sal_True; + } + catch (const Exception & rExc) + { + aExcMsg = OUStringToOString( rExc.Message, RTL_TEXTENCODING_ISO_8859_1 ); + } + + if (bReConvert) + { + if (rVal != aRet2) + { + printf( "# re-conversion of " ); + printValue( rVal ); + printf( " to " ); + printValue( aRet ); + printf( " to " ); + printValue( aRet2 ); + printf( ": first and last do not match!\n" ); + } + } + else + { + printf( "# re-conversion of " ); + printValue( aRet ); + printf( " to " ); + printf( rVal.getValueType().getTypeName().getStr() ); + printf( " failed! [" ); + printf( aExcMsg.getStr() ); + printf( "]\n" ); + } + } +#endif + + return sal_True; +} + + +typedef struct _ConvBlock +{ + Any _value; + sal_Bool _toString, _toDouble, _toFloat; + sal_Bool _toUINT32, _toINT32, _toUINT16, _toINT16, _toBYTE, _toBOOL, _toChar; + sal_Bool _toTypeClass, _toSeqINT16, _toSeqAny; + + _ConvBlock() + { + } + _ConvBlock( const Any & rValue_, + sal_Bool toString_, sal_Bool toDouble_, sal_Bool toFloat_, + sal_Bool toUINT32_, sal_Bool toINT32_, sal_Bool toUINT16_, sal_Bool toINT16_, + sal_Bool toBYTE_, sal_Bool toBOOL_, sal_Bool toChar_, + sal_Bool toTypeClass_, sal_Bool toSeqINT16_, sal_Bool toSeqAny_ ) + : _value( rValue_ ) + , _toString( toString_ ), _toDouble( toDouble_ ), _toFloat( toFloat_ ) + , _toUINT32( toUINT32_ ), _toINT32( toINT32_ ), _toUINT16( toUINT16_ ), _toINT16( toINT16_ ) + , _toBYTE( toBYTE_ ), _toBOOL( toBOOL_ ), _toChar( toChar_ ) + , _toTypeClass( toTypeClass_ ), _toSeqINT16( toSeqINT16_ ), _toSeqAny( toSeqAny_ ) + { + } +} ConvBlock; + + +static sal_Int32 initBlocks( ConvBlock * pTestBlocks ) +{ + Any aVal; + + sal_uInt32 nElems = 0; + + // ==BYTE== + aVal <<= OUString("0xff"); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 ); + aVal <<= OUString("255"); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 ); + aVal <<= (sal_Int8)0xffu; + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString("0x80"); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 ); + aVal <<= OUString("128"); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 ); + aVal <<= (sal_Int8)( 0x80u ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString("0x7f"); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 ); + aVal <<= OUString("127"); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 ); + aVal <<= (sal_Int8)( 0x7f ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString("5"); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0 ); + aVal <<= OUString("+5"); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 ); + aVal <<= (sal_Int8)( 5 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString("-5"); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (sal_Int8)( -5 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString("256"); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + // ==UINT16== + aVal <<= OUString("65535"); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 ); + aVal <<= OUString("0xffff"); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 ); + aVal <<= (sal_uInt16)( 0xffff ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString("32768"); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 ); + aVal <<= (sal_uInt16)( 0x8000 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString("32767"); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 ); + aVal <<= OUString("0x7fff"); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 ); + aVal <<= (sal_uInt16)( 0x7fff ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString("256"); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 ); + aVal <<= OUString("0x100"); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 ); + aVal <<= (sal_uInt16)( 0x100 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (sal_uInt16)( 5 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (sal_uInt16)( -5 ); // is 0xfffb + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + // ==INT16== + aVal <<= (sal_Int16)( -1 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (sal_Int16)( -0x8000 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (sal_Int16)( 0x7fff ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (sal_Int16)( 0x100 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (sal_Int16)( 5 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (sal_Int16)( -5 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + // ==UINT32== + aVal <<= OUString("+4294967295"); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 ); + aVal <<= OUString("4294967295"); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 ); + aVal <<= OUString("0xffffffff"); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 ); + aVal <<= (sal_uInt32)( 0xffffffff ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString("-2147483648"); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 ); + aVal <<= OUString("-0x80000000"); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (sal_uInt32)( 0x80000000 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString("2147483647"); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 ); + aVal <<= OUString("0x7fffffff"); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 ); + aVal <<= (sal_uInt32)( 0x7fffffff ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString("65536"); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 ); + aVal <<= OUString("0x10000"); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 ); + aVal <<= (sal_uInt32)( 0x10000 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (sal_uInt32)( 0x8000 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (sal_uInt32)( 5 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString("0xfffffffb"); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 ); + aVal <<= (sal_uInt32)( -5 ); // is 0xfffffffb + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + // ==INT32== + aVal <<= (sal_Int32)( 0xffffffff ); // is -1 + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (sal_Int32)( 0x80000000 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (sal_Int32)( 0x7fffffff ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (sal_Int32)( 0x10000 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (sal_Int32)( -0x8001 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (sal_Int32)( 5 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (sal_Int32)( -5 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + // ==FLOAT== + aVal <<= OUString("-3.4e+38"); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ); + aVal <<= (float)( MIN_FLOAT ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString("+3.4e+38"); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ); + aVal <<= (float)( MAX_FLOAT ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString("9e-20"); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 ); + aVal <<= (float)( 9e-20 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString("+.7071067811865"); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 ); + aVal <<= (float)( M_SQRT1_2 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString("3.14159265359"); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 ); + aVal <<= (float)( M_PI ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (float)( 5 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + // ==DOUBLE== + aVal <<= OUString("-1.7976931348623155e+308"); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ); + aVal <<= (double)( MIN_DOUBLE ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString("1.7976931348623155e+308"); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ); + aVal <<= (double)( MAX_DOUBLE ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (double)( MIN_FLOAT ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (double)( MAX_FLOAT ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (double)( -((double)0x80000000) ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (double)( -((double)0x80000001) ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (double)( 0x7fffffff ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (double)( 0x80000000 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (double)( 0xffffffff ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString("0x100000000"); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ); + aVal <<= (double)( SAL_CONST_INT64(0x100000000) ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= (double)( 5 ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + // ==CHAR== + sal_Unicode c = 'A'; + aVal.setValue( &c, cppu::UnoType<cppu::UnoCharType>::get() ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString("A"); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + // ==BOOL== + aVal <<= OUString("0"); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString("1"); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString("False"); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString("true"); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + + sal_Bool bTmp = sal_True; + aVal.setValue( &bTmp, cppu::UnoType<bool>::get() ); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + // ==ZERO STRINGS== + aVal <<= OUString(); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString("-"); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString("-0"); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + // ==TYPECLASS ENUM== + aVal <<= OUString("eNuM"); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal <<= OUString("DOUBLE"); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + int e = 1; + aVal.setValue( &e, cppu::UnoType<TypeClass>::get()); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + aVal.setValue( &e, cppu::UnoType<FieldAccessMode>::get()); + pTestBlocks[nElems++] = ConvBlock( aVal, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + // ==SEQ of INT== + Sequence< sal_Int32 > aINT32Seq( 3 ), aINT32Seq2( 3 ); + sal_Int32 * pINT32Seq = aINT32Seq.getArray(); + pINT32Seq[0] = -32768; + pINT32Seq[1] = 0; + pINT32Seq[2] = 32767; + aVal <<= aINT32Seq; + pTestBlocks[nElems++] = ConvBlock( aVal, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + pINT32Seq = aINT32Seq2.getArray(); + pINT32Seq[0] = -32768; + pINT32Seq[1] = -32769; + pINT32Seq[2] = 32767; + aVal <<= aINT32Seq2; + pTestBlocks[nElems++] = ConvBlock( aVal, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + // ==SEQ of ANY== + Sequence< Any > aAnySeq( 2 ), aAnySeq2( 2 ); + Any * pAnySeq = aAnySeq.getArray(); + pAnySeq[0] = makeAny( aINT32Seq ); + pAnySeq[1] = makeAny( OUString("lala") ); + aVal <<= aAnySeq; + pTestBlocks[nElems++] = ConvBlock( aVal, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + pAnySeq = aAnySeq2.getArray(); + pAnySeq[0] <<= (sal_Int32)4711; + pAnySeq[1] <<= OUString("0815"); + aVal <<= aAnySeq2; + pTestBlocks[nElems++] = ConvBlock( aVal, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1 ); + // st,do,fl,u3,i3,u1,i1,by,bo,ch,tc,si,sa + return nElems; +} + + +static void test_Conversion( const Reference< XMultiServiceFactory > & xMgr ) +{ + printf( "test_Conversion(): start...\n" ); + + Reference< XTypeConverter > xConverter( xMgr->createInstance( "com.sun.star.script.Converter" ), UNO_QUERY ); + + ConvBlock * pTestBlocks = new ConvBlock[256]; + sal_Int32 nPos = initBlocks( pTestBlocks ); + + s_xConverter = xConverter; + while (nPos--) + { + const ConvBlock& rBlock = pTestBlocks[nPos]; + const Any & rVal = rBlock._value; + + convertTo( cppu::UnoType<OUString>::get(), rVal, rBlock._toString ); + convertTo( cppu::UnoType<float>::get(), rVal, rBlock._toFloat ); + convertTo( cppu::UnoType<double>::get(), rVal, rBlock._toDouble ); + convertTo( cppu::UnoType<sal_uInt32>::get(), rVal, rBlock._toUINT32 ); + convertTo( cppu::UnoType<sal_Int32>::get(), rVal, rBlock._toINT32 ); + convertTo( cppu::UnoType<cppu::UnoUnsignedShortType>::get(), rVal, rBlock._toUINT16 ); + convertTo( cppu::UnoType<sal_Int16>::get(), rVal, rBlock._toINT16 ); + convertTo( cppu::UnoType<sal_Int8>::get(), rVal, rBlock._toBYTE ); + convertTo( cppu::UnoType<bool>::get(), rVal, rBlock._toBOOL ); + convertTo( cppu::UnoType<cppu::UnoCharType>::get(), rVal, rBlock._toChar ); + convertTo( cppu::UnoType<TypeClass>::get(), rVal, rBlock._toTypeClass ); + convertTo( cppu::UnoType<Sequence< sal_Int16 >>::get(), rVal, rBlock._toSeqINT16 ); + convertTo( cppu::UnoType<Sequence< Any >>::get(), rVal, rBlock._toSeqAny ); + + convertTo( cppu::UnoType<void>::get(), rVal, sal_True ); // anything converts to void + } + s_xConverter.clear(); + + delete [] pTestBlocks; + + Any aRet; + aRet = xConverter->convertTo( Any( &xMgr, cppu::UnoType<XMultiServiceFactory>::get()), + cppu::UnoType<XServiceInfo>::get()); + aRet = xConverter->convertTo( aRet, cppu::UnoType<XMultiServiceFactory>::get()); + aRet = xConverter->convertTo( aRet, cppu::UnoType<XServiceInfo>::get()); + aRet <<= SAL_CONST_INT64(0x7fffffffffffffff); + aRet = xConverter->convertTo( aRet, cppu::UnoType<sal_uInt64>::get()); + OSL_ASSERT( *(const sal_uInt64 *)aRet.getValue() == SAL_CONST_UINT64(0x7fffffffffffffff) ); + aRet <<= SAL_CONST_UINT64(0xffffffffffffffff); + aRet = xConverter->convertTo( aRet, cppu::UnoType<sal_uInt64>::get()); + OSL_ASSERT( *(const sal_uInt64 *)aRet.getValue() == SAL_CONST_UINT64(0xffffffffffffffff) ); + aRet <<= SAL_CONST_INT64(-1); + aRet = xConverter->convertTo( aRet, cppu::UnoType<sal_Int8>::get()); + OSL_ASSERT( *(const sal_Int8 *)aRet.getValue() == (-1) ); + printf( "test_Conversion(): end.\n" ); +} + +SAL_IMPLEMENT_MAIN() +{ + Reference< XMultiServiceFactory > xMgr( createRegistryServiceFactory( OUString("stoctest.rdb") ) ); + + try + { + Reference< XImplementationRegistration > xImplReg( + xMgr->createInstance("com.sun.star.registry.ImplementationRegistration"), UNO_QUERY ); + OSL_ENSURE( xImplReg.is(), "### no impl reg!" ); + + OUString aLibName("stocservices.uno" SAL_DLLEXTENSION ); + xImplReg->registerImplementation( + OUString("com.sun.star.loader.SharedLibrary"), + aLibName, Reference< XSimpleRegistry >() ); + + test_Conversion( xMgr ); + } + catch (const Exception & rExc) + { + DBG_UNHANDLED_EXCEPTION("stoc", "### exception occurred: " << rExc ); + } + + Reference< XComponent >( xMgr, UNO_QUERY )->dispose(); + return 0; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/stoc/test/testcorefl.cxx b/stoc/test/testcorefl.cxx new file mode 100644 index 0000000000..cd873670b7 --- /dev/null +++ b/stoc/test/testcorefl.cxx @@ -0,0 +1,377 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <sal/config.h> + +#include <sal/log.hxx> +#include <sal/main.h> +#include <osl/diagnose.h> + +#include <cppuhelper/servicefactory.hxx> +#include <cppuhelper/weak.hxx> +#include <cppuhelper/implbase.hxx> + +#include <ModuleA/XInterface1.hpp> +#include <ModuleC/XInterfaceA.hpp> +#include <ModuleC/XInterfaceB.hpp> +#include <ModuleC/ModuleC.hpp> + +#include <com/sun/star/container/XHierarchicalNameAccess.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/reflection/XIdlReflection.hpp> +#include <com/sun/star/reflection/XIdlField2.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/registry/XSimpleRegistry.hpp> +#include <com/sun/star/registry/XImplementationRegistration.hpp> + +#include <rtl/ustrbuf.hxx> + +#include <stdio.h> + +using namespace cppu; +using namespace osl; +using namespace ModuleA; +using namespace ModuleB; +using namespace ModuleC; +using namespace ModuleA::ModuleB; +using namespace com::sun::star; +using namespace css::uno; +using namespace css::lang; +using namespace css::beans; +using namespace css::registry; +using namespace css::reflection; +using namespace css::container; + + +class OInterfaceA : public WeakImplHelper< XInterfaceA > +{ +public: + + virtual void SAL_CALL methodA() throw (RuntimeException) + {} + + virtual void SAL_CALL methodB(sal_Int16 /*aShort*/) throw (RuntimeException) + {} + virtual Sequence< StructB > SAL_CALL methodC(const StructC& /*aStructC*/, StructA& /*aStructA*/) throw (RuntimeException) + { return Sequence< StructB >(); } +}; + + +static inline bool uik_equals( const Uik & rUik1, const Uik & rUik2 ) +{ + return (rUik1.m_Data1 == rUik2.m_Data1 && + rUik1.m_Data2 == rUik2.m_Data2 && + rUik1.m_Data3 == rUik2.m_Data3 && + rUik1.m_Data4 == rUik2.m_Data4 && + rUik1.m_Data5 == rUik2.m_Data5); +} + +static sal_Bool test_corefl( const Reference< XIdlReflection > & xRefl ) +{ + Reference< XIdlClass > xClass; + Reference< XHierarchicalNameAccess > xHNameAccess( xRefl, UNO_QUERY ); + OSL_ENSURE(xHNameAccess.is(), "### cannot get XHierarchicalNameAccess!" ); + + OSL_ENSURE(xRefl->forName("ModuleA.StructA")->getName() == "ModuleA.StructA", "test_RegCoreReflection(): error 2b"); + OSL_ENSURE(xRefl->forName("ModuleA.ExceptionB")->getTypeClass() == TypeClass_EXCEPTION, "test_RegCoreReflection(): error 2c"); + OSL_ENSURE(xRefl->forName("ModuleA.ModuleB.EnumA").is(), "test_RegCoreReflection(): error 2e"); + + + OSL_ENSURE(*(const sal_Bool *)xHNameAccess->getByHierarchicalName(OUString("ModuleC.aConstBoolean")).getValue() == aConstBoolean, "test_RegCoreReflection(): error 4c"); + OSL_ENSURE(*(const sal_Int8 *)xHNameAccess->getByHierarchicalName(OUString("ModuleC.aConstByte")).getValue() == aConstByte, "test_RegCoreReflection(): error 4e"); + OSL_ENSURE(xHNameAccess->getByHierarchicalName(OUString("ModuleC.aConstShort")) == aConstShort, "test_RegCoreReflection(): error 4g"); + OSL_ENSURE(xHNameAccess->getByHierarchicalName(OUString("ModuleC.aConstUShort")) == aConstUShort, "test_RegCoreReflection(): error 4i"); + OSL_ENSURE(xHNameAccess->getByHierarchicalName(OUString("ModuleC.aConstLong")) == aConstLong, "test_RegCoreReflection(): error 4k"); + OSL_ENSURE(xHNameAccess->getByHierarchicalName(OUString("ModuleC.aConstULong")) == aConstULong, "test_RegCoreReflection(): error 4m"); + + // Enums + + xClass = xRefl->forName("ModuleA.ModuleB.EnumA"); + + OSL_ENSURE(xClass.is(), "test_RegCoreReflection(): error 5"); + + Sequence<Reference< XIdlField > > fields = xClass->getFields(); + + OSL_ENSURE( + (fields.getLength() == 3) && + (fields.getArray()[0]->getName() == "VAL_1" ) && + (*(EnumA*)fields.getArray()[0]->get(Any()).getValue() == EnumA_VAL_1) && + (fields.getArray()[1]->getName() == "VAL_2" ) && + (*(EnumA*)fields.getArray()[1]->get(Any()).getValue() == EnumA_VAL_2) && + (fields.getArray()[2]->getName() == "VAL_3" ) && + (*(EnumA*)fields.getArray()[2]->get(Any()).getValue() == EnumA_VAL_3), + "test_RegCoreReflection(): error 6"); + + + // Interface + + Reference< XIdlClass > xA = xRefl->forName("ModuleC.XInterfaceB"); + + xClass = xRefl->forName("ModuleC.XInterfaceB"); + + OSL_ENSURE(xClass == xA, "test_RegCoreReflection(): error 7"); + OSL_ENSURE(xClass.is(), "test_RegCoreReflection(): error 7a"); + + typelib_TypeDescription * pTD = 0; + OUString aModuleName( "ModuleC.XInterfaceB" ); + typelib_typedescription_getByName( &pTD, aModuleName.pData ); + OSL_ENSURE( pTD, "### cannot get typedescription for ModuleC.XInterfaceB!" ); + + OSL_ENSURE( uik_equals( *(Uik *)&((typelib_InterfaceTypeDescription *)pTD)->aUik, + xClass->getUik() ), + "test_RegCoreReflection(): error 8" ); + typelib_typedescription_release( pTD ); + + OSL_ENSURE(xClass->getSuperclasses().getLength() == 1, "test_RegCoreReflection(): error 9"); + OSL_ENSURE(xClass->getSuperclasses().getArray()[0]->getName() == "ModuleC.XInterfaceA", "test_RegCoreReflection(): error 10"); + OSL_ENSURE(xClass->getMethods().getLength() == 7, "test_RegCoreReflection(): error 11"); + OSL_ENSURE(xA->getMethods().getLength() == 7, "test_RegCoreReflection(): error 11a"); + OSL_ENSURE(xClass->getMethods().getArray()[3]->getName() == "methodA", "test_RegCoreReflection(): 12"); + OSL_ENSURE(xClass->getMethods().getArray()[3]->getReturnType()->getTypeClass() == TypeClass_VOID, "test_RegCoreReflection(): error 13"); + OSL_ENSURE(xClass->getMethods().getArray()[3]->getParameterTypes().getLength() == 0, "test_RegCoreReflection(): error 14"); + OSL_ENSURE(xClass->getMethods().getArray()[3]->getExceptionTypes().getLength() == 0, "test_RegCoreReflection(): error 15"); + OSL_ENSURE(xClass->getMethods().getArray()[4]->getName() == "methodB", "test_RegCoreReflection(): error 16"); + OSL_ENSURE(xClass->getMethods().getArray()[4]->getMode() == MethodMode_ONEWAY, "test_RegCoreReflection(): error 16a"); + OSL_ENSURE(xClass->getMethods().getArray()[4]->getReturnType()->getTypeClass() == TypeClass_VOID, "test_RegCoreReflection(): error 16"); + OSL_ENSURE(xClass->getMethods().getArray()[4]->getParameterTypes().getLength() == 1, "test_RegCoreReflection(): error 17"); + OSL_ENSURE(xClass->getMethods().getArray()[4]->getParameterTypes().getArray()[0]->getTypeClass() == TypeClass_SHORT, "test_RegCoreReflection(): error 18"); + OSL_ENSURE(xClass->getMethods().getArray()[4]->getParameterInfos().getArray()[0].aName == "aShort", "test_RegCoreReflection(): error 18a"); + OSL_ENSURE(xClass->getMethods().getArray()[4]->getParameterInfos().getArray()[0].aType == xRefl->forName("short"), "test_RegCoreReflection(): error 18b"); + OSL_ENSURE(xClass->getMethods().getArray()[4]->getParameterInfos().getArray()[0].aMode == ParamMode_IN, "test_RegCoreReflection(): error 18c"); + OSL_ENSURE(xClass->getMethods().getArray()[4]->getExceptionTypes().getLength() == 0, "test_RegCoreReflection(): error 19"); + OSL_ENSURE(xClass->getMethods().getArray()[5]->getName() == "methodC", "test_RegCoreReflection(): error 20"); + OSL_ENSURE(xClass->getMethods().getArray()[5]->getMode() == MethodMode_TWOWAY, "test_RegCoreReflection(): error 20a"); + OSL_ENSURE(xClass->getMethods().getArray()[5]->getReturnType()->getTypeClass() == TypeClass_SEQUENCE, "test_RegCoreReflection(): error 21"); + OSL_ENSURE(xClass->getMethods().getArray()[5]->getReturnType()->getComponentType()->getTypeClass() == TypeClass_STRUCT, "test_RegCoreReflection(): error 22"); + OSL_ENSURE(xClass->getMethods().getArray()[5]->getReturnType()->getComponentType()->getName() == "ModuleA.StructB", "test_RegCoreReflection(): error 23"); + OSL_ENSURE(xClass->getMethods().getArray()[5]->getParameterTypes().getLength() == 2, "test_RegCoreReflection(): error 24"); + OSL_ENSURE(xClass->getMethods().getArray()[5]->getParameterTypes().getArray()[0]->getTypeClass() == TypeClass_STRUCT, "test_RegCoreReflection(): error 25"); + OSL_ENSURE(xClass->getMethods().getArray()[5]->getParameterTypes().getArray()[0]->getName() == "ModuleA.StructC", "test_RegCoreReflection(): error 26"); + OSL_ENSURE(xClass->getMethods().getArray()[5]->getParameterTypes().getArray()[1]->getTypeClass() == TypeClass_STRUCT, "test_RegCoreReflection(): error 27"); + OSL_ENSURE(xClass->getMethods().getArray()[5]->getParameterTypes().getArray()[1]->getName() == "ModuleA.StructA", "test_RegCoreReflection(): error 28"); + OSL_ENSURE(xClass->getMethods().getArray()[5]->getExceptionTypes().getLength() == 0, "test_RegCoreReflection(): error 29"); + OSL_ENSURE(xClass->getMethods().getArray()[6]->getName() == "methodD", "test_RegCoreReflection(): error 30"); + OSL_ENSURE(xClass->getMethods().getArray()[6]->getReturnType()->getTypeClass() == TypeClass_INTERFACE, "test_RegCoreReflection(): error 31"); + OSL_ENSURE(xClass->getMethods().getArray()[6]->getReturnType()->getName() == "ModuleC.XInterfaceA", "test_RegCoreReflection(): error 32"); + OSL_ENSURE(xClass->getMethods().getArray()[6]->getParameterTypes().getLength() == 1, "test_RegCoreReflection(): error 33"); + OSL_ENSURE(xClass->getMethods().getArray()[6]->getParameterTypes().getArray()[0]->getTypeClass() == TypeClass_ENUM, "test_RegCoreReflection(): error 34"); + OSL_ENSURE(xClass->getMethods().getArray()[6]->getParameterTypes().getArray()[0]->getName() == "ModuleA.ModuleB.EnumA", "test_RegCoreReflection(): error 35"); + OSL_ENSURE(xClass->getMethods().getArray()[6]->getExceptionTypes().getLength() == 3, "test_RegCoreReflection(): error 36"); + OSL_ENSURE(xClass->getMethods().getArray()[6]->getExceptionTypes().getArray()[0]->getTypeClass() == TypeClass_EXCEPTION, "test_RegCoreReflection(): error 37"); + OSL_ENSURE(xClass->getMethods().getArray()[6]->getExceptionTypes().getArray()[0]->getName() == "ModuleA.ExceptionA", "test_RegCoreReflection(): error 38"); + OSL_ENSURE(xClass->getMethods().getArray()[6]->getExceptionTypes().getArray()[1]->getTypeClass() == TypeClass_EXCEPTION, "test_RegCoreReflection(): error 38"); + OSL_ENSURE(xClass->getMethods().getArray()[6]->getExceptionTypes().getArray()[1]->getName() == "ModuleA.ExceptionB", "test_RegCoreReflection(): error 39"); + OSL_ENSURE(xClass->getMethods().getArray()[6]->getExceptionTypes().getArray()[2]->getTypeClass() == TypeClass_EXCEPTION, "test_RegCoreReflection(): error 40"); + OSL_ENSURE(xClass->getMethods().getArray()[6]->getExceptionTypes().getArray()[2]->getName() == "ModuleA.ExceptionC", "test_RegCoreReflection(): error 41"); + OSL_ENSURE(xClass->getMethods().getArray()[6]->getExceptionTypes().getArray()[2]->getFields().getLength() == 3, "test_RegCoreReflection(): error 42"); + OSL_ENSURE(xClass->getMethods().getArray()[6]->getExceptionTypes().getArray()[2]->getFields().getArray()[0]->getType()->getTypeClass() == TypeClass_BOOLEAN, "test_RegCoreReflection(): error 43"); + OSL_ENSURE(xClass->getMethods().getArray()[6]->getExceptionTypes().getArray()[2]->getFields().getArray()[0]->getType()->getName() == "boolean", "test_RegCoreReflection(): error 43a"); + OSL_ENSURE(xClass->getMethods().getArray()[6]->getExceptionTypes().getArray()[2]->getFields().getArray()[1]->getType()->getTypeClass() == TypeClass_STRUCT, "test_RegCoreReflection(): error 44"); + OSL_ENSURE(xClass->getMethods().getArray()[6]->getExceptionTypes().getArray()[2]->getFields().getArray()[1]->getType()->getName() == "ModuleA.StructC", "test_RegCoreReflection(): error 45"); + OSL_ENSURE(xClass->getMethods().getArray()[6]->getExceptionTypes().getArray()[2]->getFields().getArray()[2]->getType()->getTypeClass() == TypeClass_INTERFACE, "test_RegCoreReflection(): error 46"); + OSL_ENSURE(xClass->getMethods().getArray()[6]->getExceptionTypes().getArray()[2]->getFields().getArray()[2]->getType()->getName() == "ModuleA.XInterface1", "test_RegCoreReflection(): error 47"); + + // SequenceReflections + + OSL_ENSURE(xRefl->forName("[]ModuleA.StructA")->getTypeClass() == TypeClass_SEQUENCE, "test_RegCoreReflection(): error 48"); + OSL_ENSURE(xRefl->forName("[]ModuleA.StructA")->getComponentType().is(), "test_RegCoreReflection(): error 49"); + OSL_ENSURE(xRefl->forName("[][]ModuleA.StructA")->getComponentType()->getComponentType()->getName() == "ModuleA.StructA", "test_RegCoreReflection(): error 50"); + OSL_ENSURE(xRefl->forName("[]com.sun.star.uno.XInterface") == xRefl->forName("ModuleA.StructC")->getField(OUString("aInterfaceSeq"))->getType(), "test_RegCoreReflection(): error 51"); + + StructC aStructC; + aStructC.aLong = aConstLong; + aStructC.aShort = aConstShort; + aStructC.aFloat = aConstFloat; + aStructC.aDouble = aConstDouble; + aStructC.aInterfaceSeq = Sequence<Reference<XInterface > >(); + + Any aAny; + + xRefl->forName("ModuleA.StructC")->getField(OUString("aInterfaceSeq"))->getType()->createObject(aAny); + + OSL_ENSURE(aAny.getValueType() == cppu::UnoType<Sequence<Reference< XInterface > >>::get(), "test_RegCoreReflection(): error 51a"); + + Any aStructAny(&aStructC, cppu::UnoType<StructC>::get()); + + sal_Int32 nLong = aConstLong * 2; + aAny.setValue( &nLong, cppu::UnoType<sal_Int32>::get()); + + OSL_ENSURE(*(sal_Int32*)xRefl->forName("ModuleA.StructA")->getField(OUString( "aLong" ))->get( + Any(&aStructC, cppu::UnoType<StructC>::get())).getValue() == aConstLong, "test_RegCoreReflection(): error 52"); + OSL_ENSURE(xRefl->forName("ModuleA.StructA")->getField(OUString( "aLong" ))->getAccessMode() == FieldAccessMode_READWRITE, "test_RegCoreReflection(): error 52a"); + Reference< XIdlField2 > rField ( xRefl->forName("ModuleA.StructC")->getField(OUString( "aLong" )) , UNO_QUERY ); + rField->set(aStructAny, aAny); + OSL_ENSURE(*(sal_Int32*)xRefl->forName("ModuleA.StructB")->getField(OUString( "aLong" ))->get(aStructAny).getValue() == *(sal_Int32*)aAny.getValue(), "test_RegCoreReflection(): error 53"); + + xRefl->forName("[]ModuleA.StructA")->createObject(aAny); + + OSL_ENSURE( aAny.getValueTypeName() == "[]ModuleA.StructA", "test_RegCoreReflection(): error 54" ); + xRefl->forName("[][]ModuleA.StructA")->createObject(aAny); + + OSL_ENSURE( aAny.getValueTypeName() == "[][]ModuleA.StructA", "test_RegCoreReflection(): error 56" ); + + OSL_ENSURE(xRefl->forName("[][][]unsigned long")->getComponentType()->getComponentType()->getComponentType()->getTypeClass() == TypeClass_UNSIGNED_LONG, "test_RegCoreReflection(): error 62"); + + try + { + SAL_WARN( "stoc", "case 1" ); + Any bla = xRefl->forName("ModuleA.StructC")->getField(OUString("aString"))->get(Any()); + OSL_ENSURE(sal_False, "test_RegCoreReflection(): error 63"); + return sal_False; + } + catch (IllegalArgumentException &) + { + } + + try + { + SAL_WARN( "stoc", "case 2" ); + Any blup; + blup <<= aStructC; + Any gulp; + rField.set( xRefl->forName("ModuleA.StructC")->getField(OUString("aString")) , UNO_QUERY); + rField->set( blup, gulp); + OSL_ENSURE(sal_False, "test_RegCoreReflection(): error 64"); + return sal_False; + } + catch (IllegalArgumentException &) + { + } + + try + { + SAL_WARN( "stoc", "case 3" ); + Any gulp; + gulp <<= 3.14f; + Any blup; + blup <<= aStructC; + rField.set( xRefl->forName("ModuleA.StructC")->getField(OUString("aString")) , UNO_QUERY); + xRefl->forName("ModuleA.StructC")->getField(OUString("aString"))->set(blup, gulp); + OSL_ENSURE(sal_False, "test_RegCoreReflection(): error 65"); + return sal_False; + } + catch (IllegalArgumentException &) + { + } + + Any gulp; + gulp <<= OUString("Test"); + Any blup; + blup <<= aStructC; + xRefl->forName("ModuleA.StructC")->getField(OUString("aString"))->set(blup, gulp); + + Reference< XInterfaceA > xAI = new OInterfaceA(); + + try + { + Sequence< Any > params; + SAL_WARN( "stoc", "case 4" ); + + Any a; + a <<= xAI; + Any bla = xRefl->forName("ModuleC.XInterfaceA")->getMethod(OUString("methodC"))->invoke(a, params); + OSL_ENSURE(sal_False, "test_RegCoreReflection(): error 66"); + return sal_False; + } + catch (IllegalArgumentException &) + { + } + + StructA aStructA; + + { + Sequence< Any > params(2); + + params.getArray()[0].setValue(&aStructC, cppu::UnoType<StructC>::get()); + params.getArray()[1].setValue(&aStructC, cppu::UnoType<StructC>::get()); + + Any a; + a <<= xAI; + Any bla = xRefl->forName("ModuleC.XInterfaceA")->getMethod(OUString("methodC"))->invoke(a, params); + } + try + { + Sequence< Any > params(2); + + params.getArray()[0].setValue(&aStructA, cppu::UnoType<StructA>::get()); + params.getArray()[1].setValue(&aStructA, cppu::UnoType<StructA>::get()); + + Any a; + a <<= xAI; + Any bla = xRefl->forName("ModuleC.XInterfaceA")->getMethod(OUString("methodC"))->invoke(a, params); + OSL_ENSURE(sal_False, "test_RegCoreReflection(): error 67"); + return sal_False; + } + catch (IllegalArgumentException &) + { + } + + Sequence< Any > params(2); + + params.getArray()[0].setValue(&aStructC, cppu::UnoType<StructC>::get()); + params.getArray()[1].setValue(&aStructA, cppu::UnoType<StructA>::get()); + + Any a; + a <<= xAI; + bool result = (xRefl->forName("ModuleC.XInterfaceA")->getMethod(OUString("methodC"))->invoke(a, params).getValueType() + == cppu::UnoType<Sequence<StructB>>::get()); (void)result; + OSL_ENSURE(result, "test_RegCoreReflection(): error 68"); + + return sal_True; +} + +SAL_IMPLEMENT_MAIN() +{ + sal_Bool bSucc = sal_False; + try + { + OUString aLibName( "reflection.uno" SAL_DLLEXTENSION ); + + Reference< XMultiServiceFactory > xMgr( + createRegistryServiceFactory( + OUString( "stoctest.rdb" ) ) ); + Reference< XComponentContext > xContext; + Reference< beans::XPropertySet > xProps( xMgr, UNO_QUERY ); + OSL_ASSERT( xProps.is() ); + xProps->getPropertyValue( + OUString( "DefaultContext" ) ) >>= + xContext; + OSL_ASSERT( xContext.is() ); + + Reference< XIdlReflection > xRefl; + xContext->getValueByName( + OUString( "/singletons/com.sun.star.reflection.theCoreReflection") ) + >>= xRefl; + OSL_ENSURE( + xRefl.is(), "### CoreReflection singleton not accessible!?" ); + + bSucc = test_corefl( xRefl ); + + Reference< XComponent >( xContext, UNO_QUERY )->dispose(); + } + catch (const Exception & rExc) + { + DBG_UNHANDLED_EXCEPTION("stoc", "### exception occurred: " << rExc ); + } + + printf( "testcorefl %s !\n", (bSucc ? "succeeded" : "failed") ); + return (bSucc ? 0 : -1); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/stoc/test/testcorefl.idl b/stoc/test/testcorefl.idl new file mode 100644 index 0000000000..c345b725bb --- /dev/null +++ b/stoc/test/testcorefl.idl @@ -0,0 +1,93 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +module ModuleA +{ + exception ExceptionA + { + boolean aBoolean; + }; + + struct StructA + { + long aLong; + short aShort; + }; + + struct StructB : StructA + { + double aDouble; + float aFloat; + }; + + struct StructC : StructB + { + string aString; + sequence<com::sun::star::uno::XInterface> aInterfaceSeq; + }; + + exception ExceptionB : ExceptionA + { + StructC aStructC; + }; + + interface XInterface1 : com::sun::star::uno::XInterface + { + }; + + exception ExceptionC : ExceptionB + { + XInterface1 aInterface1; + }; + + module ModuleB + { + enum EnumA { VAL_1, VAL_2, VAL_3 = 17}; + }; + +}; + +module ModuleC +{ + const boolean aConstBoolean = True; + const byte aConstByte = 0; + const short aConstShort = -1; + const unsigned short aConstUShort = 1; + const long aConstLong = -2; + const unsigned long aConstULong = 2; + const float aConstFloat = 3.14; + const double aConstDouble = 3.14e-10; + + + interface XInterfaceA : com::sun::star::uno::XInterface + { + void methodA(); + void methodB([in] short aShort); + sequence<ModuleA::StructB> methodC([in] ModuleA::StructC aStructC, [inout] ModuleA::StructA aStructA); + }; + + interface XInterfaceB : XInterfaceA + { + [attribute] string aString; + + XInterfaceA methodD([in] ModuleA::ModuleB::EnumA aEnumA) raises (ModuleA::ExceptionA, ModuleA::ExceptionB, ModuleA::ExceptionC); + }; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/stoc/test/testiadapter.cxx b/stoc/test/testiadapter.cxx new file mode 100644 index 0000000000..ca5afc4029 --- /dev/null +++ b/stoc/test/testiadapter.cxx @@ -0,0 +1,1051 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#include <stdio.h> + +#include <sal/main.h> +#include <sal/log.hxx> +#include <osl/diagnose.h> + +#include <cppuhelper/servicefactory.hxx> +#include <cppuhelper/weak.hxx> + +#include <test/XLanguageBindingTest.hpp> +#include <com/sun/star/registry/XSimpleRegistry.hpp> +#include <com/sun/star/registry/XImplementationRegistration.hpp> +#include <com/sun/star/script/XInvocation.hpp> +#include <com/sun/star/script/XInvocationAdapterFactory.hpp> +#include <com/sun/star/script/XInvocationAdapterFactory2.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> + +#include <cppuhelper/implbase.hxx> +#include <cmath> + + +using namespace test; +using namespace cppu; +using namespace osl; +using namespace css::uno; +using namespace css::script; +using namespace css::beans; +using namespace css::lang; +using namespace css::reflection; +using namespace css::registry; + + +sal_Bool equals( const test::TestElement & rData1, const test::TestElement & rData2 ) +{ + OSL_ENSURE( rData1.Bool == rData2.Bool, "### bool does not match!" ); + OSL_ENSURE( rData1.Char == rData2.Char, "### char does not match!" ); + OSL_ENSURE( rData1.Byte == rData2.Byte, "### byte does not match!" ); + OSL_ENSURE( rData1.Short == rData2.Short, "### short does not match!" ); + OSL_ENSURE( rData1.UShort == rData2.UShort, "### unsigned short does not match!" ); + OSL_ENSURE( rData1.Long == rData2.Long, "### long does not match!" ); + OSL_ENSURE( rData1.ULong == rData2.ULong, "### unsigned long does not match!" ); + OSL_ENSURE( rData1.Hyper == rData2.Hyper, "### hyper does not match!" ); + OSL_ENSURE( rData1.UHyper == rData2.UHyper, "### unsigned hyper does not match!" ); + OSL_ENSURE( rData1.Float == rData2.Float, "### float does not match!" ); + OSL_ENSURE( rData1.Double == rData2.Double, "### double does not match!" ); + OSL_ENSURE( rData1.Enum == rData2.Enum, "### enum does not match!" ); + OSL_ENSURE( rData1.String == rData2.String, "### string does not match!" ); + OSL_ENSURE( rData1.Interface == rData2.Interface, "### interface does not match!" ); + OSL_ENSURE( 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); +} + +sal_Bool equals( const test::TestData & rData1, const test::TestData & rData2 ) +{ + sal_Int32 nLen; + + if ((rData1.Sequence == rData2.Sequence) && + equals( (const test::TestElement &)rData1, (const test::TestElement &)rData2 ) && + (nLen = rData1.Sequence.getLength()) == rData2.Sequence.getLength()) + { + // once again by hand sequence == + const test::TestElement * pElements1 = rData1.Sequence.getConstArray(); + const test::TestElement * pElements2 = rData2.Sequence.getConstArray(); + for ( ; nLen--; ) + { + if (! equals( pElements1[nLen], pElements2[nLen] )) + { + OSL_FAIL( "### sequence element did not match!" ); + return sal_False; + } + } + return sal_True; + } + return sal_False; +} + +void assign( test::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, + test::TestEnum eEnum, const OUString& rStr, + const css::uno::Reference< css::uno::XInterface >& xTest, + const css::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; +} + +void assign( test::TestData & 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, + test::TestEnum eEnum, const OUString& rStr, + const css::uno::Reference< css::uno::XInterface >& xTest, + const css::uno::Any& rAny, + const css::uno::Sequence< test::TestElement >& rSequence ) +{ + assign( (test::TestElement &)rData, + bBool, cChar, nByte, nShort, nUShort, nLong, nULong, nHyper, nUHyper, fFloat, fDouble, + eEnum, rStr, xTest, rAny ); + rData.Sequence = rSequence; +} + + +class Test_Impl : public WeakImplHelper< XLanguageBindingTest > +{ + test::TestData _aData, _aStructData; + +public: + virtual ~Test_Impl() + { SAL_INFO("stoc", "> scalar Test_Impl dtor <" ); } + + // XLBTestBase + virtual void SAL_CALL setValues( 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, + test::TestEnum eEnum, const OUString& rStr, + const css::uno::Reference< css::uno::XInterface >& xTest, + const css::uno::Any& rAny, + const css::uno::Sequence<test::TestElement >& rSequence, + const test::TestData& rStruct ) + throw(css::uno::RuntimeException); + + virtual test::TestData SAL_CALL setValues2( 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, + test::TestEnum& eEnum, OUString& rStr, + css::uno::Reference< css::uno::XInterface >& xTest, + css::uno::Any& rAny, + css::uno::Sequence<test::TestElement >& rSequence, + test::TestData& rStruct ) + throw(css::uno::RuntimeException); + + virtual test::TestData SAL_CALL getValues( 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, + test::TestEnum& eEnum, OUString& rStr, + css::uno::Reference< css::uno::XInterface >& xTest, + css::uno::Any& rAny, + css::uno::Sequence< test::TestElement >& rSequence, + test::TestData& rStruct ) + throw(css::uno::RuntimeException); + + virtual sal_Bool SAL_CALL getBool() throw(css::uno::RuntimeException) + { return _aData.Bool; } + virtual sal_Int8 SAL_CALL getByte() throw(css::uno::RuntimeException) + { return _aData.Byte; } + virtual sal_Unicode SAL_CALL getChar() throw(css::uno::RuntimeException) + { return _aData.Char; } + virtual sal_Int16 SAL_CALL getShort() throw(css::uno::RuntimeException) + { return _aData.Short; } + virtual sal_uInt16 SAL_CALL getUShort() throw(css::uno::RuntimeException) + { return _aData.UShort; } + virtual sal_Int32 SAL_CALL getLong() throw(css::uno::RuntimeException) + { return _aData.Long; } + virtual sal_uInt32 SAL_CALL getULong() throw(css::uno::RuntimeException) + { return _aData.ULong; } + virtual sal_Int64 SAL_CALL getHyper() throw(css::uno::RuntimeException) + { return _aData.Hyper; } + virtual sal_uInt64 SAL_CALL getUHyper() throw(css::uno::RuntimeException) + { return _aData.UHyper; } + virtual float SAL_CALL getFloat() throw(css::uno::RuntimeException) + { return _aData.Float; } + virtual double SAL_CALL getDouble() throw(css::uno::RuntimeException) + { return _aData.Double; } + virtual test::TestEnum SAL_CALL getEnum() throw(css::uno::RuntimeException) + { return _aData.Enum; } + virtual OUString SAL_CALL getString() throw(css::uno::RuntimeException) + { return _aData.String; } + virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getInterface( ) throw(css::uno::RuntimeException) + { return _aData.Interface; } + virtual css::uno::Any SAL_CALL getAny() throw(css::uno::RuntimeException) + { return _aData.Any; } + virtual css::uno::Sequence< test::TestElement > SAL_CALL getSequence() throw(css::uno::RuntimeException) + { return _aData.Sequence; } + virtual test::TestData SAL_CALL getStruct() throw(css::uno::RuntimeException) + { return _aStructData; } + + virtual void SAL_CALL setBool( sal_Bool _bool ) throw(css::uno::RuntimeException) + { _aData.Bool = _bool; } + virtual void SAL_CALL setByte( sal_Int8 _byte ) throw(css::uno::RuntimeException) + { _aData.Byte = _byte; } + virtual void SAL_CALL setChar( sal_Unicode _char ) throw(css::uno::RuntimeException) + { _aData.Char = _char; } + virtual void SAL_CALL setShort( sal_Int16 _short ) throw(css::uno::RuntimeException) + { _aData.Short = _short; } + virtual void SAL_CALL setUShort( sal_uInt16 _ushort ) throw(css::uno::RuntimeException) + { _aData.UShort = _ushort; } + virtual void SAL_CALL setLong( sal_Int32 _long ) throw(css::uno::RuntimeException) + { _aData.Long = _long; } + virtual void SAL_CALL setULong( sal_uInt32 _ulong ) throw(css::uno::RuntimeException) + { _aData.ULong = _ulong; } + virtual void SAL_CALL setHyper( sal_Int64 _hyper ) throw(css::uno::RuntimeException) + { _aData.Hyper = _hyper; } + virtual void SAL_CALL setUHyper( sal_uInt64 _uhyper ) throw(css::uno::RuntimeException) + { _aData.UHyper = _uhyper; } + virtual void SAL_CALL setFloat( float _float ) throw(css::uno::RuntimeException) + { _aData.Float = _float; } + virtual void SAL_CALL setDouble( double _double ) throw(css::uno::RuntimeException) + { _aData.Double = _double; } + virtual void SAL_CALL setEnum( test::TestEnum _enum ) throw(css::uno::RuntimeException) + { _aData.Enum = _enum; } + virtual void SAL_CALL setString( const OUString& _string ) throw(css::uno::RuntimeException) + { _aData.String = _string; } + virtual void SAL_CALL setInterface( const css::uno::Reference< css::uno::XInterface >& _interface ) throw(css::uno::RuntimeException) + { _aData.Interface = _interface; } + virtual void SAL_CALL setAny( const css::uno::Any& _any ) throw(css::uno::RuntimeException) + { _aData.Any = _any; } + virtual void SAL_CALL setSequence( const css::uno::Sequence<test::TestElement >& _sequence ) throw(css::uno::RuntimeException) + { _aData.Sequence = _sequence; } + virtual void SAL_CALL setStruct( const test::TestData& _struct ) throw(css::uno::RuntimeException) + { _aStructData = _struct; } + + // XLanguageBindingTest + virtual test::TestData SAL_CALL raiseException( 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, test::TestEnum& eEnum, OUString& aString, css::uno::Reference< css::uno::XInterface >& xInterface, css::uno::Any& aAny, css::uno::Sequence<test::TestElement >& aSequence,test::TestData& aStruct ) + throw(css::lang::IllegalArgumentException, css::uno::RuntimeException); + + virtual sal_Int32 SAL_CALL getRuntimeException() throw(css::uno::RuntimeException); + virtual void SAL_CALL setRuntimeException( sal_Int32 _runtimeexception ) throw(css::uno::RuntimeException); +}; + +class XLB_Invocation : public WeakImplHelper< XInvocation > +{ + Reference< XLanguageBindingTest > _xLBT; + +public: + XLB_Invocation( const Reference< XMultiServiceFactory > & /*xMgr*/, + const Reference< XLanguageBindingTest > & xLBT ) + : _xLBT( xLBT ) + {} + + // XInvocation + virtual Reference< XIntrospectionAccess > SAL_CALL getIntrospection() throw(css::uno::RuntimeException) + { return Reference< XIntrospectionAccess >(); } + virtual Any SAL_CALL invoke( const OUString & rFunctionName, + const Sequence< Any > & rParams, + Sequence< sal_Int16 > & rOutParamIndex, + Sequence< Any > & rOutParam ) throw(css::lang::IllegalArgumentException, css::script::CannotConvertException, css::reflection::InvocationTargetException, css::uno::RuntimeException); + virtual void SAL_CALL setValue( const OUString & rPropertyName, const Any & rValue ) throw(css::beans::UnknownPropertyException, css::script::CannotConvertException, css::reflection::InvocationTargetException, css::uno::RuntimeException); + virtual Any SAL_CALL getValue( const OUString & rPropertyName ) throw(css::beans::UnknownPropertyException, css::uno::RuntimeException); + virtual sal_Bool SAL_CALL hasMethod( const OUString & rName ) throw(css::uno::RuntimeException); + virtual sal_Bool SAL_CALL hasProperty( const OUString & rName ) throw(css::uno::RuntimeException); +}; + +Any XLB_Invocation::invoke( const OUString & rFunctionName, + const Sequence< Any > & rParams, + Sequence< sal_Int16 > & rOutParamIndex, + Sequence< Any > & rOutParam ) + throw(css::lang::IllegalArgumentException, css::script::CannotConvertException, css::reflection::InvocationTargetException, css::uno::RuntimeException) +{ + bool bImplementedMethod = true; + + Any aRet; + + OSL_ASSERT( rOutParam.getLength() == 0 ); + OSL_ASSERT( rOutParamIndex.getLength() == 0 ); + + try + { + sal_Bool aBool; + sal_Unicode aChar; + sal_Int8 nByte; + sal_Int16 nShort; + sal_uInt16 nUShort; + sal_Int32 nLong; + sal_uInt32 nULong; + sal_Int64 nHyper; + sal_uInt64 nUHyper; + float fFloat = 0.0; + double fDouble = 0.0; + TestEnum eEnum; + OUString aString; + Reference< XInterface > xInterface; + Any aAny; + Sequence< TestElement > aSeq; + TestData aData; + + if ( rFunctionName == "setValues" ) + { + OSL_ASSERT( rParams.getLength() == 17 ); + aBool = *(sal_Bool *)rParams[0].getValue(); + aChar = *(sal_Unicode *)rParams[1].getValue(); + rParams[2] >>= nByte; + rParams[3] >>= nShort; + rParams[4] >>= nUShort; + rParams[5] >>= nLong; + rParams[6] >>= nULong; + rParams[7] >>= nHyper; + rParams[8] >>= nUHyper; + rParams[9] >>= fFloat; + rParams[10] >>= fDouble; + rParams[11] >>= eEnum; + rParams[12] >>= aString; + rParams[13] >>= xInterface; + rParams[14] >>= aAny; + rParams[15] >>= aSeq; + rParams[16] >>= aData; + + _xLBT->setValues( aBool, aChar, nByte, nShort, nUShort, nLong, nULong, + nHyper, nUHyper, fFloat, fDouble, eEnum, aString, xInterface, + aAny, aSeq, aData ); + + rOutParamIndex.realloc( 0 ); + rOutParam.realloc( 0 ); + } + else if ( rFunctionName == "setValues2" ) + { + aBool = *(sal_Bool *)rParams[0].getValue(); + aChar = *(sal_Unicode *)rParams[1].getValue(); + rParams[2] >>= nByte; + rParams[3] >>= nShort; + rParams[4] >>= nUShort; + rParams[5] >>= nLong; + rParams[6] >>= nULong; + rParams[7] >>= nHyper; + rParams[8] >>= nUHyper; + rParams[9] >>= fFloat; + rParams[10] >>= fDouble; + rParams[11] >>= eEnum; + rParams[12] >>= aString; + rParams[13] >>= xInterface; + rParams[14] >>= aAny; + rParams[15] >>= aSeq; + rParams[16] >>= aData; + + aRet <<= _xLBT->setValues2( aBool, aChar, nByte, nShort, nUShort, nLong, nULong, + nHyper, nUHyper, fFloat, fDouble, eEnum, aString, xInterface, + aAny, aSeq, aData ); + + rOutParamIndex.realloc( 17 ); + rOutParamIndex[0] = 0; + rOutParamIndex[1] = 1; + rOutParamIndex[2] = 2; + rOutParamIndex[3] = 3; + rOutParamIndex[4] = 4; + rOutParamIndex[5] = 5; + rOutParamIndex[6] = 6; + rOutParamIndex[7] = 7; + rOutParamIndex[8] = 8; + rOutParamIndex[9] = 9; + rOutParamIndex[10] = 10; + rOutParamIndex[11] = 11; + rOutParamIndex[12] = 12; + rOutParamIndex[13] = 13; + rOutParamIndex[14] = 14; + rOutParamIndex[15] = 15; + rOutParamIndex[16] = 16; + + rOutParam.realloc( 17 ); + rOutParam[0].setValue( &aBool, cppu::UnoType<bool>::get() ); + rOutParam[1].setValue( &aChar, cppu::UnoType<cppu::UnoCharType>::get() ); + rOutParam[2] <<= nByte; + rOutParam[3] <<= nShort; + rOutParam[4] <<= nUShort; + rOutParam[5] <<= nLong; + rOutParam[6] <<= nULong; + rOutParam[7] <<= nHyper; + rOutParam[8] <<= nUHyper; + rOutParam[9] <<= fFloat; + rOutParam[10] <<= fDouble; + rOutParam[11] <<= eEnum; + rOutParam[12] <<= aString; + rOutParam[13] <<= xInterface; + rOutParam[14] <<= aAny; + rOutParam[15] <<= aSeq; + rOutParam[16] <<= aData; + } + else if ( rFunctionName == "getValues" ) + { + aRet <<= _xLBT->getValues( aBool, aChar, nByte, nShort, nUShort, nLong, nULong, + nHyper, nUHyper, fFloat, fDouble, eEnum, aString, xInterface, + aAny, aSeq, aData ); + + rOutParamIndex.realloc( 17 ); + rOutParamIndex[0] = 0; + rOutParamIndex[1] = 1; + rOutParamIndex[2] = 2; + rOutParamIndex[3] = 3; + rOutParamIndex[4] = 4; + rOutParamIndex[5] = 5; + rOutParamIndex[6] = 6; + rOutParamIndex[7] = 7; + rOutParamIndex[8] = 8; + rOutParamIndex[9] = 9; + rOutParamIndex[10] = 10; + rOutParamIndex[11] = 11; + rOutParamIndex[12] = 12; + rOutParamIndex[13] = 13; + rOutParamIndex[14] = 14; + rOutParamIndex[15] = 15; + rOutParamIndex[16] = 16; + + rOutParam.realloc( 17 ); + rOutParam[0].setValue( &aBool, cppu::UnoType<bool>::get() ); + rOutParam[1].setValue( &aChar, cppu::UnoType<cppu::UnoCharType>::get() ); + rOutParam[2] <<= nByte; + rOutParam[3] <<= nShort; + rOutParam[4] <<= nUShort; + rOutParam[5] <<= nLong; + rOutParam[6] <<= nULong; + rOutParam[7] <<= nHyper; + rOutParam[8] <<= nUHyper; + rOutParam[9] <<= fFloat; + rOutParam[10] <<= fDouble; + rOutParam[11] <<= eEnum; + rOutParam[12] <<= aString; + rOutParam[13] <<= xInterface; + rOutParam[14] <<= aAny; + rOutParam[15] <<= aSeq; + rOutParam[16] <<= aData; + } + else if ( rFunctionName == "raiseException" ) + { + aRet <<= _xLBT->raiseException( aBool, aChar, nByte, nShort, nUShort, nLong, nULong, + nHyper, nUHyper, fFloat, fDouble, eEnum, aString, xInterface, + aAny, aSeq, aData ); + + rOutParamIndex.realloc( 17 ); + rOutParamIndex[0] = 0; + rOutParamIndex[1] = 1; + rOutParamIndex[2] = 2; + rOutParamIndex[3] = 3; + rOutParamIndex[4] = 4; + rOutParamIndex[5] = 5; + rOutParamIndex[6] = 6; + rOutParamIndex[7] = 7; + rOutParamIndex[8] = 8; + rOutParamIndex[9] = 9; + rOutParamIndex[10] = 10; + rOutParamIndex[11] = 11; + rOutParamIndex[12] = 12; + rOutParamIndex[13] = 13; + rOutParamIndex[14] = 14; + rOutParamIndex[15] = 15; + rOutParamIndex[16] = 16; + + rOutParam.realloc( 17 ); + rOutParam[0].setValue( &aBool, cppu::UnoType<bool>::get() ); + rOutParam[1].setValue( &aChar, cppu::UnoType<cppu::UnoCharType>::get() ); + rOutParam[2] <<= nByte; + rOutParam[3] <<= nShort; + rOutParam[4] <<= nUShort; + rOutParam[5] <<= nLong; + rOutParam[6] <<= nULong; + rOutParam[7] <<= nHyper; + rOutParam[8] <<= nUHyper; + rOutParam[9] <<= fFloat; + rOutParam[10] <<= fDouble; + rOutParam[11] <<= eEnum; + rOutParam[12] <<= aString; + rOutParam[13] <<= xInterface; + rOutParam[14] <<= aAny; + rOutParam[15] <<= aSeq; + rOutParam[16] <<= aData; + } + else + { + bImplementedMethod = false; + } + } + catch (const IllegalArgumentException & rExc) + { + // thrown by raiseException() call + InvocationTargetException aExc; + aExc.TargetException <<= rExc; + throw aExc; + } + catch (Exception &) + { + OSL_FAIL( "### unexpected exception caught!" ); + throw; + } + + if (! bImplementedMethod) + { + throw IllegalArgumentException( + OUString( "not an implemented method!" ), + (OWeakObject *)this, 0 ); + } + + return aRet; +} + +void XLB_Invocation::setValue( const OUString & rName, const Any & rValue ) + throw(css::beans::UnknownPropertyException, css::script::CannotConvertException, css::reflection::InvocationTargetException, css::uno::RuntimeException) +{ + if ( rName == "Bool" ) + _xLBT->setBool( *(const sal_Bool *)rValue.getValue() ); + else if ( rName == "Byte" ) + _xLBT->setByte( *(const sal_Int8 *)rValue.getValue() ); + else if ( rName == "Char" ) + _xLBT->setChar( *(const sal_Unicode *)rValue.getValue() ); + else if ( rName == "Short" ) + _xLBT->setShort( *(const sal_Int16 *)rValue.getValue() ); + else if ( rName == "UShort" ) + _xLBT->setUShort( *(const sal_uInt16 *)rValue.getValue() ); + else if ( rName == "Long" ) + _xLBT->setLong( *(const sal_Int32 *)rValue.getValue() ); + else if ( rName == "ULong" ) + _xLBT->setULong( *(const sal_uInt32 *)rValue.getValue() ); + else if ( rName == "Hyper" ) + _xLBT->setHyper( *(const sal_Int64 *)rValue.getValue() ); + else if ( rName == "UHyper" ) + _xLBT->setUHyper( *(const sal_uInt64 *)rValue.getValue() ); + else if ( rName == "Float" ) + _xLBT->setFloat( *(const float *)rValue.getValue() ); + else if ( rName == "Double" ) + _xLBT->setDouble( *(const double *)rValue.getValue() ); + else if ( rName == "Enum" ) + _xLBT->setEnum( *(const TestEnum *)rValue.getValue() ); + else if ( rName == "String" ) + _xLBT->setString( *(const OUString *)rValue.getValue() ); + else if ( rName == "Interface" ) + _xLBT->setInterface( *(const Reference< XInterface > *)rValue.getValue() ); + else if ( rName == "Any" ) + _xLBT->setAny( rValue ); + else if ( rName == "Sequence" ) + _xLBT->setSequence( *(const Sequence< TestElement > *)rValue.getValue() ); + else if ( rName == "Struct" ) + _xLBT->setStruct( *(const TestData *)rValue.getValue() ); + else if ( rName == "RuntimeException" ) + _xLBT->setRuntimeException( *(const sal_Int32 *)rValue.getValue() ); +} + +Any XLB_Invocation::getValue( const OUString & rName ) + throw(css::beans::UnknownPropertyException, css::uno::RuntimeException) +{ + Any aRet; + if ( rName == "Bool" ) + { + sal_Bool aBool = _xLBT->getBool(); + aRet.setValue( &aBool, cppu::UnoType<bool>::get() ); + } + else if ( rName == "Byte" ) + aRet <<= _xLBT->getByte(); + else if ( rName == "Char" ) + { + sal_Unicode aChar = _xLBT->getChar(); + aRet.setValue( &aChar, cppu::UnoType<cppu::UnoCharType>::get() ); + } + else if ( rName == "Short" ) + aRet <<= _xLBT->getShort(); + else if ( rName == "UShort" ) + aRet <<= _xLBT->getUShort(); + else if ( rName == "Long" ) + aRet <<= _xLBT->getLong(); + else if ( rName == "ULong" ) + aRet <<= _xLBT->getULong(); + else if ( rName == "Hyper" ) + aRet <<= _xLBT->getHyper(); + else if ( rName == "UHyper" ) + aRet <<= _xLBT->getUHyper(); + else if ( rName == "Float" ) + aRet <<= _xLBT->getFloat(); + else if ( rName == "Double" ) + aRet <<= _xLBT->getDouble(); + else if ( rName == "Enum" ) + aRet <<= _xLBT->getEnum(); + else if ( rName == "String" ) + aRet <<= _xLBT->getString(); + else if ( rName == "Interface" ) + aRet <<= _xLBT->getInterface(); + else if ( rName == "Any" ) + aRet <<= _xLBT->getAny(); + else if ( rName == "Sequence" ) + aRet <<= _xLBT->getSequence(); + else if ( rName == "Struct" ) + aRet <<= _xLBT->getStruct(); + else if ( rName == "RuntimeException" ) + aRet <<= _xLBT->getRuntimeException(); + return aRet; +} + +sal_Bool XLB_Invocation::hasMethod( const OUString & rName ) + throw(css::uno::RuntimeException) +{ + return (rName == "raiseException" || + rName == "getValues" || + rName == "setValues2" || + rName == "setValues" || + rName == "acquire" || + rName == "release" || + rName == "queryInterface" ); +} + +sal_Bool XLB_Invocation::hasProperty( const OUString & rName ) + throw(css::uno::RuntimeException) +{ + return (rName == "Bool" || + rName == "Byte" || + rName == "Char" || + rName == "Short" || + rName == "UShort" || + rName == "Long" || + rName == "ULong" || + rName == "Hyper" || + rName == "UHyper" || + rName == "Float" || + rName == "Double" || + rName == "Enum" || + rName == "String" || + rName == "Interface" || + rName == "Any" || + rName == "Sequence" || + rName == "Struct" || + rName == "RuntimeException" ); +} + + +void Test_Impl::setValues( 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, + test::TestEnum eEnum, const OUString& rStr, + const css::uno::Reference< css::uno::XInterface >& xTest, + const css::uno::Any& rAny, + const css::uno::Sequence<test::TestElement >& rSequence, + const test::TestData& rStruct ) + throw(css::uno::RuntimeException) +{ + assign( _aData, + bBool, cChar, nByte, nShort, nUShort, nLong, nULong, nHyper, nUHyper, fFloat, fDouble, + eEnum, rStr, xTest, rAny, rSequence ); + _aStructData = rStruct; +} + +test::TestData Test_Impl::setValues2( 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, + test::TestEnum& eEnum, OUString& rStr, + css::uno::Reference< css::uno::XInterface >& xTest, + css::uno::Any& rAny, + css::uno::Sequence<test::TestElement >& rSequence, + test::TestData& rStruct ) + throw(css::uno::RuntimeException) +{ + assign( _aData, + bBool, cChar, nByte, nShort, nUShort, nLong, nULong, nHyper, nUHyper, fFloat, fDouble, + eEnum, rStr, xTest, rAny, rSequence ); + _aStructData = rStruct; + return _aStructData; +} + +test::TestData Test_Impl::getValues( 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, + test::TestEnum& eEnum, OUString& rStr, + css::uno::Reference< css::uno::XInterface >& xTest, + css::uno::Any& rAny, + css::uno::Sequence<test::TestElement >& rSequence, + test::TestData& rStruct ) + throw(css::uno::RuntimeException) +{ + bBool = _aData.Bool; + cChar = _aData.Char; + nByte = _aData.Byte; + nShort = _aData.Short; + nUShort = _aData.UShort; + nLong = _aData.Long; + nULong = _aData.ULong; + nHyper = _aData.Hyper; + nUHyper = _aData.UHyper; + fFloat = _aData.Float; + fDouble = _aData.Double; + eEnum = _aData.Enum; + rStr = _aData.String; + xTest = _aData.Interface; + rAny = _aData.Any; + rSequence = _aData.Sequence; + rStruct = _aStructData; + return _aStructData; +} + + +sal_Bool performTest( const Reference<XLanguageBindingTest > & xLBT ) +{ + OSL_ENSURE( xLBT.is(), "### no test interface!" ); + if (xLBT.is()) + { + // this data is never ever granted access to by calls other than equals(), assign()! + test::TestData aData; // test against this data + + Reference<XInterface > xI( *new OWeakObject() ); + + assign( (test::TestElement &)aData, + sal_True, '@', 17, 0x1234, 0xfedc, 0x12345678, 0xfedcba98, + SAL_CONST_INT64(0x123456789abcdef0), + SAL_CONST_UINT64(0xfedcba9876543210), + (float)17.03125, M_PI, TestEnum_LOLA, OUString("dumdidum"), xI, + Any( &xI, cppu::UnoType<XInterface>::get()) ); + + OSL_ENSURE( aData.Any == xI, "### unexpected any!" ); + OSL_ENSURE( !(aData.Any != xI), "### unexpected any!" ); + + aData.Sequence = Sequence<test::TestElement >( (const test::TestElement *)&aData, 1 ); + // aData complete + + + // this is a manually copy of aData for first setting... + test::TestData aSetData; + + assign( (test::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, cppu::UnoType<XInterface>::get()) ); + + aSetData.Sequence = Sequence<test::TestElement >( (const test::TestElement *)&aSetData, 1 ); + + 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 ); + + { + test::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 ); + + OSL_ASSERT( equals( aData, aRet ) && equals( aData, aRet2 ) ); + + // set last retrieved values + test::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 ); + + OSL_ASSERT( equals( aData, aSV2ret ) && equals( aData, aRet2 ) ); + } + { + test::TestData aRet, aRet2; + test::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 ); + + OSL_ASSERT( equals( aData, aRet ) && equals( aData, aRet2 ) && equals( aData, aGVret ) ); + + // 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 ); + } + { + test::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(); + + return (equals( aData, aRet ) && equals( aData, aRet2 )); + } + } + return sal_False; +} + + +test::TestData Test_Impl::raiseException( 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*/, test::TestEnum& /*eEnum*/, OUString& /*aString*/, css::uno::Reference< css::uno::XInterface >& /*xInterface*/, css::uno::Any& /*aAny*/, css::uno::Sequence< test::TestElement >& /*aSequence*/, test::TestData& /*aStruct*/ ) + throw(css::lang::IllegalArgumentException, css::uno::RuntimeException) +{ + IllegalArgumentException aExc; + aExc.ArgumentPosition = 5; + aExc.Message = "dum dum dum I dance around the circle..."; + aExc.Context = *this; + throw aExc; +} + +sal_Int32 Test_Impl::getRuntimeException() throw(css::uno::RuntimeException) +{ + RuntimeException aExc; + aExc.Message = "dum dum dum I dance around the circle..."; + aExc.Context = *this; + throw aExc; +} + +void Test_Impl::setRuntimeException( sal_Int32 /*_runtimeexception*/ ) throw(css::uno::RuntimeException) +{ + RuntimeException aExc; + aExc.Message = "dum dum dum I dance around the circle..."; + aExc.Context = *this; + throw aExc; +} + + +sal_Bool raiseException( const Reference<XLanguageBindingTest > & xLBT ) +{ + try + { + try + { + try + { + test::TestData aRet, aRet2; + xLBT->raiseException( + 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 ); + return sal_False; + } + catch (const IllegalArgumentException &aExc) + { + OSL_ENSURE( aExc.ArgumentPosition == 5 && + aExc.Message.startsWith("dum dum dum I dance around the circle..."), + "### unexpected exception content!" ); + + Reference<XLanguageBindingTest > xLBT2( + Reference<XLanguageBindingTest >::query( aExc.Context ) ); + + OSL_ENSURE( xLBT2.is(), "### unexpected source of exception!" ); + if (xLBT2.is()) + xLBT2->getRuntimeException(); + else + return sal_False; + } + } + catch (const RuntimeException & rExc) + { + OSL_ENSURE( rExc.Message.startsWith("dum dum dum I dance around the circle..."), + "### unexpected exception content!" ); + + Reference<XLanguageBindingTest > xLBT2( + Reference<XLanguageBindingTest >::query( rExc.Context ) ); + + OSL_ENSURE( xLBT2.is(), "### unexpected source of exception!" ); + if (xLBT2.is()) + xLBT2->setRuntimeException( 0xcafebabe ); + else + return sal_False; + } + } + catch (const Exception & aExc) + { + OSL_ENSURE( aExc.Message.startsWith("dum dum dum I dance around the circle..."), + "### unexpected exception content!" ); + return aExc.Message.startsWith("dum dum dum I dance around the circle..."); + } + return sal_False; +} + + +static sal_Bool test_adapter( const Reference< XMultiServiceFactory > & xMgr ) +{ + Reference< XInvocationAdapterFactory > xAdapFac( + xMgr->createInstance("com.sun.star.script.InvocationAdapterFactory"), UNO_QUERY ); + Reference< XInvocationAdapterFactory2 > xAdapFac2( xAdapFac, UNO_QUERY_THROW ); + + Reference< XLanguageBindingTest > xOriginal( (XLanguageBindingTest *)new Test_Impl() ); + Reference< XInvocation > xInvok( new XLB_Invocation( xMgr, xOriginal ) ); + Reference< XLanguageBindingTest > xLBT( xAdapFac->createAdapter( + xInvok, cppu::UnoType<XLanguageBindingTest>::get()), UNO_QUERY ); + Reference< XLanguageBindingTest > xLBT2( + xAdapFac->createAdapter( + xInvok, cppu::UnoType<XLanguageBindingTest>::get()), UNO_QUERY ); + if (xLBT != xLBT2) + return sal_False; + Reference< XInterface > xLBT3( + xAdapFac->createAdapter( + xInvok, cppu::UnoType<XInterface>::get()), UNO_QUERY ); + if (xLBT != xLBT3) + return sal_False; + Type ar[ 2 ] = { + cppu::UnoType<XLBTestBase>::get(), + cppu::UnoType<XInterface>::get()}; + Reference< XInterface > xLBT4( + xAdapFac2->createAdapter( xInvok, Sequence< Type >( ar, 2 ) ), UNO_QUERY ); + if (xLBT != xLBT4) + return sal_False; + Reference< XSimpleRegistry > xInvalidAdapter( + xAdapFac->createAdapter( + xInvok, cppu::UnoType<XSimpleRegistry>::get()), UNO_QUERY ); + if (xLBT == xInvalidAdapter) + return sal_False; + + try + { + xInvalidAdapter->isValid(); + return sal_False; + } + catch (RuntimeException &) + { + } + + return (performTest( xLBT ) && raiseException( xLBT )); +} + +static sal_Bool test_invocation( const Reference< XMultiServiceFactory > & xMgr ) +{ + Reference< XInvocationAdapterFactory > xAdapFac( + xMgr->createInstance("com.sun.star.script.InvocationAdapterFactory"), UNO_QUERY ); + Reference< XSingleServiceFactory > xInvocFac( + xMgr->createInstance("com.sun.star.script.Invocation"), UNO_QUERY ); + + Reference< XLanguageBindingTest > xOriginal( (XLanguageBindingTest *)new Test_Impl() ); + Any aOriginal( &xOriginal, cppu::UnoType<decltype(xOriginal)>::get() ); + Reference< XInvocation > xInvok( + xInvocFac->createInstanceWithArguments( Sequence< Any >( &aOriginal, 1 ) ), UNO_QUERY ); + + Reference< XLanguageBindingTest > xLBT( xAdapFac->createAdapter( + xInvok, cppu::UnoType<XLanguageBindingTest>::get()), UNO_QUERY ); + + return (performTest( xLBT ) && raiseException( xLBT )); +} + +SAL_IMPLEMENT_MAIN() +{ + Reference< XMultiServiceFactory > xMgr( createRegistryServiceFactory( + OUString( "stoctest.rdb" ) ) ); + + try + { + Reference< XImplementationRegistration > xImplReg( + xMgr->createInstance( "com.sun.star.registry.ImplementationRegistration" ), + UNO_QUERY ); + OSL_ENSURE( xImplReg.is(), "### no impl reg!" ); + + xImplReg->registerImplementation( + OUString("com.sun.star.loader.SharedLibrary"), + OUString("invocadapt.uno" SAL_DLLEXTENSION), + Reference< XSimpleRegistry >() ); + xImplReg->registerImplementation( + OUString("com.sun.star.loader.SharedLibrary"), + OUString("stocservices.uno" SAL_DLLEXTENSION), + Reference< XSimpleRegistry >() ); + xImplReg->registerImplementation( + OUString("com.sun.star.loader.SharedLibrary"), + OUString("invocation.uno" SAL_DLLEXTENSION), + Reference< XSimpleRegistry >() ); + xImplReg->registerImplementation( + OUString("com.sun.star.loader.SharedLibrary"), + OUString("reflection.uno" SAL_DLLEXTENSION), + Reference< XSimpleRegistry >() ); + xImplReg->registerImplementation( + OUString("com.sun.star.loader.SharedLibrary"), + OUString("introspection.uno" SAL_DLLEXTENSION), + Reference< XSimpleRegistry >() ); + + if (test_adapter( xMgr )) + { + fprintf( stderr, "> test_iadapter() succeeded.\n" ); + if (test_invocation( xMgr )) + { + fprintf( stderr, "> test_invocation() succeeded.\n" ); + } + } + } + catch (const Exception & rExc) + { + fprintf( stderr, "> exception occurred: " ); + OString aMsg( OUStringToOString( rExc.Message, RTL_TEXTENCODING_ASCII_US ) ); + fprintf( stderr, "%s\n", aMsg.getStr() ); + } + + Reference< XComponent >( xMgr, UNO_QUERY )->dispose(); + + return 0; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/stoc/test/testintrosp.cxx b/stoc/test/testintrosp.cxx new file mode 100644 index 0000000000..0b56c8564e --- /dev/null +++ b/stoc/test/testintrosp.cxx @@ -0,0 +1,1203 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#include <sal/main.h> +#include <cppuhelper/implbase.hxx> +#include <cppuhelper/servicefactory.hxx> +#include <osl/diagnose.h> + +#include <ModuleA/XIntroTest.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/XIntrospection.hpp> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/beans/PropertyConcept.hpp> +#include <com/sun/star/beans/MethodConcept.hpp> +#include <com/sun/star/beans/XExactName.hpp> +#include <com/sun/star/container/XElementAccess.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/container/XIndexAccess.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/reflection/XIdlReflection.hpp> +#include <com/sun/star/registry/XImplementationRegistration.hpp> +#include <com/sun/star/lang/XComponent.hpp> + +#include <stdio.h> +#include <string.h> +#include <cmath> + +using namespace cppu; +using namespace ModuleA; +using namespace css::uno; +using namespace css::lang; +using namespace css::beans; +using namespace css::registry; +using namespace css::reflection; +using namespace css::container; +using namespace css::beans::PropertyAttribute; + + +#define DEFAULT_INDEX_ACCESS_COUNT 10 +#define DEFAULT_NAME_ACCESS_COUNT 5 + +// Auxiliary function, in order to get from one type XIdlClass +Reference<XIdlClass> TypeToIdlClass( const Type& rType, const Reference< XMultiServiceFactory > & xMgr ) +{ + static Reference< XIdlReflection > xRefl; + + // register void as default class + Reference<XIdlClass> xRetClass; + typelib_TypeDescription * pTD = 0; + rType.getDescription( &pTD ); + if( pTD ) + { + OUString sOWName( pTD->pTypeName ); + if( !xRefl.is() ) + { + xRefl.set( xMgr->createInstance( "com.sun.star.reflection.CoreReflection" ), UNO_QUERY ); + OSL_ENSURE( xRefl.is(), "### no corereflection!" ); + } + xRetClass = xRefl->forName( sOWName ); + } + return xRetClass; +} + + +// Helper function to convert Any to UString +// TODO: This code could be moved to a more central place. +// Currently it's used only for simple data types. + +OUString AnyToString( const Any& aValue, sal_Bool bIncludeType, const Reference< XMultiServiceFactory > & xMgr ) +{ + Type aValType = aValue.getValueType(); + TypeClass eType = aValType.getTypeClass(); + char pBuffer[50]; + + OUString aRetStr; + switch( eType ) + { + case TypeClass_TYPE: aRetStr = "TYPE TYPE"; break; + case TypeClass_INTERFACE: aRetStr = "TYPE INTERFACE"; break; + case TypeClass_SERVICE: aRetStr = "TYPE SERVICE"; break; + case TypeClass_STRUCT: aRetStr = "TYPE STRUCT"; break; + case TypeClass_TYPEDEF: aRetStr = "TYPE TYPEDEF"; break; + case TypeClass_ENUM: aRetStr = "TYPE ENUM"; break; + case TypeClass_EXCEPTION: aRetStr = "TYPE EXCEPTION"; break; + case TypeClass_SEQUENCE: aRetStr = "TYPE SEQUENCE"; break; + case TypeClass_VOID: aRetStr = "TYPE void"; break; + case TypeClass_ANY: aRetStr = "TYPE any"; break; + case TypeClass_UNKNOWN: aRetStr = "TYPE unknown"; break; + case TypeClass_BOOLEAN: + { + sal_Bool b = *(sal_Bool*)aValue.getValue(); + aRetStr = OUString::valueOf( b ); + break; + } + case TypeClass_CHAR: + { + sal_Unicode c = *(sal_Unicode*)aValue.getValue(); + aRetStr = OUString::valueOf( c ); + break; + } + case TypeClass_STRING: + { + aValue >>= aRetStr; + break; + } + case TypeClass_FLOAT: + { + float f(0.0); + aValue >>= f; + snprintf( pBuffer, sizeof( pBuffer ), "%f", f ); + aRetStr = OUString( pBuffer, strlen( pBuffer ), RTL_TEXTENCODING_ASCII_US ); + break; + } + case TypeClass_DOUBLE: + { + double d(0.0); + aValue >>= d; + snprintf( pBuffer, sizeof( pBuffer ), "%f", d ); + aRetStr = OUString( pBuffer, strlen( pBuffer ), RTL_TEXTENCODING_ASCII_US ); + break; + } + case TypeClass_BYTE: + { + sal_Int8 n(0); + aValue >>= n; + aRetStr = OUString::valueOf( (sal_Int32) n ); + break; + } + case TypeClass_SHORT: + { + sal_Int16 n(0); + aValue >>= n; + aRetStr = OUString::valueOf( (sal_Int32) n ); + break; + } + case TypeClass_LONG: + { + sal_Int32 n(0); + aValue >>= n; + aRetStr = OUString::valueOf( n ); + break; + } + default: ; + } + + if( bIncludeType ) + { + Reference< XIdlClass > xIdlClass = TypeToIdlClass( aValType, xMgr ); + aRetStr += " (Typ: " + xIdlClass->getName() + ")"; + } + return aRetStr; +} + +// XPropertySetInfo for test class + +class ImplPropertySetInfo : public WeakImplHelper< XPropertySetInfo > +{ + friend class ImplIntroTest; + + Reference< XMultiServiceFactory > mxMgr; + +public: + explicit ImplPropertySetInfo( const Reference< XMultiServiceFactory > & xMgr ) + : mxMgr( xMgr ) {} + + // Methods of XPropertySetInfo + virtual Sequence< Property > SAL_CALL getProperties( ) + throw(RuntimeException); + virtual Property SAL_CALL getPropertyByName( const OUString& aName ) + throw(UnknownPropertyException, RuntimeException); + virtual sal_Bool SAL_CALL hasPropertyByName( const OUString& Name ) + throw(RuntimeException); +}; + + +Sequence< Property > ImplPropertySetInfo::getProperties() + throw( RuntimeException ) +{ + static Sequence<Property> * pSeq = NULL; + + if( !pSeq ) + { + // Create information for the properties "Width", "Height" and "Name" + pSeq = new Sequence<Property>( 3 ); + Property * pAry = pSeq->getArray(); + + pAry[0].Name = "Factor"; + pAry[0].Handle = -1; + pAry[0].Type = cppu::UnoType<double>::get(); + pAry[0].Attributes = BOUND | TRANSIENT; + + pAry[1].Name = "MyCount"; + pAry[1].Handle = -1; + pAry[1].Type = cppu::UnoType<sal_Int32>::get(); + pAry[1].Attributes = BOUND | TRANSIENT; + + pAry[2].Name = "Info"; + pAry[2].Handle = -1; + pAry[2].Type = cppu::UnoType<OUString>::get(); + pAry[2].Attributes = TRANSIENT; + } + // Return information about all three properties + return *pSeq; +} + +Property ImplPropertySetInfo::getPropertyByName(const OUString& Name) + throw( UnknownPropertyException, RuntimeException ) +{ + Sequence<Property> aSeq = getProperties(); + const Property * pAry = aSeq.getConstArray(); + + for( sal_Int32 i = aSeq.getLength(); i--; ) + { + if( pAry[i].Name == Name ) + return pAry[i]; + } + // Property unknown, also return empty ones + return Property(); +} + +sal_Bool ImplPropertySetInfo::hasPropertyByName(const OUString& Name) + throw( RuntimeException ) +{ + Sequence<Property> aSeq = getProperties(); + const Property * pAry = aSeq.getConstArray(); + + for( sal_Int32 i = aSeq.getLength(); i--; ) + { + if( pAry[i].Name == Name ) + return sal_True; + } + // Property unknown, also return empty ones + return sal_False; +} + + +class ImplIntroTest : public WeakImplHelper< XIntroTest, XPropertySet, XNameAccess, XIndexAccess > +{ + Reference< XMultiServiceFactory > mxMgr; + + friend class ImplPropertySetInfo; + + // Properties for the PropertySet + Any aAnyArray[10]; + + Reference< XPropertySetInfo > m_xMyInfo; + + OUString m_ObjectName; + + sal_Int16 m_nMarkusAge; + sal_Int16 m_nMarkusChildrenCount; + + long m_lDroenk; + sal_Int16 m_nBla; + sal_Int16 m_nBlub; + sal_Int16 m_nGulp; + sal_Int16 m_nLaber; + TypeClass eTypeClass; + Sequence< OUString > aStringSeq; + Sequence< Sequence< Sequence< sal_Int16 > > > aMultSeq; + Reference< XIntroTest > m_xIntroTest; + + // Data for NameAccess + Reference< XIntroTest >* pNameAccessTab; + + // Data for IndexAccess + Reference< XIntroTest >* pIndexAccessTab; + sal_Int16 iIndexAccessCount; + + // struct properties + Property m_aFirstStruct; + PropertyValue m_aSecondStruct; + + // remember listener (one listener per property) + Reference< XPropertyChangeListener > aPropChangeListener; + OUString aPropChangeListenerStr; + Reference< XVetoableChangeListener > aVetoPropChangeListener; + OUString aVetoPropChangeListenerStr; + + void Init(); + +public: + explicit ImplIntroTest( const Reference< XMultiServiceFactory > & xMgr ) + : mxMgr( xMgr ) + { + Init(); + } + + // despite virtual inline, to simplify coding (testing only) + // XPropertySet + virtual Reference< XPropertySetInfo > SAL_CALL getPropertySetInfo( ) + throw(RuntimeException); + virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const Any& aValue ) + throw(UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException); + virtual Any SAL_CALL getPropertyValue( const OUString& PropertyName ) + throw(UnknownPropertyException, WrappedTargetException, RuntimeException); + virtual void SAL_CALL addPropertyChangeListener( const OUString& /*aPropertyName*/, const Reference< XPropertyChangeListener >& /*xListener*/ ) + throw(UnknownPropertyException, WrappedTargetException, RuntimeException) + {} + virtual void SAL_CALL removePropertyChangeListener( const OUString& /*aPropertyName*/, const Reference< XPropertyChangeListener >& /*aListener*/ ) + throw(UnknownPropertyException, WrappedTargetException, RuntimeException) + {} + virtual void SAL_CALL addVetoableChangeListener( const OUString& /*PropertyName*/, const Reference< XVetoableChangeListener >& /*aListener*/ ) + throw(UnknownPropertyException, WrappedTargetException, RuntimeException) + {} + virtual void SAL_CALL removeVetoableChangeListener( const OUString& /*PropertyName*/, const Reference< XVetoableChangeListener >& /*aListener*/ ) + throw(UnknownPropertyException, WrappedTargetException, RuntimeException) + {} + + // XIntroTest methods + // Attributes + virtual OUString SAL_CALL getObjectName() throw(RuntimeException) + { return m_ObjectName; } + virtual void SAL_CALL setObjectName( const OUString& _objectname ) throw(RuntimeException) + { m_ObjectName = _objectname; } + virtual OUString SAL_CALL getFirstName() + throw(RuntimeException); + virtual OUString SAL_CALL getLastName() throw(RuntimeException) + { return OUString("Meyer"); } + virtual sal_Int16 SAL_CALL getAge() throw(RuntimeException) + { return m_nMarkusAge; } + virtual sal_Int16 SAL_CALL getChildrenCount() throw(RuntimeException) + { return m_nMarkusChildrenCount; } + virtual void SAL_CALL setChildrenCount( sal_Int16 _childrencount ) throw(RuntimeException) + { m_nMarkusChildrenCount = _childrencount; } + virtual Property SAL_CALL getFirstStruct() throw(RuntimeException) + { return m_aFirstStruct; } + virtual void SAL_CALL setFirstStruct( const Property& _firststruct ) throw(RuntimeException) + { m_aFirstStruct = _firststruct; } + virtual PropertyValue SAL_CALL getSecondStruct() throw(RuntimeException) + { return m_aSecondStruct; } + virtual void SAL_CALL setSecondStruct( const PropertyValue& _secondstruct ) throw(RuntimeException) + { m_aSecondStruct = _secondstruct; } + + // Methods + virtual void SAL_CALL writeln( const OUString& Text ) + throw(RuntimeException); + virtual sal_Int32 SAL_CALL getDroenk( ) throw(RuntimeException) + { return m_lDroenk; } + virtual Reference< ::ModuleA::XIntroTest > SAL_CALL getIntroTest( ) throw(RuntimeException); + virtual sal_Int32 SAL_CALL getUps( sal_Int32 l ) throw(RuntimeException) + { return 2*l; } + virtual void SAL_CALL setDroenk( sal_Int32 l ) throw(RuntimeException) + { m_lDroenk = l; } + virtual sal_Int16 SAL_CALL getBla( ) throw(RuntimeException) + { return m_nBla; } + virtual void SAL_CALL setBla( sal_Int32 n ) throw(RuntimeException) + { m_nBla = (sal_Int16)n; } + virtual sal_Int16 SAL_CALL getBlub( ) throw(RuntimeException) + { return m_nBlub; } + virtual void SAL_CALL setBlub( sal_Int16 n ) throw(RuntimeException) + { m_nBlub = n; } + virtual sal_Int16 SAL_CALL getGulp( ) throw(RuntimeException) + { return m_nGulp; } + virtual sal_Int16 SAL_CALL setGulp( sal_Int16 n ) throw(RuntimeException) + { m_nGulp = n; return 1; } + virtual TypeClass SAL_CALL getTypeClass( sal_Int16 /*n*/ ) throw(RuntimeException) + { return eTypeClass; } + virtual void SAL_CALL setTypeClass( TypeClass t, double /*d1*/, double /*d2*/ ) throw(RuntimeException) + { eTypeClass = t; } + virtual Sequence< OUString > SAL_CALL getStrings( ) throw(RuntimeException) + { return aStringSeq; } + virtual void SAL_CALL setStrings( const Sequence< OUString >& Strings ) throw(RuntimeException) + { aStringSeq = Strings; } + virtual void SAL_CALL setStringsPerMethod( const Sequence< OUString >& Strings, sal_Int16 /*n*/ ) throw(RuntimeException) + { aStringSeq = Strings; } + virtual Sequence< Sequence< Sequence< sal_Int16 > > > SAL_CALL getMultiSequence( ) throw(RuntimeException) + { return aMultSeq; } + virtual void SAL_CALL setMultiSequence( const Sequence< Sequence< Sequence< sal_Int16 > > >& Seq ) throw(RuntimeException) + { aMultSeq = Seq; } + virtual void SAL_CALL addPropertiesChangeListener( const Sequence< OUString >& PropertyNames, const Reference< XPropertiesChangeListener >& Listener ) + throw(RuntimeException); + virtual void SAL_CALL removePropertiesChangeListener( const Reference< XPropertiesChangeListener >& Listener ) + throw(RuntimeException); + + + // Methods of XElementAccess + virtual Type SAL_CALL getElementType( ) + throw(RuntimeException); + virtual sal_Bool SAL_CALL hasElements( ) + throw(RuntimeException); + + // XNameAccess methods + // Methods + virtual Any SAL_CALL getByName( const OUString& aName ) + throw(NoSuchElementException, WrappedTargetException, RuntimeException); + virtual Sequence< OUString > SAL_CALL getElementNames( ) + throw(RuntimeException); + virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) + throw(RuntimeException); + + // XIndexAccess methods + // Methods + virtual sal_Int32 SAL_CALL getCount( ) + throw(RuntimeException); + virtual Any SAL_CALL getByIndex( sal_Int32 Index ) + throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException); +}; + +void ImplIntroTest::Init() +{ + // set unique name + static sal_Int32 nObjCount = 0; + OUString aName( "IntroTest-Obj Nr. " ); + aName += OUString::valueOf( nObjCount ); + setObjectName( aName ); + + // initialize properties + aAnyArray[0] <<= 3.14; + aAnyArray[1] <<= (sal_Int32)42; + aAnyArray[2] <<= OUString( "Hallo" ); + + // fetch PropertySetInfo once for internal use + m_xMyInfo = getPropertySetInfo(); + m_xMyInfo->acquire(); // otherwise it could crash at shutdown + + m_nMarkusAge = 33; + m_nMarkusChildrenCount = 2; + + m_lDroenk = 314; + m_nBla = 42; + m_nBlub = 111; + m_nGulp = 99; + m_nLaber = 1; + eTypeClass = TypeClass_INTERFACE; + + // string sequence initialization + aStringSeq.realloc( 3 ); + aStringSeq[ 0 ] = "String 0"; + aStringSeq[ 1 ] = "String 1"; + aStringSeq[ 2 ] = "String 2"; + + // structs initialization + m_aFirstStruct.Name = "FirstStruct-Name"; + m_aFirstStruct.Handle = 77777; + //XIdlClassRef Type; + m_aFirstStruct.Attributes = -222; + + //XInterfaceRef Source; + Any Value; + Value <<= M_E; + m_aSecondStruct.Value = Value; + //XIdlClassRef ListenerType; + m_aSecondStruct.State = PropertyState_DIRECT_VALUE; + + // IndexAccess + iIndexAccessCount = DEFAULT_INDEX_ACCESS_COUNT; + pIndexAccessTab = NULL; + pNameAccessTab = NULL; +} + +Reference< XPropertySetInfo > ImplIntroTest::getPropertySetInfo() + throw(RuntimeException) +{ + static ImplPropertySetInfo aInfo( mxMgr ); + // All objects have the same Properties, so + // the Info is the same for all + return &aInfo; +} + +void ImplIntroTest::setPropertyValue( const OUString& aPropertyName, const Any& aValue ) + throw(UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException) +{ + if( aPropChangeListener.is() && aPropertyName == aPropChangeListenerStr ) + { + PropertyChangeEvent aEvt; + aEvt.Source = (OWeakObject*)this; + aEvt.PropertyName = aPropertyName; + aEvt.PropertyHandle = 0; + aPropChangeListener->propertyChange( aEvt ); + } + if( aVetoPropChangeListener.is() && aPropertyName == aVetoPropChangeListenerStr ) + { + PropertyChangeEvent aEvt; + aEvt.Source = (OWeakObject*)this; + aEvt.PropertyName = aVetoPropChangeListenerStr; + aEvt.PropertyHandle = 0; + aVetoPropChangeListener->vetoableChange( aEvt ); + } + + Sequence<Property> aPropSeq = m_xMyInfo->getProperties(); + sal_Int32 nLen = aPropSeq.getLength(); + for( sal_Int32 i = 0 ; i < nLen ; i++ ) + { + Property aProp = aPropSeq.getArray()[ i ]; + if( aProp.Name == aPropertyName ) + aAnyArray[i] = aValue; + } +} + +Any ImplIntroTest::getPropertyValue( const OUString& PropertyName ) + throw(UnknownPropertyException, WrappedTargetException, RuntimeException) +{ + Sequence<Property> aPropSeq = m_xMyInfo->getProperties(); + sal_Int32 nLen = aPropSeq.getLength(); + for( sal_Int32 i = 0 ; i < nLen ; i++ ) + { + Property aProp = aPropSeq.getArray()[ i ]; + if( aProp.Name == PropertyName ) + return aAnyArray[i]; + } + return Any(); +} + +OUString ImplIntroTest::getFirstName() + throw(RuntimeException) +{ + return OUString("Markus"); +} + +void ImplIntroTest::writeln( const OUString& Text ) + throw(RuntimeException) +{ + OString aStr( Text.getStr(), Text.getLength(), RTL_TEXTENCODING_ASCII_US ); + + printf( "%s", aStr.getStr() ); +} + +Reference< XIntroTest > ImplIntroTest::getIntroTest() + throw(RuntimeException) +{ + if( !m_xIntroTest.is() ) + m_xIntroTest = new ImplIntroTest( mxMgr ); + return m_xIntroTest; +} + +// Methods of XElementAccess +Type ImplIntroTest::getElementType( ) + throw(RuntimeException) +{ + // TODO + Type aRetType; + return aRetType; +} + +sal_Bool ImplIntroTest::hasElements( ) + throw(RuntimeException) +{ + return sal_True; +} + +// XNameAccess methods +sal_Int32 getIndexForName( const OUString& ItemName ) +{ + OUString aLeftStr = ItemName.copy( 0, 4 ); + if( aLeftStr == "Item" ) + { + // TODO + OUString aNumStr = ItemName.copy( 4 ); + } + return -1; +} + + +Any ImplIntroTest::getByName( const OUString& aName ) + throw(NoSuchElementException, WrappedTargetException, RuntimeException) +{ + Any aRetAny; + + if( !pNameAccessTab ) + pNameAccessTab = new Reference< XIntroTest >[ DEFAULT_NAME_ACCESS_COUNT ]; + + sal_Int32 iIndex = getIndexForName( aName ); + if( iIndex != -1 ) + { + if( !pNameAccessTab[iIndex].is() ) + { + ImplIntroTest* p = new ImplIntroTest( mxMgr ); + OUString aName2( "IntroTest by Name-Access, Index = " ); + aName2 += OUString::valueOf( iIndex ); + p->setObjectName( aName2 ); + pNameAccessTab[iIndex] = p; + } + + Reference< XIntroTest > xRet = pNameAccessTab[iIndex]; + aRetAny = makeAny( xRet ); + } + return aRetAny; +} + +Sequence< OUString > ImplIntroTest::getElementNames( ) + throw(RuntimeException) +{ + Sequence<OUString> aStrSeq( DEFAULT_NAME_ACCESS_COUNT ); + OUString* pStr = aStrSeq.getArray(); + for( sal_Int32 i = 0 ; i < DEFAULT_NAME_ACCESS_COUNT ; i++ ) + { + OUString aName( "Item" ); + aName += OUString::valueOf( i ); + pStr[i] = aName; + } + return aStrSeq; +} + +sal_Bool ImplIntroTest::hasByName( const OUString& aName ) + throw(RuntimeException) +{ + return ( getIndexForName( aName ) != -1 ); +} + +// XIndexAccess methods +sal_Int32 ImplIntroTest::getCount( ) + throw(RuntimeException) +{ + return iIndexAccessCount; +} + +Any ImplIntroTest::getByIndex( sal_Int32 Index ) + throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException) +{ + Any aRetAny; + + if( !pIndexAccessTab ) + pIndexAccessTab = new Reference< XIntroTest >[ iIndexAccessCount ]; + + if( Index < iIndexAccessCount ) + { + if( !pNameAccessTab[Index].is() ) + { + ImplIntroTest* p = new ImplIntroTest( mxMgr ); + OUString aName( "IntroTest by Index-Access, Index = " ); + aName += OUString::valueOf( Index ); + p->setObjectName( aName ); + pIndexAccessTab[Index] = p; + } + Reference< XIntroTest > xRet = pIndexAccessTab[Index]; + aRetAny = makeAny( xRet ); + } + return aRetAny; +} + +void ImplIntroTest::addPropertiesChangeListener( const Sequence< OUString >& /*PropertyNames*/, + const Reference< XPropertiesChangeListener >& /*Listener*/ ) + throw(RuntimeException) +{ +} + +void ImplIntroTest::removePropertiesChangeListener +( const Reference< XPropertiesChangeListener >& /*Listener*/ ) + throw(RuntimeException) +{ +} + + +struct DefItem +{ + char const * pName; + sal_Int32 nConcept; +}; + +// special value for method concept, to mark "normal" functions +#define MethodConcept_NORMAL_IMPL 0x80000000 + + +// return test object +Any getIntrospectionTestObject( const Reference< XMultiServiceFactory > & xMgr ) +{ + Any aObjAny; + Reference< XIntroTest > xTestObj = new ImplIntroTest( xMgr ); + aObjAny.setValue( &xTestObj, cppu::UnoType<XIntroTest>::get()); + return aObjAny; +} + +static sal_Bool test_introsp( Reference< XMultiServiceFactory > xMgr, + Reference< XIdlReflection > /*xRefl*/, Reference< XIntrospection > xIntrospection ) +{ + DefItem pPropertyDefs[] = + { + { "Factor", PropertyConcept::PROPERTYSET }, + { "MyCount", PropertyConcept::PROPERTYSET }, + { "Info", PropertyConcept::PROPERTYSET }, + { "ObjectName", PropertyConcept::ATTRIBUTES }, + { "FirstName", PropertyConcept::ATTRIBUTES }, + { "LastName", PropertyConcept::ATTRIBUTES }, + { "Age", PropertyConcept::ATTRIBUTES }, + { "ChildrenCount", PropertyConcept::ATTRIBUTES }, + { "FirstStruct", PropertyConcept::ATTRIBUTES }, + { "SecondStruct", PropertyConcept::ATTRIBUTES }, + { "Droenk", PropertyConcept::METHODS }, + { "IntroTest", PropertyConcept::METHODS }, + { "Bla", PropertyConcept::METHODS }, + { "Blub", PropertyConcept::METHODS }, + { "Gulp", PropertyConcept::METHODS }, + { "Strings", PropertyConcept::METHODS }, + { "MultiSequence", PropertyConcept::METHODS }, + { "PropertySetInfo", PropertyConcept::METHODS }, + { "ElementType", PropertyConcept::METHODS }, + { "ElementNames", PropertyConcept::METHODS }, + { "Count", PropertyConcept::METHODS }, + { "Types", PropertyConcept::METHODS }, + { "ImplementationId", PropertyConcept::METHODS }, + { NULL, 0 } + }; + + char const * pDemandedPropVals[] = + { + "3.140000", + "42", + "Hallo", + "IntroTest-Obj Nr. 0", + "Markus", + "Meyer", + "33", + "2", + "TYPE STRUCT", + "TYPE STRUCT", + "314", + "TYPE INTERFACE", + "42", + "111", + "99", + "TYPE SEQUENCE", + "TYPE SEQUENCE", + "TYPE INTERFACE", + "TYPE TYPE", + "TYPE SEQUENCE", + "10", + "TYPE SEQUENCE", + "TYPE SEQUENCE", + }; + + char const * pDemandedModifiedPropVals[] = + { + "4.140000", + "43", + "Hallo (Modified!)", + "IntroTest-Obj Nr. 0 (Modified!)", + "Markus", + "Meyer", + "33", + "3", + "Value has not been modified", + "Value has not been modified", + "315", + "Value has not been modified", + "42", + "112", + "99", + "Value has not been modified", + "Value has not been modified", + "Value has not been modified", + "Value has not been modified", + "Value has not been modified", + "10", + "Value has not been modified", + "Value has not been modified", + }; + + char const * pDemandedPropTypes[] = + { + "double", + "long", + "string", + "string", + "string", + "string", + "short", + "short", + "com.sun.star.beans.Property", + "com.sun.star.beans.PropertyValue", + "long", + "ModuleA.XIntroTest", + "short", + "short", + "short", + "[]string", + "[][][]short", + "com.sun.star.beans.XPropertySetInfo", + "type", + "[]string", + "long", + "[]type", + "[]byte", + }; + + DefItem pMethodDefs[] = + { + { "queryInterface", MethodConcept_NORMAL_IMPL }, + { "acquire", MethodConcept::DANGEROUS }, + { "release", MethodConcept::DANGEROUS }, + { "writeln", MethodConcept_NORMAL_IMPL }, + { "getDroenk", MethodConcept::PROPERTY }, + { "getIntroTest", MethodConcept::PROPERTY }, + { "getUps", MethodConcept_NORMAL_IMPL }, + { "setDroenk", MethodConcept::PROPERTY }, + { "getBla", MethodConcept::PROPERTY }, + { "setBla", MethodConcept_NORMAL_IMPL }, + { "getBlub", MethodConcept::PROPERTY }, + { "setBlub", MethodConcept::PROPERTY }, + { "getGulp", MethodConcept::PROPERTY }, + { "setGulp", MethodConcept_NORMAL_IMPL }, + { "getTypeClass", MethodConcept_NORMAL_IMPL }, + { "setTypeClass", MethodConcept_NORMAL_IMPL }, + { "getStrings", MethodConcept::PROPERTY }, + { "setStrings", MethodConcept::PROPERTY }, + { "setStringsPerMethod", MethodConcept_NORMAL_IMPL }, + { "getMultiSequence", MethodConcept::PROPERTY }, + { "setMultiSequence", MethodConcept::PROPERTY }, + { "addPropertiesChangeListener", MethodConcept::LISTENER }, + { "removePropertiesChangeListener", MethodConcept::LISTENER }, + { "getPropertySetInfo", MethodConcept::PROPERTY }, + { "setPropertyValue", MethodConcept_NORMAL_IMPL }, + { "getPropertyValue", MethodConcept_NORMAL_IMPL }, + { "addPropertyChangeListener", MethodConcept::LISTENER }, + { "removePropertyChangeListener", MethodConcept::LISTENER }, + { "addVetoableChangeListener", MethodConcept::LISTENER }, + { "removeVetoableChangeListener", MethodConcept::LISTENER }, + { "getElementType", MethodConcept::PROPERTY | MethodConcept::NAMECONTAINER| MethodConcept::INDEXCONTAINER | MethodConcept::ENUMERATION }, + { "hasElements", MethodConcept::NAMECONTAINER | MethodConcept::INDEXCONTAINER | MethodConcept::ENUMERATION }, + { "getByName", MethodConcept::NAMECONTAINER }, + { "getElementNames", MethodConcept::PROPERTY | MethodConcept::NAMECONTAINER }, + { "hasByName", MethodConcept::NAMECONTAINER }, + { "getCount", MethodConcept::PROPERTY | MethodConcept::INDEXCONTAINER }, + { "getByIndex", MethodConcept::INDEXCONTAINER }, + { "getTypes", MethodConcept::PROPERTY }, + { "getImplementationId", MethodConcept::PROPERTY }, + { "queryAdapter", MethodConcept_NORMAL_IMPL }, + { NULL, 0 } + }; + + OString aErrorStr; + + + // create test object + Any aObjAny = getIntrospectionTestObject( xMgr ); + + // inspect introspection service + xIntrospection->inspect( aObjAny ); + xIntrospection->inspect( aObjAny ); + Reference< XIntrospectionAccess > xAccess = xIntrospection->inspect( aObjAny ); + OSL_ENSURE( xAccess.is(), "introspection failed, no XIntrospectionAccess returned" ); + if( !xAccess.is() ) + return sal_False; + + // check result of introspection + + // determine XPropertySet-UIK + Type aType = cppu::UnoType<XPropertySet>::get(); + + Reference< XInterface > xPropSetIface = xAccess->queryAdapter( aType ); + Reference< XPropertySet > xPropSet( xPropSetIface, UNO_QUERY ); + OSL_ENSURE( xPropSet.is(), "Could not get XPropertySet by queryAdapter()" ); + + // XExactName + Reference< XExactName > xExactName( xAccess, UNO_QUERY ); + OSL_ENSURE( xExactName.is(), "Introspection doesn't support ExactName" ); + + // loop over all concept combinations + for( sal_Int32 nConcepts = 0 ; nConcepts < 16 ; nConcepts++ ) + { + // how many properties should this be + sal_Int32 nDemandedPropCount = 0; + sal_Int32 iList = 0; + while( pPropertyDefs[ iList ].pName ) + { + if( pPropertyDefs[ iList ].nConcept & nConcepts ) + nDemandedPropCount++; + iList++; + } + + if( xPropSet.is() ) + { + Reference< XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo(); + Sequence<Property> aRetSeq = xAccess->getProperties( nConcepts ); + + sal_Int32 nLen = aRetSeq.getLength(); + + aErrorStr = "Expected to find " + + OString::valueOf( nDemandedPropCount ) + + " properties but found " + + OString::valueOf( nLen ); + OSL_ENSURE( nLen == nDemandedPropCount, aErrorStr.getStr() ); + + const Property* pProps = aRetSeq.getConstArray(); + Any aPropVal; + sal_Int32 i; + iList = 0; + for( i = 0 ; i < nLen ; i++ ) + { + const Property aProp = pProps[ i ]; + + // search for next suitable method in the list + while( pPropertyDefs[ iList ].pName ) + { + if( pPropertyDefs[ iList ].nConcept & nConcepts ) + break; + iList++; + } + sal_Int32 iDemanded = iList; + iList++; + + OUString aPropName = aProp.Name; + OString aNameStr( aPropName.getStr(), aPropName.getLength(), RTL_TEXTENCODING_ASCII_US ); + + OString aDemandedName = pPropertyDefs[ iDemanded ].pName; + aErrorStr = "Expected property \"" + + aDemandedName + + "\", found \"" + + aNameStr + + "\""; + OSL_ENSURE( aNameStr == aDemandedName, aErrorStr.getStr() ); + + Type aPropType = aProp.Type; + OString aTypeNameStr( OUStringToOString(aPropType.getTypeName(), RTL_TEXTENCODING_ASCII_US) ); + OString aDemandedTypeNameStr = pDemandedPropTypes[ iDemanded ]; + aErrorStr = "Property \"" + + aDemandedName + + "\", expected type >" + + aDemandedTypeNameStr + + "< found type >" + + aTypeNameStr + + "<"; + OSL_ENSURE( aTypeNameStr == aDemandedTypeNameStr, aErrorStr.getStr() ); + + // read and report value of property + aPropVal = xPropSet->getPropertyValue( aPropName ); + + OString aValStr = OUStringToOString( AnyToString( aPropVal, sal_False, xMgr ), RTL_TEXTENCODING_ASCII_US ); + OString aDemandedValStr = pDemandedPropVals[ iDemanded ]; + aErrorStr = "Property \"" + + aDemandedName + + "\", expected val >" + + aDemandedValStr + + "< found val >" + + aValStr + + "<"; + OSL_ENSURE( aValStr == aDemandedValStr, aErrorStr.getStr() ); + + // check value and modify it according to its type + TypeClass eType = aPropVal.getValueType().getTypeClass(); + Any aNewVal; + sal_Bool bModify = sal_True; + switch( eType ) + { + case TypeClass_STRING: + { + OUString aStr; + aPropVal >>= aStr; + aStr += " (Modified!)"; + aNewVal <<= aStr; + break; + } + case TypeClass_DOUBLE: + { + double d(0.0); + aPropVal >>= d; + aNewVal <<= d + 1.0; + break; + } + case TypeClass_SHORT: + { + sal_Int16 n(0); + aPropVal >>= n; + aNewVal <<= sal_Int16( n + 1 ); + break; + } + case TypeClass_LONG: + { + sal_Int32 n(0); + aPropVal >>= n; + aNewVal <<= sal_Int32( n + 1 ); + break; + } + default: + bModify = sal_False; + break; + } + + // modify only in the last iteration + if( nConcepts == 15 ) + { + // check XExactName, switch everything to upper case + // (introspection uses lower case) + OUString aUpperUStr = aPropName.toAsciiUpperCase(); + OUString aExactName = xExactName->getExactName( aUpperUStr ); + if( aExactName != aPropName ) + { + aErrorStr = "Property \"" + + OUStringToOString( aPropName, RTL_TEXTENCODING_ASCII_US ) + + "\", not found as \"" + + OUStringToOString(aUpperUStr, RTL_TEXTENCODING_ASCII_US ) + + "\" using XExactName"; + OSL_ENSURE( sal_False, aErrorStr.getStr() ); + } + } + else + { + bModify = sal_False; + } + + // set new value, then read and return value + if( bModify ) + { + // catch UnknownPropertyException for ReadOnly properties + try + { + xPropSet->setPropertyValue( aPropName, aNewVal ); + } + catch(const UnknownPropertyException &) + { + } + + aPropVal = xPropSet->getPropertyValue( aPropName ); + + OUString aStr = AnyToString( aPropVal, sal_False, xMgr ); + OString aModifiedValStr = OUStringToOString( aStr, RTL_TEXTENCODING_ASCII_US ); + OString aDemandedModifiedValStr = pDemandedModifiedPropVals[ i ]; + aErrorStr = "Property \"" + + aDemandedName + + "\", expected modified val >" + + aDemandedModifiedValStr + + "< found val >" + + aModifiedValStr + + "<"; + OSL_ENSURE( aModifiedValStr == aDemandedModifiedValStr, aErrorStr.getStr() ); + } + + // check whether all properties can be found individually + aErrorStr = "property \"" + + aDemandedName + + "\" not found with hasProperty()"; + OUString aWDemandedName = OStringToOUString(aDemandedName, RTL_TEXTENCODING_ASCII_US ); + sal_Bool bProperty = xAccess->hasProperty( aWDemandedName, nConcepts ); + OSL_ENSURE( bProperty, aErrorStr.getStr() ); + + aErrorStr = "property \"" + + aDemandedName + + "\" not equal to same Property in sequence returned by getProperties()"; + try + { + Property aGetProp = xAccess->getProperty( aWDemandedName, nConcepts ); + } + catch (const RuntimeException &) + { + aErrorStr = "property \"" + + aDemandedName + + "\", exception was thrown when trying getProperty()"; + OSL_ENSURE( sal_False, aErrorStr.getStr() ); + } + + } + } + } + + // loop over all concept combinations + for( sal_Int32 nConcepts = 0 ; nConcepts < 128 ; nConcepts++ ) + { + // The 2^6th bit stands for "the rest" + sal_Int32 nRealConcepts = nConcepts; + if( nConcepts & 0x40 ) + nRealConcepts |= (0xFFFFFFFF - 0x3F); + + // Count the number of methods there should be + sal_Int32 nDemandedMethCount = 0; + sal_Int32 iList = 0; + while( pMethodDefs[ iList ].pName ) + { + if( pMethodDefs[ iList ].nConcept & nRealConcepts ) + nDemandedMethCount++; + iList++; + } + + // Output the method array. + Sequence< Reference< XIdlMethod > > aMethodSeq = xAccess->getMethods( nRealConcepts ); + sal_Int32 nLen = aMethodSeq.getLength(); + + aErrorStr = "Expected to find " + + OString::valueOf( nDemandedMethCount ) + + " methods but found " + + OString::valueOf( nLen ); + OSL_ENSURE( nLen == nDemandedMethCount, aErrorStr.getStr() ); + + const Reference< XIdlMethod >* pMethods = aMethodSeq.getConstArray(); + sal_Int32 i; + iList = 0; + + for( i = 0 ; i < nLen ; i++ ) + { + const Reference< XIdlMethod >& rxMethod = pMethods[i]; + + OUString aMethName = rxMethod->getName(); + OString aNameStr = OUStringToOString(aMethName, RTL_TEXTENCODING_ASCII_US ); + + // locate the next matching method in the list. + while( pMethodDefs[ iList ].pName ) + { + if( pMethodDefs[ iList ].nConcept & nRealConcepts ) + break; + iList++; + } + OString aDemandedName = pMethodDefs[ iList ].pName; + iList++; + + aErrorStr = "Expected method \"" + + aDemandedName + + "\", found \"" + + aNameStr + + "\""; + OSL_ENSURE( aNameStr == aDemandedName, aErrorStr.getStr() ); + + // Check that the method is really there with hasMethod. + aErrorStr = "method \"" + + aDemandedName + + "\" not found with hasMethod()"; + OUString aWDemandedName = OStringToOUString(aDemandedName, RTL_TEXTENCODING_ASCII_US ); + sal_Bool bMethod = xAccess->hasMethod( aWDemandedName, nRealConcepts ); + OSL_ENSURE( bMethod, aErrorStr.getStr() ); + + aErrorStr = "method \"" + + aDemandedName + + "\" not equal to same method in sequence returned by getMethods()"; + try + { + Reference< XIdlMethod > xGetMethod = xAccess->getMethod( aWDemandedName, nRealConcepts ); + OSL_ENSURE( xGetMethod == rxMethod , aErrorStr.getStr() ); + } + catch (const RuntimeException &) + { + aErrorStr = "method \"" + + aDemandedName + + "\", exception was thrown when trying getMethod()"; + OSL_ENSURE( sal_False, aErrorStr.getStr() ); + } + } + } + + // print listener class + Sequence< Type > aClassSeq = xAccess->getSupportedListeners(); + sal_Int32 nLen = aClassSeq.getLength(); + + const Type* pListeners = aClassSeq.getConstArray(); + for( sal_Int32 i = 0 ; i < nLen ; i++ ) + { + const Type& aListenerType = pListeners[i]; + OUString aListenerClassName = aListenerType.getTypeName(); + } + + return sal_True; +} + + +SAL_IMPLEMENT_MAIN() +{ + Reference< XMultiServiceFactory > xMgr( createRegistryServiceFactory( OUString("stoctest.rdb") ) ); + + sal_Bool bSucc = sal_False; + try + { + Reference< XImplementationRegistration > xImplReg( + xMgr->createInstance("com.sun.star.registry.ImplementationRegistration"), UNO_QUERY ); + OSL_ENSURE( xImplReg.is(), "### no impl reg!" ); + + // Register services + OUString libName( "reflection.uno" SAL_DLLEXTENSION ); + fprintf(stderr, "1\n" ); + xImplReg->registerImplementation(OUString("com.sun.star.loader.SharedLibrary"), + libName, Reference< XSimpleRegistry >() ); + fprintf(stderr, "2\n" ); + Reference< XIdlReflection > xRefl( xMgr->createInstance("com.sun.star.reflection.CoreReflection"), UNO_QUERY ); + OSL_ENSURE( xRefl.is(), "### no corereflection!" ); + + // Introspection + libName = OUString( "introspection.uno" SAL_DLLEXTENSION); + fprintf(stderr, "3\n" ); + xImplReg->registerImplementation(OUString("com.sun.star.loader.SharedLibrary"), + libName, Reference< XSimpleRegistry >() ); + fprintf(stderr, "4\n" ); + Reference< XIntrospection > xIntrosp( xMgr->createInstance("com.sun.star.beans.Introspection"), UNO_QUERY ); + OSL_ENSURE( xRefl.is(), "### no corereflection!" ); + + fprintf(stderr, "before test_introsp\n" ); + bSucc = test_introsp( xMgr, xRefl, xIntrosp ); + fprintf(stderr, "after test_introsp\n" ); + } + catch (const Exception & rExc) + { + DBG_UNHANDLED_EXCEPTION("stoc", "### exception occurred: " << rExc ); + } + + Reference< XComponent >( xMgr, UNO_QUERY )->dispose(); + + printf( "testintrosp %s !\n", (bSucc ? "succeeded" : "failed") ); + return (bSucc ? 0 : -1); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/stoc/test/testintrosp.idl b/stoc/test/testintrosp.idl new file mode 100644 index 0000000000..fbb53ffb7e --- /dev/null +++ b/stoc/test/testintrosp.idl @@ -0,0 +1,187 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +module ModuleA +{ +//module com { module sun { module star { module beans { + +//interface XPropertyChangeListener; +//interface XPropertiesChangeListener; + + +/** This is a test interface for introspection. + + <p>IMPORTANT: FOR TEST ONLY! + + <p>The following interface is just for testing purposes. It will not + stay in the product. It is only used as an exportable test class, + i.e. for BASIC integration. + + @deprecated +*/ +interface XIntroTest: com::sun::star::uno::XInterface +{ + + /** contains the ID-String of the implementation. + */ + [attribute] string ObjectName; + + + /** contains the first name of a person. + */ + [readonly, attribute] string FirstName; + + + /** contains the last name of a person. + */ + [readonly, attribute] string LastName; + + + /** contains the age of a person. + */ + [readonly, attribute] short Age; + + + /** contains the number of children person has. + */ + [attribute] short ChildrenCount; + + + /** contains a struct of type Property. + */ + [attribute] com::sun::star::beans::Property FirstStruct; + + + /** contains a struct of type PropertyValue. + */ + [attribute] com::sun::star::beans::PropertyValue SecondStruct; + + + /** output method + */ + void writeln( [in] string Text ); + + + /** ... + */ + long getDroenk(); + + + /** get further introspection test objects + */ + XIntroTest getIntroTest(); + //com::sun::star::beans::XIntroTest getIntroTest(); + + + /** !!! No property, because parameter exists + */ + long getUps( [in] long l ); + + + /** ... + */ + void setDroenk( [in] long l ); + + + /** ... + */ + short getBla(); + + + /** !!! Not the set method for property Bla, because param type != return type. + */ + void setBla( [in] long n ); + + + /** ... + */ + short getBlub(); + + + /** ... + */ + void setBlub( [in] short n ); + + + /** ... + */ + short getGulp(); + + + /** !!! Not the set method for property Gulp, because return type != void. + */ + short setGulp( [in] short n ); + + + /** ... + */ + com::sun::star::uno::TypeClass getTypeClass( [in] short n ); + + + /** ... + */ + void setTypeClass( [in] com::sun::star::uno::TypeClass t, + [in] double d1, + [in] double d2 ); + + + /** + */ + sequence<string> getStrings(); + + + /** ... + */ + void setStrings( [in] sequence<string> Strings ); + + + /** ... + */ + void setStringsPerMethod( [in] sequence<string> Strings, + [in] short n ); + + + /** + */ + sequence< sequence< sequence< short > > > getMultiSequence(); + + + /** ... + */ + void setMultiSequence( [in] sequence< sequence< sequence< short > > > Seq ); + + + /**Add a PropertiesChangeListener + */ + void addPropertiesChangeListener( [in] sequence< string > PropertyNames, + [in] com::sun::star::beans::XPropertiesChangeListener Listener ); + + + /**Remove a PropertiesChangeListener + */ + void removePropertiesChangeListener( [in] com::sun::star::beans::XPropertiesChangeListener Listener ); + +}; + + + +}; +//}; }; }; }; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/stoc/test/testloader.cxx b/stoc/test/testloader.cxx new file mode 100644 index 0000000000..beb77e7d96 --- /dev/null +++ b/stoc/test/testloader.cxx @@ -0,0 +1,120 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#include <stdio.h> + +#include <sal/main.h> +#include <osl/module.hxx> +#include <osl/diagnose.h> + +#include <com/sun/star/loader/XImplementationLoader.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/lang/XSingleComponentFactory.hpp> + +#include <cppuhelper/implbase.hxx> +#include <cppuhelper/factory.hxx> + +#if defined ( UNX ) +#include <limits.h> +#define _MAX_PATH PATH_MAX +#endif + +using namespace css::uno; +using namespace css::loader; +using namespace css::lang; +using namespace osl; +using namespace cppu; + + +class EmptyComponentContext : public WeakImplHelper< XComponentContext > +{ +public: + virtual Any SAL_CALL getValueByName( const OUString& /*Name*/ ) + throw (RuntimeException) + { + return Any(); + } + virtual Reference< XMultiComponentFactory > SAL_CALL getServiceManager( ) + throw (RuntimeException) + { + return Reference< XMultiComponentFactory > (); + } + +}; + + +SAL_IMPLEMENT_MAIN() +{ + Reference<XInterface> xIFace; + + Module module; + + OUString dllName( + "bootstrap.uno" SAL_DLLEXTENSION ); + + if (module.load(dllName)) + { + // try to get provider from module + component_getFactoryFunc pCompFactoryFunc = (component_getFactoryFunc) + module.getFunctionSymbol( OUString(COMPONENT_GETFACTORY) ); + + if (pCompFactoryFunc) + { + XSingleServiceFactory * pRet = (XSingleServiceFactory *)(*pCompFactoryFunc)( + "com.sun.star.comp.stoc.DLLComponentLoader", 0, 0 ); + if (pRet) + { + xIFace = pRet; + pRet->release(); + } + } + } + + OSL_ENSURE( xIFace.is(), "testloader error1"); + + Reference<XSingleComponentFactory> xFactory( Reference<XSingleComponentFactory>::query(xIFace) ); + + OSL_ENSURE( xFactory.is(), "testloader error2"); + + Reference<XInterface> xLoader = xFactory->createInstanceWithContext( new EmptyComponentContext ); + + OSL_ENSURE( xLoader.is(), "testloader error3"); + + Reference<XServiceInfo> xServInfo( Reference<XServiceInfo>::query(xLoader) ); + + OSL_ENSURE( xServInfo.is(), "testloader error4"); + + OSL_ENSURE( xServInfo->getImplementationName() == "com.sun.star.comp.stoc.DLLComponentLoader", "testloader error5"); + OSL_ENSURE( xServInfo->supportsService("com.sun.star.loader.SharedLibrary"), "testloader error6"); + OSL_ENSURE( xServInfo->getSupportedServiceNames().getLength() == 1, "testloader error7"); + + xIFace.clear(); + xFactory.clear(); + xLoader.clear(); + xServInfo.clear(); + + printf("Test Dll ComponentLoader, OK!\n"); + + return 0; +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/stoc/test/testproxyfac.cxx b/stoc/test/testproxyfac.cxx new file mode 100644 index 0000000000..befc67ae8e --- /dev/null +++ b/stoc/test/testproxyfac.cxx @@ -0,0 +1,359 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#include <sal/main.h> +#include <sal/log.hxx> +#include <osl/diagnose.h> +#include <rtl/alloc.h> +#include <uno/environment.hxx> +#include <uno/lbnames.h> +#include <cppuhelper/servicefactory.hxx> +#include <cppuhelper/implbase.hxx> +#include <com/sun/star/uno/XCurrentContext.hpp> +#include <com/sun/star/lang/DisposedException.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/registry/XSimpleRegistry.hpp> +#include <com/sun/star/registry/XImplementationRegistration.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/reflection/XProxyFactory.hpp> + +#include <stdio.h> + + +using namespace ::osl; +using namespace ::cppu; +using namespace ::com::sun::star; +using namespace css::uno; + + +typedef WeakImplHelper< lang::XServiceInfo, + XCurrentContext, + reflection::XProxyFactory > t_impl; + + +class TargetObject : public t_impl +{ +public: + static int s_obj; + + virtual ~TargetObject() { + --s_obj; + SAL_INFO("stoc", "~TargetObject()" ); + } + TargetObject() + { ++s_obj; } + + Any SAL_CALL queryInterface( Type const & type ) + throw (RuntimeException); + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() throw (RuntimeException) + { return OUString("target"); } + virtual sal_Bool SAL_CALL supportsService( const OUString & /*rServiceName*/ ) + throw (RuntimeException) + { return sal_False; } + virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() + throw (RuntimeException) + { return Sequence< OUString >(); } + // XProxyFactory + virtual Reference< XAggregation > SAL_CALL createProxy( + const Reference< XInterface > & xTarget ) throw (RuntimeException) + { return Reference< XAggregation >( xTarget, UNO_QUERY ); } + // XCurrentContext + virtual Any SAL_CALL getValueByName( OUString const & name ) + throw (RuntimeException) + { return makeAny( name ); } +}; + + +Any TargetObject::queryInterface( Type const & type ) + throw (RuntimeException) +{ + Any ret( t_impl::queryInterface( type ) ); + if (ret.hasValue()) + return ret; + throw lang::DisposedException( + OUString( "my test exception" ), + getXWeak() ); +} + +int TargetObject::s_obj = 0; + + +class TestMaster : public WeakImplHelper< lang::XServiceInfo > +{ + Reference< XAggregation > m_xProxyTarget; + Reference<lang::XServiceInfo> m_xOtherProxyTargetBeforeSetDelegator; + + inline TestMaster() { ++s_obj; } +public: + static int s_obj; + static Reference< XInterface > create( + Reference< reflection::XProxyFactory > const & xProxyFac ); + static Reference< XInterface > create( + Reference< XInterface > const & xTarget, + Reference< reflection::XProxyFactory > const & xProxyFac ); + + virtual ~TestMaster() { + --s_obj; + SAL_INFO("stoc", "~TestMaster()" ); + } + + virtual Any SAL_CALL queryInterface( const Type & rType ) + throw (RuntimeException) + { + Any aRet( + WeakImplHelper< lang::XServiceInfo >::queryInterface( rType ) ); + if (aRet.hasValue()) + return aRet; + return m_xProxyTarget->queryAggregation( rType ); + } + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() throw (RuntimeException) + { return OUString("master"); } + virtual sal_Bool SAL_CALL supportsService( const OUString & /*rServiceName*/ ) + throw (RuntimeException) + { return sal_False; } + virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() + throw (RuntimeException) + { return Sequence< OUString >(); } +}; + +int TestMaster::s_obj = 0; + + +Reference< XInterface > TestMaster::create( + Reference< XInterface > const & xTarget, + Reference< reflection::XProxyFactory > const & xProxyFac ) +{ + TestMaster * that = new TestMaster; + Reference< XInterface > xRet( getXWeak( that ) ); + { + Reference< XAggregation > xAgg( xProxyFac->createProxy( xTarget ) ); + // ownership take over + that->m_xProxyTarget.set( xAgg, UNO_QUERY_THROW ); + that->m_xOtherProxyTargetBeforeSetDelegator.set( + that->m_xProxyTarget, UNO_QUERY ); + } + that->m_xProxyTarget->setDelegator( xRet ); + return xRet; +} + +Reference< XInterface > TestMaster::create( + Reference< reflection::XProxyFactory > const & xProxyFac ) +{ + return create( + getXWeak( new TargetObject ), xProxyFac ); +} + + +static void test_proxyfac_( + Reference< XInterface > const & xMaster, OUString const & test, + Reference< reflection::XProxyFactory > const & /*xProxyFac*/ ) +{ + (void)test; + Reference< lang::XServiceInfo > xMaster_XServiceInfo( + xMaster, UNO_QUERY_THROW ); + OSL_ASSERT( xMaster_XServiceInfo->getImplementationName().equals( test ) ); + + Reference< reflection::XProxyFactory > xTarget( xMaster, UNO_QUERY_THROW ); + Reference< XCurrentContext > xTarget_XCurrentContext( + xTarget, UNO_QUERY_THROW ); + Reference< XCurrentContext > xMaster_XCurrentContext( + xMaster, UNO_QUERY_THROW ); + + OSL_ASSERT( + xTarget_XCurrentContext->getValueByName( test ) == makeAny( test ) ); + OSL_ASSERT( + xMaster_XCurrentContext->getValueByName( test ) == makeAny( test ) ); + + Reference< XAggregation > xFakeAgg( xTarget->createProxy( xTarget ) ); + if (xFakeAgg.is()) + { + OSL_ASSERT( xTarget == xFakeAgg ); + OSL_ASSERT( xMaster == xFakeAgg ); + } + + Reference< lang::XServiceInfo > xTarget_XServiceInfo( + xTarget, UNO_QUERY_THROW ); + OSL_ASSERT( xTarget_XServiceInfo->getImplementationName().equals( test ) ); + Reference< lang::XServiceInfo > xTarget_XServiceInfo2( + xTarget, UNO_QUERY_THROW ); + OSL_ASSERT( xTarget_XServiceInfo2.get() == xTarget_XServiceInfo.get() ); + + OSL_ASSERT( xTarget == xTarget_XCurrentContext ); + OSL_ASSERT( xTarget_XCurrentContext == xMaster ); + OSL_ASSERT( + xTarget_XCurrentContext.get() == xMaster_XCurrentContext.get() ); + OSL_ASSERT( xTarget_XCurrentContext == xMaster ); + OSL_ASSERT( xTarget == xMaster ); + OSL_ASSERT( xTarget_XServiceInfo.get() == xMaster_XServiceInfo.get() ); + OSL_ASSERT( xTarget_XServiceInfo == xMaster ); + OSL_ASSERT( xMaster_XServiceInfo == xMaster ); + + try + { + Reference< registry::XRegistryKey >( + xMaster, UNO_QUERY_THROW ); + } + catch (const lang::DisposedException & exc) + { + if ( exc.Message != "my test exception" ) + throw; + } +} + +static void test_proxyfac( + Reference< XInterface > const & xMaster, OUString const & test, + Reference< reflection::XProxyFactory > const & xProxyFac ) +{ + test_proxyfac_( xMaster, test, xProxyFac ); + // proxy the proxy... + Reference< XInterface > xNew( TestMaster::create( xMaster, xProxyFac ) ); + test_proxyfac_( + xNew, OUString( "master" ), xProxyFac ); +} + +SAL_IMPLEMENT_MAIN() +{ + bool success = true; + + Environment cpp_env; + OUString cpp( CPPU_CURRENT_LANGUAGE_BINDING_NAME ); + uno_getEnvironment( + reinterpret_cast< uno_Environment ** >( &cpp_env ), + cpp.pData, 0 ); + OSL_ENSURE( cpp_env.is(), "### cannot get C++ uno env!" ); + + { + Reference< lang::XMultiServiceFactory > xMgr( + createRegistryServiceFactory( + OUString( "stoctest.rdb" ) ) ); + + try + { + Reference< registry::XImplementationRegistration > xImplReg( + xMgr->createInstance( "com.sun.star.registry.ImplementationRegistration" ), + UNO_QUERY ); + OSL_ENSURE( xImplReg.is(), "### no impl reg!" ); + + OUString aLibName( + "proxyfac.uno" SAL_DLLEXTENSION ); + xImplReg->registerImplementation( + OUString( "com.sun.star.loader.SharedLibrary" ), + aLibName, Reference< registry::XSimpleRegistry >() ); + + Reference< reflection::XProxyFactory > xProxyFac( + xMgr->createInstance("com.sun.star.reflection.ProxyFactory"), + UNO_QUERY_THROW ); + + Reference< XAggregation > x( + xProxyFac->createProxy( + getXWeak( new TargetObject ) ) ); + // no call + + { + Reference< XInterface > xMaster( TestMaster::create( xProxyFac ) ); + test_proxyfac( + xMaster, + OUString( "master" ), + xProxyFac ); + } + { + Reference< XInterface > xMaster( TestMaster::create( xProxyFac ) ); + // no call + } + + { + Reference< XInterface > xMaster( TestMaster::create( xProxyFac ) ); + Reference< reflection::XProxyFactory > xSlave_lives_alone( + xMaster, UNO_QUERY_THROW ); + xMaster.clear(); + test_proxyfac( + xSlave_lives_alone, + OUString( "master" ), + xProxyFac ); + uno_dumpEnvironment( stdout, cpp_env.get(), 0 ); + } + { + Reference< XInterface > xMaster( TestMaster::create( xProxyFac ) ); + Reference< reflection::XProxyFactory > xSlave_lives_alone( + xMaster, UNO_QUERY_THROW ); + // no call + } + + test_proxyfac( + xProxyFac->createProxy( + getXWeak( new TargetObject ) ), + OUString( "target" ), + xProxyFac ); + uno_dumpEnvironment( stdout, cpp_env.get(), 0 ); + } + catch (const Exception & rExc) + { + (void)rExc; + OSL_ENSURE( + ! __FILE__, + OUStringToOString( + rExc.Message, RTL_TEXTENCODING_ASCII_US ).getStr() ); + success = false; + } + + + Reference< lang::XComponent > xComp; + Reference< beans::XPropertySet >( + xMgr, UNO_QUERY_THROW )->getPropertyValue( + OUString( "DefaultContext" ) ) + >>= xComp; + xComp->dispose(); + } + + if (TestMaster::s_obj != 0) + fprintf( stderr, "TestMaster objects: %d\n", TestMaster::s_obj ); + if (TargetObject::s_obj != 0) + fprintf( stderr, "TargetObject objects: %d\n", TargetObject::s_obj ); + + uno_dumpEnvironment( stdout, cpp_env.get(), 0 ); + void ** ppInterfaces; + sal_Int32 len; + uno_ExtEnvironment * env = cpp_env.get()->pExtEnv; + (*env->getRegisteredInterfaces)( + env, &ppInterfaces, &len, rtl_allocateMemory ); + if (len != 0) + fprintf( stderr, "%d registered C++ interfaces left!\n", len ); + + success &= (TestMaster::s_obj == 0 && + TargetObject::s_obj == 0 && + len == 0); + if (success) + { + printf( "testproxyfac succeeded.\n" ); + return 0; + } + else + { + fprintf( stderr, "testproxyfac failed!\n" ); + return 1; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/stoc/test/testregistry.cxx b/stoc/test/testregistry.cxx new file mode 100644 index 0000000000..ef0d0a91d5 --- /dev/null +++ b/stoc/test/testregistry.cxx @@ -0,0 +1,670 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <sal/main.h> +#include <osl/module.hxx> +#include <osl/diagnose.h> +#include <osl/process.h> +#include <registry/registry.hxx> + + +#include <com/sun/star/registry/XSimpleRegistry.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <cppuhelper/factory.hxx> +#include <cppuhelper/bootstrap.hxx> +#include <cppuhelper/servicefactory.hxx> + +#include <com/sun/star/lang/XComponent.hpp> + +#if defined ( UNX ) +#include <limits.h> +#define _MAX_PATH PATH_MAX +#endif + +using namespace com::sun::star; +using namespace css::uno; +using namespace css::registry; +using namespace css::lang; +using namespace css::beans; +using namespace osl; + + +namespace stoc_impreg +{ +void SAL_CALL mergeKeys( +Reference< registry::XRegistryKey > const & xDest, +Reference< registry::XRegistryKey > const & xSource ); +} +static void mergeKeys( +Reference< registry::XSimpleRegistry > const & xDest, +OUString const & rBaseNode, +OUString const & rURL ) +{ +Reference< registry::XRegistryKey > xDestRoot( xDest->getRootKey() ); +Reference< registry::XRegistryKey > xDestKey; +if (rBaseNode.getLength()) +{ +xDestKey = xDestRoot->createKey( rBaseNode ); +xDestRoot->closeKey(); +} +else +{ +xDestKey = xDestRoot; +} +Reference< registry::XSimpleRegistry > xSimReg( ::cppu::createSimpleRegistry() ); +xSimReg->open( rURL, sal_True, sal_False ); +OSL_ASSERT( xSimReg->isValid() ); +Reference< registry::XRegistryKey > xSourceKey( xSimReg->getRootKey() ); +::stoc_impreg::mergeKeys( xDestKey, xSourceKey ); +xSourceKey->closeKey(); +xSimReg->close(); +xDestKey->closeKey(); +} + + +OString userRegEnv("STAR_USER_REGISTRY="); + +OUString getExePath() +{ +OUString exe; +OSL_VERIFY( osl_getExecutableFile( &exe.pData ) == osl_Process_E_None); +#if defined(_WIN32) +exe = exe.copy(0, exe.getLength() - 16); +#else +exe = exe.copy(0, exe.getLength() - 12); +#endif +return exe; +} + +void setStarUserRegistry() +{ +Registry *myRegistry = new Registry(); + +RegistryKey rootKey, rKey, rKey2; + +OUString userReg = getExePath(); +userReg += "user.rdb"; +if(myRegistry->open(userReg, RegAccessMode::READWRITE)) +{ +OSL_VERIFY(!myRegistry->create(userReg)); +} + +OSL_VERIFY(!myRegistry->close()); +delete myRegistry; + +userRegEnv += OUStringToOString(userReg, RTL_TEXTENCODING_ASCII_US); + putenv((char *)userRegEnv.getStr()); +} + +void setLinkInDefaultRegistry(const OUString& linkName, const OUString& linkTarget) +{ + Registry *myRegistry = new Registry(); + + RegistryKey rootKey; + + OUString appReg = getExePath(); + appReg += "stoctest.rdb"; + + OSL_VERIFY(!myRegistry->open(appReg, RegAccessMode::READWRITE)); + OSL_VERIFY(!myRegistry->openRootKey(rootKey)); + + OSL_VERIFY(!rootKey.createLink(linkName, linkTarget)); + + OSL_VERIFY(!rootKey.closeKey()); + OSL_VERIFY(!myRegistry->close()); + + delete myRegistry; +} + + +void test_SimpleRegistry( + OUString const & testreg, + OUString const & testreg2, + bool bMergeDifferently = true ) +{ + Reference<XInterface> xIFace; + Module module; + + OUString dllName( + "simplereg.uno" SAL_DLLEXTENSION ); + + if (module.load(dllName)) + { + // try to get provider from module + component_getFactoryFunc pCompFactoryFunc = (component_getFactoryFunc) + module.getFunctionSymbol( OUString(COMPONENT_GETFACTORY) ); + + if (pCompFactoryFunc) + { + XSingleServiceFactory * pRet = (XSingleServiceFactory *) + (*pCompFactoryFunc)( + "com.sun.star.comp.stoc.SimpleRegistry", 0, 0 ); + if (pRet) + { + xIFace = pRet; + pRet->release(); + } + } + } + + OSL_ENSURE( xIFace.is(), "test_SimpleRegistry error1"); + + Reference<XSingleServiceFactory> xFactory( Reference<XSingleServiceFactory>::query(xIFace) ); + xIFace.clear(); + + OSL_ENSURE( xFactory.is(), "testloader error11"); + + Reference<XInterface> xIFace2 = xFactory->createInstance(); + xFactory.clear(); + + OSL_ENSURE( xIFace2.is(), "testloader error12"); + + Reference<XServiceInfo> xServInfo( Reference<XServiceInfo>::query(xIFace2) ); + + OSL_ENSURE( xServInfo.is(), "test_SimpleRegistry error2"); + + OSL_ENSURE( xServInfo->getImplementationName() == "com.sun.star.comp.stoc.SimpleRegistry", "test_SimpleRegistry error3"); + OSL_ENSURE( xServInfo->supportsService("com.sun.star.registry.SimpleRegistry"), "test_SimpleRegistry error4"); + OSL_ENSURE( xServInfo->getSupportedServiceNames().getLength() == 1, "test_SimpleRegistry error5"); + xServInfo.clear(); + + Reference<XSimpleRegistry> xReg( Reference<XSimpleRegistry>::query(xIFace2) ); + xIFace2.clear(); + + OSL_ENSURE( xReg.is(), "test_SimpleRegistry error6"); + + try + { + xReg->open(testreg, sal_False, sal_True); + + OSL_ENSURE( xReg->isValid() != sal_False, "test_SimpleRegistry error 7" ); + OSL_ENSURE( xReg->isReadOnly() == sal_False, "test_SimpleRegistry error 8" ); + + Reference<XRegistryKey> xRootKey(xReg->getRootKey()); + OSL_ENSURE( xRootKey->isValid(), "test_SimpleRegistry error 9" ); + + Reference<XRegistryKey> xKey = xRootKey->createKey(OUString( "FirstKey" )); + + Reference<XRegistryKey> xSubKey = xKey->createKey(OUString( "FirstSubKey" )); + xSubKey->setLongValue(123456789); + + xSubKey = xKey->createKey(OUString( "SecondSubKey" )); + xSubKey->setAsciiValue(OUString( "I'm an ascii value" )); + + xSubKey = xKey->createKey(OUString( "ThirdSubKey" )); + xSubKey->setStringValue(OUString( "I'm a Unicode value" )); + + xSubKey = xKey->createKey(OUString( "FourthSubKey" )); + Sequence<sal_Int8> aSeq((sal_Int8*)"I'm a binary value", 25); + xSubKey->setBinaryValue(aSeq); + + Sequence<OUString> seqNames = xKey->getKeyNames(); + Sequence< Reference<XRegistryKey> > seqKeys = xKey->openKeys(); + + OUString name; + for (sal_Int32 i=0; i < seqNames.getLength(); i++) + { + name = seqNames.getArray()[i]; + xSubKey = seqKeys.getArray()[i]; + + if (name == "/FirstKey/FirstSubKey" ) + { + OSL_ENSURE( xSubKey->getLongValue() == 123456789, + "test_SimpleRegistry error 10" ); + } else + if (name == "/FirstKey/SecondSubKey" ) + { + OSL_ENSURE( xSubKey->getAsciiValue() == "I'm an ascii value", + "test_SimpleRegistry error 11" ); + } else + if (name == "/FirstKey/ThirdSubKey" ) + { + OSL_ENSURE( xSubKey->getStringValue() == "I'm a Unicode value", + "test_SimpleRegistry error 12" ); + } else + if (name == "/FirstKey/FourthSubKey" ) + { + Sequence<sal_Int8> seqByte = xSubKey->getBinaryValue(); + OSL_ENSURE(!strcmp(((const char*)seqByte.getArray()), "I'm a binary value"), + "test_SimpleRegistry error 13" ); + } + + seqKeys.getArray()[i]->closeKey(); + } + + xKey->closeKey(); + + xRootKey->deleteKey(OUString( "FirstKey" )); + xRootKey->createKey(OUString( "SecondFirstKey" )); + + xKey = xRootKey->createKey(OUString( "SecondKey" )); + sal_Int32 pLongs[3] = {123, 456, 789}; + Sequence<sal_Int32> seqLongs(pLongs, 3); + xKey->setLongListValue(seqLongs); + + Sequence<sal_Int32> seqLongs2; + seqLongs2 = xKey->getLongListValue(); + OSL_ENSURE( seqLongs.getLength() == 3, "test_SimpleRegistry error 14" ); + OSL_ENSURE( seqLongs.getArray()[0] == 123, "test_SimpleRegistry error 15" ); + OSL_ENSURE( seqLongs.getArray()[1] == 456, "test_SimpleRegistry error 16" ); + OSL_ENSURE( seqLongs.getArray()[2] == 789, "test_SimpleRegistry error 17" ); + + + xKey = xRootKey->createKey(OUString( "ThirdKey" )); + OUString pAscii[3]; + pAscii[0] = "Hello"; + pAscii[1] = "here I"; + pAscii[2] = "come"; + + Sequence<OUString> seqAscii(pAscii, 3); + xKey->setAsciiListValue(seqAscii); + + Sequence<OUString> seqAscii2; + seqAscii2 = xKey->getAsciiListValue(); + OSL_ENSURE( seqAscii2.getLength() == 3, "test_SimpleRegistry error 18" ); + OSL_ENSURE( seqAscii2.getArray()[0] == "Hello", "test_SimpleRegistry error 19"); + OSL_ENSURE( seqAscii2.getArray()[1] == "here I", "test_SimpleRegistry error 20"); + OSL_ENSURE( seqAscii2.getArray()[2] == "come", "test_SimpleRegistry error 21"); + + xKey = xRootKey->createKey(OUString( "FourthKey" )); + OUString pUnicode[3]; + pUnicode[0] = "Hello"; + pUnicode[1] = "here I"; + pUnicode[2] = "come as unicode"; + + Sequence<OUString> seqUnicode(pUnicode, 3); + xKey->setStringListValue(seqUnicode); + + Sequence<OUString> seqUnicode2; + seqUnicode2 = xKey->getStringListValue(); + OSL_ENSURE( seqUnicode2.getLength() == 3, "test_SimpleRegistry error 22" ); + OSL_ENSURE( seqUnicode2.getArray()[0] == "Hello", "test_SimpleRegistry error 23"); + OSL_ENSURE( seqUnicode2.getArray()[1] == "here I", "test_SimpleRegistry error 24"); + OSL_ENSURE( seqUnicode2.getArray()[2] == "come as unicode", "test_SimpleRegistry error 25"); + + + xReg->open(testreg2, sal_False, sal_True); + OSL_ENSURE( xReg->isValid() != sal_False, "test_SimpleRegistry error 25" ); + xRootKey = xReg->getRootKey(); + xKey = xRootKey->createKey(OUString( "ThirdKey/FirstSubKey/WithSubSubKey" )); + xKey->closeKey(); + OSL_VERIFY( + xRootKey->createLink( + OUString( "LinkTest" ), + OUString( "/ThirdKey/FirstSubKey/WithSubSubKey" )) ); + xRootKey->closeKey(); + xReg->close(); + + xReg->open(testreg, sal_False, sal_False); + OSL_ENSURE( xReg->isValid() != sal_False, "test_SimpleRegistry error 26" ); + + if (bMergeDifferently) + { + mergeKeys( + xReg, + OUString(), + testreg2 ); + } + else + { + xReg->mergeKey(OUString(), testreg2); + } + + xRootKey = xReg->getRootKey(); + xKey = xRootKey->openKey("LinkTest"); + OSL_ENSURE( xKey.is() && xKey->isValid() && xKey->getKeyName() == "/ThirdKey/FirstSubKey/WithSubSubKey", "test_SimpleRegistry error 1213" ); + xKey->closeKey(); + OSL_ENSURE( + xRootKey->getKeyType( OUString( "LinkTest" ) ) == + registry::RegistryKeyType_LINK, + "test_SimpleRegistry error 1214" ); + + xKey = xRootKey->openKey("FirstKey/SecondSubKey"); + OSL_ENSURE( !xKey.is(), "test_SimpleRegistry error 27" ); + + // Test Links + xKey = xRootKey->createKey(OUString( "FifthKey" )); + xKey->createLink(OUString( "MyFirstLink" ), + OUString( "/ThirdKey/FirstSubKey" )); + + xKey = xRootKey->openKey("/FifthKey/MyFirstLink"); + OSL_ENSURE( xKey->isValid(), "test_SimpleRegistry error 27" ); + OSL_ENSURE( xKey->getKeyName() == "/ThirdKey/FirstSubKey", "test_SimpleRegistry error 28" ); + + xKey->createLink(OUString( "/WithSubSubKey/MyFourthLink" ), + OUString( "/FourthKey/MySecondLink" )); + + OSL_ENSURE( xKey->getLinkTarget(OUString( "/WithSubSubKey/MyFourthLink" )) + == "/FourthKey/MySecondLink", "test_SimpleRegistry error 29" ); + + try + { + OSL_ENSURE( xKey->getResolvedName(OUString( "/WithSubSubKey/MyFourthLink/BlaBlaBla" )) + == "/FourthKey/MySecondLink/BlaBlaBla", "test_SimpleRegistry error 30" ); + } + catch(InvalidRegistryException&) + { + } + + xRootKey->createLink(OUString( "/FourthKey/MySecondLink" ), + OUString( "/SixthKey/MyThirdLink" )); + xKey = xRootKey->createKey(OUString( "SixthKey" )); + xKey->createLink(OUString( "MyThirdLink" ), + OUString( "/FourthKey/MySecondLink" )); + + xKey = xRootKey->createKey(OUString( "/SixthKey/SixthSubKey" )); + + try + { + xRootKey->openKey("/FifthKey/MyFirstLink/WithSubSubKey/MyFourthLink"); + } + catch(InvalidRegistryException&) + { + } + + OSL_ENSURE( xRootKey->getLinkTarget(OUString( "/FifthKey/MyFirstLink/WithSubSubKey/MyFourthLink" )) + == "/FourthKey/MySecondLink", "test_SimpleRegistry error 31" ); + + xRootKey->deleteLink(OUString( "/FifthKey/MyFirstLink/WithSubSubKey/MyFourthLink" )); + + xRootKey->createLink(OUString( "/FourthKey/MySecondLink" ), + OUString( "/ThirdKey/FirstSubKey/WithSubSubKey" )); + + xKey = xRootKey->openKey("SixthKey"); + seqNames = xKey->getKeyNames(); + seqKeys = xKey->openKeys(); + + OSL_ENSURE( seqNames.getArray()[0] == "/SixthKey/SixthSubKey", + "test_SimpleRegistry error 32" ); + OSL_ENSURE( seqNames.getArray()[1] == "/SixthKey/MyThirdLink", + "test_SimpleRegistry error 33" ); + + OSL_ENSURE( seqKeys.getArray()[0]->getKeyName() == "/SixthKey/SixthSubKey", + "test_SimpleRegistry error 34" ); + OSL_ENSURE( seqKeys.getArray()[1]->getKeyName() == "/ThirdKey/FirstSubKey/WithSubSubKey", + "test_SimpleRegistry error 35" ); + + xRootKey->deleteLink(OUString( "/FourthKey/MySecondLink" )); + xRootKey->closeKey(); + } + catch(InvalidRegistryException&) + { + OSL_ENSURE(0, "exception InvalidRegistryExcption raised while doing test_SimpleRegistry"); + } + catch(InvalidValueException&) + { + OSL_ENSURE(0, "exception InvalidValueExcption raised while doing test_SimpleRegistry()"); + } + + xReg.clear(); + + printf("Test SimpleRegistry, OK!\n"); +} + + +void test_DefaultRegistry( + OUString const & testreg, + OUString const & testreg2, + bool bMergeDifferently = false ) +{ + // Test NestedRegistry + OUString exePath( getExePath() ); + OUString userRdb(exePath); + OUString applicatRdb(exePath); + + userRdb += "user.rdb"; + applicatRdb += "stoctest.rdb"; + + Reference < XMultiServiceFactory > rSMgr = ::cppu::createRegistryServiceFactory( userRdb, applicatRdb, sal_False, OUString()); + //OUString("//./e:/src596/stoc/wntmsci3/bin") ); + + Reference< XPropertySet > xPropSet( rSMgr, UNO_QUERY); + OSL_ENSURE( xPropSet.is(), "test_DefaultRegistry error0"); + + Any aPropertyAny( xPropSet->getPropertyValue("Registry") ); + OSL_ENSURE( aPropertyAny.hasValue(), "test_DefaultRegistry error1"); + + Reference<XSimpleRegistry> xReg; + aPropertyAny >>= xReg; + OSL_ENSURE( xReg.is(), "test_DefaultRegistry error1a"); + + Reference<XServiceInfo> xServInfo( Reference<XServiceInfo>::query(xReg) ); + + OSL_ENSURE( xServInfo.is(), "test_DefaultRegistry error2"); + + OSL_ENSURE( xServInfo->getImplementationName() == "com.sun.star.comp.stoc.NestedRegistry", "test_DefaultRegistry error3"); + OSL_ENSURE( xServInfo->supportsService("com.sun.star.registry.NestedRegistry"), "test_DefaultRegistry error4"); + OSL_ENSURE( xServInfo->getSupportedServiceNames().getLength() == 1, "test_DefaultRegistry error5"); + xServInfo.clear(); + + OSL_ENSURE( xReg.is(), "test_DefaultRegistry error6"); + + try + { + Reference<XRegistryKey> xRootKey(xReg->getRootKey()); + + Reference<XRegistryKey> xKey = xRootKey->openKey("/UCR/com/sun/star/registry/XSimpleRegistry"); + + OSL_ENSURE( xKey->getKeyName() == "/UCR/com/sun/star/registry/XSimpleRegistry", + "test_DefaultRegistry error 7" ); + + if (bMergeDifferently) + { + mergeKeys( + xReg, + OUString( "Test" ), + testreg ); + } + else + { + xReg->mergeKey(OUString( "Test" ), testreg ); + } + + xKey = xRootKey->openKey("Test/ThirdKey/FirstSubKey/WithSubSubKey"); + if (xKey.is()) + xKey->setLongValue(123456789); + + xKey = xRootKey->openKey("Test/ThirdKey/FirstSubKey"); + if (xKey.is()) + { + xKey->createKey(OUString( "SecondSubSubKey" )); + + Sequence<OUString> seqNames = xKey->getKeyNames(); + + OSL_ENSURE( seqNames.getLength() == 2, "test_DefaultRegistry error 8" ); + } + + xKey = xRootKey->openKey("/Test/ThirdKey"); + if (xKey.is()) + { + RegistryValueType valueType = xKey->getValueType(); + OSL_ENSURE( valueType == RegistryValueType_ASCIILIST, "test_DefaultRegistry error 9" ); + + Sequence<OUString> seqValue = xKey->getAsciiListValue(); + + OSL_ENSURE( seqValue.getLength() == 3, "test_DefaultRegistry error 10" ); + OSL_ENSURE( seqValue.getArray()[0] == "Hello", + "test_DefaultRegistry error 11" ); + OSL_ENSURE( seqValue.getArray()[1] == "here I", + "test_DefaultRegistry error 12" ); + OSL_ENSURE( seqValue.getArray()[2] == "come", + "test_DefaultRegistry error 13" ); + + xKey->setLongListValue({ 1234, 4567, 7890 }); + + Sequence<sal_Int32> seqLongValue = xKey->getLongListValue(); + + OSL_ENSURE( seqLongValue.getLength() == 3, "test_DefaultRegistry error 14" ); + OSL_ENSURE( seqLongValue.getArray()[0] == 1234, "test_DefaultRegistry error 15" ); + OSL_ENSURE( seqLongValue.getArray()[1] == 4567, "test_DefaultRegistry error 16" ); + OSL_ENSURE( seqLongValue.getArray()[2] == 7890, "test_DefaultRegistry error 17" ); + } + + // Test Links + xKey = xRootKey->createKey(OUString( "/Test/FifthKey" )); + xKey->createLink(OUString( "MyFirstLink" ), + OUString( "/Test/ThirdKey/FirstSubKey" )); + + xKey = xRootKey->openKey("/Test/FifthKey/MyFirstLink"); + OSL_ENSURE( xKey->isValid(), "test_DefaultRegistry error 18" ); + OSL_ENSURE( xKey->getKeyName() == "/Test/ThirdKey/FirstSubKey", + "test_DefaultRegistry error 19" ); + + xKey->createLink(OUString( "/WithSubSubKey/MyFourthLink" ), + OUString( "/Test/FourthKey/MySecondLink" )); + + OSL_ENSURE( xKey->getLinkTarget(OUString( "/WithSubSubKey/MyFourthLink" )) + == "/Test/FourthKey/MySecondLink", + "test_DefaultRegistry error 20" ); + + try + { + OSL_ENSURE( xKey->getResolvedName(OUString( "/WithSubSubKey/MyFourthLink/BlaBlaBla" )) + == "/Test/FourthKey/MySecondLink/BlaBlaBla", + "test_DefaultRegistry error 21" ); + } + catch(InvalidRegistryException&) + { + } + + xRootKey->createLink(OUString( "/Test/FourthKey/MySecondLink" ), + OUString( "/Test/SixthKey/MyThirdLink" )); + xKey = xRootKey->createKey(OUString( "/Test/SixthKey" )); + xKey->createLink(OUString( "MyThirdLink" ), + OUString( "/Test/FourthKey/MySecondLink" )); + + try + { + xRootKey->openKey("/Test/FifthKey/MyFirstLink/WithSubSubKey/MyFourthLink"); + } + catch(InvalidRegistryException&) + { + printf("test InvalidRegistryExcption OK!\n"); + } + + OSL_ENSURE( xRootKey->getLinkTarget(OUString( "/Test/FifthKey/MyFirstLink/WithSubSubKey/MyFourthLink" )) + == "/Test/FourthKey/MySecondLink", + "test_DefaultRegistry error 22" ); + + xRootKey->deleteLink(OUString( "/Test/FifthKey/MyFirstLink/WithSubSubKey/MyFourthLink" )); + + xKey = xRootKey->openKey("/Test/DefaultLink/SecondSubSubKey"); + if (xKey.is()) + { + OSL_ENSURE( xKey->getKeyName() == "/Test/ThirdKey/FirstSubKey/SecondSubSubKey", "test_DefaultRegistry error 23" ); + } + xKey = xRootKey->createKey(OUString( "/Test/DefaultLink/ThirdSubSubKey" )); + if (xKey.is()) + { + OSL_ENSURE( xKey->getKeyName() == "/Test/ThirdKey/FirstSubKey/ThirdSubSubKey", + "test_DefaultRegistry error 24" ); + } + + xKey = xRootKey->openKey("Test"); + OSL_ENSURE( xKey->isValid(), "test_DefaultRegistry error 25" ); + + xRootKey->deleteKey(OUString( "Test" )); + + if (bMergeDifferently) + { + mergeKeys( + xReg, + OUString( "AllFromTestreg2" ), + testreg2); + } + else + { + xReg->mergeKey(OUString( "AllFromTestreg2" ), + testreg2); + } + + xKey = xRootKey->openKey("/AllFromTestreg2/ThirdKey/FirstSubKey"); + if (xKey.is()) + { + xRootKey->deleteKey(OUString( "/AllFromTestreg2" )); + } + + } + catch(InvalidRegistryException&) + { + OSL_ENSURE(0, "exception InvalidRegistryExcption raised while doing test_DefaultRegistry"); + } + catch(InvalidValueException&) + { + OSL_ENSURE(0, "exception InvalidValueExcption raised while doing test_DefaultRegistry()"); + } + try + { + xReg->close(); + } + catch(const InvalidRegistryException& e) + { + (void)e; + OSL_ENSURE(0, OUStringToOString(e.Message,RTL_TEXTENCODING_ASCII_US).getStr()); + } + + + xReg.clear(); + + // shutdown + Reference< css::lang::XComponent > xComp( rSMgr, UNO_QUERY ); + OSL_ENSURE( xComp.is(), "### service manager has to implement XComponent!" ); + xComp->dispose(); + + printf("Test DefaultRegistry, OK!\n"); +} + + +SAL_IMPLEMENT_MAIN() +{ +// setStarUserRegistry(); + setLinkInDefaultRegistry(OUString("/Test/DefaultLink"), + OUString("/Test/FifthKey/MyFirstLink")); + + OUString reg1( "testreg1.rdb" ); + OUString reg2( "testreg2.rdb" ); + OUString areg1( "atestreg1.rdb" ); + OUString areg2( "atestreg2.rdb" ); + + test_SimpleRegistry( reg1, reg2 ); + test_DefaultRegistry( reg1, reg2 ); + test_SimpleRegistry( areg1, areg2, true ); // use different merge + test_DefaultRegistry( areg1, areg2, true ); + + Reference< XSimpleRegistry > xSimReg( ::cppu::createSimpleRegistry() ); + xSimReg->open( reg1, sal_False, sal_True ); + xSimReg->destroy(); + xSimReg->open( reg2, sal_False, sal_True ); + xSimReg->destroy(); + xSimReg->open( areg1, sal_False, sal_True ); + xSimReg->destroy(); + xSimReg->open( areg2, sal_False, sal_True ); + xSimReg->destroy(); + return 0; +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/stoc/test/testsmgr.cxx b/stoc/test/testsmgr.cxx new file mode 100644 index 0000000000..a8243386e2 --- /dev/null +++ b/stoc/test/testsmgr.cxx @@ -0,0 +1,88 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <stdio.h> + +#include <sal/main.h> +#include <osl/process.h> +#include <registry/registry.hxx> +#include <uno/mapping.hxx> + +#include <com/sun/star/registry/XSimpleRegistry.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> + +extern "C" void SAL_CALL test_ServiceManager(); + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +OString userRegEnv("STAR_USER_REGISTRY="); + +OUString getExePath() +{ + OUString exe; + + OSL_VERIFY(osl_getExecutableFile(&exe.pData) == osl_Process_E_None); + +#if defined(_WIN32) + exe = exe.copy(0, exe.getLength() - 16); +#else + exe = exe.copy(0, exe.getLength() - 12); +#endif + return exe; +} + +void setStarUserRegistry() +{ + Registry* myRegistry = new Registry(); + + RegistryKey rootKey, rKey, rKey2; + + OUString userReg = getExePath(); + userReg += "user.rdb"; + if (myRegistry->open(userReg, RegAccessMode::READWRITE)) + { + OSL_VERIFY(!myRegistry->create(userReg)); + } + + OSL_VERIFY(!myRegistry->close()); + delete myRegistry; + + userRegEnv += OUStringToOString(userReg, RTL_TEXTENCODING_ASCII_US); + putenv((char*)userRegEnv.getStr()); +} + +SAL_IMPLEMENT_MAIN() +{ + printf("ServiceManagerTest : \r"); + setStarUserRegistry(); + fflush(stdout); + test_ServiceManager(); + + printf("ServiceManagerTest : OK\n"); + return 0; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/stoc/test/testsmgr2.cxx b/stoc/test/testsmgr2.cxx new file mode 100644 index 0000000000..2e40c0444d --- /dev/null +++ b/stoc/test/testsmgr2.cxx @@ -0,0 +1,109 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#include <stdio.h> + +#include <sal/main.h> +#include <cppuhelper/bootstrap.hxx> + +#include <com/sun/star/container/XContentEnumerationAccess.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/registry/XSimpleRegistry.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/lang/DisposedException.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> + +using namespace ::cppu; +using namespace css::uno; +using namespace css::lang; +using namespace css::container; +using namespace css::registry; + +SAL_IMPLEMENT_MAIN() +{ + try + { + + Reference< XSimpleRegistry > r1 = createSimpleRegistry(); + Reference< XSimpleRegistry > r2 = createSimpleRegistry(); + r1->open( OUString( "test1.rdb" ), sal_True, sal_False ); + r2->open( OUString( "test2.rdb" ), sal_True, sal_False ); + Reference< XSimpleRegistry > r = createNestedRegistry( ); + Reference< XInitialization > rInit( r, UNO_QUERY ); + Sequence< Any > seq( 2 ); + seq[0] <<= r1; + seq[1] <<= r2; + rInit->initialize( seq ); + + Reference< XComponentContext > rComp = bootstrap_InitialComponentContext( r ); + + Reference< XContentEnumerationAccess > xCtAccess( rComp->getServiceManager(), UNO_QUERY ); + + Reference< XEnumeration > rEnum = + xCtAccess->createContentEnumeration( OUString( "com.sun.star.bridge.Bridge" ) ); + + sal_Int32 n = 0; + while( rEnum->hasMoreElements() ) + { + Reference< XServiceInfo > r3; + rEnum->nextElement() >>= r3; + OString o = OUStringToOString( r3->getImplementationName() , RTL_TEXTENCODING_ASCII_US ); + printf( "%s\n" , o.getStr() ); + Sequence< OUString > seq2 = r3->getSupportedServiceNames(); + for( int i = 0 ;i < seq2.getLength() ; i ++ ) + { + o = OUStringToOString( seq2[i] , RTL_TEXTENCODING_ASCII_US ); + printf( " %s\n" , o.getStr() ); + } + n ++; + } + // there are two services in two registries ! + OSL_ASSERT( 2 == n ); + if( 2 == n ) + { + printf( "test passed\n" ); + } + + Reference< XComponent > xComp( rComp, UNO_QUERY ); + xComp->dispose(); + try + { + xCtAccess->createContentEnumeration( + OUString( "blabla" ) ); + } + catch (DisposedException &) + { + printf( "already disposed results in DisposedException: ok.\n" ); + return 0; + } + fprintf( stderr, "missing DisposedException!\n" ); + return 1; + } + catch ( const Exception & e ) + { + OString o = OUStringToOString( e.Message , RTL_TEXTENCODING_ASCII_US ); + printf( "%s\n" , o.getStr() ); + OSL_ASSERT( 0 ); + return 1; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/stoc/test/testsmgr_cpnt.cxx b/stoc/test/testsmgr_cpnt.cxx new file mode 100644 index 0000000000..0adc74f874 --- /dev/null +++ b/stoc/test/testsmgr_cpnt.cxx @@ -0,0 +1,302 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <rtl/alloc.h> +#include <osl/security.h> +#include <osl/thread.h> +#include <osl/mutex.hxx> +#include <cppuhelper/queryinterface.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <cppuhelper/weak.hxx> +#include <uno/mapping.hxx> + + +#include <cppuhelper/factory.hxx> +#include <cppuhelper/servicefactory.hxx> +#include <cppuhelper/implbase.hxx> +#include <registry/registry.hxx> + +#include <com/sun/star/registry/XSimpleRegistry.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/registry/XImplementationRegistration.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/container/XContentEnumerationAccess.hpp> +#include <com/sun/star/container/XEnumerationAccess.hpp> +#include <com/sun/star/container/XEnumeration.hpp> + +#include <stdio.h> + +#if defined ( UNX ) +#include <limits.h> +#define _MAX_PATH PATH_MAX +#endif + + +#define IMPLEMENTATION_NAME "com.sun.star.DummyService.V10" +#define SERVICE_NAME "com.sun.star.ts.TestManagerImpl" + + +using namespace css::uno; +using namespace css::registry; +using namespace css::lang; +using namespace css::container; +using namespace osl; +using namespace cppu; + + +Reference<XMultiServiceFactory> getProcessServiceManager() +{ + static Reference<XMultiServiceFactory> s_x( + createRegistryServiceFactory(OUString("stoctest.rdb"), sal_False)); + return s_x; +} + +Reference< XMultiServiceFactory > createRegistryServiceManager( const OUString& registryName ) +{ + return createRegistryServiceFactory( registryName ); +} + + +/********************************** +* The service, that is used to test the Service manager +* +* +* +*************************************/ +static sal_uInt32 nInstanceCount = 0; +class Test_Manager_Impl : public WeakImplHelper< XServiceInfo > +{ +public: + Test_Manager_Impl(){ nInstanceCount++;} + ~Test_Manager_Impl(); + + // XServiceInfo + OUString SAL_CALL getImplementationName() throw(); + sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw(); + Sequence< OUString > SAL_CALL getSupportedServiceNames() throw(); + static Sequence< OUString > SAL_CALL getSupportedServiceNames_Static() throw(); + +private: +// static XIdlClassRef getStaticIdlClass(); +}; + +Test_Manager_Impl::~Test_Manager_Impl() +{ + nInstanceCount--; +} + + +// old, is no longer needed by the new Mimic +Reference< XInterface > SAL_CALL Test_Manager_Impl_CreateInstance_Impl() +{ + return (OWeakObject *)new Test_Manager_Impl(); +} + + +// Test_Manager_Impl_CreateInstance() + +Reference < XInterface > SAL_CALL Test_Manager_Impl_CreateInstance( + const Reference< XMultiServiceFactory > & /*rSMgr*/ ) throw (Exception) +{ + Reference < XInterface > xService = (XWeak *)(OWeakObject *)new Test_Manager_Impl( ); + + return xService; +} + + +// Test_Manager_Impl::getImplementationName + +OUString Test_Manager_Impl::getImplementationName() throw() +{ + return OUString(IMPLEMENTATION_NAME); +} + +// Test_Manager_Impl::supportsService +sal_Bool Test_Manager_Impl::supportsService( const OUString& ServiceName ) throw() +{ + return cppu::supportsService(this, ServiceName); +} + + +// Test_Manager_Impl::getSupportedServiceNames + +Sequence< OUString > Test_Manager_Impl::getSupportedServiceNames() throw () +{ + return getSupportedServiceNames_Static(); +} + + +// Test_Manager_Impl::getSupportedServiceNames_Static + +Sequence< OUString > Test_Manager_Impl::getSupportedServiceNames_Static() throw () +{ + return { SERVICE_NAME, "com.sun.star.bridge.Bridge" }; +} + + +/**** +* +* +* This routine performs the test of the process service manager ( getProcessServiceManager is called ) +* +* +* +****/ + +extern "C" void SAL_CALL test_ServiceManager() +{ +#if ! defined SAL_DLLPREFIX +#define SAL_DLLPREFIX "" +#endif + OUString atUModule2 = SAL_DLLPREFIX "testsmgr_component" SAL_DLLEXTENSION ; + + // expand shared library name + OString atModule2( OUStringToOString(atUModule2, RTL_TEXTENCODING_ASCII_US) ); + + // get the process servicemanager + Reference <XMultiServiceFactory> xSMgr = getProcessServiceManager(); + + OSL_ENSURE( xSMgr.is() , "query on XServiceManager failed" ); + + Reference<XContentEnumerationAccess> xContEnum(xSMgr, UNO_QUERY); + OSL_ENSURE( xContEnum.is() , "query on XContentEnumerationAccess failed" ); + Reference<XEnumeration > xEnum(xContEnum->createContentEnumeration(OUString("com.sun.star.registry.SimpleRegistry"))); + OSL_ENSURE( xEnum.is() , "createContentEnumeration failed" ); + sal_Int32 nLen = 0; + while( xEnum->hasMoreElements() ) + { + nLen++; + xEnum->nextElement(); + } + OSL_ENSURE( nLen == 1, "more than one implementation for SimpleRegistry" ); + + Reference<XEnumerationAccess> xImplEnum(xSMgr, UNO_QUERY); + OSL_ENSURE( xImplEnum.is() , "query on XEnumeration failed" ); + xEnum.set(xImplEnum->createEnumeration()); + OSL_ENSURE( xEnum.is() , "createEnumeration failed" ); + nLen = 0; + while( xEnum->hasMoreElements() ) + { + nLen++; + Reference< XServiceInfo > sf( xEnum->nextElement(), UNO_QUERY ); + OString str( OUStringToOString( sf->getImplementationName(), RTL_TEXTENCODING_ASCII_US ) ); + ::fprintf( stderr, "> implementation name: %s\n", str.getStr() ); + } + OSL_ENSURE( nLen == 8, "more than 6 factories" ); + + // try to get an instance for an unknown service + OSL_VERIFY( !xSMgr->createInstance("bla.blup.Q").is() ); + + + // First test : register service via the internal function of the component itself + + { + Reference< XImplementationRegistration > + xInst( xSMgr->createInstance("com.sun.star.registry.ImplementationRegistration"), UNO_QUERY ); + OSL_ENSURE( xInst.is(), "no ImplementationRegistration" ); + + try { + // register the services via writeComponentRegInfo (see at end of this file) + xInst->registerImplementation(OUString("com.sun.star.loader.SharedLibrary"), atUModule2, Reference< XSimpleRegistry >() ); + } + catch(const CannotRegisterImplementationException &) { + OSL_ENSURE( 0, "register implementation failed" ); + } + + // getImplementations() check + Sequence<OUString> seqImpl = xInst->getImplementations(OUString("com.sun.star.loader.SharedLibrary"), atUModule2); + OSL_ENSURE( seqImpl.getLength() == 1, "count of implementations is wrong" ); + OSL_ENSURE( seqImpl.getConstArray()[0] == "com.sun.star.DummyService.V10", "implementation name is not equal" ); + + + // tests, if a service provider can be instantiated. + + Reference< XInterface > xIFace(xSMgr->createInstance("com.sun.star.ts.TestManagerImpl")); + OSL_ENSURE( xIFace.is(), "loadable service not found" ); + + // remove the service + OSL_VERIFY( xInst->revokeImplementation(atUModule2, Reference< XSimpleRegistry > ()) ); + } + + Reference<XComponent> xComp(xSMgr, UNO_QUERY); + xComp->dispose(); + + xComp.clear(); + xSMgr.clear(); +} + + +extern "C" +{ + +sal_Bool SAL_CALL component_writeInfo( + void * /*pServiceManager*/, void * pRegistryKey ) +{ + if (pRegistryKey) + { + try + { + Reference< XRegistryKey > xNewKey( + reinterpret_cast< XRegistryKey * >( pRegistryKey )->createKey( + OUString( "/" IMPLEMENTATION_NAME "/UNO/SERVICES" ) ) ); + + const Sequence< OUString > & rSNL = + Test_Manager_Impl::getSupportedServiceNames_Static(); + const OUString * pArray = rSNL.getConstArray(); + for ( sal_Int32 nPos = rSNL.getLength(); nPos--; ) + xNewKey->createKey( pArray[nPos] ); + + return sal_True; + } + catch (InvalidRegistryException &) + { + OSL_FAIL( "### InvalidRegistryException!" ); + } + } + return sal_False; +} + +SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory( + const char * pImplName, void * pServiceManager, void * /*pRegistryKey*/ ) +{ + void * pRet = 0; + + if (rtl_str_compare( pImplName, IMPLEMENTATION_NAME ) == 0) + { + Reference< XSingleServiceFactory > xFactory( createSingleFactory( + reinterpret_cast< XMultiServiceFactory * >( pServiceManager ), + OUString( IMPLEMENTATION_NAME ), + Test_Manager_Impl_CreateInstance, + Test_Manager_Impl::getSupportedServiceNames_Static() ) ); + + if (xFactory.is()) + { + xFactory->acquire(); + pRet = xFactory.get(); + } + } + + return pRet; +} +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/stoc/test/testsmgr_cpnt.map b/stoc/test/testsmgr_cpnt.map new file mode 100644 index 0000000000..0bd933d7e8 --- /dev/null +++ b/stoc/test/testsmgr_cpnt.map @@ -0,0 +1,25 @@ +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you under the Apache +# License, Version 2.0 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.apache.org/licenses/LICENSE-2.0 . +# +UDK_3_0_0 { + global: + component_writeInfo; + component_getFactory; + test_ServiceManager; + local: + *; +}; diff --git a/stoc/test/uriproc/test_uriproc.cxx b/stoc/test/uriproc/test_uriproc.cxx new file mode 100644 index 0000000000..aa96e6a86b --- /dev/null +++ b/stoc/test/uriproc/test_uriproc.cxx @@ -0,0 +1,1420 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/uri/ExternalUriReferenceTranslator.hpp> +#include <com/sun/star/uri/UriReferenceFactory.hpp> +#include <com/sun/star/uri/VndSunStarPkgUrlReferenceFactory.hpp> +#include <com/sun/star/uri/XExternalUriReferenceTranslator.hpp> +#include <com/sun/star/uri/XUriReference.hpp> +#include <com/sun/star/uri/XUriReferenceFactory.hpp> +#include <com/sun/star/uri/XVndSunStarExpandUrlReference.hpp> +#include <com/sun/star/uri/XVndSunStarPkgUrlReferenceFactory.hpp> +#include <com/sun/star/uri/XVndSunStarScriptUrlReference.hpp> +#include <com/sun/star/util/XMacroExpander.hpp> +#include <cppuhelper/bootstrap.hxx> +#include <cppunit/TestAssert.h> +#include <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/plugin/TestPlugIn.h> +#include <rtl/string.hxx> +#include <rtl/textenc.h> +#include <rtl/uri.hxx> +#include <rtl/ustrbuf.hxx> +#include <rtl/ustring.hxx> +#include <sal/types.h> +#include <sal/macros.h> + +namespace { + +#define TEST_ASSERT_EQUAL(token1, token2, token3, expected, actual) \ + CPPUNIT_ASSERT_EQUAL_MESSAGE( \ + createTestAssertEqualMessage( \ + token1, token2, token3, #expected, #actual, expected, actual). \ + getStr(), \ + (expected), (actual)) + +template< typename T > void append( + OUStringBuffer & buffer, T const & value) +{ + buffer.append(value); +} + +template<> void append(OUStringBuffer & buffer, bool const & value) { + buffer.append(value); +} + +template<> void append(OUStringBuffer & buffer, std::size_t const & value) +{ + buffer.append(static_cast< sal_Int32 >(value)); +} + +template<> void append(OUStringBuffer & buffer, char const * const & value) +{ + buffer.appendAscii(value); +} + +template< typename T1, typename T2, typename T3, typename T4 > +OString createTestAssertEqualMessage( + char const * token1, T1 const & token2, T2 const & token3, + char const * expectedExpr, char const * actualExpr, T3 const & expected, + T4 const & actual) +{ + OUStringBuffer buf(512); + buf.appendAscii(token1); + buf.append('|'); + append(buf, token2); + buf.append('|'); + append(buf, token3); + buf.append(": TEST_ASSERT_EQUAL("); + buf.appendAscii(expectedExpr); + buf.append(", "); + buf.appendAscii(actualExpr); + buf.append("): <"); + append(buf, expected); + buf.append("> != <"); + append(buf, actual); + buf.append('>'); + return OUStringToOString( + buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US); +} + +class Test: public CppUnit::TestFixture { +public: + virtual void setUp(); + + virtual void tearDown(); + + void testParse(); + + void testMakeAbsolute(); + + void testMakeRelative(); + + void testVndSunStarExpand(); + + void testVndSunStarScript(); + + void testTranslator(); + + void testPkgUrlFactory(); + + CPPUNIT_TEST_SUITE(Test); + CPPUNIT_TEST(testParse); + CPPUNIT_TEST(testMakeAbsolute); + CPPUNIT_TEST(testMakeRelative); + CPPUNIT_TEST(testVndSunStarExpand); + CPPUNIT_TEST(testVndSunStarScript); + CPPUNIT_TEST(testTranslator); + CPPUNIT_TEST(testPkgUrlFactory); + CPPUNIT_TEST_SUITE_END(); + +private: + css::uno::Reference< css::uno::XComponentContext > m_context; + css::uno::Reference< css::uri::XUriReferenceFactory > m_uriFactory; +}; + +void Test::setUp() { + m_context = cppu::defaultBootstrap_InitialComponentContext(); + m_uriFactory = css::uri::UriReferenceFactory::create(m_context); +} + +void Test::tearDown() { + m_uriFactory.clear(); + css::uno::Reference< css::lang::XComponent >( + m_context, css::uno::UNO_QUERY_THROW)->dispose(); +} + +void Test::testParse() { + struct Data { + char const * uriReference; + char const * scheme; + char const * schemeSpecificPart; + bool isHierarchical; + char const * authority; + char const * path; + bool hasRelativePath; + sal_Int32 pathSegmentCount; + char const * pathSegment0; + char const * pathSegment1; + char const * pathSegment2; + char const * pathSegment3; + char const * pathSegment4; + char const * query; + char const * fragment; + }; + Data data[] = { + { "", nullptr, "", true, nullptr, + "", true, 0, "", "", "", "", "", nullptr, nullptr }, + { "scheme:", "scheme", "", false, nullptr, + "", true, 0, "", "", "", "", "", nullptr, nullptr }, + { "scheme:/", "scheme", "/", true, nullptr, + "/", false, 1, "", "", "", "", "", nullptr, nullptr }, + { "scheme://", "scheme", "//", true, "", + "", false, 0, "", "", "", "", "", nullptr, nullptr }, + { "scheme:///", "scheme", "///", true, "", + "/", false, 1, "", "", "", "", "", nullptr, nullptr }, + { "scheme:////", "scheme", "////", true, "", + "//", false, 2, "", "", "", "", "", nullptr, nullptr }, + { "scheme:////", "scheme", "////", true, "", + "//", false, 2, "", "", "", "", "", nullptr, nullptr }, + { "scheme:#", "scheme", "", false, nullptr, + "", true, 0, "", "", "", "", "", nullptr, "" }, + { "scheme:?", "scheme", "?", false, nullptr, + "", true, 0, "", "", "", "", "", "", nullptr }, + { "/", nullptr, "/", true, nullptr, + "/", false, 1, "", "", "", "", "", nullptr, nullptr }, + { "//", nullptr, "//", true, "", + "", false, 0, "", "", "", "", "", nullptr, nullptr }, + { "///", nullptr, "///", true, "", + "/", false, 1, "", "", "", "", "", nullptr, nullptr }, + { "////", nullptr, "////", true, "", + "//", false, 2, "", "", "", "", "", nullptr, nullptr } }; + for (std::size_t i = 0; i < SAL_N_ELEMENTS(data); ++i) { + css::uno::Reference< css::uri::XUriReference > uriRef( + m_uriFactory->parse( + OUString::createFromAscii(data[i].uriReference))); + TEST_ASSERT_EQUAL( + "testParse", i, data[i].uriReference, data[i].schemeSpecificPart != nullptr, + uriRef.is()); + if (uriRef.is()) { + TEST_ASSERT_EQUAL( + "testParse", i, data[i].uriReference, + OUString::createFromAscii(data[i].uriReference), + uriRef->getUriReference()); + TEST_ASSERT_EQUAL( + "testParse", i, data[i].uriReference, + data[i].scheme != nullptr, bool(uriRef->isAbsolute())); + TEST_ASSERT_EQUAL( + "testParse", i, data[i].uriReference, + OUString::createFromAscii( + data[i].scheme == nullptr ? "" : data[i].scheme), + uriRef->getScheme()); + TEST_ASSERT_EQUAL( + "testParse", i, data[i].uriReference, + OUString::createFromAscii(data[i].schemeSpecificPart), + uriRef->getSchemeSpecificPart()); + TEST_ASSERT_EQUAL( + "testParse", i, data[i].uriReference, + data[i].isHierarchical, + static_cast< bool >(uriRef->isHierarchical())); + TEST_ASSERT_EQUAL( + "testParse", i, data[i].uriReference, + data[i].authority != nullptr, bool(uriRef->hasAuthority())); + TEST_ASSERT_EQUAL( + "testParse", i, data[i].uriReference, + OUString::createFromAscii( + data[i].authority == nullptr ? "" : data[i].authority), + uriRef->getAuthority()); + TEST_ASSERT_EQUAL( + "testParse", i, data[i].uriReference, + OUString::createFromAscii(data[i].path), + uriRef->getPath()); + TEST_ASSERT_EQUAL( + "testParse", i, data[i].uriReference, + data[i].hasRelativePath, + static_cast< bool >(uriRef->hasRelativePath())); + TEST_ASSERT_EQUAL( + "testParse", i, data[i].uriReference, + data[i].pathSegmentCount, uriRef->getPathSegmentCount()); + TEST_ASSERT_EQUAL( + "testParse", i, data[i].uriReference, + OUString(), uriRef->getPathSegment(-1)); + TEST_ASSERT_EQUAL( + "testParse", i, data[i].uriReference, + OUString::createFromAscii(data[i].pathSegment0), + uriRef->getPathSegment(0)); + TEST_ASSERT_EQUAL( + "testParse", i, data[i].uriReference, + OUString::createFromAscii(data[i].pathSegment1), + uriRef->getPathSegment(1)); + TEST_ASSERT_EQUAL( + "testParse", i, data[i].uriReference, + OUString::createFromAscii(data[i].pathSegment2), + uriRef->getPathSegment(2)); + TEST_ASSERT_EQUAL( + "testParse", i, data[i].uriReference, + OUString::createFromAscii(data[i].pathSegment3), + uriRef->getPathSegment(3)); + TEST_ASSERT_EQUAL( + "testParse", i, data[i].uriReference, + OUString::createFromAscii(data[i].pathSegment4), + uriRef->getPathSegment(4)); + TEST_ASSERT_EQUAL( + "testParse", i, data[i].uriReference, + OUString(), uriRef->getPathSegment(5)); + TEST_ASSERT_EQUAL( + "testParse", i, data[i].uriReference, + data[i].query != nullptr, bool(uriRef->hasQuery())); + TEST_ASSERT_EQUAL( + "testParse", i, data[i].uriReference, + OUString::createFromAscii( + data[i].query == nullptr ? "" : data[i].query), + uriRef->getQuery()); + TEST_ASSERT_EQUAL( + "testParse", i, data[i].uriReference, + data[i].fragment != nullptr, bool(uriRef->hasFragment())); + TEST_ASSERT_EQUAL( + "testParse", i, data[i].uriReference, + OUString::createFromAscii( + data[i].fragment == nullptr ? "" : data[i].fragment), + uriRef->getFragment()); + } + } +} + +void Test::testMakeAbsolute() { + struct Data { + char const * baseUriReference; + char const * uriReference; + bool processSpecialBaseSegments; + css::uri::RelativeUriExcessParentSegments excessParentSegments; + char const * absolute; + }; + Data data[] = { + // The following tests are taken from RFC 3986, Section 5.4: + { "http://a/b/c/d;p?q", "g:h", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "g:h" }, + { "http://a/b/c/d;p?q", "g", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "http://a/b/c/g" }, + { "http://a/b/c/d;p?q", "./g", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "http://a/b/c/g" }, + { "http://a/b/c/d;p?q", "g/", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "http://a/b/c/g/" }, + { "http://a/b/c/d;p?q", "/g", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "http://a/g" }, + { "http://a/b/c/d;p?q", "//g", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "http://g" }, + { "http://a/b/c/d;p?q", "?y", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "http://a/b/c/d;p?y" }, + { "http://a/b/c/d;p?q", "g?y", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, + "http://a/b/c/g?y" }, + { "http://a/b/c/d;p?q", "#s", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, + "http://a/b/c/d;p?q#s" }, + { "http://a/b/c/d;p?q", "g#s", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, + "http://a/b/c/g#s" }, + { "http://a/b/c/d;p?q", "g?y#s", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, + "http://a/b/c/g?y#s" }, + { "http://a/b/c/d;p?q", ";x", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "http://a/b/c/;x" }, + { "http://a/b/c/d;p?q", "g;x", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, + "http://a/b/c/g;x" }, + { "http://a/b/c/d;p?q", "g;x?y#s", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, + "http://a/b/c/g;x?y#s" }, + { "http://a/b/c/d;p?q", "", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, + "http://a/b/c/d;p?q" }, + { "http://a/b/c/d;p?q", ".", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "http://a/b/c/" }, + { "http://a/b/c/d;p?q", "./", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "http://a/b/c/" }, + { "http://a/b/c/d;p?q", "..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "http://a/b/" }, + { "http://a/b/c/d;p?q", "../", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "http://a/b/" }, + { "http://a/b/c/d;p?q", "../g", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "http://a/b/g" }, + { "http://a/b/c/d;p?q", "../..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "http://a/" }, + { "http://a/b/c/d;p?q", "../../", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "http://a/" }, + { "http://a/b/c/d;p?q", "../../g", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "http://a/g" }, + { "http://a/b/c/d;p?q", "../../../g", true, + css::uri::RelativeUriExcessParentSegments_ERROR, nullptr }, + { "http://a/b/c/d;p?q", "../../../g", true, + css::uri::RelativeUriExcessParentSegments_RETAIN, "http://a/../g" }, + { "http://a/b/c/d;p?q", "../../../g", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "http://a/g" }, + { "http://a/b/c/d;p?q", "../../../../g", true, + css::uri::RelativeUriExcessParentSegments_ERROR, nullptr }, + { "http://a/b/c/d;p?q", "../../../../g", true, + css::uri::RelativeUriExcessParentSegments_RETAIN, + "http://a/../../g" }, + { "http://a/b/c/d;p?q", "../../../../g", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "http://a/g" }, + { "http://a/b/c/d;p?q", "/./g", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "http://a/g" }, + { "http://a/b/c/d;p?q", "/../g", true, + css::uri::RelativeUriExcessParentSegments_ERROR, nullptr }, + { "http://a/b/c/d;p?q", "/../g", true, + css::uri::RelativeUriExcessParentSegments_RETAIN, "http://a/../g" }, + { "http://a/b/c/d;p?q", "/../g", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "http://a/g" }, + { "http://a/b/c/d;p?q", "g.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "http://a/b/c/g." }, + { "http://a/b/c/d;p?q", ".g", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "http://a/b/c/.g" }, + { "http://a/b/c/d;p?q", "g..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, + "http://a/b/c/g.." }, + { "http://a/b/c/d;p?q", "..g", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, + "http://a/b/c/..g" }, + { "http://a/b/c/d;p?q", "./../g", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "http://a/b/g" }, + { "http://a/b/c/d;p?q", "./g/.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "http://a/b/c/g/" }, + { "http://a/b/c/d;p?q", "g/./h", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, + "http://a/b/c/g/h" }, + { "http://a/b/c/d;p?q", "g/../h", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "http://a/b/c/h" }, + { "http://a/b/c/d;p?q", "g;x=1/./y", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, + "http://a/b/c/g;x=1/y" }, + { "http://a/b/c/d;p?q", "g;x=1/../y", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "http://a/b/c/y" }, + { "http://a/b/c/d;p?q", "g?y/./x", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, + "http://a/b/c/g?y/./x" }, + { "http://a/b/c/d;p?q", "g?y/../x", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, + "http://a/b/c/g?y/../x" }, + { "http://a/b/c/d;p?q", "g#s/./x", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, + "http://a/b/c/g#s/./x" }, + { "http://a/b/c/d;p?q", "g#s/../x", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, + "http://a/b/c/g#s/../x" }, + { "http://a/b/c/d;p?q", "http:g", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "http:g" }, + + { "scheme:", "", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:" }, + { "scheme:", ".", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:" }, + { "scheme:", "./", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:" }, + { "scheme:", "./.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:" }, + { "scheme:", "././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:" }, + { "scheme:", "././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:" }, + { "scheme:", "x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + { "scheme:", "x/../", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + { "scheme:", "x/../.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + { "scheme:", "x/.././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + { "scheme:", "x/.././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + { "scheme:", "x/../././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + { "scheme:", "x/../././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + { "scheme:", "./x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + { "scheme:", "././x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + { "scheme:", "./././x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + { "scheme:", "./x/../.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + { "scheme:", "./x/.././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + { "scheme:", "././x/.././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + { "scheme:", "././x/../././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + { "scheme:", "./././x/../././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + + { "scheme://a", "", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a" }, + { "scheme://a", ".", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a", "./", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a", "./.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a", "././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a", "././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a", "x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a", "x/../", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a", "x/../.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a", "x/.././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a", "x/.././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a", "x/../././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a", "x/../././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a", "./x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a", "././x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a", "./././x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a", "./x/../.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a", "./x/.././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a", "././x/.././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a", "././x/../././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a", "./././x/../././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + + { "scheme://a/", "", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a/", ".", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a/", "./", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a/", "./.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a/", "././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a/", "././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a/", "x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a/", "x/../", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a/", "x/../.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a/", "x/.././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a/", "x/.././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a/", "x/../././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a/", "x/../././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a/", "./x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a/", "././x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a/", "./././x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a/", "./x/../.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a/", "./x/.././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a/", "././x/.././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a/", "././x/../././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a/", "./././x/../././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + + { "scheme://a/b", "", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/b" }, + { "scheme://a/b", ".", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a/b", "./", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a/b", "./.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a/b", "././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a/b", "././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a/b", "x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a/b", "x/../", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a/b", "x/../.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a/b", "x/.././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a/b", "x/.././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a/b", "x/../././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a/b", "x/../././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a/b", "./x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a/b", "././x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a/b", "./././x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a/b", "./x/../.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a/b", "./x/.././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a/b", "././x/.././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a/b", "././x/../././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + { "scheme://a/b", "./././x/../././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/" }, + + { "scheme://a/b/", "", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/b/" }, + { "scheme://a/b/", ".", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/b/" }, + { "scheme://a/b/", "./", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/b/" }, + { "scheme://a/b/", "./.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/b/" }, + { "scheme://a/b/", "././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/b/" }, + { "scheme://a/b/", "././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/b/" }, + { "scheme://a/b/", "x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/b/" }, + { "scheme://a/b/", "x/../", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/b/" }, + { "scheme://a/b/", "x/../.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/b/" }, + { "scheme://a/b/", "x/.././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/b/" }, + { "scheme://a/b/", "x/.././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/b/" }, + { "scheme://a/b/", "x/../././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/b/" }, + { "scheme://a/b/", "x/../././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/b/" }, + { "scheme://a/b/", "./x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/b/" }, + { "scheme://a/b/", "././x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/b/" }, + { "scheme://a/b/", "./././x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/b/" }, + { "scheme://a/b/", "./x/../.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/b/" }, + { "scheme://a/b/", "./x/.././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/b/" }, + { "scheme://a/b/", "././x/.././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/b/" }, + { "scheme://a/b/", "././x/../././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/b/" }, + { "scheme://a/b/", "./././x/../././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a/b/" }, + + { "scheme:a", "", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a" }, + { "scheme:a", ".", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:" }, + { "scheme:a", "./", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:" }, + { "scheme:a", "./.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:" }, + { "scheme:a", "././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:" }, + { "scheme:a", "././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:" }, + { "scheme:a", "x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + { "scheme:a", "x/../", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + { "scheme:a", "x/../.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + { "scheme:a", "x/.././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + { "scheme:a", "x/.././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + { "scheme:a", "x/../././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + { "scheme:a", "x/../././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + { "scheme:a", "./x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + { "scheme:a", "././x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + { "scheme:a", "./././x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + { "scheme:a", "./x/../.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + { "scheme:a", "./x/.././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + { "scheme:a", "././x/.././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + { "scheme:a", "././x/../././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + { "scheme:a", "./././x/../././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + + { "scheme:a/", "", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/" }, + { "scheme:a/", ".", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/" }, + { "scheme:a/", "./", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/" }, + { "scheme:a/", "./.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/" }, + { "scheme:a/", "././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/" }, + { "scheme:a/", "././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/" }, + { "scheme:a/", "x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/" }, + { "scheme:a/", "x/../", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/" }, + { "scheme:a/", "x/../.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/" }, + { "scheme:a/", "x/.././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/" }, + { "scheme:a/", "x/.././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/" }, + { "scheme:a/", "x/../././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/" }, + { "scheme:a/", "x/../././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/" }, + { "scheme:a/", "./x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/" }, + { "scheme:a/", "././x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/" }, + { "scheme:a/", "./././x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/" }, + { "scheme:a/", "./x/../.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/" }, + { "scheme:a/", "./x/.././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/" }, + { "scheme:a/", "././x/.././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/" }, + { "scheme:a/", "././x/../././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/" }, + { "scheme:a/", "./././x/../././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/" }, + + { "scheme:a/b", "", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/b" }, + { "scheme:a/b", ".", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/" }, + { "scheme:a/b", "./", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/" }, + { "scheme:a/b", "./.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/" }, + { "scheme:a/b", "././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/" }, + { "scheme:a/b", "././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/" }, + { "scheme:a/b", "x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/" }, + { "scheme:a/b", "x/../", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/" }, + { "scheme:a/b", "x/../.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/" }, + { "scheme:a/b", "x/.././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/" }, + { "scheme:a/b", "x/.././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/" }, + { "scheme:a/b", "x/../././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/" }, + { "scheme:a/b", "x/../././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/" }, + { "scheme:a/b", "./x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/" }, + { "scheme:a/b", "././x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/" }, + { "scheme:a/b", "./././x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/" }, + { "scheme:a/b", "./x/../.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/" }, + { "scheme:a/b", "./x/.././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/" }, + { "scheme:a/b", "././x/.././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/" }, + { "scheme:a/b", "././x/../././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/" }, + { "scheme:a/b", "./././x/../././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/" }, + + { "scheme:a/b/", "", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/b/" }, + { "scheme:a/b/", ".", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/b/" }, + { "scheme:a/b/", "./", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/b/" }, + { "scheme:a/b/", "./.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/b/" }, + { "scheme:a/b/", "././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/b/" }, + { "scheme:a/b/", "././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/b/" }, + { "scheme:a/b/", "x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/b/" }, + { "scheme:a/b/", "x/../", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/b/" }, + { "scheme:a/b/", "x/../.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/b/" }, + { "scheme:a/b/", "x/.././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/b/" }, + { "scheme:a/b/", "x/.././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/b/" }, + { "scheme:a/b/", "x/../././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/b/" }, + { "scheme:a/b/", "x/../././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/b/" }, + { "scheme:a/b/", "./x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/b/" }, + { "scheme:a/b/", "././x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/b/" }, + { "scheme:a/b/", "./././x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/b/" }, + { "scheme:a/b/", "./x/../.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/b/" }, + { "scheme:a/b/", "./x/.././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/b/" }, + { "scheme:a/b/", "././x/.././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/b/" }, + { "scheme:a/b/", "././x/../././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/b/" }, + { "scheme:a/b/", "./././x/../././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:a/b/" }, + + { "scheme:/a", "", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a" }, + { "scheme:/a", ".", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + { "scheme:/a", "./", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + { "scheme:/a", "./.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + { "scheme:/a", "././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + { "scheme:/a", "././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + { "scheme:/a", "x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + { "scheme:/a", "x/../", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + { "scheme:/a", "x/../.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + { "scheme:/a", "x/.././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + { "scheme:/a", "x/.././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + { "scheme:/a", "x/../././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + { "scheme:/a", "x/../././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + { "scheme:/a", "./x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + { "scheme:/a", "././x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + { "scheme:/a", "./././x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + { "scheme:/a", "./x/../.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + { "scheme:/a", "./x/.././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + { "scheme:/a", "././x/.././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + { "scheme:/a", "././x/../././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + { "scheme:/a", "./././x/../././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/" }, + + { "scheme:/a/", "", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/" }, + { "scheme:/a/", ".", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/" }, + { "scheme:/a/", "./", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/" }, + { "scheme:/a/", "./.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/" }, + { "scheme:/a/", "././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/" }, + { "scheme:/a/", "././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/" }, + { "scheme:/a/", "x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/" }, + { "scheme:/a/", "x/../", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/" }, + { "scheme:/a/", "x/../.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/" }, + { "scheme:/a/", "x/.././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/" }, + { "scheme:/a/", "x/.././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/" }, + { "scheme:/a/", "x/../././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/" }, + { "scheme:/a/", "x/../././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/" }, + { "scheme:/a/", "./x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/" }, + { "scheme:/a/", "././x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/" }, + { "scheme:/a/", "./././x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/" }, + { "scheme:/a/", "./x/../.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/" }, + { "scheme:/a/", "./x/.././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/" }, + { "scheme:/a/", "././x/.././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/" }, + { "scheme:/a/", "././x/../././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/" }, + { "scheme:/a/", "./././x/../././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/" }, + + { "scheme:/a/b", "", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/b" }, + { "scheme:/a/b", ".", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/" }, + { "scheme:/a/b", "./", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/" }, + { "scheme:/a/b", "./.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/" }, + { "scheme:/a/b", "././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/" }, + { "scheme:/a/b", "././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/" }, + { "scheme:/a/b", "x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/" }, + { "scheme:/a/b", "x/../", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/" }, + { "scheme:/a/b", "x/../.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/" }, + { "scheme:/a/b", "x/.././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/" }, + { "scheme:/a/b", "x/.././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/" }, + { "scheme:/a/b", "x/../././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/" }, + { "scheme:/a/b", "x/../././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/" }, + { "scheme:/a/b", "./x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/" }, + { "scheme:/a/b", "././x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/" }, + { "scheme:/a/b", "./././x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/" }, + { "scheme:/a/b", "./x/../.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/" }, + { "scheme:/a/b", "./x/.././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/" }, + { "scheme:/a/b", "././x/.././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/" }, + { "scheme:/a/b", "././x/../././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/" }, + { "scheme:/a/b", "./././x/../././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/" }, + + { "scheme:/a/b/", "", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/b/" }, + { "scheme:/a/b/", ".", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/b/" }, + { "scheme:/a/b/", "./", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/b/" }, + { "scheme:/a/b/", "./.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/b/" }, + { "scheme:/a/b/", "././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/b/" }, + { "scheme:/a/b/", "././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/b/" }, + { "scheme:/a/b/", "x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/b/" }, + { "scheme:/a/b/", "x/../", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/b/" }, + { "scheme:/a/b/", "x/../.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/b/" }, + { "scheme:/a/b/", "x/.././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/b/" }, + { "scheme:/a/b/", "x/.././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/b/" }, + { "scheme:/a/b/", "x/../././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/b/" }, + { "scheme:/a/b/", "x/../././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/b/" }, + { "scheme:/a/b/", "./x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/b/" }, + { "scheme:/a/b/", "././x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/b/" }, + { "scheme:/a/b/", "./././x/..", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/b/" }, + { "scheme:/a/b/", "./x/../.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/b/" }, + { "scheme:/a/b/", "./x/.././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/b/" }, + { "scheme:/a/b/", "././x/.././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/b/" }, + { "scheme:/a/b/", "././x/../././", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/b/" }, + { "scheme:/a/b/", "./././x/../././.", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme:/a/b/" }, + + { "scheme://a#s", "", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a" }, + { "scheme://a", "?q", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a?q" }, + { "scheme://a#s", "?q", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a?q" }, + { "scheme://a", "#s", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a#s" }, + { "scheme://a#s1", "#s2", true, + css::uri::RelativeUriExcessParentSegments_REMOVE, "scheme://a#s2" }, + + { "schema://a", "schema://b/c/../d", true, css::uri::RelativeUriExcessParentSegments_REMOVE, + "schema://b/d" }, + + // Per RFC 3986 Section 5.2.1 "Pre-parse the Base URI", "Normalization of the base URI + // [...; esp. dot-segment removal per Section 6.2.2.3 "Path Segment Normalization"] is + // optional" (and not done by our implementation), so if the relative URI has no scheme and + // no authority and an empty path, the Base URI's path is used unmodified per Section 5.2.2 + // "Transform References" and thus still contains dot-segments: + { "scheme:/a/../b/c", "", true, css::uri::RelativeUriExcessParentSegments_REMOVE, + "scheme:/a/../b/c" }, + { "scheme:/a/../b/c", "d", true, css::uri::RelativeUriExcessParentSegments_REMOVE, + "scheme:/b/d" } }; + for (std::size_t i = 0; i < SAL_N_ELEMENTS(data); ++i) { + css::uno::Reference< css::uri::XUriReference > baseUriRef( + m_uriFactory->parse( + OUString::createFromAscii(data[i].baseUriReference))); + TEST_ASSERT_EQUAL("testMakeAbsolute", i, data[i].baseUriReference, true, baseUriRef.is()); + css::uno::Reference< css::uri::XUriReference > uriRef( + m_uriFactory->parse( + OUString::createFromAscii(data[i].uriReference))); + TEST_ASSERT_EQUAL("testMakeAbsolute", i, data[i].uriReference, true, uriRef.is()); + css::uno::Reference< css::uri::XUriReference > absolute( + m_uriFactory->makeAbsolute( + baseUriRef, uriRef, data[i].processSpecialBaseSegments, + data[i].excessParentSegments)); + TEST_ASSERT_EQUAL( + "testMakeAbsolute", i, data[i].uriReference, + data[i].absolute != nullptr, absolute.is()); + if (absolute.is()) { + TEST_ASSERT_EQUAL( + "testMakeAbsolute", i, data[i].uriReference, + OUString::createFromAscii(data[i].absolute), + absolute->getUriReference()); + } + // For those test cases that conform to RFC 3986, check that the behavior matches + // rtl::Uri::convertRelToAbs: + if (data[i].processSpecialBaseSegments + && data[i].excessParentSegments == css::uri::RelativeUriExcessParentSegments_REMOVE) + { + try { + auto const absolute2 = rtl::Uri::convertRelToAbs( + OUString::createFromAscii(data[i].baseUriReference), + OUString::createFromAscii(data[i].uriReference)); + TEST_ASSERT_EQUAL( + "testMakeAbsolute", i, data[i].uriReference, true, data[i].absolute != nullptr); + TEST_ASSERT_EQUAL( + "testMakeAbsolute", i, data[i].uriReference, + OUString::createFromAscii(data[i].absolute), absolute2); + } catch (rtl::MalformedUriException &) { + TEST_ASSERT_EQUAL( + "testMakeAbsolute", i, data[i].uriReference, true, data[i].absolute == nullptr); + } + } + } +} + +void Test::testMakeRelative() { + struct Data { + char const * baseUriReference; + char const * uriReference; + bool preferAuthorityOverRelativePath; + bool preferAbsoluteOverRelativePath; + bool encodeRetainedSpecialSegments; + char const * relative; + char const * absolute; + }; + Data data[] = { + { "scheme1://a/b/c", "scheme2://a/b/c?q#s", true, true, false, + "scheme2://a/b/c?q#s", nullptr }, + { "scheme://a/b/c", "scheme:a/b/c?q#s", true, true, false, + "scheme:a/b/c?q#s", nullptr }, + { "scheme://a/b/c", "", true, true, false, "", "scheme://a/b/c" }, + { "scheme://a/b/c", "//d/e/f", true, true, false, "//d/e/f", + "scheme://d/e/f" }, + { "scheme://a/b/c", "./e?q#s", true, true, false, "./e?q#s", + "scheme://a/b/e?q#s" }, + { "scheme://a/b", "scheme://a?q", true, true, false, "/?q", + "scheme://a/?q" }, + { "scheme://a/b", "scheme://a?q", true, false, false, "/?q", + "scheme://a/?q" }, + { "scheme://a", "scheme://a?q", true, true, false, "?q", nullptr }, + { "scheme://a/", "scheme://a?q", true, true, false, "?q", + "scheme://a/?q" }, + { "scheme://a", "scheme://a/?q", true, true, false, "/?q", + nullptr }, + { "scheme://a/", "scheme://a/?q", true, true, false, "?q", + nullptr }, + { "scheme://a?q", "scheme://a?q", true, true, false, "", nullptr }, + { "scheme://a/?q", "scheme://a?q", true, true, false, "", + "scheme://a/?q" }, + { "scheme://a?q", "scheme://a/?q", true, true, false, "/?q", + nullptr }, + { "scheme://a/?q", "scheme://a/?q", true, true, false, "", nullptr }, + { "scheme://a/b/c/d", "scheme://a//", true, true, false, "//a//", nullptr }, + { "scheme://a/b/c/d", "scheme://a//", false, true, false, "../..//", + nullptr }, + { "scheme://a/b/c/d", "scheme://a//", true, false, false, "../..//", + nullptr }, + { "scheme://a/b/c/d", "scheme://a//", false, false, false, "../..//", + nullptr }, + { "scheme://a/b/c/d", "scheme://a/e", true, true, false, "/e", nullptr }, + { "scheme://a/b/c/d", "scheme://a/e", true, false, false, "../../e", + nullptr }, + { "scheme://a/b/c/d/e", "scheme://a/b/f", true, true, false, "../../f", + nullptr }, + { "scheme://a/b/c/d/e", "scheme://a/b", true, true, false, "/b", nullptr }, + { "scheme://a/b/c/d/e", "scheme://a/b", true, false, false, + "../../../b", nullptr }, + { "scheme://a/b/c/d/e", "scheme://a/b/", true, true, false, "../..", + nullptr }, + { "scheme://a/b/c/d/e", "scheme://a/b/c", true, true, false, "../../c", + nullptr }, + { "scheme://a/b/c/d/e", "scheme://a/b/c/", true, true, false, "..", nullptr }, + { "scheme://a/b/", "scheme://a/b/c/d", true, true, false, "c/d", nullptr }, + { "scheme://a/b/", "scheme://a/b/c/d/", true, true, false, "c/d/", nullptr }, + { "scheme://a/b/c", "scheme://a/b//", true, true, false, ".//", nullptr }, + { "scheme://a/b/c", "scheme://a/b//d", true, true, false, ".//d", nullptr }, + { "scheme://a/b/c", "scheme://a/b//d//", true, true, false, ".//d//", + nullptr }, + { "scheme://a/b/c", "scheme://a/b/d+:", true, true, false, "./d+:", nullptr }, + { "scheme://a/b/c", "scheme://a/b/+d:", true, true, false, "+d:", nullptr }, + { "scheme://a/b/c", "scheme://a/b/d#e:f", true, true, false, "d#e:f", + nullptr }, + { "scheme://a/b/c/", "scheme://a/b/../d/.e/.", true, true, false, + "../../d/.e/.", + "scheme://a/d/.e/" }, + { "scheme://a/b/c/", "scheme://a/b/../d/.e/.", true, true, true, + "../%2E%2E/d/.e/%2E", "scheme://a/b/%2E%2E/d/.e/%2E" }, + { "scheme://auth/a/b", "scheme://auth//c/d", true, true, false, + "//auth//c/d", nullptr }, + { "scheme://auth/a/b", "scheme://auth//c/d", false, true, false, + "..//c/d", nullptr }, + { "scheme://auth/a/b", "scheme://auth/c/d", true, true, false, "/c/d", + nullptr }, + { "scheme://auth/a/b", "scheme://auth/c/d", true, false, false, + "../c/d", nullptr }, + { "scheme:a/b/c", "scheme://d/e/f", true, true, false, "//d/e/f", nullptr }, + { "scheme:/a/b/c", "scheme://d/e/f", true, true, false, "//d/e/f", nullptr }, + { "scheme:a/b/c", "scheme:/d/e/f", true, true, false, "/d/e/f", nullptr }, + { "scheme:/a/b/c", "scheme:/d/e/f", true, true, false, "/d/e/f", nullptr }, + { "scheme:a/b/c", "scheme:d/e/f", true, true, false, "scheme:d/e/f", nullptr }, + { "scheme:/a/b/c", "scheme:d/e/f", true, true, false, "scheme:d/e/f", nullptr } }; + for (std::size_t i = 0; i < SAL_N_ELEMENTS(data); ++i) { + css::uno::Reference< css::uri::XUriReference > baseUriRef( + m_uriFactory->parse( + OUString::createFromAscii(data[i].baseUriReference))); + TEST_ASSERT_EQUAL("testMakeRelative", i, data[i].baseUriReference, true, baseUriRef.is()); + css::uno::Reference< css::uri::XUriReference > uriRef( + m_uriFactory->parse( + OUString::createFromAscii(data[i].uriReference))); + TEST_ASSERT_EQUAL("testMakeRelative", i, data[i].uriReference, true, uriRef.is()); + css::uno::Reference< css::uri::XUriReference > relative( + m_uriFactory->makeRelative( + baseUriRef, uriRef, data[i].preferAuthorityOverRelativePath, + data[i].preferAbsoluteOverRelativePath, + data[i].encodeRetainedSpecialSegments)); + TEST_ASSERT_EQUAL( + "testMakeRelative", i, data[i].uriReference, + data[i].relative != nullptr, relative.is()); + if (relative.is()) { + TEST_ASSERT_EQUAL( + "testMakeRelative", i, data[i].uriReference, + OUString::createFromAscii(data[i].relative), + relative->getUriReference()); + css::uno::Reference< css::uri::XUriReference > absolute( + m_uriFactory->makeAbsolute( + baseUriRef, relative, true, + css::uri::RelativeUriExcessParentSegments_ERROR)); + TEST_ASSERT_EQUAL("testMakeRelative", i, data[i].uriReference, true, absolute.is()); + TEST_ASSERT_EQUAL( + "testMakeRelative", i, data[i].uriReference, + OUString::createFromAscii( + data[i].absolute == nullptr + ? data[i].uriReference : data[i].absolute), + absolute->getUriReference()); + } + } +} + +void Test::testVndSunStarExpand() { + struct Data { + char const * uriReference; + char const * expanded; + }; + Data data[] = { + { "vnd.sun.star.expand:", "" }, // liberally accepted + { "vnd.sun.star.expand:/", "/" }, // liberally accepted + { "vnd.sun.star.expand:%80", nullptr }, + { "vnd.sun.star.expand:%5C$%5C%24%5C%5C", "$$\\" } }; + css::uno::Reference< css::util::XMacroExpander > expander( + m_context->getValueByName( + "/singletons/com.sun.star.util.theMacroExpander"), + css::uno::UNO_QUERY_THROW); + for (std::size_t i = 0; i < SAL_N_ELEMENTS(data); ++i) { + css::uno::Reference< css::uri::XUriReference > uriRef( + m_uriFactory->parse( + OUString::createFromAscii(data[i].uriReference))); + TEST_ASSERT_EQUAL( + "testVndSunStarExpand", i, data[i].uriReference, + data[i].expanded != nullptr, uriRef.is()); + if (uriRef.is()) { + css::uno::Reference< css::uri::XVndSunStarExpandUrlReference > + expandUrl(uriRef, css::uno::UNO_QUERY_THROW); + TEST_ASSERT_EQUAL( + "testVndSunStarExpand", i, data[i].uriReference, + OUString::createFromAscii(data[i].expanded), + expandUrl->expand(expander)); + } + } +} + +void Test::testVndSunStarScript() { + struct Parameter { + char const * key; + char const * value; + }; + std::size_t const parameterCount = 3; + struct Data { + char const * uriReference; + char const * name; + const bool normalized; + Parameter parameters[parameterCount]; + }; + Data data[] = { + { "vnd.sun.star.script:", nullptr, false, {} }, + { "vnd.sun.star.script:/", nullptr, false, {} }, + { "vnd.sun.star.script:/abc/def?ghi=jkl&mno=pqr", nullptr, false, {} }, + { "vnd.sun.star.script:abc%3fdef/ghi", "abc?def/ghi", false, {} }, + { "vnd.sun.star.script:name?a", nullptr, false, {} }, + { "vnd.sun.star.script:name?a=", "name", true, { { "a", "" }, { "A", nullptr } } }, + { "vnd.sun.star.script:name?a=&", nullptr, true, {} }, + { "vnd.sun.star.script:name?key1=&%26=%3D&key1=hello", "name", true, + { { "key1", "" }, { "key2", nullptr }, { "&", "=" } } } }; + for (std::size_t i = 0; i < SAL_N_ELEMENTS(data); ++i) { + css::uno::Reference< css::uri::XUriReference > uriRef( + m_uriFactory->parse( + OUString::createFromAscii(data[i].uriReference))); + TEST_ASSERT_EQUAL( + "testVndSunStarScript", i, data[i].uriReference, data[i].name != nullptr, + uriRef.is()); + if (uriRef.is()) { + css::uno::Reference< css::uri::XVndSunStarScriptUrlReference > + scriptUrl(uriRef, css::uno::UNO_QUERY_THROW); + TEST_ASSERT_EQUAL( + "testVndSunStarScript", i, data[i].uriReference, + OUString::createFromAscii(data[i].uriReference), + scriptUrl->getUriReference()); + TEST_ASSERT_EQUAL( + "testVndSunStarScript", i, data[i].uriReference, + OUString::createFromAscii(data[i].name), + scriptUrl->getName()); + OUString originalReference(uriRef->getUriReference()); + for (std::size_t j = 0; j < parameterCount; ++j) { + if (data[i].parameters[j].key != nullptr) { + TEST_ASSERT_EQUAL( + "testVndSunStarScript", + static_cast< double >(i) + + static_cast< double >(j) / 10.0, + data[i].uriReference, + data[i].parameters[j].value != nullptr, + bool( + scriptUrl->hasParameter( + OUString::createFromAscii( + data[i].parameters[j].key)))); + TEST_ASSERT_EQUAL( + "testVndSunStarScript", + static_cast< double >(i) + + static_cast< double >(j) / 10.0, + data[i].uriReference, + OUString::createFromAscii( + data[i].parameters[j].value), + scriptUrl->getParameter( + OUString::createFromAscii( + data[i].parameters[j].key))); + + // setting the parameter to its original value should not change + // the overall uri reference (provided it was normalized before) + if ( data[i].normalized ) { + if ( scriptUrl->hasParameter(OUString::createFromAscii( + data[i].parameters[j].key)) ) { + scriptUrl->setParameter( + OUString::createFromAscii( + data[i].parameters[j].key), + scriptUrl->getParameter( + OUString::createFromAscii( + data[i].parameters[j].key))); + TEST_ASSERT_EQUAL( + "testVndSunStarScript", + static_cast< double >(i) + + static_cast< double >(j) / 10.0, + OUString("setParameter"), + originalReference, + uriRef->getUriReference()); + } + } + } + } + if ( data[i].normalized ) { + scriptUrl->setName(scriptUrl->getName()); + TEST_ASSERT_EQUAL( + "testVndSunStarScript", + i, + OUString("setName"), + originalReference, + uriRef->getUriReference()); + } + } + } + + css::uno::Reference< css::uri::XUriReference > uriRef( + m_uriFactory->parse( + "vnd.sun.star.script:Hello?location=Library.Module"), + css::uno::UNO_SET_THROW); + css::uno::Reference< css::uri::XVndSunStarScriptUrlReference > + scriptUrl(uriRef, css::uno::UNO_QUERY_THROW); + + scriptUrl->setParameter( + "location", + "foo"); + TEST_ASSERT_EQUAL( + "testVndSunStarScript", sal_Int32(10), sal_Int32(1), + OUString("vnd.sun.star.script:Hello?location=foo"), + uriRef->getUriReference()); + + scriptUrl->setParameter( + "language", + "StarBasic"); + TEST_ASSERT_EQUAL( + "testVndSunStarScript", sal_Int32(10), sal_Int32(2), + OUString("vnd.sun.star.script:Hello?location=foo&language=StarBasic"), + uriRef->getUriReference()); + + + bool caughtExpected = false; + try { + scriptUrl->setName(OUString()); + } + catch( const css::lang::IllegalArgumentException& ) { + caughtExpected = true; + } + TEST_ASSERT_EQUAL( + "testVndSunStarScript", + OUString("illegal arguments"), + OUString("name"), + true, + caughtExpected); + + caughtExpected = false; + try { + scriptUrl->setParameter( + OUString(), + "non-empty"); + } + catch( const css::lang::IllegalArgumentException& ) { + caughtExpected = true; + } + TEST_ASSERT_EQUAL( + "testVndSunStarScript", + OUString("illegal arguments"), + OUString("parameter"), + true, + caughtExpected); +} + +void Test::testTranslator() { + struct Data { + char const * externalUriReference; + char const * internalUriReference; + bool toInternal; + }; + Data data[] = { + { "", "", true }, + { "#fragment", "#fragment", true }, + { "segment/segment?query#fragment", "segment/segment?query#fragment", + true }, + { "/segment/segment?query#fragment", "/segment/segment?query#fragment", + true }, + { "//authority/segment?query#fragment", + "//authority/segment?query#fragment", true }, + { "foo:bar#fragment", "foo:bar#fragment", true }, + { "file:///abc/def", "file:///abc/def", true }, + { "file:///abc/%FEef", "file:///abc/%feef", false }, + { "file:///abc/%80%80ef", "file:///abc/%80%80ef", false }, + { "file:///abc/%ED%A0%80%ED%B0%80ef", + "file:///abc/%ED%A0%80%ED%B0%80ef", false }, + { "file:///abc/%25.ef", "file:///abc/%.ef", false }, + { "file:///abc/%25ef", "file:///abc/%25ef", true } }; + css::uno::Reference< css::uri::XExternalUriReferenceTranslator > + translator(css::uri::ExternalUriReferenceTranslator::create(m_context)); + for (std::size_t i = 0; i < SAL_N_ELEMENTS(data); ++i) { + if (data[i].toInternal) { + TEST_ASSERT_EQUAL( + "testTranslator, translateToInternal", i, + data[i].externalUriReference, + OUString::createFromAscii(data[i].internalUriReference), + translator->translateToInternal( + OUString::createFromAscii( + data[i].externalUriReference))); + } + TEST_ASSERT_EQUAL( + "testTranslator, translateToExternal", i, + data[i].internalUriReference, + OUString::createFromAscii(data[i].externalUriReference), + translator->translateToExternal( + OUString::createFromAscii(data[i].internalUriReference))); + } +} + +void Test::testPkgUrlFactory() { + struct Data { + char const * authority; + char const * result; + }; + Data data[] = { + { "a/b/c", nullptr }, + { "file:///#foo", nullptr }, + { "file:///a%25b%2fc/d~e&f@g?h", + "vnd.sun.star.pkg://file:%2F%2F%2Fa%2525b%252fc%2Fd~e&f@g%3Fh" } }; + css::uno::Reference< css::uri::XVndSunStarPkgUrlReferenceFactory > factory( + css::uri::VndSunStarPkgUrlReferenceFactory::create(m_context)); + for (std::size_t i = 0; i < SAL_N_ELEMENTS(data); ++i) { + css::uno::Reference< css::uri::XUriReference > url( + factory->createVndSunStarPkgUrlReference( + m_uriFactory->parse( + OUString::createFromAscii(data[i].authority)))); + TEST_ASSERT_EQUAL( + "testVndSunStarPkgFactory", i, data[i].authority, + data[i].result != nullptr, url.is()); + if (data[i].result != nullptr) { + TEST_ASSERT_EQUAL( + "testVndSunStarPkgFactory", i, data[i].authority, + OUString::createFromAscii(data[i].result), + url->getUriReference()); + } + } +} + +CPPUNIT_TEST_SUITE_REGISTRATION(Test); + +} + +CPPUNIT_PLUGIN_IMPLEMENT(); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |