1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_extensions.hxx"
31 //#include <tools/presys.h>
33 //#include <tools/postsys.h>
34 #include <smart/com/sun/star/test/XSimpleTest.hxx>
35 #include <smart/com/sun/star/lang/XMultiServiceFactory.hxx> // for the multiservice-factories
39 #include <smart/com/sun/star/io/XActiveDataSource.hxx>
40 #include <smart/com/sun/star/io/XOutputStream.hxx>
41 #include <smart/com/sun/star/xml/sax/SAXParseException.hxx>
42 #include <smart/com/sun/star/xml/sax/XParser.hxx>
43 #include <smart/com/sun/star/xml/sax/XExtendedDocumentHandler.hxx>
45 #include <rtl/wstring.hxx>
47 #include <usr/weak.hxx>
48 #include <tools/string.hxx>
50 #include <usr/factoryhlp.hxx>
52 #include <usr/reflserv.hxx> // for EXTERN_SERVICE_CALLTYPE
59 #define BUILD_ERROR(expr, Message)\
61 m_seqErrors.realloc( m_seqErrors.getLen() + 1 ); \
62 m_seqExceptions.realloc( m_seqExceptions.getLen() + 1 ); \
73 m_seqErrors.getArray()[ m_seqErrors.getLen()-1] = StringToUString( str , CHARSET_SYSTEM ); \
78 #define WARNING_ASSERT(expr, Message) \
80 m_seqWarnings.realloc( m_seqErrors.getLen() +1 ); \
91 m_seqWarnings.getArray()[ m_seqWarnings.getLen()-1] = StringToUString( str , CHARSET_SYSTEM ); \
96 #define ERROR_ASSERT(expr, Message) \
98 BUILD_ERROR(expr, Message );\
103 #define ERROR_EXCEPTION_ASSERT(expr, Message, Exception) \
105 BUILD_ERROR(expr,Message);\
106 m_seqExceptions.getArray()[ m_seqExceptions.getLen()-1] = UsrAny( Exception );\
120 public XOutputStream
,
124 OFileWriter( char *pcFile
) { strcpy( m_pcFile
, pcFile
); m_f
= 0; }
127 public: // refcounting
128 BOOL
queryInterface( Uik aUik
, XInterfaceRef
& rOut
)
130 if( XOutputStream::getSmartUik() == aUik
) {
131 rOut
= (XOutputStream
*) this;
133 else return OWeakObject::queryInterface( aUik
, rOut
);
137 void acquire() { OWeakObject::acquire(); }
138 void release() { OWeakObject::release(); }
139 void* getImplementation(Reflection
*p
) { return OWeakObject::getImplementation(p
); }
142 virtual void writeBytes(const Sequence
< BYTE
>& aData
)
143 THROWS( (NotConnectedException
, BufferSizeExceededException
, UsrSystemException
) );
144 virtual void flush(void)
145 THROWS( (NotConnectedException
, BufferSizeExceededException
, UsrSystemException
) );
146 virtual void closeOutput(void)
147 THROWS( (NotConnectedException
, BufferSizeExceededException
, UsrSystemException
) );
156 void OFileWriter::writeBytes(const Sequence
< BYTE
>& aData
)
157 THROWS( (NotConnectedException
, BufferSizeExceededException
, UsrSystemException
) )
160 m_f
= fopen( m_pcFile
, "w" );
163 fwrite( aData
.getConstArray() , 1 , aData
.getLen() , m_f
);
168 void OFileWriter::flush(void)
169 THROWS( (NotConnectedException
, BufferSizeExceededException
, UsrSystemException
) )
174 void OFileWriter::closeOutput(void)
175 THROWS( (NotConnectedException
, BufferSizeExceededException
, UsrSystemException
) )
182 class OSaxWriterTest
:
187 OSaxWriterTest( const XMultiServiceFactoryRef
& rFactory
) : m_rFactory( rFactory
)
193 public: // refcounting
194 BOOL
queryInterface( Uik aUik
, XInterfaceRef
& rOut
);
195 void acquire() { OWeakObject::acquire(); }
196 void release() { OWeakObject::release(); }
197 void* getImplementation(Reflection
*p
) { return OWeakObject::getImplementation(p
); }
200 virtual void testInvariant(const UString
& TestName
, const XInterfaceRef
& TestObject
)
201 THROWS( ( IllegalArgumentException
,
202 UsrSystemException
) );
204 virtual INT32
test( const UString
& TestName
,
205 const XInterfaceRef
& TestObject
,
206 INT32 hTestHandle
) THROWS( ( IllegalArgumentException
,
207 UsrSystemException
) );
209 virtual BOOL
testPassed(void) THROWS( ( UsrSystemException
) );
210 virtual Sequence
< UString
> getErrors(void) THROWS( (UsrSystemException
) );
211 virtual Sequence
< UsrAny
> getErrorExceptions(void) THROWS( (UsrSystemException
) );
212 virtual Sequence
< UString
> getWarnings(void) THROWS( (UsrSystemException
) );
215 void testSimple( const XExtendedDocumentHandlerRef
&r
);
216 void testExceptions( const XExtendedDocumentHandlerRef
&r
);
217 void testDTD( const XExtendedDocumentHandlerRef
&r
);
218 void testPerformance( const XExtendedDocumentHandlerRef
&r
);
219 void writeParagraph( const XExtendedDocumentHandlerRef
&r
, const UString
& s
);
222 Sequence
<UsrAny
> m_seqExceptions
;
223 Sequence
<UString
> m_seqErrors
;
224 Sequence
<UString
> m_seqWarnings
;
225 XMultiServiceFactoryRef m_rFactory
;
231 /*----------------------------------------
233 * Attributlist implementation
235 *----------------------------------------*/
236 struct AttributeListImpl_impl
;
237 class AttributeListImpl
:
238 public XAttributeList
,
243 AttributeListImpl( const AttributeListImpl
& );
244 ~AttributeListImpl();
247 BOOL
queryInterface( Uik aUik
, XInterfaceRef
& rOut
);
248 void acquire() { OWeakObject::acquire(); }
249 void release() { OWeakObject::release(); }
250 void* getImplementation(Reflection
*p
) { return OWeakObject::getImplementation(p
); }
253 virtual INT16
getLength(void) THROWS( (UsrSystemException
) );
254 virtual UString
getNameByIndex(INT16 i
) THROWS( (UsrSystemException
) );
255 virtual UString
getTypeByIndex(INT16 i
) THROWS( (UsrSystemException
) );
256 virtual UString
getTypeByName(const UString
& aName
) THROWS( (UsrSystemException
) );
257 virtual UString
getValueByIndex(INT16 i
) THROWS( (UsrSystemException
) );
258 virtual UString
getValueByName(const UString
& aName
) THROWS( (UsrSystemException
) );
261 void addAttribute( const UString
&sName
, const UString
&sType
, const UString
&sValue
);
265 struct AttributeListImpl_impl
*m_pImpl
;
272 TagAttribute( const UString
&sName
, const UString
&sType
, const UString
&sValue
)
276 this->sValue
= sValue
;
284 struct AttributeListImpl_impl
286 AttributeListImpl_impl()
288 // performance improvement during adding
289 vecAttribute
.reserve(20);
291 vector
<struct TagAttribute
> vecAttribute
;
296 INT16
AttributeListImpl::getLength(void) THROWS( (UsrSystemException
) )
298 return m_pImpl
->vecAttribute
.size();
302 AttributeListImpl::AttributeListImpl( const AttributeListImpl
&r
)
304 m_pImpl
= new AttributeListImpl_impl
;
305 *m_pImpl
= *(r
.m_pImpl
);
308 UString
AttributeListImpl::getNameByIndex(INT16 i
) THROWS( (UsrSystemException
) )
310 if( i
< m_pImpl
->vecAttribute
.size() ) {
311 return m_pImpl
->vecAttribute
[i
].sName
;
317 UString
AttributeListImpl::getTypeByIndex(INT16 i
) THROWS( (UsrSystemException
) )
319 if( i
< m_pImpl
->vecAttribute
.size() ) {
320 return m_pImpl
->vecAttribute
[i
].sType
;
325 UString
AttributeListImpl::getValueByIndex(INT16 i
) THROWS( (UsrSystemException
) )
327 if( i
< m_pImpl
->vecAttribute
.size() ) {
328 return m_pImpl
->vecAttribute
[i
].sValue
;
334 UString
AttributeListImpl::getTypeByName( const UString
& sName
) THROWS( (UsrSystemException
) )
336 vector
<struct TagAttribute
>::iterator ii
= m_pImpl
->vecAttribute
.begin();
338 for( ; ii
!= m_pImpl
->vecAttribute
.end() ; ii
++ ) {
339 if( (*ii
).sName
== sName
) {
346 UString
AttributeListImpl::getValueByName(const UString
& sName
) THROWS( (UsrSystemException
) )
348 vector
<struct TagAttribute
>::iterator ii
= m_pImpl
->vecAttribute
.begin();
350 for( ; ii
!= m_pImpl
->vecAttribute
.end() ; ii
++ ) {
351 if( (*ii
).sName
== sName
) {
359 BOOL
AttributeListImpl::queryInterface( Uik aUik
, XInterfaceRef
& rOut
)
361 if( aUik
== XAttributeList::getSmartUik() ) {
362 rOut
= (XAttributeList
* )this;
365 return OWeakObject::queryInterface( aUik
, rOut
);
371 AttributeListImpl::AttributeListImpl()
373 m_pImpl
= new AttributeListImpl_impl
;
378 AttributeListImpl::~AttributeListImpl()
384 void AttributeListImpl::addAttribute( const UString
&sName
,
385 const UString
&sType
,
386 const UString
&sValue
)
388 m_pImpl
->vecAttribute
.push_back( TagAttribute( sName
, sType
, sValue
) );
391 void AttributeListImpl::clear()
393 vector
<struct TagAttribute
> dummy
;
394 m_pImpl
->vecAttribute
.swap( dummy
);
396 OSL_ASSERT( ! getLength() );
410 * for external binding
414 XInterfaceRef
OSaxWriterTest_CreateInstance( const XMultiServiceFactoryRef
& rSMgr
) THROWS((Exception
))
416 OSaxWriterTest
*p
= new OSaxWriterTest( rSMgr
);
417 XInterfaceRef xService
= *p
;
421 UString
OSaxWriterTest_getServiceName( ) THROWS( () )
423 return L
"test.com.sun.star.xml.sax.Writer";
426 UString
OSaxWriterTest_getImplementationName( ) THROWS( () )
428 return L
"test.extensions.xml.sax.Writer";
431 Sequence
<UString
> OSaxWriterTest_getSupportedServiceNames( ) THROWS( () )
433 Sequence
<UString
> aRet(1);
435 aRet
.getArray()[0] = OSaxWriterTest_getImplementationName( );
441 BOOL
OSaxWriterTest::queryInterface( Uik uik
, XInterfaceRef
&rOut
)
443 if( XSimpleTest::getSmartUik() == uik
) {
444 rOut
= (XSimpleTest
*) this;
447 return OWeakObject::queryInterface( uik
, rOut
);
453 void OSaxWriterTest::testInvariant( const UString
& TestName
, const XInterfaceRef
& TestObject
)
454 THROWS( ( IllegalArgumentException
,
455 UsrSystemException
) )
457 if( L
"com.sun.star.xml.sax.Writer" == TestName
) {
458 XDocumentHandlerRef
doc( TestObject
, USR_QUERY
);
459 XExtendedDocumentHandlerRef
ext( TestObject
, USR_QUERY
);
460 XActiveDataSourceRef
source( TestObject
, USR_QUERY
);
462 ERROR_ASSERT( doc
.is() , "XDocumentHandler cannot be queried" );
463 ERROR_ASSERT( ext
.is() , "XExtendedDocumentHandler cannot be queried" );
464 ERROR_ASSERT( source
.is() , "XActiveDataSource cannot be queried" );
467 BUILD_ERROR( 0 , "wrong test" );
472 INT32
OSaxWriterTest::test( const UString
& TestName
,
473 const XInterfaceRef
& TestObject
,
474 INT32 hTestHandle
) THROWS( ( IllegalArgumentException
,
475 UsrSystemException
) )
477 if( L
"com.sun.star.xml.sax.Writer" == TestName
) {
479 if( 0 == hTestHandle
) {
480 testInvariant( TestName
, TestObject
);
484 XExtendedDocumentHandlerRef
writer( TestObject
, USR_QUERY
);
486 if( 1 == hTestHandle
) {
487 testSimple( writer
);
489 else if( 2 == hTestHandle
) {
490 testExceptions( writer
);
492 else if( 3 == hTestHandle
) {
495 else if( 4 == hTestHandle
) {
496 testPerformance( writer
);
500 catch( Exception
& e
) {
501 BUILD_ERROR( 0 , UStringToString( e
.getName() , CHARSET_SYSTEM
).GetCharStr() );
504 BUILD_ERROR( 0 , "unknown exception (Exception is not base class)" );
509 if( hTestHandle
>= 5) {
510 // all tests finished.
515 BUILD_ERROR( 0 , "service not supported by test." );
522 BOOL
OSaxWriterTest::testPassed(void) THROWS( (UsrSystemException
) )
524 return m_seqErrors
.getLen() == 0;
528 Sequence
< UString
> OSaxWriterTest::getErrors(void) THROWS( (UsrSystemException
) )
534 Sequence
< UsrAny
> OSaxWriterTest::getErrorExceptions(void) THROWS( (UsrSystemException
) )
536 return m_seqExceptions
;
540 Sequence
< UString
> OSaxWriterTest::getWarnings(void) THROWS( (UsrSystemException
) )
542 return m_seqWarnings
;
545 void OSaxWriterTest::writeParagraph( const XExtendedDocumentHandlerRef
&r
, const UString
& s
)
550 Sequence
<UINT16
> seq( s
.len() );
551 memcpy( seq
.getArray() , s
.getStr() , s
.len() * sizeof( UINT16
) );
553 for( int n
= 1 ; n
< nMax
; n
++ ){
554 if( 32 == seq
.getArray()[n
] ) {
556 r
->characters( s
.copy( nStart
, n
- nStart
) );
561 r
->characters( s
.copy( nStart
, n
- nStart
) );
568 void OSaxWriterTest::testSimple( const XExtendedDocumentHandlerRef
&r
)
570 UString testParagraph
= L
"Dies ist ein bloeder Test um zu uberpruefen, ob der SAXWriter "
571 L
"wohl Zeilenumbrueche halbwegs richtig macht oder ob er die Zeile "
572 L
"bis zum bitteren Ende schreibt.";
574 OFileWriter
*pw
= new OFileWriter("output.xml");
575 AttributeListImpl
*pList
= new AttributeListImpl
;
577 XAttributeListRef
rList( (XAttributeList
*) pList
, USR_QUERY
);
578 XOutputStreamRef
ref( ( XOutputStream
* ) pw
, USR_QUERY
);
580 XActiveDataSourceRef
source( r
, USR_QUERY
);
582 ERROR_ASSERT( ref
.is() , "no output stream" );
583 ERROR_ASSERT( source
.is() , "no active data source" );
585 source
->setOutputStream( ref
);
589 pList
->addAttribute( L
"Arg1" , L
"CDATA" , L
"bla\n u" );
590 pList
->addAttribute( L
"Arg2" , L
"CDATA" , L
"blub" );
592 r
->startElement( L
"tag1" , rList
);
593 r
->ignorableWhitespace( L
"" );
595 r
->characters( L
"huhu" );
596 r
->ignorableWhitespace( L
"" );
598 r
->startElement( L
"hi" , rList
);
599 r
->ignorableWhitespace( L
"" );
601 // the enpassant must be converted & -> &
602 r
->characters( L
"ü" );
604 // Test added for mib. Tests if errors during conversions occurs
605 r
->ignorableWhitespace( UString() );
607 for( sal_Int32 n
= 32 ; n
< 254 ; n
++ ) {
612 StringToUString( array
, RTL_TEXTENCODING_SYMBOL
)
614 r
->ignorableWhitespace( UString() );
616 // '>' must not be converted
618 r
->characters( L
">fsfsdf<" );
620 r
->ignorableWhitespace( UString() );
622 writeParagraph( r
, testParagraph
);
625 r
->ignorableWhitespace( UString() );
626 r
->comment( L
"Dies ist ein Kommentar !" );
627 r
->ignorableWhitespace( UString() );
629 r
->startElement( L
"emptytagtest" , rList
);
630 r
->endElement( L
"emptytagtest" );
632 r
->endElement( L
"hi" );
633 r
->ignorableWhitespace( L
"" );
635 r
->endElement( L
"tag1" );
640 void OSaxWriterTest::testExceptions( const XExtendedDocumentHandlerRef
& r
)
643 OFileWriter
*pw
= new OFileWriter("output2.xml");
644 AttributeListImpl
*pList
= new AttributeListImpl
;
646 XAttributeListRef
rList( (XAttributeList
*) pList
, USR_QUERY
);
647 XOutputStreamRef
ref( ( XOutputStream
* ) pw
, USR_QUERY
);
649 XActiveDataSourceRef
source( r
, USR_QUERY
);
651 ERROR_ASSERT( ref
.is() , "no output stream" );
652 ERROR_ASSERT( source
.is() , "no active data source" );
654 source
->setOutputStream( ref
);
656 { // startDocument must be called before start element
657 BOOL bException
= TRUE
;
659 r
->startElement( L
"huhu" , rList
);
662 catch( SAXException
& e
) {
665 ERROR_ASSERT( bException
, "expected exception not thrown !" );
670 r
->startElement( L
"huhu" , rList
);
674 BOOL bException
= TRUE
;
676 r
->startElement( L
"huhu" , rList
);
679 catch( SAXException
& e
) {
682 ERROR_ASSERT( bException
, "expected exception not thrown !" );
686 r
->endElement( L
"hi" );
692 void OSaxWriterTest::testDTD(const XExtendedDocumentHandlerRef
&r
)
694 OFileWriter
*pw
= new OFileWriter("outputDTD.xml");
695 AttributeListImpl
*pList
= new AttributeListImpl
;
697 XAttributeListRef
rList( (XAttributeList
*) pList
, USR_QUERY
);
698 XOutputStreamRef
ref( ( XOutputStream
* ) pw
, USR_QUERY
);
700 XActiveDataSourceRef
source( r
, USR_QUERY
);
702 ERROR_ASSERT( ref
.is() , "no output stream" );
703 ERROR_ASSERT( source
.is() , "no active data source" );
705 source
->setOutputStream( ref
);
709 r
->unknown( L
"<!DOCTYPE iCalendar >\n" );
710 r
->startElement( L
"huhu" , rList
);
712 r
->endElement( L
"huhu" );
716 void OSaxWriterTest::testPerformance(const XExtendedDocumentHandlerRef
&r
)
718 OFileWriter
*pw
= new OFileWriter("testPerformance.xml");
719 AttributeListImpl
*pList
= new AttributeListImpl
;
721 UString testParagraph
= L
"Dies ist ein bloeder Test um zu uberpruefen, ob der SAXWriter "
722 L
"wohl > Zeilenumbrueche halbwegs richtig macht oder ob er die Zeile "
723 L
"bis zum bitteren Ende schreibt.";
726 XAttributeListRef
rList( (XAttributeList
*) pList
, USR_QUERY
);
727 XOutputStreamRef
ref( ( XOutputStream
* ) pw
, USR_QUERY
);
729 XActiveDataSourceRef
source( r
, USR_QUERY
);
731 ERROR_ASSERT( ref
.is() , "no output stream" );
732 ERROR_ASSERT( source
.is() , "no active data source" );
734 source
->setOutputStream( ref
);
736 TimeValue aStartTime
, aEndTime
;
737 osl_getSystemTime( &aStartTime
);
741 // just write a bunch of xml tags !
742 // for performance testing
744 for( i2
= 0 ; i2
< 15 ; i2
++ )
746 r
->startElement( UString( L
"tag" ) + UString::valueOf( i2
), rList
);
747 for( sal_Int32 i
= 0 ; i
< 450 ; i
++ )
749 r
->ignorableWhitespace( L
"");
750 r
->startElement( L
"huhu" , rList
);
751 r
->characters( testParagraph
);
752 // writeParagraph( r , testParagraph );
754 r
->ignorableWhitespace( L
"");
755 r
->endElement( L
"huhu" );
758 for( i2
= 14 ; i2
>= 0 ; i2
-- )
760 r
->ignorableWhitespace( L
"");
761 r
->endElement( UString( L
"tag" ) + UString::valueOf( i2
) );
766 osl_getSystemTime( &aEndTime
);
768 double fStart
= (double)aStartTime
.Seconds
+ ((double)aStartTime
.Nanosec
/ 1000000000.0);
769 double fEnd
= (double)aEndTime
.Seconds
+ ((double)aEndTime
.Nanosec
/ 1000000000.0);
771 printf( "Performance writing : %g s\n" , fEnd
- fStart
);