bump product version to 6.3.0.0.beta1
[LibreOffice.git] / shell / source / all / xml_parser.cxx
blobb067c6231b817e35ecfcae6809f5ce772678b601
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <xml_parser.hxx>
22 #include <i_xml_parser_event_handler.hxx>
24 #ifdef _WIN32
25 #include <utilities.hxx>
26 #else
27 #define UTF8ToWString(s) s
28 #endif
30 #include <assert.h>
32 namespace /* private */
35 /* Extracts the local part of tag without
36 namespace decoration e.g. meta:creator -> creator */
37 const XML_Char COLON = ':';
39 const XML_Char* get_local_name(const XML_Char* rawname)
41 const XML_Char* p = rawname;
43 // go to the end
44 while (*p) p++;
46 // go back until the first ':'
47 while (*p != COLON && p > rawname)
48 p--;
50 // if we are on a colon one step forward
51 if (*p == COLON)
52 p++;
54 return p;
57 xml_parser* get_parser_instance(void* data)
59 return static_cast<xml_parser*>(XML_GetUserData(
60 static_cast<XML_Parser>(data)));
63 bool has_only_whitespaces(const XML_Char* s, int len)
65 const XML_Char* p = s;
66 for (int i = 0; i < len; i++)
67 if (*p++ != ' ') return false;
68 return true;
72 xml_parser::xml_parser() :
73 document_handler_(nullptr),
74 xml_parser_(XML_ParserCreate(nullptr))
76 init();
79 xml_parser::~xml_parser()
81 XML_ParserFree(xml_parser_);
84 /* Callback functions will be called by the parser on
85 different events */
87 extern "C"
90 static void xml_start_element_handler(void* UserData, const XML_Char* name, const XML_Char** atts)
92 assert(UserData != nullptr);
94 xml_parser* pImpl = get_parser_instance(UserData);
96 i_xml_parser_event_handler* pDocHdl = pImpl->get_document_handler();
97 if (!pDocHdl)
98 return;
100 xml_tag_attribute_container_t attributes;
102 int i = 0;
104 while(atts[i])
106 attributes[UTF8ToWString(reinterpret_cast<const char*>(get_local_name(atts[i])))] = UTF8ToWString(reinterpret_cast<const char*>(atts[i+1]));
107 i += 2; // skip to next pair
110 pDocHdl->start_element(
111 UTF8ToWString(reinterpret_cast<const char*>(name)), UTF8ToWString(reinterpret_cast<const char*>(get_local_name(name))), attributes);
114 static void xml_end_element_handler(void* UserData, const XML_Char* name)
116 assert(UserData);
118 xml_parser* pImpl = get_parser_instance(UserData);
119 i_xml_parser_event_handler* pDocHdl = pImpl->get_document_handler();
120 if (pDocHdl)
121 pDocHdl->end_element(UTF8ToWString(reinterpret_cast<const char*>(name)), UTF8ToWString(reinterpret_cast<const char*>(get_local_name(name))));
124 static void xml_character_data_handler(void* UserData, const XML_Char* s, int len)
126 assert(UserData);
128 xml_parser* pImpl = get_parser_instance(UserData);
129 i_xml_parser_event_handler* pDocHdl = pImpl->get_document_handler();
130 if (pDocHdl)
132 if (has_only_whitespaces(s,len))
133 pDocHdl->ignore_whitespace(UTF8ToWString(std::string(reinterpret_cast<const char*>(s), len)));
134 else
135 pDocHdl->characters(UTF8ToWString(std::string(reinterpret_cast<const char*>(s), len)));
139 static void xml_comment_handler(void* UserData, const XML_Char* Data)
141 assert(UserData);
143 xml_parser* pImpl = get_parser_instance(UserData);
144 i_xml_parser_event_handler* pDocHdl = pImpl->get_document_handler();
145 if (pDocHdl)
146 pDocHdl->comment(UTF8ToWString(reinterpret_cast<const char*>(Data)));
149 } // extern "C"
151 void xml_parser::init()
153 XML_SetUserData(xml_parser_, this);
155 // we use the parser as handler argument,
156 // so we could use it if necessary, the
157 // UserData are usable anyway using
158 // XML_GetUserData(...)
159 XML_UseParserAsHandlerArg(xml_parser_);
161 XML_SetElementHandler(
162 xml_parser_,
163 xml_start_element_handler,
164 xml_end_element_handler);
166 XML_SetCharacterDataHandler(
167 xml_parser_,
168 xml_character_data_handler);
170 XML_SetCommentHandler(
171 xml_parser_,
172 xml_comment_handler);
175 void xml_parser::parse(const char* XmlData, size_t Length, bool IsFinal)
177 if (XML_STATUS_ERROR ==
178 XML_Parse(xml_parser_, XmlData, static_cast<int>(Length), IsFinal))
180 throw xml_parser_exception(
181 XML_ErrorString(XML_GetErrorCode(xml_parser_)));
185 void xml_parser::set_document_handler(
186 i_xml_parser_event_handler* event_handler)
188 document_handler_ = event_handler;
192 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */