diff options
Diffstat (limited to 'i18npool/source/localedata/saxparser.cxx')
-rw-r--r-- | i18npool/source/localedata/saxparser.cxx | 343 |
1 files changed, 343 insertions, 0 deletions
diff --git a/i18npool/source/localedata/saxparser.cxx b/i18npool/source/localedata/saxparser.cxx new file mode 100644 index 000000000..d13e99bb7 --- /dev/null +++ b/i18npool/source/localedata/saxparser.cxx @@ -0,0 +1,343 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <sal/config.h> + +#include <cstdlib> +#include <iostream> +#include <stdio.h> +#include <string> +#include <stack> + +#include <sal/main.h> + +#include <com/sun/star/lang/XComponent.hpp> + +#include <com/sun/star/xml/sax/SAXException.hpp> +#include <com/sun/star/xml/sax/Parser.hpp> +#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp> + +#include <cppuhelper/bootstrap.hxx> +#include <cppuhelper/implbase.hxx> +#include <tools/long.hxx> +#include <rtl/ref.hxx> + +#include "LocaleNode.hxx" + +using namespace ::std; +using namespace ::cppu; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::xml::sax; +using namespace ::com::sun::star::io; + +namespace { + +/************ + * Sequence of bytes -> InputStream + ************/ +class OInputStream : public WeakImplHelper < XInputStream > +{ +public: + explicit OInputStream( const Sequence< sal_Int8 >&seq ) + : nPos(0) + , m_seq(seq) + {} + +public: + virtual sal_Int32 SAL_CALL readBytes( Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead ) override + { + nBytesToRead = std::min(nBytesToRead, m_seq.getLength() - nPos); + aData = Sequence< sal_Int8 > ( &(m_seq.getConstArray()[nPos]) , nBytesToRead ); + nPos += nBytesToRead; + return nBytesToRead; + } + virtual sal_Int32 SAL_CALL readSomeBytes( + css::uno::Sequence< sal_Int8 >& aData, + sal_Int32 nMaxBytesToRead ) override + { + return readBytes( aData, nMaxBytesToRead ); + } + virtual void SAL_CALL skipBytes( sal_Int32 /*nBytesToSkip*/ ) override + { + // not implemented + } + virtual sal_Int32 SAL_CALL available( ) override + { + return m_seq.getLength() - nPos; + } + virtual void SAL_CALL closeInput( ) override + { + // not needed + } + sal_Int32 nPos; + Sequence< sal_Int8> m_seq; +}; + +} + +// Helper : create an input stream from a file + +static Reference< XInputStream > createStreamFromFile( + const char *pcFile ) +{ + Reference< XInputStream > r; + + FILE *f = fopen( pcFile , "rb" ); + + if (!f) + { + fprintf(stderr, "failure opening %s\n", pcFile); + return r; + } + + if (fseek( f , 0 , SEEK_END ) == -1) + { + fprintf(stderr, "failure fseeking %s\n", pcFile); + fclose(f); + return r; + } + + tools::Long nLength = ftell( f ); + if (nLength == -1) + { + fprintf(stderr, "failure ftelling %s\n", pcFile); + fclose(f); + return r; + } + + if (fseek( f , 0 , SEEK_SET ) == -1) + { + fprintf(stderr, "failure fseeking %s\n", pcFile); + fclose(f); + return r; + } + + Sequence<sal_Int8> seqIn(nLength); + if (fread( seqIn.getArray(), nLength , 1 , f ) == 1) + r.set( new OInputStream( seqIn ) ); + else + fprintf(stderr, "failure reading %s\n", pcFile); + fclose( f ); + return r; +} + +namespace { + +class TestDocumentHandler : + public WeakImplHelper< XExtendedDocumentHandler , XEntityResolver , XErrorHandler > +{ +public: + TestDocumentHandler(const char* locale, const char* outFile ) + : rootNode(nullptr) + , nError(0) + , theLocale(locale) + , of(outFile, locale) + { + } + + virtual ~TestDocumentHandler( ) override + { + of.closeOutput(); + delete rootNode; + } + + +public: // Error handler + virtual void SAL_CALL error(const Any& aSAXParseException) override + { + ++nError; + printf( "Error !\n" ); + throw SAXException( + "error from error handler", + Reference < XInterface >() , + aSAXParseException ); + } + virtual void SAL_CALL fatalError(const Any& /*aSAXParseException*/) override + { + ++nError; + printf( "Fatal Error !\n" ); + } + virtual void SAL_CALL warning(const Any& /*aSAXParseException*/) override + { + printf( "Warning !\n" ); + } + + +public: // ExtendedDocumentHandler + + + stack<LocaleNode *> currentNode ; + LocaleNode * rootNode; + + virtual void SAL_CALL startDocument() override + { + printf( "parsing document %s started\n", theLocale.c_str()); + of.writeAsciiString("#include <sal/types.h>\n\n\n"); + of.writeAsciiString("#include <stdio.h>\n\n"); + of.writeAsciiString("extern \"C\" {\n\n"); + } + + virtual void SAL_CALL endDocument() override + { + if (rootNode) + { + rootNode->generateCode(of); + int err = rootNode->getError(); + if (err) + { + printf( "Error: in data for %s: %d\n", theLocale.c_str(), err); + nError += err; + } + } + else + { + ++nError; + printf( "Error: no data for %s\n", theLocale.c_str()); + } + printf( "parsing document %s finished\n", theLocale.c_str()); + + of.writeAsciiString("} // extern \"C\"\n\n"); + of.closeOutput(); + } + + virtual void SAL_CALL startElement(const OUString& aName, + const Reference< XAttributeList > & xAttribs) override + { + + LocaleNode * l = LocaleNode::createNode (aName, xAttribs); + if (!currentNode.empty() ) { + LocaleNode * ln = currentNode.top(); + ln->addChild(l); + } else { + rootNode = l; + } + currentNode.push (l); + } + + + virtual void SAL_CALL endElement(const OUString& /*aName*/) override + { + currentNode.pop(); + } + + virtual void SAL_CALL characters(const OUString& aChars) override + { + + LocaleNode * l = currentNode.top(); + l->setValue (aChars); + } + + virtual void SAL_CALL ignorableWhitespace(const OUString& /*aWhitespaces*/) override + { + } + + virtual void SAL_CALL processingInstruction(const OUString& /*aTarget*/, const OUString& /*aData*/) override + { + // ignored + } + + virtual void SAL_CALL setDocumentLocator(const Reference< XLocator> & /*xLocator*/) override + { + // ignored + } + + virtual InputSource SAL_CALL resolveEntity( + const OUString& sPublicId, + const OUString& sSystemId) override + { + InputSource source; + source.sSystemId = sSystemId; + source.sPublicId = sPublicId; + + source.aInputStream = createStreamFromFile( + OUStringToOString(sSystemId, RTL_TEXTENCODING_ASCII_US).getStr() ); + + return source; + } + + virtual void SAL_CALL startCDATA() override + { + } + virtual void SAL_CALL endCDATA() override + { + } + virtual void SAL_CALL comment(const OUString& /*sComment*/) override + { + } + virtual void SAL_CALL unknown(const OUString& /*sString*/) override + { + } + + virtual void SAL_CALL allowLineBreak() override + { + + } + +public: + int nError; + std::string theLocale; + OFileWriter of; +}; + +} + +SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv) +{ + try { + if( argc < 4) { + printf( "usage : %s <locale> <XML inputfile> <destination file>\n", argv[0] ); + exit( 1 ); + } + + Reference< XComponentContext > xContext( + defaultBootstrap_InitialComponentContext()); + + + // parser demo + // read xml from a file and count elements + + Reference< XParser > rParser = Parser::create(xContext); + + int nError = 0; + // create and connect the document handler to the parser + rtl::Reference<TestDocumentHandler> pDocHandler = new TestDocumentHandler( argv[1], argv[3]); + + rParser->setDocumentHandler( pDocHandler ); + rParser->setEntityResolver( pDocHandler ); + + // create the input stream + InputSource source; + source.aInputStream = createStreamFromFile( argv[2] ); + source.sSystemId = OUString::createFromAscii( argv[2] ); + + // start parsing + rParser->parseStream( source ); + + nError = pDocHandler->nError; + css::uno::Reference<css::lang::XComponent>( + xContext, css::uno::UNO_QUERY_THROW)->dispose(); + return nError; + } catch (css::uno::Exception & e) { + std::cerr << "ERROR: " << e.Message << '\n'; + return EXIT_FAILURE; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |