update dev300-m58
[ooovba.git] / sax / test / saxdemo.cxx
blobfd8656bb5b167daf4ef7d57c2211637e6495c4a0
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: saxdemo.cxx,v $
10 * $Revision: 1.8 $
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 //------------------------------------------------------
32 // testcomponent - Loads a service and its testcomponent from dlls performs a test.
33 // Expands the dll-names depending on the actual environment.
34 // Example : testcomponent stardiv.uno.io.Pipe stm
36 // Therefor the testcode must exist in teststm and the testservice must be named test.stardiv.uno.io.Pipe
39 #include <stdio.h>
40 #include <vector>
42 #include <com/sun/star/registry/XImplementationRegistration.hpp>
43 #include <com/sun/star/lang/XComponent.hpp>
45 #include <com/sun/star/xml/sax/SAXParseException.hpp>
46 #include <com/sun/star/xml/sax/XParser.hpp>
47 #include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
49 #include <com/sun/star/io/XOutputStream.hpp>
50 #include <com/sun/star/io/XActiveDataSource.hpp>
52 #include <cppuhelper/servicefactory.hxx>
53 #include <cppuhelper/implbase1.hxx>
54 #include <cppuhelper/implbase3.hxx>
56 #include <vos/dynload.hxx>
57 #include <vos/diagnose.hxx>
59 using namespace ::rtl;
60 using namespace ::std;
61 using namespace ::cppu;
62 using namespace ::com::sun::star::uno;
63 using namespace ::com::sun::star::lang;
64 using namespace ::com::sun::star::registry;
65 using namespace ::com::sun::star::xml::sax;
66 using namespace ::com::sun::star::io;
69 /************
70 * Sequence of bytes -> InputStream
71 ************/
72 class OInputStream : public WeakImplHelper1 < XInputStream >
74 public:
75 OInputStream( const Sequence< sal_Int8 >&seq ) :
76 m_seq( seq ),
77 nPos( 0 )
80 public:
81 virtual sal_Int32 SAL_CALL readBytes( Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
82 throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
84 nBytesToRead = (nBytesToRead > m_seq.getLength() - nPos ) ?
85 m_seq.getLength() - nPos :
86 nBytesToRead;
87 aData = Sequence< sal_Int8 > ( &(m_seq.getConstArray()[nPos]) , nBytesToRead );
88 nPos += nBytesToRead;
89 return nBytesToRead;
91 virtual sal_Int32 SAL_CALL readSomeBytes(
92 ::com::sun::star::uno::Sequence< sal_Int8 >& aData,
93 sal_Int32 nMaxBytesToRead )
94 throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
96 return readBytes( aData, nMaxBytesToRead );
98 virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip )
99 throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
101 // not implemented
103 virtual sal_Int32 SAL_CALL available( )
104 throw(NotConnectedException, IOException, RuntimeException)
106 return m_seq.getLength() - nPos;
108 virtual void SAL_CALL closeInput( )
109 throw(NotConnectedException, IOException, RuntimeException)
111 // not needed
113 sal_Int32 nPos;
114 Sequence< sal_Int8> m_seq;
117 //-------------------------------
118 // Helper : create an input stream from a file
119 //------------------------------
120 Reference< XInputStream > createStreamFromFile(
121 const char *pcFile )
123 FILE *f = fopen( pcFile , "rb" );
124 Reference< XInputStream > r;
126 if( f ) {
127 fseek( f , 0 , SEEK_END );
128 int nLength = ftell( f );
129 fseek( f , 0 , SEEK_SET );
131 Sequence<sal_Int8> seqIn(nLength);
132 fread( seqIn.getArray() , nLength , 1 , f );
134 r = Reference< XInputStream > ( new OInputStream( seqIn ) );
135 fclose( f );
137 return r;
140 //-----------------------------------------
141 // The document handler, which is needed for the saxparser
142 // The Documenthandler for reading sax
143 //-----------------------------------------
144 class TestDocumentHandler :
145 public WeakImplHelper3< XExtendedDocumentHandler , XEntityResolver , XErrorHandler >
147 public:
148 TestDocumentHandler( )
152 public: // Error handler
153 virtual void SAL_CALL error(const Any& aSAXParseException) throw (SAXException, RuntimeException)
155 printf( "Error !\n" );
156 throw SAXException(
157 OUString( RTL_CONSTASCII_USTRINGPARAM("error from error handler")) ,
158 Reference < XInterface >() ,
159 aSAXParseException );
161 virtual void SAL_CALL fatalError(const Any& aSAXParseException) throw (SAXException, RuntimeException)
163 printf( "Fatal Error !\n" );
165 virtual void SAL_CALL warning(const Any& aSAXParseException) throw (SAXException, RuntimeException)
167 printf( "Warning !\n" );
171 public: // ExtendedDocumentHandler
173 virtual void SAL_CALL startDocument(void) throw (SAXException, RuntimeException)
175 m_iElementCount = 0;
176 m_iAttributeCount = 0;
177 m_iWhitespaceCount =0;
178 m_iCharCount=0;
179 printf( "document started\n" );
181 virtual void SAL_CALL endDocument(void) throw (SAXException, RuntimeException)
183 printf( "document finished\n" );
184 printf( "(ElementCount %d),(AttributeCount %d),(WhitespaceCount %d),(CharCount %d)\n",
185 m_iElementCount, m_iAttributeCount, m_iWhitespaceCount , m_iCharCount );
188 virtual void SAL_CALL startElement(const OUString& aName,
189 const Reference< XAttributeList > & xAttribs)
190 throw (SAXException,RuntimeException)
192 m_iElementCount ++;
193 m_iAttributeCount += xAttribs->getLength();
196 virtual void SAL_CALL endElement(const OUString& aName) throw (SAXException,RuntimeException)
198 // ignored
201 virtual void SAL_CALL characters(const OUString& aChars) throw (SAXException,RuntimeException)
203 m_iCharCount += aChars.getLength();
205 virtual void SAL_CALL ignorableWhitespace(const OUString& aWhitespaces) throw (SAXException,RuntimeException)
207 m_iWhitespaceCount += aWhitespaces.getLength();
210 virtual void SAL_CALL processingInstruction(const OUString& aTarget, const OUString& aData) throw (SAXException,RuntimeException)
212 // ignored
215 virtual void SAL_CALL setDocumentLocator(const Reference< XLocator> & xLocator)
216 throw (SAXException,RuntimeException)
218 // ignored
221 virtual InputSource SAL_CALL resolveEntity(
222 const OUString& sPublicId,
223 const OUString& sSystemId)
224 throw (SAXException,RuntimeException)
226 InputSource source;
227 source.sSystemId = sSystemId;
228 source.sPublicId = sPublicId;
230 source.aInputStream = createStreamFromFile(
231 OUStringToOString( sSystemId , RTL_TEXTENCODING_ASCII_US) );
233 return source;
236 virtual void SAL_CALL startCDATA(void) throw (SAXException,RuntimeException)
239 virtual void SAL_CALL endCDATA(void) throw (SAXException,RuntimeException)
242 virtual void SAL_CALL comment(const OUString& sComment) throw (SAXException,RuntimeException)
245 virtual void SAL_CALL unknown(const OUString& sString) throw (SAXException,RuntimeException)
249 virtual void SAL_CALL allowLineBreak( void) throw (SAXException, RuntimeException )
254 public:
255 int m_iElementCount;
256 int m_iAttributeCount;
257 int m_iWhitespaceCount;
258 int m_iCharCount;
261 //--------------------------------------
262 // helper implementation for writing
263 // implements an XAttributeList
264 //-------------------------------------
265 struct AttributeListImpl_impl;
266 class AttributeListImpl : public WeakImplHelper1< XAttributeList >
268 public:
269 AttributeListImpl();
270 AttributeListImpl( const AttributeListImpl & );
271 ~AttributeListImpl();
273 public:
274 virtual sal_Int16 SAL_CALL getLength(void) throw (RuntimeException);
275 virtual OUString SAL_CALL getNameByIndex(sal_Int16 i) throw (RuntimeException);
276 virtual OUString SAL_CALL getTypeByIndex(sal_Int16 i) throw (RuntimeException);
277 virtual OUString SAL_CALL getTypeByName(const OUString& aName) throw (RuntimeException);
278 virtual OUString SAL_CALL getValueByIndex(sal_Int16 i) throw (RuntimeException);
279 virtual OUString SAL_CALL getValueByName(const OUString& aName) throw (RuntimeException);
281 public:
282 void addAttribute( const OUString &sName ,
283 const OUString &sType ,
284 const OUString &sValue );
285 void clear();
287 private:
288 struct AttributeListImpl_impl *m_pImpl;
292 struct TagAttribute
294 TagAttribute(){}
295 TagAttribute( const OUString &sName,
296 const OUString &sType ,
297 const OUString &sValue )
299 this->sName = sName;
300 this->sType = sType;
301 this->sValue = sValue;
304 OUString sName;
305 OUString sType;
306 OUString sValue;
309 struct AttributeListImpl_impl
311 AttributeListImpl_impl()
313 // performance improvement during adding
314 vecAttribute.reserve(20);
316 vector<struct TagAttribute> vecAttribute;
321 sal_Int16 AttributeListImpl::getLength(void) throw (RuntimeException)
323 return m_pImpl->vecAttribute.size();
327 AttributeListImpl::AttributeListImpl( const AttributeListImpl &r )
329 m_pImpl = new AttributeListImpl_impl;
330 *m_pImpl = *(r.m_pImpl);
333 OUString AttributeListImpl::getNameByIndex(sal_Int16 i) throw (RuntimeException)
335 if( i < m_pImpl->vecAttribute.size() ) {
336 return m_pImpl->vecAttribute[i].sName;
338 return OUString();
342 OUString AttributeListImpl::getTypeByIndex(sal_Int16 i) throw (RuntimeException)
344 if( i < m_pImpl->vecAttribute.size() ) {
345 return m_pImpl->vecAttribute[i].sType;
347 return OUString();
350 OUString AttributeListImpl::getValueByIndex(sal_Int16 i) throw (RuntimeException)
352 if( i < m_pImpl->vecAttribute.size() ) {
353 return m_pImpl->vecAttribute[i].sValue;
355 return OUString();
359 OUString AttributeListImpl::getTypeByName( const OUString& sName ) throw (RuntimeException)
361 vector<struct TagAttribute>::iterator ii = m_pImpl->vecAttribute.begin();
363 for( ; ii != m_pImpl->vecAttribute.end() ; ii ++ ) {
364 if( (*ii).sName == sName ) {
365 return (*ii).sType;
368 return OUString();
371 OUString AttributeListImpl::getValueByName(const OUString& sName) throw (RuntimeException)
373 vector<struct TagAttribute>::iterator ii = m_pImpl->vecAttribute.begin();
375 for( ; ii != m_pImpl->vecAttribute.end() ; ii ++ ) {
376 if( (*ii).sName == sName ) {
377 return (*ii).sValue;
380 return OUString();
385 AttributeListImpl::AttributeListImpl()
387 m_pImpl = new AttributeListImpl_impl;
392 AttributeListImpl::~AttributeListImpl()
394 delete m_pImpl;
398 void AttributeListImpl::addAttribute( const OUString &sName ,
399 const OUString &sType ,
400 const OUString &sValue )
402 m_pImpl->vecAttribute.push_back( TagAttribute( sName , sType , sValue ) );
405 void AttributeListImpl::clear()
407 m_pImpl->vecAttribute.clear();
411 //--------------------------------------
412 // helper function for writing
413 // ensures that linebreaks are inserted
414 // when writing a long text.
415 // Note: this implementation may be a bit slow,
416 // but it shows, how the SAX-Writer handles the allowLineBreak calls.
417 //--------------------------------------
418 void writeParagraphHelper(
419 const Reference< XExtendedDocumentHandler > &r ,
420 const OUString & s)
422 int nMax = s.getLength();
423 int nStart = 0;
425 Sequence<sal_uInt16> seq( s.getLength() );
426 memcpy( seq.getArray() , s.getStr() , s.getLength() * sizeof( sal_uInt16 ) );
428 for( int n = 1 ; n < nMax ; n++ ){
429 if( 32 == seq.getArray()[n] ) {
430 r->allowLineBreak();
431 r->characters( s.copy( nStart , n - nStart ) );
432 nStart = n;
435 r->allowLineBreak();
436 r->characters( s.copy( nStart , n - nStart ) );
440 //---------------------------------
441 // helper implementation for SAX-Writer
442 // writes data to a file
443 //--------------------------------
444 class OFileWriter :
445 public WeakImplHelper1< XOutputStream >
447 public:
448 OFileWriter( char *pcFile ) { strncpy( m_pcFile , pcFile, 256 - 1 ); m_f = 0; }
451 public:
452 virtual void SAL_CALL writeBytes(const Sequence< sal_Int8 >& aData)
453 throw (NotConnectedException, BufferSizeExceededException, RuntimeException);
454 virtual void SAL_CALL flush(void)
455 throw (NotConnectedException, BufferSizeExceededException, RuntimeException);
456 virtual void SAL_CALL closeOutput(void)
457 throw (NotConnectedException, BufferSizeExceededException, RuntimeException);
458 private:
459 char m_pcFile[256];
460 FILE *m_f;
464 void OFileWriter::writeBytes(const Sequence< sal_Int8 >& aData)
465 throw (NotConnectedException, BufferSizeExceededException, RuntimeException)
467 if( ! m_f ) {
468 m_f = fopen( m_pcFile , "w" );
471 fwrite( aData.getConstArray() , 1 , aData.getLength() , m_f );
475 void OFileWriter::flush(void)
476 throw (NotConnectedException, BufferSizeExceededException, RuntimeException)
478 fflush( m_f );
481 void OFileWriter::closeOutput(void)
482 throw (NotConnectedException, BufferSizeExceededException, RuntimeException)
484 fclose( m_f );
485 m_f = 0;
490 // Needed to switch on solaris threads
491 #ifdef SOLARIS
492 extern "C" void ChangeGlobalInit();
493 #endif
494 int main (int argc, char **argv)
497 if( argc < 3) {
498 printf( "usage : saxdemo inputfile outputfile\n" );
499 exit( 0 );
501 #ifdef SOLARIS
502 // switch on threads in solaris
503 ChangeGlobalInit();
504 #endif
506 // create service manager
507 Reference< XMultiServiceFactory > xSMgr = createRegistryServiceFactory(
508 OUString( RTL_CONSTASCII_USTRINGPARAM( "applicat.rdb" )) );
510 Reference < XImplementationRegistration > xReg;
513 // Create registration service
514 Reference < XInterface > x = xSMgr->createInstance(
515 OUString::createFromAscii( "com.sun.star.registry.ImplementationRegistration" ) );
516 xReg = Reference< XImplementationRegistration > ( x , UNO_QUERY );
518 catch( Exception & ) {
519 printf( "Couldn't create ImplementationRegistration service\n" );
520 exit(1);
523 OString sTestName;
526 // Load dll for the tested component
527 OUString aDllName =
528 OUString::createFromAscii( "sax.uno" SAL_DLLEXTENSION );
529 xReg->registerImplementation(
530 OUString::createFromAscii( "com.sun.star.loader.SharedLibrary" ),
531 aDllName,
532 Reference< XSimpleRegistry > () );
534 catch( Exception &e ) {
535 printf( "Couldn't reach sax dll\n" );
536 printf( "%s\n" , OUStringToOString( e.Message , RTL_TEXTENCODING_ASCII_US ).getStr() );
538 exit(1);
542 //--------------------------------
543 // parser demo
544 // read xml from a file and count elements
545 //--------------------------------
546 Reference< XInterface > x = xSMgr->createInstance(
547 OUString::createFromAscii( "com.sun.star.xml.sax.Parser" ) );
548 if( x.is() )
550 Reference< XParser > rParser( x , UNO_QUERY );
552 // create and connect the document handler to the parser
553 TestDocumentHandler *pDocHandler = new TestDocumentHandler( );
555 Reference < XDocumentHandler > rDocHandler( (XDocumentHandler *) pDocHandler );
556 Reference< XEntityResolver > rEntityResolver( (XEntityResolver *) pDocHandler );
558 rParser->setDocumentHandler( rDocHandler );
559 rParser->setEntityResolver( rEntityResolver );
561 // create the input stream
562 InputSource source;
563 source.aInputStream = createStreamFromFile( argv[1] );
564 source.sSystemId = OUString::createFromAscii( argv[1] );
568 // start parsing
569 rParser->parseStream( source );
572 catch( Exception & e )
574 OString o1 = OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8 );
575 printf( "Exception during parsing : %s\n" , o1.getStr() );
578 else
580 printf( "couln't create sax-parser component\n" );
584 //----------------------
585 // The SAX-Writer demo
586 //----------------------
587 x= xSMgr->createInstance( OUString::createFromAscii( "com.sun.star.xml.sax.Writer" ) );
588 if( x.is() )
590 printf( "start writing to %s\n" , argv[2] );
592 OFileWriter *pw = new OFileWriter( argv[2] );
593 Reference< XActiveDataSource > source( x , UNO_QUERY );
594 source->setOutputStream( Reference< XOutputStream> ( (XOutputStream*) pw ) );
596 AttributeListImpl *pList = new AttributeListImpl;
597 Reference< XAttributeList > rList( (XAttributeList *) pList );
599 Reference< XExtendedDocumentHandler > r( x , UNO_QUERY );
600 r->startDocument();
602 pList->addAttribute( OUString( RTL_CONSTASCII_USTRINGPARAM("Arg1" )),
603 OUString( RTL_CONSTASCII_USTRINGPARAM("CDATA")) ,
604 OUString( RTL_CONSTASCII_USTRINGPARAM("foo\n u")) );
605 pList->addAttribute( OUString( RTL_CONSTASCII_USTRINGPARAM("Arg2")) ,
606 OUString( RTL_CONSTASCII_USTRINGPARAM("CDATA")) ,
607 OUString( RTL_CONSTASCII_USTRINGPARAM("foo2")) );
609 r->startElement( OUString( RTL_CONSTASCII_USTRINGPARAM("tag1")) , rList );
610 // tells the writer to insert a linefeed
611 r->ignorableWhitespace( OUString() );
613 r->characters( OUString( RTL_CONSTASCII_USTRINGPARAM("huhu")) );
614 r->ignorableWhitespace( OUString() );
616 r->startElement( OUString( RTL_CONSTASCII_USTRINGPARAM("hi")) , rList );
617 r->ignorableWhitespace( OUString() );
619 // the enpassant must be converted & -> &amp;
620 r->characters( OUString( RTL_CONSTASCII_USTRINGPARAM("&#252;")) );
621 r->ignorableWhitespace( OUString() );
623 // '>' must not be converted
624 r->startCDATA();
625 r->characters( OUString( RTL_CONSTASCII_USTRINGPARAM(" > foo < ")) );
626 r->endCDATA();
627 r->ignorableWhitespace( OUString() );
629 OUString testParagraph = OUString( RTL_CONSTASCII_USTRINGPARAM(
630 "This is only a test to check, if the writer inserts line feeds "
631 "if needed or if the writer puts the whole text into one line." ));
632 writeParagraphHelper( r , testParagraph );
634 r->ignorableWhitespace( OUString() );
635 r->comment( OUString( RTL_CONSTASCII_USTRINGPARAM("This is a comment !")) );
636 r->ignorableWhitespace( OUString() );
638 r->startElement( OUString( RTL_CONSTASCII_USTRINGPARAM("emptytagtest")) , rList );
639 r->endElement( OUString( RTL_CONSTASCII_USTRINGPARAM("emptytagtest")) );
640 r->ignorableWhitespace( OUString() );
642 r->endElement( OUString( RTL_CONSTASCII_USTRINGPARAM("hi")) );
643 r->ignorableWhitespace( OUString() );
645 r->endElement( OUString( RTL_CONSTASCII_USTRINGPARAM("tag1")) );
646 r->endDocument();
648 printf( "finished writing\n" );
650 else
652 printf( "couln't create sax-writer component\n" );