1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 //------------------------------------------------------
30 // testcomponent - Loads a service and its testcomponent from dlls performs a test.
31 // Expands the dll-names depending on the actual environment.
32 // Example : testcomponent stardiv.uno.io.Pipe stm
34 // Therefor the testcode must exist in teststm and the testservice must be named test.stardiv.uno.io.Pipe
41 #include <com/sun/star/registry/XImplementationRegistration.hpp>
42 #include <com/sun/star/lang/XComponent.hpp>
44 #include <com/sun/star/xml/sax/SAXParseException.hpp>
45 #include <com/sun/star/xml/sax/XParser.hpp>
46 #include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
48 #include <com/sun/star/io/XOutputStream.hpp>
49 #include <com/sun/star/io/XActiveDataSource.hpp>
51 #include <cppuhelper/servicefactory.hxx>
52 #include <cppuhelper/implbase1.hxx>
53 #include <cppuhelper/implbase3.hxx>
55 #include <osl/diagnose.h>
57 using namespace ::rtl
;
58 using namespace ::std
;
59 using namespace ::cppu
;
60 using namespace ::com::sun::star::uno
;
61 using namespace ::com::sun::star::lang
;
62 using namespace ::com::sun::star::registry
;
63 using namespace ::com::sun::star::xml::sax
;
64 using namespace ::com::sun::star::io
;
68 * Sequence of bytes -> InputStream
70 class OInputStream
: public WeakImplHelper1
< XInputStream
>
73 OInputStream( const Sequence
< sal_Int8
>&seq
) :
79 virtual sal_Int32 SAL_CALL
readBytes( Sequence
< sal_Int8
>& aData
, sal_Int32 nBytesToRead
)
80 throw(NotConnectedException
, BufferSizeExceededException
, IOException
, RuntimeException
)
82 nBytesToRead
= (nBytesToRead
> m_seq
.getLength() - nPos
) ?
83 m_seq
.getLength() - nPos
:
85 aData
= Sequence
< sal_Int8
> ( &(m_seq
.getConstArray()[nPos
]) , nBytesToRead
);
89 virtual sal_Int32 SAL_CALL
readSomeBytes(
90 ::com::sun::star::uno::Sequence
< sal_Int8
>& aData
,
91 sal_Int32 nMaxBytesToRead
)
92 throw(NotConnectedException
, BufferSizeExceededException
, IOException
, RuntimeException
)
94 return readBytes( aData
, nMaxBytesToRead
);
96 virtual void SAL_CALL
skipBytes( sal_Int32
/* nBytesToSkip */ )
97 throw(NotConnectedException
, BufferSizeExceededException
, IOException
, RuntimeException
)
101 virtual sal_Int32 SAL_CALL
available( )
102 throw(NotConnectedException
, IOException
, RuntimeException
)
104 return m_seq
.getLength() - nPos
;
106 virtual void SAL_CALL
closeInput( )
107 throw(NotConnectedException
, IOException
, RuntimeException
)
111 Sequence
< sal_Int8
> m_seq
;
115 //-------------------------------
116 // Helper : create an input stream from a file
117 //------------------------------
118 Reference
< XInputStream
> createStreamFromFile(
121 FILE *f
= fopen( pcFile
, "rb" );
122 Reference
< XInputStream
> r
;
125 fseek( f
, 0 , SEEK_END
);
126 int nLength
= ftell( f
);
127 fseek( f
, 0 , SEEK_SET
);
129 Sequence
<sal_Int8
> seqIn(nLength
);
130 fread( seqIn
.getArray() , nLength
, 1 , f
);
132 r
= Reference
< XInputStream
> ( new OInputStream( seqIn
) );
138 //-----------------------------------------
139 // The document handler, which is needed for the saxparser
140 // The Documenthandler for reading sax
141 //-----------------------------------------
142 class TestDocumentHandler
:
143 public WeakImplHelper3
< XExtendedDocumentHandler
, XEntityResolver
, XErrorHandler
>
146 TestDocumentHandler( )
150 public: // Error handler
151 virtual void SAL_CALL
error(const Any
& aSAXParseException
) throw (SAXException
, RuntimeException
)
153 printf( "Error !\n" );
155 OUString( "error from error handler") ,
156 Reference
< XInterface
>() ,
157 aSAXParseException
);
159 virtual void SAL_CALL
fatalError(const Any
& /* aSAXParseException */) throw (SAXException
, RuntimeException
)
161 printf( "Fatal Error !\n" );
163 virtual void SAL_CALL
warning(const Any
& /* aSAXParseException */) throw (SAXException
, RuntimeException
)
165 printf( "Warning !\n" );
169 public: // ExtendedDocumentHandler
171 virtual void SAL_CALL
startDocument(void) throw (SAXException
, RuntimeException
)
174 m_iAttributeCount
= 0;
175 m_iWhitespaceCount
=0;
177 printf( "document started\n" );
179 virtual void SAL_CALL
endDocument(void) throw (SAXException
, RuntimeException
)
181 printf( "document finished\n" );
182 printf( "(ElementCount %d),(AttributeCount %d),(WhitespaceCount %d),(CharCount %d)\n",
183 m_iElementCount
, m_iAttributeCount
, m_iWhitespaceCount
, m_iCharCount
);
186 virtual void SAL_CALL
startElement(const OUString
& /* aName */,
187 const Reference
< XAttributeList
> & xAttribs
)
188 throw (SAXException
,RuntimeException
)
191 m_iAttributeCount
+= xAttribs
->getLength();
194 virtual void SAL_CALL
endElement(const OUString
& /* aName */) throw (SAXException
,RuntimeException
)
199 virtual void SAL_CALL
characters(const OUString
& aChars
) throw (SAXException
,RuntimeException
)
201 m_iCharCount
+= aChars
.getLength();
203 virtual void SAL_CALL
ignorableWhitespace(const OUString
& aWhitespaces
) throw (SAXException
,RuntimeException
)
205 m_iWhitespaceCount
+= aWhitespaces
.getLength();
208 virtual void SAL_CALL
processingInstruction(const OUString
& /* aTarget */, const OUString
& /* aData */) throw (SAXException
,RuntimeException
)
213 virtual void SAL_CALL
setDocumentLocator(const Reference
< XLocator
> & /* xLocator */)
214 throw (SAXException
,RuntimeException
)
219 virtual InputSource SAL_CALL
resolveEntity(
220 const OUString
& sPublicId
,
221 const OUString
& sSystemId
)
222 throw (RuntimeException
)
225 source
.sSystemId
= sSystemId
;
226 source
.sPublicId
= sPublicId
;
228 source
.aInputStream
= createStreamFromFile(
229 OUStringToOString( sSystemId
, RTL_TEXTENCODING_ASCII_US
).getStr() );
234 virtual void SAL_CALL
startCDATA(void) throw (SAXException
,RuntimeException
)
237 virtual void SAL_CALL
endCDATA(void) throw (RuntimeException
)
240 virtual void SAL_CALL
comment(const OUString
& /* sComment */) throw (SAXException
,RuntimeException
)
243 virtual void SAL_CALL
unknown(const OUString
& /* sString */) throw (SAXException
,RuntimeException
)
247 virtual void SAL_CALL
allowLineBreak( void) throw (SAXException
, RuntimeException
)
254 int m_iAttributeCount
;
255 int m_iWhitespaceCount
;
259 //--------------------------------------
260 // helper implementation for writing
261 // implements an XAttributeList
262 //-------------------------------------
263 struct AttributeListImpl_impl
;
264 class AttributeListImpl
: public WeakImplHelper1
< XAttributeList
>
268 AttributeListImpl( const AttributeListImpl
& );
269 ~AttributeListImpl();
272 virtual sal_Int16 SAL_CALL
getLength(void) throw (RuntimeException
);
273 virtual OUString SAL_CALL
getNameByIndex(sal_Int16 i
) throw (RuntimeException
);
274 virtual OUString SAL_CALL
getTypeByIndex(sal_Int16 i
) throw (RuntimeException
);
275 virtual OUString SAL_CALL
getTypeByName(const OUString
& aName
) throw (RuntimeException
);
276 virtual OUString SAL_CALL
getValueByIndex(sal_Int16 i
) throw (RuntimeException
);
277 virtual OUString SAL_CALL
getValueByName(const OUString
& aName
) throw (RuntimeException
);
280 void addAttribute( const OUString
&sName
,
281 const OUString
&sType
,
282 const OUString
&sValue
);
286 struct AttributeListImpl_impl
*m_pImpl
;
293 TagAttribute( const OUString
&s_Name
,
294 const OUString
&s_Type
,
295 const OUString
&s_Value
)
297 this->sName
= s_Name
;
298 this->sType
= s_Type
;
299 this->sValue
= s_Value
;
307 struct AttributeListImpl_impl
309 AttributeListImpl_impl()
311 // performance improvement during adding
312 vecAttribute
.reserve(20);
314 vector
<struct TagAttribute
> vecAttribute
;
319 sal_Int16
AttributeListImpl::getLength(void) throw (RuntimeException
)
321 return (sal_Int16
) m_pImpl
->vecAttribute
.size();
325 AttributeListImpl::AttributeListImpl( const AttributeListImpl
&r
)
327 m_pImpl
= new AttributeListImpl_impl
;
328 *m_pImpl
= *(r
.m_pImpl
);
331 OUString
AttributeListImpl::getNameByIndex(sal_Int16 i
) throw (RuntimeException
)
333 if( i
< sal::static_int_cast
<sal_Int16
>(m_pImpl
->vecAttribute
.size()) ) {
334 return m_pImpl
->vecAttribute
[i
].sName
;
340 OUString
AttributeListImpl::getTypeByIndex(sal_Int16 i
) throw (RuntimeException
)
342 if( i
< sal::static_int_cast
<sal_Int16
>(m_pImpl
->vecAttribute
.size()) ) {
343 return m_pImpl
->vecAttribute
[i
].sType
;
348 OUString
AttributeListImpl::getValueByIndex(sal_Int16 i
) throw (RuntimeException
)
350 if( i
< sal::static_int_cast
<sal_Int16
>(m_pImpl
->vecAttribute
.size()) ) {
351 return m_pImpl
->vecAttribute
[i
].sValue
;
357 OUString
AttributeListImpl::getTypeByName( const OUString
& sName
) throw (RuntimeException
)
359 vector
<struct TagAttribute
>::iterator ii
= m_pImpl
->vecAttribute
.begin();
361 for( ; ii
!= m_pImpl
->vecAttribute
.end() ; ++ii
) {
362 if( (*ii
).sName
== sName
) {
369 OUString
AttributeListImpl::getValueByName(const OUString
& sName
) throw (RuntimeException
)
371 vector
<struct TagAttribute
>::iterator ii
= m_pImpl
->vecAttribute
.begin();
373 for( ; ii
!= m_pImpl
->vecAttribute
.end() ; ++ii
) {
374 if( (*ii
).sName
== sName
) {
383 AttributeListImpl::AttributeListImpl()
385 m_pImpl
= new AttributeListImpl_impl
;
390 AttributeListImpl::~AttributeListImpl()
396 void AttributeListImpl::addAttribute( const OUString
&sName
,
397 const OUString
&sType
,
398 const OUString
&sValue
)
400 m_pImpl
->vecAttribute
.push_back( TagAttribute( sName
, sType
, sValue
) );
403 void AttributeListImpl::clear()
405 m_pImpl
->vecAttribute
.clear();
409 //--------------------------------------
410 // helper function for writing
411 // ensures that linebreaks are inserted
412 // when writing a long text.
413 // Note: this implementation may be a bit slow,
414 // but it shows, how the SAX-Writer handles the allowLineBreak calls.
415 //--------------------------------------
416 void writeParagraphHelper(
417 const Reference
< XExtendedDocumentHandler
> &r
,
420 int nMax
= s
.getLength();
424 Sequence
<sal_uInt16
> seq( s
.getLength() );
425 memcpy( seq
.getArray() , s
.getStr() , s
.getLength() * sizeof( sal_uInt16
) );
427 for( n
= 1 ; n
< nMax
; n
++ ){
428 if( 32 == seq
.getArray()[n
] ) {
430 r
->characters( s
.copy( nStart
, n
- nStart
) );
435 r
->characters( s
.copy( nStart
, n
- nStart
) );
439 //---------------------------------
440 // helper implementation for SAX-Writer
441 // writes data to a file
442 //--------------------------------
444 public WeakImplHelper1
< XOutputStream
>
447 OFileWriter( char *pcFile
) { strncpy( m_pcFile
, pcFile
, 256 - 1 ); m_f
= 0; }
451 virtual void SAL_CALL
writeBytes(const Sequence
< sal_Int8
>& aData
)
452 throw (NotConnectedException
, BufferSizeExceededException
, RuntimeException
);
453 virtual void SAL_CALL
flush(void)
454 throw (NotConnectedException
, BufferSizeExceededException
, RuntimeException
);
455 virtual void SAL_CALL
closeOutput(void)
456 throw (NotConnectedException
, BufferSizeExceededException
, RuntimeException
);
463 void OFileWriter::writeBytes(const Sequence
< sal_Int8
>& aData
)
464 throw (NotConnectedException
, BufferSizeExceededException
, RuntimeException
)
467 m_f
= fopen( m_pcFile
, "w" );
470 fwrite( aData
.getConstArray() , 1 , aData
.getLength() , m_f
);
474 void OFileWriter::flush(void)
475 throw (NotConnectedException
, BufferSizeExceededException
, RuntimeException
)
480 void OFileWriter::closeOutput(void)
481 throw (NotConnectedException
, BufferSizeExceededException
, RuntimeException
)
489 // Needed to switch on solaris threads
491 extern "C" void ChangeGlobalInit();
493 int main (int argc
, char **argv
)
497 printf( "usage : saxdemo inputfile outputfile\n" );
501 // switch on threads in solaris
505 // create service manager
506 Reference
< XMultiServiceFactory
> xSMgr
= createRegistryServiceFactory(
507 OUString( "applicat.rdb" ) );
509 Reference
< XImplementationRegistration
> xReg
;
512 // Create registration service
513 Reference
< XInterface
> x
= xSMgr
->createInstance(
514 OUString("com.sun.star.registry.ImplementationRegistration") );
515 xReg
= Reference
< XImplementationRegistration
> ( x
, UNO_QUERY
);
517 catch( Exception
& ) {
518 printf( "Couldn't create ImplementationRegistration service\n" );
525 // Load dll for the tested component
526 OUString
aDllName( "sax.uno" SAL_DLLEXTENSION
);
527 xReg
->registerImplementation(
528 OUString("com.sun.star.loader.SharedLibrary"),
530 Reference
< XSimpleRegistry
> () );
532 catch( Exception
&e
) {
533 printf( "Couldn't reach sax dll\n" );
534 printf( "%s\n" , OUStringToOString( e
.Message
, RTL_TEXTENCODING_ASCII_US
).getStr() );
540 //--------------------------------
542 // read xml from a file and count elements
543 //--------------------------------
544 Reference
< XInterface
> x
= xSMgr
->createInstance(
545 OUString("com.sun.star.xml.sax.Parser") );
548 Reference
< XParser
> rParser( x
, UNO_QUERY
);
550 // create and connect the document handler to the parser
551 TestDocumentHandler
*pDocHandler
= new TestDocumentHandler( );
553 Reference
< XDocumentHandler
> rDocHandler( (XDocumentHandler
*) pDocHandler
);
554 Reference
< XEntityResolver
> rEntityResolver( (XEntityResolver
*) pDocHandler
);
556 rParser
->setDocumentHandler( rDocHandler
);
557 rParser
->setEntityResolver( rEntityResolver
);
559 // create the input stream
561 source
.aInputStream
= createStreamFromFile( argv
[1] );
562 source
.sSystemId
= OUString::createFromAscii( argv
[1] );
567 rParser
->parseStream( source
);
570 catch( Exception
& e
)
572 OString o1
= OUStringToOString(e
.Message
, RTL_TEXTENCODING_UTF8
);
573 printf( "Exception during parsing : %s\n" , o1
.getStr() );
578 printf( "couldn't create sax-parser component\n" );
582 //----------------------
583 // The SAX-Writer demo
584 //----------------------
585 x
= xSMgr
->createInstance( OUString("com.sun.star.xml.sax.Writer") );
588 printf( "start writing to %s\n" , argv
[2] );
590 OFileWriter
*pw
= new OFileWriter( argv
[2] );
591 Reference
< XActiveDataSource
> source( x
, UNO_QUERY
);
592 source
->setOutputStream( Reference
< XOutputStream
> ( (XOutputStream
*) pw
) );
594 AttributeListImpl
*pList
= new AttributeListImpl
;
595 Reference
< XAttributeList
> rList( (XAttributeList
*) pList
);
597 Reference
< XExtendedDocumentHandler
> r( x
, UNO_QUERY
);
600 pList
->addAttribute( OUString( "Arg1" ),
602 OUString( "foo\n u") );
603 pList
->addAttribute( OUString( "Arg2") ,
607 r
->startElement( OUString( "tag1") , rList
);
608 // tells the writer to insert a linefeed
609 r
->ignorableWhitespace( OUString() );
611 r
->characters( OUString( "huhu") );
612 r
->ignorableWhitespace( OUString() );
614 r
->startElement( OUString( "hi") , rList
);
615 r
->ignorableWhitespace( OUString() );
617 // the enpassant must be converted & -> &
618 r
->characters( OUString( "ü") );
619 r
->ignorableWhitespace( OUString() );
621 // '>' must not be converted
623 r
->characters( OUString( " > foo < ") );
625 r
->ignorableWhitespace( OUString() );
627 OUString testParagraph
= OUString(
628 "This is only a test to check, if the writer inserts line feeds "
629 "if needed or if the writer puts the whole text into one line." );
630 writeParagraphHelper( r
, testParagraph
);
632 r
->ignorableWhitespace( OUString() );
633 r
->comment( OUString( "This is a comment !") );
634 r
->ignorableWhitespace( OUString() );
636 r
->startElement( OUString( "emptytagtest") , rList
);
637 r
->endElement( OUString( "emptytagtest") );
638 r
->ignorableWhitespace( OUString() );
640 r
->endElement( OUString( "hi") );
641 r
->ignorableWhitespace( OUString() );
643 r
->endElement( OUString( "tag1") );
646 printf( "finished writing\n" );
650 printf( "couldn't create sax-writer component\n" );
654 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */