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

/*
 * This file is part of gitg
 *
 * Copyright (C) 2015 - Jesse van den Kieboom
 *
 * gitg is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * gitg 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with gitg. If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdlib.h>
#include <string.h>
#include <glib.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 _g_free0(var) (var = (g_free (var), NULL))
#define _g_string_free0(var) ((var == NULL) ? NULL : (var = (g_string_free (var, TRUE), NULL)))

VALA_EXTERN void gitg_convert_utf8_validate_fallback (gchar** text,
                                          gssize size);
VALA_EXTERN gchar* gitg_convert_convert_fallback (const gchar* text,
                                      gssize size,
                                      const gchar* fallback);
VALA_EXTERN gboolean gitg_convert_convert_and_check (const gchar* text,
                                         gssize size,
                                         const gchar* from_charset,
                                         gchar** ret);
VALA_EXTERN gchar* gitg_convert_utf8 (const gchar* str,
                          gssize size,
                          const gchar* from_charset);

void
gitg_convert_utf8_validate_fallback (gchar** text,
                                     gssize size)
{
	gchar* end = NULL;
	g_return_if_fail (*text != NULL);
	while (TRUE) {
		gchar* _tmp0_ = NULL;
		gboolean _tmp1_;
		gchar* _tmp2_;
		_tmp1_ = g_utf8_validate (*text, size, &_tmp0_);
		end = _tmp0_;
		if (!(!_tmp1_)) {
			break;
		}
		_tmp2_ = end;
		*_tmp2_ = '?';
	}
}

gchar*
gitg_convert_convert_fallback (const gchar* text,
                               gssize size,
                               const gchar* fallback)
{
	gchar* res = NULL;
	gchar* _tmp0_;
	gsize read = 0UL;
	GString* str = NULL;
	GString* _tmp1_;
	GString* _tmp10_;
	const gchar* _tmp11_;
	gchar* retval = NULL;
	GString* _tmp12_;
	const gchar* _tmp13_;
	gchar* _tmp14_;
	GString* _tmp15_;
	GError* _inner_error0_ = NULL;
	gchar* result;
	g_return_val_if_fail (text != NULL, NULL);
	g_return_val_if_fail (fallback != NULL, NULL);
	_tmp0_ = g_strdup ("");
	res = _tmp0_;
	_tmp1_ = g_string_new ("");
	str = _tmp1_;
	while (TRUE) {
		{
			gchar* _tmp2_ = NULL;
			gsize _tmp3_ = 0UL;
			gchar* _tmp4_;
			gchar* _tmp5_;
			_tmp4_ = g_convert (text, size, "UTF-8", "ASCII", &_tmp3_, NULL, &_inner_error0_);
			read = _tmp3_;
			_tmp2_ = _tmp4_;
			if (G_UNLIKELY (_inner_error0_ != NULL)) {
				goto __catch0_g_error;
			}
			_tmp5_ = _tmp2_;
			_tmp2_ = NULL;
			_g_free0 (res);
			res = _tmp5_;
			_g_free0 (_tmp2_);
			break;
		}
		goto __finally0;
		__catch0_g_error:
		{
			GString* _tmp9_;
			g_clear_error (&_inner_error0_);
			{
				gchar* _tmp6_ = NULL;
				gchar* _tmp7_;
				GString* _tmp8_;
				_tmp7_ = g_convert (text, (gssize) read, "UTF-8", "ASCII", NULL, NULL, &_inner_error0_);
				_tmp6_ = _tmp7_;
				if (G_UNLIKELY (_inner_error0_ != NULL)) {
					goto __catch1_g_error;
				}
				_tmp8_ = str;
				g_string_append (_tmp8_, _tmp6_);
				_g_free0 (_tmp6_);
			}
			goto __finally1;
			__catch1_g_error:
			{
				g_clear_error (&_inner_error0_);
			}
			__finally1:
			if (G_UNLIKELY (_inner_error0_ != NULL)) {
				_g_string_free0 (str);
				_g_free0 (res);
				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 NULL;
			}
			_tmp9_ = str;
			g_string_append (_tmp9_, fallback);
			text = (const gchar*) (((guint8*) text) + ((gint) (read + 1)));
			size = size - ((gssize) read);
		}
		__finally0:
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			_g_string_free0 (str);
			_g_free0 (res);
			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;
		}
	}
	_tmp10_ = str;
	_tmp11_ = res;
	g_string_append (_tmp10_, _tmp11_);
	_tmp12_ = str;
	_tmp13_ = _tmp12_->str;
	_tmp14_ = g_strdup (_tmp13_);
	retval = _tmp14_;
	_tmp15_ = str;
	gitg_convert_utf8_validate_fallback (&retval, _tmp15_->len);
	result = retval;
	_g_string_free0 (str);
	_g_free0 (res);
	return result;
}

gboolean
gitg_convert_convert_and_check (const gchar* text,
                                gssize size,
                                const gchar* from_charset,
                                gchar** ret)
{
	gchar* _vala_ret = NULL;
	gsize read = 0UL;
	gsize written = 0UL;
	GError* _inner_error0_ = NULL;
	gboolean result;
	g_return_val_if_fail (text != NULL, FALSE);
	g_return_val_if_fail (from_charset != NULL, FALSE);
	_g_free0 (_vala_ret);
	_vala_ret = NULL;
	{
		gchar* _tmp0_ = NULL;
		gsize _tmp1_ = 0UL;
		gsize _tmp2_ = 0UL;
		gchar* _tmp3_;
		gchar* _tmp4_;
		_tmp3_ = g_convert (text, size, "UTF-8", from_charset, &_tmp1_, &_tmp2_, &_inner_error0_);
		read = _tmp1_;
		written = _tmp2_;
		_tmp0_ = _tmp3_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			goto __catch0_g_error;
		}
		_tmp4_ = _tmp0_;
		_tmp0_ = NULL;
		_g_free0 (_vala_ret);
		_vala_ret = _tmp4_;
		if (read == ((gsize) size)) {
			gitg_convert_utf8_validate_fallback (&_vala_ret, (gssize) written);
			result = TRUE;
			_g_free0 (_tmp0_);
			if (ret) {
				*ret = _vala_ret;
			} else {
				_g_free0 (_vala_ret);
			}
			return result;
		}
		_g_free0 (_tmp0_);
	}
	goto __finally0;
	__catch0_g_error:
	{
		g_clear_error (&_inner_error0_);
	}
	__finally0:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		gboolean _tmp5_ = FALSE;
		_g_free0 (_vala_ret);
		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 _tmp5_;
	}
	result = FALSE;
	if (ret) {
		*ret = _vala_ret;
	} else {
		_g_free0 (_vala_ret);
	}
	return result;
}

static gchar*
string_slice (const gchar* self,
              glong start,
              glong end)
{
	glong string_length = 0L;
	gint _tmp0_;
	gint _tmp1_;
	gboolean _tmp2_ = FALSE;
	gboolean _tmp3_ = FALSE;
	gchar* _tmp4_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = strlen (self);
	_tmp1_ = _tmp0_;
	string_length = (glong) _tmp1_;
	if (start < ((glong) 0)) {
		start = string_length + start;
	}
	if (end < ((glong) 0)) {
		end = string_length + end;
	}
	if (start >= ((glong) 0)) {
		_tmp2_ = start <= string_length;
	} else {
		_tmp2_ = FALSE;
	}
	g_return_val_if_fail (_tmp2_, NULL);
	if (end >= ((glong) 0)) {
		_tmp3_ = end <= string_length;
	} else {
		_tmp3_ = FALSE;
	}
	g_return_val_if_fail (_tmp3_, NULL);
	g_return_val_if_fail (start <= end, NULL);
	_tmp4_ = g_strndup (((gchar*) self) + start, (gsize) (end - start));
	result = _tmp4_;
	return result;
}

gchar*
gitg_convert_utf8 (const gchar* str,
                   gssize size,
                   const gchar* from_charset)
{
	gchar* locale_charset = NULL;
	const gchar* _tmp6_ = NULL;
	gboolean _tmp7_;
	gchar* _tmp8_;
	gchar* _tmp12_;
	gchar* result;
	g_return_val_if_fail (str != NULL, NULL);
	if (size == ((gssize) -1)) {
		gint _tmp0_;
		gint _tmp1_;
		_tmp0_ = strlen (str);
		_tmp1_ = _tmp0_;
		size = (gssize) _tmp1_;
	}
	if (from_charset == NULL) {
		if (g_utf8_validate (str, size, NULL)) {
			gchar* _tmp2_;
			_tmp2_ = string_slice (str, (glong) 0, (glong) size);
			result = _tmp2_;
			return result;
		}
	} else {
		gchar* ret = NULL;
		gchar* _tmp4_ = NULL;
		gboolean _tmp5_;
		if (g_ascii_strcasecmp (from_charset, "UTF-8") == 0) {
			gchar* _tmp3_;
			_tmp3_ = string_slice (str, (glong) 0, (glong) size);
			_g_free0 (ret);
			ret = _tmp3_;
			gitg_convert_utf8_validate_fallback (&ret, size);
			result = ret;
			return result;
		}
		_tmp5_ = gitg_convert_convert_and_check (str, size, from_charset, &_tmp4_);
		_g_free0 (ret);
		ret = _tmp4_;
		if (_tmp5_) {
			result = ret;
			return result;
		}
		_g_free0 (ret);
	}
	_tmp7_ = g_get_charset (&_tmp6_);
	_g_free0 (locale_charset);
	_tmp8_ = g_strdup (_tmp6_);
	locale_charset = _tmp8_;
	if (!_tmp7_) {
		gchar* ret = NULL;
		const gchar* _tmp9_;
		gchar* _tmp10_ = NULL;
		gboolean _tmp11_;
		_tmp9_ = locale_charset;
		_tmp11_ = gitg_convert_convert_and_check (str, size, _tmp9_, &_tmp10_);
		_g_free0 (ret);
		ret = _tmp10_;
		if (_tmp11_) {
			result = ret;
			_g_free0 (locale_charset);
			return result;
		}
		_g_free0 (ret);
	}
	_tmp12_ = gitg_convert_convert_fallback (str, size, "?");
	result = _tmp12_;
	_g_free0 (locale_charset);
	return result;
}

