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

#include "crypto-vala.h"
#include <glib.h>
#include <gio/gio.h>
#include <stdlib.h>
#include <string.h>
#include <glib-object.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

enum  {
	CRYPTO_SYMMETRIC_CIPHER_CONVERTER_0_PROPERTY,
	CRYPTO_SYMMETRIC_CIPHER_CONVERTER_NUM_PROPERTIES
};
static GParamSpec* crypto_symmetric_cipher_converter_properties[CRYPTO_SYMMETRIC_CIPHER_CONVERTER_NUM_PROPERTIES];
#define _crypto_symmetric_cipher_unref0(var) ((var == NULL) ? NULL : (var = (crypto_symmetric_cipher_unref (var), NULL)))
#define _g_free0(var) (var = (g_free (var), NULL))
#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
enum  {
	CRYPTO_SYMMETRIC_CIPHER_ENCRYPTER_0_PROPERTY,
	CRYPTO_SYMMETRIC_CIPHER_ENCRYPTER_NUM_PROPERTIES
};
static GParamSpec* crypto_symmetric_cipher_encrypter_properties[CRYPTO_SYMMETRIC_CIPHER_ENCRYPTER_NUM_PROPERTIES];
enum  {
	CRYPTO_SYMMETRIC_CIPHER_DECRYPTER_0_PROPERTY,
	CRYPTO_SYMMETRIC_CIPHER_DECRYPTER_NUM_PROPERTIES
};
static GParamSpec* crypto_symmetric_cipher_decrypter_properties[CRYPTO_SYMMETRIC_CIPHER_DECRYPTER_NUM_PROPERTIES];

static gpointer crypto_symmetric_cipher_converter_parent_class = NULL;
static GConverterIface * crypto_symmetric_cipher_converter_g_converter_parent_iface = NULL;
static gpointer crypto_symmetric_cipher_encrypter_parent_class = NULL;
static gpointer crypto_symmetric_cipher_decrypter_parent_class = NULL;

static GConverterResult crypto_symmetric_cipher_converter_real_convert (CryptoSymmetricCipherConverter* self,
                                                                 guint8* inbuf,
                                                                 gsize inbuf_length1,
                                                                 guint8* outbuf,
                                                                 gsize outbuf_length1,
                                                                 GConverterFlags flags,
                                                                 gsize* bytes_read,
                                                                 gsize* bytes_written,
                                                                 GError** error);
static void crypto_symmetric_cipher_converter_real_reset (GConverter* base);
static void crypto_symmetric_cipher_converter_finalize (GObject * obj);
static GType crypto_symmetric_cipher_converter_get_type_once (void);
static GConverterResult crypto_symmetric_cipher_encrypter_real_convert (CryptoSymmetricCipherConverter* base,
                                                                 guint8* inbuf,
                                                                 gsize inbuf_length1,
                                                                 guint8* outbuf,
                                                                 gsize outbuf_length1,
                                                                 GConverterFlags flags,
                                                                 gsize* bytes_read,
                                                                 gsize* bytes_written,
                                                                 GError** error);
static GType crypto_symmetric_cipher_encrypter_get_type_once (void);
static GConverterResult crypto_symmetric_cipher_decrypter_real_convert (CryptoSymmetricCipherConverter* base,
                                                                 guint8* inbuf,
                                                                 gsize inbuf_length1,
                                                                 guint8* outbuf,
                                                                 gsize outbuf_length1,
                                                                 GConverterFlags flags,
                                                                 gsize* bytes_read,
                                                                 gsize* bytes_written,
                                                                 GError** error);
static GType crypto_symmetric_cipher_decrypter_get_type_once (void);

static GConverterResult
crypto_symmetric_cipher_converter_real_convert (CryptoSymmetricCipherConverter* self,
                                                guint8* inbuf,
                                                gsize inbuf_length1,
                                                guint8* outbuf,
                                                gsize outbuf_length1,
                                                GConverterFlags flags,
                                                gsize* bytes_read,
                                                gsize* bytes_written,
                                                GError** error)
{
	g_critical ("Type `%s' does not implement abstract method `crypto_symmetric_cipher_converter_convert'", g_type_name (G_TYPE_FROM_INSTANCE (self)));
	return 0;
}

