Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 :
21 : #include <stdio.h>
22 : #include <string.h>
23 : #include <stack>
24 :
25 : #include "sal/main.h"
26 :
27 : #include <com/sun/star/lang/XComponent.hpp>
28 :
29 : #include <com/sun/star/xml/sax/SAXParseException.hpp>
30 : #include <com/sun/star/xml/sax/Parser.hpp>
31 : #include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
32 :
33 : #include <com/sun/star/io/XOutputStream.hpp>
34 : #include <com/sun/star/io/XActiveDataSource.hpp>
35 :
36 : #include <cppuhelper/bootstrap.hxx>
37 : #include <cppuhelper/implbase1.hxx>
38 : #include <cppuhelper/implbase3.hxx>
39 :
40 : #include <osl/diagnose.h>
41 :
42 : #include "LocaleNode.hxx"
43 :
44 : using namespace ::rtl;
45 : using namespace ::std;
46 : using namespace ::cppu;
47 : using namespace ::com::sun::star::uno;
48 : using namespace ::com::sun::star::lang;
49 : using namespace ::com::sun::star::registry;
50 : using namespace ::com::sun::star::xml::sax;
51 : using namespace ::com::sun::star::io;
52 :
53 :
54 :
55 :
56 :
57 :
58 : /************
59 : * Sequence of bytes -> InputStream
60 : ************/
61 440 : class OInputStream : public WeakImplHelper1 < XInputStream >
62 : {
63 : public:
64 220 : OInputStream( const Sequence< sal_Int8 >&seq ) :
65 : nPos( 0 ),
66 220 : m_seq( seq )
67 220 : {}
68 :
69 : public:
70 517 : virtual sal_Int32 SAL_CALL readBytes( Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
71 : throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
72 : {
73 517 : nBytesToRead = (nBytesToRead > m_seq.getLength() - nPos ) ?
74 440 : m_seq.getLength() - nPos :
75 957 : nBytesToRead;
76 517 : aData = Sequence< sal_Int8 > ( &(m_seq.getConstArray()[nPos]) , nBytesToRead );
77 517 : nPos += nBytesToRead;
78 517 : return nBytesToRead;
79 : }
80 517 : 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)
84 : {
85 517 : return readBytes( aData, nMaxBytesToRead );
86 : }
87 0 : virtual void SAL_CALL skipBytes( sal_Int32 /*nBytesToSkip*/ )
88 : throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
89 : {
90 : // not implemented
91 0 : }
92 0 : virtual sal_Int32 SAL_CALL available( )
93 : throw(NotConnectedException, IOException, RuntimeException)
94 : {
95 0 : return m_seq.getLength() - nPos;
96 : }
97 0 : virtual void SAL_CALL closeInput( )
98 : throw(NotConnectedException, IOException, RuntimeException)
99 : {
100 : // not needed
101 0 : }
102 : sal_Int32 nPos;
103 : Sequence< sal_Int8> m_seq;
104 : };
105 :
106 : //-------------------------------
107 : // Helper : create an input stream from a file
108 : //------------------------------
109 220 : Reference< XInputStream > createStreamFromFile(
110 : const char *pcFile )
111 : {
112 220 : FILE *f = fopen( pcFile , "rb" );
113 220 : Reference< XInputStream > r;
114 :
115 220 : if( f ) {
116 220 : fseek( f , 0 , SEEK_END );
117 220 : size_t nLength = ftell( f );
118 220 : fseek( f , 0 , SEEK_SET );
119 :
120 220 : Sequence<sal_Int8> seqIn(nLength);
121 220 : if (fread( seqIn.getArray() , nLength , 1 , f ) == 1)
122 220 : r = Reference< XInputStream > ( new OInputStream( seqIn ) );
123 : else
124 0 : fprintf(stderr, "failure reading %s\n", pcFile);
125 220 : fclose( f );
126 : }
127 220 : return r;
128 : }
129 :
130 :
131 : class TestDocumentHandler :
132 : public WeakImplHelper3< XExtendedDocumentHandler , XEntityResolver , XErrorHandler >
133 : {
134 : public:
135 220 : TestDocumentHandler(const char* locale, const char* outFile )
136 : : rootNode(0)
137 : , nError(0)
138 220 : , of(outFile, locale)
139 : {
140 220 : strncpy( theLocale, locale, sizeof(theLocale) );
141 220 : theLocale[sizeof(theLocale)-1] = 0;
142 220 : }
143 :
144 440 : ~TestDocumentHandler( )
145 440 : {
146 220 : of.closeOutput();
147 220 : delete rootNode;
148 440 : }
149 :
150 :
151 : public: // Error handler
152 0 : virtual void SAL_CALL error(const Any& aSAXParseException) throw (SAXException, RuntimeException)
153 : {
154 0 : ++nError;
155 0 : printf( "Error !\n" );
156 : throw SAXException(
157 : OUString( "error from error handler") ,
158 : Reference < XInterface >() ,
159 0 : aSAXParseException );
160 : }
161 0 : virtual void SAL_CALL fatalError(const Any& /*aSAXParseException*/) throw (SAXException, RuntimeException)
162 : {
163 0 : ++nError;
164 0 : printf( "Fatal Error !\n" );
165 0 : }
166 0 : virtual void SAL_CALL warning(const Any& /*aSAXParseException*/) throw (SAXException, RuntimeException)
167 : {
168 0 : printf( "Warning !\n" );
169 0 : }
170 :
171 :
172 : public: // ExtendedDocumentHandler
173 :
174 :
175 :
176 : stack<LocaleNode *> currentNode ;
177 : sal_Bool fElement ;
178 : LocaleNode * rootNode;
179 :
180 220 : virtual void SAL_CALL startDocument(void) throw (SAXException, RuntimeException)
181 : {
182 220 : printf( "parsing document %s started\n", theLocale);
183 220 : of.writeAsciiString("#include <sal/types.h>\n\n\n");
184 220 : of.writeAsciiString("#include <stdio.h> // debug printfs\n\n");
185 220 : of.writeAsciiString("extern \"C\" {\n\n");
186 220 : }
187 :
188 220 : virtual void SAL_CALL endDocument(void) throw (SAXException, RuntimeException)
189 : {
190 220 : if (rootNode)
191 : {
192 220 : rootNode->generateCode(of);
193 220 : int err = rootNode->getError();
194 220 : if (err)
195 : {
196 0 : printf( "Error: in data for %s: %d\n", theLocale, err);
197 0 : nError += err;
198 : }
199 : }
200 : else
201 : {
202 0 : ++nError;
203 0 : printf( "Error: no data for %s\n", theLocale);
204 : }
205 220 : printf( "parsing document %s finished\n", theLocale);
206 :
207 220 : of.writeAsciiString("} // extern \"C\"\n\n");
208 220 : of.closeOutput();
209 220 : }
210 :
211 46922 : virtual void SAL_CALL startElement(const OUString& aName,
212 : const Reference< XAttributeList > & xAttribs)
213 : throw (SAXException,RuntimeException)
214 : {
215 :
216 46922 : LocaleNode * l = LocaleNode::createNode (aName, xAttribs);
217 46922 : if (!currentNode.empty() ) {
218 46702 : LocaleNode * ln = (LocaleNode *) currentNode.top();
219 46702 : ln->addChild(l);
220 : } else {
221 220 : rootNode = l;
222 : }
223 46922 : currentNode.push (l);
224 46922 : }
225 :
226 :
227 46922 : virtual void SAL_CALL endElement(const OUString& /*aName*/) throw (SAXException,RuntimeException)
228 : {
229 46922 : currentNode.pop();
230 46922 : }
231 :
232 152475 : virtual void SAL_CALL characters(const OUString& aChars) throw (SAXException,RuntimeException)
233 : {
234 :
235 152475 : LocaleNode * l = currentNode.top();
236 152475 : l->setValue (aChars);
237 152475 : }
238 :
239 0 : virtual void SAL_CALL ignorableWhitespace(const OUString& /*aWhitespaces*/) throw (SAXException,RuntimeException)
240 : {
241 0 : }
242 :
243 0 : virtual void SAL_CALL processingInstruction(const OUString& /*aTarget*/, const OUString& /*aData*/) throw (SAXException,RuntimeException)
244 : {
245 : // ignored
246 0 : }
247 :
248 220 : virtual void SAL_CALL setDocumentLocator(const Reference< XLocator> & /*xLocator*/)
249 : throw (SAXException,RuntimeException)
250 : {
251 : // ignored
252 220 : }
253 :
254 0 : virtual InputSource SAL_CALL resolveEntity(
255 : const OUString& sPublicId,
256 : const OUString& sSystemId)
257 : throw (RuntimeException)
258 : {
259 0 : InputSource source;
260 0 : source.sSystemId = sSystemId;
261 0 : source.sPublicId = sPublicId;
262 :
263 : source.aInputStream = createStreamFromFile(
264 0 : OUStringToOString(sSystemId, RTL_TEXTENCODING_ASCII_US).getStr() );
265 :
266 0 : return source;
267 : }
268 :
269 0 : virtual void SAL_CALL startCDATA(void) throw (SAXException,RuntimeException)
270 : {
271 0 : }
272 0 : virtual void SAL_CALL endCDATA(void) throw (RuntimeException)
273 : {
274 0 : }
275 366 : virtual void SAL_CALL comment(const OUString& /*sComment*/) throw (SAXException,RuntimeException)
276 : {
277 366 : }
278 2696 : virtual void SAL_CALL unknown(const OUString& /*sString*/) throw (SAXException,RuntimeException)
279 : {
280 2696 : }
281 :
282 0 : virtual void SAL_CALL allowLineBreak( void) throw (SAXException, RuntimeException )
283 : {
284 :
285 0 : }
286 :
287 : public:
288 : int nError;
289 : sal_Char theLocale[50];
290 : OFileWriter of;
291 : };
292 :
293 :
294 :
295 :
296 :
297 440 : SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv)
298 : {
299 :
300 :
301 220 : if( argc < 4) {
302 0 : printf( "usage : %s <locaLe> <XML inputfile> <destination file>\n", argv[0] );
303 0 : exit( 1 );
304 : }
305 :
306 220 : Reference< XComponentContext > xContext;
307 : try
308 : {
309 220 : xContext = defaultBootstrap_InitialComponentContext();
310 : }
311 0 : catch ( const Exception &e )
312 : {
313 : printf( "Exception bootstrapping UNO: %s\n",
314 0 : OUStringToOString( e.Message , RTL_TEXTENCODING_ASCII_US ).getStr() );
315 0 : exit(1);
316 : }
317 :
318 : //--------------------------------
319 : // parser demo
320 : // read xml from a file and count elements
321 : //--------------------------------
322 220 : Reference< XParser > rParser = Parser::create(xContext);
323 :
324 220 : int nError = 0;
325 : // create and connect the document handler to the parser
326 220 : TestDocumentHandler *pDocHandler = new TestDocumentHandler( argv[1], argv[3]);
327 :
328 220 : Reference < XDocumentHandler > rDocHandler( (XDocumentHandler *) pDocHandler );
329 220 : Reference< XEntityResolver > rEntityResolver( (XEntityResolver *) pDocHandler );
330 :
331 220 : rParser->setDocumentHandler( rDocHandler );
332 220 : rParser->setEntityResolver( rEntityResolver );
333 :
334 : // create the input stream
335 220 : InputSource source;
336 220 : source.aInputStream = createStreamFromFile( argv[2] );
337 220 : source.sSystemId = OUString::createFromAscii( argv[2] );
338 :
339 : try
340 : {
341 : // start parsing
342 220 : rParser->parseStream( source );
343 : }
344 :
345 0 : catch( const Exception & e )
346 : {
347 0 : OString o1 = OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8 );
348 0 : printf( "Exception during parsing : %s\n" , o1.getStr() );
349 0 : exit(1);
350 : }
351 220 : nError = pDocHandler->nError;
352 :
353 220 : return nError;
354 : }
355 :
356 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|