1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: saxparser.cxx,v $
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 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_i18npool.hxx"
40 #include <com/sun/star/registry/XImplementationRegistration.hpp>
41 #include <com/sun/star/lang/XComponent.hpp>
43 #include <com/sun/star/xml/sax/SAXParseException.hpp>
44 #include <com/sun/star/xml/sax/XParser.hpp>
45 #include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
47 #include <com/sun/star/io/XOutputStream.hpp>
48 #include <com/sun/star/io/XActiveDataSource.hpp>
50 #include <cppuhelper/servicefactory.hxx>
51 #include <cppuhelper/implbase1.hxx>
52 #include <cppuhelper/implbase3.hxx>
54 #include <vos/diagnose.hxx>
56 #include "LocaleNode.hxx"
58 using namespace ::rtl
;
59 using namespace ::std
;
60 using namespace ::cppu
;
61 using namespace ::com::sun::star::uno
;
62 using namespace ::com::sun::star::lang
;
63 using namespace ::com::sun::star::registry
;
64 using namespace ::com::sun::star::xml::sax
;
65 using namespace ::com::sun::star::io
;
73 * Sequence of bytes -> InputStream
75 class OInputStream
: public WeakImplHelper1
< XInputStream
>
78 OInputStream( const Sequence
< sal_Int8
>&seq
) :
84 virtual sal_Int32 SAL_CALL
readBytes( Sequence
< sal_Int8
>& aData
, sal_Int32 nBytesToRead
)
85 throw(NotConnectedException
, BufferSizeExceededException
, IOException
, RuntimeException
)
87 nBytesToRead
= (nBytesToRead
> m_seq
.getLength() - nPos
) ?
88 m_seq
.getLength() - nPos
:
90 aData
= Sequence
< sal_Int8
> ( &(m_seq
.getConstArray()[nPos
]) , nBytesToRead
);
94 virtual sal_Int32 SAL_CALL
readSomeBytes(
95 ::com::sun::star::uno::Sequence
< sal_Int8
>& aData
,
96 sal_Int32 nMaxBytesToRead
)
97 throw(NotConnectedException
, BufferSizeExceededException
, IOException
, RuntimeException
)
99 return readBytes( aData
, nMaxBytesToRead
);
101 virtual void SAL_CALL
skipBytes( sal_Int32
/*nBytesToSkip*/ )
102 throw(NotConnectedException
, BufferSizeExceededException
, IOException
, RuntimeException
)
106 virtual sal_Int32 SAL_CALL
available( )
107 throw(NotConnectedException
, IOException
, RuntimeException
)
109 return m_seq
.getLength() - nPos
;
111 virtual void SAL_CALL
closeInput( )
112 throw(NotConnectedException
, IOException
, RuntimeException
)
117 Sequence
< sal_Int8
> m_seq
;
120 //-------------------------------
121 // Helper : create an input stream from a file
122 //------------------------------
123 Reference
< XInputStream
> createStreamFromFile(
126 FILE *f
= fopen( pcFile
, "rb" );
127 Reference
< XInputStream
> r
;
130 fseek( f
, 0 , SEEK_END
);
131 int nLength
= ftell( f
);
132 fseek( f
, 0 , SEEK_SET
);
134 Sequence
<sal_Int8
> seqIn(nLength
);
135 fread( seqIn
.getArray() , nLength
, 1 , f
);
137 r
= Reference
< XInputStream
> ( new OInputStream( seqIn
) );
144 class TestDocumentHandler
:
145 public WeakImplHelper3
< XExtendedDocumentHandler
, XEntityResolver
, XErrorHandler
>
148 TestDocumentHandler(const char* locale
, const char* outFile
) :
149 rootNode(0), nError(0), nbOfCurrencies(0), nbOfCalendars(0), nbOfFormatElements(0),
150 nbOfTransliterations(0), nbOfCollations(0), nbOfDays(50), nbOfMonths(50), nbOfEras(10),
151 flag(-1), of(outFile
, locale
), isStartDayOfWeek(false), foundDefaultName(false),
152 foundVariant(false), openElement(false)
154 strncpy( theLocale
, locale
, sizeof(theLocale
) );
155 theLocale
[sizeof(theLocale
)-1] = 0;
158 ~TestDocumentHandler( )
164 public: // Error handler
165 virtual void SAL_CALL
error(const Any
& aSAXParseException
) throw (SAXException
, RuntimeException
)
168 printf( "Error !\n" );
170 OUString( RTL_CONSTASCII_USTRINGPARAM("error from error handler")) ,
171 Reference
< XInterface
>() ,
172 aSAXParseException
);
174 virtual void SAL_CALL
fatalError(const Any
& /*aSAXParseException*/) throw (SAXException
, RuntimeException
)
177 printf( "Fatal Error !\n" );
179 virtual void SAL_CALL
warning(const Any
& /*aSAXParseException*/) throw (SAXException
, RuntimeException
)
181 printf( "Warning !\n" );
185 public: // ExtendedDocumentHandler
189 stack
<LocaleNode
*> currentNode
;
191 LocaleNode
* rootNode
;
193 virtual void SAL_CALL
startDocument(void) throw (SAXException
, RuntimeException
)
195 printf( "parsing document %s started\n", theLocale
);
196 of
.writeAsciiString("#include <sal/types.h>\n\n\n");
197 of
.writeAsciiString("#include <stdio.h> // debug printfs\n\n");
198 of
.writeAsciiString("extern \"C\" {\n\n");
201 virtual void SAL_CALL
endDocument(void) throw (SAXException
, RuntimeException
)
205 rootNode
->generateCode(of
);
206 int err
= rootNode
->getError();
209 printf( "Error: in data for %s: %d\n", theLocale
, err
);
216 printf( "Error: no data for %s\n", theLocale
);
218 printf( "parsing document %s finished\n", theLocale
);
220 of
.writeAsciiString("} // extern \"C\"\n\n");
224 virtual void SAL_CALL
startElement(const OUString
& aName
,
225 const Reference
< XAttributeList
> & xAttribs
)
226 throw (SAXException
,RuntimeException
)
229 LocaleNode
* l
= LocaleNode::createNode (aName
, xAttribs
);
230 if (!currentNode
.empty() ) {
231 LocaleNode
* ln
= (LocaleNode
*) currentNode
. top();
236 currentNode
. push (l
);
240 virtual void SAL_CALL
endElement(const OUString
& /*aName*/) throw (SAXException
,RuntimeException
)
245 virtual void SAL_CALL
characters(const OUString
& aChars
) throw (SAXException
,RuntimeException
)
248 LocaleNode
* l
= currentNode
. top();
249 l
->setValue (aChars
);
250 ::rtl::OUString
str(aChars
);
251 sal_Unicode nonBreakSPace
[2]= {0xa, 0x0};
252 if(!openElement
|| str
.equals(nonBreakSPace
))
256 virtual void SAL_CALL
ignorableWhitespace(const OUString
& /*aWhitespaces*/) throw (SAXException
,RuntimeException
)
260 virtual void SAL_CALL
processingInstruction(const OUString
& /*aTarget*/, const OUString
& /*aData*/) throw (SAXException
,RuntimeException
)
265 virtual void SAL_CALL
setDocumentLocator(const Reference
< XLocator
> & /*xLocator*/)
266 throw (SAXException
,RuntimeException
)
271 virtual InputSource SAL_CALL
resolveEntity(
272 const OUString
& sPublicId
,
273 const OUString
& sSystemId
)
274 throw (RuntimeException
)
277 source
.sSystemId
= sSystemId
;
278 source
.sPublicId
= sPublicId
;
280 source
.aInputStream
= createStreamFromFile(
281 OUStringToOString( sSystemId
, RTL_TEXTENCODING_ASCII_US
) );
286 virtual void SAL_CALL
startCDATA(void) throw (SAXException
,RuntimeException
)
289 virtual void SAL_CALL
endCDATA(void) throw (RuntimeException
)
292 virtual void SAL_CALL
comment(const OUString
& /*sComment*/) throw (SAXException
,RuntimeException
)
295 virtual void SAL_CALL
unknown(const OUString
& /*sString*/) throw (SAXException
,RuntimeException
)
299 virtual void SAL_CALL
allowLineBreak( void) throw (SAXException
, RuntimeException
)
306 ::rtl::OUString currentElement
;
307 sal_Int16 nbOfCurrencies
;
308 sal_Int16 nbOfCalendars
;
309 sal_Int16 nbOfFormatElements
;
310 sal_Int16 nbOfTransliterations
;
311 sal_Int16 nbOfCollations
;
312 Sequence
<sal_Int16
> nbOfDays
;
313 Sequence
<sal_Int16
> nbOfMonths
;
314 Sequence
<sal_Int16
> nbOfEras
;
315 sal_Char
*elementTag
;
316 sal_Char theLocale
[50];
319 sal_Bool isStartDayOfWeek
;
320 sal_Bool foundDefaultName
;
321 sal_Bool foundVariant
;
322 sal_Bool openElement
;
329 SAL_IMPLEMENT_MAIN_WITH_ARGS(argc
, argv
)
334 printf( "usage : %s <locaLe> <XML inputfile> <destination file> <services.rdb location> <types.rdb location>\n", argv
[0] );
338 // create service manager
339 Reference
< XMultiServiceFactory
> xSMgr
;
342 xSMgr
= createRegistryServiceFactory(
343 ::rtl::OUString::createFromAscii(argv
[4]),
344 ::rtl::OUString::createFromAscii(argv
[5]) );
348 printf( "Exception on createRegistryServiceFactory\n" );
352 Reference
< XImplementationRegistration
> xReg
;
355 // Create registration service
356 Reference
< XInterface
> x
= xSMgr
->createInstance(
357 OUString::createFromAscii( "com.sun.star.registry.ImplementationRegistration" ) );
358 xReg
= Reference
< XImplementationRegistration
> ( x
, UNO_QUERY
);
360 catch( Exception
& ) {
361 printf( "Couldn't create ImplementationRegistration service\n" );
368 // Load dll for the tested component
370 OUString::createFromAscii( "sax.uno" SAL_DLLEXTENSION
);
371 xReg
->registerImplementation(
372 OUString::createFromAscii( "com.sun.star.loader.SharedLibrary" ),
374 Reference
< XSimpleRegistry
> () );
376 catch( Exception
&e
) {
377 printf( "Couldn't raise sax.uno library!\n" );
378 printf( "%s\n" , OUStringToOString( e
.Message
, RTL_TEXTENCODING_ASCII_US
).getStr() );
384 //--------------------------------
386 // read xml from a file and count elements
387 //--------------------------------
388 Reference
< XInterface
> x
= xSMgr
->createInstance(
389 OUString::createFromAscii( "com.sun.star.xml.sax.Parser" ) );
393 Reference
< XParser
> rParser( x
, UNO_QUERY
);
395 // create and connect the document handler to the parser
396 TestDocumentHandler
*pDocHandler
= new TestDocumentHandler( argv
[1], argv
[3]);
398 Reference
< XDocumentHandler
> rDocHandler( (XDocumentHandler
*) pDocHandler
);
399 Reference
< XEntityResolver
> rEntityResolver( (XEntityResolver
*) pDocHandler
);
401 rParser
->setDocumentHandler( rDocHandler
);
402 rParser
->setEntityResolver( rEntityResolver
);
404 // create the input stream
406 source
.aInputStream
= createStreamFromFile( argv
[2] );
407 source
.sSystemId
= OUString::createFromAscii( argv
[2] );
412 rParser
->parseStream( source
);
415 catch( Exception
& e
)
417 OString o1
= OUStringToOString(e
.Message
, RTL_TEXTENCODING_UTF8
);
418 printf( "Exception during parsing : %s\n" , o1
.getStr() );
421 nError
= pDocHandler
->nError
;
425 printf( "couln't create sax-parser component\n" );