1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: testwriter.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_extensions.hxx"
34 //#include <tools/presys.h>
36 //#include <tools/postsys.h>
37 #include <smart/com/sun/star/test/XSimpleTest.hxx>
38 #include <smart/com/sun/star/lang/XMultiServiceFactory.hxx> // for the multiservice-factories
42 #include <smart/com/sun/star/io/XActiveDataSource.hxx>
43 #include <smart/com/sun/star/io/XOutputStream.hxx>
44 #include <smart/com/sun/star/xml/sax/SAXParseException.hxx>
45 #include <smart/com/sun/star/xml/sax/XParser.hxx>
46 #include <smart/com/sun/star/xml/sax/XExtendedDocumentHandler.hxx>
48 #include <rtl/wstring.hxx>
50 #include <usr/weak.hxx>
51 #include <tools/string.hxx>
53 #if OSL_DEBUG_LEVEL == 0
58 #include <usr/factoryhlp.hxx>
60 #include <usr/reflserv.hxx> // for EXTERN_SERVICE_CALLTYPE
67 #define BUILD_ERROR(expr, Message)\
69 m_seqErrors.realloc( m_seqErrors.getLen() + 1 ); \
70 m_seqExceptions.realloc( m_seqExceptions.getLen() + 1 ); \
81 m_seqErrors.getArray()[ m_seqErrors.getLen()-1] = StringToUString( str , CHARSET_SYSTEM ); \
86 #define WARNING_ASSERT(expr, Message) \
88 m_seqWarnings.realloc( m_seqErrors.getLen() +1 ); \
99 m_seqWarnings.getArray()[ m_seqWarnings.getLen()-1] = StringToUString( str , CHARSET_SYSTEM ); \
104 #define ERROR_ASSERT(expr, Message) \
106 BUILD_ERROR(expr, Message );\
111 #define ERROR_EXCEPTION_ASSERT(expr, Message, Exception) \
113 BUILD_ERROR(expr,Message);\
114 m_seqExceptions.getArray()[ m_seqExceptions.getLen()-1] = UsrAny( Exception );\
128 public XOutputStream
,
132 OFileWriter( char *pcFile
) { strcpy( m_pcFile
, pcFile
); m_f
= 0; }
135 public: // refcounting
136 BOOL
queryInterface( Uik aUik
, XInterfaceRef
& rOut
)
138 if( XOutputStream::getSmartUik() == aUik
) {
139 rOut
= (XOutputStream
*) this;
141 else return OWeakObject::queryInterface( aUik
, rOut
);
145 void acquire() { OWeakObject::acquire(); }
146 void release() { OWeakObject::release(); }
147 void* getImplementation(Reflection
*p
) { return OWeakObject::getImplementation(p
); }
150 virtual void writeBytes(const Sequence
< BYTE
>& aData
)
151 THROWS( (NotConnectedException
, BufferSizeExceededException
, UsrSystemException
) );
152 virtual void flush(void)
153 THROWS( (NotConnectedException
, BufferSizeExceededException
, UsrSystemException
) );
154 virtual void closeOutput(void)
155 THROWS( (NotConnectedException
, BufferSizeExceededException
, UsrSystemException
) );
164 void OFileWriter::writeBytes(const Sequence
< BYTE
>& aData
)
165 THROWS( (NotConnectedException
, BufferSizeExceededException
, UsrSystemException
) )
168 m_f
= fopen( m_pcFile
, "w" );
171 fwrite( aData
.getConstArray() , 1 , aData
.getLen() , m_f
);
176 void OFileWriter::flush(void)
177 THROWS( (NotConnectedException
, BufferSizeExceededException
, UsrSystemException
) )
182 void OFileWriter::closeOutput(void)
183 THROWS( (NotConnectedException
, BufferSizeExceededException
, UsrSystemException
) )
190 class OSaxWriterTest
:
195 OSaxWriterTest( const XMultiServiceFactoryRef
& rFactory
) : m_rFactory( rFactory
)
201 public: // refcounting
202 BOOL
queryInterface( Uik aUik
, XInterfaceRef
& rOut
);
203 void acquire() { OWeakObject::acquire(); }
204 void release() { OWeakObject::release(); }
205 void* getImplementation(Reflection
*p
) { return OWeakObject::getImplementation(p
); }
208 virtual void testInvariant(const UString
& TestName
, const XInterfaceRef
& TestObject
)
209 THROWS( ( IllegalArgumentException
,
210 UsrSystemException
) );
212 virtual INT32
test( const UString
& TestName
,
213 const XInterfaceRef
& TestObject
,
214 INT32 hTestHandle
) THROWS( ( IllegalArgumentException
,
215 UsrSystemException
) );
217 virtual BOOL
testPassed(void) THROWS( ( UsrSystemException
) );
218 virtual Sequence
< UString
> getErrors(void) THROWS( (UsrSystemException
) );
219 virtual Sequence
< UsrAny
> getErrorExceptions(void) THROWS( (UsrSystemException
) );
220 virtual Sequence
< UString
> getWarnings(void) THROWS( (UsrSystemException
) );
223 void testSimple( const XExtendedDocumentHandlerRef
&r
);
224 void testExceptions( const XExtendedDocumentHandlerRef
&r
);
225 void testDTD( const XExtendedDocumentHandlerRef
&r
);
226 void testPerformance( const XExtendedDocumentHandlerRef
&r
);
227 void writeParagraph( const XExtendedDocumentHandlerRef
&r
, const UString
& s
);
230 Sequence
<UsrAny
> m_seqExceptions
;
231 Sequence
<UString
> m_seqErrors
;
232 Sequence
<UString
> m_seqWarnings
;
233 XMultiServiceFactoryRef m_rFactory
;
239 /*----------------------------------------
241 * Attributlist implementation
243 *----------------------------------------*/
244 struct AttributeListImpl_impl
;
245 class AttributeListImpl
:
246 public XAttributeList
,
251 AttributeListImpl( const AttributeListImpl
& );
252 ~AttributeListImpl();
255 BOOL
queryInterface( Uik aUik
, XInterfaceRef
& rOut
);
256 void acquire() { OWeakObject::acquire(); }
257 void release() { OWeakObject::release(); }
258 void* getImplementation(Reflection
*p
) { return OWeakObject::getImplementation(p
); }
261 virtual INT16
getLength(void) THROWS( (UsrSystemException
) );
262 virtual UString
getNameByIndex(INT16 i
) THROWS( (UsrSystemException
) );
263 virtual UString
getTypeByIndex(INT16 i
) THROWS( (UsrSystemException
) );
264 virtual UString
getTypeByName(const UString
& aName
) THROWS( (UsrSystemException
) );
265 virtual UString
getValueByIndex(INT16 i
) THROWS( (UsrSystemException
) );
266 virtual UString
getValueByName(const UString
& aName
) THROWS( (UsrSystemException
) );
269 void addAttribute( const UString
&sName
, const UString
&sType
, const UString
&sValue
);
273 struct AttributeListImpl_impl
*m_pImpl
;
280 TagAttribute( const UString
&sName
, const UString
&sType
, const UString
&sValue
)
284 this->sValue
= sValue
;
292 struct AttributeListImpl_impl
294 AttributeListImpl_impl()
296 // performance improvement during adding
297 vecAttribute
.reserve(20);
299 vector
<struct TagAttribute
> vecAttribute
;
304 INT16
AttributeListImpl::getLength(void) THROWS( (UsrSystemException
) )
306 return m_pImpl
->vecAttribute
.size();
310 AttributeListImpl::AttributeListImpl( const AttributeListImpl
&r
)
312 m_pImpl
= new AttributeListImpl_impl
;
313 *m_pImpl
= *(r
.m_pImpl
);
316 UString
AttributeListImpl::getNameByIndex(INT16 i
) THROWS( (UsrSystemException
) )
318 if( i
< m_pImpl
->vecAttribute
.size() ) {
319 return m_pImpl
->vecAttribute
[i
].sName
;
325 UString
AttributeListImpl::getTypeByIndex(INT16 i
) THROWS( (UsrSystemException
) )
327 if( i
< m_pImpl
->vecAttribute
.size() ) {
328 return m_pImpl
->vecAttribute
[i
].sType
;
333 UString
AttributeListImpl::getValueByIndex(INT16 i
) THROWS( (UsrSystemException
) )
335 if( i
< m_pImpl
->vecAttribute
.size() ) {
336 return m_pImpl
->vecAttribute
[i
].sValue
;
342 UString
AttributeListImpl::getTypeByName( const UString
& sName
) THROWS( (UsrSystemException
) )
344 vector
<struct TagAttribute
>::iterator ii
= m_pImpl
->vecAttribute
.begin();
346 for( ; ii
!= m_pImpl
->vecAttribute
.end() ; ii
++ ) {
347 if( (*ii
).sName
== sName
) {
354 UString
AttributeListImpl::getValueByName(const UString
& sName
) THROWS( (UsrSystemException
) )
356 vector
<struct TagAttribute
>::iterator ii
= m_pImpl
->vecAttribute
.begin();
358 for( ; ii
!= m_pImpl
->vecAttribute
.end() ; ii
++ ) {
359 if( (*ii
).sName
== sName
) {
367 BOOL
AttributeListImpl::queryInterface( Uik aUik
, XInterfaceRef
& rOut
)
369 if( aUik
== XAttributeList::getSmartUik() ) {
370 rOut
= (XAttributeList
* )this;
373 return OWeakObject::queryInterface( aUik
, rOut
);
379 AttributeListImpl::AttributeListImpl()
381 m_pImpl
= new AttributeListImpl_impl
;
386 AttributeListImpl::~AttributeListImpl()
392 void AttributeListImpl::addAttribute( const UString
&sName
,
393 const UString
&sType
,
394 const UString
&sValue
)
396 m_pImpl
->vecAttribute
.push_back( TagAttribute( sName
, sType
, sValue
) );
399 void AttributeListImpl::clear()
401 vector
<struct TagAttribute
> dummy
;
402 m_pImpl
->vecAttribute
.swap( dummy
);
404 assert( ! getLength() );
418 * for external binding
422 XInterfaceRef
OSaxWriterTest_CreateInstance( const XMultiServiceFactoryRef
& rSMgr
) THROWS((Exception
))
424 OSaxWriterTest
*p
= new OSaxWriterTest( rSMgr
);
425 XInterfaceRef xService
= *p
;
429 UString
OSaxWriterTest_getServiceName( ) THROWS( () )
431 return L
"test.com.sun.star.xml.sax.Writer";
434 UString
OSaxWriterTest_getImplementationName( ) THROWS( () )
436 return L
"test.extensions.xml.sax.Writer";
439 Sequence
<UString
> OSaxWriterTest_getSupportedServiceNames( ) THROWS( () )
441 Sequence
<UString
> aRet(1);
443 aRet
.getArray()[0] = OSaxWriterTest_getImplementationName( );
449 BOOL
OSaxWriterTest::queryInterface( Uik uik
, XInterfaceRef
&rOut
)
451 if( XSimpleTest::getSmartUik() == uik
) {
452 rOut
= (XSimpleTest
*) this;
455 return OWeakObject::queryInterface( uik
, rOut
);
461 void OSaxWriterTest::testInvariant( const UString
& TestName
, const XInterfaceRef
& TestObject
)
462 THROWS( ( IllegalArgumentException
,
463 UsrSystemException
) )
465 if( L
"com.sun.star.xml.sax.Writer" == TestName
) {
466 XDocumentHandlerRef
doc( TestObject
, USR_QUERY
);
467 XExtendedDocumentHandlerRef
ext( TestObject
, USR_QUERY
);
468 XActiveDataSourceRef
source( TestObject
, USR_QUERY
);
470 ERROR_ASSERT( doc
.is() , "XDocumentHandler cannot be queried" );
471 ERROR_ASSERT( ext
.is() , "XExtendedDocumentHandler cannot be queried" );
472 ERROR_ASSERT( source
.is() , "XActiveDataSource cannot be queried" );
475 BUILD_ERROR( 0 , "wrong test" );
480 INT32
OSaxWriterTest::test( const UString
& TestName
,
481 const XInterfaceRef
& TestObject
,
482 INT32 hTestHandle
) THROWS( ( IllegalArgumentException
,
483 UsrSystemException
) )
485 if( L
"com.sun.star.xml.sax.Writer" == TestName
) {
487 if( 0 == hTestHandle
) {
488 testInvariant( TestName
, TestObject
);
492 XExtendedDocumentHandlerRef
writer( TestObject
, USR_QUERY
);
494 if( 1 == hTestHandle
) {
495 testSimple( writer
);
497 else if( 2 == hTestHandle
) {
498 testExceptions( writer
);
500 else if( 3 == hTestHandle
) {
503 else if( 4 == hTestHandle
) {
504 testPerformance( writer
);
508 catch( Exception
& e
) {
509 BUILD_ERROR( 0 , UStringToString( e
.getName() , CHARSET_SYSTEM
).GetCharStr() );
512 BUILD_ERROR( 0 , "unknown exception (Exception is not base class)" );
517 if( hTestHandle
>= 5) {
518 // all tests finished.
523 BUILD_ERROR( 0 , "service not supported by test." );
530 BOOL
OSaxWriterTest::testPassed(void) THROWS( (UsrSystemException
) )
532 return m_seqErrors
.getLen() == 0;
536 Sequence
< UString
> OSaxWriterTest::getErrors(void) THROWS( (UsrSystemException
) )
542 Sequence
< UsrAny
> OSaxWriterTest::getErrorExceptions(void) THROWS( (UsrSystemException
) )
544 return m_seqExceptions
;
548 Sequence
< UString
> OSaxWriterTest::getWarnings(void) THROWS( (UsrSystemException
) )
550 return m_seqWarnings
;
553 void OSaxWriterTest::writeParagraph( const XExtendedDocumentHandlerRef
&r
, const UString
& s
)
558 Sequence
<UINT16
> seq( s
.len() );
559 memcpy( seq
.getArray() , s
.getStr() , s
.len() * sizeof( UINT16
) );
561 for( int n
= 1 ; n
< nMax
; n
++ ){
562 if( 32 == seq
.getArray()[n
] ) {
564 r
->characters( s
.copy( nStart
, n
- nStart
) );
569 r
->characters( s
.copy( nStart
, n
- nStart
) );
576 void OSaxWriterTest::testSimple( const XExtendedDocumentHandlerRef
&r
)
578 UString testParagraph
= L
"Dies ist ein bloeder Test um zu uberpruefen, ob der SAXWriter "
579 L
"wohl Zeilenumbrueche halbwegs richtig macht oder ob er die Zeile "
580 L
"bis zum bitteren Ende schreibt.";
582 OFileWriter
*pw
= new OFileWriter("output.xml");
583 AttributeListImpl
*pList
= new AttributeListImpl
;
585 XAttributeListRef
rList( (XAttributeList
*) pList
, USR_QUERY
);
586 XOutputStreamRef
ref( ( XOutputStream
* ) pw
, USR_QUERY
);
588 XActiveDataSourceRef
source( r
, USR_QUERY
);
590 ERROR_ASSERT( ref
.is() , "no output stream" );
591 ERROR_ASSERT( source
.is() , "no active data source" );
593 source
->setOutputStream( ref
);
597 pList
->addAttribute( L
"Arg1" , L
"CDATA" , L
"bla\n u" );
598 pList
->addAttribute( L
"Arg2" , L
"CDATA" , L
"blub" );
600 r
->startElement( L
"tag1" , rList
);
601 r
->ignorableWhitespace( L
"" );
603 r
->characters( L
"huhu" );
604 r
->ignorableWhitespace( L
"" );
606 r
->startElement( L
"hi" , rList
);
607 r
->ignorableWhitespace( L
"" );
609 // the enpassant must be converted & -> &
610 r
->characters( L
"ü" );
612 // Test added for mib. Tests if errors during conversions occurs
613 r
->ignorableWhitespace( UString() );
615 for( sal_Int32 n
= 32 ; n
< 254 ; n
++ ) {
620 StringToUString( array
, RTL_TEXTENCODING_SYMBOL
)
622 r
->ignorableWhitespace( UString() );
624 // '>' must not be converted
626 r
->characters( L
">fsfsdf<" );
628 r
->ignorableWhitespace( UString() );
630 writeParagraph( r
, testParagraph
);
633 r
->ignorableWhitespace( UString() );
634 r
->comment( L
"Dies ist ein Kommentar !" );
635 r
->ignorableWhitespace( UString() );
637 r
->startElement( L
"emptytagtest" , rList
);
638 r
->endElement( L
"emptytagtest" );
640 r
->endElement( L
"hi" );
641 r
->ignorableWhitespace( L
"" );
643 r
->endElement( L
"tag1" );
648 void OSaxWriterTest::testExceptions( const XExtendedDocumentHandlerRef
& r
)
651 OFileWriter
*pw
= new OFileWriter("output2.xml");
652 AttributeListImpl
*pList
= new AttributeListImpl
;
654 XAttributeListRef
rList( (XAttributeList
*) pList
, USR_QUERY
);
655 XOutputStreamRef
ref( ( XOutputStream
* ) pw
, USR_QUERY
);
657 XActiveDataSourceRef
source( r
, USR_QUERY
);
659 ERROR_ASSERT( ref
.is() , "no output stream" );
660 ERROR_ASSERT( source
.is() , "no active data source" );
662 source
->setOutputStream( ref
);
664 { // startDocument must be called before start element
665 BOOL bException
= TRUE
;
667 r
->startElement( L
"huhu" , rList
);
670 catch( SAXException
& e
) {
673 ERROR_ASSERT( bException
, "expected exception not thrown !" );
678 r
->startElement( L
"huhu" , rList
);
682 BOOL bException
= TRUE
;
684 r
->startElement( L
"huhu" , rList
);
687 catch( SAXException
& e
) {
690 ERROR_ASSERT( bException
, "expected exception not thrown !" );
694 r
->endElement( L
"hi" );
700 void OSaxWriterTest::testDTD(const XExtendedDocumentHandlerRef
&r
)
702 OFileWriter
*pw
= new OFileWriter("outputDTD.xml");
703 AttributeListImpl
*pList
= new AttributeListImpl
;
705 XAttributeListRef
rList( (XAttributeList
*) pList
, USR_QUERY
);
706 XOutputStreamRef
ref( ( XOutputStream
* ) pw
, USR_QUERY
);
708 XActiveDataSourceRef
source( r
, USR_QUERY
);
710 ERROR_ASSERT( ref
.is() , "no output stream" );
711 ERROR_ASSERT( source
.is() , "no active data source" );
713 source
->setOutputStream( ref
);
717 r
->unknown( L
"<!DOCTYPE iCalendar >\n" );
718 r
->startElement( L
"huhu" , rList
);
720 r
->endElement( L
"huhu" );
724 void OSaxWriterTest::testPerformance(const XExtendedDocumentHandlerRef
&r
)
726 OFileWriter
*pw
= new OFileWriter("testPerformance.xml");
727 AttributeListImpl
*pList
= new AttributeListImpl
;
729 UString testParagraph
= L
"Dies ist ein bloeder Test um zu uberpruefen, ob der SAXWriter "
730 L
"wohl > Zeilenumbrueche halbwegs richtig macht oder ob er die Zeile "
731 L
"bis zum bitteren Ende schreibt.";
734 XAttributeListRef
rList( (XAttributeList
*) pList
, USR_QUERY
);
735 XOutputStreamRef
ref( ( XOutputStream
* ) pw
, USR_QUERY
);
737 XActiveDataSourceRef
source( r
, USR_QUERY
);
739 ERROR_ASSERT( ref
.is() , "no output stream" );
740 ERROR_ASSERT( source
.is() , "no active data source" );
742 source
->setOutputStream( ref
);
744 TimeValue aStartTime
, aEndTime
;
745 osl_getSystemTime( &aStartTime
);
749 // just write a bunch of xml tags !
750 // for performance testing
752 for( i2
= 0 ; i2
< 15 ; i2
++ )
754 r
->startElement( UString( L
"tag" ) + UString::valueOf( i2
), rList
);
755 for( sal_Int32 i
= 0 ; i
< 450 ; i
++ )
757 r
->ignorableWhitespace( L
"");
758 r
->startElement( L
"huhu" , rList
);
759 r
->characters( testParagraph
);
760 // writeParagraph( r , testParagraph );
762 r
->ignorableWhitespace( L
"");
763 r
->endElement( L
"huhu" );
766 for( i2
= 14 ; i2
>= 0 ; i2
-- )
768 r
->ignorableWhitespace( L
"");
769 r
->endElement( UString( L
"tag" ) + UString::valueOf( i2
) );
774 osl_getSystemTime( &aEndTime
);
776 double fStart
= (double)aStartTime
.Seconds
+ ((double)aStartTime
.Nanosec
/ 1000000000.0);
777 double fEnd
= (double)aEndTime
.Seconds
+ ((double)aEndTime
.Nanosec
/ 1000000000.0);
779 printf( "Performance writing : %g s\n" , fEnd
- fStart
);