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 
36 #include <cppuhelper/bootstrap.hxx>
37 #include <cppuhelper/implbase.hxx>
38 #include <tools/long.hxx>
39 #include <rtl/ref.hxx>
40 
41 #include "LocaleNode.hxx"
42 
43 using namespace ::std;
44 using namespace ::cppu;
45 using namespace ::com::sun::star::uno;
46 using namespace ::com::sun::star::lang;
47 using namespace ::com::sun::star::xml::sax;
48 using namespace ::com::sun::star::io;
49 
50 namespace {
51 
52 /************
53  * Sequence of bytes -> InputStream
54  ************/
55 class OInputStream : public WeakImplHelper < XInputStream >
56 {
57 public:
58  explicit OInputStream( const Sequence< sal_Int8 >&seq )
59  : nPos(0)
60  , m_seq(seq)
61  {}
62 
63 public:
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 
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 
141 namespace {
142 
143 class TestDocumentHandler :
144  public WeakImplHelper< XExtendedDocumentHandler , XEntityResolver , XErrorHandler >
145 {
146 public:
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 
162 public: // 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 
183 public: // 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 
293 public:
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 
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: */
static LocaleNode * createNode(const OUString &name, const Reference< XAttributeList > &attr)
Definition: LocaleNode.cxx:91
long Long
void addChild(LocaleNode *node)
Definition: LocaleNode.cxx:61
void setValue(std::u16string_view oValue)
Definition: LocaleNode.hxx:89
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
err
static Reference< XInputStream > createStreamFromFile(const char *pcFile)
Definition: saxparser.cxx:97
virtual void generateCode(const OFileWriter &of) const
Definition: LocaleNode.cxx:129
CPPUHELPER_DLLPUBLIC css::uno::Reference< css::uno::XComponentContext > SAL_CALL defaultBootstrap_InitialComponentContext()
int getError() const
Definition: LocaleNode.cxx:53
SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv)
Definition: saxparser.cxx:301
void(* f)(TrueTypeTable *)
sal_Int32 nLength
void dispose()
sal_uInt16 nPos