xref: /trunk/main/sax/test/sax/testwriter.cxx (revision f9b72d11)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 #include <vector>
24 #include <stdio.h>
25 
26 #include <com/sun/star/test/XSimpleTest.hpp>
27 #include <com/sun/star/lang/XMultiServiceFactory.hpp>  // for the multiservice-factories
28 
29 #include <com/sun/star/io/XActiveDataSource.hpp>
30 #include <com/sun/star/io/XOutputStream.hpp>
31 #include <com/sun/star/xml/sax/SAXParseException.hpp>
32 #include <com/sun/star/xml/sax/XParser.hpp>
33 #include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
34 
35 #include <osl/time.h>
36 
37 #include <cppuhelper/factory.hxx>
38 #include <cppuhelper/implbase1.hxx>
39 #include <cppuhelper/implbase3.hxx>
40 
41 
42 using namespace ::std;
43 using namespace ::rtl;
44 using namespace ::cppu;
45 using namespace ::com::sun::star::uno;
46 using namespace ::com::sun::star::lang;
47 using namespace ::com::sun::star::test;
48 using namespace ::com::sun::star::registry;
49 using namespace ::com::sun::star::io;
50 using namespace ::com::sun::star::xml::sax;
51 
52 #include "factory.hxx"
53 
54 namespace sax_test {
55 
56 class OFileWriter :
57 		public WeakImplHelper1< XOutputStream >
58 {
59 public:
OFileWriter(char * pcFile)60     OFileWriter( char *pcFile ) { strncpy( m_pcFile, pcFile, 256 - 1 ); m_f = 0; }
61 
62 
63 public:
64     virtual void SAL_CALL writeBytes(const Sequence< sal_Int8 >& aData)
65 		throw  (NotConnectedException, BufferSizeExceededException, RuntimeException);
66     virtual void SAL_CALL flush(void)
67 		throw  (NotConnectedException, BufferSizeExceededException, RuntimeException);
68     virtual void SAL_CALL closeOutput(void)
69 		throw  (NotConnectedException, BufferSizeExceededException, RuntimeException);
70 private:
71 	char m_pcFile[256];
72 	FILE *m_f;
73 };
74 
75 
writeBytes(const Sequence<sal_Int8> & aData)76 void OFileWriter::writeBytes(const Sequence< sal_Int8 >& aData)
77 	throw  (NotConnectedException, BufferSizeExceededException, RuntimeException)
78 {
79 	if( ! m_f ) {
80 		m_f = fopen( m_pcFile , "w" );
81 	}
82 
83    	fwrite( aData.getConstArray() , 1 , aData.getLength() , m_f );
84 }
85 
86 
flush(void)87 void OFileWriter::flush(void)
88 	throw  (NotConnectedException, BufferSizeExceededException, RuntimeException)
89 {
90 	fflush( m_f );
91 }
92 
closeOutput(void)93 void OFileWriter::closeOutput(void)
94 	throw  (NotConnectedException, BufferSizeExceededException, RuntimeException)
95 {
96 	fclose( m_f );
97 	m_f = 0;
98 }
99 
100 
101 class OSaxWriterTest :
102 		public WeakImplHelper1< XSimpleTest >
103 {
104 public:
OSaxWriterTest(const Reference<XMultiServiceFactory> & rFactory)105 	OSaxWriterTest( const Reference < XMultiServiceFactory > & rFactory ) : m_rFactory( rFactory )
106 	{
107 
108 	}
~OSaxWriterTest()109 	~OSaxWriterTest() {}
110 
111 
112 public:
113     virtual void SAL_CALL testInvariant(
114 		const OUString& TestName,
115 		const Reference < XInterface >& TestObject)
116 		throw  (	IllegalArgumentException,
117 					RuntimeException);
118 
119     virtual sal_Int32 SAL_CALL test(
120 		const OUString& TestName,
121 		const Reference < XInterface >& TestObject,
122 		sal_Int32 hTestHandle)
123 		throw  (	IllegalArgumentException,RuntimeException);
124 
125     virtual sal_Bool SAL_CALL testPassed(void)
126 		throw  (	RuntimeException);
127     virtual Sequence< OUString > SAL_CALL getErrors(void) 				throw  (RuntimeException);
128     virtual Sequence< Any > SAL_CALL getErrorExceptions(void) 		throw  (RuntimeException);
129     virtual Sequence< OUString > SAL_CALL getWarnings(void) 			throw  (RuntimeException);
130 
131 private:
132 	void testSimple( const Reference< XExtendedDocumentHandler > &r );
133 	void testExceptions( const Reference< XExtendedDocumentHandler > &r );
134 	void testDTD( const Reference< XExtendedDocumentHandler > &r );
135 	void testPerformance( const Reference< XExtendedDocumentHandler > &r );
136 	void writeParagraph( const Reference< XExtendedDocumentHandler > &r , const OUString & s);
137 
138 private:
139 	Sequence<Any>  		m_seqExceptions;
140 	Sequence<OUString> 		m_seqErrors;
141 	Sequence<OUString> 		m_seqWarnings;
142 	Reference < XMultiServiceFactory > m_rFactory;
143 
144 };
145 
146 
147 
148 /*----------------------------------------
149 *
150 * 	Attributlist implementation
151 *
152 *----------------------------------------*/
153 struct AttributeListImpl_impl;
154 class AttributeListImpl : public WeakImplHelper1< XAttributeList >
155 {
156 public:
157 	AttributeListImpl();
158 	AttributeListImpl( const AttributeListImpl & );
159 	~AttributeListImpl();
160 
161 public:
162     virtual sal_Int16 SAL_CALL getLength(void) throw  (RuntimeException);
163     virtual OUString SAL_CALL getNameByIndex(sal_Int16 i) throw  (RuntimeException);
164     virtual OUString SAL_CALL getTypeByIndex(sal_Int16 i) throw  (RuntimeException);
165     virtual OUString SAL_CALL getTypeByName(const OUString& aName) throw  (RuntimeException);
166     virtual OUString SAL_CALL getValueByIndex(sal_Int16 i) throw  (RuntimeException);
167     virtual OUString SAL_CALL getValueByName(const OUString& aName) throw  (RuntimeException);
168 
169 public:
170 	void addAttribute( const OUString &sName ,
171 					   const OUString &sType ,
172 					   const OUString &sValue );
173 	void clear();
174 
175 private:
176 	struct AttributeListImpl_impl *m_pImpl;
177 };
178 
179 
180 struct TagAttribute
181 {
TagAttributesax_test::TagAttribute182 	TagAttribute(){}
TagAttributesax_test::TagAttribute183 	TagAttribute( const OUString &sName,
184 				  const OUString &sType ,
185 				  const OUString &sValue )
186 	{
187 		this->sName 	= sName;
188 		this->sType 	= sType;
189 		this->sValue 	= sValue;
190 	}
191 
192 	OUString sName;
193 	OUString sType;
194 	OUString sValue;
195 };
196 
197 struct AttributeListImpl_impl
198 {
AttributeListImpl_implsax_test::AttributeListImpl_impl199 	AttributeListImpl_impl()
200 	{
201 		// performance improvement during adding
202 		vecAttribute.reserve(20);
203 	}
204 	vector<struct TagAttribute> vecAttribute;
205 };
206 
207 
208 
getLength(void)209 sal_Int16 AttributeListImpl::getLength(void) throw  (RuntimeException)
210 {
211 	return m_pImpl->vecAttribute.size();
212 }
213 
214 
AttributeListImpl(const AttributeListImpl & r)215 AttributeListImpl::AttributeListImpl( const AttributeListImpl &r )
216 {
217 	m_pImpl = new AttributeListImpl_impl;
218 	*m_pImpl = *(r.m_pImpl);
219 }
220 
getNameByIndex(sal_Int16 i)221 OUString AttributeListImpl::getNameByIndex(sal_Int16 i) throw  (RuntimeException)
222 {
223 	if( i < m_pImpl->vecAttribute.size() ) {
224 		return m_pImpl->vecAttribute[i].sName;
225 	}
226 	return OUString();
227 }
228 
229 
getTypeByIndex(sal_Int16 i)230 OUString AttributeListImpl::getTypeByIndex(sal_Int16 i) throw  (RuntimeException)
231 {
232 	if( i < m_pImpl->vecAttribute.size() ) {
233 		return m_pImpl->vecAttribute[i].sType;
234 	}
235 	return OUString();
236 }
237 
getValueByIndex(sal_Int16 i)238 OUString AttributeListImpl::getValueByIndex(sal_Int16 i) throw  (RuntimeException)
239 {
240 	if( i < m_pImpl->vecAttribute.size() ) {
241 		return m_pImpl->vecAttribute[i].sValue;
242 	}
243 	return OUString();
244 
245 }
246 
getTypeByName(const OUString & sName)247 OUString AttributeListImpl::getTypeByName( const OUString& sName ) throw  (RuntimeException)
248 {
249 	vector<struct TagAttribute>::iterator ii = m_pImpl->vecAttribute.begin();
250 
251 	for( ; ii != m_pImpl->vecAttribute.end() ; ii ++ ) {
252 		if( (*ii).sName == sName ) {
253 			return (*ii).sType;
254 		}
255 	}
256 	return OUString();
257 }
258 
getValueByName(const OUString & sName)259 OUString AttributeListImpl::getValueByName(const OUString& sName) throw  (RuntimeException)
260 {
261 	vector<struct TagAttribute>::iterator ii = m_pImpl->vecAttribute.begin();
262 
263 	for( ; ii != m_pImpl->vecAttribute.end() ; ii ++ ) {
264 		if( (*ii).sName == sName ) {
265 			return (*ii).sValue;
266 		}
267 	}
268 	return OUString();
269 }
270 
271 
272 
AttributeListImpl()273 AttributeListImpl::AttributeListImpl()
274 {
275 	m_pImpl = new AttributeListImpl_impl;
276 }
277 
278 
279 
~AttributeListImpl()280 AttributeListImpl::~AttributeListImpl()
281 {
282 	delete m_pImpl;
283 }
284 
285 
addAttribute(const OUString & sName,const OUString & sType,const OUString & sValue)286 void AttributeListImpl::addAttribute( 	const OUString &sName ,
287 										const OUString &sType ,
288 										const OUString &sValue )
289 {
290 	m_pImpl->vecAttribute.push_back( TagAttribute( sName , sType , sValue ) );
291 }
292 
clear()293 void AttributeListImpl::clear()
294 {
295 	m_pImpl->vecAttribute.clear();
296 
297 }
298 
299 
300 
301 
302 
303 
304 
305 
306 
307 
308 
309 /**
310 * for external binding
311 *
312 *
313 **/
OSaxWriterTest_CreateInstance(const Reference<XMultiServiceFactory> & rSMgr)314 Reference < XInterface > SAL_CALL OSaxWriterTest_CreateInstance( const Reference < XMultiServiceFactory > & rSMgr ) throw (Exception)
315 {
316 	OSaxWriterTest *p = new OSaxWriterTest( rSMgr );
317 	Reference < XInterface > xService = *p;
318 	return xService;
319 }
320 
OSaxWriterTest_getServiceName()321 OUString     OSaxWriterTest_getServiceName( ) throw  ()
322 {
323 	return OUString( RTL_CONSTASCII_USTRINGPARAM("test.com.sun.star.xml.sax.Writer"));
324 }
325 
OSaxWriterTest_getImplementationName()326 OUString 	OSaxWriterTest_getImplementationName( ) throw  ()
327 {
328 	return OUString( RTL_CONSTASCII_USTRINGPARAM("test.extensions.xml.sax.Writer"));
329 }
330 
OSaxWriterTest_getSupportedServiceNames()331 Sequence<OUString> OSaxWriterTest_getSupportedServiceNames( ) throw  ()
332 {
333 	Sequence<OUString> aRet(1);
334 
335 	aRet.getArray()[0] = OSaxWriterTest_getImplementationName( );
336 
337 	return aRet;
338 }
339 
340 
341 
testInvariant(const OUString & TestName,const Reference<XInterface> & TestObject)342 void OSaxWriterTest::testInvariant( const OUString& TestName,
343 									const Reference < XInterface >& TestObject )
344 	throw  (	IllegalArgumentException, RuntimeException)
345 {
346 	if( OUString::createFromAscii("com.sun.star.xml.sax.Writer") == TestName ) {
347 		Reference< XDocumentHandler > doc( TestObject , UNO_QUERY );
348 		Reference< XExtendedDocumentHandler > ext( TestObject , UNO_QUERY );
349 		Reference< XActiveDataSource > source( TestObject , UNO_QUERY );
350 
351 		ERROR_ASSERT( doc.is() , "XDocumentHandler cannot be queried" );
352 		ERROR_ASSERT( ext.is() , "XExtendedDocumentHandler cannot be queried" );
353 		ERROR_ASSERT( source.is() , "XActiveDataSource cannot be queried" );
354 	}
355 	else {
356 		BUILD_ERROR( 0 , "wrong test" );
357 	}
358 }
359 
360 
test(const OUString & TestName,const Reference<XInterface> & TestObject,sal_Int32 hTestHandle)361 sal_Int32 OSaxWriterTest::test(
362 	const OUString& TestName,
363 	const Reference < XInterface >& TestObject,
364 	sal_Int32 hTestHandle)
365 	throw  (	IllegalArgumentException,RuntimeException)
366 {
367 	if( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Writer")) == TestName )
368 	{
369 		try
370 		{
371 			if( 0 == hTestHandle )
372 			{
373 				testInvariant( TestName , TestObject );
374 			}
375 			else
376 			{
377 				Reference< XExtendedDocumentHandler > writer( TestObject , UNO_QUERY );
378 
379 				if( 1 == hTestHandle ) {
380 					testSimple( writer );
381 				}
382 				else if( 2 == hTestHandle ) {
383 					testExceptions( writer );
384 				}
385 				else if( 3 == hTestHandle ) {
386 					testDTD( writer );
387 				}
388 				else if( 4 == hTestHandle ) {
389 					testPerformance( writer );
390 				}
391 			}
392 		}
393 		catch( Exception & e )  {
394 			OString o = OUStringToOString( e.Message , RTL_TEXTENCODING_ASCII_US );
395 			BUILD_ERROR( 0 , o.getStr() );
396 		}
397 		catch( ... )
398 		{
399 			BUILD_ERROR( 0 , "unknown exception (Exception is  not base class)" );
400 		}
401 
402 		hTestHandle ++;
403 
404 		if( hTestHandle >= 5) {
405 			// all tests finished.
406 			hTestHandle = -1;
407 		}
408 	}
409 	else {
410 		BUILD_ERROR( 0 , "service not supported by test." );
411 	}
412 	return hTestHandle;
413 }
414 
415 
416 
testPassed(void)417 sal_Bool OSaxWriterTest::testPassed(void)					throw  (RuntimeException)
418 {
419 	return m_seqErrors.getLength() == 0;
420 }
421 
422 
getErrors(void)423 Sequence< OUString > OSaxWriterTest::getErrors(void) throw  (RuntimeException)
424 {
425 	return m_seqErrors;
426 }
427 
428 
getErrorExceptions(void)429 Sequence< Any > OSaxWriterTest::getErrorExceptions(void) 					throw  (RuntimeException)
430 {
431 	return m_seqExceptions;
432 }
433 
434 
getWarnings(void)435 Sequence< OUString > OSaxWriterTest::getWarnings(void) 						throw  (RuntimeException)
436 {
437 	return m_seqWarnings;
438 }
439 
writeParagraph(const Reference<XExtendedDocumentHandler> & r,const OUString & s)440 void OSaxWriterTest::writeParagraph(
441 	const Reference< XExtendedDocumentHandler > &r ,
442 	const OUString & s)
443 {
444 	int nMax = s.getLength();
445 	int nStart = 0;
446 
447 	Sequence<sal_uInt16> seq( s.getLength() );
448 	memcpy( seq.getArray() , s.getStr() , s.getLength() * sizeof( sal_uInt16 ) );
449 
450 	for( int n = 1 ; n < nMax ; n++ ){
451 		if( 32 == seq.getArray()[n] ) {
452 			r->allowLineBreak();
453 			r->characters( s.copy( nStart , n - nStart ) );
454 			nStart = n;
455 		}
456 	}
457 	r->allowLineBreak();
458 	r->characters( s.copy( nStart , n - nStart ) );
459 }
460 
461 
462 
testSimple(const Reference<XExtendedDocumentHandler> & r)463 void OSaxWriterTest::testSimple( const Reference< XExtendedDocumentHandler > &r )
464 {
465 	OUString testParagraph = OUString( RTL_CONSTASCII_USTRINGPARAM(
466 		"Dies ist ein bloeder Test um zu uberpruefen, ob der SAXWriter "
467 		"wohl Zeilenumbrueche halbwegs richtig macht oder ob er die Zeile "
468 		"bis zum bitteren Ende schreibt." ));
469 
470 	OFileWriter *pw = new OFileWriter("output.xml");
471 	AttributeListImpl *pList = new AttributeListImpl;
472 
473 	Reference< XAttributeList > rList( (XAttributeList *) pList , UNO_QUERY );
474 	Reference< XOutputStream > ref( ( XOutputStream * ) pw , UNO_QUERY );
475 
476 	Reference< XActiveDataSource > source( r , UNO_QUERY );
477 
478 	ERROR_ASSERT( ref.is() , "no output stream" );
479 	ERROR_ASSERT( source.is() , "no active data source" );
480 
481 	source->setOutputStream( ref );
482 
483 	r->startDocument();
484 
485 	pList->addAttribute( OUString( RTL_CONSTASCII_USTRINGPARAM("Arg1" )),
486 						 OUString( RTL_CONSTASCII_USTRINGPARAM("CDATA")) ,
487 						 OUString( RTL_CONSTASCII_USTRINGPARAM("bla\n	u")) );
488 	pList->addAttribute( OUString( RTL_CONSTASCII_USTRINGPARAM("Arg2")) ,
489 						 OUString( RTL_CONSTASCII_USTRINGPARAM("CDATA")) ,
490 						 OUString( RTL_CONSTASCII_USTRINGPARAM("blub")) );
491 
492 	r->startElement( OUString( RTL_CONSTASCII_USTRINGPARAM("tag1"))  , rList );
493 	r->ignorableWhitespace( OUString() );
494 
495 	r->characters( OUString( RTL_CONSTASCII_USTRINGPARAM("huhu")) );
496 	r->ignorableWhitespace( OUString() );
497 
498 	r->startElement( OUString( RTL_CONSTASCII_USTRINGPARAM("hi")) , rList );
499 	r->ignorableWhitespace( OUString() );
500 
501 	// the enpassant must be converted & -> &amp;
502 	r->characters( OUString( RTL_CONSTASCII_USTRINGPARAM("&#252;")) );
503 
504 	// Test added for mib. Tests if errors during conversions occurs
505 	r->ignorableWhitespace( OUString() );
506 	sal_Char array[256];
507 	for( sal_Int32 n = 32 ; n < 254 ; n ++ ) {
508 		array[n-32] = n;
509 	}
510 	array[254-32] = 0;
511 	r->characters(
512 		OStringToOUString( array , RTL_TEXTENCODING_SYMBOL )
513 		);
514 	r->ignorableWhitespace( OUString() );
515 
516 	// '>' must not be converted
517 	r->startCDATA();
518 	r->characters( OUString( RTL_CONSTASCII_USTRINGPARAM(">fsfsdf<"))  );
519 	r->endCDATA();
520 	r->ignorableWhitespace( OUString() );
521 
522 	writeParagraph( r , testParagraph );
523 
524 
525 	r->ignorableWhitespace( OUString() );
526 	r->comment( OUString( RTL_CONSTASCII_USTRINGPARAM("Dies ist ein Kommentar !")) );
527 	r->ignorableWhitespace( OUString() );
528 
529 	r->startElement( OUString( RTL_CONSTASCII_USTRINGPARAM("emptytagtest"))  , rList );
530 	r->endElement( OUString( RTL_CONSTASCII_USTRINGPARAM("emptytagtest")) );
531 
532 	r->endElement( OUString( RTL_CONSTASCII_USTRINGPARAM("hi")) );
533 	r->ignorableWhitespace( OUString() );
534 
535 	r->endElement( OUString( RTL_CONSTASCII_USTRINGPARAM("tag1")) );
536 	r->endDocument();
537 
538 }
539 
testExceptions(const Reference<XExtendedDocumentHandler> & r)540 void OSaxWriterTest::testExceptions( const Reference< XExtendedDocumentHandler > & r )
541 {
542 
543 	OFileWriter *pw = new OFileWriter("output2.xml");
544 	AttributeListImpl *pList = new AttributeListImpl;
545 
546 	Reference< XAttributeList > rList( (XAttributeList *) pList , UNO_QUERY );
547 	Reference< XOutputStream > ref( ( XOutputStream * ) pw , UNO_QUERY );
548 
549 	Reference< XActiveDataSource > source( r , UNO_QUERY );
550 
551 	ERROR_ASSERT( ref.is() , "no output stream" );
552 	ERROR_ASSERT( source.is() , "no active data source" );
553 
554 	source->setOutputStream( ref );
555 
556 	{ // startDocument must be called before start element
557 		sal_Bool bException = sal_True;
558 		try
559 		{
560 			r->startElement( OUString( RTL_CONSTASCII_USTRINGPARAM("huhu")) , rList );
561 			bException = sal_False;
562 		}
563 		catch( SAXException &e )
564 		{
565 
566 		}
567 		ERROR_ASSERT( bException , "expected exception not thrown !" );
568 	}
569 
570 	r->startDocument();
571 
572 	r->startElement( OUString( RTL_CONSTASCII_USTRINGPARAM("huhu")) , rList );
573 	r->startCDATA();
574 
575 	{
576 		sal_Bool bException = sal_True;
577 		try{
578 			r->startElement( OUString( RTL_CONSTASCII_USTRINGPARAM("huhu")) , rList );
579 			bException = sal_False;
580 		}
581 		catch( SAXException &e ) {
582 
583 		}
584 		ERROR_ASSERT( bException , "expected exception not thrown !" );
585 	}
586 
587 	r->endCDATA();
588 
589 	{
590 		sal_Unicode array[] = { 'a' , 'b' , 4 , 9 , 10 };
591 		OUString o( array , 5 );
592 		try
593 		{
594 			r->characters( o );
595 			ERROR_ASSERT( 0 , "Writer allowed to write forbidden characters" );
596 		}
597 		catch( SAXException & e )
598 		{
599 
600 		}
601 	}
602 	r->endElement( OUString( RTL_CONSTASCII_USTRINGPARAM("huhu")) );
603 
604 	r->endDocument();
605 }
606 
607 
testDTD(const Reference<XExtendedDocumentHandler> & r)608 void OSaxWriterTest::testDTD(const  Reference< XExtendedDocumentHandler > &r )
609 {
610 	OFileWriter *pw = new OFileWriter("outputDTD.xml");
611 	AttributeListImpl *pList = new AttributeListImpl;
612 
613 	Reference< XAttributeList > rList( (XAttributeList *) pList , UNO_QUERY );
614 	Reference< XOutputStream > ref( ( XOutputStream * ) pw , UNO_QUERY );
615 
616 	Reference< XActiveDataSource > source( r , UNO_QUERY );
617 
618 	ERROR_ASSERT( ref.is() , "no output stream" );
619 	ERROR_ASSERT( source.is() , "no active data source" );
620 
621 	source->setOutputStream( ref );
622 
623 
624 	r->startDocument();
625 	r->unknown( OUString( RTL_CONSTASCII_USTRINGPARAM("<!DOCTYPE iCalendar >\n")) );
626 	r->startElement( OUString( RTL_CONSTASCII_USTRINGPARAM("huhu")) , rList );
627 
628 	r->endElement( OUString( RTL_CONSTASCII_USTRINGPARAM("huhu")) );
629 	r->endDocument();
630 }
631 
testPerformance(const Reference<XExtendedDocumentHandler> & r)632 void OSaxWriterTest::testPerformance(const  Reference< XExtendedDocumentHandler > &r )
633 {
634 	OFileWriter *pw = new OFileWriter("testPerformance.xml");
635 	AttributeListImpl *pList = new AttributeListImpl;
636 
637 	OUString testParagraph =
638 		OUString( RTL_CONSTASCII_USTRINGPARAM(
639 			"Dies ist ein bloeder Test um zu uberpruefen, ob der SAXWriter "
640 			"wohl Zeilenumbrueche halbwegs richtig macht oder ob er die Zeile "
641 			"bis zum bitteren Ende schreibt." ));
642 
643 
644 	Reference< XAttributeList > rList( (XAttributeList *) pList , UNO_QUERY );
645 	Reference< XOutputStream > ref( ( XOutputStream * ) pw , UNO_QUERY );
646 
647 	Reference< XActiveDataSource > source( r , UNO_QUERY );
648 
649 	ERROR_ASSERT( ref.is() , "no output stream" );
650 	ERROR_ASSERT( source.is() , "no active data source" );
651 
652 	source->setOutputStream( ref );
653 
654 	TimeValue aStartTime, aEndTime;
655 	osl_getSystemTime( &aStartTime );
656 
657 
658 	r->startDocument();
659 	// just write a bunch of xml tags !
660 	// for performance testing
661 	sal_Int32 i2;
662 	OUString huhu( RTL_CONSTASCII_USTRINGPARAM("huhu") );
663 	OUString emptyString;
664 	const int ITERATIONS = 125;
665 	for( i2 = 0 ; i2 < ITERATIONS ; i2 ++ )
666 	{
667 		r->startElement( OUString( RTL_CONSTASCII_USTRINGPARAM("tag") ) +
668 						 OUString::valueOf( i2 ), rList );
669 		for( sal_Int32 i = 0 ; i < 450 ; i ++ )
670 		{
671 			r->ignorableWhitespace( emptyString );
672 			r->startElement( huhu , rList );
673 			r->characters( testParagraph );
674 
675 			r->ignorableWhitespace( emptyString );
676 			r->endElement( huhu );
677 		}
678 	}
679 	for( i2 = ITERATIONS-1 ; i2 >= 0  ; i2-- )
680 	{
681 		r->ignorableWhitespace( emptyString );
682 		r->endElement( OUString( RTL_CONSTASCII_USTRINGPARAM("tag") ) + OUString::valueOf( i2 ) );
683 	}
684 
685 	r->endDocument();
686 
687 	osl_getSystemTime( &aEndTime );
688 
689 	double fStart = (double)aStartTime.Seconds + ((double)aStartTime.Nanosec / 1000000000.0);
690 	double fEnd = (double)aEndTime.Seconds + ((double)aEndTime.Nanosec / 1000000000.0);
691 
692 	printf( "Performance writing : %g s\n" , fEnd - fStart );
693 }
694 }
695