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

/* -*- coding: utf-8 -*-*/
/*
 * Copyright (C) 2011-2018 Daiki Ueno <ueno@gnu.org>
 * Copyright (C) 2011-2018 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;
enum  {
	SKK_ROM_KANA_NODE_0_PROPERTY,
	SKK_ROM_KANA_NODE_NUM_PROPERTIES
};
static GParamSpec* skk_rom_kana_node_properties[SKK_ROM_KANA_NODE_NUM_PROPERTIES];
#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;
enum  {
	SKK_ROM_KANA_CONVERTER_0_PROPERTY,
	SKK_ROM_KANA_CONVERTER_RULE_PROPERTY,
	SKK_ROM_KANA_CONVERTER_KANA_MODE_PROPERTY,
	SKK_ROM_KANA_CONVERTER_PERIOD_STYLE_PROPERTY,
	SKK_ROM_KANA_CONVERTER_OUTPUT_PROPERTY,
	SKK_ROM_KANA_CONVERTER_PREEDIT_PROPERTY,
	SKK_ROM_KANA_CONVERTER_NUM_PROPERTIES
};
static GParamSpec* skk_rom_kana_converter_properties[SKK_ROM_KANA_CONVERTER_NUM_PROPERTIES];
#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)))

#define SKK_TYPE_INPUT_MODE (skk_input_mode_get_type ())

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

typedef enum  {
	SKK_INPUT_MODE_HIRAGANA = SKK_KANA_MODE_HIRAGANA,
	SKK_INPUT_MODE_KATAKANA = SKK_KANA_MODE_KATAKANA,
	SKK_INPUT_MODE_HANKAKU_KATAKANA = SKK_KANA_MODE_HANKAKU_KATAKANA,
	SKK_INPUT_MODE_LATIN,
	SKK_INPUT_MODE_WIDE_LATIN,
	SKK_INPUT_MODE_LAST,
	SKK_INPUT_MODE_DEFAULT = SKK_INPUT_MODE_HIRAGANA
} SkkInputMode;


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;
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))
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);
GType skk_input_mode_get_type (void) G_GNUC_CONST;
gchar* skk_util_convert_by_input_mode (const gchar* str,
                                       SkkInputMode input_mode);
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;
	gchar* _tmp6_;
	if (kana_mode == SKK_KANA_MODE_HIRAGANA) {
		const gchar* _tmp0_;
		gchar* _tmp1_;
		_tmp0_ = (*self).hiragana;
		_tmp1_ = g_strdup (_tmp0_);
		result = _tmp1_;
		return result;
	} else {
		if (kana_mode == SKK_KANA_MODE_KATAKANA) {
			const gchar* _tmp2_;
			gchar* _tmp3_;
			_tmp2_ = (*self).katakana;
			_tmp3_ = g_strdup (_tmp2_);
			result = _tmp3_;
			return result;
		} else {
			if (kana_mode == SKK_KANA_MODE_HANKAKU_KATAKANA) {
				const gchar* _tmp4_;
				gchar* _tmp5_;
				_tmp4_ = (*self).hankaku_katakana;
				_tmp5_ = g_strdup (_tmp4_);
				result = _tmp5_;
				return result;
			}
		}
	}
	_tmp6_ = g_strdup ("");
	result = _tmp6_;
	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_;
	self = (SkkRomKanaNode*) g_object_new (object_type, NULL);
	_tmp0_ = _skk_rom_kana_entry_dup0 (entry);
	_skk_rom_kana_entry_free0 (self->entry);
	self->entry = _tmp0_;
	{
		gint i = 0;
		i = 0;
		{
			gboolean _tmp1_ = FALSE;
			_tmp1_ = TRUE;
			while (TRUE) {
				gint _tmp3_;
				gint _tmp4_;
				SkkRomKanaNode* _tmp5_;
				if (!_tmp1_) {
					gint _tmp2_;
					_tmp2_ = i;
					i = _tmp2_ + 1;
				}
				_tmp1_ = FALSE;
				_tmp3_ = i;
				if (!(_tmp3_ < 128)) {
					break;
				}
				_tmp4_ = i;
				_g_object_unref0 (self->children[_tmp4_]);
				self->children[_tmp4_] = NULL;
				_tmp5_ = self->children[_tmp4_];
			}
		}
	}
	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';
	gchar _tmp0_;
	g_return_val_if_fail (self != NULL, '\0');
	_tmp0_ = ((gchar*) self)[index];
	result = _tmp0_;
	return result;
}


void
skk_rom_kana_node_insert (SkkRomKanaNode* self,
                          const gchar* key,
                          SkkRomKanaEntry* entry)
{
	SkkRomKanaNode* node = NULL;
	SkkRomKanaNode* _tmp0_;
	SkkRomKanaNode* _tmp24_;
	SkkRomKanaEntry _tmp25_;
	SkkRomKanaEntry _tmp26_;
	SkkRomKanaEntry* _tmp27_;
	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 = 0;
		i = 0;
		{
			gboolean _tmp1_ = FALSE;
			_tmp1_ = TRUE;
			while (TRUE) {
				gint _tmp3_;
				gint _tmp4_;
				gint _tmp5_;
				SkkRomKanaNode* _tmp6_;
				gint _tmp7_;
				SkkRomKanaNode* _tmp8_;
				SkkRomKanaNode* _tmp16_;
				guint _tmp17_;
				SkkRomKanaNode* _tmp18_;
				gint _tmp19_;
				SkkRomKanaNode* _tmp20_;
				SkkRomKanaNode* _tmp21_;
				gint _tmp22_;
				gboolean _tmp23_;
				if (!_tmp1_) {
					gint _tmp2_;
					_tmp2_ = i;
					i = _tmp2_ + 1;
				}
				_tmp1_ = FALSE;
				_tmp3_ = i;
				_tmp4_ = strlen (key);
				_tmp5_ = _tmp4_;
				if (!(_tmp3_ < _tmp5_)) {
					break;
				}
				_tmp6_ = node;
				_tmp7_ = i;
				_tmp8_ = _tmp6_->children[string_get (key, (glong) _tmp7_)];
				if (_tmp8_ == NULL) {
					SkkRomKanaNode* child = NULL;
					SkkRomKanaNode* _tmp9_;
					gint _tmp10_;
					SkkRomKanaNode* _tmp11_;
					SkkRomKanaNode* _tmp12_;
					SkkRomKanaNode* _tmp13_;
					SkkRomKanaNode* _tmp14_;
					SkkRomKanaNode* _tmp15_;
					_tmp9_ = node;
					_tmp10_ = i;
					_tmp11_ = skk_rom_kana_node_new (NULL);
					_g_object_unref0 (_tmp9_->children[string_get (key, (glong) _tmp10_)]);
					_tmp9_->children[string_get (key, (glong) _tmp10_)] = _tmp11_;
					_tmp12_ = _tmp9_->children[string_get (key, (glong) _tmp10_)];
					_tmp13_ = _g_object_ref0 (_tmp12_);
					child = _tmp13_;
					_tmp14_ = child;
					_tmp15_ = node;
					_tmp14_->parent = _tmp15_;
					_g_object_unref0 (child);
				}
				_tmp16_ = node;
				_tmp17_ = _tmp16_->n_children;
				_tmp16_->n_children = _tmp17_ + 1;
				_tmp18_ = node;
				_tmp19_ = i;
				_tmp20_ = _tmp18_->children[string_get (key, (glong) _tmp19_)];
				_tmp21_ = _g_object_ref0 (_tmp20_);
				_g_object_unref0 (node);
				node = _tmp21_;
				_tmp22_ = i;
				self->valid[string_get (key, (glong) _tmp22_)] = TRUE;
				_tmp23_ = self->valid[string_get (key, (glong) _tmp22_)];
			}
		}
	}
	_tmp24_ = node;
	_tmp25_ = *entry;
	_tmp26_ = _tmp25_;
	_tmp27_ = _skk_rom_kana_entry_dup0 (&_tmp26_);
	_skk_rom_kana_entry_free0 (_tmp24_->entry);
	_tmp24_->entry = _tmp27_;
	_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* metadata = NULL;
		SkkRuleMetadata* _tmp0_;
		SkkRuleMetadata* _tmp1_;
		SkkRomKanaMapFile* _tmp3_ = NULL;
		SkkRuleMetadata* _tmp4_;
		SkkRuleMetadata _tmp5_;
		SkkRomKanaMapFile* _tmp6_;
		SkkRomKanaMapFile* _tmp7_;
		SkkRomKanaMapFile* _tmp8_;
		SkkRomKanaNode* _tmp9_;
		SkkRomKanaNode* _tmp10_;
		_tmp0_ = skk_rule_find_rule ("default");
		metadata = _tmp0_;
		_tmp1_ = metadata;
		if (_tmp1_ == NULL) {
			GError* _tmp2_;
			_tmp2_ = g_error_new_literal (SKK_RULE_PARSE_ERROR, SKK_RULE_PARSE_ERROR_FAILED, "can't find default rule");
			_inner_error_ = _tmp2_;
			_skk_rule_metadata_free0 (metadata);
			if (_inner_error_->domain == SKK_RULE_PARSE_ERROR) {
				goto __catch0_skk_rule_parse_error;
			}
			_skk_rule_metadata_free0 (metadata);
			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;
		}
		_tmp4_ = metadata;
		_tmp5_ = *_tmp4_;
		_tmp6_ = skk_rom_kana_map_file_new (&_tmp5_, &_inner_error_);
		_tmp3_ = _tmp6_;
		if (G_UNLIKELY (_inner_error_ != NULL)) {
			_skk_rule_metadata_free0 (metadata);
			if (_inner_error_->domain == SKK_RULE_PARSE_ERROR) {
				goto __catch0_skk_rule_parse_error;
			}
			_skk_rule_metadata_free0 (metadata);
			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;
		}
		_tmp7_ = _tmp3_;
		_tmp3_ = NULL;
		_g_object_unref0 (self->priv->_rule);
		self->priv->_rule = _tmp7_;
		_tmp8_ = self->priv->_rule;
		_tmp9_ = _tmp8_->root_node;
		_tmp10_ = _g_object_ref0 (_tmp9_);
		_g_object_unref0 (self->priv->current_node);
		self->priv->current_node = _tmp10_;
		_g_object_unref0 (_tmp3_);
		_skk_rule_metadata_free0 (metadata);
	}
	goto __finally0;
	__catch0_skk_rule_parse_error:
	{
		GError* e = NULL;
		const gchar* _tmp11_;
		e = _inner_error_;
		_inner_error_ = NULL;
		_tmp11_ = e->message;
		g_warning ("rom-kana.vala:202: can't find default rom-kana rule: %s", _tmp11_);
		g_assert_not_reached ();
		_g_error_free0 (e);
	}
	__finally0:
	if (G_UNLIKELY (_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;
	SkkRomKanaMapFile* _tmp0_;
	SkkRomKanaNode* _tmp1_;
	gboolean _tmp2_;
	g_return_val_if_fail (self != NULL, FALSE);
	if (uc > ((gunichar) 128)) {
		result = FALSE;
		return result;
	}
	_tmp0_ = self->priv->_rule;
	_tmp1_ = _tmp0_->root_node;
	_tmp2_ = _tmp1_->valid[(gint) uc];
	result = _tmp2_;
	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;
	gunichar _tmp0_;
	g_return_val_if_fail (self != NULL, FALSE);
	_vala_c = g_utf8_get_char (((gchar*) self) + (*index));
	_tmp0_ = _vala_c;
	if (_tmp0_ != ((gunichar) 0)) {
		gchar* _tmp1_;
		_tmp1_ = g_utf8_next_char (((gchar*) self) + (*index));
		*index = (gint) (_tmp1_ - ((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 = 0;
	gunichar c = 0U;
	g_return_if_fail (self != NULL);
	g_return_if_fail (text != NULL);
	index = 0;
	while (TRUE) {
		gunichar _tmp0_ = 0U;
		gboolean _tmp1_;
		gunichar _tmp2_;
		_tmp1_ = string_get_next_char (text, &index, &_tmp0_);
		c = _tmp0_;
		if (!_tmp1_) {
			break;
		}
		_tmp2_ = c;
		skk_rom_kana_converter_append (self, _tmp2_);
	}
}


/**
         * 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;
	gchar* _result_ = NULL;
	gchar* _tmp0_;
	gchar* _tmp1_;
	g_return_val_if_fail (self != NULL, 0);
	_tmp0_ = g_utf8_strchr (((gchar*) self) + start_index, (gssize) -1, c);
	_result_ = _tmp0_;
	_tmp1_ = _result_;
	if (_tmp1_ != NULL) {
		gchar* _tmp2_;
		_tmp2_ = _result_;
		result = (gint) (_tmp2_ - ((gchar*) self));
		return result;
	} else {
		result = -1;
		return result;
	}
}


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


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


static gchar*
g_unichar_to_string (gunichar self)
{
	gchar* result = NULL;
	gchar* str = NULL;
	gchar* _tmp0_;
	const gchar* _tmp1_;
	_tmp0_ = g_new0 (gchar, 7);
	str = (gchar*) _tmp0_;
	_tmp1_ = str;
	g_unichar_to_utf8 (self, _tmp1_);
	result = str;
	return result;
}


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


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)
{
	g_return_if_fail (self != NULL);
	if (skk_rom_kana_converter_get_kana_mode (self) != value) {
		self->priv->_kana_mode = value;
		g_object_notify_by_pspec ((GObject *) self, skk_rom_kana_converter_properties[SKK_ROM_KANA_CONVERTER_KANA_MODE_PROPERTY]);
	}
}


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)
{
	g_return_if_fail (self != NULL);
	if (skk_rom_kana_converter_get_period_style (self) != value) {
		self->priv->_period_style = value;
		g_object_notify_by_pspec ((GObject *) self, skk_rom_kana_converter_properties[SKK_ROM_KANA_CONVERTER_PERIOD_STYLE_PROPERTY]);
	}
}


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_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->_output;
	g_string_assign (_tmp0_, value);
	g_object_notify_by_pspec ((GObject *) self, skk_rom_kana_converter_properties[SKK_ROM_KANA_CONVERTER_OUTPUT_PROPERTY]);
}


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_PROPERTY, skk_rom_kana_converter_properties[SKK_ROM_KANA_CONVERTER_RULE_PROPERTY] = g_param_spec_object ("rule", "rule", "rule", SKK_TYPE_ROM_KANA_MAP_FILE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), SKK_ROM_KANA_CONVERTER_KANA_MODE_PROPERTY, skk_rom_kana_converter_properties[SKK_ROM_KANA_CONVERTER_KANA_MODE_PROPERTY] = g_param_spec_enum ("kana-mode", "kana-mode", "kana-mode", SKK_TYPE_KANA_MODE, SKK_KANA_MODE_HIRAGANA, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), SKK_ROM_KANA_CONVERTER_PERIOD_STYLE_PROPERTY, skk_rom_kana_converter_properties[SKK_ROM_KANA_CONVERTER_PERIOD_STYLE_PROPERTY] = g_param_spec_enum ("period-style", "period-style", "period-style", SKK_TYPE_PERIOD_STYLE, SKK_PERIOD_STYLE_JA_JA, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), SKK_ROM_KANA_CONVERTER_OUTPUT_PROPERTY, skk_rom_kana_converter_properties[SKK_ROM_KANA_CONVERTER_OUTPUT_PROPERTY] = g_param_spec_string ("output", "output", "output", NULL, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), SKK_ROM_KANA_CONVERTER_PREEDIT_PROPERTY, skk_rom_kana_converter_properties[SKK_ROM_KANA_CONVERTER_PREEDIT_PROPERTY] = g_param_spec_string ("preedit", "preedit", "preedit", NULL, G_PARAM_STATIC_STRINGS | 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_PROPERTY:
		g_value_set_object (value, skk_rom_kana_converter_get_rule (self));
		break;
		case SKK_ROM_KANA_CONVERTER_KANA_MODE_PROPERTY:
		g_value_set_enum (value, skk_rom_kana_converter_get_kana_mode (self));
		break;
		case SKK_ROM_KANA_CONVERTER_PERIOD_STYLE_PROPERTY:
		g_value_set_enum (value, skk_rom_kana_converter_get_period_style (self));
		break;
		case SKK_ROM_KANA_CONVERTER_OUTPUT_PROPERTY:
		g_value_set_string (value, skk_rom_kana_converter_get_output (self));
		break;
		case SKK_ROM_KANA_CONVERTER_PREEDIT_PROPERTY:
		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_PROPERTY:
		skk_rom_kana_converter_set_rule (self, g_value_get_object (value));
		break;
		case SKK_ROM_KANA_CONVERTER_KANA_MODE_PROPERTY:
		skk_rom_kana_converter_set_kana_mode (self, g_value_get_enum (value));
		break;
		case SKK_ROM_KANA_CONVERTER_PERIOD_STYLE_PROPERTY:
		skk_rom_kana_converter_set_period_style (self, g_value_get_enum (value));
		break;
		case SKK_ROM_KANA_CONVERTER_OUTPUT_PROPERTY:
		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);
}



