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

/*
    Copyright (C) 2015 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-object.h>
#include <glib.h>
#include <string.h>
#include "xmlbird.h"

#define B_XML_DATA_FIRST_BIT ((gchar) (1 << 7))
#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;
typedef struct _BXmlStringPrivate BXmlStringPrivate;

#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;
typedef struct _BXmlDataPrivate BXmlDataPrivate;
enum  {
	B_XML_DATA_0_PROPERTY,
	B_XML_DATA_NUM_PROPERTIES
};
static GParamSpec* b_xml_data_properties[B_XML_DATA_NUM_PROPERTIES];
#define _g_free0(var) ((var == NULL) ? NULL : (var = (g_free (var), NULL)))

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;
};

struct _BXmlDataPrivate {
	gint* start_tags;
	gint tags_capacity;
	gint tags_size;
};

static gint BXmlData_private_offset;
static gpointer b_xml_data_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 BXmlString* b_xml_string_new (gchar* data,
                              gint length);
VALA_EXTERN BXmlString* b_xml_string_construct (GType object_type,
                                    gchar* data,
                                    gint length);
static void b_xml_data_index_start_tags (BXmlData* self);
VALA_EXTERN gint b_xml_data_get_index (BXmlData* self,
                           BXmlString* start);
VALA_EXTERN gint b_xml_data_find_next_tag_token (BXmlData* self,
                                     gint index);
static gint b_xml_data_skip_quote (BXmlData* self,
                            gchar* data,
                            gint i);
VALA_EXTERN void b_xml_parser_warning (const gchar* message);
static void b_xml_data_add_tag (BXmlData* self,
                         gint index);
static gboolean b_xml_data_increase_capacity (BXmlData* self);
static void b_xml_data_finalize (GObject * obj);
static GType b_xml_data_get_type_once (void);

static inline gpointer
b_xml_data_get_instance_private (BXmlData* self)
{
	return G_STRUCT_MEMBER_P (self, BXmlData_private_offset);
}

BXmlData*
b_xml_data_construct (GType object_type,
                      gchar* data,
                      gint length,
                      gint log_level)
{
	BXmlData * self = NULL;
	self = (BXmlData*) b_xml_string_construct (object_type, data, length);
	self->log_level = log_level;
	self->priv->start_tags = NULL;
	self->priv->tags_capacity = 0;
	self->priv->tags_size = 0;
	b_xml_data_index_start_tags (self);
	return self;
}

BXmlData*
b_xml_data_new (gchar* data,
                gint length,
                gint log_level)
{
	return b_xml_data_construct (B_TYPE_XML_DATA, data, length, log_level);
}

gint
b_xml_data_get_index (BXmlData* self,
                      BXmlString* start)
{
	gint offset = 0;
	gchar* _tmp0_;
	gchar* _tmp1_;
	gint result;
	g_return_val_if_fail (self != NULL, -1);
	g_return_val_if_fail (start != NULL, -1);
	_tmp0_ = start->data;
	_tmp1_ = ((BXmlString*) self)->data;
	offset = (gint) (((gsize) _tmp0_) - ((gsize) _tmp1_));
	result = offset;
	return result;
}

gint
b_xml_data_find_next_tag_token (BXmlData* self,
                                gint index)
{
	gint new_index = 0;
	gint lower = 0;
	gint upper = 0;
	gint i = 0;
	gint result;
	g_return_val_if_fail (self != NULL, -1);
	if (index >= ((BXmlString*) self)->length) {
		result = -1;
		return result;
	}
	lower = 0;
	upper = self->priv->tags_size;
	i = lower + ((upper - lower) / 2);
	while (TRUE) {
		gboolean _tmp0_ = FALSE;
		gint* _tmp12_;
		gint _tmp13_;
		if (i == 0) {
			gint* _tmp1_;
			gint _tmp2_;
			_tmp1_ = self->priv->start_tags;
			_tmp2_ = _tmp1_[i];
			_tmp0_ = _tmp2_ >= index;
		} else {
			_tmp0_ = FALSE;
		}
		if (_tmp0_) {
			gint* _tmp3_;
			gint _tmp4_;
			_tmp3_ = self->priv->start_tags;
			_tmp4_ = _tmp3_[i];
			new_index = _tmp4_;
			break;
		} else {
			gboolean _tmp5_ = FALSE;
			gint* _tmp6_;
			gint _tmp7_;
			_tmp6_ = self->priv->start_tags;
			_tmp7_ = _tmp6_[i];
			if (_tmp7_ >= index) {
				gint* _tmp8_;
				gint _tmp9_;
				_tmp8_ = self->priv->start_tags;
				_tmp9_ = _tmp8_[i - 1];
				_tmp5_ = _tmp9_ < index;
			} else {
				_tmp5_ = FALSE;
			}
			if (_tmp5_) {
				gint* _tmp10_;
				gint _tmp11_;
				_tmp10_ = self->priv->start_tags;
				_tmp11_ = _tmp10_[i];
				new_index = _tmp11_;
				break;
			}
		}
		if (lower >= upper) {
			new_index = -1;
			break;
		}
		_tmp12_ = self->priv->start_tags;
		_tmp13_ = _tmp12_[i];
		if (_tmp13_ < index) {
			lower = i + 1;
		} else {
			upper = i - 1;
		}
		i = lower + ((upper - lower) / 2);
	}
	result = new_index;
	return result;
}

static void
b_xml_data_index_start_tags (BXmlData* self)
{
	gint i = 0;
	gchar* d = NULL;
	gchar* _tmp0_;
	gchar c = '\0';
	gboolean tag_is_open = FALSE;
	gchar* _tmp1_;
	gchar _tmp2_;
	g_return_if_fail (self != NULL);
	i = 0;
	_tmp0_ = ((BXmlString*) self)->data;
	d = _tmp0_;
	tag_is_open = FALSE;
	_tmp1_ = d;
	_tmp2_ = _tmp1_[i];
	c = _tmp2_;
	while (TRUE) {
		gint _tmp5_;
		gchar* _tmp6_;
		gchar _tmp7_;
		if (!(c != '\0')) {
			break;
		}
		if (((gint) (c & B_XML_DATA_FIRST_BIT)) == 0) {
			gboolean _tmp3_ = FALSE;
			if (tag_is_open) {
				_tmp3_ = c == '"';
			} else {
				_tmp3_ = FALSE;
			}
			if (_tmp3_) {
				gchar* _tmp4_;
				_tmp4_ = d;
				i = b_xml_data_skip_quote (self, _tmp4_, i);
				if (G_UNLIKELY (i == -1)) {
					if (self->log_level == B_WARNINGS) {
						b_xml_parser_warning ("No end quote.");
					}
					self->error = TRUE;
					break;
				}
			}
			if (c == '<') {
				b_xml_data_add_tag (self, i);
				tag_is_open = TRUE;
			}
			if (c == '>') {
				tag_is_open = FALSE;
			}
		}
		_tmp5_ = i;
		i = _tmp5_ + 1;
		_tmp6_ = d;
		_tmp7_ = _tmp6_[i];
		c = _tmp7_;
	}
}

static gint
b_xml_data_skip_quote (BXmlData* self,
                       gchar* data,
                       gint i)
{
	gchar c = '\0';
	gchar _tmp0_;
	gint result;
	g_return_val_if_fail (self != NULL, -1);
	_tmp0_ = data[i];
	c = _tmp0_;
	if (G_UNLIKELY (c != '"')) {
		if (self->log_level == B_WARNINGS) {
			b_xml_parser_warning ("Not a quote.");
		}
		self->error = TRUE;
		result = i + 1;
		return result;
	}
	while (TRUE) {
		gint _tmp1_;
		gchar _tmp2_;
		if (!(c != '\0')) {
			break;
		}
		if (((gint) (c & B_XML_DATA_FIRST_BIT)) == 0) {
			if (c == '"') {
				result = i + 1;
				return result;
			}
		}
		_tmp1_ = i;
		i = _tmp1_ + 1;
		_tmp2_ = data[i];
		c = _tmp2_;
	}
	result = -1;
	return result;
}

static void
b_xml_data_add_tag (BXmlData* self,
                    gint index)
{
	gint* _tmp0_;
	gint _tmp1_;
	g_return_if_fail (self != NULL);
	if (G_UNLIKELY (self->priv->tags_size == self->priv->tags_capacity)) {
		if (!b_xml_data_increase_capacity (self)) {
			return;
		}
	}
	_tmp0_ = self->priv->start_tags;
	_tmp0_[self->priv->tags_size] = index;
	_tmp1_ = self->priv->tags_size;
	self->priv->tags_size = _tmp1_ + 1;
}

static gboolean
b_xml_data_increase_capacity (BXmlData* self)
{
	gint* tags = NULL;
	void* _tmp0_;
	gint* _tmp1_;
	gint* _tmp6_;
	gint* _tmp8_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	self->priv->tags_capacity = self->priv->tags_capacity + 512;
	_tmp0_ = g_try_malloc ((gsize) (self->priv->tags_capacity * sizeof (gint)));
	tags = (gint*) _tmp0_;
	_tmp1_ = tags;
	if (G_UNLIKELY (_tmp1_ == NULL)) {
		gint* _tmp2_;
		self->priv->tags_capacity = 0;
		_tmp2_ = self->priv->start_tags;
		if (_tmp2_ != NULL) {
			gint* _tmp3_;
			_tmp3_ = self->priv->start_tags;
			_g_free0 (_tmp3_);
			self->priv->start_tags = NULL;
			self->priv->tags_size = 0;
			self->error = TRUE;
		}
		if (self->log_level == B_WARNINGS) {
			b_xml_parser_warning ("Can not allocate xml data buffer.");
		}
		result = FALSE;
		return result;
	}
	if (self->priv->tags_size > 0) {
		gint* _tmp4_;
		gint* _tmp5_;
		_tmp4_ = tags;
		_tmp5_ = self->priv->start_tags;
		memcpy (_tmp4_, _tmp5_, (gsize) (self->priv->tags_size * sizeof (gint)));
	}
	_tmp6_ = self->priv->start_tags;
	if (_tmp6_ != NULL) {
		gint* _tmp7_;
		_tmp7_ = self->priv->start_tags;
		_g_free0 (_tmp7_);
	}
	_tmp8_ = tags;
	self->priv->start_tags = _tmp8_;
	result = TRUE;
	return result;
}

static void
b_xml_data_class_init (BXmlDataClass * klass,
                       gpointer klass_data)
{
	b_xml_data_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &BXmlData_private_offset);
	G_OBJECT_CLASS (klass)->finalize = b_xml_data_finalize;
}

static void
b_xml_data_instance_init (BXmlData * self,
                          gpointer klass)
{
	self->priv = b_xml_data_get_instance_private (self);
	self->error = FALSE;
	self->log_level = B_WARNINGS;
}

static void
b_xml_data_finalize (GObject * obj)
{
	BXmlData * self;
	gint* _tmp0_;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, B_TYPE_XML_DATA, BXmlData);
	_tmp0_ = self->priv->start_tags;
	if (_tmp0_ != NULL) {
		gint* _tmp1_;
		_tmp1_ = self->priv->start_tags;
		_g_free0 (_tmp1_);
		self->priv->start_tags = NULL;
	}
	G_OBJECT_CLASS (b_xml_data_parent_class)->finalize (obj);
}

static GType
b_xml_data_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (BXmlDataClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) b_xml_data_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (BXmlData), 0, (GInstanceInitFunc) b_xml_data_instance_init, NULL };
	GType b_xml_data_type_id;
	b_xml_data_type_id = g_type_register_static (B_TYPE_XML_STRING, "BXmlData", &g_define_type_info, 0);
	BXmlData_private_offset = g_type_add_instance_private (b_xml_data_type_id, sizeof (BXmlDataPrivate));
	return b_xml_data_type_id;
}

GType
b_xml_data_get_type (void)
{
	static volatile gsize b_xml_data_type_id__once = 0;
	if (g_once_init_enter (&b_xml_data_type_id__once)) {
		GType b_xml_data_type_id;
		b_xml_data_type_id = b_xml_data_get_type_once ();
		g_once_init_leave (&b_xml_data_type_id__once, b_xml_data_type_id);
	}
	return b_xml_data_type_id__once;
}

