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