bump product version to 4.1.6.2
[LibreOffice.git] / sax / test / saxdemo.cxx
bloba330e242f74688bd114018341160f7f1a80b609a
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 //------------------------------------------------------
21 // testcomponent - Loads a service and its testcomponent from dlls performs a test.
22 // Expands the dll-names depending on the actual environment.
23 // Example : testcomponent stardiv.uno.io.Pipe stm
25 // Therefor the testcode must exist in teststm and the testservice must be named test.stardiv.uno.io.Pipe
28 #include <stdio.h>
29 #include <vector>
30 #include <cstring>
32 #include <com/sun/star/registry/XImplementationRegistration.hpp>
33 #include <com/sun/star/lang/XComponent.hpp>
35 #include <com/sun/star/xml/sax/SAXParseException.hpp>
36 #include <com/sun/star/xml/sax/XParser.hpp>
37 #include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
39 #include <com/sun/star/io/XOutputStream.hpp>
40 #include <com/sun/star/io/XActiveDataSource.hpp>
42 #include <cppuhelper/servicefactory.hxx>
43 #include <cppuhelper/implbase1.hxx>
44 #include <cppuhelper/implbase3.hxx>
46 #include <osl/diagnose.h>
48 using namespace ::rtl;
49 using namespace ::std;
50 using namespace ::cppu;
51 using namespace ::com::sun::star::uno;
52 using namespace ::com::sun::star::lang;
53 using namespace ::com::sun::star::registry;
54 using namespace ::com::sun::star::xml::sax;
55 using namespace ::com::sun::star::io;
58 /************
59 * Sequence of bytes -> InputStream
60 ************/
61 class OInputStream : public WeakImplHelper1 < XInputStream >
63 public:
64 OInputStream( const Sequence< sal_Int8 >&seq ) :
65 m_seq( seq ),
66 nPos( 0 )
69 public:
70 virtual sal_Int32 SAL_CALL readBytes( Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
71 throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
73 nBytesToRead = (nBytesToRead > m_seq.getLength() - nPos ) ?
74 m_seq.getLength() - nPos :
75 nBytesToRead;
76 aData = Sequence< sal_Int8 > ( &(m_seq.getConstArray()[nPos]) , nBytesToRead );
77 nPos += nBytesToRead;
78 return nBytesToRead;
80 virtual sal_Int32 SAL_CALL readSomeBytes(
81 ::com::sun::star::uno::Sequence< sal_Int8 >& aData,
82 sal_Int32 nMaxBytesToRead )
83 throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
85 return readBytes( aData, nMaxBytesToRead );
87 virtual void SAL_CALL skipBytes( sal_Int32 /* nBytesToSkip */ )
88 throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
90 // not implemented
92 virtual sal_Int32 SAL_CALL available( )
93 throw(NotConnectedException, IOException, RuntimeException)
95 return m_seq.getLength() - nPos;
97 virtual void SAL_CALL closeInput( )
98 throw(NotConnectedException, IOException, RuntimeException)
100 // not needed
102 Sequence< sal_Int8> m_seq;
103 sal_Int32 nPos;
106 //-------------------------------
107 // Helper : create an input stream from a file
108 //------------------------------
109 Reference< XInputStream > createStreamFromFile(
110 const char *pcFile )
112 FILE *f = fopen( pcFile , "rb" );
113 Reference< XInputStream > r;
115 if( f ) {
116 fseek( f , 0 , SEEK_END );
117 int nLength = ftell( f );
118 fseek( f , 0 , SEEK_SET );
120 Sequence<sal_Int8> seqIn(nLength);
121 fread( seqIn.getArray() , nLength , 1 , f );
123 r = Reference< XInputStream > ( new OInputStream( seqIn ) );
124 fclose( f );
126 return r;
129 //-----------------------------------------
130 // The document handler, which is needed for the saxparser
131 // The Documenthandler for reading sax
132 //-----------------------------------------
133 class TestDocumentHandler :
134 public WeakImplHelper3< XExtendedDocumentHandler , XEntityResolver , XErrorHandler >
136 public:
137 TestDocumentHandler( )
141 public: // Error handler
142 virtual void SAL_CALL error(const Any& aSAXParseException) throw (SAXException, RuntimeException)
144 printf( "Error !\n" );
145 throw SAXException(
146 OUString( "error from error handler") ,
147 Reference < XInterface >() ,
148 aSAXParseException );
150 virtual void SAL_CALL fatalError(const Any& /* aSAXParseException */) throw (SAXException, RuntimeException)
152 printf( "Fatal Error !\n" );
154 virtual void SAL_CALL warning(const Any& /* aSAXParseException */) throw (SAXException, RuntimeException)
156 printf( "Warning !\n" );
160 public: // ExtendedDocumentHandler
162 virtual void SAL_CALL startDocument(void) throw (SAXException, RuntimeException)
164 m_iElementCount = 0;
165 m_iAttributeCount = 0;
166 m_iWhitespaceCount =0;
167 m_iCharCount=0;
168 printf( "document started\n" );
170 virtual void SAL_CALL endDocument(void) throw (SAXException, RuntimeException)
172 printf( "document finished\n" );
173 printf( "(ElementCount %d),(AttributeCount %d),(WhitespaceCount %d),(CharCount %d)\n",
174 m_iElementCount, m_iAttributeCount, m_iWhitespaceCount , m_iCharCount );
177 virtual void SAL_CALL startElement(const OUString& /* aName */,
178 const Reference< XAttributeList > & xAttribs)
179 throw (SAXException,RuntimeException)
181 m_iElementCount ++;
182 m_iAttributeCount += xAttribs->getLength();
185 virtual void SAL_CALL endElement(const OUString& /* aName */) throw (SAXException,RuntimeException)
187 // ignored
190 virtual void SAL_CALL characters(const OUString& aChars) throw (SAXException,RuntimeException)
192 m_iCharCount += aChars.getLength();
194 virtual void SAL_CALL ignorableWhitespace(const OUString& aWhitespaces) throw (SAXException,RuntimeException)
196 m_iWhitespaceCount += aWhitespaces.getLength();
199 virtual void SAL_CALL processingInstruction(const OUString& /* aTarget */, const OUString& /* aData */) throw (SAXException,RuntimeException)
201 // ignored
204 virtual void SAL_CALL setDocumentLocator(const Reference< XLocator> & /* xLocator */)
205 throw (SAXException,RuntimeException)
207 // ignored
210 virtual InputSource SAL_CALL resolveEntity(
211 const OUString& sPublicId,
212 const OUString& sSystemId)
213 throw (RuntimeException)
215 InputSource source;
216 source.sSystemId = sSystemId;
217 source.sPublicId = sPublicId;
219 source.aInputStream = createStreamFromFile(
220 OUStringToOString( sSystemId, RTL_TEXTENCODING_ASCII_US).getStr() );
222 return source;
225 virtual void SAL_CALL startCDATA(void) throw (SAXException,RuntimeException)
228 virtual void SAL_CALL endCDATA(void) throw (RuntimeException)
231 virtual void SAL_CALL comment(const OUString& /* sComment */) throw (SAXException,RuntimeException)
234 virtual void SAL_CALL unknown(const OUString& /* sString */) throw (SAXException,RuntimeException)
238 virtual void SAL_CALL allowLineBreak( void) throw (SAXException, RuntimeException )
243 public:
244 int m_iElementCount;
245 int m_iAttributeCount;
246 int m_iWhitespaceCount;
247 int m_iCharCount;
250 //--------------------------------------
251 // helper implementation for writing
252 // implements an XAttributeList
253 //-------------------------------------
254 struct AttributeListImpl_impl;
255 class AttributeListImpl : public WeakImplHelper1< XAttributeList >
257 public:
258 AttributeListImpl();
259 AttributeListImpl( const AttributeListImpl & );
260 ~AttributeListImpl();
262 public:
263 virtual sal_Int16 SAL_CALL getLength(void) throw (RuntimeException);
264 virtual OUString SAL_CALL getNameByIndex(sal_Int16 i) throw (RuntimeException);
265 virtual OUString SAL_CALL getTypeByIndex(sal_Int16 i) throw (RuntimeException);
266 virtual OUString SAL_CALL getTypeByName(const OUString& aName) throw (RuntimeException);
267 virtual OUString SAL_CALL getValueByIndex(sal_Int16 i) throw (RuntimeException);
268 virtual OUString SAL_CALL getValueByName(const OUString& aName) throw (RuntimeException);
270 public:
271 void addAttribute( const OUString &sName ,
272 const OUString &sType ,
273 const OUString &sValue );
274 void clear();
276 private:
277 struct AttributeListImpl_impl *m_pImpl;
281 struct TagAttribute
283 TagAttribute(){}
284 TagAttribute( const OUString &s_Name,
285 const OUString &s_Type ,
286 const OUString &s_Value )
288 this->sName = s_Name;
289 this->sType = s_Type;
290 this->sValue = s_Value;
293 OUString sName;
294 OUString sType;
295 OUString sValue;
298 struct AttributeListImpl_impl
300 AttributeListImpl_impl()
302 // performance improvement during adding
303 vecAttribute.reserve(20);
305 vector<struct TagAttribute> vecAttribute;
310 sal_Int16 AttributeListImpl::getLength(void) throw (RuntimeException)
312 return (sal_Int16) m_pImpl->vecAttribute.size();
316 AttributeListImpl::AttributeListImpl( const AttributeListImpl &r )
318 m_pImpl = new AttributeListImpl_impl;
319 *m_pImpl = *(r.m_pImpl);
322 OUString AttributeListImpl::getNameByIndex(sal_Int16 i) throw (RuntimeException)
324 if( i < sal::static_int_cast<sal_Int16>(m_pImpl->vecAttribute.size()) ) {
325 return m_pImpl->vecAttribute[i].sName;
327 return OUString();
331 OUString AttributeListImpl::getTypeByIndex(sal_Int16 i) throw (RuntimeException)
333 if( i < sal::static_int_cast<sal_Int16>(m_pImpl->vecAttribute.size()) ) {
334 return m_pImpl->vecAttribute[i].sType;
336 return OUString();
339 OUString AttributeListImpl::getValueByIndex(sal_Int16 i) throw (RuntimeException)
341 if( i < sal::static_int_cast<sal_Int16>(m_pImpl->vecAttribute.size()) ) {
342 return m_pImpl->vecAttribute[i].sValue;
344 return OUString();
348 OUString AttributeListImpl::getTypeByName( const OUString& sName ) throw (RuntimeException)
350 vector<struct TagAttribute>::iterator ii = m_pImpl->vecAttribute.begin();
352 for( ; ii != m_pImpl->vecAttribute.end() ; ++ii ) {
353 if( (*ii).sName == sName ) {
354 return (*ii).sType;
357 return OUString();
360 OUString AttributeListImpl::getValueByName(const OUString& sName) throw (RuntimeException)
362 vector<struct TagAttribute>::iterator ii = m_pImpl->vecAttribute.begin();
364 for( ; ii != m_pImpl->vecAttribute.end() ; ++ii ) {
365 if( (*ii).sName == sName ) {
366 return (*ii).sValue;
369 return OUString();
374 AttributeListImpl::AttributeListImpl()
376 m_pImpl = new AttributeListImpl_impl;
381 AttributeListImpl::~AttributeListImpl()
383 delete m_pImpl;
387 void AttributeListImpl::addAttribute( const OUString &sName ,
388 const OUString &sType ,
389 const OUString &sValue )
391 m_pImpl->vecAttribute.push_back( TagAttribute( sName , sType , sValue ) );
394 void AttributeListImpl::clear()
396 m_pImpl->vecAttribute.clear();
400 //--------------------------------------
401 // helper function for writing
402 // ensures that linebreaks are inserted
403 // when writing a long text.
404 // Note: this implementation may be a bit slow,
405 // but it shows, how the SAX-Writer handles the allowLineBreak calls.
406 //--------------------------------------
407 void writeParagraphHelper(
408 const Reference< XExtendedDocumentHandler > &r ,
409 const OUString & s)
411 int nMax = s.getLength();
412 int nStart = 0;
413 int n = 1;
415 Sequence<sal_uInt16> seq( s.getLength() );
416 memcpy( seq.getArray() , s.getStr() , s.getLength() * sizeof( sal_uInt16 ) );
418 for( n = 1 ; n < nMax ; n++ ){
419 if( 32 == seq.getArray()[n] ) {
420 r->allowLineBreak();
421 r->characters( s.copy( nStart , n - nStart ) );
422 nStart = n;
425 r->allowLineBreak();
426 r->characters( s.copy( nStart , n - nStart ) );
430 //---------------------------------
431 // helper implementation for SAX-Writer
432 // writes data to a file
433 //--------------------------------
434 class OFileWriter :
435 public WeakImplHelper1< XOutputStream >
437 public:
438 OFileWriter( char *pcFile ) { strncpy( m_pcFile , pcFile, 256 - 1 ); m_f = 0; }
441 public:
442 virtual void SAL_CALL writeBytes(const Sequence< sal_Int8 >& aData)
443 throw (NotConnectedException, BufferSizeExceededException, RuntimeException);
444 virtual void SAL_CALL flush(void)
445 throw (NotConnectedException, BufferSizeExceededException, RuntimeException);
446 virtual void SAL_CALL closeOutput(void)
447 throw (NotConnectedException, BufferSizeExceededException, RuntimeException);
448 private:
449 char m_pcFile[256];
450 FILE *m_f;
454 void OFileWriter::writeBytes(const Sequence< sal_Int8 >& aData)
455 throw (NotConnectedException, BufferSizeExceededException, RuntimeException)
457 if( ! m_f ) {
458 m_f = fopen( m_pcFile , "w" );
461 fwrite( aData.getConstArray() , 1 , aData.getLength() , m_f );
465 void OFileWriter::flush(void)
466 throw (NotConnectedException, BufferSizeExceededException, RuntimeException)
468 fflush( m_f );
471 void OFileWriter::closeOutput(void)
472 throw (NotConnectedException, BufferSizeExceededException, RuntimeException)
474 fclose( m_f );
475 m_f = 0;
480 // Needed to switch on solaris threads
481 #ifdef SOLARIS
482 extern "C" void ChangeGlobalInit();
483 #endif
484 int main (int argc, char **argv)
487 if( argc < 3) {
488 printf( "usage : saxdemo inputfile outputfile\n" );
489 exit( 0 );
491 #ifdef SOLARIS
492 // switch on threads in solaris
493 ChangeGlobalInit();
494 #endif
496 // create service manager
497 Reference< XMultiServiceFactory > xSMgr = createRegistryServiceFactory(
498 OUString( "applicat.rdb" ) );
500 Reference < XImplementationRegistration > xReg;
503 // Create registration service
504 Reference < XInterface > x = xSMgr->createInstance(
505 OUString("com.sun.star.registry.ImplementationRegistration") );
506 xReg = Reference< XImplementationRegistration > ( x , UNO_QUERY );
508 catch( Exception & ) {
509 printf( "Couldn't create ImplementationRegistration service\n" );
510 exit(1);
513 OString sTestName;
516 // Load dll for the tested component
517 OUString aDllName( "sax.uno" SAL_DLLEXTENSION );
518 xReg->registerImplementation(
519 OUString("com.sun.star.loader.SharedLibrary"),
520 aDllName,
521 Reference< XSimpleRegistry > () );
523 catch( Exception &e ) {
524 printf( "Couldn't reach sax dll\n" );
525 printf( "%s\n" , OUStringToOString( e.Message , RTL_TEXTENCODING_ASCII_US ).getStr() );
527 exit(1);
531 //--------------------------------
532 // parser demo
533 // read xml from a file and count elements
534 //--------------------------------
535 Reference< XInterface > x = xSMgr->createInstance(
536 OUString("com.sun.star.xml.sax.Parser") );
537 if( x.is() )
539 Reference< XParser > rParser( x , UNO_QUERY );
541 // create and connect the document handler to the parser
542 TestDocumentHandler *pDocHandler = new TestDocumentHandler( );
544 Reference < XDocumentHandler > rDocHandler( (XDocumentHandler *) pDocHandler );
545 Reference< XEntityResolver > rEntityResolver( (XEntityResolver *) pDocHandler );
547 rParser->setDocumentHandler( rDocHandler );
548 rParser->setEntityResolver( rEntityResolver );
550 // create the input stream
551 InputSource source;
552 source.aInputStream = createStreamFromFile( argv[1] );
553 source.sSystemId = OUString::createFromAscii( argv[1] );
557 // start parsing
558 rParser->parseStream( source );
561 catch( Exception & e )
563 OString o1 = OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8 );
564 printf( "Exception during parsing : %s\n" , o1.getStr() );
567 else
569 printf( "couldn't create sax-parser component\n" );
573 //----------------------
574 // The SAX-Writer demo
575 //----------------------
576 x= xSMgr->createInstance( OUString("com.sun.star.xml.sax.Writer") );
577 if( x.is() )
579 printf( "start writing to %s\n" , argv[2] );
581 OFileWriter *pw = new OFileWriter( argv[2] );
582 Reference< XActiveDataSource > source( x , UNO_QUERY );
583 source->setOutputStream( Reference< XOutputStream> ( (XOutputStream*) pw ) );
585 AttributeListImpl *pList = new AttributeListImpl;
586 Reference< XAttributeList > rList( (XAttributeList *) pList );
588 Reference< XExtendedDocumentHandler > r( x , UNO_QUERY );
589 r->startDocument();
591 pList->addAttribute( OUString( "Arg1" ),
592 OUString( "CDATA") ,
593 OUString( "foo\n u") );
594 pList->addAttribute( OUString( "Arg2") ,
595 OUString( "CDATA") ,
596 OUString( "foo2") );
598 r->startElement( OUString( "tag1") , rList );
599 // tells the writer to insert a linefeed
600 r->ignorableWhitespace( OUString() );
602 r->characters( OUString( "huhu") );
603 r->ignorableWhitespace( OUString() );
605 r->startElement( OUString( "hi") , rList );
606 r->ignorableWhitespace( OUString() );
608 // the enpassant must be converted & -> &amp;
609 r->characters( OUString( "&#252;") );
610 r->ignorableWhitespace( OUString() );
612 // '>' must not be converted
613 r->startCDATA();
614 r->characters( OUString( " > foo < ") );
615 r->endCDATA();
616 r->ignorableWhitespace( OUString() );
618 OUString testParagraph = OUString(
619 "This is only a test to check, if the writer inserts line feeds "
620 "if needed or if the writer puts the whole text into one line." );
621 writeParagraphHelper( r , testParagraph );
623 r->ignorableWhitespace( OUString() );
624 r->comment( OUString( "This is a comment !") );
625 r->ignorableWhitespace( OUString() );
627 r->startElement( OUString( "emptytagtest") , rList );
628 r->endElement( OUString( "emptytagtest") );
629 r->ignorableWhitespace( OUString() );
631 r->endElement( OUString( "hi") );
632 r->ignorableWhitespace( OUString() );
634 r->endElement( OUString( "tag1") );
635 r->endDocument();
637 printf( "finished writing\n" );
639 else
641 printf( "couldn't create sax-writer component\n" );
645 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */