13
0
livetrax/libs/glibmm2/glib/src/markup.ccg
Carl Hetherington a313924b77 Re-add glibmm2 properly.
git-svn-id: svn://localhost/ardour2/trunk@2644 d708f5d6-7413-0410-9779-e7cbd77b26cf
2007-11-13 10:37:24 +00:00

347 lines
9.9 KiB
C++

// -*- c++ -*-
/* $Id: markup.ccg,v 1.5 2006/10/04 12:04:09 murrayc Exp $ */
/* Copyright (C) 2002 The gtkmm Development Team
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <glibmm/markup.h>
#include <glibmm/exceptionhandler.h>
#include <glibmm/utility.h>
#include <glib.h>
namespace Glib
{
namespace Markup
{
Glib::ustring escape_text(const Glib::ustring& text)
{
const Glib::ScopedPtr<char> buf (g_markup_escape_text(text.data(), text.bytes()));
return Glib::ustring(buf.get());
}
/**** Glib::Markup::AttributeKeyLess ***************************************/
bool AttributeKeyLess::operator()(const Glib::ustring& lhs, const Glib::ustring& rhs) const
{
return (lhs.raw() < rhs.raw());
}
/**** Glib::Markup::ParserCallbacks ****************************************/
class ParserCallbacks
{
public:
static const GMarkupParser vfunc_table;
static void start_element(GMarkupParseContext* context,
const char* element_name,
const char** attribute_names,
const char** attribute_values,
void* user_data,
GError** error);
static void end_element(GMarkupParseContext* context,
const char* element_name,
void* user_data,
GError** error);
static void text(GMarkupParseContext* context,
const char* text,
gsize text_len,
void* user_data,
GError** error);
static void passthrough(GMarkupParseContext* context,
const char* passthrough_text,
gsize text_len,
void* user_data,
GError** error);
static void error(GMarkupParseContext* context,
GError* error,
void* user_data);
};
const GMarkupParser ParserCallbacks::vfunc_table =
{
&ParserCallbacks::start_element,
&ParserCallbacks::end_element,
&ParserCallbacks::text,
&ParserCallbacks::passthrough,
&ParserCallbacks::error,
};
void ParserCallbacks::start_element(GMarkupParseContext* context,
const char* element_name,
const char** attribute_names,
const char** attribute_values,
void* user_data,
GError** error)
{
if(!&error) error = error; //Avoid an unused parameter warning when GLIBMM_EXCEPTIONS_ENABLED is used.
ParseContext& cpp_context = *static_cast<ParseContext*>(user_data);
g_return_if_fail(context == cpp_context.gobj());
#ifdef GLIBMM_EXCEPTIONS_ENABLED
try
{
#endif //GLIBMM_EXCEPTIONS_ENABLED
Parser::AttributeMap attributes;
if(attribute_names && attribute_values)
{
const char *const * pname = attribute_names;
const char *const * pvalue = attribute_values;
for(; *pname && *pvalue; ++pname, ++pvalue)
attributes.insert(Parser::AttributeMap::value_type(*pname, *pvalue));
g_return_if_fail(*pname == 0 && *pvalue == 0);
}
cpp_context.get_parser()->on_start_element(cpp_context, element_name, attributes);
#ifdef GLIBMM_EXCEPTIONS_ENABLED
}
catch(MarkupError& err)
{
err.propagate(error);
}
catch(...)
{
Glib::exception_handlers_invoke();
}
#endif //GLIBMM_EXCEPTIONS_ENABLED
}
void ParserCallbacks::end_element(GMarkupParseContext* context,
const char* element_name,
void* user_data,
GError** error)
{
if(!&error) error = error; //Avoid an unused parameter warning when GLIBMM_EXCEPTIONS_ENABLED is used.
ParseContext& cpp_context = *static_cast<ParseContext*>(user_data);
g_return_if_fail(context == cpp_context.gobj());
#ifdef GLIBMM_EXCEPTIONS_ENABLED
try
{
#endif //GLIBMM_EXCEPTIONS_ENABLED
cpp_context.get_parser()->on_end_element(cpp_context, element_name);
#ifdef GLIBMM_EXCEPTIONS_ENABLED
}
catch(MarkupError& err)
{
err.propagate(error);
}
catch(...)
{
Glib::exception_handlers_invoke();
}
#endif //GLIBMM_EXCEPTIONS_ENABLED
}
void ParserCallbacks::text(GMarkupParseContext* context,
const char* text,
gsize text_len,
void* user_data,
GError** error)
{
if(!&error) error = error; //Avoid an unused parameter warning when GLIBMM_EXCEPTIONS_ENABLED is used.
ParseContext& cpp_context = *static_cast<ParseContext*>(user_data);
g_return_if_fail(context == cpp_context.gobj());
#ifdef GLIBMM_EXCEPTIONS_ENABLED
try
{
#endif //GLIBMM_EXCEPTIONS_ENABLED
cpp_context.get_parser()->on_text(cpp_context, Glib::ustring(text, text + text_len));
#ifdef GLIBMM_EXCEPTIONS_ENABLED
}
catch(MarkupError& err)
{
err.propagate(error);
}
catch(...)
{
Glib::exception_handlers_invoke();
}
#endif //GLIBMM_EXCEPTIONS_ENABLED
}
void ParserCallbacks::passthrough(GMarkupParseContext* context,
const char* passthrough_text,
gsize text_len,
void* user_data,
GError** error)
{
if(!&error) error = error; //Avoid an unused parameter warning when GLIBMM_EXCEPTIONS_ENABLED is used.
ParseContext& cpp_context = *static_cast<ParseContext*>(user_data);
g_return_if_fail(context == cpp_context.gobj());
#ifdef GLIBMM_EXCEPTIONS_ENABLED
try
{
#endif //GLIBMM_EXCEPTIONS_ENABLED
cpp_context.get_parser()->on_passthrough(
cpp_context, Glib::ustring(passthrough_text, passthrough_text + text_len));
#ifdef GLIBMM_EXCEPTIONS_ENABLED
}
catch(MarkupError& err)
{
err.propagate(error);
}
catch(...)
{
Glib::exception_handlers_invoke();
}
#endif //GLIBMM_EXCEPTIONS_ENABLED
}
void ParserCallbacks::error(GMarkupParseContext* context,
GError* error,
void* user_data)
{
ParseContext& cpp_context = *static_cast<ParseContext*>(user_data);
g_return_if_fail(context == cpp_context.gobj());
g_return_if_fail(error->domain == G_MARKUP_ERROR);
#ifdef GLIBMM_EXCEPTIONS_ENABLED
try
{
#endif //GLIBMM_EXCEPTIONS_ENABLED
cpp_context.get_parser()->on_error(cpp_context, MarkupError(g_error_copy(error)));
#ifdef GLIBMM_EXCEPTIONS_ENABLED
}
catch(...)
{
Glib::exception_handlers_invoke();
}
#endif //GLIBMM_EXCEPTIONS_ENABLED
}
/**** Glib::Markup::Parser *************************************************/
Parser::Parser()
{}
Parser::~Parser()
{}
void Parser::on_start_element(ParseContext&, const Glib::ustring&, const Parser::AttributeMap&)
{}
void Parser::on_end_element(ParseContext&, const Glib::ustring&)
{}
void Parser::on_text(ParseContext&, const Glib::ustring&)
{}
void Parser::on_passthrough(ParseContext&, const Glib::ustring&)
{}
void Parser::on_error(ParseContext&, const MarkupError&)
{}
/**** Glib::Markup::ParseContext *******************************************/
ParseContext::ParseContext(Parser& parser, ParseFlags flags)
:
parser_ (&parser),
gobject_ (g_markup_parse_context_new(&ParserCallbacks::vfunc_table, (GMarkupParseFlags) flags,
this, &ParseContext::destroy_notify_callback))
{}
ParseContext::~ParseContext()
{
parser_ = 0;
g_markup_parse_context_free(gobject_);
}
void ParseContext::parse(const Glib::ustring& text)
{
GError* error = 0;
g_markup_parse_context_parse(gobject_, text.data(), text.bytes(), &error);
if(error)
Glib::Error::throw_exception(error);
}
void ParseContext::parse(const char* text_begin, const char* text_end)
{
GError* error = 0;
g_markup_parse_context_parse(gobject_, text_begin, text_end - text_begin, &error);
if(error)
Glib::Error::throw_exception(error);
}
void ParseContext::end_parse()
{
GError* error = 0;
g_markup_parse_context_end_parse(gobject_, &error);
if(error)
Glib::Error::throw_exception(error);
}
Glib::ustring ParseContext::get_element() const
{
const char *const element_name = g_markup_parse_context_get_element(gobject_);
return (element_name) ? Glib::ustring(element_name) : Glib::ustring();
}
int ParseContext::get_line_number() const
{
int line_number = 0;
g_markup_parse_context_get_position(gobject_, &line_number, 0);
return line_number;
}
int ParseContext::get_char_number() const
{
int char_number = 0;
g_markup_parse_context_get_position(gobject_, 0, &char_number);
return char_number;
}
// static
void ParseContext::destroy_notify_callback(void* data)
{
ParseContext *const self = static_cast<ParseContext*>(data);
// Detect premature destruction.
g_return_if_fail(self->parser_ == 0);
}
} // namespace Markup
} // namespace Glib