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 ::cppu;
44using namespace ::com::sun::star::uno;
45using namespace ::com::sun::star::lang;
46using namespace ::com::sun::star::xml::sax;
47using namespace ::com::sun::star::io;
48
49namespace {
50
51/************
52 * Sequence of bytes -> InputStream
53 ************/
54class OInputStream : public WeakImplHelper < XInputStream >
55{
56public:
57 explicit OInputStream( const Sequence< sal_Int8 >&seq )
58 : nPos(0)
59 , m_seq(seq)
60 {}
61
62public:
63 virtual sal_Int32 SAL_CALL readBytes( Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead ) override
64 {
65 nBytesToRead = std::min(nBytesToRead, m_seq.getLength() - nPos);
66 aData = Sequence< sal_Int8 > ( &(m_seq.getConstArray()[nPos]) , nBytesToRead );
67 nPos += nBytesToRead;
68 return nBytesToRead;
69 }
70 virtual sal_Int32 SAL_CALL readSomeBytes(
71 css::uno::Sequence< sal_Int8 >& aData,
72 sal_Int32 nMaxBytesToRead ) override
73 {
74 return readBytes( aData, nMaxBytesToRead );
75 }
76 virtual void SAL_CALL skipBytes( sal_Int32 /*nBytesToSkip*/ ) override
77 {
78 // not implemented
79 }
80 virtual sal_Int32 SAL_CALL available( ) override
81 {
82 return m_seq.getLength() - nPos;
83 }
84 virtual void SAL_CALL closeInput( ) override
85 {
86 // not needed
87 }
88 sal_Int32 nPos;
89 Sequence< sal_Int8> m_seq;
90};
91
92}
93
94// Helper : create an input stream from a file
95
96static Reference< XInputStream > createStreamFromFile(
97 const char *pcFile )
98{
99 Reference< XInputStream > r;
100
101 FILE *f = fopen( pcFile , "rb" );
102
103 if (!f)
104 {
105 fprintf(stderr, "failure opening %s\n", pcFile);
106 return r;
107 }
108
109 if (fseek( f , 0 , SEEK_END ) == -1)
110 {
111 fprintf(stderr, "failure fseeking %s\n", pcFile);
112 fclose(f);
113 return r;
114 }
115
116 tools::Long nLength = ftell( f );
117 if (nLength == -1)
118 {
119 fprintf(stderr, "failure ftelling %s\n", pcFile);
120 fclose(f);
121 return r;
122 }
123
124 if (fseek( f , 0 , SEEK_SET ) == -1)
125 {
126 fprintf(stderr, "failure fseeking %s\n", pcFile);
127 fclose(f);
128 return r;
129 }
130
131 Sequence<sal_Int8> seqIn(nLength);
132 if (fread( seqIn.getArray(), nLength , 1 , f ) == 1)
133 r.set( new OInputStream( seqIn ) );
134 else
135 fprintf(stderr, "failure reading %s\n", pcFile);
136 fclose( f );
137 return r;
138}
139
140namespace {
141
142class TestDocumentHandler :
143 public WeakImplHelper< XExtendedDocumentHandler , XEntityResolver , XErrorHandler >
144{
145public:
146 TestDocumentHandler(const char* locale, const char* outFile )
147 : rootNode(nullptr)
148 , nError(0)
149 , theLocale(locale)
150 , of(outFile, locale)
151 {
152 }
153
154 virtual ~TestDocumentHandler( ) override
155 {
156 of.closeOutput();
157 delete rootNode;
158 }
159
160
161public: // Error handler
162 virtual void SAL_CALL error(const Any& aSAXParseException) override
163 {
164 ++nError;
165 printf( "Error !\n" );
166 throw SAXException(
167 "error from error handler",
168 Reference < XInterface >() ,
169 aSAXParseException );
170 }
171 virtual void SAL_CALL fatalError(const Any& /*aSAXParseException*/) override
172 {
173 ++nError;
174 printf( "Fatal Error !\n" );
175 }
176 virtual void SAL_CALL warning(const Any& /*aSAXParseException*/) override
177 {
178 printf( "Warning !\n" );
179 }
180
181
182public: // ExtendedDocumentHandler
183
184
185 std::stack<LocaleNode *> currentNode ;
186 LocaleNode * rootNode;
187
188 virtual void SAL_CALL startDocument() override
189 {
190 printf( "parsing document %s started\n", theLocale.c_str());
191 of.writeAsciiString("#include <sal/types.h>\n\n\n");
192 of.writeAsciiString("#include <rtl/ustring.hxx>\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:91
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:96
SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv)
Definition: saxparser.cxx:301
sal_Int32 nLength