xref: /aoo41x/main/extensions/test/sax/testwriter.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
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.
14  *
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).
20  *
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.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_extensions.hxx"
30 
31 //#include <tools/presys.h>
32 #include <vector>
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
36 
37 #include <stdio.h>
38 
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>
44 
45 #include <rtl/wstring.hxx>
46 #include <osl/time.h>
47 #include <usr/weak.hxx>
48 #include <tools/string.hxx>
49 
50 #include <usr/factoryhlp.hxx>
51 
52 #include <usr/reflserv.hxx>  // for EXTERN_SERVICE_CALLTYPE
53 
54 using namespace std;
55 using namespace rtl;
56 using namespace vos;
57 using namespace usr;
58 
59 #define BUILD_ERROR(expr, Message)\
60 		{\
61 			m_seqErrors.realloc( m_seqErrors.getLen() + 1 ); \
62 		m_seqExceptions.realloc(  m_seqExceptions.getLen() + 1 ); \
63 		String str; \
64 		str += __FILE__;\
65 		str += " "; \
66 		str += "(" ; \
67 		str += __LINE__ ;\
68 		str += ")\n";\
69 		str += "[ " ; \
70 		str += #expr; \
71 		str += " ] : " ; \
72 		str += Message; \
73 		m_seqErrors.getArray()[ m_seqErrors.getLen()-1] = StringToUString( str , CHARSET_SYSTEM ); \
74 		}\
75 		((void)0)
76 
77 
78 #define WARNING_ASSERT(expr, Message) \
79 		if( ! (expr) ) { \
80 			m_seqWarnings.realloc( m_seqErrors.getLen() +1 ); \
81 			String str;\
82 			str += __FILE__;\
83 			str += " "; \
84 			str += "(" ; \
85 			str += __LINE__ ;\
86 			str += ")\n";\
87 			str += "[ " ; \
88 			str += #expr; \
89 			str += " ] : " ; \
90 			str += Message; \
91 			m_seqWarnings.getArray()[ m_seqWarnings.getLen()-1] = StringToUString( str , CHARSET_SYSTEM ); \
92 			return; \
93 		}\
94 		((void)0)
95 
96 #define ERROR_ASSERT(expr, Message) \
97 		if( ! (expr) ) { \
98 			BUILD_ERROR(expr, Message );\
99 			return; \
100 		}\
101 		((void)0)
102 
103 #define ERROR_EXCEPTION_ASSERT(expr, Message, Exception) \
104 	if( !(expr)) { \
105 		BUILD_ERROR(expr,Message);\
106 		m_seqExceptions.getArray()[ m_seqExceptions.getLen()-1] = UsrAny( Exception );\
107 		return; \
108 	} \
109 	((void)0)
110 
111 /****
112 * test szenarios :
113 *
114 *
115 *
116 ****/
117 
118 
119 class OFileWriter :
120 		public XOutputStream,
121 		public OWeakObject
122 {
123 public:
124 	OFileWriter( char *pcFile ) { strcpy( m_pcFile , pcFile ); m_f = 0; }
125 
126 
127 public: // refcounting
128 	BOOL						queryInterface( Uik aUik, XInterfaceRef & rOut )
129 	{
130 		if( XOutputStream::getSmartUik() == aUik ) {
131 			rOut = (XOutputStream *) this;
132 		}
133 		else return OWeakObject::queryInterface( aUik , rOut );
134 
135 		return TRUE;
136 	}
137 	void 						acquire() 						 { OWeakObject::acquire(); }
138 	void 						release() 						 { OWeakObject::release(); }
139 	void* 						getImplementation(Reflection *p) { return OWeakObject::getImplementation(p); }
140 
141 public:
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) );
148 
149 
150 private:
151 	char m_pcFile[256];
152 	FILE *m_f;
153 };
154 
155 
156 void OFileWriter::writeBytes(const Sequence< BYTE >& aData)
157 			THROWS( (NotConnectedException, BufferSizeExceededException, UsrSystemException) )
158 {
159 	if( ! m_f ) {
160 		m_f = fopen( m_pcFile , "w" );
161 	}
162 
163 	fwrite( aData.getConstArray() , 1 , aData.getLen() , m_f );
164 
165 }
166 
167 
168 void OFileWriter::flush(void)
169 			THROWS( (NotConnectedException, BufferSizeExceededException, UsrSystemException) )
170 {
171 	fflush( m_f );
172 }
173 
174 void OFileWriter::closeOutput(void)
175     					THROWS( (NotConnectedException, BufferSizeExceededException, UsrSystemException) )
176 {
177 	fclose( m_f );
178 	m_f = 0;
179 }
180 
181 
182 class OSaxWriterTest :
183 		public XSimpleTest,
184         public OWeakObject
185 {
186 public:
187 	OSaxWriterTest( const XMultiServiceFactoryRef & rFactory ) : m_rFactory( rFactory )
188 	{
189 
190 	}
191 	~OSaxWriterTest() {}
192 
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); }
198 
199 public:
200     virtual void testInvariant(const UString& TestName, const XInterfaceRef& TestObject)
201     															THROWS( (	IllegalArgumentException,
202     																		UsrSystemException) );
203 
204     virtual INT32 test(	const UString& TestName,
205     					const XInterfaceRef& TestObject,
206     					INT32 hTestHandle) 						THROWS( (	IllegalArgumentException,
207     																		UsrSystemException) );
208 
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) );
213 
214 private:
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);
220 
221 private:
222 	Sequence<UsrAny>  		m_seqExceptions;
223 	Sequence<UString> 		m_seqErrors;
224 	Sequence<UString> 		m_seqWarnings;
225 	XMultiServiceFactoryRef m_rFactory;
226 
227 };
228 
229 
230 
231 /*----------------------------------------
232 *
233 * 	Attributlist implementation
234 *
235 *----------------------------------------*/
236 struct AttributeListImpl_impl;
237 class AttributeListImpl :
238 		public XAttributeList,
239 		public OWeakObject
240 {
241 public:
242 	AttributeListImpl();
243 	AttributeListImpl( const AttributeListImpl & );
244 	~AttributeListImpl();
245 
246 public:
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); }
251 
252 public:
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) );
259 
260 public:
261 	void addAttribute( const UString &sName , const UString &sType , const UString &sValue );
262 	void clear();
263 
264 private:
265 	struct AttributeListImpl_impl *m_pImpl;
266 };
267 
268 
269 struct TagAttribute
270 {
271 	TagAttribute(){}
272 	TagAttribute( const UString &sName, const UString &sType , const UString &sValue )
273 	{
274 		this->sName 	= sName;
275 		this->sType 	= sType;
276 		this->sValue 	= sValue;
277 	}
278 
279 	UString sName;
280 	UString sType;
281 	UString sValue;
282 };
283 
284 struct AttributeListImpl_impl
285 {
286 	AttributeListImpl_impl()
287 	{
288 		// performance improvement during adding
289 		vecAttribute.reserve(20);
290 	}
291 	vector<struct TagAttribute> vecAttribute;
292 };
293 
294 
295 
296 INT16 AttributeListImpl::getLength(void) THROWS( (UsrSystemException) )
297 {
298 	return m_pImpl->vecAttribute.size();
299 }
300 
301 
302 AttributeListImpl::AttributeListImpl( const AttributeListImpl &r )
303 {
304 	m_pImpl = new AttributeListImpl_impl;
305 	*m_pImpl = *(r.m_pImpl);
306 }
307 
308 UString AttributeListImpl::getNameByIndex(INT16 i) THROWS( (UsrSystemException) )
309 {
310 	if( i < m_pImpl->vecAttribute.size() ) {
311 		return m_pImpl->vecAttribute[i].sName;
312 	}
313 	return UString();
314 }
315 
316 
317 UString AttributeListImpl::getTypeByIndex(INT16 i) THROWS( (UsrSystemException) )
318 {
319 	if( i < m_pImpl->vecAttribute.size() ) {
320 		return m_pImpl->vecAttribute[i].sType;
321 	}
322 	return UString();
323 }
324 
325 UString AttributeListImpl::getValueByIndex(INT16 i) THROWS( (UsrSystemException) )
326 {
327 	if( i < m_pImpl->vecAttribute.size() ) {
328 		return m_pImpl->vecAttribute[i].sValue;
329 	}
330 	return UString();
331 
332 }
333 
334 UString AttributeListImpl::getTypeByName( const UString& sName ) THROWS( (UsrSystemException) )
335 {
336 	vector<struct TagAttribute>::iterator ii = m_pImpl->vecAttribute.begin();
337 
338 	for( ; ii != m_pImpl->vecAttribute.end() ; ii ++ ) {
339 		if( (*ii).sName == sName ) {
340 			return (*ii).sType;
341 		}
342 	}
343 	return UString();
344 }
345 
346 UString AttributeListImpl::getValueByName(const UString& sName) THROWS( (UsrSystemException) )
347 {
348 	vector<struct TagAttribute>::iterator ii = m_pImpl->vecAttribute.begin();
349 
350 	for( ; ii != m_pImpl->vecAttribute.end() ; ii ++ ) {
351 		if( (*ii).sName == sName ) {
352 			return (*ii).sValue;
353 		}
354 	}
355 	return UString();
356 }
357 
358 
359 BOOL AttributeListImpl::queryInterface( Uik aUik, XInterfaceRef & rOut )
360 {
361 	if( aUik == XAttributeList::getSmartUik() ) {
362 		rOut = (XAttributeList * )this;
363 	}
364 	else {
365 		return OWeakObject::queryInterface( aUik , rOut );
366 	}
367 	return TRUE;
368 }
369 
370 
371 AttributeListImpl::AttributeListImpl()
372 {
373 	m_pImpl = new AttributeListImpl_impl;
374 }
375 
376 
377 
378 AttributeListImpl::~AttributeListImpl()
379 {
380 	delete m_pImpl;
381 }
382 
383 
384 void AttributeListImpl::addAttribute( 	const UString &sName ,
385 										const UString &sType ,
386 										const UString &sValue )
387 {
388 	m_pImpl->vecAttribute.push_back( TagAttribute( sName , sType , sValue ) );
389 }
390 
391 void AttributeListImpl::clear()
392 {
393 	vector<struct TagAttribute> dummy;
394 	m_pImpl->vecAttribute.swap( dummy );
395 
396 	OSL_ASSERT( ! getLength() );
397 }
398 
399 
400 
401 
402 
403 
404 
405 
406 
407 
408 
409 /**
410 * for external binding
411 *
412 *
413 **/
414 XInterfaceRef OSaxWriterTest_CreateInstance( const XMultiServiceFactoryRef & rSMgr ) THROWS((Exception))
415 {
416 	OSaxWriterTest *p = new OSaxWriterTest( rSMgr );
417 	XInterfaceRef xService = *p;
418 	return xService;
419 }
420 
421 UString     OSaxWriterTest_getServiceName( ) THROWS( () )
422 {
423 	return L"test.com.sun.star.xml.sax.Writer";
424 }
425 
426 UString 	OSaxWriterTest_getImplementationName( ) THROWS( () )
427 {
428 	return L"test.extensions.xml.sax.Writer";
429 }
430 
431 Sequence<UString> OSaxWriterTest_getSupportedServiceNames( ) THROWS( () )
432 {
433 	Sequence<UString> aRet(1);
434 
435 	aRet.getArray()[0] = OSaxWriterTest_getImplementationName( );
436 
437 	return aRet;
438 }
439 
440 
441 BOOL OSaxWriterTest::queryInterface( Uik uik , XInterfaceRef &rOut )
442 {
443 	if( XSimpleTest::getSmartUik() == uik ) {
444 		rOut = (XSimpleTest *) this;
445 	}
446 	else {
447 		return OWeakObject::queryInterface( uik , rOut );
448 	}
449 	return TRUE;
450 }
451 
452 
453 void OSaxWriterTest::testInvariant( const UString& TestName, const XInterfaceRef& TestObject )
454     															THROWS( (	IllegalArgumentException,
455     																		UsrSystemException) )
456 {
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 );
461 
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" );
465 	}
466 	else {
467 		BUILD_ERROR( 0 , "wrong test" );
468 	}
469 }
470 
471 
472 INT32 OSaxWriterTest::test(	const UString& TestName,
473     					const XInterfaceRef& TestObject,
474     					INT32 hTestHandle) 						THROWS( (	IllegalArgumentException,
475     																		UsrSystemException) )
476 {
477 	if( L"com.sun.star.xml.sax.Writer" == TestName )  {
478 		try {
479 			if( 0 == hTestHandle ) {
480 				testInvariant( TestName , TestObject );
481 			}
482 			else {
483 
484 				XExtendedDocumentHandlerRef writer( TestObject , USR_QUERY );
485 
486 				if( 1 == hTestHandle ) {
487 					testSimple( writer );
488 				}
489 				else if( 2 == hTestHandle ) {
490 					testExceptions( writer );
491 				}
492 				else if( 3 == hTestHandle ) {
493 					testDTD( writer );
494 				}
495 				else if( 4 == hTestHandle ) {
496 					testPerformance( writer );
497 				}
498 			}
499 		}
500 		catch( Exception& e )  {
501 			BUILD_ERROR( 0 , UStringToString( e.getName() , CHARSET_SYSTEM ).GetCharStr() );
502 		}
503 		catch(...) {
504 			BUILD_ERROR( 0 , "unknown exception (Exception is  not base class)" );
505 		}
506 
507 		hTestHandle ++;
508 
509 		if( hTestHandle >= 5) {
510 			// all tests finished.
511 			hTestHandle = -1;
512 		}
513 	}
514 	else {
515 		BUILD_ERROR( 0 , "service not supported by test." );
516 	}
517 	return hTestHandle;
518 }
519 
520 
521 
522 BOOL OSaxWriterTest::testPassed(void) 										THROWS( (UsrSystemException) )
523 {
524 	return m_seqErrors.getLen() == 0;
525 }
526 
527 
528 Sequence< UString > OSaxWriterTest::getErrors(void) 							THROWS( (UsrSystemException) )
529 {
530 	return m_seqErrors;
531 }
532 
533 
534 Sequence< UsrAny > OSaxWriterTest::getErrorExceptions(void) 					THROWS( (UsrSystemException) )
535 {
536 	return m_seqExceptions;
537 }
538 
539 
540 Sequence< UString > OSaxWriterTest::getWarnings(void) 						THROWS( (UsrSystemException) )
541 {
542 	return m_seqWarnings;
543 }
544 
545 void OSaxWriterTest::writeParagraph( const XExtendedDocumentHandlerRef &r , const UString & s)
546 {
547 	int nMax = s.len();
548 	int nStart = 0;
549 
550 	Sequence<UINT16> seq( s.len() );
551 	memcpy( seq.getArray() , s.getStr() , s.len() * sizeof( UINT16 ) );
552 
553 	for( int n = 1 ; n < nMax ; n++ ){
554 		if( 32 == seq.getArray()[n] ) {
555 			r->allowLineBreak();
556 			r->characters( s.copy( nStart , n - nStart ) );
557 			nStart = n;
558 		}
559 	}
560 	r->allowLineBreak();
561 	r->characters( s.copy( nStart , n - nStart ) );
562 
563 
564 }
565 
566 
567 
568 void OSaxWriterTest::testSimple( const XExtendedDocumentHandlerRef &r )
569 {
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.";
573 
574 	OFileWriter *pw = new OFileWriter("output.xml");
575 	AttributeListImpl *pList = new AttributeListImpl;
576 
577 	XAttributeListRef rList( (XAttributeList *) pList , USR_QUERY );
578 	XOutputStreamRef ref( ( XOutputStream * ) pw , USR_QUERY );
579 
580 	XActiveDataSourceRef source( r , USR_QUERY );
581 
582 	ERROR_ASSERT( ref.is() , "no output stream" );
583 	ERROR_ASSERT( source.is() , "no active data source" );
584 
585 	source->setOutputStream( ref );
586 
587 	r->startDocument();
588 
589 	pList->addAttribute( L"Arg1" , L"CDATA" , L"bla\n	u" );
590 	pList->addAttribute( L"Arg2" , L"CDATA" , L"blub" );
591 
592 	r->startElement( L"tag1"  , rList );
593 	r->ignorableWhitespace( L"" );
594 
595 	r->characters( L"huhu" );
596 	r->ignorableWhitespace( L"" );
597 
598 	r->startElement( L"hi" , rList );
599 	r->ignorableWhitespace( L"" );
600 
601 	// the enpassant must be converted & -> &amp;
602 	r->characters( L"&#252;" );
603 
604 	// Test added for mib. Tests if errors during conversions occurs
605 	r->ignorableWhitespace( UString() );
606 	sal_Char array[256];
607 	for( sal_Int32 n = 32 ; n < 254 ; n ++ ) {
608 		array[n-32] = n;
609 	}
610 	array[254-32] = 0;
611 	r->characters(
612 		StringToUString( array , RTL_TEXTENCODING_SYMBOL )
613 		);
614 	r->ignorableWhitespace( UString() );
615 
616 	// '>' must not be converted
617 	r->startCDATA();
618 	r->characters( L">fsfsdf<" );
619 	r->endCDATA();
620 	r->ignorableWhitespace( UString() );
621 
622 	writeParagraph( r , testParagraph );
623 
624 
625 	r->ignorableWhitespace( UString() );
626 	r->comment( L"Dies ist ein Kommentar !" );
627 	r->ignorableWhitespace( UString() );
628 
629 	r->startElement( L"emptytagtest"  , rList );
630 	r->endElement( L"emptytagtest" );
631 
632 	r->endElement( L"hi" );
633 	r->ignorableWhitespace( L"" );
634 
635 	r->endElement( L"tag1" );
636 	r->endDocument();
637 
638 }
639 
640 void OSaxWriterTest::testExceptions( const XExtendedDocumentHandlerRef & r )
641 {
642 
643 	OFileWriter *pw = new OFileWriter("output2.xml");
644 	AttributeListImpl *pList = new AttributeListImpl;
645 
646 	XAttributeListRef rList( (XAttributeList *) pList , USR_QUERY );
647 	XOutputStreamRef ref( ( XOutputStream * ) pw , USR_QUERY );
648 
649 	XActiveDataSourceRef source( r , USR_QUERY );
650 
651 	ERROR_ASSERT( ref.is() , "no output stream" );
652 	ERROR_ASSERT( source.is() , "no active data source" );
653 
654 	source->setOutputStream( ref );
655 
656 	{ // startDocument must be called before start element
657 		BOOL bException = TRUE;
658 		try {
659 			r->startElement( L"huhu" , rList );
660 			bException = FALSE;
661 		}
662 		catch( SAXException& e ) {
663 
664 		}
665 		ERROR_ASSERT( bException , "expected exception not thrown !" );
666 	}
667 
668 	r->startDocument();
669 
670 	r->startElement( L"huhu" , rList );
671 	r->startCDATA();
672 
673 	{
674 		BOOL bException = TRUE;
675 		try {
676 			r->startElement( L"huhu" , rList );
677 			bException = FALSE;
678 		}
679 		catch( SAXException& e ) {
680 
681 		}
682 		ERROR_ASSERT( bException , "expected exception not thrown !" );
683 	}
684 
685 	r->endCDATA();
686 	r->endElement( L"hi" );
687 
688 	r->endDocument();
689 }
690 
691 
692 void OSaxWriterTest::testDTD(const  XExtendedDocumentHandlerRef &r )
693 {
694 	OFileWriter *pw = new OFileWriter("outputDTD.xml");
695 	AttributeListImpl *pList = new AttributeListImpl;
696 
697 	XAttributeListRef rList( (XAttributeList *) pList , USR_QUERY );
698 	XOutputStreamRef ref( ( XOutputStream * ) pw , USR_QUERY );
699 
700 	XActiveDataSourceRef source( r , USR_QUERY );
701 
702 	ERROR_ASSERT( ref.is() , "no output stream" );
703 	ERROR_ASSERT( source.is() , "no active data source" );
704 
705 	source->setOutputStream( ref );
706 
707 
708 	r->startDocument();
709 	r->unknown( L"<!DOCTYPE iCalendar >\n" );
710 	r->startElement( L"huhu" , rList );
711 
712 	r->endElement( L"huhu" );
713 	r->endDocument();
714 }
715 
716 void OSaxWriterTest::testPerformance(const  XExtendedDocumentHandlerRef &r )
717 {
718 	OFileWriter *pw = new OFileWriter("testPerformance.xml");
719 	AttributeListImpl *pList = new AttributeListImpl;
720 
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.";
724 
725 
726 	XAttributeListRef rList( (XAttributeList *) pList , USR_QUERY );
727 	XOutputStreamRef ref( ( XOutputStream * ) pw , USR_QUERY );
728 
729 	XActiveDataSourceRef source( r , USR_QUERY );
730 
731 	ERROR_ASSERT( ref.is() , "no output stream" );
732 	ERROR_ASSERT( source.is() , "no active data source" );
733 
734 	source->setOutputStream( ref );
735 
736 	TimeValue aStartTime, aEndTime;
737 	osl_getSystemTime( &aStartTime );
738 
739 
740 	r->startDocument();
741 	// just write a bunch of xml tags !
742 	// for performance testing
743 	sal_Int32 i2;
744 	for( i2 = 0 ; i2 < 15 ; i2 ++ )
745 	{
746 		r->startElement( UString( L"tag" ) + UString::valueOf( i2 ), rList );
747 		for( sal_Int32 i = 0 ; i < 450 ; i ++ )
748 		{
749 			r->ignorableWhitespace( L"");
750 			r->startElement( L"huhu" , rList );
751 			r->characters( testParagraph );
752 //			writeParagraph( r , testParagraph );
753 
754 			r->ignorableWhitespace( L"");
755 			r->endElement( L"huhu" );
756 		}
757 	}
758 	for( i2 = 14 ; i2 >= 0  ; i2-- )
759 	{
760 		r->ignorableWhitespace( L"");
761 		r->endElement( UString( L"tag" ) + UString::valueOf( i2 ) );
762 	}
763 
764 	r->endDocument();
765 
766 	osl_getSystemTime( &aEndTime );
767 
768 	double fStart = (double)aStartTime.Seconds + ((double)aStartTime.Nanosec / 1000000000.0);
769 	double fEnd = (double)aEndTime.Seconds + ((double)aEndTime.Nanosec / 1000000000.0);
770 
771 	printf( "Performance writing : %g s\n" , fEnd - fStart );
772 }
773