/* avatar-cache.c generated by valac 0.14.0.15-f8b5, the Vala compiler
 * generated from avatar-cache.vala, do not modify */

/*
 * Copyright (C) 2011 Collabora Ltd.
 *
 * This library is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This library 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 Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Philip Withnall <philip.withnall@collabora.co.uk>
 */

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


#define FOLKS_TYPE_AVATAR_CACHE (folks_avatar_cache_get_type ())
#define FOLKS_AVATAR_CACHE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FOLKS_TYPE_AVATAR_CACHE, FolksAvatarCache))
#define FOLKS_AVATAR_CACHE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), FOLKS_TYPE_AVATAR_CACHE, FolksAvatarCacheClass))
#define FOLKS_IS_AVATAR_CACHE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FOLKS_TYPE_AVATAR_CACHE))
#define FOLKS_IS_AVATAR_CACHE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), FOLKS_TYPE_AVATAR_CACHE))
#define FOLKS_AVATAR_CACHE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), FOLKS_TYPE_AVATAR_CACHE, FolksAvatarCacheClass))

typedef struct _FolksAvatarCache FolksAvatarCache;
typedef struct _FolksAvatarCacheClass FolksAvatarCacheClass;
typedef struct _FolksAvatarCachePrivate FolksAvatarCachePrivate;
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _g_free0(var) (var = (g_free (var), NULL))
typedef struct _FolksAvatarCacheLoadAvatarData FolksAvatarCacheLoadAvatarData;
#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
typedef struct _FolksAvatarCacheStoreAvatarData FolksAvatarCacheStoreAvatarData;
typedef struct _FolksAvatarCacheRemoveAvatarData FolksAvatarCacheRemoveAvatarData;

struct _FolksAvatarCache {
	GObject parent_instance;
	FolksAvatarCachePrivate * priv;
};

struct _FolksAvatarCacheClass {
	GObjectClass parent_class;
};

struct _FolksAvatarCachePrivate {
	GFile* _cache_directory;
};

struct _FolksAvatarCacheLoadAvatarData {
	int _state_;
	GObject* _source_object_;
	GAsyncResult* _res_;
	GSimpleAsyncResult* _async_result;
	FolksAvatarCache* self;
	gchar* id;
	GLoadableIcon* result;
	const gchar* _tmp0_;
	GFile* _tmp1_;
	GFile* avatar_file;
	const gchar* _tmp2_;
	GFile* _tmp3_;
	gchar* _tmp4_;
	gchar* _tmp5_;
	GFile* _tmp6_;
	gboolean _tmp7_;
	GFile* _tmp8_;
	GFileIcon* _tmp9_;
};

struct _FolksAvatarCacheStoreAvatarData {
	int _state_;
	GObject* _source_object_;
	GAsyncResult* _res_;
	GSimpleAsyncResult* _async_result;
	FolksAvatarCache* self;
	gchar* id;
	GLoadableIcon* avatar;
	gchar* result;
	const gchar* _tmp0_;
	GFile* _tmp1_;
	GFile* dest_avatar_file;
	const gchar* _tmp2_;
	GFile* _tmp3_;
	gchar* _tmp4_;
	gchar* _tmp5_;
	GLoadableIcon* _tmp6_;
	GInputStream* _tmp7_;
	GInputStream* src_avatar_stream;
	GOutputStream* dest_avatar_stream;
	GFile* _tmp8_;
	GFileOutputStream* _tmp9_;
	GFileOutputStream* _tmp10_;
	GOutputStream* _tmp11_;
	GInputStream* _tmp12_;
	GOutputStream* _tmp13_;
	GError* e;
	GError* _tmp14_;
	GOutputStream* _tmp15_;
	GOutputStream* _tmp16_;
	GError* _tmp17_;
	GError* _tmp18_;
	GInputStream* _tmp19_;
	const gchar* _tmp20_;
	gchar* _tmp21_;
	GError * _inner_error_;
};

struct _FolksAvatarCacheRemoveAvatarData {
	int _state_;
	GObject* _source_object_;
	GAsyncResult* _res_;
	GSimpleAsyncResult* _async_result;
	FolksAvatarCache* self;
	gchar* id;
	const gchar* _tmp0_;
	GFile* _tmp1_;
	GFile* avatar_file;
	const gchar* _tmp2_;
	GFile* _tmp3_;
	gchar* _tmp4_;
	gchar* _tmp5_;
	GFile* _tmp6_;
	GError* e;
	GError* _tmp7_;
	GError* _tmp8_;
	GError* _tmp9_;
	GError * _inner_error_;
};


static gpointer folks_avatar_cache_parent_class = NULL;
static FolksAvatarCache* folks_avatar_cache__instance;
static GStaticRecMutex __lock_folks_avatar_cache__instance = {0};
static FolksAvatarCache* folks_avatar_cache__instance = NULL;

GType folks_avatar_cache_get_type (void) G_GNUC_CONST;
#define FOLKS_AVATAR_CACHE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), FOLKS_TYPE_AVATAR_CACHE, FolksAvatarCachePrivate))
enum  {
	FOLKS_AVATAR_CACHE_DUMMY_PROPERTY
};
static FolksAvatarCache* folks_avatar_cache_new (void);
static FolksAvatarCache* folks_avatar_cache_construct (GType object_type);
FolksAvatarCache* folks_avatar_cache_dup (void);
static void folks_avatar_cache_load_avatar_data_free (gpointer _data);
void folks_avatar_cache_load_avatar (FolksAvatarCache* self, const gchar* id, GAsyncReadyCallback _callback_, gpointer _user_data_);
GLoadableIcon* folks_avatar_cache_load_avatar_finish (FolksAvatarCache* self, GAsyncResult* _res_, GError** error);
static gboolean folks_avatar_cache_load_avatar_co (FolksAvatarCacheLoadAvatarData* _data_);
static GFile* _folks_avatar_cache_get_avatar_file (FolksAvatarCache* self, const gchar* id);
static void folks_avatar_cache_store_avatar_data_free (gpointer _data);
void folks_avatar_cache_store_avatar (FolksAvatarCache* self, const gchar* id, GLoadableIcon* avatar, GAsyncReadyCallback _callback_, gpointer _user_data_);
gchar* folks_avatar_cache_store_avatar_finish (FolksAvatarCache* self, GAsyncResult* _res_, GError** error);
static gboolean folks_avatar_cache_store_avatar_co (FolksAvatarCacheStoreAvatarData* _data_);
static void folks_avatar_cache_store_avatar_ready (GObject* source_object, GAsyncResult* _res_, gpointer _user_data_);
static void _folks_avatar_cache_create_cache_directory (FolksAvatarCache* self, GError** error);
gchar* folks_avatar_cache_build_uri_for_avatar (FolksAvatarCache* self, const gchar* id);
static void folks_avatar_cache_remove_avatar_data_free (gpointer _data);
void folks_avatar_cache_remove_avatar (FolksAvatarCache* self, const gchar* id, GAsyncReadyCallback _callback_, gpointer _user_data_);
void folks_avatar_cache_remove_avatar_finish (FolksAvatarCache* self, GAsyncResult* _res_, GError** error);
static gboolean folks_avatar_cache_remove_avatar_co (FolksAvatarCacheRemoveAvatarData* _data_);
static void folks_avatar_cache_finalize (GObject* obj);


/**
   * Private constructor for an instance of the avatar cache. The singleton
   * instance should be retrieved by calling {@link AvatarCache.dup()} instead.
   *
   * @since 0.6.0
   */
static FolksAvatarCache* folks_avatar_cache_construct (GType object_type) {
	FolksAvatarCache * self = NULL;
	const gchar* _tmp0_ = NULL;
	GFile* _tmp1_ = NULL;
	GFile* _tmp2_;
	GFile* _tmp3_ = NULL;
	GFile* _tmp4_;
	GFile* _tmp5_ = NULL;
	self = (FolksAvatarCache*) g_object_new (object_type, NULL);
	_tmp0_ = g_get_user_cache_dir ();
	_tmp1_ = g_file_new_for_path (_tmp0_);
	_tmp2_ = _tmp1_;
	_tmp3_ = g_file_get_child (_tmp2_, "folks");
	_tmp4_ = _tmp3_;
	_tmp5_ = g_file_get_child (_tmp4_, "avatars");
	_g_object_unref0 (self->priv->_cache_directory);
	self->priv->_cache_directory = _tmp5_;
	_g_object_unref0 (_tmp4_);
	_g_object_unref0 (_tmp2_);
	return self;
}


static FolksAvatarCache* folks_avatar_cache_new (void) {
	return folks_avatar_cache_construct (FOLKS_TYPE_AVATAR_CACHE);
}


/**
   * Create or return the singleton {@link AvatarCache} class instance.
   * If the instance doesn't exist already, it will be created.
   *
   * This function is thread-safe.
   *
   * @return Singleton {@link AvatarCache} instance
   * @since 0.6.0
   */
static gpointer _g_object_ref0 (gpointer self) {
	return self ? g_object_ref (self) : NULL;
}


FolksAvatarCache* folks_avatar_cache_dup (void) {
	FolksAvatarCache* result = NULL;
	GError * _inner_error_ = NULL;
	{
		FolksAvatarCache* _tmp0_;
		_tmp0_ = folks_avatar_cache__instance;
		g_static_rec_mutex_lock (&__lock_folks_avatar_cache__instance);
		{
			FolksAvatarCache* _tmp1_;
			FolksAvatarCache* _tmp2_;
			FolksAvatarCache* retval;
			FolksAvatarCache* _tmp3_;
			_tmp1_ = folks_avatar_cache__instance;
			_tmp2_ = _g_object_ref0 (_tmp1_);
			retval = _tmp2_;
			_tmp3_ = retval;
			if (_tmp3_ == NULL) {
				FolksAvatarCache* _tmp4_;
				FolksAvatarCache* _tmp5_;
				_tmp4_ = folks_avatar_cache_new ();
				_g_object_unref0 (retval);
				retval = _tmp4_;
				_tmp5_ = retval;
				folks_avatar_cache__instance = _tmp5_;
			}
			result = retval;
			{
				FolksAvatarCache* _tmp6_;
				_tmp6_ = folks_avatar_cache__instance;
				g_static_rec_mutex_unlock (&__lock_folks_avatar_cache__instance);
			}
			return result;
		}
		__finally30:
		{
			FolksAvatarCache* _tmp7_;
			_tmp7_ = folks_avatar_cache__instance;
			g_static_rec_mutex_unlock (&__lock_folks_avatar_cache__instance);
		}
		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;
	}
}


static void folks_avatar_cache_load_avatar_data_free (gpointer _data) {
	FolksAvatarCacheLoadAvatarData* _data_;
	_data_ = _data;
	_g_free0 (_data_->id);
	_g_object_unref0 (_data_->result);
	_g_object_unref0 (_data_->self);
	g_slice_free (FolksAvatarCacheLoadAvatarData, _data_);
}


void folks_avatar_cache_load_avatar (FolksAvatarCache* self, const gchar* id, GAsyncReadyCallback _callback_, gpointer _user_data_) {
	FolksAvatarCacheLoadAvatarData* _data_;
	FolksAvatarCache* _tmp0_;
	const gchar* _tmp1_;
	const gchar* _tmp2_;
	_data_ = g_slice_new0 (FolksAvatarCacheLoadAvatarData);
	_data_->_async_result = g_simple_async_result_new (G_OBJECT (self), _callback_, _user_data_, folks_avatar_cache_load_avatar);
	g_simple_async_result_set_op_res_gpointer (_data_->_async_result, _data_, folks_avatar_cache_load_avatar_data_free);
	_tmp0_ = _g_object_ref0 (self);
	_data_->self = _tmp0_;
	_tmp1_ = id;
	_tmp2_ = g_strdup (_tmp1_);
	_data_->id = _tmp2_;
	folks_avatar_cache_load_avatar_co (_data_);
}


GLoadableIcon* folks_avatar_cache_load_avatar_finish (FolksAvatarCache* self, GAsyncResult* _res_, GError** error) {
	GLoadableIcon* result;
	FolksAvatarCacheLoadAvatarData* _data_;
	if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (_res_), error)) {
		return NULL;
	}
	_data_ = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (_res_));
	result = _data_->result;
	_data_->result = NULL;
	return result;
}


/**
   * Fetch an avatar from the cache by its globally unique ID.
   *
   * @param id the globally unique ID for the avatar
   * @return Avatar from the cache, or `null` if it doesn't exist in the cache
   * @throws GLib.Error if checking for existence of the cache file failed
   * @since 0.6.0
   */
static gboolean folks_avatar_cache_load_avatar_co (FolksAvatarCacheLoadAvatarData* _data_) {
	switch (_data_->_state_) {
		case 0:
		goto _state_0;
		default:
		g_assert_not_reached ();
	}
	_state_0:
	_data_->_tmp0_ = _data_->id;
	_data_->_tmp1_ = NULL;
	_data_->_tmp1_ = _folks_avatar_cache_get_avatar_file (_data_->self, _data_->_tmp0_);
	_data_->avatar_file = _data_->_tmp1_;
	_data_->_tmp2_ = _data_->id;
	_data_->_tmp3_ = _data_->avatar_file;
	_data_->_tmp4_ = NULL;
	_data_->_tmp4_ = g_file_get_uri (_data_->_tmp3_);
	_data_->_tmp5_ = _data_->_tmp4_;
	g_debug ("avatar-cache.vala:96: Loading avatar '%s' from file '%s'.", _data_->_tmp2_, _data_->_tmp5_);
	_g_free0 (_data_->_tmp5_);
	_data_->_tmp6_ = _data_->avatar_file;
	_data_->_tmp7_ = FALSE;
	_data_->_tmp7_ = g_file_query_exists (_data_->_tmp6_, NULL);
	if (_data_->_tmp7_ == FALSE) {
		_data_->result = NULL;
		_g_object_unref0 (_data_->avatar_file);
		if (_data_->_state_ == 0) {
			g_simple_async_result_complete_in_idle (_data_->_async_result);
		} else {
			g_simple_async_result_complete (_data_->_async_result);
		}
		g_object_unref (_data_->_async_result);
		return FALSE;
	}
	_data_->_tmp8_ = _data_->avatar_file;
	_data_->_tmp9_ = (GFileIcon*) g_file_icon_new (_data_->_tmp8_);
	_data_->result = (GLoadableIcon*) _data_->_tmp9_;
	_g_object_unref0 (_data_->avatar_file);
	if (_data_->_state_ == 0) {
		g_simple_async_result_complete_in_idle (_data_->_async_result);
	} else {
		g_simple_async_result_complete (_data_->_async_result);
	}
	g_object_unref (_data_->_async_result);
	return FALSE;
	_g_object_unref0 (_data_->avatar_file);
	if (_data_->_state_ == 0) {
		g_simple_async_result_complete_in_idle (_data_->_async_result);
	} else {
		g_simple_async_result_complete (_data_->_async_result);
	}
	g_object_unref (_data_->_async_result);
	return FALSE;
}


static void folks_avatar_cache_store_avatar_data_free (gpointer _data) {
	FolksAvatarCacheStoreAvatarData* _data_;
	_data_ = _data;
	_g_free0 (_data_->id);
	_g_object_unref0 (_data_->avatar);
	_g_free0 (_data_->result);
	_g_object_unref0 (_data_->self);
	g_slice_free (FolksAvatarCacheStoreAvatarData, _data_);
}


void folks_avatar_cache_store_avatar (FolksAvatarCache* self, const gchar* id, GLoadableIcon* avatar, GAsyncReadyCallback _callback_, gpointer _user_data_) {
	FolksAvatarCacheStoreAvatarData* _data_;
	FolksAvatarCache* _tmp0_;
	const gchar* _tmp1_;
	const gchar* _tmp2_;
	GLoadableIcon* _tmp3_;
	GLoadableIcon* _tmp4_;
	_data_ = g_slice_new0 (FolksAvatarCacheStoreAvatarData);
	_data_->_async_result = g_simple_async_result_new (G_OBJECT (self), _callback_, _user_data_, folks_avatar_cache_store_avatar);
	g_simple_async_result_set_op_res_gpointer (_data_->_async_result, _data_, folks_avatar_cache_store_avatar_data_free);
	_tmp0_ = _g_object_ref0 (self);
	_data_->self = _tmp0_;
	_tmp1_ = id;
	_tmp2_ = g_strdup (_tmp1_);
	_data_->id = _tmp2_;
	_tmp3_ = avatar;
	_tmp4_ = _g_object_ref0 (_tmp3_);
	_data_->avatar = _tmp4_;
	folks_avatar_cache_store_avatar_co (_data_);
}


gchar* folks_avatar_cache_store_avatar_finish (FolksAvatarCache* self, GAsyncResult* _res_, GError** error) {
	gchar* result;
	FolksAvatarCacheStoreAvatarData* _data_;
	if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (_res_), error)) {
		return NULL;
	}
	_data_ = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (_res_));
	result = _data_->result;
	_data_->result = NULL;
	return result;
}


/**
   * Store an avatar in the cache, assigning the given globally unique ID to it,
   * which can later be used to load and remove the avatar from the cache. For
   * example, this ID could be the UID of a persona. The URI of the cached
   * avatar file will be returned.
   *
   * @param id the globally unique ID for the avatar
   * @param avatar the avatar data to cache
   * @return a URI for the file storing the cached avatar
   * @throws GLib.Error if the avatar data couldn't be loaded, or if creating
   * the avatar directory or cache file failed
   * @since 0.6.0
   */
static void folks_avatar_cache_store_avatar_ready (GObject* source_object, GAsyncResult* _res_, gpointer _user_data_) {
	FolksAvatarCacheStoreAvatarData* _data_;
	_data_ = _user_data_;
	_data_->_source_object_ = source_object;
	_data_->_res_ = _res_;
	folks_avatar_cache_store_avatar_co (_data_);
}


static gpointer _g_error_copy0 (gpointer self) {
	return self ? g_error_copy (self) : NULL;
}


static gboolean folks_avatar_cache_store_avatar_co (FolksAvatarCacheStoreAvatarData* _data_) {
	switch (_data_->_state_) {
		case 0:
		goto _state_0;
		case 1:
		goto _state_1;
		case 2:
		goto _state_2;
		case 3:
		goto _state_3;
		case 4:
		goto _state_4;
		case 5:
		goto _state_5;
		case 6:
		goto _state_6;
		default:
		g_assert_not_reached ();
	}
	_state_0:
	_data_->_tmp0_ = _data_->id;
	_data_->_tmp1_ = NULL;
	_data_->_tmp1_ = _folks_avatar_cache_get_avatar_file (_data_->self, _data_->_tmp0_);
	_data_->dest_avatar_file = _data_->_tmp1_;
	_data_->_tmp2_ = _data_->id;
	_data_->_tmp3_ = _data_->dest_avatar_file;
	_data_->_tmp4_ = NULL;
	_data_->_tmp4_ = g_file_get_uri (_data_->_tmp3_);
	_data_->_tmp5_ = _data_->_tmp4_;
	g_debug ("avatar-cache.vala:125: Storing avatar '%s' in file '%s'.", _data_->_tmp2_, _data_->_tmp5_);
	_g_free0 (_data_->_tmp5_);
	_data_->_tmp6_ = _data_->avatar;
	_data_->_state_ = 1;
	g_loadable_icon_load_async (_data_->_tmp6_, -1, NULL, folks_avatar_cache_store_avatar_ready, _data_);
	return FALSE;
	_state_1:
	_data_->_tmp7_ = NULL;
	_data_->_tmp7_ = g_loadable_icon_load_finish (_data_->_tmp6_, _data_->_res_, NULL, &_data_->_inner_error_);
	_data_->src_avatar_stream = _data_->_tmp7_;
	if (_data_->_inner_error_ != NULL) {
		g_simple_async_result_set_from_error (_data_->_async_result, _data_->_inner_error_);
		g_error_free (_data_->_inner_error_);
		_g_object_unref0 (_data_->dest_avatar_file);
		if (_data_->_state_ == 0) {
			g_simple_async_result_complete_in_idle (_data_->_async_result);
		} else {
			g_simple_async_result_complete (_data_->_async_result);
		}
		g_object_unref (_data_->_async_result);
		return FALSE;
	}
	while (TRUE) {
		_data_->dest_avatar_stream = NULL;
		{
			_data_->_tmp8_ = _data_->dest_avatar_file;
			_data_->_state_ = 2;
			g_file_replace_async (_data_->_tmp8_, NULL, FALSE, G_FILE_CREATE_PRIVATE, G_PRIORITY_DEFAULT, NULL, folks_avatar_cache_store_avatar_ready, _data_);
			return FALSE;
			_state_2:
			_data_->_tmp9_ = NULL;
			_data_->_tmp9_ = g_file_replace_finish (_data_->_tmp8_, _data_->_res_, &_data_->_inner_error_);
			_data_->_tmp10_ = _data_->_tmp9_;
			if (_data_->_inner_error_ != NULL) {
				goto __catch31_g_error;
			}
			_g_object_unref0 (_data_->dest_avatar_stream);
			_data_->dest_avatar_stream = (GOutputStream*) _data_->_tmp10_;
			_data_->_tmp11_ = _data_->dest_avatar_stream;
			_data_->_tmp12_ = _data_->src_avatar_stream;
			_data_->_state_ = 3;
			g_output_stream_splice_async (_data_->_tmp11_, _data_->_tmp12_, G_OUTPUT_STREAM_SPLICE_NONE, G_PRIORITY_DEFAULT, NULL, folks_avatar_cache_store_avatar_ready, _data_);
			return FALSE;
			_state_3:
			g_output_stream_splice_finish (_data_->_tmp11_, _data_->_res_, &_data_->_inner_error_);
			if (_data_->_inner_error_ != NULL) {
				goto __catch31_g_error;
			}
			_data_->_tmp13_ = _data_->dest_avatar_stream;
			_data_->_state_ = 4;
			g_output_stream_close_async (_data_->_tmp13_, G_PRIORITY_DEFAULT, NULL, folks_avatar_cache_store_avatar_ready, _data_);
			return FALSE;
			_state_4:
			g_output_stream_close_finish (_data_->_tmp13_, _data_->_res_, &_data_->_inner_error_);
			if (_data_->_inner_error_ != NULL) {
				goto __catch31_g_error;
			}
			_g_object_unref0 (_data_->dest_avatar_stream);
			break;
		}
		goto __finally31;
		__catch31_g_error:
		{
			_data_->e = _data_->_inner_error_;
			_data_->_inner_error_ = NULL;
			_data_->_tmp14_ = _data_->e;
			if (g_error_matches (_data_->_tmp14_, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) {
				_folks_avatar_cache_create_cache_directory (_data_->self, &_data_->_inner_error_);
				if (_data_->_inner_error_ != NULL) {
					_g_error_free0 (_data_->e);
					goto __finally31;
				}
				_g_error_free0 (_data_->e);
				_g_object_unref0 (_data_->dest_avatar_stream);
				continue;
			}
			_data_->_tmp15_ = _data_->dest_avatar_stream;
			if (_data_->_tmp15_ != NULL) {
				_data_->_tmp16_ = _data_->dest_avatar_stream;
				_data_->_state_ = 5;
				g_output_stream_close_async (_data_->_tmp16_, G_PRIORITY_DEFAULT, NULL, folks_avatar_cache_store_avatar_ready, _data_);
				return FALSE;
				_state_5:
				g_output_stream_close_finish (_data_->_tmp16_, _data_->_res_, &_data_->_inner_error_);
				if (_data_->_inner_error_ != NULL) {
					_g_error_free0 (_data_->e);
					goto __finally31;
				}
			}
			_data_->_tmp17_ = _data_->e;
			_data_->_tmp18_ = _g_error_copy0 (_data_->_tmp17_);
			_data_->_inner_error_ = _data_->_tmp18_;
			_g_error_free0 (_data_->e);
			goto __finally31;
		}
		__finally31:
		g_simple_async_result_set_from_error (_data_->_async_result, _data_->_inner_error_);
		g_error_free (_data_->_inner_error_);
		_g_object_unref0 (_data_->dest_avatar_stream);
		_g_object_unref0 (_data_->src_avatar_stream);
		_g_object_unref0 (_data_->dest_avatar_file);
		if (_data_->_state_ == 0) {
			g_simple_async_result_complete_in_idle (_data_->_async_result);
		} else {
			g_simple_async_result_complete (_data_->_async_result);
		}
		g_object_unref (_data_->_async_result);
		return FALSE;
	}
	_data_->_tmp19_ = _data_->src_avatar_stream;
	_data_->_state_ = 6;
	g_input_stream_close_async (_data_->_tmp19_, G_PRIORITY_DEFAULT, NULL, folks_avatar_cache_store_avatar_ready, _data_);
	return FALSE;
	_state_6:
	g_input_stream_close_finish (_data_->_tmp19_, _data_->_res_, &_data_->_inner_error_);
	if (_data_->_inner_error_ != NULL) {
		g_simple_async_result_set_from_error (_data_->_async_result, _data_->_inner_error_);
		g_error_free (_data_->_inner_error_);
		_g_object_unref0 (_data_->src_avatar_stream);
		_g_object_unref0 (_data_->dest_avatar_file);
		if (_data_->_state_ == 0) {
			g_simple_async_result_complete_in_idle (_data_->_async_result);
		} else {
			g_simple_async_result_complete (_data_->_async_result);
		}
		g_object_unref (_data_->_async_result);
		return FALSE;
	}
	_data_->_tmp20_ = _data_->id;
	_data_->_tmp21_ = NULL;
	_data_->_tmp21_ = folks_avatar_cache_build_uri_for_avatar (_data_->self, _data_->_tmp20_);
	_data_->result = _data_->_tmp21_;
	_g_object_unref0 (_data_->src_avatar_stream);
	_g_object_unref0 (_data_->dest_avatar_file);
	if (_data_->_state_ == 0) {
		g_simple_async_result_complete_in_idle (_data_->_async_result);
	} else {
		g_simple_async_result_complete (_data_->_async_result);
	}
	g_object_unref (_data_->_async_result);
	return FALSE;
	_g_object_unref0 (_data_->src_avatar_stream);
	_g_object_unref0 (_data_->dest_avatar_file);
	if (_data_->_state_ == 0) {
		g_simple_async_result_complete_in_idle (_data_->_async_result);
	} else {
		g_simple_async_result_complete (_data_->_async_result);
	}
	g_object_unref (_data_->_async_result);
	return FALSE;
}


static void folks_avatar_cache_remove_avatar_data_free (gpointer _data) {
	FolksAvatarCacheRemoveAvatarData* _data_;
	_data_ = _data;
	_g_free0 (_data_->id);
	_g_object_unref0 (_data_->self);
	g_slice_free (FolksAvatarCacheRemoveAvatarData, _data_);
}


void folks_avatar_cache_remove_avatar (FolksAvatarCache* self, const gchar* id, GAsyncReadyCallback _callback_, gpointer _user_data_) {
	FolksAvatarCacheRemoveAvatarData* _data_;
	FolksAvatarCache* _tmp0_;
	const gchar* _tmp1_;
	const gchar* _tmp2_;
	_data_ = g_slice_new0 (FolksAvatarCacheRemoveAvatarData);
	_data_->_async_result = g_simple_async_result_new (G_OBJECT (self), _callback_, _user_data_, folks_avatar_cache_remove_avatar);
	g_simple_async_result_set_op_res_gpointer (_data_->_async_result, _data_, folks_avatar_cache_remove_avatar_data_free);
	_tmp0_ = _g_object_ref0 (self);
	_data_->self = _tmp0_;
	_tmp1_ = id;
	_tmp2_ = g_strdup (_tmp1_);
	_data_->id = _tmp2_;
	folks_avatar_cache_remove_avatar_co (_data_);
}


void folks_avatar_cache_remove_avatar_finish (FolksAvatarCache* self, GAsyncResult* _res_, GError** error) {
	FolksAvatarCacheRemoveAvatarData* _data_;
	if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (_res_), error)) {
		return;
	}
	_data_ = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (_res_));
}


/**
   * Remove an avatar from the cache, if it exists in the cache. If the avatar
   * exists in the cache but there is a problem in removing it, a
   * {@link GLib.Error} will be thrown.
   *
   * @param id the globally unique ID for the avatar
   * @throws GLib.Error if deleting the cache file failed
   * @since 0.6.0
   */
static gboolean folks_avatar_cache_remove_avatar_co (FolksAvatarCacheRemoveAvatarData* _data_) {
	switch (_data_->_state_) {
		case 0:
		goto _state_0;
		default:
		g_assert_not_reached ();
	}
	_state_0:
	_data_->_tmp0_ = _data_->id;
	_data_->_tmp1_ = NULL;
	_data_->_tmp1_ = _folks_avatar_cache_get_avatar_file (_data_->self, _data_->_tmp0_);
	_data_->avatar_file = _data_->_tmp1_;
	_data_->_tmp2_ = _data_->id;
	_data_->_tmp3_ = _data_->avatar_file;
	_data_->_tmp4_ = NULL;
	_data_->_tmp4_ = g_file_get_uri (_data_->_tmp3_);
	_data_->_tmp5_ = _data_->_tmp4_;
	g_debug ("avatar-cache.vala:184: Removing avatar '%s' in file '%s'.", _data_->_tmp2_, _data_->_tmp5_);
	_g_free0 (_data_->_tmp5_);
	{
		_data_->_tmp6_ = _data_->avatar_file;
		g_file_delete (_data_->_tmp6_, NULL, &_data_->_inner_error_);
		if (_data_->_inner_error_ != NULL) {
			goto __catch32_g_error;
		}
	}
	goto __finally32;
	__catch32_g_error:
	{
		_data_->e = _data_->_inner_error_;
		_data_->_inner_error_ = NULL;
		_data_->_tmp7_ = _data_->e;
		if (!g_error_matches (_data_->_tmp7_, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) {
			_data_->_tmp8_ = _data_->e;
			_data_->_tmp9_ = _g_error_copy0 (_data_->_tmp8_);
			_data_->_inner_error_ = _data_->_tmp9_;
			_g_error_free0 (_data_->e);
			goto __finally32;
		}
		_g_error_free0 (_data_->e);
	}
	__finally32:
	if (_data_->_inner_error_ != NULL) {
		g_simple_async_result_set_from_error (_data_->_async_result, _data_->_inner_error_);
		g_error_free (_data_->_inner_error_);
		_g_object_unref0 (_data_->avatar_file);
		if (_data_->_state_ == 0) {
			g_simple_async_result_complete_in_idle (_data_->_async_result);
		} else {
			g_simple_async_result_complete (_data_->_async_result);
		}
		g_object_unref (_data_->_async_result);
		return FALSE;
	}
	_g_object_unref0 (_data_->avatar_file);
	if (_data_->_state_ == 0) {
		g_simple_async_result_complete_in_idle (_data_->_async_result);
	} else {
		g_simple_async_result_complete (_data_->_async_result);
	}
	g_object_unref (_data_->_async_result);
	return FALSE;
}


/**
   * Build the URI of an avatar file in the cache from a globally unique ID.
   * This will always succeed, even if the avatar doesn't exist in the cache.
   *
   * @param id the globally unique ID for the avatar
   * @return URI of the avatar file with the given globally unique ID
   * @since 0.6.0
   */
gchar* folks_avatar_cache_build_uri_for_avatar (FolksAvatarCache* self, const gchar* id) {
	gchar* result = NULL;
	const gchar* _tmp0_;
	GFile* _tmp1_ = NULL;
	GFile* _tmp2_;
	gchar* _tmp3_ = NULL;
	gchar* _tmp4_;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (id != NULL, NULL);
	_tmp0_ = id;
	_tmp1_ = _folks_avatar_cache_get_avatar_file (self, _tmp0_);
	_tmp2_ = _tmp1_;
	_tmp3_ = g_file_get_uri (_tmp2_);
	_tmp4_ = _tmp3_;
	_g_object_unref0 (_tmp2_);
	result = _tmp4_;
	return result;
}


static GFile* _folks_avatar_cache_get_avatar_file (FolksAvatarCache* self, const gchar* id) {
	GFile* result = NULL;
	const gchar* _tmp0_;
	gchar* _tmp1_ = NULL;
	gchar* escaped_uri;
	GFile* _tmp2_;
	GFile* _tmp3_ = NULL;
	GFile* file;
	GFile* _tmp4_;
	gboolean _tmp5_ = FALSE;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (id != NULL, NULL);
	_tmp0_ = id;
	_tmp1_ = g_uri_escape_string (_tmp0_, "", FALSE);
	escaped_uri = _tmp1_;
	_tmp2_ = self->priv->_cache_directory;
	_tmp3_ = g_file_get_child (_tmp2_, escaped_uri);
	file = _tmp3_;
	_tmp4_ = self->priv->_cache_directory;
	_tmp5_ = g_file_has_parent (file, _tmp4_);
	g_assert (_tmp5_ == TRUE);
	result = file;
	_g_free0 (escaped_uri);
	return result;
}


static void _folks_avatar_cache_create_cache_directory (FolksAvatarCache* self, GError** error) {
	GError * _inner_error_ = NULL;
	g_return_if_fail (self != NULL);
	{
		GFile* _tmp0_;
		_tmp0_ = self->priv->_cache_directory;
		g_file_make_directory_with_parents (_tmp0_, NULL, &_inner_error_);
		if (_inner_error_ != NULL) {
			goto __catch33_g_error;
		}
	}
	goto __finally33;
	__catch33_g_error:
	{
		GError* e = NULL;
		GError* _tmp1_;
		e = _inner_error_;
		_inner_error_ = NULL;
		_tmp1_ = e;
		if (!g_error_matches (_tmp1_, G_IO_ERROR, G_IO_ERROR_EXISTS)) {
			GError* _tmp2_;
			GError* _tmp3_;
			_tmp2_ = e;
			_tmp3_ = _g_error_copy0 (_tmp2_);
			_inner_error_ = _tmp3_;
			_g_error_free0 (e);
			goto __finally33;
		}
		_g_error_free0 (e);
	}
	__finally33:
	if (_inner_error_ != NULL) {
		g_propagate_error (error, _inner_error_);
		return;
	}
}


static void folks_avatar_cache_class_init (FolksAvatarCacheClass * klass) {
	folks_avatar_cache_parent_class = g_type_class_peek_parent (klass);
	g_type_class_add_private (klass, sizeof (FolksAvatarCachePrivate));
	G_OBJECT_CLASS (klass)->finalize = folks_avatar_cache_finalize;
	g_static_rec_mutex_init (&__lock_folks_avatar_cache__instance);
}


static void folks_avatar_cache_instance_init (FolksAvatarCache * self) {
	self->priv = FOLKS_AVATAR_CACHE_GET_PRIVATE (self);
}


static void folks_avatar_cache_finalize (GObject* obj) {
	FolksAvatarCache * self;
	GError * _inner_error_ = NULL;
	self = FOLKS_AVATAR_CACHE (obj);
	{
		FolksAvatarCache* _tmp0_;
		_tmp0_ = folks_avatar_cache__instance;
		g_static_rec_mutex_lock (&__lock_folks_avatar_cache__instance);
		{
			folks_avatar_cache__instance = NULL;
		}
		__finally29:
		{
			FolksAvatarCache* _tmp1_;
			_tmp1_ = folks_avatar_cache__instance;
			g_static_rec_mutex_unlock (&__lock_folks_avatar_cache__instance);
		}
		if (_inner_error_ != NULL) {
			g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
			g_clear_error (&_inner_error_);
		}
	}
	_g_object_unref0 (self->priv->_cache_directory);
	G_OBJECT_CLASS (folks_avatar_cache_parent_class)->finalize (obj);
}


/**
 * A singleton persistent cache object for avatars used across backends in
 * folks. Avatars may be added to the cache, and referred to by a persistent
 * URI from that point onwards.
 *
 * @since 0.6.0
 */
GType folks_avatar_cache_get_type (void) {
	static volatile gsize folks_avatar_cache_type_id__volatile = 0;
	if (g_once_init_enter (&folks_avatar_cache_type_id__volatile)) {
		static const GTypeInfo g_define_type_info = { sizeof (FolksAvatarCacheClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) folks_avatar_cache_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (FolksAvatarCache), 0, (GInstanceInitFunc) folks_avatar_cache_instance_init, NULL };
		GType folks_avatar_cache_type_id;
		folks_avatar_cache_type_id = g_type_register_static (G_TYPE_OBJECT, "FolksAvatarCache", &g_define_type_info, 0);
		g_once_init_leave (&folks_avatar_cache_type_id__volatile, folks_avatar_cache_type_id);
	}
	return folks_avatar_cache_type_id__volatile;
}



