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

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

#if !defined(VALA_STRICT_C)
#if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ >= 14)
#pragma GCC diagnostic warning "-Wincompatible-pointer-types"
#elif defined(__clang__) && (__clang_major__ >= 16)
#pragma clang diagnostic ignored "-Wincompatible-function-pointer-types"
#pragma clang diagnostic ignored "-Wincompatible-pointer-types"
#endif
#endif
#if !defined(VALA_EXTERN)
#if defined(_MSC_VER)
#define VALA_EXTERN __declspec(dllexport) extern
#elif __GNUC__ >= 4
#define VALA_EXTERN __attribute__((visibility("default"))) extern
#else
#define VALA_EXTERN extern
#endif
#endif

#define G4_TYPE_TAG_CACHE (g4_tag_cache_get_type ())
#define G4_TAG_CACHE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G4_TYPE_TAG_CACHE, G4TagCache))
#define G4_TAG_CACHE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), G4_TYPE_TAG_CACHE, G4TagCacheClass))
#define G4_IS_TAG_CACHE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G4_TYPE_TAG_CACHE))
#define G4_IS_TAG_CACHE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), G4_TYPE_TAG_CACHE))
#define G4_TAG_CACHE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), G4_TYPE_TAG_CACHE, G4TagCacheClass))

typedef struct _G4TagCache G4TagCache;
typedef struct _G4TagCacheClass G4TagCacheClass;
typedef struct _G4TagCachePrivate G4TagCachePrivate;

#define G4_TYPE_EVENT (g4_event_get_type ())
#define G4_EVENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G4_TYPE_EVENT, G4Event))
#define G4_EVENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), G4_TYPE_EVENT, G4EventClass))
#define G4_IS_EVENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G4_TYPE_EVENT))
#define G4_IS_EVENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), G4_TYPE_EVENT))
#define G4_EVENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), G4_TYPE_EVENT, G4EventClass))

typedef struct _G4Event G4Event;
typedef struct _G4EventClass G4EventClass;

#define G4_TYPE_MUSIC (g4_music_get_type ())
#define G4_MUSIC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G4_TYPE_MUSIC, G4Music))
#define G4_MUSIC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), G4_TYPE_MUSIC, G4MusicClass))
#define G4_IS_MUSIC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G4_TYPE_MUSIC))
#define G4_IS_MUSIC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), G4_TYPE_MUSIC))
#define G4_MUSIC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), G4_TYPE_MUSIC, G4MusicClass))

typedef struct _G4Music G4Music;
typedef struct _G4MusicClass G4MusicClass;
#define _g4_event_unref0(var) ((var == NULL) ? NULL : (var = (g4_event_unref (var), NULL)))
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _g_hash_table_unref0(var) ((var == NULL) ? NULL : (var = (g_hash_table_unref (var), NULL)))
#define _g_free0(var) (var = (g_free (var), NULL))
typedef struct _G4MusicPrivate G4MusicPrivate;

#define G4_TYPE_DATA_INPUT_BYTES (g4_data_input_bytes_get_type ())
#define G4_DATA_INPUT_BYTES(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G4_TYPE_DATA_INPUT_BYTES, G4DataInputBytes))
#define G4_DATA_INPUT_BYTES_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), G4_TYPE_DATA_INPUT_BYTES, G4DataInputBytesClass))
#define G4_IS_DATA_INPUT_BYTES(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G4_TYPE_DATA_INPUT_BYTES))
#define G4_IS_DATA_INPUT_BYTES_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), G4_TYPE_DATA_INPUT_BYTES))
#define G4_DATA_INPUT_BYTES_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), G4_TYPE_DATA_INPUT_BYTES, G4DataInputBytesClass))

typedef struct _G4DataInputBytes G4DataInputBytes;
typedef struct _G4DataInputBytesClass G4DataInputBytesClass;
#define _g_bytes_unref0(var) ((var == NULL) ? NULL : (var = (g_bytes_unref (var), NULL)))
#define _g_mapped_file_unref0(var) ((var == NULL) ? NULL : (var = (g_mapped_file_unref (var), NULL)))
#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))

#define G4_TYPE_DATA_OUTPUT_BYTES (g4_data_output_bytes_get_type ())
#define G4_DATA_OUTPUT_BYTES(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G4_TYPE_DATA_OUTPUT_BYTES, G4DataOutputBytes))
#define G4_DATA_OUTPUT_BYTES_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), G4_TYPE_DATA_OUTPUT_BYTES, G4DataOutputBytesClass))
#define G4_IS_DATA_OUTPUT_BYTES(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G4_TYPE_DATA_OUTPUT_BYTES))
#define G4_IS_DATA_OUTPUT_BYTES_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), G4_TYPE_DATA_OUTPUT_BYTES))
#define G4_DATA_OUTPUT_BYTES_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), G4_TYPE_DATA_OUTPUT_BYTES, G4DataOutputBytesClass))

typedef struct _G4DataOutputBytes G4DataOutputBytes;
typedef struct _G4DataOutputBytesClass G4DataOutputBytesClass;
typedef struct _Block66Data Block66Data;
#define _g4_tag_cache_unref0(var) ((var == NULL) ? NULL : (var = (g4_tag_cache_unref (var), NULL)))
typedef struct _G4ParamSpecTagCache G4ParamSpecTagCache;

struct _G4TagCache {
	GTypeInstance parent_instance;
	volatile int ref_count;
	G4TagCachePrivate * priv;
};

struct _G4TagCacheClass {
	GTypeClass parent_class;
	void (*finalize) (G4TagCache *self);
};

struct _G4TagCachePrivate {
	G4Event* _event;
	GFile* _file;
	gboolean _modified;
	GHashTable* _cache;
	GRecMutex __lock__cache;
};

struct _G4Music {
	GObject parent_instance;
	G4MusicPrivate * priv;
	gchar* album;
	gchar* artist;
	gchar* title;
	gchar* album_artist;
	guint32 date;
	gchar* genre;
	gint track;
	gint disc;
	gboolean has_cover;
	gint64 modified_time;
	gchar* uri;
	gchar* cover_uri;
	gchar* _album_key;
	gchar* _artist_key;
	gchar* _title_key;
	gint _order;
};

struct _G4MusicClass {
	GObjectClass parent_class;
	gchar* (*get_abbreviation) (G4Music* self);
};

struct _Block66Data {
	int _ref_count_;
	G4TagCache* self;
	G4DataOutputBytes* dos;
};

struct _G4ParamSpecTagCache {
	GParamSpec parent_instance;
};

static gint G4TagCache_private_offset;
static gpointer g4_tag_cache_parent_class = NULL;
static guint32 g4_tag_cache_MAGIC;
static guint32 g4_tag_cache_MAGIC = (guint32) 0x54414733;

VALA_EXTERN gpointer g4_tag_cache_ref (gpointer instance);
VALA_EXTERN void g4_tag_cache_unref (gpointer instance);
VALA_EXTERN GParamSpec* g4_param_spec_tag_cache (const gchar* name,
                                     const gchar* nick,
                                     const gchar* blurb,
                                     GType object_type,
                                     GParamFlags flags);
VALA_EXTERN void g4_value_set_tag_cache (GValue* value,
                             gpointer v_object);
VALA_EXTERN void g4_value_take_tag_cache (GValue* value,
                              gpointer v_object);
VALA_EXTERN gpointer g4_value_get_tag_cache (const GValue* value);
VALA_EXTERN GType g4_tag_cache_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (G4TagCache, g4_tag_cache_unref)
VALA_EXTERN gpointer g4_event_ref (gpointer instance);
VALA_EXTERN void g4_event_unref (gpointer instance);
VALA_EXTERN GParamSpec* g4_param_spec_event (const gchar* name,
                                 const gchar* nick,
                                 const gchar* blurb,
                                 GType object_type,
                                 GParamFlags flags);
VALA_EXTERN void g4_value_set_event (GValue* value,
                         gpointer v_object);
VALA_EXTERN void g4_value_take_event (GValue* value,
                          gpointer v_object);
VALA_EXTERN gpointer g4_value_get_event (const GValue* value);
VALA_EXTERN GType g4_event_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (G4Event, g4_event_unref)
VALA_EXTERN GType g4_music_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (G4Music, g_object_unref)
VALA_EXTERN G4Event* g4_event_new (void);
VALA_EXTERN G4Event* g4_event_construct (GType object_type);
static void _g_object_unref0_ (gpointer var);
VALA_EXTERN G4TagCache* g4_tag_cache_new (const gchar* name);
VALA_EXTERN G4TagCache* g4_tag_cache_construct (GType object_type,
                                    const gchar* name);
VALA_EXTERN G4Music* g4_tag_cache_get (G4TagCache* self,
                           const gchar* uri);
VALA_EXTERN void g4_tag_cache_add (G4TagCache* self,
                       G4Music* music);
VALA_EXTERN G4Music* g4_tag_cache_remove (G4TagCache* self,
                              const gchar* uri);
VALA_EXTERN void g4_tag_cache_load (G4TagCache* self);
VALA_EXTERN void g4_event_reset (G4Event* self);
VALA_EXTERN GType g4_data_input_bytes_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (G4DataInputBytes, g_object_unref)
VALA_EXTERN G4DataInputBytes* g4_data_input_bytes_new (GBytes* bytes);
VALA_EXTERN G4DataInputBytes* g4_data_input_bytes_construct (GType object_type,
                                                 GBytes* bytes);
VALA_EXTERN guint32 g4_data_input_bytes_read_uint32 (G4DataInputBytes* self,
                                         GError** error);
VALA_EXTERN gsize g4_data_input_bytes_read_size (G4DataInputBytes* self,
                                     GError** error);
VALA_EXTERN G4Music* g4_music_new_deserialize (G4DataInputBytes* dis,
                                   GError** error);
VALA_EXTERN G4Music* g4_music_construct_deserialize (GType object_type,
                                         G4DataInputBytes* dis,
                                         GError** error);
VALA_EXTERN void g4_event_notify (G4Event* self);
VALA_EXTERN void g4_tag_cache_save (G4TagCache* self);
VALA_EXTERN GType g4_data_output_bytes_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (G4DataOutputBytes, g_object_unref)
static Block66Data* block66_data_ref (Block66Data* _data66_);
static void block66_data_unref (void * _userdata_);
static gboolean* _bool_dup (gboolean* self);
VALA_EXTERN G4DataOutputBytes* g4_data_output_bytes_new (guint reserved_size);
VALA_EXTERN G4DataOutputBytes* g4_data_output_bytes_construct (GType object_type,
                                                   guint reserved_size);
VALA_EXTERN void g4_data_output_bytes_write_uint32 (G4DataOutputBytes* self,
                                        guint32 n);
VALA_EXTERN void g4_data_output_bytes_write_size (G4DataOutputBytes* self,
                                      gsize n);
static void ____lambda22_ (Block66Data* _data66_,
                    const gchar* key,
                    G4Music* music);
VALA_EXTERN void g4_music_serialize (G4Music* self,
                         G4DataOutputBytes* dos,
                         GError** error);
static void _____lambda22__gh_func (gconstpointer key,
                             gconstpointer value,
                             gpointer self);
VALA_EXTERN gboolean g4_data_output_bytes_write_to (G4DataOutputBytes* self,
                                        GOutputStream* stream,
                                        GError** error);
VALA_EXTERN void g4_tag_cache_wait_loading (G4TagCache* self);
VALA_EXTERN void g4_event_wait (G4Event* self);
VALA_EXTERN gboolean g4_tag_cache_get_modified (G4TagCache* self);
static void g4_tag_cache_finalize (G4TagCache * obj);
static GType g4_tag_cache_get_type_once (void);
static inline gpointer _vala_memdup2 (gconstpointer mem,
                        gsize byte_size);

static inline gpointer
g4_tag_cache_get_instance_private (G4TagCache* self)
{
	return G_STRUCT_MEMBER_P (self, G4TagCache_private_offset);
}

static void
_g_object_unref0_ (gpointer var)
{
	(var == NULL) ? NULL : (var = (g_object_unref (var), NULL));
}

G4TagCache*
g4_tag_cache_construct (GType object_type,
                        const gchar* name)
{
	G4TagCache* self = NULL;
	gchar* dir = NULL;
	const gchar* _tmp0_;
	gchar* _tmp1_;
	GFile* _tmp2_;
	g_return_val_if_fail (name != NULL, NULL);
	self = (G4TagCache*) g_type_create_instance (object_type);
	_tmp0_ = g_get_user_cache_dir ();
	_tmp1_ = g_strdup (_tmp0_);
	dir = _tmp1_;
	_tmp2_ = g_file_new_build_filename (dir, APP_ID, name, NULL);
	_g_object_unref0 (self->priv->_file);
	self->priv->_file = _tmp2_;
	_g_free0 (dir);
	return self;
}

G4TagCache*
g4_tag_cache_new (const gchar* name)
{
	return g4_tag_cache_construct (G4_TYPE_TAG_CACHE, name);
}

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

G4Music*
g4_tag_cache_get (G4TagCache* self,
                  const gchar* uri)
{
	const gchar* key = NULL;
	G4Music* music = NULL;
	GError* _inner_error0_ = NULL;
	G4Music* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (uri != NULL, NULL);
	{
		GHashTable* _tmp0_;
		_tmp0_ = self->priv->_cache;
		g_rec_mutex_lock (&self->priv->__lock__cache);
		{
			GHashTable* _tmp1_;
			gconstpointer _tmp2_ = NULL;
			gconstpointer _tmp3_ = NULL;
			gboolean _tmp4_;
			_tmp1_ = self->priv->_cache;
			_tmp4_ = g_hash_table_lookup_extended (_tmp1_, uri, &_tmp2_, &_tmp3_);
			key = (const gchar*) _tmp2_;
			music = (G4Music*) _tmp3_;
			if (_tmp4_) {
				G4Music* _tmp5_;
				G4Music* _tmp6_;
				_tmp5_ = music;
				_tmp6_ = _g_object_ref0 (_tmp5_);
				result = _tmp6_;
				{
					GHashTable* _tmp7_;
					_tmp7_ = self->priv->_cache;
					g_rec_mutex_unlock (&self->priv->__lock__cache);
				}
				return result;
			}
		}
		__finally0:
		{
			GHashTable* _tmp8_;
			_tmp8_ = self->priv->_cache;
			g_rec_mutex_unlock (&self->priv->__lock__cache);
		}
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
			g_clear_error (&_inner_error0_);
			return NULL;
		}
	}
	result = NULL;
	return result;
}

void
g4_tag_cache_add (G4TagCache* self,
                  G4Music* music)
{
	GError* _inner_error0_ = NULL;
	g_return_if_fail (self != NULL);
	g_return_if_fail (music != NULL);
	{
		GHashTable* _tmp0_;
		_tmp0_ = self->priv->_cache;
		g_rec_mutex_lock (&self->priv->__lock__cache);
		{
			GHashTable* _tmp1_;
			const gchar* _tmp2_;
			G4Music* _tmp3_;
			_tmp1_ = self->priv->_cache;
			_tmp2_ = music->uri;
			_tmp3_ = _g_object_ref0 (music);
			g_hash_table_insert (_tmp1_, _tmp2_, _tmp3_);
			self->priv->_modified = TRUE;
		}
		__finally0:
		{
			GHashTable* _tmp4_;
			_tmp4_ = self->priv->_cache;
			g_rec_mutex_unlock (&self->priv->__lock__cache);
		}
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
			g_clear_error (&_inner_error0_);
			return;
		}
	}
}

G4Music*
g4_tag_cache_remove (G4TagCache* self,
                     const gchar* uri)
{
	gchar* key = NULL;
	G4Music* value = NULL;
	GError* _inner_error0_ = NULL;
	G4Music* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (uri != NULL, NULL);
	{
		GHashTable* _tmp0_;
		_tmp0_ = self->priv->_cache;
		g_rec_mutex_lock (&self->priv->__lock__cache);
		{
			GHashTable* _tmp1_;
			gpointer _tmp2_ = NULL;
			gpointer _tmp3_ = NULL;
			gboolean _tmp4_;
			gchar* _tmp5_;
			_tmp1_ = self->priv->_cache;
			_tmp4_ = g_hash_table_steal_extended (_tmp1_, uri, &_tmp2_, &_tmp3_);
			_g_free0 (key);
			_tmp5_ = g_strdup ((const gchar*) _tmp2_);
			key = _tmp5_;
			_g_object_unref0 (value);
			value = (G4Music*) _tmp3_;
			if (_tmp4_) {
				G4Music* _tmp6_;
				G4Music* _tmp7_;
				self->priv->_modified = TRUE;
				_tmp6_ = value;
				_tmp7_ = _g_object_ref0 (_tmp6_);
				result = _tmp7_;
				{
					GHashTable* _tmp8_;
					_tmp8_ = self->priv->_cache;
					g_rec_mutex_unlock (&self->priv->__lock__cache);
				}
				_g_object_unref0 (value);
				_g_free0 (key);
				return result;
			}
		}
		__finally0:
		{
			GHashTable* _tmp9_;
			_tmp9_ = self->priv->_cache;
			g_rec_mutex_unlock (&self->priv->__lock__cache);
		}
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			_g_object_unref0 (value);
			_g_free0 (key);
			g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
			g_clear_error (&_inner_error0_);
			return NULL;
		}
	}
	result = NULL;
	_g_object_unref0 (value);
	_g_free0 (key);
	return result;
}

void
g4_tag_cache_load (G4TagCache* self)
{
	G4Event* _tmp0_;
	G4Event* _tmp34_;
	GError* _inner_error0_ = NULL;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->_event;
	g4_event_reset (_tmp0_);
	{
		gchar* _tmp1_ = NULL;
		GFile* _tmp2_;
		gchar* _tmp3_;
		GMappedFile* mapped = NULL;
		GMappedFile* _tmp5_;
		G4DataInputBytes* dis = NULL;
		GMappedFile* _tmp6_;
		GBytes* _tmp7_;
		GBytes* _tmp8_;
		G4DataInputBytes* _tmp9_;
		G4DataInputBytes* _tmp10_;
		guint32 magic = 0U;
		G4DataInputBytes* _tmp11_;
		gsize count = 0UL;
		G4DataInputBytes* _tmp18_;
		_tmp2_ = self->priv->_file;
		_tmp3_ = g_file_get_path (_tmp2_);
		_tmp1_ = _tmp3_;
		if (_tmp1_ == NULL) {
			gchar* _tmp4_;
			_tmp4_ = g_strdup ("");
			_g_free0 (_tmp1_);
			_tmp1_ = _tmp4_;
		}
		_tmp5_ = g_mapped_file_new ((const gchar*) _tmp1_, FALSE, &_inner_error0_);
		mapped = _tmp5_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			_g_free0 (_tmp1_);
			goto __catch0_g_error;
		}
		_tmp6_ = mapped;
		_tmp7_ = g_mapped_file_get_bytes (_tmp6_);
		_tmp8_ = _tmp7_;
		_tmp9_ = g4_data_input_bytes_new (_tmp8_);
		_tmp10_ = _tmp9_;
		_g_bytes_unref0 (_tmp8_);
		dis = _tmp10_;
		_tmp11_ = dis;
		magic = g4_data_input_bytes_read_uint32 (_tmp11_, &_inner_error0_);
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			_g_object_unref0 (dis);
			_g_mapped_file_unref0 (mapped);
			_g_free0 (_tmp1_);
			goto __catch0_g_error;
		}
		if (magic != g4_tag_cache_MAGIC) {
			gchar* _tmp12_;
			gchar* _tmp13_;
			gchar* _tmp14_;
			gchar* _tmp15_;
			GError* _tmp16_;
			GError* _tmp17_;
			_tmp12_ = g_strdup_printf ("%u", magic);
			_tmp13_ = _tmp12_;
			_tmp14_ = g_strconcat ("Magic=", _tmp13_, NULL);
			_tmp15_ = _tmp14_;
			_tmp16_ = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_INVALID_DATA, _tmp15_);
			_tmp17_ = _tmp16_;
			_g_free0 (_tmp15_);
			_g_free0 (_tmp13_);
			_inner_error0_ = _tmp17_;
			_g_object_unref0 (dis);
			_g_mapped_file_unref0 (mapped);
			_g_free0 (_tmp1_);
			goto __catch0_g_error;
		}
		_tmp18_ = dis;
		count = g4_data_input_bytes_read_size (_tmp18_, &_inner_error0_);
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			_g_object_unref0 (dis);
			_g_mapped_file_unref0 (mapped);
			_g_free0 (_tmp1_);
			goto __catch0_g_error;
		}
		{
			GHashTable* _tmp19_;
			_tmp19_ = self->priv->_cache;
			g_rec_mutex_lock (&self->priv->__lock__cache);
			{
				{
					gint i = 0;
					i = 0;
					{
						gboolean _tmp20_ = FALSE;
						_tmp20_ = TRUE;
						while (TRUE) {
							G4Music* music = NULL;
							G4DataInputBytes* _tmp22_;
							G4Music* _tmp23_;
							GHashTable* _tmp24_;
							G4Music* _tmp25_;
							const gchar* _tmp26_;
							G4Music* _tmp27_;
							G4Music* _tmp28_;
							if (!_tmp20_) {
								gint _tmp21_;
								_tmp21_ = i;
								i = _tmp21_ + 1;
							}
							_tmp20_ = FALSE;
							if (!(((gsize) i) < count)) {
								break;
							}
							_tmp22_ = dis;
							_tmp23_ = g4_music_new_deserialize (_tmp22_, &_inner_error0_);
							music = _tmp23_;
							if (G_UNLIKELY (_inner_error0_ != NULL)) {
								goto __catch1_g_error;
							}
							_tmp24_ = self->priv->_cache;
							_tmp25_ = music;
							_tmp26_ = _tmp25_->uri;
							_tmp27_ = music;
							_tmp28_ = _g_object_ref0 (_tmp27_);
							g_hash_table_insert (_tmp24_, _tmp26_, _tmp28_);
							_g_object_unref0 (music);
						}
					}
				}
			}
			goto __finally1;
			__catch1_g_error:
			{
				GError* _lock_error_ = NULL;
				GError* _tmp29_;
				_lock_error_ = _inner_error0_;
				_inner_error0_ = NULL;
				_tmp29_ = _lock_error_;
				_lock_error_ = NULL;
				_inner_error0_ = _tmp29_;
				_g_error_free0 (_lock_error_);
				goto __finally1;
			}
			__finally1:
			{
				GError* _inner_error1_ = NULL;
				GHashTable* _tmp30_;
				_tmp30_ = self->priv->_cache;
				g_rec_mutex_unlock (&self->priv->__lock__cache);
			}
			if (G_UNLIKELY (_inner_error0_ != NULL)) {
				_g_object_unref0 (dis);
				_g_mapped_file_unref0 (mapped);
				_g_free0 (_tmp1_);
				goto __catch0_g_error;
			}
		}
		_g_object_unref0 (dis);
		_g_mapped_file_unref0 (mapped);
		_g_free0 (_tmp1_);
	}
	goto __finally0;
	__catch0_g_error:
	{
		GError* e = NULL;
		GError* _tmp31_;
		e = _inner_error0_;
		_inner_error0_ = NULL;
		_tmp31_ = e;
		if (_tmp31_->code != G_FILE_ERROR_NOENT) {
			GError* _tmp32_;
			const gchar* _tmp33_;
			_tmp32_ = e;
			_tmp33_ = _tmp32_->message;
			g_print ("Load tags error: %s\n", _tmp33_);
		}
		_g_error_free0 (e);
	}
	__finally0:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
		g_clear_error (&_inner_error0_);
		return;
	}
	_tmp34_ = self->priv->_event;
	g4_event_notify (_tmp34_);
}

static Block66Data*
block66_data_ref (Block66Data* _data66_)
{
	g_atomic_int_inc (&_data66_->_ref_count_);
	return _data66_;
}

static void
block66_data_unref (void * _userdata_)
{
	Block66Data* _data66_;
	_data66_ = (Block66Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data66_->_ref_count_)) {
		G4TagCache* self;
		self = _data66_->self;
		_g_object_unref0 (_data66_->dos);
		_g4_tag_cache_unref0 (self);
		g_slice_free (Block66Data, _data66_);
	}
}

static gboolean*
_bool_dup (gboolean* self)
{
	gboolean* dup;
	dup = g_new0 (gboolean, 1);
	memcpy (dup, self, sizeof (gboolean));
	return dup;
}

static gpointer
__bool_dup0 (gpointer self)
{
	return self ? _bool_dup (self) : NULL;
}

static void
____lambda22_ (Block66Data* _data66_,
               const gchar* key,
               G4Music* music)
{
	G4TagCache* self;
	GError* _inner_error0_ = NULL;
	self = _data66_->self;
	g_return_if_fail (key != NULL);
	g_return_if_fail (music != NULL);
	{
		G4DataOutputBytes* _tmp0_;
		_tmp0_ = _data66_->dos;
		g4_music_serialize (music, _tmp0_, &_inner_error0_);
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			goto __catch0_g_error;
		}
	}
	goto __finally0;
	__catch0_g_error:
	{
		g_clear_error (&_inner_error0_);
	}
	__finally0:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
		g_clear_error (&_inner_error0_);
		return;
	}
}

static void
_____lambda22__gh_func (gconstpointer key,
                        gconstpointer value,
                        gpointer self)
{
	____lambda22_ (self, (const gchar*) key, (G4Music*) value);
}

void
g4_tag_cache_save (G4TagCache* self)
{
	G4Event* _tmp0_;
	G4Event* _tmp36_;
	GError* _inner_error0_ = NULL;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->_event;
	g4_event_reset (_tmp0_);
	{
		Block66Data* _data66_;
		GFile* parent = NULL;
		GFile* _tmp1_;
		GFile* _tmp2_;
		GFile* _tmp3_ = NULL;
		GFile* _tmp4_;
		gboolean* _tmp5_ = NULL;
		gboolean* _tmp8_ = NULL;
		gboolean* _tmp9_;
		gboolean exists = FALSE;
		gboolean* _tmp12_;
		gboolean _tmp13_;
		GFileOutputStream* fos = NULL;
		GFile* _tmp19_;
		GFileOutputStream* _tmp20_;
		G4DataOutputBytes* _tmp21_;
		G4DataOutputBytes* _tmp22_;
		_data66_ = g_slice_new0 (Block66Data);
		_data66_->_ref_count_ = 1;
		_data66_->self = g4_tag_cache_ref (self);
		_tmp1_ = self->priv->_file;
		_tmp2_ = g_file_get_parent (_tmp1_);
		parent = _tmp2_;
		_tmp4_ = parent;
		_tmp3_ = _tmp4_;
		_tmp5_ = NULL;
		if (_tmp3_ != NULL) {
			gboolean _tmp6_;
			gboolean* _tmp7_;
			_tmp6_ = g_file_query_exists (G_TYPE_CHECK_INSTANCE_CAST (_tmp3_, g_file_get_type (), GFile), NULL);
			_tmp7_ = __bool_dup0 (&_tmp6_);
			_g_free0 (_tmp5_);
			_tmp5_ = _tmp7_;
		}
		_tmp9_ = _tmp5_;
		_tmp5_ = NULL;
		_tmp8_ = _tmp9_;
		if (_tmp8_ == NULL) {
			gboolean _tmp10_;
			gboolean* _tmp11_;
			_tmp10_ = FALSE;
			_tmp11_ = __bool_dup0 (&_tmp10_);
			_g_free0 (_tmp8_);
			_tmp8_ = _tmp11_;
		}
		_tmp12_ = _tmp8_;
		_tmp8_ = NULL;
		_tmp13_ = (gboolean) (*_tmp12_);
		_g_free0 (_tmp12_);
		exists = _tmp13_;
		if (!exists) {
			GFile* _tmp14_ = NULL;
			GFile* _tmp15_;
			gboolean* _tmp16_ = NULL;
			_tmp15_ = parent;
			_tmp14_ = _tmp15_;
			_tmp16_ = NULL;
			if (_tmp14_ != NULL) {
				gboolean _tmp17_ = FALSE;
				gboolean* _tmp18_;
				_tmp17_ = g_file_make_directory_with_parents (G_TYPE_CHECK_INSTANCE_CAST (_tmp14_, g_file_get_type (), GFile), NULL, &_inner_error0_);
				if (G_UNLIKELY (_inner_error0_ != NULL)) {
					_g_free0 (_tmp16_);
					_g_free0 (_tmp8_);
					_g_free0 (_tmp5_);
					_g_object_unref0 (parent);
					block66_data_unref (_data66_);
					_data66_ = NULL;
					goto __catch0_g_error;
				}
				_tmp18_ = __bool_dup0 (&_tmp17_);
				_g_free0 (_tmp16_);
				_tmp16_ = _tmp18_;
			}
			_g_free0 (_tmp16_);
		}
		_tmp19_ = self->priv->_file;
		_tmp20_ = g_file_replace (_tmp19_, NULL, FALSE, G_FILE_CREATE_NONE, NULL, &_inner_error0_);
		fos = _tmp20_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			_g_free0 (_tmp8_);
			_g_free0 (_tmp5_);
			_g_object_unref0 (parent);
			block66_data_unref (_data66_);
			_data66_ = NULL;
			goto __catch0_g_error;
		}
		_tmp21_ = g4_data_output_bytes_new ((guint) 4096);
		_data66_->dos = _tmp21_;
		_tmp22_ = _data66_->dos;
		g4_data_output_bytes_write_uint32 (_tmp22_, g4_tag_cache_MAGIC);
		{
			GHashTable* _tmp23_;
			_tmp23_ = self->priv->_cache;
			g_rec_mutex_lock (&self->priv->__lock__cache);
			{
				G4DataOutputBytes* _tmp24_;
				GHashTable* _tmp25_;
				guint _tmp26_;
				guint _tmp27_;
				GHashTable* _tmp28_;
				gboolean _tmp29_ = FALSE;
				G4DataOutputBytes* _tmp30_;
				GFileOutputStream* _tmp31_;
				_tmp24_ = _data66_->dos;
				_tmp25_ = self->priv->_cache;
				_tmp26_ = g_hash_table_size (_tmp25_);
				_tmp27_ = _tmp26_;
				g4_data_output_bytes_write_size (_tmp24_, (gsize) _tmp27_);
				_tmp28_ = self->priv->_cache;
				g_hash_table_foreach (_tmp28_, _____lambda22__gh_func, _data66_);
				_tmp30_ = _data66_->dos;
				_tmp31_ = fos;
				_tmp29_ = g4_data_output_bytes_write_to (_tmp30_, (GOutputStream*) _tmp31_, &_inner_error0_);
				if (G_UNLIKELY (_inner_error0_ != NULL)) {
					goto __catch1_g_error;
				}
				self->priv->_modified = !_tmp29_;
			}
			goto __finally1;
			__catch1_g_error:
			{
				GError* _lock_error_ = NULL;
				GError* _tmp32_;
				_lock_error_ = _inner_error0_;
				_inner_error0_ = NULL;
				_tmp32_ = _lock_error_;
				_lock_error_ = NULL;
				_inner_error0_ = _tmp32_;
				_g_error_free0 (_lock_error_);
				goto __finally1;
			}
			__finally1:
			{
				GError* _inner_error1_ = NULL;
				GHashTable* _tmp33_;
				_tmp33_ = self->priv->_cache;
				g_rec_mutex_unlock (&self->priv->__lock__cache);
			}
			if (G_UNLIKELY (_inner_error0_ != NULL)) {
				_g_object_unref0 (fos);
				_g_free0 (_tmp8_);
				_g_free0 (_tmp5_);
				_g_object_unref0 (parent);
				block66_data_unref (_data66_);
				_data66_ = NULL;
				goto __catch0_g_error;
			}
		}
		_g_object_unref0 (fos);
		_g_free0 (_tmp8_);
		_g_free0 (_tmp5_);
		_g_object_unref0 (parent);
		block66_data_unref (_data66_);
		_data66_ = NULL;
	}
	goto __finally0;
	__catch0_g_error:
	{
		GError* e = NULL;
		GError* _tmp34_;
		const gchar* _tmp35_;
		e = _inner_error0_;
		_inner_error0_ = NULL;
		_tmp34_ = e;
		_tmp35_ = _tmp34_->message;
		g_print ("Save tags error: %s\n", _tmp35_);
		_g_error_free0 (e);
	}
	__finally0:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
		g_clear_error (&_inner_error0_);
		return;
	}
	_tmp36_ = self->priv->_event;
	g4_event_notify (_tmp36_);
}

void
g4_tag_cache_wait_loading (G4TagCache* self)
{
	G4Event* _tmp0_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->_event;
	g4_event_wait (_tmp0_);
}

gboolean
g4_tag_cache_get_modified (G4TagCache* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = self->priv->_modified;
	return result;
}

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

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

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

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

static gchar*
g4_value_tag_cache_collect_value (GValue* value,
                                  guint n_collect_values,
                                  GTypeCValue* collect_values,
                                  guint collect_flags)
{
	if (collect_values[0].v_pointer) {
		G4TagCache * 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 = g4_tag_cache_ref (object);
	} else {
		value->data[0].v_pointer = NULL;
	}
	return NULL;
}

static gchar*
g4_value_tag_cache_lcopy_value (const GValue* value,
                                guint n_collect_values,
                                GTypeCValue* collect_values,
                                guint collect_flags)
{
	G4TagCache ** 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 = g4_tag_cache_ref (value->data[0].v_pointer);
	}
	return NULL;
}

GParamSpec*
g4_param_spec_tag_cache (const gchar* name,
                         const gchar* nick,
                         const gchar* blurb,
                         GType object_type,
                         GParamFlags flags)
{
	G4ParamSpecTagCache* spec;
	g_return_val_if_fail (g_type_is_a (object_type, G4_TYPE_TAG_CACHE), 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
g4_value_get_tag_cache (const GValue* value)
{
	g_return_val_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, G4_TYPE_TAG_CACHE), NULL);
	return value->data[0].v_pointer;
}

void
g4_value_set_tag_cache (GValue* value,
                        gpointer v_object)
{
	G4TagCache * old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, G4_TYPE_TAG_CACHE));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, G4_TYPE_TAG_CACHE));
		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;
		g4_tag_cache_ref (value->data[0].v_pointer);
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		g4_tag_cache_unref (old);
	}
}

void
g4_value_take_tag_cache (GValue* value,
                         gpointer v_object)
{
	G4TagCache * old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, G4_TYPE_TAG_CACHE));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, G4_TYPE_TAG_CACHE));
		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) {
		g4_tag_cache_unref (old);
	}
}

static void
g4_tag_cache_class_init (G4TagCacheClass * klass,
                         gpointer klass_data)
{
	g4_tag_cache_parent_class = g_type_class_peek_parent (klass);
	((G4TagCacheClass *) klass)->finalize = g4_tag_cache_finalize;
	g_type_class_adjust_private_offset (klass, &G4TagCache_private_offset);
}

static void
g4_tag_cache_instance_init (G4TagCache * self,
                            gpointer klass)
{
	G4Event* _tmp0_;
	GHashFunc _tmp1_;
	GEqualFunc _tmp2_;
	GHashTable* _tmp3_;
	self->priv = g4_tag_cache_get_instance_private (self);
	_tmp0_ = g4_event_new ();
	self->priv->_event = _tmp0_;
	self->priv->_modified = FALSE;
	g_rec_mutex_init (&self->priv->__lock__cache);
	_tmp1_ = g_str_hash;
	_tmp2_ = g_str_equal;
	_tmp3_ = g_hash_table_new_full (_tmp1_, _tmp2_, NULL, _g_object_unref0_);
	self->priv->_cache = _tmp3_;
	self->ref_count = 1;
}

static void
g4_tag_cache_finalize (G4TagCache * obj)
{
	G4TagCache * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, G4_TYPE_TAG_CACHE, G4TagCache);
	g_signal_handlers_destroy (self);
	_g4_event_unref0 (self->priv->_event);
	_g_object_unref0 (self->priv->_file);
	g_rec_mutex_clear (&self->priv->__lock__cache);
	_g_hash_table_unref0 (self->priv->_cache);
}

static GType
g4_tag_cache_get_type_once (void)
{
	static const GTypeValueTable g_define_type_value_table = { g4_value_tag_cache_init, g4_value_tag_cache_free_value, g4_value_tag_cache_copy_value, g4_value_tag_cache_peek_pointer, "p", g4_value_tag_cache_collect_value, "p", g4_value_tag_cache_lcopy_value };
	static const GTypeInfo g_define_type_info = { sizeof (G4TagCacheClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) g4_tag_cache_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (G4TagCache), 0, (GInstanceInitFunc) g4_tag_cache_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 g4_tag_cache_type_id;
	g4_tag_cache_type_id = g_type_register_fundamental (g_type_fundamental_next (), "G4TagCache", &g_define_type_info, &g_define_type_fundamental_info, 0);
	G4TagCache_private_offset = g_type_add_instance_private (g4_tag_cache_type_id, sizeof (G4TagCachePrivate));
	return g4_tag_cache_type_id;
}

GType
g4_tag_cache_get_type (void)
{
	static volatile gsize g4_tag_cache_type_id__once = 0;
	if (g_once_init_enter (&g4_tag_cache_type_id__once)) {
		GType g4_tag_cache_type_id;
		g4_tag_cache_type_id = g4_tag_cache_get_type_once ();
		g_once_init_leave (&g4_tag_cache_type_id__once, g4_tag_cache_type_id);
	}
	return g4_tag_cache_type_id__once;
}

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

void
g4_tag_cache_unref (gpointer instance)
{
	G4TagCache * self;
	self = instance;
	if (g_atomic_int_dec_and_test (&self->ref_count)) {
		G4_TAG_CACHE_GET_CLASS (self)->finalize (self);
		g_type_free_instance ((GTypeInstance *) self);
	}
}

static inline gpointer
_vala_memdup2 (gconstpointer mem,
               gsize byte_size)
{
	gpointer new_mem;
	if (mem && byte_size != 0) {
		new_mem = g_malloc (byte_size);
		memcpy (new_mem, mem, byte_size);
	} else {
		new_mem = NULL;
	}
	return new_mem;
}

