/* retro-module-iterator.c generated by valac 0.36.1.17-97a62, the Vala compiler
 * generated from retro-module-iterator.vala, do not modify */

/* This file is part of retro-gtk. License: GPL-3.0+.*/

#include <glib.h>
#include <glib-object.h>
#include <stdlib.h>
#include <string.h>
#include <gio/gio.h>
#include <gobject/gvaluecollector.h>


#define RETRO_TYPE_MODULE_ITERATOR (retro_module_iterator_get_type ())
#define RETRO_MODULE_ITERATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RETRO_TYPE_MODULE_ITERATOR, RetroModuleIterator))
#define RETRO_MODULE_ITERATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RETRO_TYPE_MODULE_ITERATOR, RetroModuleIteratorClass))
#define RETRO_IS_MODULE_ITERATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RETRO_TYPE_MODULE_ITERATOR))
#define RETRO_IS_MODULE_ITERATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RETRO_TYPE_MODULE_ITERATOR))
#define RETRO_MODULE_ITERATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RETRO_TYPE_MODULE_ITERATOR, RetroModuleIteratorClass))

typedef struct _RetroModuleIterator RetroModuleIterator;
typedef struct _RetroModuleIteratorClass RetroModuleIteratorClass;
typedef struct _RetroModuleIteratorPrivate RetroModuleIteratorPrivate;

#define RETRO_TYPE_CORE_DESCRIPTOR (retro_core_descriptor_get_type ())
#define RETRO_CORE_DESCRIPTOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RETRO_TYPE_CORE_DESCRIPTOR, RetroCoreDescriptor))
#define RETRO_CORE_DESCRIPTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RETRO_TYPE_CORE_DESCRIPTOR, RetroCoreDescriptorClass))
#define RETRO_IS_CORE_DESCRIPTOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RETRO_TYPE_CORE_DESCRIPTOR))
#define RETRO_IS_CORE_DESCRIPTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RETRO_TYPE_CORE_DESCRIPTOR))
#define RETRO_CORE_DESCRIPTOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RETRO_TYPE_CORE_DESCRIPTOR, RetroCoreDescriptorClass))

typedef struct _RetroCoreDescriptor RetroCoreDescriptor;
typedef struct _RetroCoreDescriptorClass RetroCoreDescriptorClass;
enum  {
	RETRO_MODULE_ITERATOR_DUMMY_PROPERTY,
	RETRO_MODULE_ITERATOR_LAST_PROPERTY
};
static GParamSpec* retro_module_iterator_properties[RETRO_MODULE_ITERATOR_LAST_PROPERTY];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _retro_module_iterator_unref0(var) ((var == NULL) ? NULL : (var = (retro_module_iterator_unref (var), NULL)))
#define _g_hash_table_unref0(var) ((var == NULL) ? NULL : (var = (g_hash_table_unref (var), NULL)))
#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
#define _g_free0(var) (var = (g_free (var), NULL))
typedef struct _RetroParamSpecModuleIterator RetroParamSpecModuleIterator;

struct _RetroModuleIterator {
	GTypeInstance parent_instance;
	volatile int ref_count;
	RetroModuleIteratorPrivate * priv;
};

struct _RetroModuleIteratorClass {
	GTypeClass parent_class;
	void (*finalize) (RetroModuleIterator *self);
};

struct _RetroModuleIteratorPrivate {
	gchar** directories;
	gint directories_length1;
	gint _directories_size_;
	gboolean recursive;
	gint current_directory;
	GFileEnumerator* file_enumerator;
	RetroCoreDescriptor* core_descriptor;
	RetroModuleIterator* sub_directory;
	GHashTable* visited;
};

struct _RetroParamSpecModuleIterator {
	GParamSpec parent_instance;
};


static gpointer retro_module_iterator_parent_class = NULL;

gpointer retro_module_iterator_ref (gpointer instance);
void retro_module_iterator_unref (gpointer instance);
GParamSpec* retro_param_spec_module_iterator (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags);
void retro_value_set_module_iterator (GValue* value, gpointer v_object);
void retro_value_take_module_iterator (GValue* value, gpointer v_object);
gpointer retro_value_get_module_iterator (const GValue* value);
GType retro_module_iterator_get_type (void) G_GNUC_CONST;
GType retro_core_descriptor_get_type (void) G_GNUC_CONST;
#define RETRO_MODULE_ITERATOR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RETRO_TYPE_MODULE_ITERATOR, RetroModuleIteratorPrivate))
RetroModuleIterator* retro_module_iterator_new (gchar** lookup_paths, int lookup_paths_length1, gboolean recursive);
RetroModuleIterator* retro_module_iterator_construct (GType object_type, gchar** lookup_paths, int lookup_paths_length1, gboolean recursive);
static gchar** _vala_array_dup1 (gchar** self, int length);
static void _g_free0_ (gpointer var);
static RetroModuleIterator* retro_module_iterator_new_for_subdirectory (const gchar* lookup_path, GHashTable* visited_paths);
static RetroModuleIterator* retro_module_iterator_construct_for_subdirectory (GType object_type, const gchar* lookup_path, GHashTable* visited_paths);
RetroCoreDescriptor* retro_module_iterator_get (RetroModuleIterator* self);
gboolean retro_module_iterator_next (RetroModuleIterator* self);
static void retro_module_iterator_set_current_directory_as_visited (RetroModuleIterator* self);
static gboolean retro_module_iterator_next_in_current_path (RetroModuleIterator* self, GError** error);
static gboolean retro_module_iterator_was_current_directory_visited (RetroModuleIterator* self);
static gboolean retro_module_iterator_next_in_sub_directory (RetroModuleIterator* self, GError** error);
RetroCoreDescriptor* retro_core_descriptor_new (const gchar* filename, GError** error);
RetroCoreDescriptor* retro_core_descriptor_construct (GType object_type, const gchar* filename, GError** error);
static void retro_module_iterator_finalize (RetroModuleIterator * obj);
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);


static gchar** _vala_array_dup1 (gchar** self, int length) {
	gchar** result;
	int i;
	result = g_new0 (gchar*, length + 1);
	for (i = 0; i < length; i++) {
		gchar* _tmp0_;
		_tmp0_ = g_strdup (self[i]);
		result[i] = _tmp0_;
	}
	return result;
}


static void _g_free0_ (gpointer var) {
	var = (g_free (var), NULL);
}


RetroModuleIterator* retro_module_iterator_construct (GType object_type, gchar** lookup_paths, int lookup_paths_length1, gboolean recursive) {
	RetroModuleIterator* self = NULL;
	gchar** _tmp0_;
	gint _tmp0__length1;
	gchar** _tmp1_;
	gint _tmp1__length1;
	gboolean _tmp2_;
	GHashFunc _tmp3_;
	GEqualFunc _tmp4_;
	GHashTable* _tmp5_;
	self = (RetroModuleIterator*) g_type_create_instance (object_type);
	_tmp0_ = lookup_paths;
	_tmp0__length1 = lookup_paths_length1;
	_tmp1_ = (_tmp0_ != NULL) ? _vala_array_dup1 (_tmp0_, _tmp0__length1) : ((gpointer) _tmp0_);
	_tmp1__length1 = _tmp0__length1;
	self->priv->directories = (_vala_array_free (self->priv->directories, self->priv->directories_length1, (GDestroyNotify) g_free), NULL);
	self->priv->directories = _tmp1_;
	self->priv->directories_length1 = _tmp1__length1;
	self->priv->_directories_size_ = self->priv->directories_length1;
	_tmp2_ = recursive;
	self->priv->recursive = _tmp2_;
	_tmp3_ = g_str_hash;
	_tmp4_ = g_str_equal;
	_tmp5_ = g_hash_table_new_full (_tmp3_, _tmp4_, NULL, _g_free0_);
	_g_hash_table_unref0 (self->priv->visited);
	self->priv->visited = _tmp5_;
	return self;
}


RetroModuleIterator* retro_module_iterator_new (gchar** lookup_paths, int lookup_paths_length1, gboolean recursive) {
	return retro_module_iterator_construct (RETRO_TYPE_MODULE_ITERATOR, lookup_paths, lookup_paths_length1, recursive);
}


static gpointer _g_hash_table_ref0 (gpointer self) {
	return self ? g_hash_table_ref (self) : NULL;
}


static RetroModuleIterator* retro_module_iterator_construct_for_subdirectory (GType object_type, const gchar* lookup_path, GHashTable* visited_paths) {
	RetroModuleIterator* self = NULL;
	const gchar* _tmp0_;
	gchar* _tmp1_;
	gchar** _tmp2_;
	GHashTable* _tmp3_;
	GHashTable* _tmp4_;
	g_return_val_if_fail (lookup_path != NULL, NULL);
	g_return_val_if_fail (visited_paths != NULL, NULL);
	self = (RetroModuleIterator*) g_type_create_instance (object_type);
	_tmp0_ = lookup_path;
	_tmp1_ = g_strdup (_tmp0_);
	_tmp2_ = g_new0 (gchar*, 1 + 1);
	_tmp2_[0] = _tmp1_;
	self->priv->directories = (_vala_array_free (self->priv->directories, self->priv->directories_length1, (GDestroyNotify) g_free), NULL);
	self->priv->directories = _tmp2_;
	self->priv->directories_length1 = 1;
	self->priv->_directories_size_ = self->priv->directories_length1;
	self->priv->recursive = TRUE;
	_tmp3_ = visited_paths;
	_tmp4_ = _g_hash_table_ref0 (_tmp3_);
	_g_hash_table_unref0 (self->priv->visited);
	self->priv->visited = _tmp4_;
	return self;
}


static RetroModuleIterator* retro_module_iterator_new_for_subdirectory (const gchar* lookup_path, GHashTable* visited_paths) {
	return retro_module_iterator_construct_for_subdirectory (RETRO_TYPE_MODULE_ITERATOR, lookup_path, visited_paths);
}


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


RetroCoreDescriptor* retro_module_iterator_get (RetroModuleIterator* self) {
	RetroCoreDescriptor* result = NULL;
	RetroCoreDescriptor* _tmp0_;
	RetroCoreDescriptor* _tmp1_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->core_descriptor;
	_tmp1_ = _g_object_ref0 (_tmp0_);
	result = _tmp1_;
	return result;
}


gboolean retro_module_iterator_next (RetroModuleIterator* self) {
	gboolean result = FALSE;
	GError * _inner_error_ = NULL;
	g_return_val_if_fail (self != NULL, FALSE);
	while (TRUE) {
		gint _tmp0_;
		gchar** _tmp1_;
		gint _tmp1__length1;
		_tmp0_ = self->priv->current_directory;
		_tmp1_ = self->priv->directories;
		_tmp1__length1 = self->priv->directories_length1;
		if (!(_tmp0_ < _tmp1__length1)) {
			break;
		}
		retro_module_iterator_set_current_directory_as_visited (self);
		{
			gboolean _tmp2_;
			gboolean _tmp3_;
			_tmp3_ = retro_module_iterator_next_in_current_path (self, &_inner_error_);
			_tmp2_ = _tmp3_;
			if (G_UNLIKELY (_inner_error_ != NULL)) {
				goto __catch0_g_error;
			}
			if (_tmp2_) {
				result = TRUE;
				return result;
			}
		}
		goto __finally0;
		__catch0_g_error:
		{
			GError* e = NULL;
			GError* _tmp4_;
			const gchar* _tmp5_;
			e = _inner_error_;
			_inner_error_ = NULL;
			_tmp4_ = e;
			_tmp5_ = _tmp4_->message;
			g_debug ("retro-module-iterator.vala:37: %s", _tmp5_);
			_g_error_free0 (e);
		}
		__finally0:
		if (G_UNLIKELY (_inner_error_ != NULL)) {
			gboolean _tmp6_ = FALSE;
			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 _tmp6_;
		}
		while (TRUE) {
			gboolean _tmp7_ = FALSE;
			gint _tmp8_;
			gchar** _tmp9_;
			gint _tmp9__length1;
			gint _tmp11_;
			_tmp8_ = self->priv->current_directory;
			_tmp9_ = self->priv->directories;
			_tmp9__length1 = self->priv->directories_length1;
			if (_tmp8_ < _tmp9__length1) {
				gboolean _tmp10_;
				_tmp10_ = retro_module_iterator_was_current_directory_visited (self);
				_tmp7_ = _tmp10_;
			} else {
				_tmp7_ = FALSE;
			}
			if (!_tmp7_) {
				break;
			}
			_tmp11_ = self->priv->current_directory;
			self->priv->current_directory = _tmp11_ + 1;
		}
	}
	_g_object_unref0 (self->priv->file_enumerator);
	self->priv->file_enumerator = NULL;
	_g_object_unref0 (self->priv->core_descriptor);
	self->priv->core_descriptor = NULL;
	_retro_module_iterator_unref0 (self->priv->sub_directory);
	self->priv->sub_directory = NULL;
	result = FALSE;
	return result;
}


