Update ooo320-m1
[ooovba.git] / extensions / test / sax / testwriter.cxx
blobd9520ac147de74cf4518234490bb707f6c7e1679
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: testwriter.cxx,v $
10 * $Revision: 1.7 $
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>
35 #include <vector>
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
40 #include <stdio.h>
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>
49 #include <osl/time.h>
50 #include <usr/weak.hxx>
51 #include <tools/string.hxx>
53 #if OSL_DEBUG_LEVEL == 0
54 #define NDEBUG
55 #endif
56 #include <assert.h>
58 #include <usr/factoryhlp.hxx>
60 #include <usr/reflserv.hxx> // for EXTERN_SERVICE_CALLTYPE
62 using namespace std;
63 using namespace rtl;
64 using namespace vos;
65 using namespace usr;
67 #define BUILD_ERROR(expr, Message)\
69 m_seqErrors.realloc( m_seqErrors.getLen() + 1 ); \
70 m_seqExceptions.realloc( m_seqExceptions.getLen() + 1 ); \
71 String str; \
72 str += __FILE__;\
73 str += " "; \
74 str += "(" ; \
75 str += __LINE__ ;\
76 str += ")\n";\
77 str += "[ " ; \
78 str += #expr; \
79 str += " ] : " ; \
80 str += Message; \
81 m_seqErrors.getArray()[ m_seqErrors.getLen()-1] = StringToUString( str , CHARSET_SYSTEM ); \
83 ((void)0)
86 #define WARNING_ASSERT(expr, Message) \
87 if( ! (expr) ) { \
88 m_seqWarnings.realloc( m_seqErrors.getLen() +1 ); \
89 String str;\
90 str += __FILE__;\
91 str += " "; \
92 str += "(" ; \
93 str += __LINE__ ;\
94 str += ")\n";\
95 str += "[ " ; \
96 str += #expr; \
97 str += " ] : " ; \
98 str += Message; \
99 m_seqWarnings.getArray()[ m_seqWarnings.getLen()-1] = StringToUString( str , CHARSET_SYSTEM ); \
100 return; \
102 ((void)0)
104 #define ERROR_ASSERT(expr, Message) \
105 if( ! (expr) ) { \
106 BUILD_ERROR(expr, Message );\
107 return; \
109 ((void)0)
111 #define ERROR_EXCEPTION_ASSERT(expr, Message, Exception) \
112 if( !(expr)) { \
113 BUILD_ERROR(expr,Message);\
114 m_seqExceptions.getArray()[ m_seqExceptions.getLen()-1] = UsrAny( Exception );\
115 return; \
117 ((void)0)
119 /****
120 * test szenarios :
124 ****/
127 class OFileWriter :
128 public XOutputStream,
129 public OWeakObject
131 public:
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 );
143 return TRUE;
145 void acquire() { OWeakObject::acquire(); }
146 void release() { OWeakObject::release(); }
147 void* getImplementation(Reflection *p) { return OWeakObject::getImplementation(p); }
149 public:
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) );
158 private:
159 char m_pcFile[256];
160 FILE *m_f;
164 void OFileWriter::writeBytes(const Sequence< BYTE >& aData)
165 THROWS( (NotConnectedException, BufferSizeExceededException, UsrSystemException) )
167 if( ! m_f ) {
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) )
179 fflush( m_f );
182 void OFileWriter::closeOutput(void)
183 THROWS( (NotConnectedException, BufferSizeExceededException, UsrSystemException) )
185 fclose( m_f );
186 m_f = 0;
190 class OSaxWriterTest :
191 public XSimpleTest,
192 public OWeakObject
194 public:
195 OSaxWriterTest( const XMultiServiceFactoryRef & rFactory ) : m_rFactory( rFactory )
199 ~OSaxWriterTest() {}
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); }
207 public:
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) );
222 private:
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);
229 private:
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,
247 public OWeakObject
249 public:
250 AttributeListImpl();
251 AttributeListImpl( const AttributeListImpl & );
252 ~AttributeListImpl();
254 public:
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); }
260 public:
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) );
268 public:
269 void addAttribute( const UString &sName , const UString &sType , const UString &sValue );
270 void clear();
272 private:
273 struct AttributeListImpl_impl *m_pImpl;
277 struct TagAttribute
279 TagAttribute(){}
280 TagAttribute( const UString &sName, const UString &sType , const UString &sValue )
282 this->sName = sName;
283 this->sType = sType;
284 this->sValue = sValue;
287 UString sName;
288 UString sType;
289 UString 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;
321 return UString();
325 UString AttributeListImpl::getTypeByIndex(INT16 i) THROWS( (UsrSystemException) )
327 if( i < m_pImpl->vecAttribute.size() ) {
328 return m_pImpl->vecAttribute[i].sType;
330 return UString();
333 UString AttributeListImpl::getValueByIndex(INT16 i) THROWS( (UsrSystemException) )
335 if( i < m_pImpl->vecAttribute.size() ) {
336 return m_pImpl->vecAttribute[i].sValue;
338 return UString();
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 ) {
348 return (*ii).sType;
351 return UString();
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 ) {
360 return (*ii).sValue;
363 return UString();
367 BOOL AttributeListImpl::queryInterface( Uik aUik, XInterfaceRef & rOut )
369 if( aUik == XAttributeList::getSmartUik() ) {
370 rOut = (XAttributeList * )this;
372 else {
373 return OWeakObject::queryInterface( aUik , rOut );
375 return TRUE;
379 AttributeListImpl::AttributeListImpl()
381 m_pImpl = new AttributeListImpl_impl;
386 AttributeListImpl::~AttributeListImpl()
388 delete m_pImpl;
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;
426 return xService;
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( );
445 return aRet;
449 BOOL OSaxWriterTest::queryInterface( Uik uik , XInterfaceRef &rOut )
451 if( XSimpleTest::getSmartUik() == uik ) {
452 rOut = (XSimpleTest *) this;
454 else {
455 return OWeakObject::queryInterface( uik , rOut );
457 return TRUE;
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" );
474 else {
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 ) {
486 try {
487 if( 0 == hTestHandle ) {
488 testInvariant( TestName , TestObject );
490 else {
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 ) {
501 testDTD( writer );
503 else if( 4 == hTestHandle ) {
504 testPerformance( writer );
508 catch( Exception& e ) {
509 BUILD_ERROR( 0 , UStringToString( e.getName() , CHARSET_SYSTEM ).GetCharStr() );
511 catch(...) {
512 BUILD_ERROR( 0 , "unknown exception (Exception is not base class)" );
515 hTestHandle ++;
517 if( hTestHandle >= 5) {
518 // all tests finished.
519 hTestHandle = -1;
522 else {
523 BUILD_ERROR( 0 , "service not supported by test." );
525 return hTestHandle;
530 BOOL OSaxWriterTest::testPassed(void) THROWS( (UsrSystemException) )
532 return m_seqErrors.getLen() == 0;
536 Sequence< UString > OSaxWriterTest::getErrors(void) THROWS( (UsrSystemException) )
538 return m_seqErrors;
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)
555 int nMax = s.len();
556 int nStart = 0;
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] ) {
563 r->allowLineBreak();
564 r->characters( s.copy( nStart , n - nStart ) );
565 nStart = n;
568 r->allowLineBreak();
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 );
595 r->startDocument();
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 & -> &amp;
610 r->characters( L"&#252;" );
612 // Test added for mib. Tests if errors during conversions occurs
613 r->ignorableWhitespace( UString() );
614 sal_Char array[256];
615 for( sal_Int32 n = 32 ; n < 254 ; n ++ ) {
616 array[n-32] = n;
618 array[254-32] = 0;
619 r->characters(
620 StringToUString( array , RTL_TEXTENCODING_SYMBOL )
622 r->ignorableWhitespace( UString() );
624 // '>' must not be converted
625 r->startCDATA();
626 r->characters( L">fsfsdf<" );
627 r->endCDATA();
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" );
644 r->endDocument();
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;
666 try {
667 r->startElement( L"huhu" , rList );
668 bException = FALSE;
670 catch( SAXException& e ) {
673 ERROR_ASSERT( bException , "expected exception not thrown !" );
676 r->startDocument();
678 r->startElement( L"huhu" , rList );
679 r->startCDATA();
682 BOOL bException = TRUE;
683 try {
684 r->startElement( L"huhu" , rList );
685 bException = FALSE;
687 catch( SAXException& e ) {
690 ERROR_ASSERT( bException , "expected exception not thrown !" );
693 r->endCDATA();
694 r->endElement( L"hi" );
696 r->endDocument();
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 );
716 r->startDocument();
717 r->unknown( L"<!DOCTYPE iCalendar >\n" );
718 r->startElement( L"huhu" , rList );
720 r->endElement( L"huhu" );
721 r->endDocument();
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 );
748 r->startDocument();
749 // just write a bunch of xml tags !
750 // for performance testing
751 sal_Int32 i2;
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 ) );
772 r->endDocument();
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 );