GConverterResult
crypto_symmetric_cipher_converter_convert (CryptoSymmetricCipherConverter* self,
                                           guint8* inbuf,
                                           gsize inbuf_length1,
                                           guint8* outbuf,
                                           gsize outbuf_length1,
                                           GConverterFlags flags,
                                           gsize* bytes_read,
                                           gsize* bytes_written,
                                           GError** error)
{
	CryptoSymmetricCipherConverterClass* _klass_;
	g_return_val_if_fail (self != NULL, 0);
	_klass_ = CRYPTO_SYMMETRIC_CIPHER_CONVERTER_GET_CLASS (self);
	if (_klass_->convert) {
		return _klass_->convert (self, inbuf, inbuf_length1, outbuf, outbuf_length1, flags, bytes_read, bytes_written, error);
	}
	return 0;
}

guint8*
crypto_symmetric_cipher_converter_get_tag (CryptoSymmetricCipherConverter* self,
                                           gsize taglen,
                                           gint* result_length1,
                                           GError** error)
{
	guint8* _tmp0_ = NULL;
	CryptoSymmetricCipher* _tmp1_;
	gint _tmp2_ = 0;
	guint8* _tmp3_;
	gint _tmp0__length1;
	gint __tmp0__size_;
	guint8* _tmp4_;
	gint _tmp4__length1;
	guint8* _tmp5_;
	gint _tmp5__length1;
	GError* _inner_error0_ = NULL;
	guint8* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp1_ = self->cipher;
	_tmp3_ = crypto_symmetric_cipher_get_tag (_tmp1_, taglen, &_tmp2_, &_inner_error0_);
	_tmp0_ = _tmp3_;
	_tmp0__length1 = _tmp2_;
	__tmp0__size_ = _tmp0__length1;
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		if (_inner_error0_->domain == CRYPTO_ERROR) {
			g_propagate_error (error, _inner_error0_);
			return NULL;
		} else {
			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;
		}
	}
	_tmp4_ = _tmp0_;
	_tmp4__length1 = _tmp0__length1;
	_tmp0_ = NULL;
	_tmp0__length1 = 0;
	_tmp5_ = _tmp4_;
	_tmp5__length1 = _tmp4__length1;
	if (result_length1) {
		*result_length1 = _tmp5__length1;
	}
	result = _tmp5_;
	_tmp0_ = (g_free (_tmp0_), NULL);
	return result;
}

void
crypto_symmetric_cipher_converter_check_tag (CryptoSymmetricCipherConverter* self,
                                             guint8* tag,
                                             gint tag_length1,
                                             GError** error)
{
	CryptoSymmetricCipher* _tmp0_;
	GError* _inner_error0_ = NULL;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->cipher;
	crypto_symmetric_cipher_check_tag (_tmp0_, tag, (gint) tag_length1, &_inner_error0_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		if (_inner_error0_->domain == CRYPTO_ERROR) {
			g_propagate_error (error, _inner_error0_);
			return;
		} else {
			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 const gchar*
string_to_string (const gchar* self)
{
	const gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	result = self;
	return result;
}

static void
crypto_symmetric_cipher_converter_real_reset (GConverter* base)
{
	CryptoSymmetricCipherConverter * self;
	GError* _inner_error0_ = NULL;
	self = (CryptoSymmetricCipherConverter*) base;
	{
		CryptoSymmetricCipher* _tmp0_;
		_tmp0_ = self->cipher;
		crypto_symmetric_cipher_reset (_tmp0_, &_inner_error0_);
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			if (_inner_error0_->domain == CRYPTO_ERROR) {
				goto __catch0_crypto_error;
			}
			g_critical ("file %s: line %d: unexpected 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;
		}
	}
	goto __finally0;
	__catch0_crypto_error:
	{
		GError* e = NULL;
		GError* _tmp1_;
		const gchar* _tmp2_;
		GError* _tmp3_;
		const gchar* _tmp4_;
		const gchar* _tmp5_;
		gchar* _tmp6_;
		gchar* _tmp7_;
		e = _inner_error0_;
		_inner_error0_ = NULL;
		_tmp1_ = e;
		_tmp2_ = g_quark_to_string (_tmp1_->domain);
		_tmp3_ = e;
		_tmp4_ = _tmp3_->message;
		_tmp5_ = string_to_string (_tmp4_);
		_tmp6_ = g_strconcat (_tmp2_, " error while resetting cipher: ", _tmp5_, NULL);
		_tmp7_ = _tmp6_;
		g_warning ("cipher_converter.vala:22: %s", _tmp7_);
		_g_free0 (_tmp7_);
		_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;
	}
}

CryptoSymmetricCipherConverter*
crypto_symmetric_cipher_converter_construct (GType object_type)
{
	CryptoSymmetricCipherConverter * self = NULL;
	self = (CryptoSymmetricCipherConverter*) g_object_new (object_type, NULL);
	return self;
}

static void
crypto_symmetric_cipher_converter_class_init (CryptoSymmetricCipherConverterClass * klass,
                                              gpointer klass_data)
{
	crypto_symmetric_cipher_converter_parent_class = g_type_class_peek_parent (klass);
	((CryptoSymmetricCipherConverterClass *) klass)->convert = (GConverterResult (*) (CryptoSymmetricCipherConverter*, guint8*, gsize, guint8*, gsize, GConverterFlags, gsize*, gsize*, GError**)) crypto_symmetric_cipher_converter_real_convert;
	G_OBJECT_CLASS (klass)->finalize = crypto_symmetric_cipher_converter_finalize;
}

static void
crypto_symmetric_cipher_converter_g_converter_interface_init (GConverterIface * iface,
                                                              gpointer iface_data)
{
	crypto_symmetric_cipher_converter_g_converter_parent_iface = g_type_interface_peek_parent (iface);
	iface->convert = (GConverterResult (*) (GConverter*, guint8*, gsize, guint8*, gsize, GConverterFlags, gsize*, gsize*, GError**)) crypto_symmetric_cipher_converter_convert;
	iface->reset = (void (*) (GConverter*)) crypto_symmetric_cipher_converter_real_reset;
}

static void
crypto_symmetric_cipher_converter_instance_init (CryptoSymmetricCipherConverter * self,
                                                 gpointer klass)
{
}

static void
crypto_symmetric_cipher_converter_finalize (GObject * obj)
{
	CryptoSymmetricCipherConverter * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, CRYPTO_TYPE_SYMMETRIC_CIPHER_CONVERTER, CryptoSymmetricCipherConverter);
	_crypto_symmetric_cipher_unref0 (self->cipher);
	G_OBJECT_CLASS (crypto_symmetric_cipher_converter_parent_class)->finalize (obj);
}

static GType
crypto_symmetric_cipher_converter_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (CryptoSymmetricCipherConverterClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) crypto_symmetric_cipher_converter_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (CryptoSymmetricCipherConverter), 0, (GInstanceInitFunc) crypto_symmetric_cipher_converter_instance_init, NULL };
	static const GInterfaceInfo g_converter_info = { (GInterfaceInitFunc) crypto_symmetric_cipher_converter_g_converter_interface_init, (GInterfaceFinalizeFunc) NULL, NULL};
	GType crypto_symmetric_cipher_converter_type_id;
	crypto_symmetric_cipher_converter_type_id = g_type_register_static (G_TYPE_OBJECT, "CryptoSymmetricCipherConverter", &g_define_type_info, G_TYPE_FLAG_ABSTRACT);
	g_type_add_interface_static (crypto_symmetric_cipher_converter_type_id, g_converter_get_type (), &g_converter_info);
	return crypto_symmetric_cipher_converter_type_id;
}

GType
crypto_symmetric_cipher_converter_get_type (void)
{
	static volatile gsize crypto_symmetric_cipher_converter_type_id__once = 0;
	if (g_once_init_enter (&crypto_symmetric_cipher_converter_type_id__once)) {
		GType crypto_symmetric_cipher_converter_type_id;
		crypto_symmetric_cipher_converter_type_id = crypto_symmetric_cipher_converter_get_type_once ();
		g_once_init_leave (&crypto_symmetric_cipher_converter_type_id__once, crypto_symmetric_cipher_converter_type_id);
	}
	return crypto_symmetric_cipher_converter_type_id__once;
}

CryptoSymmetricCipherEncrypter*
crypto_symmetric_cipher_encrypter_construct (GType object_type,
                                             CryptoSymmetricCipher* cipher,
                                             gsize attached_taglen)
{
	CryptoSymmetricCipherEncrypter * self = NULL;
	CryptoSymmetricCipher* _tmp0_;
	g_return_val_if_fail (cipher != NULL, NULL);
	self = (CryptoSymmetricCipherEncrypter*) crypto_symmetric_cipher_converter_construct (object_type);
	_tmp0_ = cipher;
	cipher = NULL;
	_crypto_symmetric_cipher_unref0 (((CryptoSymmetricCipherConverter*) self)->cipher);
	((CryptoSymmetricCipherConverter*) self)->cipher = _tmp0_;
	((CryptoSymmetricCipherConverter*) self)->attached_taglen = attached_taglen;
	_crypto_symmetric_cipher_unref0 (cipher);
	return self;
}

CryptoSymmetricCipherEncrypter*
crypto_symmetric_cipher_encrypter_new (CryptoSymmetricCipher* cipher,
                                       gsize attached_taglen)
{
	return crypto_symmetric_cipher_encrypter_construct (CRYPTO_TYPE_SYMMETRIC_CIPHER_ENCRYPTER, cipher, attached_taglen);
}

static GConverterResult
crypto_symmetric_cipher_encrypter_real_convert (CryptoSymmetricCipherConverter* base,
                                                guint8* inbuf,
                                                gsize inbuf_length1,
                                                guint8* outbuf,
                                                gsize outbuf_length1,
                                                GConverterFlags flags,
                                                gsize* bytes_read,
                                                gsize* bytes_written,
                                                GError** error)
{
	CryptoSymmetricCipherEncrypter * self;
	gsize _vala_bytes_read = 0UL;
	gsize _vala_bytes_written = 0UL;
	gboolean _tmp1_ = FALSE;
	GError* _inner_error0_ = NULL;
	GConverterResult result;
	self = (CryptoSymmetricCipherEncrypter*) base;
	if (inbuf_length1 > outbuf_length1) {
		GError* _tmp0_;
		_tmp0_ = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_NO_SPACE, "CipherConverter needs at least the size of input as output space");
		_inner_error0_ = _tmp0_;
		if (_inner_error0_->domain == G_IO_ERROR) {
			g_propagate_error (error, _inner_error0_);
			return 0;
		} else {
			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 0;
		}
	}
	if ((flags & G_CONVERTER_INPUT_AT_END) != 0) {
		_tmp1_ = (inbuf_length1 + ((CryptoSymmetricCipherConverter*) self)->attached_taglen) > ((gsize) outbuf_length1);
	} else {
		_tmp1_ = FALSE;
	}
	if (_tmp1_) {
		GError* _tmp2_;
		_tmp2_ = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_NO_SPACE, "CipherConverter needs additional output space to attach tag");
		_inner_error0_ = _tmp2_;
		if (_inner_error0_->domain == G_IO_ERROR) {
			g_propagate_error (error, _inner_error0_);
			return 0;
		} else {
			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 0;
		}
	}
	{
		if (inbuf_length1 > 0) {
			CryptoSymmetricCipher* _tmp3_;
			_tmp3_ = ((CryptoSymmetricCipherConverter*) self)->cipher;
			crypto_symmetric_cipher_encrypt (_tmp3_, outbuf, (gint) outbuf_length1, inbuf, (gint) inbuf_length1, &_inner_error0_);
			if (G_UNLIKELY (_inner_error0_ != NULL)) {
				if (_inner_error0_->domain == CRYPTO_ERROR) {
					goto __catch0_crypto_error;
				}
				g_critical ("file %s: line %d: unexpected 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 0;
			}
		}
		_vala_bytes_read = (gsize) inbuf_length1;
		_vala_bytes_written = (gsize) inbuf_length1;
		if ((flags & G_CONVERTER_INPUT_AT_END) != 0) {
			if (((CryptoSymmetricCipherConverter*) self)->attached_taglen > ((gsize) 0)) {
				guint8* _tmp4_ = NULL;
				gint _tmp5_ = 0;
				guint8* _tmp6_;
				gint _tmp4__length1;
				gint __tmp4__size_;
				_tmp6_ = crypto_symmetric_cipher_converter_get_tag ((CryptoSymmetricCipherConverter*) self, ((CryptoSymmetricCipherConverter*) self)->attached_taglen, &_tmp5_, &_inner_error0_);
				_tmp4_ = _tmp6_;
				_tmp4__length1 = _tmp5_;
				__tmp4__size_ = _tmp4__length1;
				if (G_UNLIKELY (_inner_error0_ != NULL)) {
					if (_inner_error0_->domain == CRYPTO_ERROR) {
						goto __catch0_crypto_error;
					}
					g_critical ("file %s: line %d: unexpected 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 0;
				}
				memcpy (((guint8*) outbuf) + inbuf_length1, _tmp4_, ((CryptoSymmetricCipherConverter*) self)->attached_taglen);
				_vala_bytes_written = inbuf_length1 + ((CryptoSymmetricCipherConverter*) self)->attached_taglen;
				_tmp4_ = (g_free (_tmp4_), NULL);
			}
			result = G_CONVERTER_FINISHED;
			if (bytes_read) {
				*bytes_read = _vala_bytes_read;
			}
			if (bytes_written) {
				*bytes_written = _vala_bytes_written;
			}
			return result;
		}
		if ((flags & G_CONVERTER_FLUSH) != 0) {
			result = G_CONVERTER_FLUSHED;
			if (bytes_read) {
				*bytes_read = _vala_bytes_read;
			}
			if (bytes_written) {
				*bytes_written = _vala_bytes_written;
			}
			return result;
		}
		result = G_CONVERTER_CONVERTED;
		if (bytes_read) {
			*bytes_read = _vala_bytes_read;
		}
		if (bytes_written) {
			*bytes_written = _vala_bytes_written;
		}
		return result;
	}
	goto __finally0;
	__catch0_crypto_error:
	{
		GError* e = NULL;
		GError* _tmp7_;
		const gchar* _tmp8_;
		GError* _tmp9_;
		const gchar* _tmp10_;
		const gchar* _tmp11_;
		gchar* _tmp12_;
		gchar* _tmp13_;
		GError* _tmp14_;
		GError* _tmp15_;
		e = _inner_error0_;
		_inner_error0_ = NULL;
		_tmp7_ = e;
		_tmp8_ = g_quark_to_string (_tmp7_->domain);
		_tmp9_ = e;
		_tmp10_ = _tmp9_->message;
		_tmp11_ = string_to_string (_tmp10_);
		_tmp12_ = g_strconcat (_tmp8_, " error while encrypting: ", _tmp11_, NULL);
		_tmp13_ = _tmp12_;
		_tmp14_ = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_FAILED, _tmp13_);
		_tmp15_ = _tmp14_;
		_g_free0 (_tmp13_);
		_inner_error0_ = _tmp15_;
		_g_error_free0 (e);
		goto __finally0;
	}
	__finally0:
	if (_inner_error0_->domain == G_IO_ERROR) {
		g_propagate_error (error, _inner_error0_);
		return 0;
	} else {
		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 0;
	}
}

static void
crypto_symmetric_cipher_encrypter_class_init (CryptoSymmetricCipherEncrypterClass * klass,
                                              gpointer klass_data)
{
	crypto_symmetric_cipher_encrypter_parent_class = g_type_class_peek_parent (klass);
	((CryptoSymmetricCipherConverterClass *) klass)->convert = (GConverterResult (*) (CryptoSymmetricCipherConverter*, guint8*, gsize, guint8*, gsize, GConverterFlags, gsize*, gsize*, GError**)) crypto_symmetric_cipher_encrypter_real_convert;
}

static void
crypto_symmetric_cipher_encrypter_instance_init (CryptoSymmetricCipherEncrypter * self,
                                                 gpointer klass)
{
}

static GType
crypto_symmetric_cipher_encrypter_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (CryptoSymmetricCipherEncrypterClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) crypto_symmetric_cipher_encrypter_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (CryptoSymmetricCipherEncrypter), 0, (GInstanceInitFunc) crypto_symmetric_cipher_encrypter_instance_init, NULL };
	GType crypto_symmetric_cipher_encrypter_type_id;
	crypto_symmetric_cipher_encrypter_type_id = g_type_register_static (CRYPTO_TYPE_SYMMETRIC_CIPHER_CONVERTER, "CryptoSymmetricCipherEncrypter", &g_define_type_info, 0);
	return crypto_symmetric_cipher_encrypter_type_id;
}

GType
crypto_symmetric_cipher_encrypter_get_type (void)
{
	static volatile gsize crypto_symmetric_cipher_encrypter_type_id__once = 0;
	if (g_once_init_enter (&crypto_symmetric_cipher_encrypter_type_id__once)) {
		GType crypto_symmetric_cipher_encrypter_type_id;
		crypto_symmetric_cipher_encrypter_type_id = crypto_symmetric_cipher_encrypter_get_type_once ();
		g_once_init_leave (&crypto_symmetric_cipher_encrypter_type_id__once, crypto_symmetric_cipher_encrypter_type_id);
	}
	return crypto_symmetric_cipher_encrypter_type_id__once;
}

CryptoSymmetricCipherDecrypter*
crypto_symmetric_cipher_decrypter_construct (GType object_type,
                                             CryptoSymmetricCipher* cipher,
                                             gsize attached_taglen)
{
	CryptoSymmetricCipherDecrypter * self = NULL;
	CryptoSymmetricCipher* _tmp0_;
	g_return_val_if_fail (cipher != NULL, NULL);
	self = (CryptoSymmetricCipherDecrypter*) crypto_symmetric_cipher_converter_construct (object_type);
	_tmp0_ = cipher;
	cipher = NULL;
	_crypto_symmetric_cipher_unref0 (((CryptoSymmetricCipherConverter*) self)->cipher);
	((CryptoSymmetricCipherConverter*) self)->cipher = _tmp0_;
	((CryptoSymmetricCipherConverter*) self)->attached_taglen = attached_taglen;
	_crypto_symmetric_cipher_unref0 (cipher);
	return self;
}

CryptoSymmetricCipherDecrypter*
crypto_symmetric_cipher_decrypter_new (CryptoSymmetricCipher* cipher,
                                       gsize attached_taglen)
{
	return crypto_symmetric_cipher_decrypter_construct (CRYPTO_TYPE_SYMMETRIC_CIPHER_DECRYPTER, cipher, attached_taglen);
}

static GConverterResult
crypto_symmetric_cipher_decrypter_real_convert (CryptoSymmetricCipherConverter* base,
                                                guint8* inbuf,
                                                gsize inbuf_length1,
                                                guint8* outbuf,
                                                gsize outbuf_length1,
                                                GConverterFlags flags,
                                                gsize* bytes_read,
                                                gsize* bytes_written,
                                                GError** error)
{
	CryptoSymmetricCipherDecrypter * self;
	gsize _vala_bytes_read = 0UL;
	gsize _vala_bytes_written = 0UL;
	gboolean _tmp1_ = FALSE;
	GError* _inner_error0_ = NULL;
	GConverterResult result;
	self = (CryptoSymmetricCipherDecrypter*) base;
	if (((gsize) inbuf_length1) > (outbuf_length1 + ((CryptoSymmetricCipherConverter*) self)->attached_taglen)) {
		GError* _tmp0_;
		_tmp0_ = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_NO_SPACE, "CipherConverter needs at least the size of input as output space");
		_inner_error0_ = _tmp0_;
		if (_inner_error0_->domain == G_IO_ERROR) {
			g_propagate_error (error, _inner_error0_);
			return 0;
		} else {
			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 0;
		}
	}
	if ((flags & G_CONVERTER_INPUT_AT_END) != 0) {
		_tmp1_ = ((gsize) inbuf_length1) < ((CryptoSymmetricCipherConverter*) self)->attached_taglen;
	} else {
		_tmp1_ = FALSE;
	}
	if (_tmp1_) {
		GError* _tmp2_;
		_tmp2_ = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_PARTIAL_INPUT, "CipherConverter needs additional input to read tag");
		_inner_error0_ = _tmp2_;
		if (_inner_error0_->domain == G_IO_ERROR) {
			g_propagate_error (error, _inner_error0_);
			return 0;
		} else {
			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 0;
		}
	} else {
		gboolean _tmp3_ = FALSE;
		if ((flags & G_CONVERTER_INPUT_AT_END) == 0) {
			_tmp3_ = ((gsize) inbuf_length1) < (((CryptoSymmetricCipherConverter*) self)->attached_taglen + 1);
		} else {
			_tmp3_ = FALSE;
		}
		if (_tmp3_) {
			GError* _tmp4_;
			_tmp4_ = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_PARTIAL_INPUT, "CipherConverter needs additional input to make sure to not accidentall" \
"y read tag");
			_inner_error0_ = _tmp4_;
			if (_inner_error0_->domain == G_IO_ERROR) {
				g_propagate_error (error, _inner_error0_);
				return 0;
			} else {
				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 0;
			}
		}
	}
	{
		inbuf_length1 = inbuf_length1 - ((gint) ((CryptoSymmetricCipherConverter*) self)->attached_taglen);
		if (inbuf_length1 > 0) {
			CryptoSymmetricCipher* _tmp5_;
			_tmp5_ = ((CryptoSymmetricCipherConverter*) self)->cipher;
			crypto_symmetric_cipher_decrypt (_tmp5_, outbuf, (gint) outbuf_length1, inbuf, (gint) inbuf_length1, &_inner_error0_);
			if (G_UNLIKELY (_inner_error0_ != NULL)) {
				if (_inner_error0_->domain == CRYPTO_ERROR) {
					goto __catch0_crypto_error;
				}
				g_critical ("file %s: line %d: unexpected 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 0;
			}
		}
		_vala_bytes_read = (gsize) inbuf_length1;
		_vala_bytes_written = (gsize) inbuf_length1;
		inbuf_length1 = inbuf_length1 + ((gint) ((CryptoSymmetricCipherConverter*) self)->attached_taglen);
		if ((flags & G_CONVERTER_INPUT_AT_END) != 0) {
			if (((CryptoSymmetricCipherConverter*) self)->attached_taglen > ((gsize) 0)) {
				crypto_symmetric_cipher_converter_check_tag ((CryptoSymmetricCipherConverter*) self, inbuf + ((gint) (inbuf_length1 - ((CryptoSymmetricCipherConverter*) self)->attached_taglen)), (gint) (inbuf_length1 - ((gint) (inbuf_length1 - ((CryptoSymmetricCipherConverter*) self)->attached_taglen))), &_inner_error0_);
				if (G_UNLIKELY (_inner_error0_ != NULL)) {
					if (_inner_error0_->domain == CRYPTO_ERROR) {
						goto __catch0_crypto_error;
					}
					g_critical ("file %s: line %d: unexpected 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 0;
				}
				_vala_bytes_read = (gsize) inbuf_length1;
			}
			result = G_CONVERTER_FINISHED;
			if (bytes_read) {
				*bytes_read = _vala_bytes_read;
			}
			if (bytes_written) {
				*bytes_written = _vala_bytes_written;
			}
			return result;
		}
		if ((flags & G_CONVERTER_FLUSH) != 0) {
			result = G_CONVERTER_FLUSHED;
			if (bytes_read) {
				*bytes_read = _vala_bytes_read;
			}
			if (bytes_written) {
				*bytes_written = _vala_bytes_written;
			}
			return result;
		}
		result = G_CONVERTER_CONVERTED;
		if (bytes_read) {
			*bytes_read = _vala_bytes_read;
		}
		if (bytes_written) {
			*bytes_written = _vala_bytes_written;
		}
		return result;
	}
	goto __finally0;
	__catch0_crypto_error:
	{
		GError* e = NULL;
		GError* _tmp6_;
		const gchar* _tmp7_;
		GError* _tmp8_;
		const gchar* _tmp9_;
		const gchar* _tmp10_;
		gchar* _tmp11_;
		gchar* _tmp12_;
		GError* _tmp13_;
		GError* _tmp14_;
		e = _inner_error0_;
		_inner_error0_ = NULL;
		_tmp6_ = e;
		_tmp7_ = g_quark_to_string (_tmp6_->domain);
		_tmp8_ = e;
		_tmp9_ = _tmp8_->message;
		_tmp10_ = string_to_string (_tmp9_);
		_tmp11_ = g_strconcat (_tmp7_, " error while decrypting: ", _tmp10_, NULL);
		_tmp12_ = _tmp11_;
		_tmp13_ = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_FAILED, _tmp12_);
		_tmp14_ = _tmp13_;
		_g_free0 (_tmp12_);
		_inner_error0_ = _tmp14_;
		_g_error_free0 (e);
		goto __finally0;
	}
	__finally0:
	if (_inner_error0_->domain == G_IO_ERROR) {
		g_propagate_error (error, _inner_error0_);
		return 0;
	} else {
		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 0;
	}
}

static void
crypto_symmetric_cipher_decrypter_class_init (CryptoSymmetricCipherDecrypterClass * klass,
                                              gpointer klass_data)
{
	crypto_symmetric_cipher_decrypter_parent_class = g_type_class_peek_parent (klass);
	((CryptoSymmetricCipherConverterClass *) klass)->convert = (GConverterResult (*) (CryptoSymmetricCipherConverter*, guint8*, gsize, guint8*, gsize, GConverterFlags, gsize*, gsize*, GError**)) crypto_symmetric_cipher_decrypter_real_convert;
}

static void
crypto_symmetric_cipher_decrypter_instance_init (CryptoSymmetricCipherDecrypter * self,
                                                 gpointer klass)
{
}

static GType
crypto_symmetric_cipher_decrypter_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (CryptoSymmetricCipherDecrypterClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) crypto_symmetric_cipher_decrypter_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (CryptoSymmetricCipherDecrypter), 0, (GInstanceInitFunc) crypto_symmetric_cipher_decrypter_instance_init, NULL };
	GType crypto_symmetric_cipher_decrypter_type_id;
	crypto_symmetric_cipher_decrypter_type_id = g_type_register_static (CRYPTO_TYPE_SYMMETRIC_CIPHER_CONVERTER, "CryptoSymmetricCipherDecrypter", &g_define_type_info, 0);
	return crypto_symmetric_cipher_decrypter_type_id;
}

GType
crypto_symmetric_cipher_decrypter_get_type (void)
{
	static volatile gsize crypto_symmetric_cipher_decrypter_type_id__once = 0;
	if (g_once_init_enter (&crypto_symmetric_cipher_decrypter_type_id__once)) {
		GType crypto_symmetric_cipher_decrypter_type_id;
		crypto_symmetric_cipher_decrypter_type_id = crypto_symmetric_cipher_decrypter_get_type_once ();
		g_once_init_leave (&crypto_symmetric_cipher_decrypter_type_id__once, crypto_symmetric_cipher_decrypter_type_id);
	}
	return crypto_symmetric_cipher_decrypter_type_id__once;
}