static gboolean retro_module_iterator_next_in_current_path (RetroModuleIterator* self, GError** error) {
	gboolean result = FALSE;
	gboolean _tmp0_ = FALSE;
	RetroModuleIterator* _tmp1_;
	GFile* directory;
	gchar** _tmp5_;
	gint _tmp5__length1;
	gint _tmp6_;
	const gchar* _tmp7_;
	GFile* _tmp8_;
	GFileEnumerator* _tmp9_;
	GFileEnumerator* _tmp15_;
	GError * _inner_error_ = NULL;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp1_ = self->priv->sub_directory;
	if (_tmp1_ != NULL) {
		gboolean _tmp2_;
		gboolean _tmp3_;
		_tmp3_ = retro_module_iterator_next_in_sub_directory (self, &_inner_error_);
		_tmp2_ = _tmp3_;
		if (G_UNLIKELY (_inner_error_ != NULL)) {
			gboolean _tmp4_ = FALSE;
			g_propagate_error (error, _inner_error_);
			return _tmp4_;
		}
		_tmp0_ = _tmp2_;
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		result = TRUE;
		return result;
	}
	_tmp5_ = self->priv->directories;
	_tmp5__length1 = self->priv->directories_length1;
	_tmp6_ = self->priv->current_directory;
	_tmp7_ = _tmp5_[_tmp6_];
	_tmp8_ = g_file_new_for_path (_tmp7_);
	directory = _tmp8_;
	_tmp9_ = self->priv->file_enumerator;
	if (_tmp9_ == NULL) {
		GFileEnumerator* _tmp10_;
		GFile* _tmp11_;
		GFileEnumerator* _tmp12_;
		GFileEnumerator* _tmp14_;
		_tmp11_ = directory;
		_tmp12_ = g_file_enumerate_children (_tmp11_, "", G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, &_inner_error_);
		_tmp10_ = _tmp12_;
		if (G_UNLIKELY (_inner_error_ != NULL)) {
			gboolean _tmp13_ = FALSE;
			g_propagate_error (error, _inner_error_);
			_g_object_unref0 (directory);
			return _tmp13_;
		}
		_tmp14_ = _tmp10_;
		_tmp10_ = NULL;
		_g_object_unref0 (self->priv->file_enumerator);
		self->priv->file_enumerator = _tmp14_;
		_g_object_unref0 (_tmp10_);
	}
	_tmp15_ = self->priv->file_enumerator;
	if (_tmp15_ == NULL) {
		result = FALSE;
		_g_object_unref0 (directory);
		return result;
	}
	{
		GFileInfo* info;
		GFileEnumerator* _tmp16_;
		GFileInfo* _tmp17_;
		_tmp16_ = self->priv->file_enumerator;
		_tmp17_ = g_file_enumerator_next_file (_tmp16_, NULL, &_inner_error_);
		info = _tmp17_;
		if (G_UNLIKELY (_inner_error_ != NULL)) {
			gboolean _tmp18_ = FALSE;
			g_propagate_error (error, _inner_error_);
			_g_object_unref0 (directory);
			return _tmp18_;
		}
		{
			gboolean _tmp19_;
			_tmp19_ = TRUE;
			while (TRUE) {
				GFileInfo* _tmp25_;
				gboolean _tmp26_ = FALSE;
				gboolean _tmp27_ = FALSE;
				gboolean _tmp28_;
				gchar* core_descriptor_basename;
				GFileInfo* _tmp49_;
				const gchar* _tmp50_;
				gchar* _tmp51_;
				const gchar* _tmp52_;
				gboolean _tmp53_;
				GFile* core_descriptor_file;
				GFile* _tmp54_;
				const gchar* _tmp55_;
				GFile* _tmp56_;
				gchar* core_descriptor_path;
				GFile* _tmp57_;
				gchar* _tmp58_;
				if (!_tmp19_) {
					GFileInfo* _tmp20_;
					GFileEnumerator* _tmp21_;
					GFileInfo* _tmp22_;
					GFileInfo* _tmp24_;
					_tmp21_ = self->priv->file_enumerator;
					_tmp22_ = g_file_enumerator_next_file (_tmp21_, NULL, &_inner_error_);
					_tmp20_ = _tmp22_;
					if (G_UNLIKELY (_inner_error_ != NULL)) {
						gboolean _tmp23_ = FALSE;
						g_propagate_error (error, _inner_error_);
						_g_object_unref0 (info);
						_g_object_unref0 (directory);
						return _tmp23_;
					}
					_tmp24_ = _tmp20_;
					_tmp20_ = NULL;
					_g_object_unref0 (info);
					info = _tmp24_;
					_g_object_unref0 (_tmp20_);
				}
				_tmp19_ = FALSE;
				_tmp25_ = info;
				if (!(_tmp25_ != NULL)) {
					break;
				}
				_tmp28_ = self->priv->recursive;
				if (_tmp28_) {
					GFileInfo* _tmp29_;
					GFileType _tmp30_;
					_tmp29_ = info;
					_tmp30_ = g_file_info_get_file_type (_tmp29_);
					_tmp27_ = _tmp30_ == G_FILE_TYPE_DIRECTORY;
				} else {
					_tmp27_ = FALSE;
				}
				if (_tmp27_) {
					RetroModuleIterator* _tmp31_;
					_tmp31_ = self->priv->sub_directory;
					_tmp26_ = _tmp31_ == NULL;
				} else {
					_tmp26_ = FALSE;
				}
				if (_tmp26_) {
					gchar* sub_directory_basename;
					GFileInfo* _tmp32_;
					const gchar* _tmp33_;
					gchar* _tmp34_;
					GFile* sub_directory_file;
					GFile* _tmp35_;
					const gchar* _tmp36_;
					GFile* _tmp37_;
					gchar* sub_directory_path;
					GFile* _tmp38_;
					gchar* _tmp39_;
					GHashTable* _tmp40_;
					const gchar* _tmp41_;
					gboolean _tmp42_;
					const gchar* _tmp43_;
					GHashTable* _tmp44_;
					RetroModuleIterator* _tmp45_;
					gboolean _tmp46_;
					gboolean _tmp47_;
					_tmp32_ = info;
					_tmp33_ = g_file_info_get_name (_tmp32_);
					_tmp34_ = g_strdup (_tmp33_);
					sub_directory_basename = _tmp34_;
					_tmp35_ = directory;
					_tmp36_ = sub_directory_basename;
					_tmp37_ = g_file_get_child (_tmp35_, _tmp36_);
					sub_directory_file = _tmp37_;
					_tmp38_ = sub_directory_file;
					_tmp39_ = g_file_get_path (_tmp38_);
					sub_directory_path = _tmp39_;
					_tmp40_ = self->priv->visited;
					_tmp41_ = sub_directory_path;
					_tmp42_ = g_hash_table_contains (_tmp40_, _tmp41_);
					if (_tmp42_) {
						_g_free0 (sub_directory_path);
						_g_object_unref0 (sub_directory_file);
						_g_free0 (sub_directory_basename);
						continue;
					}
					_tmp43_ = sub_directory_path;
					_tmp44_ = self->priv->visited;
					_tmp45_ = retro_module_iterator_new_for_subdirectory (_tmp43_, _tmp44_);
					_retro_module_iterator_unref0 (self->priv->sub_directory);
					self->priv->sub_directory = _tmp45_;
					_tmp47_ = retro_module_iterator_next_in_sub_directory (self, &_inner_error_);
					_tmp46_ = _tmp47_;
					if (G_UNLIKELY (_inner_error_ != NULL)) {
						gboolean _tmp48_ = FALSE;
						g_propagate_error (error, _inner_error_);
						_g_free0 (sub_directory_path);
						_g_object_unref0 (sub_directory_file);
						_g_free0 (sub_directory_basename);
						_g_object_unref0 (info);
						_g_object_unref0 (directory);
						return _tmp48_;
					}
					if (_tmp46_) {
						result = TRUE;
						_g_free0 (sub_directory_path);
						_g_object_unref0 (sub_directory_file);
						_g_free0 (sub_directory_basename);
						_g_object_unref0 (info);
						_g_object_unref0 (directory);
						return result;
					} else {
						_g_free0 (sub_directory_path);
						_g_object_unref0 (sub_directory_file);
						_g_free0 (sub_directory_basename);
						continue;
					}
					_g_free0 (sub_directory_path);
					_g_object_unref0 (sub_directory_file);
					_g_free0 (sub_directory_basename);
				}
				_tmp49_ = info;
				_tmp50_ = g_file_info_get_name (_tmp49_);
				_tmp51_ = g_strdup (_tmp50_);
				core_descriptor_basename = _tmp51_;
				_tmp52_ = core_descriptor_basename;
				_tmp53_ = g_str_has_suffix (_tmp52_, ".libretro");
				if (!_tmp53_) {
					_g_free0 (core_descriptor_basename);
					continue;
				}
				_tmp54_ = directory;
				_tmp55_ = core_descriptor_basename;
				_tmp56_ = g_file_get_child (_tmp54_, _tmp55_);
				core_descriptor_file = _tmp56_;
				_tmp57_ = core_descriptor_file;
				_tmp58_ = g_file_get_path (_tmp57_);
				core_descriptor_path = _tmp58_;
				{
					RetroCoreDescriptor* _tmp59_;
					const gchar* _tmp60_;
					RetroCoreDescriptor* _tmp61_;
					RetroCoreDescriptor* _tmp62_;
					_tmp60_ = core_descriptor_path;
					_tmp61_ = retro_core_descriptor_new (_tmp60_, &_inner_error_);
					_tmp59_ = _tmp61_;
					if (G_UNLIKELY (_inner_error_ != NULL)) {
						goto __catch1_g_error;
					}
					_tmp62_ = _tmp59_;
					_tmp59_ = NULL;
					_g_object_unref0 (self->priv->core_descriptor);
					self->priv->core_descriptor = _tmp62_;
					result = TRUE;
					_g_object_unref0 (_tmp59_);
					_g_free0 (core_descriptor_path);
					_g_object_unref0 (core_descriptor_file);
					_g_free0 (core_descriptor_basename);
					_g_object_unref0 (info);
					_g_object_unref0 (directory);
					return result;
				}
				goto __finally1;
				__catch1_g_error:
				{
					GError* e = NULL;
					GError* _tmp63_;
					const gchar* _tmp64_;
					e = _inner_error_;
					_inner_error_ = NULL;
					_tmp63_ = e;
					_tmp64_ = _tmp63_->message;
					g_debug ("retro-module-iterator.vala:91: %s", _tmp64_);
					_g_error_free0 (e);
				}
				__finally1:
				if (G_UNLIKELY (_inner_error_ != NULL)) {
					gboolean _tmp65_ = FALSE;
					g_propagate_error (error, _inner_error_);
					_g_free0 (core_descriptor_path);
					_g_object_unref0 (core_descriptor_file);
					_g_free0 (core_descriptor_basename);
					_g_object_unref0 (info);
					_g_object_unref0 (directory);
					return _tmp65_;
				}
				_g_free0 (core_descriptor_path);
				_g_object_unref0 (core_descriptor_file);
				_g_free0 (core_descriptor_basename);
			}
		}
		_g_object_unref0 (info);
	}
	_g_object_unref0 (self->priv->file_enumerator);
	self->priv->file_enumerator = NULL;
	result = FALSE;
	_g_object_unref0 (directory);
	return result;
}


static gboolean retro_module_iterator_next_in_sub_directory (RetroModuleIterator* self, GError** error) {
	gboolean result = FALSE;
	RetroModuleIterator* _tmp0_;
	gboolean _tmp1_;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = self->priv->sub_directory;
	_tmp1_ = retro_module_iterator_next (_tmp0_);
	if (_tmp1_) {
		RetroModuleIterator* _tmp2_;
		RetroCoreDescriptor* _tmp3_;
		_tmp2_ = self->priv->sub_directory;
		_tmp3_ = retro_module_iterator_get (_tmp2_);
		_g_object_unref0 (self->priv->core_descriptor);
		self->priv->core_descriptor = _tmp3_;
		result = TRUE;
		return result;
	}
	_retro_module_iterator_unref0 (self->priv->sub_directory);
	self->priv->sub_directory = NULL;
	result = FALSE;
	return result;
}


static void retro_module_iterator_set_current_directory_as_visited (RetroModuleIterator* self) {
	GFile* current_directory_file;
	gchar** _tmp0_;
	gint _tmp0__length1;
	gint _tmp1_;
	const gchar* _tmp2_;
	GFile* _tmp3_;
	gchar* current_directory_path;
	gchar* _tmp4_;
	GHashTable* _tmp5_;
	gchar* _tmp6_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->directories;
	_tmp0__length1 = self->priv->directories_length1;
	_tmp1_ = self->priv->current_directory;
	_tmp2_ = _tmp0_[_tmp1_];
	_tmp3_ = g_file_new_for_path (_tmp2_);
	current_directory_file = _tmp3_;
	_tmp4_ = g_file_get_path (current_directory_file);
	current_directory_path = _tmp4_;
	_tmp5_ = self->priv->visited;
	_tmp6_ = g_strdup (current_directory_path);
	g_hash_table_add (_tmp5_, _tmp6_);
	_g_free0 (current_directory_path);
	_g_object_unref0 (current_directory_file);
}


static gboolean retro_module_iterator_was_current_directory_visited (RetroModuleIterator* self) {
	gboolean result = FALSE;
	GFile* current_directory_file;
	gchar** _tmp0_;
	gint _tmp0__length1;
	gint _tmp1_;
	const gchar* _tmp2_;
	GFile* _tmp3_;
	gchar* current_directory_path;
	gchar* _tmp4_;
	GHashTable* _tmp5_;
	gboolean _tmp6_;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = self->priv->directories;
	_tmp0__length1 = self->priv->directories_length1;
	_tmp1_ = self->priv->current_directory;
	_tmp2_ = _tmp0_[_tmp1_];
	_tmp3_ = g_file_new_for_path (_tmp2_);
	current_directory_file = _tmp3_;
	_tmp4_ = g_file_get_path (current_directory_file);
	current_directory_path = _tmp4_;
	_tmp5_ = self->priv->visited;
	_tmp6_ = g_hash_table_contains (_tmp5_, current_directory_path);
	result = _tmp6_;
	_g_free0 (current_directory_path);
	_g_object_unref0 (current_directory_file);
	return result;
}


static void retro_value_module_iterator_init (GValue* value) {
	value->data[0].v_pointer = NULL;
}


static void retro_value_module_iterator_free_value (GValue* value) {
	if (value->data[0].v_pointer) {
		retro_module_iterator_unref (value->data[0].v_pointer);
	}
}


static void retro_value_module_iterator_copy_value (const GValue* src_value, GValue* dest_value) {
	if (src_value->data[0].v_pointer) {
		dest_value->data[0].v_pointer = retro_module_iterator_ref (src_value->data[0].v_pointer);
	} else {
		dest_value->data[0].v_pointer = NULL;
	}
}


static gpointer retro_value_module_iterator_peek_pointer (const GValue* value) {
	return value->data[0].v_pointer;
}


static gchar* retro_value_module_iterator_collect_value (GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) {
	if (collect_values[0].v_pointer) {
		RetroModuleIterator * object;
		object = collect_values[0].v_pointer;
		if (object->parent_instance.g_class == NULL) {
			return g_strconcat ("invalid unclassed object pointer for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		} else if (!g_value_type_compatible (G_TYPE_FROM_INSTANCE (object), G_VALUE_TYPE (value))) {
			return g_strconcat ("invalid object type `", g_type_name (G_TYPE_FROM_INSTANCE (object)), "' for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		}
		value->data[0].v_pointer = retro_module_iterator_ref (object);
	} else {
		value->data[0].v_pointer = NULL;
	}
	return NULL;
}


static gchar* retro_value_module_iterator_lcopy_value (const GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) {
	RetroModuleIterator ** object_p;
	object_p = collect_values[0].v_pointer;
	if (!object_p) {
		return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
	}
	if (!value->data[0].v_pointer) {
		*object_p = NULL;
	} else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) {
		*object_p = value->data[0].v_pointer;
	} else {
		*object_p = retro_module_iterator_ref (value->data[0].v_pointer);
	}
	return NULL;
}


GParamSpec* retro_param_spec_module_iterator (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags) {
	RetroParamSpecModuleIterator* spec;
	g_return_val_if_fail (g_type_is_a (object_type, RETRO_TYPE_MODULE_ITERATOR), NULL);
	spec = g_param_spec_internal (G_TYPE_PARAM_OBJECT, name, nick, blurb, flags);
	G_PARAM_SPEC (spec)->value_type = object_type;
	return G_PARAM_SPEC (spec);
}


gpointer retro_value_get_module_iterator (const GValue* value) {
	g_return_val_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, RETRO_TYPE_MODULE_ITERATOR), NULL);
	return value->data[0].v_pointer;
}


void retro_value_set_module_iterator (GValue* value, gpointer v_object) {
	RetroModuleIterator * old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, RETRO_TYPE_MODULE_ITERATOR));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, RETRO_TYPE_MODULE_ITERATOR));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
		retro_module_iterator_ref (value->data[0].v_pointer);
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		retro_module_iterator_unref (old);
	}
}


void retro_value_take_module_iterator (GValue* value, gpointer v_object) {
	RetroModuleIterator * old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, RETRO_TYPE_MODULE_ITERATOR));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, RETRO_TYPE_MODULE_ITERATOR));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		retro_module_iterator_unref (old);
	}
}


static void retro_module_iterator_class_init (RetroModuleIteratorClass * klass) {
	retro_module_iterator_parent_class = g_type_class_peek_parent (klass);
	((RetroModuleIteratorClass *) klass)->finalize = retro_module_iterator_finalize;
	g_type_class_add_private (klass, sizeof (RetroModuleIteratorPrivate));
}


static void retro_module_iterator_instance_init (RetroModuleIterator * self) {
	self->priv = RETRO_MODULE_ITERATOR_GET_PRIVATE (self);
	self->ref_count = 1;
}


static void retro_module_iterator_finalize (RetroModuleIterator * obj) {
	RetroModuleIterator * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, RETRO_TYPE_MODULE_ITERATOR, RetroModuleIterator);
	g_signal_handlers_destroy (self);
	self->priv->directories = (_vala_array_free (self->priv->directories, self->priv->directories_length1, (GDestroyNotify) g_free), NULL);
	_g_object_unref0 (self->priv->file_enumerator);
	_g_object_unref0 (self->priv->core_descriptor);
	_retro_module_iterator_unref0 (self->priv->sub_directory);
	_g_hash_table_unref0 (self->priv->visited);
}


GType retro_module_iterator_get_type (void) {
	static volatile gsize retro_module_iterator_type_id__volatile = 0;
	if (g_once_init_enter (&retro_module_iterator_type_id__volatile)) {
		static const GTypeValueTable g_define_type_value_table = { retro_value_module_iterator_init, retro_value_module_iterator_free_value, retro_value_module_iterator_copy_value, retro_value_module_iterator_peek_pointer, "p", retro_value_module_iterator_collect_value, "p", retro_value_module_iterator_lcopy_value };
		static const GTypeInfo g_define_type_info = { sizeof (RetroModuleIteratorClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) retro_module_iterator_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RetroModuleIterator), 0, (GInstanceInitFunc) retro_module_iterator_instance_init, &g_define_type_value_table };
		static const GTypeFundamentalInfo g_define_type_fundamental_info = { (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) };
		GType retro_module_iterator_type_id;
		retro_module_iterator_type_id = g_type_register_fundamental (g_type_fundamental_next (), "RetroModuleIterator", &g_define_type_info, &g_define_type_fundamental_info, 0);
		g_once_init_leave (&retro_module_iterator_type_id__volatile, retro_module_iterator_type_id);
	}
	return retro_module_iterator_type_id__volatile;
}


gpointer retro_module_iterator_ref (gpointer instance) {
	RetroModuleIterator * self;
	self = instance;
	g_atomic_int_inc (&self->ref_count);
	return instance;
}


void retro_module_iterator_unref (gpointer instance) {
	RetroModuleIterator * self;
	self = instance;
	if (g_atomic_int_dec_and_test (&self->ref_count)) {
		RETRO_MODULE_ITERATOR_GET_CLASS (self)->finalize (self);
		g_type_free_instance ((GTypeInstance *) self);
	}
}


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



