/* Xml.c generated by valac 0.56.19, the Vala compiler
 * generated from Xml.vala, do not modify */

/*
    Copyright (C) 2014 Johan Mattsson

    This library is free software; you can redistribute it and/or modify 
    it under the terms of the GNU Lesser General Public License as 
    published by the Free Software Foundation; either version 3 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 
    Lesser General Public License for more details.
*/

#include <glib.h>
#include "xmlbird.h"
#include <glib-object.h>
#include <stdlib.h>
#include <string.h>

#define B_NONE 0
#define B_WARNINGS 1
#if !defined(VALA_STRICT_C)
#if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ >= 14)
#pragma GCC diagnostic warning "-Wincompatible-pointer-types"
#elif defined(__clang__) && (__clang_major__ >= 16)
#pragma clang diagnostic ignored "-Wincompatible-function-pointer-types"
#pragma clang diagnostic ignored "-Wincompatible-pointer-types"
#endif
#endif

#define B_TYPE_XML_STRING (b_xml_string_get_type ())
#define B_XML_STRING(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), B_TYPE_XML_STRING, BXmlString))
#define B_XML_STRING_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), B_TYPE_XML_STRING, BXmlStringClass))
#define B_IS_XML_STRING(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), B_TYPE_XML_STRING))
#define B_IS_XML_STRING_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), B_TYPE_XML_STRING))
#define B_XML_STRING_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), B_TYPE_XML_STRING, BXmlStringClass))

typedef struct _BXmlString BXmlString;
typedef struct _BXmlStringClass BXmlStringClass;

#define B_TYPE_XML_DATA (b_xml_data_get_type ())
#define B_XML_DATA(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), B_TYPE_XML_DATA, BXmlData))
#define B_XML_DATA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), B_TYPE_XML_DATA, BXmlDataClass))
#define B_IS_XML_DATA(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), B_TYPE_XML_DATA))
#define B_IS_XML_DATA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), B_TYPE_XML_DATA))
#define B_XML_DATA_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), B_TYPE_XML_DATA, BXmlDataClass))

typedef struct _BXmlData BXmlData;
typedef struct _BXmlDataClass BXmlDataClass;
enum  {
	B_XML_PARSER_0_PROPERTY,
	B_XML_PARSER_NUM_PROPERTIES
};
static GParamSpec* b_xml_parser_properties[B_XML_PARSER_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _g_free0(var) (var = (g_free (var), NULL))
typedef struct _BXmlStringPrivate BXmlStringPrivate;
typedef struct _BXmlDataPrivate BXmlDataPrivate;
#define _g_regex_unref0(var) ((var == NULL) ? NULL : (var = (g_regex_unref (var), NULL)))

struct _BXmlParserPrivate {
	BTag* root;
	BXmlData* data;
	gchar* input;
	gboolean error;
};

struct _BXmlString {
	GObject parent_instance;
	BXmlStringPrivate * priv;
	gint length;
	gchar* data;
};

struct _BXmlStringClass {
	GObjectClass parent_class;
};

struct _BXmlData {
	BXmlString parent_instance;
	BXmlDataPrivate * priv;
	gboolean error;
	gint log_level;
};

struct _BXmlDataClass {
	BXmlStringClass parent_class;
};

static gint BXmlParser_private_offset;
static gpointer b_xml_parser_parent_class = NULL;

VALA_EXTERN GType b_xml_string_get_type (void) G_GNUC_CONST ;
VALA_EXTERN GType b_xml_data_get_type (void) G_GNUC_CONST ;
VALA_EXTERN BXmlData* b_xml_data_new (gchar* data,
                          gint length,
                          gint log_level);
VALA_EXTERN BXmlData* b_xml_data_construct (GType object_type,
                                gchar* data,
                                gint length,
                                gint log_level);
VALA_EXTERN void b_xml_parser_reparse (BXmlParser* self,
                           gint log_level);
static gboolean b_xml_parser_validate_tags (BXmlParser* self,
                                     BTag* tag);
VALA_EXTERN gboolean b_tag_has_failed (BTag* self);
VALA_EXTERN gint b_attribute_get_name_length (BAttribute* self);
VALA_EXTERN BXmlString* b_xml_string_new (gchar* data,
                              gint length);
VALA_EXTERN BXmlString* b_xml_string_construct (GType object_type,
                                    gchar* data,
                                    gint length);
static gint b_xml_parser_find_root_tag (BXmlParser* self);
VALA_EXTERN void b_xml_parser_warning (const gchar* message);
VALA_EXTERN BTag* b_tag_new_empty (void);
VALA_EXTERN BTag* b_tag_construct_empty (GType object_type);
VALA_EXTERN BXmlString* b_xml_string_substring (BXmlString* self,
                                    gint offset,
                                    gint len);
VALA_EXTERN BTag* b_tag_new (BXmlString* name,
                 BXmlString* attributes,
                 BXmlString* content,
                 gint log_level,
                 BXmlData* entire_file,
                 BTag* parent);
VALA_EXTERN BTag* b_tag_construct (GType object_type,
                       BXmlString* name,
                       BXmlString* attributes,
                       BXmlString* content,
                       gint log_level,
                       BXmlData* entire_file,
                       BTag* parent);
VALA_EXTERN BTag* b_tag_get_next_tag (BTag* self);
VALA_EXTERN gboolean b_xml_string_get_next_ascii_char (BXmlString* self,
                                           gint* index,
                                           gunichar* c);
static void b_xml_parser_finalize (GObject * obj);
static GType b_xml_parser_get_type_once (void);

static inline gpointer
b_xml_parser_get_instance_private (BXmlParser* self)
{
	return G_STRUCT_MEMBER_P (self, BXmlParser_private_offset);
}

/** 
 * Create a new xml parser. 
 * @param data valid xml data
 */
BXmlParser*
b_xml_parser_construct (GType object_type,
                        const gchar* data)
{
	BXmlParser * self = NULL;
	gchar* _tmp0_;
	gint _tmp1_;
	gint _tmp2_;
	BXmlData* _tmp3_;
	g_return_val_if_fail (data != NULL, NULL);
	self = (BXmlParser*) g_object_new (object_type, NULL);
	_tmp0_ = g_strdup (data);
	_g_free0 (self->priv->input);
	self->priv->input = _tmp0_;
	_tmp1_ = strlen (data);
	_tmp2_ = _tmp1_;
	_tmp3_ = b_xml_data_new (data, _tmp2_, B_NONE);
	_g_object_unref0 (self->priv->data);
	self->priv->data = _tmp3_;
	b_xml_parser_reparse (self, B_NONE);
	return self;
}

BXmlParser*
b_xml_parser_new (const gchar* data)
{
	return b_xml_parser_construct (B_TYPE_XML_PARSER, data);
}

/** 
 * Determine if the document can be parsed.
 * @return true if the xml document is valid xml.
 */
gboolean
b_xml_parser_validate (BXmlParser* self)
{
	gboolean valid = FALSE;
	BXmlData* _tmp0_;
	BTag* _tmp1_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = self->priv->data;
	if (_tmp0_->error) {
		self->priv->error = TRUE;
		result = FALSE;
		return result;
	}
	b_xml_parser_reparse (self, B_NONE);
	if (self->priv->error) {
		result = FALSE;
		return result;
	}
	_tmp1_ = self->priv->root;
	valid = b_xml_parser_validate_tags (self, _tmp1_);
	b_xml_parser_reparse (self, B_NONE);
	result = valid;
	return result;
}

static gboolean
b_xml_parser_validate_tags (BXmlParser* self,
                            BTag* tag)
{
	BAttributes* attributes = NULL;
	BAttributes* _tmp0_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (tag != NULL, FALSE);
	_tmp0_ = b_tag_get_attributes (tag);
	attributes = _tmp0_;
	tag->log_level = B_NONE;
	{
		BAttributesIterator* _a_it = NULL;
		BAttributes* _tmp1_;
		BAttributesIterator* _tmp2_;
		_tmp1_ = attributes;
		_tmp2_ = b_attributes_iterator (_tmp1_);
		_a_it = _tmp2_;
		while (TRUE) {
			BAttributesIterator* _tmp3_;
			BAttribute* a = NULL;
			BAttributesIterator* _tmp4_;
			BAttribute* _tmp5_;
			gboolean _tmp6_ = FALSE;
			gboolean _tmp7_ = FALSE;
			_tmp3_ = _a_it;
			if (!b_attributes_iterator_next (_tmp3_)) {
				break;
			}
			_tmp4_ = _a_it;
			_tmp5_ = b_attributes_iterator_get (_tmp4_);
			a = _tmp5_;
			if (self->priv->error) {
				_tmp7_ = TRUE;
			} else {
				_tmp7_ = b_tag_has_failed (tag);
			}
			if (_tmp7_) {
				_tmp6_ = TRUE;
			} else {
				BAttribute* _tmp8_;
				_tmp8_ = a;
				_tmp6_ = b_attribute_get_name_length (_tmp8_) == 0;
			}
			if (_tmp6_) {
				result = FALSE;
				_g_object_unref0 (a);
				_g_object_unref0 (_a_it);
				_g_object_unref0 (attributes);
				return result;
			}
			_g_object_unref0 (a);
		}
		_g_object_unref0 (_a_it);
	}
	{
		BTagIterator* _t_it = NULL;
		BTagIterator* _tmp9_;
		_tmp9_ = b_tag_iterator (tag);
		_t_it = _tmp9_;
		while (TRUE) {
			BTagIterator* _tmp10_;
			BTag* t = NULL;
			BTagIterator* _tmp11_;
			BTag* _tmp12_;
			gboolean _tmp13_ = FALSE;
			gboolean _tmp14_ = FALSE;
			BTag* _tmp16_;
			_tmp10_ = _t_it;
			if (!b_tag_iterator_next (_tmp10_)) {
				break;
			}
			_tmp11_ = _t_it;
			_tmp12_ = b_tag_iterator_get (_tmp11_);
			t = _tmp12_;
			if (self->priv->error) {
				_tmp14_ = TRUE;
			} else {
				BTag* _tmp15_;
				_tmp15_ = t;
				_tmp14_ = b_tag_has_failed (_tmp15_);
			}
			if (_tmp14_) {
				_tmp13_ = TRUE;
			} else {
				_tmp13_ = b_tag_has_failed (tag);
			}
			if (_tmp13_) {
				result = FALSE;
				_g_object_unref0 (t);
				_g_object_unref0 (_t_it);
				_g_object_unref0 (attributes);
				return result;
			}
			_tmp16_ = t;
			if (!b_xml_parser_validate_tags (self, _tmp16_)) {
				result = FALSE;
				_g_object_unref0 (t);
				_g_object_unref0 (_t_it);
				_g_object_unref0 (attributes);
				return result;
			}
			_g_object_unref0 (t);
		}
		_g_object_unref0 (_t_it);
	}
	if (b_tag_has_failed (tag)) {
		result = FALSE;
		_g_object_unref0 (attributes);
		return result;
	}
	result = TRUE;
	_g_object_unref0 (attributes);
	return result;
}

/** 
 * Obtain the root tag.
 * @return the root tag. 
 */
static gpointer
_g_object_ref0 (gpointer self)
{
	return self ? g_object_ref (self) : NULL;
}

BTag*
b_xml_parser_get_root_tag (BXmlParser* self)
{
	BTag* _tmp0_;
	BTag* _tmp1_;
	BTag* result;
	g_return_val_if_fail (self != NULL, NULL);
	b_xml_parser_reparse (self, B_WARNINGS);
	_tmp0_ = self->priv->root;
	_tmp1_ = _g_object_ref0 (_tmp0_);
	result = _tmp1_;
	return result;
}

/** 
 * Reset the parser and start from the beginning of the XML document. 
 */
void
b_xml_parser_reparse (BXmlParser* self,
                      gint log_level)
{
	gint root_index = 0;
	BTag* container = NULL;
	BXmlString* content = NULL;
	BXmlString* empty = NULL;
	BXmlString* _tmp0_;
	BXmlData* _tmp1_;
	g_return_if_fail (self != NULL);
	self->priv->error = FALSE;
	_tmp0_ = b_xml_string_new ("", 0);
	_g_object_unref0 (empty);
	empty = _tmp0_;
	_tmp1_ = self->priv->data;
	_tmp1_->log_level = log_level;
	root_index = b_xml_parser_find_root_tag (self);
	if (root_index == -1) {
		BTag* _tmp2_;
		if (log_level == B_WARNINGS) {
			b_xml_parser_warning ("No root tag found.");
		}
		self->priv->error = TRUE;
		_tmp2_ = b_tag_new_empty ();
		_g_object_unref0 (self->priv->root);
		self->priv->root = _tmp2_;
	} else {
		BXmlData* _tmp3_;
		BXmlString* _tmp4_;
		BXmlString* _tmp5_;
		BXmlString* _tmp6_;
		BXmlString* _tmp7_;
		BXmlData* _tmp8_;
		BTag* _tmp9_;
		BTag* _tmp10_;
		BTag* _tmp11_;
		BTag* _tmp12_;
		_tmp3_ = self->priv->data;
		_tmp4_ = b_xml_string_substring ((BXmlString*) _tmp3_, root_index, -1);
		_g_object_unref0 (content);
		content = _tmp4_;
		_tmp5_ = empty;
		_tmp6_ = empty;
		_tmp7_ = content;
		_tmp8_ = self->priv->data;
		_tmp9_ = b_tag_new (_tmp5_, _tmp6_, _tmp7_, log_level, _tmp8_, NULL);
		_g_object_unref0 (container);
		container = _tmp9_;
		_tmp10_ = container;
		_tmp11_ = b_tag_get_next_tag (_tmp10_);
		_g_object_unref0 (self->priv->root);
		self->priv->root = _tmp11_;
		_tmp12_ = container;
		if (b_tag_has_failed (_tmp12_)) {
			self->priv->error = TRUE;
		}
	}
	_g_object_unref0 (empty);
	_g_object_unref0 (content);
	_g_object_unref0 (container);
}

static gint
b_xml_parser_find_root_tag (BXmlParser* self)
{
	gint index = 0;
	gint prev_index = 0;
	gint modifier = 0;
	gunichar c = 0U;
	gint result;
	g_return_val_if_fail (self != NULL, -1);
	index = 0;
	prev_index = 0;
	modifier = 0;
	while (TRUE) {
		BXmlData* _tmp0_;
		gunichar _tmp1_ = 0U;
		gboolean _tmp2_;
		prev_index = index;
		_tmp0_ = self->priv->data;
		_tmp2_ = b_xml_string_get_next_ascii_char ((BXmlString*) _tmp0_, &index, &_tmp1_);
		c = _tmp1_;
		if (!_tmp2_) {
			break;
		}
		if (c == ((gunichar) '<')) {
			BXmlData* _tmp3_;
			gunichar _tmp4_ = 0U;
			gboolean _tmp5_ = FALSE;
			gboolean _tmp6_ = FALSE;
			modifier = index;
			_tmp3_ = self->priv->data;
			b_xml_string_get_next_ascii_char ((BXmlString*) _tmp3_, &modifier, &_tmp4_);
			c = _tmp4_;
			if (c != ((gunichar) '?')) {
				_tmp6_ = c != ((gunichar) '[');
			} else {
				_tmp6_ = FALSE;
			}
			if (_tmp6_) {
				_tmp5_ = c != ((gunichar) '!');
			} else {
				_tmp5_ = FALSE;
			}
			if (_tmp5_) {
				result = prev_index;
				return result;
			}
		}
	}
	result = -1;
	return result;
}

/**
 * Print a warning message.
 */
void
b_xml_parser_warning (const gchar* message)
{
	g_return_if_fail (message != NULL);
	g_print ("XML error: ");
	g_print ("%s", message);
	g_print ("\n");
}

/**
 * Replace escaped character with plain text characters. 
 * &amp; will be replaced with & etc.
 */
static gchar*
string_replace (const gchar* self,
                const gchar* old,
                const gchar* replacement)
{
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	GError* _inner_error0_ = NULL;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (old != NULL, NULL);
	g_return_val_if_fail (replacement != NULL, NULL);
	if ((*((gchar*) self)) == '\0') {
		_tmp1_ = TRUE;
	} else {
		_tmp1_ = (*((gchar*) old)) == '\0';
	}
	if (_tmp1_) {
		_tmp0_ = TRUE;
	} else {
		_tmp0_ = g_strcmp0 (old, replacement) == 0;
	}
	if (_tmp0_) {
		gchar* _tmp2_;
		_tmp2_ = g_strdup (self);
		result = _tmp2_;
		return result;
	}
	{
		GRegex* regex = NULL;
		gchar* _tmp3_;
		gchar* _tmp4_;
		GRegex* _tmp5_;
		GRegex* _tmp6_;
		gchar* _tmp7_ = NULL;
		GRegex* _tmp8_;
		gchar* _tmp9_;
		gchar* _tmp10_;
		_tmp3_ = g_regex_escape_string (old, -1);
		_tmp4_ = _tmp3_;
		_tmp5_ = g_regex_new (_tmp4_, 0, 0, &_inner_error0_);
		_tmp6_ = _tmp5_;
		_g_free0 (_tmp4_);
		regex = _tmp6_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			if (_inner_error0_->domain == G_REGEX_ERROR) {
				goto __catch0_g_regex_error;
			}
			g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
			g_clear_error (&_inner_error0_);
			return NULL;
		}
		_tmp8_ = regex;
		_tmp9_ = g_regex_replace_literal (_tmp8_, self, (gssize) -1, 0, replacement, 0, &_inner_error0_);
		_tmp7_ = _tmp9_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			_g_regex_unref0 (regex);
			if (_inner_error0_->domain == G_REGEX_ERROR) {
				goto __catch0_g_regex_error;
			}
			g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
			g_clear_error (&_inner_error0_);
			return NULL;
		}
		_tmp10_ = _tmp7_;
		_tmp7_ = NULL;
		result = _tmp10_;
		_g_free0 (_tmp7_);
		_g_regex_unref0 (regex);
		return result;
	}
	goto __finally0;
	__catch0_g_regex_error:
	{
		g_clear_error (&_inner_error0_);
		g_assert_not_reached ();
	}
	__finally0:
	g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
	g_clear_error (&_inner_error0_);
	return NULL;
}

gchar*
b_xml_parser_decode (const gchar* s)
{
	gchar* t = NULL;
	gchar* _tmp0_;
	const gchar* _tmp1_;
	gchar* _tmp2_;
	const gchar* _tmp3_;
	gchar* _tmp4_;
	const gchar* _tmp5_;
	gchar* _tmp6_;
	const gchar* _tmp7_;
	gchar* _tmp8_;
	gchar* result;
	g_return_val_if_fail (s != NULL, NULL);
	_tmp0_ = string_replace (s, "&quot;", "\"");
	_g_free0 (t);
	t = _tmp0_;
	_tmp1_ = t;
	_tmp2_ = string_replace (_tmp1_, "&apos;", "'");
	_g_free0 (t);
	t = _tmp2_;
	_tmp3_ = t;
	_tmp4_ = string_replace (_tmp3_, "&lt;", "<");
	_g_free0 (t);
	t = _tmp4_;
	_tmp5_ = t;
	_tmp6_ = string_replace (_tmp5_, "&gt;", ">");
	_g_free0 (t);
	t = _tmp6_;
	_tmp7_ = t;
	_tmp8_ = string_replace (_tmp7_, "&amp;", "&");
	_g_free0 (t);
	t = _tmp8_;
	result = t;
	return result;
}

/**
 * Replace ", ' < > and & with encoded characters.
 */
gchar*
b_xml_parser_encode (const gchar* s)
{
	gchar* t = NULL;
	gchar* _tmp0_;
	const gchar* _tmp1_;
	gchar* _tmp2_;
	const gchar* _tmp3_;
	gchar* _tmp4_;
	const gchar* _tmp5_;
	gchar* _tmp6_;
	const gchar* _tmp7_;
	gchar* _tmp8_;
	gchar* result;
	g_return_val_if_fail (s != NULL, NULL);
	_tmp0_ = string_replace (s, "&", "&amp;");
	_g_free0 (t);
	t = _tmp0_;
	_tmp1_ = t;
	_tmp2_ = string_replace (_tmp1_, "\"", "&quot;");
	_g_free0 (t);
	t = _tmp2_;
	_tmp3_ = t;
	_tmp4_ = string_replace (_tmp3_, "'", "&apos;");
	_g_free0 (t);
	t = _tmp4_;
	_tmp5_ = t;
	_tmp6_ = string_replace (_tmp5_, "<", "&lt;");
	_g_free0 (t);
	t = _tmp6_;
	_tmp7_ = t;
	_tmp8_ = string_replace (_tmp7_, ">", "&gt;");
	_g_free0 (t);
	t = _tmp8_;
	result = t;
	return result;
}

static void
b_xml_parser_class_init (BXmlParserClass * klass,
                         gpointer klass_data)
{
	b_xml_parser_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &BXmlParser_private_offset);
	G_OBJECT_CLASS (klass)->finalize = b_xml_parser_finalize;
}

static void
b_xml_parser_instance_init (BXmlParser * self,
                            gpointer klass)
{
	self->priv = b_xml_parser_get_instance_private (self);
}

static void
b_xml_parser_finalize (GObject * obj)
{
	BXmlParser * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, B_TYPE_XML_PARSER, BXmlParser);
	_g_object_unref0 (self->priv->root);
	_g_object_unref0 (self->priv->data);
	_g_free0 (self->priv->input);
	G_OBJECT_CLASS (b_xml_parser_parent_class)->finalize (obj);
}

/** 
 * XML parser
 * 
 * XML parser written in Vala.
 * 
 * Example:
 * {{{
 * 
 * using B;
 * 
 * // Print all tags and attributes in an XML document. 
 * // Expected output:
 * // tag1
 * // tag2
 * // attribute1
 * public static int main (string[] arg) {
 * 	Tag root;
 * 	XmlParser parser;
 * 
 * 	parser = new XmlParser ("""<tag1><tag2 attribute1=""/></tag1>""");	
 * 
 * 	if (!parser.validate ()) {
 * 		warning ("Invalid XML.");
 * 		return 1;
 * 	}
 * 
 * 	root = parser.get_root_tag ();
 * 	print_tags (root);
 * 
 * 	return 0;
 * }
 * 
 * 
 * void print_tags (Tag tag) {
 * 	print (tag.get_name ());
 * 	print ("\n");
 * 	print_attributes (tag);
 * 
 * 	foreach (Tag t in tag) {
 * 		print_tags (t);
 * 	}
 * }
 * 
 * void print_attributes (Tag tag) {
 * 	Attributes attributes = tag.get_attributes ();
 * 	foreach (Attribute attribute in attributes) {
 * 		print (attribute.get_name ());
 * 		print ("\n");
 * 	}
 * }
 * 
 * }}}
 * 
 */
static GType
b_xml_parser_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (BXmlParserClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) b_xml_parser_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (BXmlParser), 0, (GInstanceInitFunc) b_xml_parser_instance_init, NULL };
	GType b_xml_parser_type_id;
	b_xml_parser_type_id = g_type_register_static (G_TYPE_OBJECT, "BXmlParser", &g_define_type_info, 0);
	BXmlParser_private_offset = g_type_add_instance_private (b_xml_parser_type_id, sizeof (BXmlParserPrivate));
	return b_xml_parser_type_id;
}

GType
b_xml_parser_get_type (void)
{
	static volatile gsize b_xml_parser_type_id__once = 0;
	if (g_once_init_enter (&b_xml_parser_type_id__once)) {
		GType b_xml_parser_type_id;
		b_xml_parser_type_id = b_xml_parser_get_type_once ();
		g_once_init_leave (&b_xml_parser_type_id__once, b_xml_parser_type_id);
	}
	return b_xml_parser_type_id__once;
}

