1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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
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
;
59 * Sequence of bytes -> InputStream
61 class OInputStream
: public WeakImplHelper1
< XInputStream
>
64 OInputStream( const Sequence
< sal_Int8
>&seq
) :
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
:
76 aData
= Sequence
< sal_Int8
> ( &(m_seq
.getConstArray()[nPos
]) , 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
)
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
)
102 Sequence
< sal_Int8
> m_seq
;
106 //-------------------------------
107 // Helper : create an input stream from a file
108 //------------------------------
109 Reference
< XInputStream
> createStreamFromFile(
112 FILE *f
= fopen( pcFile
, "rb" );
113 Reference
< XInputStream
> r
;
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
) );
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
>
137 TestDocumentHandler( )
141 public: // Error handler
142 virtual void SAL_CALL
error(const Any
& aSAXParseException
) throw (SAXException
, RuntimeException
)
144 printf( "Error !\n" );
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
)
165 m_iAttributeCount
= 0;
166 m_iWhitespaceCount
=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
)
182 m_iAttributeCount
+= xAttribs
->getLength();
185 virtual void SAL_CALL
endElement(const OUString
& /* aName */) throw (SAXException
,RuntimeException
)
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
)
204 virtual void SAL_CALL
setDocumentLocator(const Reference
< XLocator
> & /* xLocator */)
205 throw (SAXException
,RuntimeException
)
210 virtual InputSource SAL_CALL
resolveEntity(
211 const OUString
& sPublicId
,
212 const OUString
& sSystemId
)
213 throw (RuntimeException
)
216 source
.sSystemId
= sSystemId
;
217 source
.sPublicId
= sPublicId
;
219 source
.aInputStream
= createStreamFromFile(
220 OUStringToOString( sSystemId
, RTL_TEXTENCODING_ASCII_US
).getStr() );
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
)
245 int m_iAttributeCount
;
246 int m_iWhitespaceCount
;
250 //--------------------------------------
251 // helper implementation for writing
252 // implements an XAttributeList
253 //-------------------------------------
254 struct AttributeListImpl_impl
;
255 class AttributeListImpl
: public WeakImplHelper1
< XAttributeList
>
259 AttributeListImpl( const AttributeListImpl
& );
260 ~AttributeListImpl();
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
);
271 void addAttribute( const OUString
&sName
,
272 const OUString
&sType
,
273 const OUString
&sValue
);
277 struct AttributeListImpl_impl
*m_pImpl
;
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
;
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
;
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
;
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
;
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
) {
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
) {
374 AttributeListImpl::AttributeListImpl()
376 m_pImpl
= new AttributeListImpl_impl
;
381 AttributeListImpl::~AttributeListImpl()
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
,
411 int nMax
= s
.getLength();
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
] ) {
421 r
->characters( s
.copy( nStart
, n
- nStart
) );
426 r
->characters( s
.copy( nStart
, n
- nStart
) );
430 //---------------------------------
431 // helper implementation for SAX-Writer
432 // writes data to a file
433 //--------------------------------
435 public WeakImplHelper1
< XOutputStream
>
438 OFileWriter( char *pcFile
) { strncpy( m_pcFile
, pcFile
, 256 - 1 ); m_f
= 0; }
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
);
454 void OFileWriter::writeBytes(const Sequence
< sal_Int8
>& aData
)
455 throw (NotConnectedException
, BufferSizeExceededException
, RuntimeException
)
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
)
471 void OFileWriter::closeOutput(void)
472 throw (NotConnectedException
, BufferSizeExceededException
, RuntimeException
)
480 // Needed to switch on solaris threads
482 extern "C" void ChangeGlobalInit();
484 int main (int argc
, char **argv
)
488 printf( "usage : saxdemo inputfile outputfile\n" );
492 // switch on threads in solaris
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" );
516 // Load dll for the tested component
517 OUString
aDllName( "sax.uno" SAL_DLLEXTENSION
);
518 xReg
->registerImplementation(
519 OUString("com.sun.star.loader.SharedLibrary"),
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() );
531 //--------------------------------
533 // read xml from a file and count elements
534 //--------------------------------
535 Reference
< XInterface
> x
= xSMgr
->createInstance(
536 OUString("com.sun.star.xml.sax.Parser") );
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
552 source
.aInputStream
= createStreamFromFile( argv
[1] );
553 source
.sSystemId
= OUString::createFromAscii( argv
[1] );
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() );
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") );
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
);
591 pList
->addAttribute( OUString( "Arg1" ),
593 OUString( "foo\n u") );
594 pList
->addAttribute( OUString( "Arg2") ,
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 & -> &
609 r
->characters( OUString( "ü") );
610 r
->ignorableWhitespace( OUString() );
612 // '>' must not be converted
614 r
->characters( OUString( " > foo < ") );
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") );
637 printf( "finished writing\n" );
641 printf( "couldn't create sax-writer component\n" );
645 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */