/* rom-kana.c generated by valac 0.20.0.2-fd7ed, the Vala compiler
 * generated from rom-kana.vala, do not modify */

/* -*- coding: utf-8 -*-*/
/*
 * Copyright (C) 2011-2012 Daiki Ueno <ueno@unixuser.org>
 * Copyright (C) 2011-2012 Red Hat, Inc.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

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


#define SKK_TYPE_ROM_KANA_ENTRY (skk_rom_kana_entry_get_type ())
typedef struct _SkkRomKanaEntry SkkRomKanaEntry;
#define _g_free0(var) (var = (g_free (var), NULL))

#define SKK_TYPE_KANA_MODE (skk_kana_mode_get_type ())

#define SKK_TYPE_ROM_KANA_NODE (skk_rom_kana_node_get_type ())
#define SKK_ROM_KANA_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SKK_TYPE_ROM_KANA_NODE, SkkRomKanaNode))
#define SKK_ROM_KANA_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SKK_TYPE_ROM_KANA_NODE, SkkRomKanaNodeClass))
#define SKK_IS_ROM_KANA_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SKK_TYPE_ROM_KANA_NODE))
#define SKK_IS_ROM_KANA_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SKK_TYPE_ROM_KANA_NODE))
#define SKK_ROM_KANA_NODE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SKK_TYPE_ROM_KANA_NODE, SkkRomKanaNodeClass))

typedef struct _SkkRomKanaNode SkkRomKanaNode;
typedef struct _SkkRomKanaNodeClass SkkRomKanaNodeClass;
typedef struct _SkkRomKanaNodePrivate SkkRomKanaNodePrivate;
#define _skk_rom_kana_entry_free0(var) ((var == NULL) ? NULL : (var = (skk_rom_kana_entry_free (var), NULL)))
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))

#define SKK_TYPE_PERIOD_STYLE (skk_period_style_get_type ())

#define SKK_TYPE_ROM_KANA_CONVERTER (skk_rom_kana_converter_get_type ())
#define SKK_ROM_KANA_CONVERTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SKK_TYPE_ROM_KANA_CONVERTER, SkkRomKanaConverter))
#define SKK_ROM_KANA_CONVERTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SKK_TYPE_ROM_KANA_CONVERTER, SkkRomKanaConverterClass))
#define SKK_IS_ROM_KANA_CONVERTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SKK_TYPE_ROM_KANA_CONVERTER))
#define SKK_IS_ROM_KANA_CONVERTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SKK_TYPE_ROM_KANA_CONVERTER))
#define SKK_ROM_KANA_CONVERTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SKK_TYPE_ROM_KANA_CONVERTER, SkkRomKanaConverterClass))

typedef struct _SkkRomKanaConverter SkkRomKanaConverter;
typedef struct _SkkRomKanaConverterClass SkkRomKanaConverterClass;
typedef struct _SkkRomKanaConverterPrivate SkkRomKanaConverterPrivate;

#define SKK_TYPE_MAP_FILE (skk_map_file_get_type ())
#define SKK_MAP_FILE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SKK_TYPE_MAP_FILE, SkkMapFile))
#define SKK_MAP_FILE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SKK_TYPE_MAP_FILE, SkkMapFileClass))
#define SKK_IS_MAP_FILE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SKK_TYPE_MAP_FILE))
#define SKK_IS_MAP_FILE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SKK_TYPE_MAP_FILE))
#define SKK_MAP_FILE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SKK_TYPE_MAP_FILE, SkkMapFileClass))

typedef struct _SkkMapFile SkkMapFile;
typedef struct _SkkMapFileClass SkkMapFileClass;

#define SKK_TYPE_ROM_KANA_MAP_FILE (skk_rom_kana_map_file_get_type ())
#define SKK_ROM_KANA_MAP_FILE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SKK_TYPE_ROM_KANA_MAP_FILE, SkkRomKanaMapFile))
#define SKK_ROM_KANA_MAP_FILE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SKK_TYPE_ROM_KANA_MAP_FILE, SkkRomKanaMapFileClass))
#define SKK_IS_ROM_KANA_MAP_FILE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SKK_TYPE_ROM_KANA_MAP_FILE))
#define SKK_IS_ROM_KANA_MAP_FILE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SKK_TYPE_ROM_KANA_MAP_FILE))
#define SKK_ROM_KANA_MAP_FILE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SKK_TYPE_ROM_KANA_MAP_FILE, SkkRomKanaMapFileClass))

typedef struct _SkkRomKanaMapFile SkkRomKanaMapFile;
typedef struct _SkkRomKanaMapFileClass SkkRomKanaMapFileClass;
#define _g_string_free0(var) ((var == NULL) ? NULL : (var = (g_string_free (var, TRUE), NULL)))

#define SKK_TYPE_RULE_METADATA (skk_rule_metadata_get_type ())
typedef struct _SkkRuleMetadata SkkRuleMetadata;
#define _skk_rule_metadata_free0(var) ((var == NULL) ? NULL : (var = (skk_rule_metadata_free (var), NULL)))
typedef struct _SkkMapFilePrivate SkkMapFilePrivate;
typedef struct _SkkRomKanaMapFilePrivate SkkRomKanaMapFilePrivate;
#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))

struct _SkkRomKanaEntry {
	gchar* rom;
	gchar* carryover;
	gchar* hiragana;
	gchar* katakana;
	gchar* hankaku_katakana;
};

typedef enum  {
	SKK_KANA_MODE_HIRAGANA,
	SKK_KANA_MODE_KATAKANA,
	SKK_KANA_MODE_HANKAKU_KATAKANA
} SkkKanaMode;

struct _SkkRomKanaNode {
	GObject parent_instance;
	SkkRomKanaNodePrivate * priv;
	SkkRomKanaEntry* entry;
	SkkRomKanaNode* parent;
	SkkRomKanaNode* children[128];
	gchar c;
	guint n_children;
	gboolean valid[128];
};

struct _SkkRomKanaNodeClass {
	GObjectClass parent_class;
};

typedef enum  {
	SKK_PERIOD_STYLE_JA_JA,
	SKK_PERIOD_STYLE_EN_EN,
	SKK_PERIOD_STYLE_JA_EN,
	SKK_PERIOD_STYLE_EN_JA
} SkkPeriodStyle;

struct _SkkRomKanaConverter {
	GObject parent_instance;
	SkkRomKanaConverterPrivate * priv;
};

struct _SkkRomKanaConverterClass {
	GObjectClass parent_class;
};

struct _SkkRomKanaConverterPrivate {
	SkkRomKanaMapFile* _rule;
	SkkRomKanaNode* current_node;
	SkkKanaMode _kana_mode;
	SkkPeriodStyle _period_style;
	GString* _output;
	GString* _preedit;
};

struct _SkkRuleMetadata {
	gchar* base_dir;
	gchar* name;
	gchar* label;
	gchar* description;
	gchar* filter;
};

typedef enum  {
	SKK_RULE_PARSE_ERROR_FAILED
} SkkRuleParseError;
#define SKK_RULE_PARSE_ERROR skk_rule_parse_error_quark ()
struct _SkkMapFile {
	GObject parent_instance;
	SkkMapFilePrivate * priv;
};

struct _SkkMapFileClass {
	GObjectClass parent_class;
};

struct _SkkRomKanaMapFile {
	SkkMapFile parent_instance;
	SkkRomKanaMapFilePrivate * priv;
	SkkRomKanaNode* root_node;
};

struct _SkkRomKanaMapFileClass {
	SkkMapFileClass parent_class;
};


static gpointer skk_rom_kana_node_parent_class = NULL;
static gpointer skk_rom_kana_converter_parent_class = NULL;

GType skk_rom_kana_entry_get_type (void) G_GNUC_CONST;
SkkRomKanaEntry* skk_rom_kana_entry_dup (const SkkRomKanaEntry* self);
void skk_rom_kana_entry_free (SkkRomKanaEntry* self);
void skk_rom_kana_entry_copy (const SkkRomKanaEntry* self, SkkRomKanaEntry* dest);
void skk_rom_kana_entry_destroy (SkkRomKanaEntry* self);
GType skk_kana_mode_get_type (void) G_GNUC_CONST;
gchar* skk_rom_kana_entry_get_kana (SkkRomKanaEntry *self, SkkKanaMode kana_mode);
GType skk_rom_kana_node_get_type (void) G_GNUC_CONST;
enum  {
	SKK_ROM_KANA_NODE_DUMMY_PROPERTY
};
SkkRomKanaNode* skk_rom_kana_node_new (SkkRomKanaEntry* entry);
SkkRomKanaNode* skk_rom_kana_node_construct (GType object_type, SkkRomKanaEntry* entry);
void skk_rom_kana_node_insert (SkkRomKanaNode* self, const gchar* key, SkkRomKanaEntry* entry);
static void skk_rom_kana_node_finalize (GObject* obj);
GType skk_period_style_get_type (void) G_GNUC_CONST;
GType skk_rom_kana_converter_get_type (void) G_GNUC_CONST;
GType skk_map_file_get_type (void) G_GNUC_CONST;
GType skk_rom_kana_map_file_get_type (void) G_GNUC_CONST;
#define SKK_ROM_KANA_CONVERTER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SKK_TYPE_ROM_KANA_CONVERTER, SkkRomKanaConverterPrivate))
enum  {
	SKK_ROM_KANA_CONVERTER_DUMMY_PROPERTY,
	SKK_ROM_KANA_CONVERTER_RULE,
	SKK_ROM_KANA_CONVERTER_KANA_MODE,
	SKK_ROM_KANA_CONVERTER_PERIOD_STYLE,
	SKK_ROM_KANA_CONVERTER_OUTPUT,
	SKK_ROM_KANA_CONVERTER_PREEDIT
};
SkkRomKanaConverter* skk_rom_kana_converter_new (void);
SkkRomKanaConverter* skk_rom_kana_converter_construct (GType object_type);
GType skk_rule_metadata_get_type (void) G_GNUC_CONST;
SkkRuleMetadata* skk_rule_metadata_dup (const SkkRuleMetadata* self);
void skk_rule_metadata_free (SkkRuleMetadata* self);
void skk_rule_metadata_copy (const SkkRuleMetadata* self, SkkRuleMetadata* dest);
void skk_rule_metadata_destroy (SkkRuleMetadata* self);
SkkRuleMetadata* skk_rule_find_rule (const gchar* name);
GQuark skk_rule_parse_error_quark (void);
SkkRomKanaMapFile* skk_rom_kana_map_file_new (SkkRuleMetadata* metadata, GError** error);
SkkRomKanaMapFile* skk_rom_kana_map_file_construct (GType object_type, SkkRuleMetadata* metadata, GError** error);
gboolean skk_rom_kana_converter_is_valid (SkkRomKanaConverter* self, gunichar uc);
gboolean skk_rom_kana_converter_output_nn_if_any (SkkRomKanaConverter* self);
SkkKanaMode skk_rom_kana_converter_get_kana_mode (SkkRomKanaConverter* self);
SkkRomKanaMapFile* skk_rom_kana_converter_get_rule (SkkRomKanaConverter* self);
void skk_rom_kana_converter_append_text (SkkRomKanaConverter* self, const gchar* text);
gboolean skk_rom_kana_converter_append (SkkRomKanaConverter* self, gunichar uc);
SkkPeriodStyle skk_rom_kana_converter_get_period_style (SkkRomKanaConverter* self);
gboolean skk_rom_kana_converter_can_consume (SkkRomKanaConverter* self, gunichar uc, gboolean preedit_only, gboolean no_carryover);
void skk_rom_kana_converter_reset (SkkRomKanaConverter* self);
gboolean skk_rom_kana_converter_delete (SkkRomKanaConverter* self);
void skk_rom_kana_converter_set_rule (SkkRomKanaConverter* self, SkkRomKanaMapFile* value);
void skk_rom_kana_converter_set_kana_mode (SkkRomKanaConverter* self, SkkKanaMode value);
void skk_rom_kana_converter_set_period_style (SkkRomKanaConverter* self, SkkPeriodStyle value);
const gchar* skk_rom_kana_converter_get_output (SkkRomKanaConverter* self);
void skk_rom_kana_converter_set_output (SkkRomKanaConverter* self, const gchar* value);
const gchar* skk_rom_kana_converter_get_preedit (SkkRomKanaConverter* self);
static void skk_rom_kana_converter_finalize (GObject* obj);
static void _vala_skk_rom_kana_converter_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec);
static void _vala_skk_rom_kana_converter_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec);
static void _vala_array_destroy (gpointer array, gint array_length, GDestroyNotify destroy_func);
static void _vala_array_free (gpointer array, gint array_length, GDestroyNotify destroy_func);

const gchar* SKK_PERIOD_RULE[4] = {"。、", "．，", "。，", "．、"};
static const gchar* SKK_ROM_KANA_CONVERTER_NN[3] = {"ん", "ン", "ﾝ"};

gchar* skk_rom_kana_entry_get_kana (SkkRomKanaEntry *self, SkkKanaMode kana_mode) {
	gchar* result = NULL;
	SkkKanaMode _tmp0_;
	gchar* _tmp9_;
	_tmp0_ = kana_mode;
	if (_tmp0_ == SKK_KANA_MODE_HIRAGANA) {
		const gchar* _tmp1_;
		gchar* _tmp2_;
		_tmp1_ = (*self).hiragana;
		_tmp2_ = g_strdup (_tmp1_);
		result = _tmp2_;
		return result;
	} else {
		SkkKanaMode _tmp3_;
		_tmp3_ = kana_mode;
		if (_tmp3_ == SKK_KANA_MODE_KATAKANA) {
			const gchar* _tmp4_;
			gchar* _tmp5_;
			_tmp4_ = (*self).katakana;
			_tmp5_ = g_strdup (_tmp4_);
			result = _tmp5_;
			return result;
		} else {
			SkkKanaMode _tmp6_;
			_tmp6_ = kana_mode;
			if (_tmp6_ == SKK_KANA_MODE_HANKAKU_KATAKANA) {
				const gchar* _tmp7_;
				gchar* _tmp8_;
				_tmp7_ = (*self).hankaku_katakana;
				_tmp8_ = g_strdup (_tmp7_);
				result = _tmp8_;
				return result;
			}
		}
	}
	_tmp9_ = g_strdup ("");
	result = _tmp9_;
	return result;
}


void skk_rom_kana_entry_copy (const SkkRomKanaEntry* self, SkkRomKanaEntry* dest) {
	const gchar* _tmp0_;
	gchar* _tmp1_;
	const gchar* _tmp2_;
	gchar* _tmp3_;
	const gchar* _tmp4_;
	gchar* _tmp5_;
	const gchar* _tmp6_;
	gchar* _tmp7_;
	const gchar* _tmp8_;
	gchar* _tmp9_;
	_tmp0_ = (*self).rom;
	_tmp1_ = g_strdup (_tmp0_);
	_g_free0 ((*dest).rom);
	(*dest).rom = _tmp1_;
	_tmp2_ = (*self).carryover;
	_tmp3_ = g_strdup (_tmp2_);
	_g_free0 ((*dest).carryover);
	(*dest).carryover = _tmp3_;
	_tmp4_ = (*self).hiragana;
	_tmp5_ = g_strdup (_tmp4_);
	_g_free0 ((*dest).hiragana);
	(*dest).hiragana = _tmp5_;
	_tmp6_ = (*self).katakana;
	_tmp7_ = g_strdup (_tmp6_);
	_g_free0 ((*dest).katakana);
	(*dest).katakana = _tmp7_;
	_tmp8_ = (*self).hankaku_katakana;
	_tmp9_ = g_strdup (_tmp8_);
	_g_free0 ((*dest).hankaku_katakana);
	(*dest).hankaku_katakana = _tmp9_;
}


void skk_rom_kana_entry_destroy (SkkRomKanaEntry* self) {
	_g_free0 ((*self).rom);
	_g_free0 ((*self).carryover);
	_g_free0 ((*self).hiragana);
	_g_free0 ((*self).katakana);
	_g_free0 ((*self).hankaku_katakana);
}


SkkRomKanaEntry* skk_rom_kana_entry_dup (const SkkRomKanaEntry* self) {
	SkkRomKanaEntry* dup;
	dup = g_new0 (SkkRomKanaEntry, 1);
	skk_rom_kana_entry_copy (self, dup);
	return dup;
}


void skk_rom_kana_entry_free (SkkRomKanaEntry* self) {
	skk_rom_kana_entry_destroy (self);
	g_free (self);
}


GType skk_rom_kana_entry_get_type (void) {
	static volatile gsize skk_rom_kana_entry_type_id__volatile = 0;
	if (g_once_init_enter (&skk_rom_kana_entry_type_id__volatile)) {
		GType skk_rom_kana_entry_type_id;
		skk_rom_kana_entry_type_id = g_boxed_type_register_static ("SkkRomKanaEntry", (GBoxedCopyFunc) skk_rom_kana_entry_dup, (GBoxedFreeFunc) skk_rom_kana_entry_free);
		g_once_init_leave (&skk_rom_kana_entry_type_id__volatile, skk_rom_kana_entry_type_id);
	}
	return skk_rom_kana_entry_type_id__volatile;
}


static gpointer _skk_rom_kana_entry_dup0 (gpointer self) {
	return self ? skk_rom_kana_entry_dup (self) : NULL;
}


SkkRomKanaNode* skk_rom_kana_node_construct (GType object_type, SkkRomKanaEntry* entry) {
	SkkRomKanaNode * self = NULL;
	SkkRomKanaEntry* _tmp0_;
	SkkRomKanaEntry* _tmp1_;
	self = (SkkRomKanaNode*) g_object_new (object_type, NULL);
	_tmp0_ = entry;
	_tmp1_ = _skk_rom_kana_entry_dup0 (_tmp0_);
	_skk_rom_kana_entry_free0 (self->entry);
	self->entry = _tmp1_;
	{
		gint i;
		i = 0;
		{
			gboolean _tmp2_;
			_tmp2_ = TRUE;
			while (TRUE) {
				gboolean _tmp3_;
				gint _tmp5_;
				gint _tmp6_;
				SkkRomKanaNode* _tmp7_;
				_tmp3_ = _tmp2_;
				if (!_tmp3_) {
					gint _tmp4_;
					_tmp4_ = i;
					i = _tmp4_ + 1;
				}
				_tmp2_ = FALSE;
				_tmp5_ = i;
				if (!(_tmp5_ < 128)) {
					break;
				}
				_tmp6_ = i;
				_g_object_unref0 (self->children[_tmp6_]);
				self->children[_tmp6_] = NULL;
				_tmp7_ = self->children[_tmp6_];
			}
		}
	}
	return self;
}


SkkRomKanaNode* skk_rom_kana_node_new (SkkRomKanaEntry* entry) {
	return skk_rom_kana_node_construct (SKK_TYPE_ROM_KANA_NODE, entry);
}


static gpointer _g_object_ref0 (gpointer self) {
	return self ? g_object_ref (self) : NULL;
}


static gchar string_get (const gchar* self, glong index) {
	gchar result = '\0';
	glong _tmp0_;
	gchar _tmp1_;
	g_return_val_if_fail (self != NULL, '\0');
	_tmp0_ = index;
	_tmp1_ = ((gchar*) self)[_tmp0_];
	result = _tmp1_;
	return result;
}


void skk_rom_kana_node_insert (SkkRomKanaNode* self, const gchar* key, SkkRomKanaEntry* entry) {
	SkkRomKanaNode* _tmp0_;
	SkkRomKanaNode* node;
	SkkRomKanaNode* _tmp34_;
	SkkRomKanaEntry _tmp35_;
	SkkRomKanaEntry _tmp36_;
	SkkRomKanaEntry* _tmp37_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (key != NULL);
	g_return_if_fail (entry != NULL);
	_tmp0_ = _g_object_ref0 (self);
	node = _tmp0_;
	{
		gint i;
		i = 0;
		{
			gboolean _tmp1_;
			_tmp1_ = TRUE;
			while (TRUE) {
				gboolean _tmp2_;
				gint _tmp4_;
				const gchar* _tmp5_;
				gint _tmp6_;
				gint _tmp7_;
				SkkRomKanaNode* _tmp8_;
				const gchar* _tmp9_;
				gint _tmp10_;
				gchar _tmp11_ = '\0';
				SkkRomKanaNode* _tmp12_;
				SkkRomKanaNode* _tmp22_;
				guint _tmp23_;
				SkkRomKanaNode* _tmp24_;
				const gchar* _tmp25_;
				gint _tmp26_;
				gchar _tmp27_ = '\0';
				SkkRomKanaNode* _tmp28_;
				SkkRomKanaNode* _tmp29_;
				const gchar* _tmp30_;
				gint _tmp31_;
				gchar _tmp32_ = '\0';
				gboolean _tmp33_;
				_tmp2_ = _tmp1_;
				if (!_tmp2_) {
					gint _tmp3_;
					_tmp3_ = i;
					i = _tmp3_ + 1;
				}
				_tmp1_ = FALSE;
				_tmp4_ = i;
				_tmp5_ = key;
				_tmp6_ = strlen (_tmp5_);
				_tmp7_ = _tmp6_;
				if (!(_tmp4_ < _tmp7_)) {
					break;
				}
				_tmp8_ = node;
				_tmp9_ = key;
				_tmp10_ = i;
				_tmp11_ = string_get (_tmp9_, (glong) _tmp10_);
				_tmp12_ = _tmp8_->children[_tmp11_];
				if (_tmp12_ == NULL) {
					SkkRomKanaNode* _tmp13_;
					const gchar* _tmp14_;
					gint _tmp15_;
					gchar _tmp16_ = '\0';
					SkkRomKanaNode* _tmp17_;
					SkkRomKanaNode* _tmp18_;
					SkkRomKanaNode* _tmp19_;
					SkkRomKanaNode* child;
					SkkRomKanaNode* _tmp20_;
					SkkRomKanaNode* _tmp21_;
					_tmp13_ = node;
					_tmp14_ = key;
					_tmp15_ = i;
					_tmp16_ = string_get (_tmp14_, (glong) _tmp15_);
					_tmp17_ = skk_rom_kana_node_new (NULL);
					_g_object_unref0 (_tmp13_->children[_tmp16_]);
					_tmp13_->children[_tmp16_] = _tmp17_;
					_tmp18_ = _tmp13_->children[_tmp16_];
					_tmp19_ = _g_object_ref0 (_tmp18_);
					child = _tmp19_;
					_tmp20_ = child;
					_tmp21_ = node;
					_tmp20_->parent = _tmp21_;
					_g_object_unref0 (child);
				}
				_tmp22_ = node;
				_tmp23_ = _tmp22_->n_children;
				_tmp22_->n_children = _tmp23_ + 1;
				_tmp24_ = node;
				_tmp25_ = key;
				_tmp26_ = i;
				_tmp27_ = string_get (_tmp25_, (glong) _tmp26_);
				_tmp28_ = _tmp24_->children[_tmp27_];
				_tmp29_ = _g_object_ref0 (_tmp28_);
				_g_object_unref0 (node);
				node = _tmp29_;
				_tmp30_ = key;
				_tmp31_ = i;
				_tmp32_ = string_get (_tmp30_, (glong) _tmp31_);
				self->valid[_tmp32_] = TRUE;
				_tmp33_ = self->valid[_tmp32_];
			}
		}
	}
	_tmp34_ = node;
	_tmp35_ = *entry;
	_tmp36_ = _tmp35_;
	_tmp37_ = _skk_rom_kana_entry_dup0 (&_tmp36_);
	_skk_rom_kana_entry_free0 (_tmp34_->entry);
	_tmp34_->entry = _tmp37_;
	_g_object_unref0 (node);
}


static void skk_rom_kana_node_class_init (SkkRomKanaNodeClass * klass) {
	skk_rom_kana_node_parent_class = g_type_class_peek_parent (klass);
	G_OBJECT_CLASS (klass)->finalize = skk_rom_kana_node_finalize;
}


static void skk_rom_kana_node_instance_init (SkkRomKanaNode * self) {
	self->n_children = (guint) 0;
}


static void skk_rom_kana_node_finalize (GObject* obj) {
	SkkRomKanaNode * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, SKK_TYPE_ROM_KANA_NODE, SkkRomKanaNode);
	_skk_rom_kana_entry_free0 (self->entry);
	_vala_array_destroy (self->children, 128, (GDestroyNotify) g_object_unref);
	G_OBJECT_CLASS (skk_rom_kana_node_parent_class)->finalize (obj);
}


GType skk_rom_kana_node_get_type (void) {
	static volatile gsize skk_rom_kana_node_type_id__volatile = 0;
	if (g_once_init_enter (&skk_rom_kana_node_type_id__volatile)) {
		static const GTypeInfo g_define_type_info = { sizeof (SkkRomKanaNodeClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) skk_rom_kana_node_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (SkkRomKanaNode), 0, (GInstanceInitFunc) skk_rom_kana_node_instance_init, NULL };
		GType skk_rom_kana_node_type_id;
		skk_rom_kana_node_type_id = g_type_register_static (G_TYPE_OBJECT, "SkkRomKanaNode", &g_define_type_info, 0);
		g_once_init_leave (&skk_rom_kana_node_type_id__volatile, skk_rom_kana_node_type_id);
	}
	return skk_rom_kana_node_type_id__volatile;
}


/**
     * Type representing kana scripts.
     */
GType skk_kana_mode_get_type (void) {
	static volatile gsize skk_kana_mode_type_id__volatile = 0;
	if (g_once_init_enter (&skk_kana_mode_type_id__volatile)) {
		static const GEnumValue values[] = {{SKK_KANA_MODE_HIRAGANA, "SKK_KANA_MODE_HIRAGANA", "hiragana"}, {SKK_KANA_MODE_KATAKANA, "SKK_KANA_MODE_KATAKANA", "katakana"}, {SKK_KANA_MODE_HANKAKU_KATAKANA, "SKK_KANA_MODE_HANKAKU_KATAKANA", "hankaku-katakana"}, {0, NULL, NULL}};
		GType skk_kana_mode_type_id;
		skk_kana_mode_type_id = g_enum_register_static ("SkkKanaMode", values);
		g_once_init_leave (&skk_kana_mode_type_id__volatile, skk_kana_mode_type_id);
	}
	return skk_kana_mode_type_id__volatile;
}


/**
     * Type to specify how "." and "," are converted.
     */
GType skk_period_style_get_type (void) {
	static volatile gsize skk_period_style_type_id__volatile = 0;
	if (g_once_init_enter (&skk_period_style_type_id__volatile)) {
		static const GEnumValue values[] = {{SKK_PERIOD_STYLE_JA_JA, "SKK_PERIOD_STYLE_JA_JA", "ja-ja"}, {SKK_PERIOD_STYLE_EN_EN, "SKK_PERIOD_STYLE_EN_EN", "en-en"}, {SKK_PERIOD_STYLE_JA_EN, "SKK_PERIOD_STYLE_JA_EN", "ja-en"}, {SKK_PERIOD_STYLE_EN_JA, "SKK_PERIOD_STYLE_EN_JA", "en-ja"}, {0, NULL, NULL}};
		GType skk_period_style_type_id;
		skk_period_style_type_id = g_enum_register_static ("SkkPeriodStyle", values);
		g_once_init_leave (&skk_period_style_type_id__volatile, skk_period_style_type_id);
	}
	return skk_period_style_type_id__volatile;
}


SkkRomKanaConverter* skk_rom_kana_converter_construct (GType object_type) {
	SkkRomKanaConverter * self = NULL;
	GError * _inner_error_ = NULL;
	self = (SkkRomKanaConverter*) g_object_new (object_type, NULL);
	{
		SkkRuleMetadata* _tmp0_ = NULL;
		SkkRuleMetadata* _tmp1_;
		SkkRuleMetadata _tmp2_;
		SkkRomKanaMapFile* _tmp3_;
		SkkRomKanaMapFile* _tmp4_;
		SkkRomKanaMapFile* _tmp5_;
		SkkRomKanaMapFile* _tmp6_;
		SkkRomKanaNode* _tmp7_;
		SkkRomKanaNode* _tmp8_;
		_tmp0_ = skk_rule_find_rule ("default");
		_tmp1_ = _tmp0_;
		_tmp2_ = *_tmp1_;
		_tmp3_ = skk_rom_kana_map_file_new (&_tmp2_, &_inner_error_);
		_tmp4_ = _tmp3_;
		_skk_rule_metadata_free0 (_tmp1_);
		_tmp5_ = _tmp4_;
		if (_inner_error_ != NULL) {
			if (_inner_error_->domain == SKK_RULE_PARSE_ERROR) {
				goto __catch0_skk_rule_parse_error;
			}
			g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
			g_clear_error (&_inner_error_);
			return NULL;
		}
		_g_object_unref0 (self->priv->_rule);
		self->priv->_rule = _tmp5_;
		_tmp6_ = self->priv->_rule;
		_tmp7_ = _tmp6_->root_node;
		_tmp8_ = _g_object_ref0 (_tmp7_);
		_g_object_unref0 (self->priv->current_node);
		self->priv->current_node = _tmp8_;
	}
	goto __finally0;
	__catch0_skk_rule_parse_error:
	{
		GError* e = NULL;
		const gchar* _tmp9_;
		e = _inner_error_;
		_inner_error_ = NULL;
		_tmp9_ = e->message;
		g_warning ("rom-kana.vala:198: can't find default rom-kana rule: %s", _tmp9_);
		g_assert_not_reached ();
		_g_error_free0 (e);
	}
	__finally0:
	if (_inner_error_ != NULL) {
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
		g_clear_error (&_inner_error_);
		return NULL;
	}
	return self;
}


SkkRomKanaConverter* skk_rom_kana_converter_new (void) {
	return skk_rom_kana_converter_construct (SKK_TYPE_ROM_KANA_CONVERTER);
}


gboolean skk_rom_kana_converter_is_valid (SkkRomKanaConverter* self, gunichar uc) {
	gboolean result = FALSE;
	gunichar _tmp0_;
	SkkRomKanaMapFile* _tmp1_;
	SkkRomKanaNode* _tmp2_;
	gunichar _tmp3_;
	gboolean _tmp4_;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = uc;
	if (_tmp0_ > ((gunichar) 128)) {
		result = FALSE;
		return result;
	}
	_tmp1_ = self->priv->_rule;
	_tmp2_ = _tmp1_->root_node;
	_tmp3_ = uc;
	_tmp4_ = _tmp2_->valid[(gint) _tmp3_];
	result = _tmp4_;
	return result;
}


/**
         * Output "nn" if preedit ends with "n".
         */
gboolean skk_rom_kana_converter_output_nn_if_any (SkkRomKanaConverter* self) {
	gboolean result = FALSE;
	GString* _tmp0_;
	const gchar* _tmp1_;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = self->priv->_preedit;
	_tmp1_ = _tmp0_->str;
	if (g_strcmp0 (_tmp1_, "n") == 0) {
		GString* _tmp2_;
		SkkKanaMode _tmp3_;
		const gchar* _tmp4_;
		GString* _tmp5_;
		SkkRomKanaMapFile* _tmp6_;
		SkkRomKanaMapFile* _tmp7_;
		SkkRomKanaNode* _tmp8_;
		SkkRomKanaNode* _tmp9_;
		_tmp2_ = self->priv->_output;
		_tmp3_ = self->priv->_kana_mode;
		_tmp4_ = SKK_ROM_KANA_CONVERTER_NN[_tmp3_];
		g_string_append (_tmp2_, _tmp4_);
		_tmp5_ = self->priv->_preedit;
		g_string_erase (_tmp5_, (gssize) 0, (gssize) (-1));
		_tmp6_ = skk_rom_kana_converter_get_rule (self);
		_tmp7_ = _tmp6_;
		_tmp8_ = _tmp7_->root_node;
		_tmp9_ = _g_object_ref0 (_tmp8_);
		_g_object_unref0 (self->priv->current_node);
		self->priv->current_node = _tmp9_;
		result = TRUE;
		return result;
	}
	result = FALSE;
	return result;
}


/**
         * Append text to the internal buffer.
         *
         * @param text a string
         */
static gboolean string_get_next_char (const gchar* self, gint* index, gunichar* c) {
	gunichar _vala_c = 0U;
	gboolean result = FALSE;
	gint _tmp0_;
	gunichar _tmp1_ = 0U;
	gunichar _tmp2_;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = *index;
	_tmp1_ = g_utf8_get_char (((gchar*) self) + _tmp0_);
	_vala_c = _tmp1_;
	_tmp2_ = _vala_c;
	if (_tmp2_ != ((gunichar) 0)) {
		gint _tmp3_;
		gchar* _tmp4_ = NULL;
		_tmp3_ = *index;
		_tmp4_ = g_utf8_next_char (((gchar*) self) + _tmp3_);
		*index = (gint) (_tmp4_ - ((gchar*) self));
		result = TRUE;
		if (c) {
			*c = _vala_c;
		}
		return result;
	} else {
		result = FALSE;
		if (c) {
			*c = _vala_c;
		}
		return result;
	}
	if (c) {
		*c = _vala_c;
	}
}


void skk_rom_kana_converter_append_text (SkkRomKanaConverter* self, const gchar* text) {
	gint index;
	gunichar c = 0U;
	g_return_if_fail (self != NULL);
	g_return_if_fail (text != NULL);
	index = 0;
	while (TRUE) {
		const gchar* _tmp0_;
		gunichar _tmp1_ = 0U;
		gboolean _tmp2_ = FALSE;
		gunichar _tmp3_;
		_tmp0_ = text;
		_tmp2_ = string_get_next_char (_tmp0_, &index, &_tmp1_);
		c = _tmp1_;
		if (!_tmp2_) {
			break;
		}
		_tmp3_ = c;
		skk_rom_kana_converter_append (self, _tmp3_);
	}
}


/**
         * Append a character to the internal buffer.
         *
         * @param uc an ASCII character
         *
         * @return `true` if the character is handled, `false` otherwise
         */
static gint string_index_of_char (const gchar* self, gunichar c, gint start_index) {
	gint result = 0;
	gint _tmp0_;
	gunichar _tmp1_;
	gchar* _tmp2_ = NULL;
	gchar* _result_;
	gchar* _tmp3_;
	g_return_val_if_fail (self != NULL, 0);
	_tmp0_ = start_index;
	_tmp1_ = c;
	_tmp2_ = g_utf8_strchr (((gchar*) self) + _tmp0_, (gssize) (-1), _tmp1_);
	_result_ = _tmp2_;
	_tmp3_ = _result_;
	if (_tmp3_ != NULL) {
		gchar* _tmp4_;
		_tmp4_ = _result_;
		result = (gint) (_tmp4_ - ((gchar*) self));
		return result;
	} else {
		result = -1;
		return result;
	}
}


static gint string_index_of_nth_char (const gchar* self, glong c) {
	gint result = 0;
	glong _tmp0_;
	gchar* _tmp1_ = NULL;
	g_return_val_if_fail (self != NULL, 0);
	_tmp0_ = c;
	_tmp1_ = g_utf8_offset_to_pointer (self, _tmp0_);
	result = (gint) (_tmp1_ - ((gchar*) self));
	return result;
}


static gunichar string_get_char (const gchar* self, glong index) {
	gunichar result = 0U;
	glong _tmp0_;
	gunichar _tmp1_ = 0U;
	g_return_val_if_fail (self != NULL, 0U);
	_tmp0_ = index;
	_tmp1_ = g_utf8_get_char (((gchar*) self) + _tmp0_);
	result = _tmp1_;
	return result;
}


gboolean skk_rom_kana_converter_append (SkkRomKanaConverter* self, gunichar uc) {
	gboolean result = FALSE;
	SkkRomKanaNode* _tmp0_;
	gunichar _tmp1_;
	SkkRomKanaNode* _tmp2_;
	SkkRomKanaNode* _tmp3_;
	SkkRomKanaNode* child_node;
	SkkRomKanaNode* _tmp4_;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = self->priv->current_node;
	_tmp1_ = uc;
	_tmp2_ = _tmp0_->children[_tmp1_];
	_tmp3_ = _g_object_ref0 (_tmp2_);
	child_node = _tmp3_;
	_tmp4_ = child_node;
	if (_tmp4_ == NULL) {
		gboolean _tmp5_ = FALSE;
		gboolean retval;
		gint _tmp6_ = 0;
		gunichar _tmp7_;
		gint _tmp10_;
		gint index;
		gint _tmp11_;
		_tmp5_ = skk_rom_kana_converter_output_nn_if_any (self);
		retval = _tmp5_;
		_tmp7_ = uc;
		if (_tmp7_ != ((gunichar) '\0')) {
			gunichar _tmp8_;
			gint _tmp9_ = 0;
			_tmp8_ = uc;
			_tmp9_ = string_index_of_char (".,", _tmp8_, 0);
			_tmp6_ = _tmp9_;
		} else {
			_tmp6_ = -1;
		}
		_tmp10_ = _tmp6_;
		index = _tmp10_;
		_tmp11_ = index;
		if (_tmp11_ >= 0) {
			SkkPeriodStyle _tmp12_;
			const gchar* _tmp13_;
			gint _tmp14_;
			gint _tmp15_ = 0;
			SkkPeriodStyle _tmp16_;
			const gchar* _tmp17_;
			gint _tmp18_;
			gunichar _tmp19_ = 0U;
			gunichar period;
			GString* _tmp20_;
			gunichar _tmp21_;
			GString* _tmp22_;
			SkkRomKanaMapFile* _tmp23_;
			SkkRomKanaMapFile* _tmp24_;
			SkkRomKanaNode* _tmp25_;
			SkkRomKanaNode* _tmp26_;
			_tmp12_ = self->priv->_period_style;
			_tmp13_ = SKK_PERIOD_RULE[_tmp12_];
			_tmp14_ = index;
			_tmp15_ = string_index_of_nth_char (_tmp13_, (glong) _tmp14_);
			index = _tmp15_;
			_tmp16_ = self->priv->_period_style;
			_tmp17_ = SKK_PERIOD_RULE[_tmp16_];
			_tmp18_ = index;
			_tmp19_ = string_get_char (_tmp17_, (glong) _tmp18_);
			period = _tmp19_;
			_tmp20_ = self->priv->_output;
			_tmp21_ = period;
			g_string_append_unichar (_tmp20_, _tmp21_);
			_tmp22_ = self->priv->_preedit;
			g_string_erase (_tmp22_, (gssize) 0, (gssize) (-1));
			_tmp23_ = skk_rom_kana_converter_get_rule (self);
			_tmp24_ = _tmp23_;
			_tmp25_ = _tmp24_->root_node;
			_tmp26_ = _g_object_ref0 (_tmp25_);
			_g_object_unref0 (self->priv->current_node);
			self->priv->current_node = _tmp26_;
			result = TRUE;
			_g_object_unref0 (child_node);
			return result;
		} else {
			SkkRomKanaMapFile* _tmp27_;
			SkkRomKanaMapFile* _tmp28_;
			SkkRomKanaNode* _tmp29_;
			gunichar _tmp30_;
			SkkRomKanaNode* _tmp31_;
			_tmp27_ = skk_rom_kana_converter_get_rule (self);
			_tmp28_ = _tmp27_;
			_tmp29_ = _tmp28_->root_node;
			_tmp30_ = uc;
			_tmp31_ = _tmp29_->children[_tmp30_];
			if (_tmp31_ == NULL) {
				GString* _tmp32_;
				gunichar _tmp33_;
				GString* _tmp34_;
				SkkRomKanaMapFile* _tmp35_;
				SkkRomKanaMapFile* _tmp36_;
				SkkRomKanaNode* _tmp37_;
				SkkRomKanaNode* _tmp38_;
				_tmp32_ = self->priv->_output;
				_tmp33_ = uc;
				g_string_append_unichar (_tmp32_, _tmp33_);
				_tmp34_ = self->priv->_preedit;
				g_string_erase (_tmp34_, (gssize) 0, (gssize) (-1));
				_tmp35_ = skk_rom_kana_converter_get_rule (self);
				_tmp36_ = _tmp35_;
				_tmp37_ = _tmp36_->root_node;
				_tmp38_ = _g_object_ref0 (_tmp37_);
				_g_object_unref0 (self->priv->current_node);
				self->priv->current_node = _tmp38_;
				result = retval;
				_g_object_unref0 (child_node);
				return result;
			} else {
				GString* _tmp39_;
				SkkRomKanaMapFile* _tmp40_;
				SkkRomKanaMapFile* _tmp41_;
				SkkRomKanaNode* _tmp42_;
				SkkRomKanaNode* _tmp43_;
				gunichar _tmp44_;
				gboolean _tmp45_ = FALSE;
				_tmp39_ = self->priv->_preedit;
				g_string_erase (_tmp39_, (gssize) 0, (gssize) (-1));
				_tmp40_ = skk_rom_kana_converter_get_rule (self);
				_tmp41_ = _tmp40_;
				_tmp42_ = _tmp41_->root_node;
				_tmp43_ = _g_object_ref0 (_tmp42_);
				_g_object_unref0 (self->priv->current_node);
				self->priv->current_node = _tmp43_;
				_tmp44_ = uc;
				_tmp45_ = skk_rom_kana_converter_append (self, _tmp44_);
				result = _tmp45_;
				_g_object_unref0 (child_node);
				return result;
			}
		}
	} else {
		SkkRomKanaNode* _tmp46_;
		guint _tmp47_;
		_tmp46_ = child_node;
		_tmp47_ = _tmp46_->n_children;
		if (_tmp47_ > ((guint) 0)) {
			GString* _tmp48_;
			gunichar _tmp49_;
			SkkRomKanaNode* _tmp50_;
			SkkRomKanaNode* _tmp51_;
			_tmp48_ = self->priv->_preedit;
			_tmp49_ = uc;
			g_string_append_unichar (_tmp48_, _tmp49_);
			_tmp50_ = child_node;
			_tmp51_ = _g_object_ref0 (_tmp50_);
			_g_object_unref0 (self->priv->current_node);
			self->priv->current_node = _tmp51_;
			result = TRUE;
			_g_object_unref0 (child_node);
			return result;
		} else {
			GString* _tmp52_;
			SkkRomKanaNode* _tmp53_;
			SkkRomKanaEntry* _tmp54_;
			SkkKanaMode _tmp55_;
			gchar* _tmp56_ = NULL;
			gchar* _tmp57_;
			GString* _tmp58_;
			SkkRomKanaMapFile* _tmp59_;
			SkkRomKanaMapFile* _tmp60_;
			SkkRomKanaNode* _tmp61_;
			SkkRomKanaNode* _tmp62_;
			_tmp52_ = self->priv->_output;
			_tmp53_ = child_node;
			_tmp54_ = _tmp53_->entry;
			_tmp55_ = self->priv->_kana_mode;
			_tmp56_ = skk_rom_kana_entry_get_kana (_tmp54_, _tmp55_);
			_tmp57_ = _tmp56_;
			g_string_append (_tmp52_, _tmp57_);
			_g_free0 (_tmp57_);
			_tmp58_ = self->priv->_preedit;
			g_string_erase (_tmp58_, (gssize) 0, (gssize) (-1));
			_tmp59_ = skk_rom_kana_converter_get_rule (self);
			_tmp60_ = _tmp59_;
			_tmp61_ = _tmp60_->root_node;
			_tmp62_ = _g_object_ref0 (_tmp61_);
			_g_object_unref0 (self->priv->current_node);
			self->priv->current_node = _tmp62_;
			{
				gint i;
				i = 0;
				{
					gboolean _tmp63_;
					_tmp63_ = TRUE;
					while (TRUE) {
						gboolean _tmp64_;
						gint _tmp66_;
						SkkRomKanaNode* _tmp67_;
						SkkRomKanaEntry* _tmp68_;
						const gchar* _tmp69_;
						gint _tmp70_;
						gint _tmp71_;
						SkkRomKanaNode* _tmp72_;
						SkkRomKanaEntry* _tmp73_;
						const gchar* _tmp74_;
						gint _tmp75_;
						gchar _tmp76_ = '\0';
						_tmp64_ = _tmp63_;
						if (!_tmp64_) {
							gint _tmp65_;
							_tmp65_ = i;
							i = _tmp65_ + 1;
						}
						_tmp63_ = FALSE;
						_tmp66_ = i;
						_tmp67_ = child_node;
						_tmp68_ = _tmp67_->entry;
						_tmp69_ = (*_tmp68_).carryover;
						_tmp70_ = strlen (_tmp69_);
						_tmp71_ = _tmp70_;
						if (!(_tmp66_ < _tmp71_)) {
							break;
						}
						_tmp72_ = child_node;
						_tmp73_ = _tmp72_->entry;
						_tmp74_ = (*_tmp73_).carryover;
						_tmp75_ = i;
						_tmp76_ = string_get (_tmp74_, (glong) _tmp75_);
						skk_rom_kana_converter_append (self, (gunichar) _tmp76_);
					}
				}
			}
			result = TRUE;
			_g_object_unref0 (child_node);
			return result;
		}
	}
	_g_object_unref0 (child_node);
}


/**
         * Check if a character will be consumed by the current conversion.
         *
         * @param uc an ASCII character
         * @param preedit_only only checks if preedit is active
         * @param no_carryover return false if there will be carryover
         * @return `true` if the character can be consumed
         */
gboolean skk_rom_kana_converter_can_consume (SkkRomKanaConverter* self, gunichar uc, gboolean preedit_only, gboolean no_carryover) {
	gboolean result = FALSE;
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_;
	gboolean _tmp4_;
	SkkRomKanaNode* _tmp5_;
	gunichar _tmp6_;
	SkkRomKanaNode* _tmp7_;
	SkkRomKanaNode* _tmp8_;
	SkkRomKanaNode* child_node;
	SkkRomKanaNode* _tmp9_;
	gboolean _tmp10_ = FALSE;
	gboolean _tmp11_ = FALSE;
	gboolean _tmp12_;
	gboolean _tmp15_;
	gboolean _tmp19_;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp1_ = preedit_only;
	if (_tmp1_) {
		GString* _tmp2_;
		gssize _tmp3_;
		_tmp2_ = self->priv->_preedit;
		_tmp3_ = _tmp2_->len;
		_tmp0_ = _tmp3_ == ((gssize) 0);
	} else {
		_tmp0_ = FALSE;
	}
	_tmp4_ = _tmp0_;
	if (_tmp4_) {
		result = FALSE;
		return result;
	}
	_tmp5_ = self->priv->current_node;
	_tmp6_ = uc;
	_tmp7_ = _tmp5_->children[_tmp6_];
	_tmp8_ = _g_object_ref0 (_tmp7_);
	child_node = _tmp8_;
	_tmp9_ = child_node;
	if (_tmp9_ == NULL) {
		result = FALSE;
		_g_object_unref0 (child_node);
		return result;
	}
	_tmp12_ = no_carryover;
	if (_tmp12_) {
		SkkRomKanaNode* _tmp13_;
		SkkRomKanaEntry* _tmp14_;
		_tmp13_ = child_node;
		_tmp14_ = _tmp13_->entry;
		_tmp11_ = _tmp14_ != NULL;
	} else {
		_tmp11_ = FALSE;
	}
	_tmp15_ = _tmp11_;
	if (_tmp15_) {
		SkkRomKanaNode* _tmp16_;
		SkkRomKanaEntry* _tmp17_;
		const gchar* _tmp18_;
		_tmp16_ = child_node;
		_tmp17_ = _tmp16_->entry;
		_tmp18_ = (*_tmp17_).carryover;
		_tmp10_ = g_strcmp0 (_tmp18_, "") != 0;
	} else {
		_tmp10_ = FALSE;
	}
	_tmp19_ = _tmp10_;
	if (_tmp19_) {
		result = FALSE;
		_g_object_unref0 (child_node);
		return result;
	}
	result = TRUE;
	_g_object_unref0 (child_node);
	return result;
}


/**
         * Reset the internal state of the converter.
         */
void skk_rom_kana_converter_reset (SkkRomKanaConverter* self) {
	GString* _tmp0_;
	GString* _tmp1_;
	SkkRomKanaMapFile* _tmp2_;
	SkkRomKanaMapFile* _tmp3_;
	SkkRomKanaNode* _tmp4_;
	SkkRomKanaNode* _tmp5_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->_output;
	g_string_erase (_tmp0_, (gssize) 0, (gssize) (-1));
	_tmp1_ = self->priv->_preedit;
	g_string_erase (_tmp1_, (gssize) 0, (gssize) (-1));
	_tmp2_ = skk_rom_kana_converter_get_rule (self);
	_tmp3_ = _tmp2_;
	_tmp4_ = _tmp3_->root_node;
	_tmp5_ = _g_object_ref0 (_tmp4_);
	_g_object_unref0 (self->priv->current_node);
	self->priv->current_node = _tmp5_;
}


/**
         * Delete the trailing character from the internal buffer.
         *
         * @return `true` if any character is removed, `false` otherwise
         */
gboolean skk_rom_kana_converter_delete (SkkRomKanaConverter* self) {
	gboolean result = FALSE;
	GString* _tmp0_;
	gssize _tmp1_;
	GString* _tmp17_;
	gssize _tmp18_;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = self->priv->_preedit;
	_tmp1_ = _tmp0_->len;
	if (_tmp1_ > ((gssize) 0)) {
		SkkRomKanaNode* _tmp2_;
		SkkRomKanaNode* _tmp3_;
		SkkRomKanaNode* _tmp4_;
		SkkRomKanaNode* _tmp5_;
		GString* _tmp10_;
		GString* _tmp11_;
		const gchar* _tmp12_;
		GString* _tmp13_;
		const gchar* _tmp14_;
		gint _tmp15_ = 0;
		gint _tmp16_ = 0;
		_tmp2_ = self->priv->current_node;
		_tmp3_ = _tmp2_->parent;
		_tmp4_ = _g_object_ref0 (_tmp3_);
		_g_object_unref0 (self->priv->current_node);
		self->priv->current_node = _tmp4_;
		_tmp5_ = self->priv->current_node;
		if (_tmp5_ == NULL) {
			SkkRomKanaMapFile* _tmp6_;
			SkkRomKanaMapFile* _tmp7_;
			SkkRomKanaNode* _tmp8_;
			SkkRomKanaNode* _tmp9_;
			_tmp6_ = skk_rom_kana_converter_get_rule (self);
			_tmp7_ = _tmp6_;
			_tmp8_ = _tmp7_->root_node;
			_tmp9_ = _g_object_ref0 (_tmp8_);
			_g_object_unref0 (self->priv->current_node);
			self->priv->current_node = _tmp9_;
		}
		_tmp10_ = self->priv->_preedit;
		_tmp11_ = self->priv->_preedit;
		_tmp12_ = _tmp11_->str;
		_tmp13_ = self->priv->_preedit;
		_tmp14_ = _tmp13_->str;
		_tmp15_ = g_utf8_strlen (_tmp14_, (gssize) (-1));
		_tmp16_ = string_index_of_nth_char (_tmp12_, (glong) (_tmp15_ - 1));
		g_string_truncate (_tmp10_, (gsize) _tmp16_);
		result = TRUE;
		return result;
	}
	_tmp17_ = self->priv->_output;
	_tmp18_ = _tmp17_->len;
	if (_tmp18_ > ((gssize) 0)) {
		GString* _tmp19_;
		GString* _tmp20_;
		const gchar* _tmp21_;
		GString* _tmp22_;
		const gchar* _tmp23_;
		gint _tmp24_ = 0;
		gint _tmp25_ = 0;
		_tmp19_ = self->priv->_output;
		_tmp20_ = self->priv->_output;
		_tmp21_ = _tmp20_->str;
		_tmp22_ = self->priv->_output;
		_tmp23_ = _tmp22_->str;
		_tmp24_ = g_utf8_strlen (_tmp23_, (gssize) (-1));
		_tmp25_ = string_index_of_nth_char (_tmp21_, (glong) (_tmp24_ - 1));
		g_string_truncate (_tmp19_, (gsize) _tmp25_);
		result = TRUE;
		return result;
	}
	result = FALSE;
	return result;
}


SkkRomKanaMapFile* skk_rom_kana_converter_get_rule (SkkRomKanaConverter* self) {
	SkkRomKanaMapFile* result;
	SkkRomKanaMapFile* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_rule;
	result = _tmp0_;
	return result;
}


void skk_rom_kana_converter_set_rule (SkkRomKanaConverter* self, SkkRomKanaMapFile* value) {
	SkkRomKanaMapFile* _tmp0_;
	SkkRomKanaMapFile* _tmp1_;
	SkkRomKanaMapFile* _tmp2_;
	SkkRomKanaNode* _tmp3_;
	SkkRomKanaNode* _tmp4_;
	g_return_if_fail (self != NULL);
	_tmp0_ = value;
	_tmp1_ = _g_object_ref0 (_tmp0_);
	_g_object_unref0 (self->priv->_rule);
	self->priv->_rule = _tmp1_;
	_tmp2_ = self->priv->_rule;
	_tmp3_ = _tmp2_->root_node;
	_tmp4_ = _g_object_ref0 (_tmp3_);
	_g_object_unref0 (self->priv->current_node);
	self->priv->current_node = _tmp4_;
	g_object_notify ((GObject *) self, "rule");
}


SkkKanaMode skk_rom_kana_converter_get_kana_mode (SkkRomKanaConverter* self) {
	SkkKanaMode result;
	SkkKanaMode _tmp0_;
	g_return_val_if_fail (self != NULL, 0);
	_tmp0_ = self->priv->_kana_mode;
	result = _tmp0_;
	return result;
}


void skk_rom_kana_converter_set_kana_mode (SkkRomKanaConverter* self, SkkKanaMode value) {
	SkkKanaMode _tmp0_;
	g_return_if_fail (self != NULL);
	_tmp0_ = value;
	self->priv->_kana_mode = _tmp0_;
	g_object_notify ((GObject *) self, "kana-mode");
}


SkkPeriodStyle skk_rom_kana_converter_get_period_style (SkkRomKanaConverter* self) {
	SkkPeriodStyle result;
	SkkPeriodStyle _tmp0_;
	g_return_val_if_fail (self != NULL, 0);
	_tmp0_ = self->priv->_period_style;
	result = _tmp0_;
	return result;
}


void skk_rom_kana_converter_set_period_style (SkkRomKanaConverter* self, SkkPeriodStyle value) {
	SkkPeriodStyle _tmp0_;
	g_return_if_fail (self != NULL);
	_tmp0_ = value;
	self->priv->_period_style = _tmp0_;
	g_object_notify ((GObject *) self, "period-style");
}


const gchar* skk_rom_kana_converter_get_output (SkkRomKanaConverter* self) {
	const gchar* result;
	GString* _tmp0_;
	const gchar* _tmp1_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_output;
	_tmp1_ = _tmp0_->str;
	result = _tmp1_;
	return result;
}


void skk_rom_kana_converter_set_output (SkkRomKanaConverter* self, const gchar* value) {
	GString* _tmp0_;
	const gchar* _tmp1_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->_output;
	_tmp1_ = value;
	g_string_assign (_tmp0_, _tmp1_);
	g_object_notify ((GObject *) self, "output");
}


const gchar* skk_rom_kana_converter_get_preedit (SkkRomKanaConverter* self) {
	const gchar* result;
	GString* _tmp0_;
	const gchar* _tmp1_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_preedit;
	_tmp1_ = _tmp0_->str;
	result = _tmp1_;
	return result;
}


static void skk_rom_kana_converter_class_init (SkkRomKanaConverterClass * klass) {
	skk_rom_kana_converter_parent_class = g_type_class_peek_parent (klass);
	g_type_class_add_private (klass, sizeof (SkkRomKanaConverterPrivate));
	G_OBJECT_CLASS (klass)->get_property = _vala_skk_rom_kana_converter_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_skk_rom_kana_converter_set_property;
	G_OBJECT_CLASS (klass)->finalize = skk_rom_kana_converter_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), SKK_ROM_KANA_CONVERTER_RULE, g_param_spec_object ("rule", "rule", "rule", SKK_TYPE_ROM_KANA_MAP_FILE, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), SKK_ROM_KANA_CONVERTER_KANA_MODE, g_param_spec_enum ("kana-mode", "kana-mode", "kana-mode", SKK_TYPE_KANA_MODE, SKK_KANA_MODE_HIRAGANA, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), SKK_ROM_KANA_CONVERTER_PERIOD_STYLE, g_param_spec_enum ("period-style", "period-style", "period-style", SKK_TYPE_PERIOD_STYLE, SKK_PERIOD_STYLE_JA_JA, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), SKK_ROM_KANA_CONVERTER_OUTPUT, g_param_spec_string ("output", "output", "output", NULL, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), SKK_ROM_KANA_CONVERTER_PREEDIT, g_param_spec_string ("preedit", "preedit", "preedit", NULL, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
}


static void skk_rom_kana_converter_instance_init (SkkRomKanaConverter * self) {
	GString* _tmp0_;
	GString* _tmp1_;
	self->priv = SKK_ROM_KANA_CONVERTER_GET_PRIVATE (self);
	self->priv->_kana_mode = SKK_KANA_MODE_HIRAGANA;
	self->priv->_period_style = SKK_PERIOD_STYLE_JA_JA;
	_tmp0_ = g_string_new ("");
	self->priv->_output = _tmp0_;
	_tmp1_ = g_string_new ("");
	self->priv->_preedit = _tmp1_;
}


static void skk_rom_kana_converter_finalize (GObject* obj) {
	SkkRomKanaConverter * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, SKK_TYPE_ROM_KANA_CONVERTER, SkkRomKanaConverter);
	_g_object_unref0 (self->priv->_rule);
	_g_object_unref0 (self->priv->current_node);
	_g_string_free0 (self->priv->_output);
	_g_string_free0 (self->priv->_preedit);
	G_OBJECT_CLASS (skk_rom_kana_converter_parent_class)->finalize (obj);
}


/**
     * Romaji-to-kana converter.
     */
GType skk_rom_kana_converter_get_type (void) {
	static volatile gsize skk_rom_kana_converter_type_id__volatile = 0;
	if (g_once_init_enter (&skk_rom_kana_converter_type_id__volatile)) {
		static const GTypeInfo g_define_type_info = { sizeof (SkkRomKanaConverterClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) skk_rom_kana_converter_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (SkkRomKanaConverter), 0, (GInstanceInitFunc) skk_rom_kana_converter_instance_init, NULL };
		GType skk_rom_kana_converter_type_id;
		skk_rom_kana_converter_type_id = g_type_register_static (G_TYPE_OBJECT, "SkkRomKanaConverter", &g_define_type_info, 0);
		g_once_init_leave (&skk_rom_kana_converter_type_id__volatile, skk_rom_kana_converter_type_id);
	}
	return skk_rom_kana_converter_type_id__volatile;
}


static void _vala_skk_rom_kana_converter_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec) {
	SkkRomKanaConverter * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, SKK_TYPE_ROM_KANA_CONVERTER, SkkRomKanaConverter);
	switch (property_id) {
		case SKK_ROM_KANA_CONVERTER_RULE:
		g_value_set_object (value, skk_rom_kana_converter_get_rule (self));
		break;
		case SKK_ROM_KANA_CONVERTER_KANA_MODE:
		g_value_set_enum (value, skk_rom_kana_converter_get_kana_mode (self));
		break;
		case SKK_ROM_KANA_CONVERTER_PERIOD_STYLE:
		g_value_set_enum (value, skk_rom_kana_converter_get_period_style (self));
		break;
		case SKK_ROM_KANA_CONVERTER_OUTPUT:
		g_value_set_string (value, skk_rom_kana_converter_get_output (self));
		break;
		case SKK_ROM_KANA_CONVERTER_PREEDIT:
		g_value_set_string (value, skk_rom_kana_converter_get_preedit (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}


static void _vala_skk_rom_kana_converter_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec) {
	SkkRomKanaConverter * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, SKK_TYPE_ROM_KANA_CONVERTER, SkkRomKanaConverter);
	switch (property_id) {
		case SKK_ROM_KANA_CONVERTER_RULE:
		skk_rom_kana_converter_set_rule (self, g_value_get_object (value));
		break;
		case SKK_ROM_KANA_CONVERTER_KANA_MODE:
		skk_rom_kana_converter_set_kana_mode (self, g_value_get_enum (value));
		break;
		case SKK_ROM_KANA_CONVERTER_PERIOD_STYLE:
		skk_rom_kana_converter_set_period_style (self, g_value_get_enum (value));
		break;
		case SKK_ROM_KANA_CONVERTER_OUTPUT:
		skk_rom_kana_converter_set_output (self, g_value_get_string (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}


static void _vala_array_destroy (gpointer array, gint array_length, GDestroyNotify destroy_func) {
	if ((array != NULL) && (destroy_func != NULL)) {
		int i;
		for (i = 0; i < array_length; i = i + 1) {
			if (((gpointer*) array)[i] != NULL) {
				destroy_func (((gpointer*) array)[i]);
			}
		}
	}
}


static void _vala_array_free (gpointer array, gint array_length, GDestroyNotify destroy_func) {
	_vala_array_destroy (array, array_length, destroy_func);
	g_free (array);
}



