2 /* $Id: markup.ccg,v 1.5 2006/10/04 12:04:09 murrayc Exp $ */
4 /* Copyright (C) 2002 The gtkmm Development Team
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the Free
18 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include <glibmm/markup.h>
22 #include <glibmm/exceptionhandler.h>
23 #include <glibmm/utility.h>
33 Glib::ustring escape_text(const Glib::ustring& text)
35 const Glib::ScopedPtr<char> buf (g_markup_escape_text(text.data(), text.bytes()));
36 return Glib::ustring(buf.get());
40 /**** Glib::Markup::AttributeKeyLess ***************************************/
42 bool AttributeKeyLess::operator()(const Glib::ustring& lhs, const Glib::ustring& rhs) const
44 return (lhs.raw() < rhs.raw());
48 /**** Glib::Markup::ParserCallbacks ****************************************/
53 static const GMarkupParser vfunc_table;
55 static void start_element(GMarkupParseContext* context,
56 const char* element_name,
57 const char** attribute_names,
58 const char** attribute_values,
62 static void end_element(GMarkupParseContext* context,
63 const char* element_name,
67 static void text(GMarkupParseContext* context,
73 static void passthrough(GMarkupParseContext* context,
74 const char* passthrough_text,
79 static void error(GMarkupParseContext* context,
85 const GMarkupParser ParserCallbacks::vfunc_table =
87 &ParserCallbacks::start_element,
88 &ParserCallbacks::end_element,
89 &ParserCallbacks::text,
90 &ParserCallbacks::passthrough,
91 &ParserCallbacks::error,
94 void ParserCallbacks::start_element(GMarkupParseContext* context,
95 const char* element_name,
96 const char** attribute_names,
97 const char** attribute_values,
101 if(!&error) error = error; //Avoid an unused parameter warning when GLIBMM_EXCEPTIONS_ENABLED is used.
103 ParseContext& cpp_context = *static_cast<ParseContext*>(user_data);
104 g_return_if_fail(context == cpp_context.gobj());
106 #ifdef GLIBMM_EXCEPTIONS_ENABLED
109 #endif //GLIBMM_EXCEPTIONS_ENABLED
110 Parser::AttributeMap attributes;
112 if(attribute_names && attribute_values)
114 const char *const * pname = attribute_names;
115 const char *const * pvalue = attribute_values;
117 for(; *pname && *pvalue; ++pname, ++pvalue)
118 attributes.insert(Parser::AttributeMap::value_type(*pname, *pvalue));
120 g_return_if_fail(*pname == 0 && *pvalue == 0);
123 cpp_context.get_parser()->on_start_element(cpp_context, element_name, attributes);
124 #ifdef GLIBMM_EXCEPTIONS_ENABLED
126 catch(MarkupError& err)
128 err.propagate(error);
132 Glib::exception_handlers_invoke();
134 #endif //GLIBMM_EXCEPTIONS_ENABLED
137 void ParserCallbacks::end_element(GMarkupParseContext* context,
138 const char* element_name,
142 if(!&error) error = error; //Avoid an unused parameter warning when GLIBMM_EXCEPTIONS_ENABLED is used.
144 ParseContext& cpp_context = *static_cast<ParseContext*>(user_data);
145 g_return_if_fail(context == cpp_context.gobj());
147 #ifdef GLIBMM_EXCEPTIONS_ENABLED
150 #endif //GLIBMM_EXCEPTIONS_ENABLED
151 cpp_context.get_parser()->on_end_element(cpp_context, element_name);
152 #ifdef GLIBMM_EXCEPTIONS_ENABLED
154 catch(MarkupError& err)
156 err.propagate(error);
160 Glib::exception_handlers_invoke();
162 #endif //GLIBMM_EXCEPTIONS_ENABLED
165 void ParserCallbacks::text(GMarkupParseContext* context,
171 if(!&error) error = error; //Avoid an unused parameter warning when GLIBMM_EXCEPTIONS_ENABLED is used.
173 ParseContext& cpp_context = *static_cast<ParseContext*>(user_data);
174 g_return_if_fail(context == cpp_context.gobj());
176 #ifdef GLIBMM_EXCEPTIONS_ENABLED
179 #endif //GLIBMM_EXCEPTIONS_ENABLED
180 cpp_context.get_parser()->on_text(cpp_context, Glib::ustring(text, text + text_len));
181 #ifdef GLIBMM_EXCEPTIONS_ENABLED
183 catch(MarkupError& err)
185 err.propagate(error);
189 Glib::exception_handlers_invoke();
191 #endif //GLIBMM_EXCEPTIONS_ENABLED
194 void ParserCallbacks::passthrough(GMarkupParseContext* context,
195 const char* passthrough_text,
200 if(!&error) error = error; //Avoid an unused parameter warning when GLIBMM_EXCEPTIONS_ENABLED is used.
202 ParseContext& cpp_context = *static_cast<ParseContext*>(user_data);
203 g_return_if_fail(context == cpp_context.gobj());
205 #ifdef GLIBMM_EXCEPTIONS_ENABLED
208 #endif //GLIBMM_EXCEPTIONS_ENABLED
209 cpp_context.get_parser()->on_passthrough(
210 cpp_context, Glib::ustring(passthrough_text, passthrough_text + text_len));
211 #ifdef GLIBMM_EXCEPTIONS_ENABLED
213 catch(MarkupError& err)
215 err.propagate(error);
219 Glib::exception_handlers_invoke();
221 #endif //GLIBMM_EXCEPTIONS_ENABLED
224 void ParserCallbacks::error(GMarkupParseContext* context,
228 ParseContext& cpp_context = *static_cast<ParseContext*>(user_data);
230 g_return_if_fail(context == cpp_context.gobj());
231 g_return_if_fail(error->domain == G_MARKUP_ERROR);
233 #ifdef GLIBMM_EXCEPTIONS_ENABLED
236 #endif //GLIBMM_EXCEPTIONS_ENABLED
237 cpp_context.get_parser()->on_error(cpp_context, MarkupError(g_error_copy(error)));
238 #ifdef GLIBMM_EXCEPTIONS_ENABLED
242 Glib::exception_handlers_invoke();
244 #endif //GLIBMM_EXCEPTIONS_ENABLED
248 /**** Glib::Markup::Parser *************************************************/
256 void Parser::on_start_element(ParseContext&, const Glib::ustring&, const Parser::AttributeMap&)
259 void Parser::on_end_element(ParseContext&, const Glib::ustring&)
262 void Parser::on_text(ParseContext&, const Glib::ustring&)
265 void Parser::on_passthrough(ParseContext&, const Glib::ustring&)
268 void Parser::on_error(ParseContext&, const MarkupError&)
272 /**** Glib::Markup::ParseContext *******************************************/
274 ParseContext::ParseContext(Parser& parser, ParseFlags flags)
277 gobject_ (g_markup_parse_context_new(&ParserCallbacks::vfunc_table, (GMarkupParseFlags) flags,
278 this, &ParseContext::destroy_notify_callback))
281 ParseContext::~ParseContext()
284 g_markup_parse_context_free(gobject_);
287 void ParseContext::parse(const Glib::ustring& text)
290 g_markup_parse_context_parse(gobject_, text.data(), text.bytes(), &error);
293 Glib::Error::throw_exception(error);
296 void ParseContext::parse(const char* text_begin, const char* text_end)
299 g_markup_parse_context_parse(gobject_, text_begin, text_end - text_begin, &error);
302 Glib::Error::throw_exception(error);
305 void ParseContext::end_parse()
308 g_markup_parse_context_end_parse(gobject_, &error);
311 Glib::Error::throw_exception(error);
314 Glib::ustring ParseContext::get_element() const
316 const char *const element_name = g_markup_parse_context_get_element(gobject_);
317 return (element_name) ? Glib::ustring(element_name) : Glib::ustring();
320 int ParseContext::get_line_number() const
323 g_markup_parse_context_get_position(gobject_, &line_number, 0);
327 int ParseContext::get_char_number() const
330 g_markup_parse_context_get_position(gobject_, 0, &char_number);
335 void ParseContext::destroy_notify_callback(void* data)
337 ParseContext *const self = static_cast<ParseContext*>(data);
339 // Detect premature destruction.
340 g_return_if_fail(self->parser_ == 0);
343 } // namespace Markup