1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 // MARKER(update_precomp.py): autogen include statement, do not remove
30 #include "precompiled_extensions.hxx"
33 #include <smart/com/sun/star/test/XSimpleTest.hxx>
34 #include <smart/com/sun/star/lang/XMultiServiceFactory.hxx> // for the multiservice-factories
38 #include <smart/com/sun/star/io/XActiveDataSource.hxx>
39 #include <smart/com/sun/star/io/XOutputStream.hxx>
40 #include <smart/com/sun/star/xml/sax/SAXParseException.hxx>
41 #include <smart/com/sun/star/xml/sax/XParser.hxx>
42 #include <smart/com/sun/star/xml/sax/XExtendedDocumentHandler.hxx>
44 #include <rtl/wstring.hxx>
46 #include <usr/weak.hxx>
47 #include <tools/string.hxx>
49 #include <usr/factoryhlp.hxx>
51 #include <usr/reflserv.hxx> // for EXTERN_SERVICE_CALLTYPE
57 #define BUILD_ERROR(expr, Message)\
59 m_seqErrors.realloc( m_seqErrors.getLen() + 1 ); \
60 m_seqExceptions.realloc( m_seqExceptions.getLen() + 1 ); \
71 m_seqErrors.getArray()[ m_seqErrors.getLen()-1] = StringToUString( str , CHARSET_SYSTEM ); \
76 #define WARNING_ASSERT(expr, Message) \
78 m_seqWarnings.realloc( m_seqErrors.getLen() +1 ); \
89 m_seqWarnings.getArray()[ m_seqWarnings.getLen()-1] = StringToUString( str , CHARSET_SYSTEM ); \
94 #define ERROR_ASSERT(expr, Message) \
96 BUILD_ERROR(expr, Message );\
101 #define ERROR_EXCEPTION_ASSERT(expr, Message, Exception) \
103 BUILD_ERROR(expr,Message);\
104 m_seqExceptions.getArray()[ m_seqExceptions.getLen()-1] = UsrAny( Exception );\
118 public XOutputStream
,
122 OFileWriter( char *pcFile
) { strcpy( m_pcFile
, pcFile
); m_f
= 0; }
125 public: // refcounting
126 BOOL
queryInterface( Uik aUik
, XInterfaceRef
& rOut
)
128 if( XOutputStream::getSmartUik() == aUik
) {
129 rOut
= (XOutputStream
*) this;
131 else return OWeakObject::queryInterface( aUik
, rOut
);
135 void acquire() { OWeakObject::acquire(); }
136 void release() { OWeakObject::release(); }
137 void* getImplementation(Reflection
*p
) { return OWeakObject::getImplementation(p
); }
140 virtual void writeBytes(const Sequence
< BYTE
>& aData
)
141 THROWS( (NotConnectedException
, BufferSizeExceededException
, UsrSystemException
) );
142 virtual void flush(void)
143 THROWS( (NotConnectedException
, BufferSizeExceededException
, UsrSystemException
) );
144 virtual void closeOutput(void)
145 THROWS( (NotConnectedException
, BufferSizeExceededException
, UsrSystemException
) );
154 void OFileWriter::writeBytes(const Sequence
< BYTE
>& aData
)
155 THROWS( (NotConnectedException
, BufferSizeExceededException
, UsrSystemException
) )
158 m_f
= fopen( m_pcFile
, "w" );
161 fwrite( aData
.getConstArray() , 1 , aData
.getLen() , m_f
);
166 void OFileWriter::flush(void)
167 THROWS( (NotConnectedException
, BufferSizeExceededException
, UsrSystemException
) )
172 void OFileWriter::closeOutput(void)
173 THROWS( (NotConnectedException
, BufferSizeExceededException
, UsrSystemException
) )
180 class OSaxWriterTest
:
185 OSaxWriterTest( const XMultiServiceFactoryRef
& rFactory
) : m_rFactory( rFactory
)
191 public: // refcounting
192 BOOL
queryInterface( Uik aUik
, XInterfaceRef
& rOut
);
193 void acquire() { OWeakObject::acquire(); }
194 void release() { OWeakObject::release(); }
195 void* getImplementation(Reflection
*p
) { return OWeakObject::getImplementation(p
); }
198 virtual void testInvariant(const UString
& TestName
, const XInterfaceRef
& TestObject
)
199 THROWS( ( IllegalArgumentException
,
200 UsrSystemException
) );
202 virtual INT32
test( const UString
& TestName
,
203 const XInterfaceRef
& TestObject
,
204 INT32 hTestHandle
) THROWS( ( IllegalArgumentException
,
205 UsrSystemException
) );
207 virtual BOOL
testPassed(void) THROWS( ( UsrSystemException
) );
208 virtual Sequence
< UString
> getErrors(void) THROWS( (UsrSystemException
) );
209 virtual Sequence
< UsrAny
> getErrorExceptions(void) THROWS( (UsrSystemException
) );
210 virtual Sequence
< UString
> getWarnings(void) THROWS( (UsrSystemException
) );
213 void testSimple( const XExtendedDocumentHandlerRef
&r
);
214 void testExceptions( const XExtendedDocumentHandlerRef
&r
);
215 void testDTD( const XExtendedDocumentHandlerRef
&r
);
216 void testPerformance( const XExtendedDocumentHandlerRef
&r
);
217 void writeParagraph( const XExtendedDocumentHandlerRef
&r
, const UString
& s
);
220 Sequence
<UsrAny
> m_seqExceptions
;
221 Sequence
<UString
> m_seqErrors
;
222 Sequence
<UString
> m_seqWarnings
;
223 XMultiServiceFactoryRef m_rFactory
;
229 /*----------------------------------------
231 * Attributlist implementation
233 *----------------------------------------*/
234 struct AttributeListImpl_impl
;
235 class AttributeListImpl
:
236 public XAttributeList
,
241 AttributeListImpl( const AttributeListImpl
& );
242 ~AttributeListImpl();
245 BOOL
queryInterface( Uik aUik
, XInterfaceRef
& rOut
);
246 void acquire() { OWeakObject::acquire(); }
247 void release() { OWeakObject::release(); }
248 void* getImplementation(Reflection
*p
) { return OWeakObject::getImplementation(p
); }
251 virtual INT16
getLength(void) THROWS( (UsrSystemException
) );
252 virtual UString
getNameByIndex(INT16 i
) THROWS( (UsrSystemException
) );
253 virtual UString
getTypeByIndex(INT16 i
) THROWS( (UsrSystemException
) );
254 virtual UString
getTypeByName(const UString
& aName
) THROWS( (UsrSystemException
) );
255 virtual UString
getValueByIndex(INT16 i
) THROWS( (UsrSystemException
) );
256 virtual UString
getValueByName(const UString
& aName
) THROWS( (UsrSystemException
) );
259 void addAttribute( const UString
&sName
, const UString
&sType
, const UString
&sValue
);
263 struct AttributeListImpl_impl
*m_pImpl
;
270 TagAttribute( const UString
&sName
, const UString
&sType
, const UString
&sValue
)
274 this->sValue
= sValue
;
282 struct AttributeListImpl_impl
284 AttributeListImpl_impl()
286 // performance improvement during adding
287 vecAttribute
.reserve(20);
289 vector
<struct TagAttribute
> vecAttribute
;
294 INT16
AttributeListImpl::getLength(void) THROWS( (UsrSystemException
) )
296 return m_pImpl
->vecAttribute
.size();
300 AttributeListImpl::AttributeListImpl( const AttributeListImpl
&r
)
302 m_pImpl
= new AttributeListImpl_impl
;
303 *m_pImpl
= *(r
.m_pImpl
);
306 UString
AttributeListImpl::getNameByIndex(INT16 i
) THROWS( (UsrSystemException
) )
308 if( i
< m_pImpl
->vecAttribute
.size() ) {
309 return m_pImpl
->vecAttribute
[i
].sName
;
315 UString
AttributeListImpl::getTypeByIndex(INT16 i
) THROWS( (UsrSystemException
) )
317 if( i
< m_pImpl
->vecAttribute
.size() ) {
318 return m_pImpl
->vecAttribute
[i
].sType
;
323 UString
AttributeListImpl::getValueByIndex(INT16 i
) THROWS( (UsrSystemException
) )
325 if( i
< m_pImpl
->vecAttribute
.size() ) {
326 return m_pImpl
->vecAttribute
[i
].sValue
;
332 UString
AttributeListImpl::getTypeByName( const UString
& sName
) THROWS( (UsrSystemException
) )
334 vector
<struct TagAttribute
>::iterator ii
= m_pImpl
->vecAttribute
.begin();
336 for( ; ii
!= m_pImpl
->vecAttribute
.end() ; ii
++ ) {
337 if( (*ii
).sName
== sName
) {
344 UString
AttributeListImpl::getValueByName(const UString
& sName
) THROWS( (UsrSystemException
) )
346 vector
<struct TagAttribute
>::iterator ii
= m_pImpl
->vecAttribute
.begin();
348 for( ; ii
!= m_pImpl
->vecAttribute
.end() ; ii
++ ) {
349 if( (*ii
).sName
== sName
) {
357 BOOL
AttributeListImpl::queryInterface( Uik aUik
, XInterfaceRef
& rOut
)
359 if( aUik
== XAttributeList::getSmartUik() ) {
360 rOut
= (XAttributeList
* )this;
363 return OWeakObject::queryInterface( aUik
, rOut
);
369 AttributeListImpl::AttributeListImpl()
371 m_pImpl
= new AttributeListImpl_impl
;
376 AttributeListImpl::~AttributeListImpl()
382 void AttributeListImpl::addAttribute( const UString
&sName
,
383 const UString
&sType
,
384 const UString
&sValue
)
386 m_pImpl
->vecAttribute
.push_back( TagAttribute( sName
, sType
, sValue
) );
389 void AttributeListImpl::clear()
391 vector
<struct TagAttribute
> dummy
;
392 m_pImpl
->vecAttribute
.swap( dummy
);
394 OSL_ASSERT( ! getLength() );
408 * for external binding
412 XInterfaceRef
OSaxWriterTest_CreateInstance( const XMultiServiceFactoryRef
& rSMgr
) THROWS((Exception
))
414 OSaxWriterTest
*p
= new OSaxWriterTest( rSMgr
);
415 XInterfaceRef xService
= *p
;
419 UString
OSaxWriterTest_getServiceName( ) THROWS( () )
421 return L
"test.com.sun.star.xml.sax.Writer";
424 UString
OSaxWriterTest_getImplementationName( ) THROWS( () )
426 return L
"test.extensions.xml.sax.Writer";
429 Sequence
<UString
> OSaxWriterTest_getSupportedServiceNames( ) THROWS( () )
431 Sequence
<UString
> aRet(1);
433 aRet
.getArray()[0] = OSaxWriterTest_getImplementationName( );
439 BOOL
OSaxWriterTest::queryInterface( Uik uik
, XInterfaceRef
&rOut
)
441 if( XSimpleTest::getSmartUik() == uik
) {
442 rOut
= (XSimpleTest
*) this;
445 return OWeakObject::queryInterface( uik
, rOut
);
451 void OSaxWriterTest::testInvariant( const UString
& TestName
, const XInterfaceRef
& TestObject
)
452 THROWS( ( IllegalArgumentException
,
453 UsrSystemException
) )
455 if( L
"com.sun.star.xml.sax.Writer" == TestName
) {
456 XDocumentHandlerRef
doc( TestObject
, USR_QUERY
);
457 XExtendedDocumentHandlerRef
ext( TestObject
, USR_QUERY
);
458 XActiveDataSourceRef
source( TestObject
, USR_QUERY
);
460 ERROR_ASSERT( doc
.is() , "XDocumentHandler cannot be queried" );
461 ERROR_ASSERT( ext
.is() , "XExtendedDocumentHandler cannot be queried" );
462 ERROR_ASSERT( source
.is() , "XActiveDataSource cannot be queried" );
465 BUILD_ERROR( 0 , "wrong test" );
470 INT32
OSaxWriterTest::test( const UString
& TestName
,
471 const XInterfaceRef
& TestObject
,
472 INT32 hTestHandle
) THROWS( ( IllegalArgumentException
,
473 UsrSystemException
) )
475 if( L
"com.sun.star.xml.sax.Writer" == TestName
) {
477 if( 0 == hTestHandle
) {
478 testInvariant( TestName
, TestObject
);
482 XExtendedDocumentHandlerRef
writer( TestObject
, USR_QUERY
);
484 if( 1 == hTestHandle
) {
485 testSimple( writer
);
487 else if( 2 == hTestHandle
) {
488 testExceptions( writer
);
490 else if( 3 == hTestHandle
) {
493 else if( 4 == hTestHandle
) {
494 testPerformance( writer
);
498 catch( Exception
& e
) {
499 BUILD_ERROR( 0 , UStringToString( e
.getName() , CHARSET_SYSTEM
).GetCharStr() );
502 BUILD_ERROR( 0 , "unknown exception (Exception is not base class)" );
507 if( hTestHandle
>= 5) {
508 // all tests finished.
513 BUILD_ERROR( 0 , "service not supported by test." );
520 BOOL
OSaxWriterTest::testPassed(void) THROWS( (UsrSystemException
) )
522 return m_seqErrors
.getLen() == 0;
526 Sequence
< UString
> OSaxWriterTest::getErrors(void) THROWS( (UsrSystemException
) )
532 Sequence
< UsrAny
> OSaxWriterTest::getErrorExceptions(void) THROWS( (UsrSystemException
) )
534 return m_seqExceptions
;
538 Sequence
< UString
> OSaxWriterTest::getWarnings(void) THROWS( (UsrSystemException
) )
540 return m_seqWarnings
;
543 void OSaxWriterTest::writeParagraph( const XExtendedDocumentHandlerRef
&r
, const UString
& s
)
548 Sequence
<UINT16
> seq( s
.len() );
549 memcpy( seq
.getArray() , s
.getStr() , s
.len() * sizeof( UINT16
) );
551 for( int n
= 1 ; n
< nMax
; n
++ ){
552 if( 32 == seq
.getArray()[n
] ) {
554 r
->characters( s
.copy( nStart
, n
- nStart
) );
559 r
->characters( s
.copy( nStart
, n
- nStart
) );
566 void OSaxWriterTest::testSimple( const XExtendedDocumentHandlerRef
&r
)
568 UString testParagraph
= L
"Dies ist ein bloeder Test um zu uberpruefen, ob der SAXWriter "
569 L
"wohl Zeilenumbrueche halbwegs richtig macht oder ob er die Zeile "
570 L
"bis zum bitteren Ende schreibt.";
572 OFileWriter
*pw
= new OFileWriter("output.xml");
573 AttributeListImpl
*pList
= new AttributeListImpl
;
575 XAttributeListRef
rList( (XAttributeList
*) pList
, USR_QUERY
);
576 XOutputStreamRef
ref( ( XOutputStream
* ) pw
, USR_QUERY
);
578 XActiveDataSourceRef
source( r
, USR_QUERY
);
580 ERROR_ASSERT( ref
.is() , "no output stream" );
581 ERROR_ASSERT( source
.is() , "no active data source" );
583 source
->setOutputStream( ref
);
587 pList
->addAttribute( L
"Arg1" , L
"CDATA" , L
"bla\n u" );
588 pList
->addAttribute( L
"Arg2" , L
"CDATA" , L
"blub" );
590 r
->startElement( L
"tag1" , rList
);
591 r
->ignorableWhitespace( L
"" );
593 r
->characters( L
"huhu" );
594 r
->ignorableWhitespace( L
"" );
596 r
->startElement( L
"hi" , rList
);
597 r
->ignorableWhitespace( L
"" );
599 // the enpassant must be converted & -> &
600 r
->characters( L
"ü" );
602 // Test added for mib. Tests if errors during conversions occurs
603 r
->ignorableWhitespace( UString() );
605 for( sal_Int32 n
= 32 ; n
< 254 ; n
++ ) {
610 StringToUString( array
, RTL_TEXTENCODING_SYMBOL
)
612 r
->ignorableWhitespace( UString() );
614 // '>' must not be converted
616 r
->characters( L
">fsfsdf<" );
618 r
->ignorableWhitespace( UString() );
620 writeParagraph( r
, testParagraph
);
623 r
->ignorableWhitespace( UString() );
624 r
->comment( L
"Dies ist ein Kommentar !" );
625 r
->ignorableWhitespace( UString() );
627 r
->startElement( L
"emptytagtest" , rList
);
628 r
->endElement( L
"emptytagtest" );
630 r
->endElement( L
"hi" );
631 r
->ignorableWhitespace( L
"" );
633 r
->endElement( L
"tag1" );
638 void OSaxWriterTest::testExceptions( const XExtendedDocumentHandlerRef
& r
)
641 OFileWriter
*pw
= new OFileWriter("output2.xml");
642 AttributeListImpl
*pList
= new AttributeListImpl
;
644 XAttributeListRef
rList( (XAttributeList
*) pList
, USR_QUERY
);
645 XOutputStreamRef
ref( ( XOutputStream
* ) pw
, USR_QUERY
);
647 XActiveDataSourceRef
source( r
, USR_QUERY
);
649 ERROR_ASSERT( ref
.is() , "no output stream" );
650 ERROR_ASSERT( source
.is() , "no active data source" );
652 source
->setOutputStream( ref
);
654 { // startDocument must be called before start element
655 BOOL bException
= TRUE
;
657 r
->startElement( L
"huhu" , rList
);
660 catch( SAXException
& e
) {
663 ERROR_ASSERT( bException
, "expected exception not thrown !" );
668 r
->startElement( L
"huhu" , rList
);
672 BOOL bException
= TRUE
;
674 r
->startElement( L
"huhu" , rList
);
677 catch( SAXException
& e
) {
680 ERROR_ASSERT( bException
, "expected exception not thrown !" );
684 r
->endElement( L
"hi" );
690 void OSaxWriterTest::testDTD(const XExtendedDocumentHandlerRef
&r
)
692 OFileWriter
*pw
= new OFileWriter("outputDTD.xml");
693 AttributeListImpl
*pList
= new AttributeListImpl
;
695 XAttributeListRef
rList( (XAttributeList
*) pList
, USR_QUERY
);
696 XOutputStreamRef
ref( ( XOutputStream
* ) pw
, USR_QUERY
);
698 XActiveDataSourceRef
source( r
, USR_QUERY
);
700 ERROR_ASSERT( ref
.is() , "no output stream" );
701 ERROR_ASSERT( source
.is() , "no active data source" );
703 source
->setOutputStream( ref
);
707 r
->unknown( L
"<!DOCTYPE iCalendar >\n" );
708 r
->startElement( L
"huhu" , rList
);
710 r
->endElement( L
"huhu" );
714 void OSaxWriterTest::testPerformance(const XExtendedDocumentHandlerRef
&r
)
716 OFileWriter
*pw
= new OFileWriter("testPerformance.xml");
717 AttributeListImpl
*pList
= new AttributeListImpl
;
719 UString testParagraph
= L
"Dies ist ein bloeder Test um zu uberpruefen, ob der SAXWriter "
720 L
"wohl > Zeilenumbrueche halbwegs richtig macht oder ob er die Zeile "
721 L
"bis zum bitteren Ende schreibt.";
724 XAttributeListRef
rList( (XAttributeList
*) pList
, USR_QUERY
);
725 XOutputStreamRef
ref( ( XOutputStream
* ) pw
, USR_QUERY
);
727 XActiveDataSourceRef
source( r
, USR_QUERY
);
729 ERROR_ASSERT( ref
.is() , "no output stream" );
730 ERROR_ASSERT( source
.is() , "no active data source" );
732 source
->setOutputStream( ref
);
734 TimeValue aStartTime
, aEndTime
;
735 osl_getSystemTime( &aStartTime
);
739 // just write a bunch of xml tags !
740 // for performance testing
742 for( i2
= 0 ; i2
< 15 ; i2
++ )
744 r
->startElement( UString( L
"tag" ) + UString::valueOf( i2
), rList
);
745 for( sal_Int32 i
= 0 ; i
< 450 ; i
++ )
747 r
->ignorableWhitespace( L
"");
748 r
->startElement( L
"huhu" , rList
);
749 r
->characters( testParagraph
);
750 // writeParagraph( r , testParagraph );
752 r
->ignorableWhitespace( L
"");
753 r
->endElement( L
"huhu" );
756 for( i2
= 14 ; i2
>= 0 ; i2
-- )
758 r
->ignorableWhitespace( L
"");
759 r
->endElement( UString( L
"tag" ) + UString::valueOf( i2
) );
764 osl_getSystemTime( &aEndTime
);
766 double fStart
= (double)aStartTime
.Seconds
+ ((double)aStartTime
.Nanosec
/ 1000000000.0);
767 double fEnd
= (double)aEndTime
.Seconds
+ ((double)aEndTime
.Nanosec
/ 1000000000.0);
769 printf( "Performance writing : %g s\n" , fEnd
- fStart
);
772 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */