/* gamepad-mappings-manager.c generated by valac 0.35.5, the Vala compiler
 * generated from gamepad-mappings-manager.vala, do not modify */

/* This file is part of GNOME Games. License: GPLv3*/

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


#define GAMES_TYPE_GAMEPAD_MAPPINGS_MANAGER (games_gamepad_mappings_manager_get_type ())
#define GAMES_GAMEPAD_MAPPINGS_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAMES_TYPE_GAMEPAD_MAPPINGS_MANAGER, GamesGamepadMappingsManager))
#define GAMES_GAMEPAD_MAPPINGS_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAMES_TYPE_GAMEPAD_MAPPINGS_MANAGER, GamesGamepadMappingsManagerClass))
#define GAMES_IS_GAMEPAD_MAPPINGS_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAMES_TYPE_GAMEPAD_MAPPINGS_MANAGER))
#define GAMES_IS_GAMEPAD_MAPPINGS_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAMES_TYPE_GAMEPAD_MAPPINGS_MANAGER))
#define GAMES_GAMEPAD_MAPPINGS_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAMES_TYPE_GAMEPAD_MAPPINGS_MANAGER, GamesGamepadMappingsManagerClass))

typedef struct _GamesGamepadMappingsManager GamesGamepadMappingsManager;
typedef struct _GamesGamepadMappingsManagerClass GamesGamepadMappingsManagerClass;
typedef struct _GamesGamepadMappingsManagerPrivate GamesGamepadMappingsManagerPrivate;
#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_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _g_free0(var) (var = (g_free (var), NULL))

struct _GamesGamepadMappingsManager {
	GObject parent_instance;
	GamesGamepadMappingsManagerPrivate * priv;
};

struct _GamesGamepadMappingsManagerClass {
	GObjectClass parent_class;
};

struct _GamesGamepadMappingsManagerPrivate {
	GHashTable* names;
	GHashTable* mappings;
};


static gpointer games_gamepad_mappings_manager_parent_class = NULL;
static GamesGamepadMappingsManager* games_gamepad_mappings_manager_instance;
static GamesGamepadMappingsManager* games_gamepad_mappings_manager_instance = NULL;

GType games_gamepad_mappings_manager_get_type (void) G_GNUC_CONST;
#define GAMES_GAMEPAD_MAPPINGS_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GAMES_TYPE_GAMEPAD_MAPPINGS_MANAGER, GamesGamepadMappingsManagerPrivate))
enum  {
	GAMES_GAMEPAD_MAPPINGS_MANAGER_DUMMY_PROPERTY
};
#define GAMES_GAMEPAD_MAPPINGS_MANAGER_MAPPINGS_FILE_NAME "gamecontrollerdb.txt"
static GamesGamepadMappingsManager* games_gamepad_mappings_manager_new (void);
static GamesGamepadMappingsManager* games_gamepad_mappings_manager_construct (GType object_type);
static void _g_free0_ (gpointer var);
void games_gamepad_mappings_manager_add_from_resource (GamesGamepadMappingsManager* self, const gchar* path, GError** error);
gchar* games_application_get_config_dir (void);
void games_gamepad_mappings_manager_add_from_file (GamesGamepadMappingsManager* self, const gchar* file_name, GError** error);
GamesGamepadMappingsManager* games_gamepad_mappings_manager_get_instance (void);
void games_gamepad_mappings_manager_add_from_input_stream (GamesGamepadMappingsManager* self, GInputStream* input_stream, GError** error);
void games_gamepad_mappings_manager_add_mapping (GamesGamepadMappingsManager* self, const gchar* mapping_string);
gchar* games_gamepad_mappings_manager_get_mapping (GamesGamepadMappingsManager* self, const gchar* guid);
static void games_gamepad_mappings_manager_finalize (GObject * 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 gint _vala_array_length (gpointer array);


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


static const gchar* string_to_string (const gchar* self) {
	const gchar* result = NULL;
	g_return_val_if_fail (self != NULL, NULL);
	result = self;
	return result;
}


static GamesGamepadMappingsManager* games_gamepad_mappings_manager_construct (GType object_type) {
	GamesGamepadMappingsManager * self = NULL;
	GHashTable* _tmp0_;
	GHashTable* _tmp4_;
	GError * _inner_error_ = NULL;
	self = (GamesGamepadMappingsManager*) g_object_new (object_type, NULL);
	_tmp0_ = self->priv->names;
	if (_tmp0_ == NULL) {
		GHashFunc _tmp1_;
		GEqualFunc _tmp2_;
		GHashTable* _tmp3_;
		_tmp1_ = g_str_hash;
		_tmp2_ = g_str_equal;
		_tmp3_ = g_hash_table_new_full (_tmp1_, _tmp2_, _g_free0_, _g_free0_);
		_g_hash_table_unref0 (self->priv->names);
		self->priv->names = _tmp3_;
	}
	_tmp4_ = self->priv->mappings;
	if (_tmp4_ == NULL) {
		GHashFunc _tmp5_;
		GEqualFunc _tmp6_;
		GHashTable* _tmp7_;
		_tmp5_ = g_str_hash;
		_tmp6_ = g_str_equal;
		_tmp7_ = g_hash_table_new_full (_tmp5_, _tmp6_, _g_free0_, _g_free0_);
		_g_hash_table_unref0 (self->priv->mappings);
		self->priv->mappings = _tmp7_;
	}
	{
		games_gamepad_mappings_manager_add_from_resource (self, "/org/gnome/Games/gamepads/gamecontrollerdb.txt", &_inner_error_);
		if (G_UNLIKELY (_inner_error_ != NULL)) {
			goto __catch5_g_error;
		}
	}
	goto __finally5;
	__catch5_g_error:
	{
		GError* e = NULL;
		GError* _tmp8_;
		const gchar* _tmp9_;
		e = _inner_error_;
		_inner_error_ = NULL;
		_tmp8_ = e;
		_tmp9_ = _tmp8_->message;
		g_warning ("gamepad-mappings-manager.vala:25: GamepadMappingsManager: Can’t find g" \
"amecontrollerdb.txt: %s", _tmp9_);
		_g_error_free0 (e);
	}
	__finally5:
	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;
	}
	{
		gchar* dir;
		gchar* _tmp10_;
		gchar* path;
		const gchar* _tmp11_;
		const gchar* _tmp12_;
		const gchar* _tmp13_;
		gchar* _tmp14_;
		GFile* file;
		const gchar* _tmp15_;
		GFile* _tmp16_;
		GFile* _tmp17_;
		gboolean _tmp18_;
		_tmp10_ = games_application_get_config_dir ();
		dir = _tmp10_;
		_tmp11_ = dir;
		_tmp12_ = string_to_string (_tmp11_);
		_tmp13_ = string_to_string (GAMES_GAMEPAD_MAPPINGS_MANAGER_MAPPINGS_FILE_NAME);
		_tmp14_ = g_strconcat (_tmp12_, "/", _tmp13_, NULL);
		path = _tmp14_;
		_tmp15_ = path;
		_tmp16_ = g_file_new_for_path (_tmp15_);
		file = _tmp16_;
		_tmp17_ = file;
		_tmp18_ = g_file_query_exists (_tmp17_, NULL);
		if (_tmp18_) {
			const gchar* _tmp19_;
			_tmp19_ = path;
			games_gamepad_mappings_manager_add_from_file (self, _tmp19_, &_inner_error_);
			if (G_UNLIKELY (_inner_error_ != NULL)) {
				_g_object_unref0 (file);
				_g_free0 (path);
				_g_free0 (dir);
				goto __catch6_g_error;
			}
		}
		_g_object_unref0 (file);
		_g_free0 (path);
		_g_free0 (dir);
	}
	goto __finally6;
	__catch6_g_error:
	{
		GError* e = NULL;
		GError* _tmp20_;
		const gchar* _tmp21_;
		e = _inner_error_;
		_inner_error_ = NULL;
		_tmp20_ = e;
		_tmp21_ = _tmp20_->message;
		g_warning ("gamepad-mappings-manager.vala:35: GamepadMappingsManager: Can’t add fr" \
"om user’s config dir’s %s: %s", GAMES_GAMEPAD_MAPPINGS_MANAGER_MAPPINGS_FILE_NAME, _tmp21_);
		_g_error_free0 (e);
	}
	__finally6:
	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;
}


static GamesGamepadMappingsManager* games_gamepad_mappings_manager_new (void) {
	return games_gamepad_mappings_manager_construct (GAMES_TYPE_GAMEPAD_MAPPINGS_MANAGER);
}


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


GamesGamepadMappingsManager* games_gamepad_mappings_manager_get_instance (void) {
	GamesGamepadMappingsManager* result = NULL;
	GamesGamepadMappingsManager* _tmp0_;
	GamesGamepadMappingsManager* _tmp2_;
	GamesGamepadMappingsManager* _tmp3_;
	_tmp0_ = games_gamepad_mappings_manager_instance;
	if (_tmp0_ == NULL) {
		GamesGamepadMappingsManager* _tmp1_;
		_tmp1_ = games_gamepad_mappings_manager_new ();
		_g_object_unref0 (games_gamepad_mappings_manager_instance);
		games_gamepad_mappings_manager_instance = _tmp1_;
	}
	_tmp2_ = games_gamepad_mappings_manager_instance;
	_tmp3_ = _g_object_ref0 (_tmp2_);
	result = _tmp3_;
	return result;
}


void games_gamepad_mappings_manager_add_from_resource (GamesGamepadMappingsManager* self, const gchar* path, GError** error) {
	GInputStream* _tmp0_;
	const gchar* _tmp1_;
	GInputStream* _tmp2_;
	GError * _inner_error_ = NULL;
	g_return_if_fail (self != NULL);
	g_return_if_fail (path != NULL);
	_tmp1_ = path;
	_tmp2_ = g_resources_open_stream (_tmp1_, G_RESOURCE_LOOKUP_FLAGS_NONE, &_inner_error_);
	_tmp0_ = _tmp2_;
	if (G_UNLIKELY (_inner_error_ != NULL)) {
		g_propagate_error (error, _inner_error_);
		return;
	}
	games_gamepad_mappings_manager_add_from_input_stream (self, _tmp0_, &_inner_error_);
	if (G_UNLIKELY (_inner_error_ != NULL)) {
		g_propagate_error (error, _inner_error_);
		_g_object_unref0 (_tmp0_);
		return;
	}
	_g_object_unref0 (_tmp0_);
}


void games_gamepad_mappings_manager_add_from_file (GamesGamepadMappingsManager* self, const gchar* file_name, GError** error) {
	GFile* file;
	const gchar* _tmp0_;
	GFile* _tmp1_;
	GFileInputStream* _tmp2_;
	GFile* _tmp3_;
	GFileInputStream* _tmp4_;
	GError * _inner_error_ = NULL;
	g_return_if_fail (self != NULL);
	g_return_if_fail (file_name != NULL);
	_tmp0_ = file_name;
	_tmp1_ = g_file_new_for_path (_tmp0_);
	file = _tmp1_;
	_tmp3_ = file;
	_tmp4_ = g_file_read (_tmp3_, NULL, &_inner_error_);
	_tmp2_ = _tmp4_;
	if (G_UNLIKELY (_inner_error_ != NULL)) {
		g_propagate_error (error, _inner_error_);
		_g_object_unref0 (file);
		return;
	}
	games_gamepad_mappings_manager_add_from_input_stream (self, (GInputStream*) _tmp2_, &_inner_error_);
	if (G_UNLIKELY (_inner_error_ != NULL)) {
		g_propagate_error (error, _inner_error_);
		_g_object_unref0 (_tmp2_);
		_g_object_unref0 (file);
		return;
	}
	_g_object_unref0 (_tmp2_);
	_g_object_unref0 (file);
}


void games_gamepad_mappings_manager_add_from_input_stream (GamesGamepadMappingsManager* self, GInputStream* input_stream, GError** error) {
	GDataInputStream* data_stream;
	GInputStream* _tmp0_;
	GDataInputStream* _tmp1_;
	gchar* mapping_string;
	GDataInputStream* _tmp2_;
	gchar* _tmp3_;
	GError * _inner_error_ = NULL;
	g_return_if_fail (self != NULL);
	g_return_if_fail (input_stream != NULL);
	_tmp0_ = input_stream;
	_tmp1_ = g_data_input_stream_new (_tmp0_);
	data_stream = _tmp1_;
	_tmp2_ = data_stream;
	_tmp3_ = g_data_input_stream_read_line (_tmp2_, NULL, NULL, &_inner_error_);
	mapping_string = _tmp3_;
	if (G_UNLIKELY (_inner_error_ != NULL)) {
		if (_inner_error_->domain == G_IO_ERROR) {
			g_propagate_error (error, _inner_error_);
			_g_object_unref0 (data_stream);
			return;
		} else {
			_g_object_unref0 (data_stream);
			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;
		}
	}
	while (TRUE) {
		const gchar* _tmp4_;
		const gchar* _tmp5_;
		gchar* _tmp6_;
		GDataInputStream* _tmp7_;
		gchar* _tmp8_;
		gchar* _tmp9_;
		_tmp4_ = mapping_string;
		if (!(_tmp4_ != NULL)) {
			break;
		}
		_tmp5_ = mapping_string;
		games_gamepad_mappings_manager_add_mapping (self, _tmp5_);
		_tmp7_ = data_stream;
		_tmp8_ = g_data_input_stream_read_line (_tmp7_, NULL, NULL, &_inner_error_);
		_tmp6_ = _tmp8_;
		if (G_UNLIKELY (_inner_error_ != NULL)) {
			if (_inner_error_->domain == G_IO_ERROR) {
				g_propagate_error (error, _inner_error_);
				_g_free0 (mapping_string);
				_g_object_unref0 (data_stream);
				return;
			} else {
				_g_free0 (mapping_string);
				_g_object_unref0 (data_stream);
				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;
			}
		}
		_tmp9_ = _tmp6_;
		_tmp6_ = NULL;
		_g_free0 (mapping_string);
		mapping_string = _tmp9_;
		_g_free0 (_tmp6_);
	}
	_g_free0 (mapping_string);
	_g_object_unref0 (data_stream);
}


/**
 * Adds a mapping from a SDL2 mapping string (only one gamepad)
 */
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;
}


static gint string_index_of (const gchar* self, const gchar* needle, gint start_index) {
	gint result = 0;
	gchar* _result_;
	gint _tmp0_;
	const gchar* _tmp1_;
	gchar* _tmp2_;
	gchar* _tmp3_;
	g_return_val_if_fail (self != NULL, 0);
	g_return_val_if_fail (needle != NULL, 0);
	_tmp0_ = start_index;
	_tmp1_ = needle;
	_tmp2_ = strstr (((gchar*) self) + _tmp0_, (gchar*) _tmp1_);
	_result_ = _tmp2_;
	_tmp3_ = _result_;
	if (_tmp3_ != NULL) {
		gchar* _tmp4_;
		_tmp4_ = _result_;
		result = (gint) (_tmp4_ - ((gchar*) self));
		return result;
	} else {
		result = -1;
		return result;
	}
}


void games_gamepad_mappings_manager_add_mapping (GamesGamepadMappingsManager* self, const gchar* mapping_string) {
	gboolean _tmp0_ = FALSE;
	const gchar* _tmp1_;
	gboolean _tmp4_ = FALSE;
	const gchar* _tmp5_;
	gint _tmp6_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (mapping_string != NULL);
	_tmp1_ = mapping_string;
	if (g_strcmp0 (_tmp1_, "") == 0) {
		_tmp0_ = TRUE;
	} else {
		const gchar* _tmp2_;
		gchar _tmp3_;
		_tmp2_ = mapping_string;
		_tmp3_ = string_get (_tmp2_, (glong) 0);
		_tmp0_ = _tmp3_ == '#';
	}
	if (_tmp0_) {
		return;
	}
	_tmp5_ = mapping_string;
	_tmp6_ = string_index_of (_tmp5_, "platform", 0);
	if (_tmp6_ == -1) {
		_tmp4_ = TRUE;
	} else {
		const gchar* _tmp7_;
		gint _tmp8_;
		_tmp7_ = mapping_string;
		_tmp8_ = string_index_of (_tmp7_, "platform:Linux", 0);
		_tmp4_ = _tmp8_ != -1;
	}
	if (_tmp4_) {
		gchar** split;
		const gchar* _tmp9_;
		gchar** _tmp10_;
		gchar** _tmp11_;
		gint split_length1;
		gint _split_size_;
		GHashTable* _tmp12_;
		gchar** _tmp13_;
		gint _tmp13__length1;
		const gchar* _tmp14_;
		gchar* _tmp15_;
		gchar** _tmp16_;
		gint _tmp16__length1;
		const gchar* _tmp17_;
		gchar* _tmp18_;
		GHashTable* _tmp19_;
		gchar** _tmp20_;
		gint _tmp20__length1;
		const gchar* _tmp21_;
		gchar* _tmp22_;
		gchar** _tmp23_;
		gint _tmp23__length1;
		const gchar* _tmp24_;
		gchar* _tmp25_;
		_tmp9_ = mapping_string;
		_tmp11_ = _tmp10_ = g_strsplit (_tmp9_, ",", 3);
		split = _tmp11_;
		split_length1 = _vala_array_length (_tmp10_);
		_split_size_ = split_length1;
		_tmp12_ = self->priv->names;
		_tmp13_ = split;
		_tmp13__length1 = split_length1;
		_tmp14_ = _tmp13_[0];
		_tmp15_ = g_strdup (_tmp14_);
		_tmp16_ = split;
		_tmp16__length1 = split_length1;
		_tmp17_ = _tmp16_[1];
		_tmp18_ = g_strdup (_tmp17_);
		g_hash_table_insert (_tmp12_, _tmp15_, _tmp18_);
		_tmp19_ = self->priv->mappings;
		_tmp20_ = split;
		_tmp20__length1 = split_length1;
		_tmp21_ = _tmp20_[0];
		_tmp22_ = g_strdup (_tmp21_);
		_tmp23_ = split;
		_tmp23__length1 = split_length1;
		_tmp24_ = _tmp23_[2];
		_tmp25_ = g_strdup (_tmp24_);
		g_hash_table_insert (_tmp19_, _tmp22_, _tmp25_);
		split = (_vala_array_free (split, split_length1, (GDestroyNotify) g_free), NULL);
	}
}


/**
 * Gets the current mapping from the databse
 * @param  guid          The guid of the wanted gamepad
 * @return The mapping if present in the database
 */
gchar* games_gamepad_mappings_manager_get_mapping (GamesGamepadMappingsManager* self, const gchar* guid) {
	gchar* result = NULL;
	GHashTable* _tmp0_;
	const gchar* _tmp1_;
	gconstpointer _tmp2_;
	gchar* _tmp3_;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (guid != NULL, NULL);
	_tmp0_ = self->priv->mappings;
	_tmp1_ = guid;
	_tmp2_ = g_hash_table_lookup (_tmp0_, _tmp1_);
	_tmp3_ = g_strdup ((const gchar*) _tmp2_);
	result = _tmp3_;
	return result;
}


static void games_gamepad_mappings_manager_class_init (GamesGamepadMappingsManagerClass * klass) {
	games_gamepad_mappings_manager_parent_class = g_type_class_peek_parent (klass);
	g_type_class_add_private (klass, sizeof (GamesGamepadMappingsManagerPrivate));
	G_OBJECT_CLASS (klass)->finalize = games_gamepad_mappings_manager_finalize;
}


static void games_gamepad_mappings_manager_instance_init (GamesGamepadMappingsManager * self) {
	self->priv = GAMES_GAMEPAD_MAPPINGS_MANAGER_GET_PRIVATE (self);
}


static void games_gamepad_mappings_manager_finalize (GObject * obj) {
	GamesGamepadMappingsManager * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, GAMES_TYPE_GAMEPAD_MAPPINGS_MANAGER, GamesGamepadMappingsManager);
	_g_hash_table_unref0 (self->priv->names);
	_g_hash_table_unref0 (self->priv->mappings);
	G_OBJECT_CLASS (games_gamepad_mappings_manager_parent_class)->finalize (obj);
}


/**
 * This class gives methods to set/update the mappings
 *
 * The client interfaces with this class primarily
 */
GType games_gamepad_mappings_manager_get_type (void) {
	static volatile gsize games_gamepad_mappings_manager_type_id__volatile = 0;
	if (g_once_init_enter (&games_gamepad_mappings_manager_type_id__volatile)) {
		static const GTypeInfo g_define_type_info = { sizeof (GamesGamepadMappingsManagerClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) games_gamepad_mappings_manager_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (GamesGamepadMappingsManager), 0, (GInstanceInitFunc) games_gamepad_mappings_manager_instance_init, NULL };
		GType games_gamepad_mappings_manager_type_id;
		games_gamepad_mappings_manager_type_id = g_type_register_static (G_TYPE_OBJECT, "GamesGamepadMappingsManager", &g_define_type_info, 0);
		g_once_init_leave (&games_gamepad_mappings_manager_type_id__volatile, games_gamepad_mappings_manager_type_id);
	}
	return games_gamepad_mappings_manager_type_id__volatile;
}


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


static gint _vala_array_length (gpointer array) {
	int length;
	length = 0;
	if (array) {
		while (((gpointer*) array)[length]) {
			length++;
		}
	}
	return length;
}



