Update ooo320-m1
[ooovba.git] / shell / source / all / xml_parser.cxx
blob5dcb35168265b99ed4de723dd952cc69afc501f8
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: xml_parser.cxx,v $
10 * $Revision: 1.10 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_shell.hxx"
34 #ifndef XML_PARSER_HXX_INCLUDED
35 #include "internal/xml_parser.hxx"
36 #endif
37 #include "internal/i_xml_parser_event_handler.hxx"
39 #include <assert.h>
41 namespace /* private */
44 //######################################################
45 /* Extracts the local part of tag without
46 namespace decoration e.g. meta:creator -> creator */
47 const XML_Char COLON = (XML_Char)':';
49 const XML_Char* get_local_name(const XML_Char* rawname)
51 const XML_Char* p = rawname;
53 // go to the end
54 while (*p) p++;
56 // go back until the first ':'
57 while (*p != COLON && p > rawname)
58 p--;
60 // if we are on a colon one step forward
61 if (*p == COLON)
62 p++;
64 return p;
67 //################################################
68 inline xml_parser* get_parser_instance(void* data)
70 return reinterpret_cast<xml_parser*>(XML_GetUserData(
71 reinterpret_cast<XML_Parser>(data)));
74 //################################################
75 bool has_only_whitespaces(const XML_Char* s, int len)
77 const XML_Char* p = s;
78 for (int i = 0; i < len; i++)
79 if (*p++ != ' ') return false;
80 return true;
84 //###################################################
85 xml_parser::xml_parser(const XML_Char* EncodingName) :
86 document_handler_(0),
87 xml_parser_(XML_ParserCreate(EncodingName))
89 init();
92 //###################################################
93 xml_parser::xml_parser(const XML_Char* EncodingName, XML_Char /*NamespaceSeparator*/) :
94 document_handler_(0),
95 xml_parser_(XML_ParserCreate(EncodingName))
97 init();
100 //###################################################
101 xml_parser::~xml_parser()
103 XML_ParserFree(xml_parser_);
106 //###################################################
107 /* Callback functions will be called by the parser on
108 different events */
110 //###################################################
111 extern "C"
114 static void xml_start_element_handler(void* UserData, const XML_Char* name, const XML_Char** atts)
116 assert(UserData != NULL);
118 xml_parser* pImpl = get_parser_instance(UserData);
120 i_xml_parser_event_handler* pDocHdl = pImpl->get_document_handler();
121 if (pDocHdl)
123 xml_tag_attribute_container_t attributes;
125 int i = 0;
127 while(atts[i])
129 attributes[reinterpret_cast<const char_t*>(get_local_name(atts[i]))] = reinterpret_cast<const char_t*>(atts[i+1]);
130 i += 2; // skip to next pair
133 pDocHdl->start_element(
134 reinterpret_cast<const char_t*>(name), reinterpret_cast<const char_t*>(get_local_name(name)), attributes);
138 //###################################################
139 static void xml_end_element_handler(void* UserData, const XML_Char* name)
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->end_element(reinterpret_cast<const char_t*>(name), reinterpret_cast<const char_t*>(get_local_name(name)));
149 //###################################################
150 static void xml_character_data_handler(void* UserData, const XML_Char* s, int len)
152 assert(UserData);
154 xml_parser* pImpl = get_parser_instance(UserData);
155 i_xml_parser_event_handler* pDocHdl = pImpl->get_document_handler();
156 if (pDocHdl)
158 if (has_only_whitespaces(s,len))
159 pDocHdl->ignore_whitespace(string_t(reinterpret_cast<const char_t*>(s), len));
160 else
161 pDocHdl->characters(string_t(reinterpret_cast<const char_t*>(s), len));
165 //###################################################
166 static void xml_comment_handler(void* UserData, const XML_Char* Data)
168 assert(UserData);
170 xml_parser* pImpl = get_parser_instance(UserData);
171 i_xml_parser_event_handler* pDocHdl = pImpl->get_document_handler();
172 if (pDocHdl)
173 pDocHdl->comment(reinterpret_cast<const char_t*>(Data));
176 } // extern "C"
178 //###################################################
179 void xml_parser::init()
181 XML_SetUserData(xml_parser_, this);
183 // we use the parser as handler argument,
184 // so we could use it if necessary, the
185 // UserData are usable anyway using
186 // XML_GetUserData(...)
187 XML_UseParserAsHandlerArg(xml_parser_);
189 XML_SetElementHandler(
190 xml_parser_,
191 xml_start_element_handler,
192 xml_end_element_handler);
194 XML_SetCharacterDataHandler(
195 xml_parser_,
196 xml_character_data_handler);
198 XML_SetCommentHandler(
199 xml_parser_,
200 xml_comment_handler);
203 //###################################################
204 void xml_parser::parse(const char* XmlData, size_t Length, bool IsFinal)
206 if (0 == XML_Parse(xml_parser_, XmlData, Length, IsFinal))
207 throw xml_parser_exception(
208 (char*)XML_ErrorString(XML_GetErrorCode(xml_parser_)),
209 (int)XML_GetErrorCode(xml_parser_),
210 XML_GetCurrentLineNumber(xml_parser_),
211 XML_GetCurrentColumnNumber(xml_parser_),
212 XML_GetCurrentByteIndex(xml_parser_));
215 //###################################################
216 void xml_parser::set_document_handler(
217 i_xml_parser_event_handler* event_handler)
219 document_handler_ = event_handler;
222 //###################################################
223 i_xml_parser_event_handler* xml_parser::get_document_handler() const
225 return document_handler_;
228 //###################################################
229 void xml_parser::set_encoding(const XML_Char* Encoding)
231 XML_SetEncoding(xml_parser_, Encoding);