diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
commit | ed5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch) | |
tree | 7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /sax/test | |
parent | Initial commit. (diff) | |
download | libreoffice-upstream/4%7.4.7.tar.xz libreoffice-upstream/4%7.4.7.zip |
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sax/test')
-rw-r--r-- | sax/test/makefile.mk | 58 | ||||
-rw-r--r-- | sax/test/sax/exports.dxp | 2 | ||||
-rw-r--r-- | sax/test/sax/factory.hxx | 80 | ||||
-rw-r--r-- | sax/test/sax/makefile.mk | 52 | ||||
-rw-r--r-- | sax/test/sax/testsax.cxx | 795 | ||||
-rw-r--r-- | sax/test/sax/testwriter.cxx | 662 | ||||
-rw-r--r-- | sax/test/saxdemo.cxx | 626 | ||||
-rw-r--r-- | sax/test/testcomponent.cxx | 223 |
8 files changed, 2498 insertions, 0 deletions
diff --git a/sax/test/makefile.mk b/sax/test/makefile.mk new file mode 100644 index 000000000..e2ae1546c --- /dev/null +++ b/sax/test/makefile.mk @@ -0,0 +1,58 @@ +# +# 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=extensions +TARGET=workben +LIBTARGET=NO + +TARGETTYPE=CUI +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +# --- Files -------------------------------------------------------- + +.IF "$(BUILD_TYPE)" == "$(BUILD_TYPE:s/DESKTOP//)" + +ALL: +# nothing + +.ENDIF + +# +# std testcomponent +# +APP1TARGET = testcomponent +APP2TARGET = saxdemo + +APP1OBJS = $(OBJ)$/testcomponent.obj +APP1STDLIBS = $(SALLIB) \ + $(CPPULIB)\ + $(CPPUHELPERLIB) + +APP2OBJS = $(OBJ)$/saxdemo.obj +APP2STDLIBS = $(SALLIB) \ + $(CPPULIB) \ + $(CPPUHELPERLIB) + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/sax/test/sax/exports.dxp b/sax/test/sax/exports.dxp new file mode 100644 index 000000000..86214860d --- /dev/null +++ b/sax/test/sax/exports.dxp @@ -0,0 +1,2 @@ +component_getFactory +component_writeInfo diff --git a/sax/test/sax/factory.hxx b/sax/test/sax/factory.hxx new file mode 100644 index 000000000..688691c9c --- /dev/null +++ b/sax/test/sax/factory.hxx @@ -0,0 +1,80 @@ +/* -*- 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 . + */ + +#ifndef INCLUDED_SAX_TEST_SAX_FACTORY_HXX +#define INCLUDED_SAX_TEST_SAX_FACTORY_HXX + +#include <rtl/strbuf.hxx> + +namespace sax_test { +Reference< XInterface > SAL_CALL OSaxWriterTest_CreateInstance( + const Reference< XMultiServiceFactory > & rSMgr ) throw ( Exception ); +OUString OSaxWriterTest_getServiceName( ) throw(); +OUString OSaxWriterTest_getImplementationName( ) throw(); +Sequence<OUString> OSaxWriterTest_getSupportedServiceNames( ) throw(); +} +#define BUILD_ERROR(expr, Message)\ + {\ + m_seqErrors.realloc( m_seqErrors.getLength() + 1 ); \ + m_seqExceptions.realloc( m_seqExceptions.getLength() + 1 ); \ + OStringBuffer str(128); \ + str.append( __FILE__ );\ + str.append( " " ); \ + str.append( "(" ); \ + str.append( OString::valueOf( (sal_Int32)__LINE__) );\ + str.append(")\n" );\ + str.append( "[ " ); \ + str.append( #expr ); \ + str.append( " ] : " ); \ + str.append( Message ); \ + m_seqErrors.getArray()[ m_seqErrors.getLength()-1] =\ + OStringToOUString( str.makeStringAndClear() , RTL_TEXTENCODING_ASCII_US ); \ + }\ + ((void)0) + + +#define WARNING_ASSERT(expr, Message) \ + if( ! (expr) ) { \ + m_seqWarnings.realloc( m_seqErrors.getLength() +1 ); \ + OStringBuffer str(128);\ + str.append( __FILE__);\ + str.append( " "); \ + str.append( "(" ); \ + str.append(OString::valueOf( (sal_Int32)__LINE__)) ;\ + str.append( ")\n");\ + str.append( "[ " ); \ + str.append( #expr ); \ + str.append( " ] : ") ; \ + str.append( Message); \ + m_seqWarnings.getArray()[ m_seqWarnings.getLength()-1] =\ + OStringToOUString( str.makeStringAndClear() , RTL_TEXTENCODING_ASCII_US ); \ + return; \ + }\ + ((void)0) + +#define ERROR_ASSERT(expr, Message) \ + if( ! (expr) ) { \ + BUILD_ERROR(expr, Message );\ + return; \ + }\ + ((void)0) + +#endif // INCLUDED_SAX_TEST_SAX_FACTORY_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sax/test/sax/makefile.mk b/sax/test/sax/makefile.mk new file mode 100644 index 000000000..9aa5864ca --- /dev/null +++ b/sax/test/sax/makefile.mk @@ -0,0 +1,52 @@ +# +# 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=extensions +TARGET=testsax +USE_DEFFILE=TRUE +ENABLE_EXCEPTIONS=TRUE +# --- Settings ----------------------------------------------------- +.INCLUDE : settings.mk + +# --- Files -------------------------------------------------------- + + +SLOFILES = $(SLO)$/testsax.obj \ + $(SLO)$/testwriter.obj + +SHL1TARGET= $(TARGET) +SHL1IMPLIB= i$(TARGET) + +SHL1STDLIBS= \ + $(SALLIB) \ + $(CPPULIB) \ + $(CPPUHELPERLIB) + + +SHL1LIBS= $(SLB)$/$(TARGET).lib +SHL1DEPN= makefile.mk $(SHL1LIBS) +SHL1DEF= $(MISC)$/$(SHL1TARGET).def + +DEF1NAME= $(SHL1TARGET) +DEF1EXPORTFILE= exports.dxp + + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/sax/test/sax/testsax.cxx b/sax/test/sax/testsax.cxx new file mode 100644 index 000000000..882a7a96d --- /dev/null +++ b/sax/test/sax/testsax.cxx @@ -0,0 +1,795 @@ +/* -*- 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 <string.h> + +#include <osl/time.h> +#include <osl/diagnose.h> + +#include <com/sun/star/test/XSimpleTest.hpp> +#include <com/sun/star/io/XOutputStream.hpp> +#include <com/sun/star/xml/sax/SAXParseException.hpp> +#include <com/sun/star/xml/sax/XParser.hpp> +#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp> + +#include <cppuhelper/factory.hxx> +#include <cppuhelper/implbase.hxx> + +using namespace ::cppu; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::test; +using namespace ::com::sun::star::registry; +using namespace ::com::sun::star::io; +using namespace ::com::sun::star::xml::sax; + +// test scenarios + +namespace sax_test { + +class OSaxParserTest : public WeakImplHelper< XSimpleTest > +{ +public: + explicit OSaxParserTest( const Reference < XMultiServiceFactory > & rFactory ) : m_rFactory( rFactory ) + { + } + + virtual void SAL_CALL testInvariant( + const OUString& TestName, + const Reference < XInterface >& TestObject) + throw ( IllegalArgumentException, RuntimeException); + + virtual sal_Int32 SAL_CALL test( + const OUString& TestName, + const Reference < XInterface >& TestObject, + sal_Int32 hTestHandle) + throw ( IllegalArgumentException,RuntimeException); + + virtual sal_Bool SAL_CALL testPassed() throw (RuntimeException); + virtual Sequence< OUString > SAL_CALL getErrors() throw (RuntimeException); + virtual Sequence< Any > SAL_CALL getErrorExceptions() throw (RuntimeException); + virtual Sequence< OUString > SAL_CALL getWarnings() throw (RuntimeException); + +private: + void testSimple( const Reference < XParser > &r ); + void testNamespaces( const Reference < XParser > &r ); + void testFile( const Reference < XParser > &r ); + void testEncoding( const Reference < XParser > &rParser ); + void testPerformance( const Reference < XParser > &rParser ); + + Sequence<Any> m_seqExceptions; + Sequence<OUString> m_seqErrors; + Sequence<OUString> m_seqWarnings; + Reference < XMultiServiceFactory > m_rFactory; +}; + +/// @note for external binding +Reference < XInterface > SAL_CALL OSaxParserTest_CreateInstance( const Reference < XMultiServiceFactory > & rSMgr ) throw(Exception) +{ + OSaxParserTest *p = new OSaxParserTest( rSMgr ); + return Reference < XInterface > ( (static_cast< OWeakObject * >(p)) ); +} + +OUString OSaxParserTest_getServiceName( ) throw () +{ + return OUString( "test.com.sun.star.xml.sax.Parser" ); +} + +OUString OSaxParserTest_getImplementationName( ) throw () +{ + return OUString( "test.extensions.xml.sax.Parser"); +} + +Sequence<OUString> OSaxParserTest_getSupportedServiceNames( ) throw () +{ + Sequence<OUString> aRet { OSaxParserTest_getImplementationName() }; + return aRet; +} + +void OSaxParserTest::testInvariant( + const OUString& TestName, + const Reference < XInterface >& TestObject ) + throw ( IllegalArgumentException, RuntimeException) +{ + if( OUString( "com.sun.star.xml.sax.Parser") == TestName ) { + Reference < XParser > parser( TestObject , UNO_QUERY ); + + ERROR_ASSERT( parser.is() , "XDataInputStream cannot be queried" ); + } +} + +sal_Int32 OSaxParserTest::test( + const OUString& TestName, + const Reference < XInterface >& TestObject, + sal_Int32 hTestHandle) + throw ( IllegalArgumentException, RuntimeException) +{ + if( OUString( "com.sun.star.xml.sax.Parser") == TestName ) { + try + { + if( 0 == hTestHandle ) { + testInvariant( TestName , TestObject ); + } + else { + Reference < XParser > parser( TestObject , UNO_QUERY ); + + if( 1 == hTestHandle ) { + testSimple( parser ); + } + else if( 2 == hTestHandle ) { + testNamespaces( parser ); + } + else if( 3 == hTestHandle ) { + testEncoding( parser ); + } + else if( 4 == hTestHandle ) { + testFile( parser ); + } + else if( 5 == hTestHandle ) { + testPerformance( parser ); + } + } + } + catch( Exception & e ) + { + OString o = OUStringToOString( e.Message , RTL_TEXTENCODING_ASCII_US); + BUILD_ERROR( 0 , o.getStr() ); + } + catch( ... ) + { + BUILD_ERROR( 0 , "unknown exception (Exception is not base class)" ); + } + + hTestHandle ++; + + if( hTestHandle >= 6) { + // all tests finished. + hTestHandle = -1; + } + } + else { + BUILD_ERROR( 0 , "service not supported by test." ); + } + return hTestHandle; +} + +sal_Bool OSaxParserTest::testPassed() throw (RuntimeException) +{ + return m_seqErrors.getLength() == 0; +} + +Sequence< OUString > OSaxParserTest::getErrors() throw (RuntimeException) +{ + return m_seqErrors; +} + +Sequence< Any > OSaxParserTest::getErrorExceptions() throw (RuntimeException) +{ + return m_seqExceptions; +} + +Sequence< OUString > OSaxParserTest::getWarnings() throw (RuntimeException) +{ + return m_seqWarnings; +} + +Reference < XInputStream > createStreamFromSequence( + const Sequence<sal_Int8> seqBytes , + const Reference < XMultiServiceFactory > &xSMgr ) +{ + Reference < XInterface > xOutStreamService = + xSMgr->createInstance("com.sun.star.io.Pipe"); + OSL_ASSERT( xOutStreamService.is() ); + Reference< XOutputStream > rOutStream( xOutStreamService , UNO_QUERY ); + OSL_ASSERT( rOutStream.is() ); + + Reference< XInputStream > rInStream( xOutStreamService , UNO_QUERY ); + OSL_ASSERT( rInStream.is() ); + + rOutStream->writeBytes( seqBytes ); + rOutStream->flush(); + rOutStream->closeOutput(); + + return rInStream; +} + +Reference< XInputStream > createStreamFromFile( + const char *pcFile , + const Reference < XMultiServiceFactory > &xSMgr ) +{ + FILE *f = fopen( pcFile , "rb" ); + Reference< XInputStream > r; + + if( f ) { + fseek( f , 0 , SEEK_END ); + int nLength = ftell( f ); + fseek( f , 0 , SEEK_SET ); + + Sequence<sal_Int8> seqIn(nLength); + fread( seqIn.getArray() , nLength , 1 , f ); + + r = createStreamFromSequence( seqIn , xSMgr ); + fclose( f ); + } + return r; +} + +class TestDocumentHandler : + public WeakImplHelper< XExtendedDocumentHandler , XEntityResolver , XErrorHandler > +{ +public: + TestDocumentHandler( const Reference < XMultiServiceFactory > &r , sal_Bool bPrint ) + : m_bPrint(bPrint), m_xSMgr(r) + { + } + + // Error handler + virtual void SAL_CALL error(const Any& aSAXParseException) throw (SAXException, RuntimeException) + { + printf( "Error !\n" ); + throw SAXException( + OUString( "error from error handler") , + Reference < XInterface >() , + aSAXParseException ); + } + virtual void SAL_CALL fatalError(const Any& aSAXParseException) throw (SAXException, RuntimeException) + { + printf( "Fatal Error !\n" ); + } + virtual void SAL_CALL warning(const Any& aSAXParseException) throw (SAXException, RuntimeException) + { + printf( "Warning !\n" ); + } + + // ExtendedDocumentHandler + virtual void SAL_CALL startDocument() throw (SAXException, RuntimeException) + { + m_iLevel = 0; + m_iElementCount = 0; + m_iAttributeCount = 0; + m_iWhitespaceCount =0; + m_iCharCount=0; + if( m_bPrint ) { + printf( "document started\n" ); + } + } + virtual void SAL_CALL endDocument() throw (SAXException, RuntimeException) + { + if( m_bPrint ) { + printf( "document finished\n" ); + printf( "(ElementCount %d),(AttributeCount %d),(WhitespaceCount %d),(CharCount %d)\n", + m_iElementCount, m_iAttributeCount, m_iWhitespaceCount , m_iCharCount ); + } + } + virtual void SAL_CALL startElement(const OUString& aName, + const Reference< XAttributeList > & xAttribs) + throw (SAXException,RuntimeException) + { + if( m_rLocator.is() ) { + if( m_bPrint ) + { + OString o = OUStringToOString( m_rLocator->getSystemId() , RTL_TEXTENCODING_UTF8 ); + printf( "%s(%d):" , o.getStr() , m_rLocator->getLineNumber() ); + } + } + if( m_bPrint ) { + int i; + for( i = 0; i < m_iLevel ; i ++ ) { + printf( " " ); + } + OString o = OUStringToOString(aName , RTL_TEXTENCODING_UTF8 ); + printf( "<%s> " , aName.getStr() ); + + for( i = 0 ; i < xAttribs->getLength() ; i ++ ) + { + OString o1 = OUStringToOString(xAttribs->getNameByIndex( i ), RTL_TEXTENCODING_UTF8 ); + OString o2 = OUStringToOString(xAttribs->getTypeByIndex( i ), RTL_TEXTENCODING_UTF8 ); + OString o3 = OUStringToOString(xAttribs->getValueByIndex( i ) , RTL_TEXTENCODING_UTF8 ); + printf( "(%s,%s,'%s')" , o1.getStr(), o2.getStr(), o3.getStr() ); + } + printf( "\n" ); + } + m_iLevel ++; + m_iElementCount ++; + m_iAttributeCount += xAttribs->getLength(); + } + + virtual void SAL_CALL endElement(const OUString& aName) throw (SAXException,RuntimeException) + { + OSL_ASSERT( m_iLevel ); + m_iLevel --; + if( m_bPrint ) { + int i; + for( i = 0; i < m_iLevel ; i ++ ) { + printf( " " ); + } + OString o = OUStringToOString(aName , RTL_TEXTENCODING_UTF8 ); + printf( "</%s>\n" , o.getStr() ); + } + } + + virtual void SAL_CALL characters(const OUString& aChars) throw (SAXException,RuntimeException) + { + if( m_bPrint ) { + int i; + for( i = 0; i < m_iLevel ; i ++ ) { + printf( " " ); + } + OString o = OUStringToOString(aChars , RTL_TEXTENCODING_UTF8 ); + printf( "%s\n" , o.getStr() ); + } + m_iCharCount += aChars.getLength(); + } + + virtual void SAL_CALL ignorableWhitespace(const OUString& aWhitespaces) throw (SAXException,RuntimeException) + { + m_iWhitespaceCount += aWhitespaces.getLength(); + } + + virtual void SAL_CALL processingInstruction(const OUString& aTarget, const OUString& aData) throw (SAXException,RuntimeException) + { + if( m_bPrint ) + { + OString o1 = OUStringToOString(aTarget, RTL_TEXTENCODING_UTF8 ); + OString o2 = OUStringToOString(aData, RTL_TEXTENCODING_UTF8 ); + printf( "PI : %s,%s\n" , o1.getStr() , o2.getStr() ); + } + } + + virtual void SAL_CALL setDocumentLocator(const Reference< XLocator> & xLocator) + throw (SAXException,RuntimeException) + { + m_rLocator = xLocator; + } + + virtual InputSource SAL_CALL resolveEntity( + const OUString& sPublicId, + const OUString& sSystemId) + throw (SAXException,RuntimeException) + { + InputSource source; + source.sSystemId = sSystemId; + source.sPublicId = sPublicId; + + source.aInputStream = createStreamFromFile( + OUStringToOString( sSystemId , RTL_TEXTENCODING_ASCII_US) , m_xSMgr ); + + return source; + } + + virtual void SAL_CALL startCDATA() throw (SAXException,RuntimeException) + { + if( m_bPrint ) { + printf( "CDataStart :\n" ); + } + } + virtual void SAL_CALL endCDATA() throw (SAXException,RuntimeException) + { + if( m_bPrint ) { + printf( "CEndStart :\n" ); + } + } + virtual void SAL_CALL comment(const OUString& sComment) throw (SAXException,RuntimeException) + { + if( m_bPrint ) { + OString o1 = OUStringToOString(sComment, RTL_TEXTENCODING_UTF8 ); + printf( "<!--%s-->\n" , o1.getStr() ); + } + } + virtual void SAL_CALL unknown(const OUString& sString) throw (SAXException,RuntimeException) + { + if( m_bPrint ) + { + OString o1 = OUStringToOString(sString, RTL_TEXTENCODING_UTF8 ); + printf( "UNKNOWN : {%s}\n" , o1.getStr() ); + } + } + + virtual void SAL_CALL allowLineBreak() throw (SAXException, RuntimeException ) + { + + } + + int m_iLevel; + int m_iElementCount; + int m_iAttributeCount; + int m_iWhitespaceCount; + int m_iCharCount; + sal_Bool m_bPrint; + + Reference < XMultiServiceFactory > m_xSMgr; + Reference < XLocator > m_rLocator; +}; + +void OSaxParserTest::testSimple( const Reference < XParser > &rParser ) +{ + char TestString[] = "<!DOCTYPE personnel [\n" + "<!ENTITY testInternal \"internal Test!\">\n" + "<!ENTITY test SYSTEM \"external_entity.xml\">\n" + "]>\n" + "<personnel>\n" + "<person> fjklsfdklsdfkl\n" + "fjklsfdklsdfkl\n" + "<?testpi pidata?>\n" + "&testInternal;\n" + "<HUHU x='5' y='kjfd'> blahuhu\n" + "<HI> blahi\n" + " <![CDATA[<greeting>Hello, '+1+12world!</greeting>]]>\n" + " <!-- huhu <jdk> -->\n" + "<?testpi pidata?>\n" + "</HI>\n" + "aus XMLTest\n" + "</HUHU>\n" + "</person>\n" + "</personnel>\n\n\n"; + + Sequence< sal_Int8> seqBytes( strlen( TestString ) ); + memcpy( seqBytes.getArray() , TestString , strlen( TestString ) ); + + Reference< XInputStream > rInStream; + OUString sInput; + rInStream = createStreamFromSequence( seqBytes , m_rFactory ); + sInput = "internal"; + + if( rParser.is() ) { + InputSource source; + + source.aInputStream = rInStream; + source.sSystemId = sInput; + + TestDocumentHandler *pDocHandler = new TestDocumentHandler( m_rFactory , sal_False ); + Reference < XDocumentHandler > rDocHandler( (XDocumentHandler *) pDocHandler , UNO_QUERY ); + Reference< XEntityResolver > + rEntityResolver( (XEntityResolver *) pDocHandler , UNO_QUERY ); + + rParser->setDocumentHandler( rDocHandler ); + rParser->setEntityResolver( rEntityResolver ); + + try + { + rParser->parseStream( source ); + ERROR_ASSERT( pDocHandler->m_iElementCount == 4 , "wrong element count" ); + ERROR_ASSERT( pDocHandler->m_iAttributeCount == 2 , "wrong attribute count" ); + ERROR_ASSERT( pDocHandler->m_iCharCount == 130 , "wrong char count" ); + ERROR_ASSERT( pDocHandler->m_iWhitespaceCount == 0, "wrong whitespace count" ); + } + catch( SAXParseException & e ) + { + OString o1 = OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8 ); + BUILD_ERROR( 1 , o1.getStr() ); + } + catch( SAXException & e ) + { + OString o1 = OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8 ); + BUILD_ERROR( 1 , o1.getStr() ); + } + catch( Exception & e ) + { + OString o1 = OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8 ); + BUILD_ERROR( 1 , o1.getStr() ); + } + catch( ... ) + { + BUILD_ERROR( 1 , "unknown exception" ); + } + } +} + +void OSaxParserTest::testNamespaces( const Reference < XParser > &rParser ) +{ + + char TestString[] = + "<?xml version='1.0'?>\n" + "<!-- all elements here are explicitly in the HTML namespace -->\n" + "<html:html xmlns:html='http://www.w3.org/TR/REC-html40'>\n" + "<html:head><html:title>Frobnostication</html:title></html:head>\n" + "<html:body><html:p>Moved to \n" + "<html:a href='http://frob.com'>here.</html:a></html:p></html:body>\n" + "</html:html>\n"; + + Sequence<sal_Int8> seqBytes( strlen( TestString ) ); + memcpy( seqBytes.getArray() , TestString , strlen( TestString ) ); + + Reference< XInputStream > rInStream; + OUString sInput; + + rInStream = createStreamFromSequence( seqBytes , m_rFactory ); + sInput = "internal"; + + if( rParser.is() ) { + InputSource source; + + source.aInputStream = rInStream; + source.sSystemId = sInput; + + TestDocumentHandler *pDocHandler = new TestDocumentHandler( m_rFactory , sal_False ); + Reference < XDocumentHandler > rDocHandler( (XDocumentHandler *) pDocHandler , UNO_QUERY ); + Reference< XEntityResolver > rEntityResolver( + (XEntityResolver *) pDocHandler , UNO_QUERY ); + + rParser->setDocumentHandler( rDocHandler ); + rParser->setEntityResolver( rEntityResolver ); + + try + { + rParser->parseStream( source ); + ERROR_ASSERT( pDocHandler->m_iElementCount == 6 , "wrong element count" ); + ERROR_ASSERT( pDocHandler->m_iAttributeCount == 2 , "wrong attribute count" ); + ERROR_ASSERT( pDocHandler->m_iCharCount == 33, "wrong char count" ); + ERROR_ASSERT( pDocHandler->m_iWhitespaceCount == 0 , "wrong whitespace count" ); + } + catch( Exception & e ) { + OString o1 = OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8 ); + BUILD_ERROR( 1 , o1.getStr() ); + } + catch( ... ) + { + BUILD_ERROR( 1 , "unknown exception" ); + } + } +} + +void OSaxParserTest::testEncoding( const Reference < XParser > &rParser ) +{ + char TestString[] = + "<?xml version='1.0' encoding=\"iso-8859-1\"?>\n" + "<!-- all elements here are explicitly in the HTML namespace -->\n" + "<html:html xmlns:html='http://www.w3.org/TR/REC-html40'>\n" + "<html:head><html:title>Frobnostication</html:title></html:head>\n" + "<html:body><html:p>Moved to \337\n" + "<html:a href='http://frob.com'>here.</html:a></html:p></html:body>\n" + "</html:html>\n"; + + Sequence<sal_Int8> seqBytes( strlen( TestString ) ); + memcpy( seqBytes.getArray() , TestString , strlen( TestString ) ); + + Reference< XInputStream > rInStream; + OUString sInput; + + rInStream = createStreamFromSequence( seqBytes , m_rFactory ); + sInput = "internal"; + + if( rParser.is() ) { + InputSource source; + + source.aInputStream = rInStream; + source.sSystemId = sInput; + + TestDocumentHandler *pDocHandler = new TestDocumentHandler( m_rFactory , sal_False ); + Reference < XDocumentHandler > rDocHandler( (XDocumentHandler *) pDocHandler , UNO_QUERY ); + Reference< XEntityResolver > rEntityResolver( (XEntityResolver *) pDocHandler , UNO_QUERY ); + + rParser->setDocumentHandler( rDocHandler ); + rParser->setEntityResolver( rEntityResolver ); + try + { + rParser->parseStream( source ); + } + catch( Exception & e ) + { + OString o1 = OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8 ); + BUILD_ERROR( 1 , o1.getStr() ); + } + catch ( ... ) + { + BUILD_ERROR( 1 , "unknown exception" ); + } + } +} + +void OSaxParserTest::testFile( const Reference < XParser > & rParser ) +{ + + Reference< XInputStream > rInStream = createStreamFromFile( "testsax.xml" , m_rFactory ); + OUString sInput = "testsax.xml"; + + if( rParser.is() && rInStream.is() ) { + InputSource source; + + source.aInputStream = rInStream; + source.sSystemId = sInput; + + TestDocumentHandler *pDocHandler = new TestDocumentHandler( m_rFactory , sal_True ); + Reference < XDocumentHandler > rDocHandler( (XDocumentHandler *) pDocHandler , UNO_QUERY ); + Reference < XEntityResolver > rEntityResolver( (XEntityResolver *) pDocHandler , UNO_QUERY ); + Reference < XErrorHandler > rErrorHandler( ( XErrorHandler * )pDocHandler , UNO_QUERY ); + + rParser->setDocumentHandler( rDocHandler ); + rParser->setEntityResolver( rEntityResolver ); + rParser->setErrorHandler( rErrorHandler ); + + try + { + rParser->parseStream( source ); + } + catch( SAXParseException & e ) { + Any any; + any <<= e; + + while(true) { + SAXParseException *pEx; + if( any.getValueType() == cppu::UnoType<decltype(e)>::get() ) { + pEx = ( SAXParseException * ) any.getValue(); + OString o1 = OUStringToOString(pEx->Message, RTL_TEXTENCODING_UTF8 ); + printf( "%s\n" , o1.getStr() ); + any = pEx->WrappedException; + } + else { + break; + } + } + } + catch( SAXException & e ) + { + OString o1 = OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8 ); + BUILD_ERROR( 1 , o1.getStr() ); + + } + catch( Exception & e ) { + printf( "normal exception ! %s\n", e.Message ); + } + catch ( ... ) + { + printf( "any exception !!!!\n" ); + } + } +} + +void OSaxParserTest::testPerformance( const Reference < XParser > & rParser ) +{ + Reference < XInputStream > rInStream = + createStreamFromFile( "testPerformance.xml" , m_rFactory ); + OUString sInput = "testperformance.xml"; + + if( rParser.is() && rInStream.is() ) { + InputSource source; + + source.aInputStream = rInStream; + source.sSystemId = sInput; + + TestDocumentHandler *pDocHandler = new TestDocumentHandler( m_rFactory , sal_False ); + Reference < XDocumentHandler > rDocHandler( (XDocumentHandler *) pDocHandler , UNO_QUERY ); + Reference < XEntityResolver > rEntityResolver( (XEntityResolver *) pDocHandler , UNO_QUERY ); + Reference < XErrorHandler > rErrorHandler( ( XErrorHandler * )pDocHandler , UNO_QUERY ); + + rParser->setDocumentHandler( rDocHandler ); + rParser->setEntityResolver( rEntityResolver ); + rParser->setErrorHandler( rErrorHandler ); + + try + { + TimeValue aStartTime, aEndTime; + osl_getSystemTime( &aStartTime ); + rParser->parseStream( source ); + osl_getSystemTime( &aEndTime ); + + double fStart = (double)aStartTime.Seconds + ((double)aStartTime.Nanosec / 1000000000.0); + double fEnd = (double)aEndTime.Seconds + ((double)aEndTime.Nanosec / 1000000000.0); + + printf( "Performance reading : %g s\n" , fEnd - fStart ); + + } + catch( SAXParseException &e ) { + Any any; + any <<= e; + while(true) { + if( any.getValueType() == cppu::UnoType<decltype(e)>::get() ) { + SAXParseException ex; + any >>= ex; + OString o = OUStringToOString( ex.Message , RTL_TEXTENCODING_ASCII_US ); + printf( "%s\n" , o.getStr() ); + any <<= ex.WrappedException; + } + else { + break; + } + } + } + catch( SAXException &e ) { + OString o = OUStringToOString( e.Message , RTL_TEXTENCODING_ASCII_US ); + printf( "%s\n" , o.getStr() ); + + } + catch( ... ) + { + printf( "any exception !!!!\n" ); + } + } +} +} // namespace + +using namespace sax_test; + +extern "C" +{ + +sal_Bool SAL_CALL component_writeInfo( + void * pServiceManager, void * pRegistryKey ) +{ + if (pRegistryKey) + { + try + { + Reference< XRegistryKey > xKey( + reinterpret_cast< XRegistryKey * >( pRegistryKey ) ); + + OUString str = + OUString( "/" ) + + OSaxParserTest_getImplementationName() + + OUString( "/UNO/SERVICES" ); + Reference< XRegistryKey > xNewKey = xKey->createKey( str ); + xNewKey->createKey( OSaxParserTest_getServiceName() ); + + str = + OUString( "/" ) + + OSaxWriterTest_getImplementationName() + + OUString( "/UNO/SERVICES" ); + + xNewKey = xKey->createKey( str ); + xNewKey->createKey( OSaxWriterTest_getServiceName() ); + + 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 (pServiceManager ) + { + Reference< XSingleServiceFactory > xRet; + Reference< XMultiServiceFactory > xSMgr = + reinterpret_cast< XMultiServiceFactory * > ( pServiceManager ); + + OUString aImplementationName = OUString::createFromAscii( pImplName ); + + + if (aImplementationName == OSaxWriterTest_getImplementationName() ) + { + xRet = createSingleFactory( xSMgr, aImplementationName, + OSaxWriterTest_CreateInstance, + OSaxWriterTest_getSupportedServiceNames() ); + } + else if (aImplementationName == OSaxParserTest_getImplementationName() ) + { + xRet = createSingleFactory( xSMgr, aImplementationName, + OSaxParserTest_CreateInstance, + OSaxParserTest_getSupportedServiceNames() ); + } + if (xRet.is()) + { + xRet->acquire(); + pRet = xRet.get(); + } + } + return pRet; +} + +} // extern C + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sax/test/sax/testwriter.cxx b/sax/test/sax/testwriter.cxx new file mode 100644 index 000000000..2a5d3706d --- /dev/null +++ b/sax/test/sax/testwriter.cxx @@ -0,0 +1,662 @@ +/* -*- 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 <vector> +#include <stdio.h> + +#include <com/sun/star/test/XSimpleTest.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> + +#include <com/sun/star/io/XActiveDataSource.hpp> +#include <com/sun/star/io/XOutputStream.hpp> +#include <com/sun/star/xml/sax/SAXParseException.hpp> +#include <com/sun/star/xml/sax/XParser.hpp> +#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp> + +#include <osl/time.h> + +#include <cppuhelper/factory.hxx> +#include <cppuhelper/implbase.hxx> + + +using namespace ::std; +using namespace ::cppu; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::test; +using namespace ::com::sun::star::registry; +using namespace ::com::sun::star::io; +using namespace ::com::sun::star::xml::sax; + +namespace sax_test { + +class OFileWriter : + public WeakImplHelper< XOutputStream > +{ +public: + explicit OFileWriter( char *pcFile ) { strncpy( m_pcFile, pcFile, 256 - 1 ); m_f = 0; } + + +public: + virtual void SAL_CALL writeBytes(const Sequence< sal_Int8 >& aData) + throw (NotConnectedException, BufferSizeExceededException, RuntimeException); + virtual void SAL_CALL flush() + throw (NotConnectedException, BufferSizeExceededException, RuntimeException); + virtual void SAL_CALL closeOutput() + throw (NotConnectedException, BufferSizeExceededException, RuntimeException); +private: + char m_pcFile[256]; + FILE *m_f; +}; + + +void OFileWriter::writeBytes(const Sequence< sal_Int8 >& aData) + throw (NotConnectedException, BufferSizeExceededException, RuntimeException) +{ + if( ! m_f ) { + m_f = fopen( m_pcFile , "w" ); + } + + fwrite( aData.getConstArray() , 1 , aData.getLength() , m_f ); +} + + +void OFileWriter::flush() + throw (NotConnectedException, BufferSizeExceededException, RuntimeException) +{ + fflush( m_f ); +} + +void OFileWriter::closeOutput() + throw (NotConnectedException, BufferSizeExceededException, RuntimeException) +{ + fclose( m_f ); + m_f = 0; +} + + +class OSaxWriterTest : + public WeakImplHelper< XSimpleTest > +{ +public: + explicit OSaxWriterTest( const Reference < XMultiServiceFactory > & rFactory ) : m_rFactory( rFactory ) + { + + } + ~OSaxWriterTest() {} + + +public: + virtual void SAL_CALL testInvariant( + const OUString& TestName, + const Reference < XInterface >& TestObject) + throw ( IllegalArgumentException, + RuntimeException); + + virtual sal_Int32 SAL_CALL test( + const OUString& TestName, + const Reference < XInterface >& TestObject, + sal_Int32 hTestHandle) + throw ( IllegalArgumentException,RuntimeException); + + virtual sal_Bool SAL_CALL testPassed() + throw ( RuntimeException); + virtual Sequence< OUString > SAL_CALL getErrors() throw (RuntimeException); + virtual Sequence< Any > SAL_CALL getErrorExceptions() throw (RuntimeException); + virtual Sequence< OUString > SAL_CALL getWarnings() throw (RuntimeException); + +private: + void testSimple( const Reference< XExtendedDocumentHandler > &r ); + void testExceptions( const Reference< XExtendedDocumentHandler > &r ); + void testDTD( const Reference< XExtendedDocumentHandler > &r ); + void testPerformance( const Reference< XExtendedDocumentHandler > &r ); + void writeParagraph( const Reference< XExtendedDocumentHandler > &r , const OUString & s); + +private: + Sequence<Any> m_seqExceptions; + Sequence<OUString> m_seqErrors; + Sequence<OUString> m_seqWarnings; + Reference < XMultiServiceFactory > m_rFactory; + +}; + + +/*---------------------------------------- +* +* Attributelist implementation +* +*----------------------------------------*/ +struct AttributeListImpl_impl; +class AttributeListImpl : public WeakImplHelper< XAttributeList > +{ +public: + AttributeListImpl(); + AttributeListImpl( const AttributeListImpl & ); + ~AttributeListImpl(); + +public: + virtual sal_Int16 SAL_CALL getLength() throw (RuntimeException); + virtual OUString SAL_CALL getNameByIndex(sal_Int16 i) throw (RuntimeException); + virtual OUString SAL_CALL getTypeByIndex(sal_Int16 i) throw (RuntimeException); + virtual OUString SAL_CALL getTypeByName(const OUString& aName) throw (RuntimeException); + virtual OUString SAL_CALL getValueByIndex(sal_Int16 i) throw (RuntimeException); + virtual OUString SAL_CALL getValueByName(const OUString& aName) throw (RuntimeException); + +public: + void addAttribute( const OUString &sName , + const OUString &sType , + const OUString &sValue ); + void clear(); + +private: + struct AttributeListImpl_impl *m_pImpl; +}; + + +struct TagAttribute +{ + TagAttribute(){} + TagAttribute( const OUString &sName, + const OUString &sType , + const OUString &sValue ) + { + sName = sName; + sType = sType; + sValue = sValue; + } + + OUString sName; + OUString sType; + OUString sValue; +}; + +struct AttributeListImpl_impl +{ + AttributeListImpl_impl() + { + // performance improvement during adding + vecAttribute.reserve(20); + } + vector<struct TagAttribute> vecAttribute; +}; + + +sal_Int16 AttributeListImpl::getLength() throw (RuntimeException) +{ + return m_pImpl->vecAttribute.size(); +} + + +AttributeListImpl::AttributeListImpl( const AttributeListImpl &r ) +{ + m_pImpl = new AttributeListImpl_impl; + *m_pImpl = *(r.m_pImpl); +} + +OUString AttributeListImpl::getNameByIndex(sal_Int16 i) throw (RuntimeException) +{ + if( i < m_pImpl->vecAttribute.size() ) { + return m_pImpl->vecAttribute[i].sName; + } + return OUString(); +} + + +OUString AttributeListImpl::getTypeByIndex(sal_Int16 i) throw (RuntimeException) +{ + if( i < m_pImpl->vecAttribute.size() ) { + return m_pImpl->vecAttribute[i].sType; + } + return OUString(); +} + +OUString AttributeListImpl::getValueByIndex(sal_Int16 i) throw (RuntimeException) +{ + if( i < m_pImpl->vecAttribute.size() ) { + return m_pImpl->vecAttribute[i].sValue; + } + return OUString(); + +} + +OUString AttributeListImpl::getTypeByName( const OUString& sName ) throw (RuntimeException) +{ + auto ii = std::find_if(m_pImpl->vecAttribute.begin(), m_pImpl->vecAttribute.end(), + [&sName](const struct TagAttribute& rAttr) { return rAttr.sName == sName; }); + if (ii != m_pImpl->vecAttribute.end()) + return (*ii).sType; + return OUString(); +} + +OUString AttributeListImpl::getValueByName(const OUString& sName) throw (RuntimeException) +{ + auto ii = std::find_if(m_pImpl->vecAttribute.begin(), m_pImpl->vecAttribute.end(), + [&sName](const struct TagAttribute& rAttr) { return rAttr.sName == sName; }); + if (ii != m_pImpl->vecAttribute.end()) + return (*ii).sValue; + return OUString(); +} + + +AttributeListImpl::AttributeListImpl() +{ + m_pImpl = new AttributeListImpl_impl; +} + + +AttributeListImpl::~AttributeListImpl() +{ + delete m_pImpl; +} + + +void AttributeListImpl::addAttribute( const OUString &sName , + const OUString &sType , + const OUString &sValue ) +{ + m_pImpl->vecAttribute.push_back( TagAttribute( sName , sType , sValue ) ); +} + +void AttributeListImpl::clear() +{ + m_pImpl->vecAttribute.clear(); + +} + + +/** +* for external binding +* +* +**/ +Reference < XInterface > SAL_CALL OSaxWriterTest_CreateInstance( const Reference < XMultiServiceFactory > & rSMgr ) throw (Exception) +{ + OSaxWriterTest *p = new OSaxWriterTest( rSMgr ); + Reference < XInterface > xService = *p; + return xService; +} + +OUString OSaxWriterTest_getServiceName( ) throw () +{ + return OUString( "test.com.sun.star.xml.sax.Writer"); +} + +OUString OSaxWriterTest_getImplementationName( ) throw () +{ + return OUString( "test.extensions.xml.sax.Writer"); +} + +Sequence<OUString> OSaxWriterTest_getSupportedServiceNames( ) throw () +{ + Sequence<OUString> aRet { OSaxWriterTest_getImplementationName( ) }; + return aRet; +} + + +void OSaxWriterTest::testInvariant( const OUString& TestName, + const Reference < XInterface >& TestObject ) + throw ( IllegalArgumentException, RuntimeException) +{ + if( OUString("com.sun.star.xml.sax.Writer") == TestName ) { + Reference< XDocumentHandler > doc( TestObject , UNO_QUERY ); + Reference< XExtendedDocumentHandler > ext( TestObject , UNO_QUERY ); + Reference< XActiveDataSource > source( TestObject , UNO_QUERY ); + + ERROR_ASSERT( doc.is() , "XDocumentHandler cannot be queried" ); + ERROR_ASSERT( ext.is() , "XExtendedDocumentHandler cannot be queried" ); + ERROR_ASSERT( source.is() , "XActiveDataSource cannot be queried" ); + } + else { + BUILD_ERROR( 0 , "wrong test" ); + } +} + + +sal_Int32 OSaxWriterTest::test( + const OUString& TestName, + const Reference < XInterface >& TestObject, + sal_Int32 hTestHandle) + throw ( IllegalArgumentException,RuntimeException) +{ + if( OUString( "com.sun.star.xml.sax.Writer") == TestName ) + { + try + { + if( 0 == hTestHandle ) + { + testInvariant( TestName , TestObject ); + } + else + { + Reference< XExtendedDocumentHandler > writer( TestObject , UNO_QUERY ); + + if( 1 == hTestHandle ) { + testSimple( writer ); + } + else if( 2 == hTestHandle ) { + testExceptions( writer ); + } + else if( 3 == hTestHandle ) { + testDTD( writer ); + } + else if( 4 == hTestHandle ) { + testPerformance( writer ); + } + } + } + catch( Exception & e ) { + OString o = OUStringToOString( e.Message , RTL_TEXTENCODING_ASCII_US ); + BUILD_ERROR( 0 , o.getStr() ); + } + catch( ... ) + { + BUILD_ERROR( 0 , "unknown exception (Exception is not base class)" ); + } + + hTestHandle ++; + + if( hTestHandle >= 5) { + // all tests finished. + hTestHandle = -1; + } + } + else { + BUILD_ERROR( 0 , "service not supported by test." ); + } + return hTestHandle; +} + + +sal_Bool OSaxWriterTest::testPassed() throw (RuntimeException) +{ + return m_seqErrors.getLength() == 0; +} + + +Sequence< OUString > OSaxWriterTest::getErrors() throw (RuntimeException) +{ + return m_seqErrors; +} + + +Sequence< Any > OSaxWriterTest::getErrorExceptions() throw (RuntimeException) +{ + return m_seqExceptions; +} + + +Sequence< OUString > OSaxWriterTest::getWarnings() throw (RuntimeException) +{ + return m_seqWarnings; +} + +void OSaxWriterTest::writeParagraph( + const Reference< XExtendedDocumentHandler > &r , + const OUString & s) +{ + int nMax = s.getLength(); + int nStart = 0; + + Sequence<sal_uInt16> seq( s.getLength() ); + memcpy( seq.getArray() , s.getStr() , s.getLength() * sizeof( sal_uInt16 ) ); + + for( int n = 1 ; n < nMax ; n++ ){ + if( 32 == seq.getArray()[n] ) { + r->allowLineBreak(); + r->characters( s.copy( nStart , n - nStart ) ); + nStart = n; + } + } + r->allowLineBreak(); + r->characters( s.copy( nStart , n - nStart ) ); +} + + +void OSaxWriterTest::testSimple( const Reference< XExtendedDocumentHandler > &r ) +{ + OUString testParagraph = OUString( + "This is a stupid test to check whether the SAXWriter possibly makes " + "line breaks halfway correctly or whether it writes the line to the " + "bitter end." ); + + OFileWriter *pw = new OFileWriter("output.xml"); + AttributeListImpl *pList = new AttributeListImpl; + + Reference< XAttributeList > rList( (XAttributeList *) pList , UNO_QUERY ); + Reference< XOutputStream > ref( ( XOutputStream * ) pw , UNO_QUERY ); + + Reference< XActiveDataSource > source( r , UNO_QUERY ); + + ERROR_ASSERT( ref.is() , "no output stream" ); + ERROR_ASSERT( source.is() , "no active data source" ); + + source->setOutputStream( ref ); + + r->startDocument(); + + pList->addAttribute( OUString( "Arg1" ), + OUString( "CDATA") , + OUString( "bla\n u") ); + pList->addAttribute( OUString( "Arg2") , + OUString( "CDATA") , + OUString( "blub") ); + + r->startElement( OUString( "tag1") , rList ); + r->ignorableWhitespace( OUString() ); + + r->characters( OUString( "huhu") ); + r->ignorableWhitespace( OUString() ); + + r->startElement( OUString( "hi") , rList ); + r->ignorableWhitespace( OUString() ); + + // the ampersand must be converted & -> & + r->characters( OUString( "ü") ); + + // Test added for mib. Tests if errors during conversions occurs + r->ignorableWhitespace( OUString() ); + char array[256]; + for( sal_Int32 n = 32 ; n < 254 ; n ++ ) { + array[n-32] = n; + } + array[254-32] = 0; + r->characters( + OStringToOUString( array , RTL_TEXTENCODING_SYMBOL ) + ); + r->ignorableWhitespace( OUString() ); + + // '>' must not be converted + r->startCDATA(); + r->characters( OUString( ">fsfsdf<") ); + r->endCDATA(); + r->ignorableWhitespace( OUString() ); + + writeParagraph( r , testParagraph ); + + + r->ignorableWhitespace( OUString() ); + r->comment( OUString( "This is a comment !") ); + r->ignorableWhitespace( OUString() ); + + r->startElement( OUString( "emptytagtest") , rList ); + r->endElement( OUString( "emptytagtest") ); + + r->endElement( OUString( "hi") ); + r->ignorableWhitespace( OUString() ); + + r->endElement( OUString( "tag1") ); + r->endDocument(); + +} + +void OSaxWriterTest::testExceptions( const Reference< XExtendedDocumentHandler > & r ) +{ + + OFileWriter *pw = new OFileWriter("output2.xml"); + AttributeListImpl *pList = new AttributeListImpl; + + Reference< XAttributeList > rList( (XAttributeList *) pList , UNO_QUERY ); + Reference< XOutputStream > ref( ( XOutputStream * ) pw , UNO_QUERY ); + + Reference< XActiveDataSource > source( r , UNO_QUERY ); + + ERROR_ASSERT( ref.is() , "no output stream" ); + ERROR_ASSERT( source.is() , "no active data source" ); + + source->setOutputStream( ref ); + + { // startDocument must be called before start element + sal_Bool bException = sal_True; + try + { + r->startElement( OUString( "huhu") , rList ); + bException = sal_False; + } + catch( SAXException &e ) + { + + } + ERROR_ASSERT( bException , "expected exception not thrown !" ); + } + + r->startDocument(); + + r->startElement( OUString( "huhu") , rList ); + r->startCDATA(); + + { + sal_Bool bException = sal_True; + try{ + r->startElement( OUString( "huhu") , rList ); + bException = sal_False; + } + catch( SAXException &e ) { + + } + ERROR_ASSERT( bException , "expected exception not thrown !" ); + } + + r->endCDATA(); + + { + sal_Unicode array[] = { 'a' , 'b' , 4 , 9 , 10 }; + OUString o( array , 5 ); + try + { + r->characters( o ); + ERROR_ASSERT( 0 , "Writer allowed to write forbidden characters" ); + } + catch( SAXException & e ) + { + + } + } + r->endElement( OUString( "huhu") ); + + r->endDocument(); +} + + +void OSaxWriterTest::testDTD(const Reference< XExtendedDocumentHandler > &r ) +{ + OFileWriter *pw = new OFileWriter("outputDTD.xml"); + AttributeListImpl *pList = new AttributeListImpl; + + Reference< XAttributeList > rList( (XAttributeList *) pList , UNO_QUERY ); + Reference< XOutputStream > ref( ( XOutputStream * ) pw , UNO_QUERY ); + + Reference< XActiveDataSource > source( r , UNO_QUERY ); + + ERROR_ASSERT( ref.is() , "no output stream" ); + ERROR_ASSERT( source.is() , "no active data source" ); + + source->setOutputStream( ref ); + + + r->startDocument(); + r->unknown( OUString( "<!DOCTYPE iCalendar >\n") ); + r->startElement( OUString( "huhu") , rList ); + + r->endElement( OUString( "huhu") ); + r->endDocument(); +} + +void OSaxWriterTest::testPerformance(const Reference< XExtendedDocumentHandler > &r ) +{ + OFileWriter *pw = new OFileWriter("testPerformance.xml"); + AttributeListImpl *pList = new AttributeListImpl; + + OUString testParagraph = + OUString( + "This is a stupid test to check whether the SAXWriter possibly makes " + "line breaks halfway correctly or whether it writes the line to the " + "bitter end." ); + + + Reference< XAttributeList > rList( (XAttributeList *) pList , UNO_QUERY ); + Reference< XOutputStream > ref( ( XOutputStream * ) pw , UNO_QUERY ); + + Reference< XActiveDataSource > source( r , UNO_QUERY ); + + ERROR_ASSERT( ref.is() , "no output stream" ); + ERROR_ASSERT( source.is() , "no active data source" ); + + source->setOutputStream( ref ); + + TimeValue aStartTime, aEndTime; + osl_getSystemTime( &aStartTime ); + + + r->startDocument(); + // just write a bunch of xml tags ! + // for performance testing + sal_Int32 i2; + OUString huhu( "huhu" ); + const int ITERATIONS = 125; + for( i2 = 0 ; i2 < ITERATIONS ; i2 ++ ) + { + r->startElement( OUString( "tag" ) + + OUString::valueOf( i2 ), rList ); + for( sal_Int32 i = 0 ; i < 450 ; i ++ ) + { + r->ignorableWhitespace( "" ); + r->startElement( huhu , rList ); + r->characters( testParagraph ); + + r->ignorableWhitespace( "" ); + r->endElement( huhu ); + } + } + for( i2 = ITERATIONS-1 ; i2 >= 0 ; i2-- ) + { + r->ignorableWhitespace( "" ); + r->endElement( OUString( "tag" ) + OUString::valueOf( i2 ) ); + } + + r->endDocument(); + + osl_getSystemTime( &aEndTime ); + + double fStart = (double)aStartTime.Seconds + ((double)aStartTime.Nanosec / 1000000000.0); + double fEnd = (double)aEndTime.Seconds + ((double)aEndTime.Nanosec / 1000000000.0); + + printf( "Performance writing : %g s\n" , fEnd - fStart ); +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sax/test/saxdemo.cxx b/sax/test/saxdemo.cxx new file mode 100644 index 000000000..7139d60ef --- /dev/null +++ b/sax/test/saxdemo.cxx @@ -0,0 +1,626 @@ +/* -*- 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 . + */ + + +// testcomponent - Loads a service and its testcomponent from dlls performs a test. +// Expands the dll-names depending on the actual environment. +// Example : testcomponent com.sun.star.io.Pipe stm + +// Therefore the testcode must exist in teststm and the testservice must be named test.com.sun.star.uno.io.Pipe + + +#include <stdio.h> +#include <vector> +#include <cstring> + +#include <com/sun/star/registry/XImplementationRegistration.hpp> +#include <com/sun/star/lang/XComponent.hpp> + +#include <com/sun/star/xml/sax/SAXParseException.hpp> +#include <com/sun/star/xml/sax/XParser.hpp> +#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp> + +#include <com/sun/star/io/XOutputStream.hpp> +#include <com/sun/star/io/XActiveDataSource.hpp> + +#include <cppuhelper/servicefactory.hxx> +#include <cppuhelper/implbase.hxx> + + +using namespace ::std; +using namespace ::cppu; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::registry; +using namespace ::com::sun::star::xml::sax; +using namespace ::com::sun::star::io; + + +/************ + * Sequence of bytes -> InputStream + ************/ +class OInputStream : public WeakImplHelper < XInputStream > +{ +public: + explicit OInputStream( const Sequence< sal_Int8 >&seq ) : + m_seq( seq ), + nPos( 0 ) + {} + +public: + virtual sal_Int32 SAL_CALL readBytes( Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead ) + throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) + { + nBytesToRead = (nBytesToRead > m_seq.getLength() - nPos ) ? + m_seq.getLength() - nPos : + nBytesToRead; + aData = Sequence< sal_Int8 > ( &(m_seq.getConstArray()[nPos]) , nBytesToRead ); + nPos += nBytesToRead; + return nBytesToRead; + } + virtual sal_Int32 SAL_CALL readSomeBytes( + css::uno::Sequence< sal_Int8 >& aData, + sal_Int32 nMaxBytesToRead ) + throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) + { + return readBytes( aData, nMaxBytesToRead ); + } + virtual void SAL_CALL skipBytes( sal_Int32 /* nBytesToSkip */ ) + throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) + { + // not implemented + } + virtual sal_Int32 SAL_CALL available( ) + throw(NotConnectedException, IOException, RuntimeException) + { + return m_seq.getLength() - nPos; + } + virtual void SAL_CALL closeInput( ) + throw(NotConnectedException, IOException, RuntimeException) + { + // not needed + } + Sequence< sal_Int8> m_seq; + sal_Int32 nPos; +}; + + +// Helper : create an input stream from a file + +Reference< XInputStream > createStreamFromFile( + const char *pcFile ) +{ + FILE *f = fopen( pcFile , "rb" ); + Reference< XInputStream > r; + + if( f ) { + fseek( f , 0 , SEEK_END ); + int nLength = ftell( f ); + fseek( f , 0 , SEEK_SET ); + + Sequence<sal_Int8> seqIn(nLength); + fread( seqIn.getArray() , nLength , 1 , f ); + + r.set( new OInputStream( seqIn ) ); + fclose( f ); + } + return r; +} + + +// The document handler, which is needed for the saxparser +// The Documenthandler for reading sax + +class TestDocumentHandler : + public WeakImplHelper< XExtendedDocumentHandler , XEntityResolver , XErrorHandler > +{ +public: + TestDocumentHandler( ) + { + } + +public: // Error handler + virtual void SAL_CALL error(const Any& aSAXParseException) throw (SAXException, RuntimeException) + { + printf( "Error !\n" ); + throw SAXException( + OUString( "error from error handler") , + Reference < XInterface >() , + aSAXParseException ); + } + virtual void SAL_CALL fatalError(const Any& /* aSAXParseException */) throw (SAXException, RuntimeException) + { + printf( "Fatal Error !\n" ); + } + virtual void SAL_CALL warning(const Any& /* aSAXParseException */) throw (SAXException, RuntimeException) + { + printf( "Warning !\n" ); + } + + +public: // ExtendedDocumentHandler + + virtual void SAL_CALL startDocument() throw (SAXException, RuntimeException) + { + m_iElementCount = 0; + m_iAttributeCount = 0; + m_iWhitespaceCount =0; + m_iCharCount=0; + printf( "document started\n" ); + } + virtual void SAL_CALL endDocument() throw (SAXException, RuntimeException) + { + printf( "document finished\n" ); + printf( "(ElementCount %d),(AttributeCount %d),(WhitespaceCount %d),(CharCount %d)\n", + m_iElementCount, m_iAttributeCount, m_iWhitespaceCount , m_iCharCount ); + + } + virtual void SAL_CALL startElement(const OUString& /* aName */, + const Reference< XAttributeList > & xAttribs) + throw (SAXException,RuntimeException) + { + m_iElementCount ++; + m_iAttributeCount += xAttribs->getLength(); + } + + virtual void SAL_CALL endElement(const OUString& /* aName */) throw (SAXException,RuntimeException) + { + // ignored + } + + virtual void SAL_CALL characters(const OUString& aChars) throw (SAXException,RuntimeException) + { + m_iCharCount += aChars.getLength(); + } + virtual void SAL_CALL ignorableWhitespace(const OUString& aWhitespaces) throw (SAXException,RuntimeException) + { + m_iWhitespaceCount += aWhitespaces.getLength(); + } + + virtual void SAL_CALL processingInstruction(const OUString& /* aTarget */, const OUString& /* aData */) throw (SAXException,RuntimeException) + { + // ignored + } + + virtual void SAL_CALL setDocumentLocator(const Reference< XLocator> & /* xLocator */) + throw (SAXException,RuntimeException) + { + // ignored + } + + virtual InputSource SAL_CALL resolveEntity( + const OUString& sPublicId, + const OUString& sSystemId) + throw (RuntimeException) + { + InputSource source; + source.sSystemId = sSystemId; + source.sPublicId = sPublicId; + + source.aInputStream = createStreamFromFile( + OUStringToOString( sSystemId, RTL_TEXTENCODING_ASCII_US).getStr() ); + + return source; + } + + virtual void SAL_CALL startCDATA() throw (SAXException,RuntimeException) + { + } + virtual void SAL_CALL endCDATA() throw (SAXException,RuntimeException) + { + } + virtual void SAL_CALL comment(const OUString& /* sComment */) throw (SAXException,RuntimeException) + { + } + virtual void SAL_CALL unknown(const OUString& /* sString */) throw (SAXException,RuntimeException) + { + } + + virtual void SAL_CALL allowLineBreak() throw (SAXException, RuntimeException ) + { + + } + +public: + int m_iElementCount; + int m_iAttributeCount; + int m_iWhitespaceCount; + int m_iCharCount; +}; + + +// helper implementation for writing +// implements an XAttributeList + +struct AttributeListImpl_impl; +class AttributeListImpl : public WeakImplHelper< XAttributeList > +{ +public: + AttributeListImpl(); + AttributeListImpl( const AttributeListImpl & ); + ~AttributeListImpl(); + +public: + virtual sal_Int16 SAL_CALL getLength() throw (RuntimeException); + virtual OUString SAL_CALL getNameByIndex(sal_Int16 i) throw (RuntimeException); + virtual OUString SAL_CALL getTypeByIndex(sal_Int16 i) throw (RuntimeException); + virtual OUString SAL_CALL getTypeByName(const OUString& aName) throw (RuntimeException); + virtual OUString SAL_CALL getValueByIndex(sal_Int16 i) throw (RuntimeException); + virtual OUString SAL_CALL getValueByName(const OUString& aName) throw (RuntimeException); + +public: + void addAttribute( const OUString &sName , + const OUString &sType , + const OUString &sValue ); + void clear(); + +private: + struct AttributeListImpl_impl *m_pImpl; +}; + + +struct TagAttribute +{ + TagAttribute(){} + TagAttribute( const OUString &s_Name, + const OUString &s_Type , + const OUString &s_Value ) + : sName(s_Name), + sType(s_Type), + sValue(s_Value) + { + } + + OUString sName; + OUString sType; + OUString sValue; +}; + +struct AttributeListImpl_impl +{ + AttributeListImpl_impl() + { + // performance improvement during adding + vecAttribute.reserve(20); + } + vector<struct TagAttribute> vecAttribute; +}; + + +sal_Int16 AttributeListImpl::getLength() throw (RuntimeException) +{ + return (sal_Int16) m_pImpl->vecAttribute.size(); +} + + +AttributeListImpl::AttributeListImpl( const AttributeListImpl &r ) +{ + m_pImpl = new AttributeListImpl_impl; + *m_pImpl = *(r.m_pImpl); +} + +OUString AttributeListImpl::getNameByIndex(sal_Int16 i) throw (RuntimeException) +{ + if( i < sal::static_int_cast<sal_Int16>(m_pImpl->vecAttribute.size()) ) { + return m_pImpl->vecAttribute[i].sName; + } + return OUString(); +} + + +OUString AttributeListImpl::getTypeByIndex(sal_Int16 i) throw (RuntimeException) +{ + if( i < sal::static_int_cast<sal_Int16>(m_pImpl->vecAttribute.size()) ) { + return m_pImpl->vecAttribute[i].sType; + } + return OUString(); +} + +OUString AttributeListImpl::getValueByIndex(sal_Int16 i) throw (RuntimeException) +{ + if( i < sal::static_int_cast<sal_Int16>(m_pImpl->vecAttribute.size()) ) { + return m_pImpl->vecAttribute[i].sValue; + } + return OUString(); + +} + +OUString AttributeListImpl::getTypeByName( const OUString& sName ) throw (RuntimeException) +{ + auto ii = std::find_if(m_pImpl->vecAttribute.begin(), m_pImpl->vecAttribute.end(), + [&sName](const struct TagAttribute& rAttr) { return rAttr.sName == sName; }); + if (ii != m_pImpl->vecAttribute.end()) + return (*ii).sType; + return OUString(); +} + +OUString AttributeListImpl::getValueByName(const OUString& sName) throw (RuntimeException) +{ + auto ii = std::find_if(m_pImpl->vecAttribute.begin(), m_pImpl->vecAttribute.end(), + [&sName](const struct TagAttribute& rAttr) { return rAttr.sName == sName; }); + if (ii != m_pImpl->vecAttribute.end()) + return (*ii).sValue; + return OUString(); +} + + +AttributeListImpl::AttributeListImpl() +{ + m_pImpl = new AttributeListImpl_impl; +} + + +AttributeListImpl::~AttributeListImpl() +{ + delete m_pImpl; +} + + +void AttributeListImpl::addAttribute( const OUString &sName , + const OUString &sType , + const OUString &sValue ) +{ + m_pImpl->vecAttribute.push_back( TagAttribute( sName , sType , sValue ) ); +} + +void AttributeListImpl::clear() +{ + m_pImpl->vecAttribute.clear(); +} + + +// helper function for writing +// ensures that linebreaks are inserted +// when writing a long text. +// Note: this implementation may be a bit slow, +// but it shows, how the SAX-Writer handles the allowLineBreak calls. + +void writeParagraphHelper( + const Reference< XExtendedDocumentHandler > &r , + const OUString & s) +{ + int nMax = s.getLength(); + int nStart = 0; + int n = 1; + + Sequence<sal_uInt16> seq( s.getLength() ); + memcpy( seq.getArray() , s.getStr() , s.getLength() * sizeof( sal_uInt16 ) ); + + for( n = 1 ; n < nMax ; n++ ){ + if( 32 == seq.getArray()[n] ) { + r->allowLineBreak(); + r->characters( s.copy( nStart , n - nStart ) ); + nStart = n; + } + } + r->allowLineBreak(); + r->characters( s.copy( nStart , n - nStart ) ); +} + + +// helper implementation for SAX-Writer +// writes data to a file + +class OFileWriter : + public WeakImplHelper< XOutputStream > +{ +public: + explicit OFileWriter( char *pcFile ) { strncpy( m_pcFile , pcFile, 256 - 1 ); m_f = 0; } + + +public: + virtual void SAL_CALL writeBytes(const Sequence< sal_Int8 >& aData) + throw (NotConnectedException, BufferSizeExceededException, RuntimeException); + virtual void SAL_CALL flush() + throw (NotConnectedException, BufferSizeExceededException, RuntimeException); + virtual void SAL_CALL closeOutput() + throw (NotConnectedException, BufferSizeExceededException, RuntimeException); +private: + char m_pcFile[256]; + FILE *m_f; +}; + + +void OFileWriter::writeBytes(const Sequence< sal_Int8 >& aData) + throw (NotConnectedException, BufferSizeExceededException, RuntimeException) +{ + if( ! m_f ) { + m_f = fopen( m_pcFile , "w" ); + } + + fwrite( aData.getConstArray() , 1 , aData.getLength() , m_f ); +} + + +void OFileWriter::flush() + throw (NotConnectedException, BufferSizeExceededException, RuntimeException) +{ + fflush( m_f ); +} + +void OFileWriter::closeOutput() + throw (NotConnectedException, BufferSizeExceededException, RuntimeException) +{ + fclose( m_f ); + m_f = 0; +} + + +// Needed to switch on solaris threads +#ifdef __sun +extern "C" void ChangeGlobalInit(); +#endif +int main (int argc, char **argv) +{ + + if( argc < 3) { + printf( "usage : saxdemo inputfile outputfile\n" ); + exit( 0 ); + } +#ifdef __sun + // switch on threads in solaris + ChangeGlobalInit(); +#endif + + // create service manager + Reference< XMultiServiceFactory > xSMgr = createRegistryServiceFactory( + OUString( "applicat.rdb" ) ); + + Reference < XImplementationRegistration > xReg; + try + { + // Create registration service + Reference < XInterface > x = xSMgr->createInstance( "com.sun.star.registry.ImplementationRegistration" ); + xReg.set( x , UNO_QUERY ); + } + catch( Exception & ) { + printf( "Couldn't create ImplementationRegistration service\n" ); + exit(1); + } + + OString sTestName; + try + { + // Load dll for the tested component + OUString aDllName( "sax.uno" SAL_DLLEXTENSION ); + xReg->registerImplementation( + OUString("com.sun.star.loader.SharedLibrary"), + aDllName, + Reference< XSimpleRegistry > () ); + } + catch( Exception &e ) { + printf( "Couldn't reach sax dll\n" ); + printf( "%s\n" , OUStringToOString( e.Message , RTL_TEXTENCODING_ASCII_US ).getStr() ); + + exit(1); + } + + + // parser demo + // read xml from a file and count elements + + Reference< XInterface > x = xSMgr->createInstance( "com.sun.star.xml.sax.Parser" ); + if( x.is() ) + { + Reference< XParser > rParser( x , UNO_QUERY ); + + // create and connect the document handler to the parser + TestDocumentHandler *pDocHandler = new TestDocumentHandler( ); + + Reference < XDocumentHandler > rDocHandler( (XDocumentHandler *) pDocHandler ); + Reference< XEntityResolver > rEntityResolver( (XEntityResolver *) pDocHandler ); + + rParser->setDocumentHandler( rDocHandler ); + rParser->setEntityResolver( rEntityResolver ); + + // create the input stream + InputSource source; + source.aInputStream = createStreamFromFile( argv[1] ); + source.sSystemId = OUString::createFromAscii( argv[1] ); + + try + { + // start parsing + rParser->parseStream( source ); + } + + catch( Exception & e ) + { + OString o1 = OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8 ); + printf( "Exception during parsing : %s\n" , o1.getStr() ); + } + } + else + { + printf( "couldn't create sax-parser component\n" ); + } + + + // The SAX-Writer demo + + x= xSMgr->createInstance("com.sun.star.xml.sax.Writer"); + if( x.is() ) + { + printf( "start writing to %s\n" , argv[2] ); + + OFileWriter *pw = new OFileWriter( argv[2] ); + Reference< XActiveDataSource > source( x , UNO_QUERY ); + source->setOutputStream( Reference< XOutputStream> ( (XOutputStream*) pw ) ); + + AttributeListImpl *pList = new AttributeListImpl; + Reference< XAttributeList > rList( (XAttributeList *) pList ); + + Reference< XExtendedDocumentHandler > r( x , UNO_QUERY ); + r->startDocument(); + + pList->addAttribute( OUString( "Arg1" ), + OUString( "CDATA") , + OUString( "foo\n u") ); + pList->addAttribute( OUString( "Arg2") , + OUString( "CDATA") , + OUString( "foo2") ); + + r->startElement( OUString( "tag1") , rList ); + // tells the writer to insert a linefeed + r->ignorableWhitespace( OUString() ); + + r->characters( OUString( "huhu") ); + r->ignorableWhitespace( OUString() ); + + r->startElement( OUString( "hi") , rList ); + r->ignorableWhitespace( OUString() ); + + // the enpassant must be converted & -> & + r->characters( OUString( "ü") ); + r->ignorableWhitespace( OUString() ); + + // '>' must not be converted + r->startCDATA(); + r->characters( OUString( " > foo < ") ); + r->endCDATA(); + r->ignorableWhitespace( OUString() ); + + OUString testParagraph = OUString( + "This is only a test to check, if the writer inserts line feeds " + "if needed or if the writer puts the whole text into one line." ); + writeParagraphHelper( r , testParagraph ); + + r->ignorableWhitespace( OUString() ); + r->comment( OUString( "This is a comment !") ); + r->ignorableWhitespace( OUString() ); + + r->startElement( OUString( "emptytagtest") , rList ); + r->endElement( OUString( "emptytagtest") ); + r->ignorableWhitespace( OUString() ); + + r->endElement( OUString( "hi") ); + r->ignorableWhitespace( OUString() ); + + r->endElement( OUString( "tag1") ); + r->endDocument(); + + printf( "finished writing\n" ); + } + else + { + printf( "couldn't create sax-writer component\n" ); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sax/test/testcomponent.cxx b/sax/test/testcomponent.cxx new file mode 100644 index 000000000..51f8f244e --- /dev/null +++ b/sax/test/testcomponent.cxx @@ -0,0 +1,223 @@ +/* -*- 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 . + */ + + +// testcomponent - Loads a service and its testcomponent from dlls performs a test. +// Expands the dll-names depending on the actual environment. +// Example : testcomponent com.sun.star.io.Pipe stm + +// Therefore the testcode must exist in teststm and the testservice must be named com.sun.star.io.Pipe + + +#include <stdio.h> +#include <com/sun/star/registry/XImplementationRegistration.hpp> +#include <com/sun/star/lang/XComponent.hpp> + +#include <com/sun/star/test/XSimpleTest.hpp> + +#include <cppuhelper/servicefactory.hxx> + + +using namespace ::cppu; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::test; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::registry; + +// Needed to switch on solaris threads +#ifdef __sun +extern "C" void ChangeGlobalInit(); +#endif + +int main (int argc, char **argv) +{ + + if( argc < 3) { + printf( "usage : testcomponent service dll [additional dlls]\n" ); + exit( 0 ); + } +#ifdef __sun + // switch on threads in solaris + ChangeGlobalInit(); +#endif + + // create service manager + Reference< XMultiServiceFactory > xSMgr = + createRegistryServiceFactory( OUString( "applicat.rdb") ); + + Reference < XImplementationRegistration > xReg; + Reference < XSimpleRegistry > xSimpleReg; + + try + { + // Create registration service + Reference < XInterface > x = xSMgr->createInstance( "com.sun.star.registry.ImplementationRegistration" ); + xReg.set( x , UNO_QUERY ); + } + catch (const Exception&) + { + printf( "Couldn't create ImplementationRegistration service\n" ); + exit(1); + } + + char szBuf[1024]; + OString sTestName; + + try + { + // Load dll for the tested component + for( int n = 2 ; n <argc ; n ++ ) { +#ifdef _WIN32 + OUString aDllName = OStringToOUString( argv[n] , RTL_TEXTENCODING_ASCII_US ); +#else + OUString aDllName = "lib"; + aDllName += OStringToOUString( argv[n] , RTL_TEXTENCODING_ASCII_US ); + aDllName += ".so"; +#endif + xReg->registerImplementation( + OUString("com.sun.star.loader.SharedLibrary"), + aDllName, + xSimpleReg ); + } + } + catch (const Exception &e) + { + printf( "Couldn't reach dll %s\n" , szBuf ); + printf( "%s\n" , OUStringToOString( e.Message , RTL_TEXTENCODING_ASCII_US ).getStr() ); + + exit(1); + } + + + try + { + // Load dll for the test component + sTestName = "test"; + sTestName += argv[2]; + +#ifdef _WIN32 + OUString aDllName = OStringToOUString( sTestName , RTL_TEXTENCODING_ASCII_US ); +#else + OUString aDllName = "lib"; + aDllName += OStringToOUString( sTestName , RTL_TEXTENCODING_ASCII_US ); + aDllName += ".so"; +#endif + + xReg->registerImplementation( + OUString("com.sun.star.loader.SharedLibrary") , + aDllName, + xSimpleReg ); + } + catch (const Exception&) + { + printf( "Couldn't reach dll %s\n" , szBuf ); + exit(1); + } + + + // Instantiate test service + sTestName = "test."; + sTestName += argv[1]; + + Reference < XInterface > xIntTest = + xSMgr->createInstance( OStringToOUString( sTestName , RTL_TEXTENCODING_ASCII_US ) ); + Reference< XSimpleTest > xTest( xIntTest , UNO_QUERY ); + + if( ! xTest.is() ) { + printf( "Couldn't instantiate test service \n" ); + exit( 1 ); + } + + + sal_Int32 nHandle = 0; + sal_Int32 nNewHandle; + sal_Int32 nErrorCount = 0; + sal_Int32 nWarningCount = 0; + + // loop until all test are performed + while( nHandle != -1 ) + { + // Instantiate service + Reference< XInterface > x = + xSMgr->createInstance( OStringToOUString( argv[1] , RTL_TEXTENCODING_ASCII_US ) ); + if( ! x.is() ) + { + printf( "Couldn't instantiate service !\n" ); + exit( 1 ); + } + + // do the test + try + { + nNewHandle = xTest->test( + OStringToOUString( argv[1] , RTL_TEXTENCODING_ASCII_US ) , x , nHandle ); + } + catch (const Exception &e) + { + OString o = OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ); + printf( "testcomponent : uncaught exception %s\n" , o.getStr() ); + exit(1); + } + catch (...) + { + printf( "testcomponent : uncaught unknown exception\n" ); + exit(1); + } + + + // print errors and warning + Sequence<OUString> seqErrors = xTest->getErrors(); + Sequence<OUString> seqWarnings = xTest->getWarnings(); + if( seqWarnings.getLength() > nWarningCount ) + { + printf( "Warnings during test %" SAL_PRIxUINT32 "!\n" , nHandle ); + for( ; nWarningCount < seqWarnings.getLength() ; nWarningCount ++ ) + { + OString o = OUStringToOString( + seqWarnings.getArray()[nWarningCount], RTL_TEXTENCODING_ASCII_US ); + printf( "Warning\n%s\n---------\n" , o.getStr() ); + } + } + + + if( seqErrors.getLength() > nErrorCount ) { + printf( "Errors during test %" SAL_PRIxUINT32 "!\n" , nHandle ); + for( ; nErrorCount < seqErrors.getLength() ; nErrorCount ++ ) { + OString o = OUStringToOString( + seqErrors.getArray()[nErrorCount], RTL_TEXTENCODING_ASCII_US ); + printf( "%s\n" , o.getStr() ); + } + } + + nHandle = nNewHandle; + } + + if( xTest->testPassed() ) { + printf( "Test passed !\n" ); + } + else { + printf( "Test failed !\n" ); + } + + Reference <XComponent > rComp( xSMgr , UNO_QUERY ); + rComp->dispose(); + return 0; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |