/* imap-data-format.c generated by valac 0.56.19, the Vala compiler
 * generated from imap-data-format.vala, do not modify */

/*
 * Copyright © 2016 Software Freedom Conservancy Inc.
 * Copyright © 2020 Micahel Gratton <mike@vee.net>
 *
 * This software is licensed under the GNU Lesser General Public License
 * (version 2.1 or later). See the COPYING file in this distribution.
 */

#include <glib.h>
#include "geary-engine.h"
#include <stdlib.h>
#include <string.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

VALA_EXTERN gboolean geary_imap_data_format_is_special_char (gchar ch,
                                                 gchar* ar,
                                                 gint ar_length1,
                                                 const gchar* exceptions);
static gboolean _vala_char_array_contains (gchar * stack,
                                    gssize stack_length,
                                    const gchar needle);

const gchar GEARY_IMAP_DATA_FORMAT_ATOM_SPECIALS[9] = {'(', ')', '{', ' ', '%', '*', '"', '\\', ']'};
const gchar GEARY_IMAP_DATA_FORMAT_TAG_SPECIALS[9] = {'(', ')', '{', ' ', '%', '*', '"', '\\', '+'};

 G_GNUC_NO_INLINE static GType
geary_imap_data_format_quoting_get_type_once (void)
{
	static const GEnumValue values[] = {{GEARY_IMAP_DATA_FORMAT_QUOTING_REQUIRED, "GEARY_IMAP_DATA_FORMAT_QUOTING_REQUIRED", "required"}, {GEARY_IMAP_DATA_FORMAT_QUOTING_OPTIONAL, "GEARY_IMAP_DATA_FORMAT_QUOTING_OPTIONAL", "optional"}, {GEARY_IMAP_DATA_FORMAT_QUOTING_UNALLOWED, "GEARY_IMAP_DATA_FORMAT_QUOTING_UNALLOWED", "unallowed"}, {0, NULL, NULL}};
	GType geary_imap_data_format_quoting_type_id;
	geary_imap_data_format_quoting_type_id = g_enum_register_static ("GearyImapDataFormatQuoting", values);
	return geary_imap_data_format_quoting_type_id;
}

GType
geary_imap_data_format_quoting_get_type (void)
{
	static gsize geary_imap_data_format_quoting_type_id__once = 0;
	if (g_once_init_enter (&geary_imap_data_format_quoting_type_id__once)) {
		GType geary_imap_data_format_quoting_type_id;
		geary_imap_data_format_quoting_type_id = geary_imap_data_format_quoting_get_type_once ();
		g_once_init_leave (&geary_imap_data_format_quoting_type_id__once, geary_imap_data_format_quoting_type_id);
	}
	return geary_imap_data_format_quoting_type_id__once;
}

/**
     * Returns true if the character is considered an atom-special.
     *
     * Note that while documentation indicates that the backslash
     * cannot be used in an atom, they *are* used for message flags
     * and thus must be special cased by the caller.
     */
gboolean
geary_imap_data_format_is_atom_special (gchar ch,
                                        const gchar* exceptions)
{
	gboolean result;
	result = geary_imap_data_format_is_special_char (ch, GEARY_IMAP_DATA_FORMAT_ATOM_SPECIALS, (gint) G_N_ELEMENTS (GEARY_IMAP_DATA_FORMAT_ATOM_SPECIALS), exceptions);
	return result;
}

/**
     * Returns true if the character is considered a tag-special.
     *
     * Tag specials are like atom specials but include the
     * continuation character ('+'). Also, the star character is
     * allowed, although technically only correct in the context of a
     * status response; it's the responsibility of the caller to catch
     * this.
     */
gboolean
geary_imap_data_format_is_tag_special (gchar ch,
                                       const gchar* exceptions)
{
	gboolean result;
	result = geary_imap_data_format_is_special_char (ch, GEARY_IMAP_DATA_FORMAT_TAG_SPECIALS, (gint) G_N_ELEMENTS (GEARY_IMAP_DATA_FORMAT_TAG_SPECIALS), exceptions);
	return result;
}

/**
     * Determines quoting policy for a string to be sent over the wire.
     */
static gchar
string_get (const gchar* self,
            glong index)
{
	gchar _tmp0_;
	gchar result;
	g_return_val_if_fail (self != NULL, '\0');
	_tmp0_ = ((gchar*) self)[index];
	result = _tmp0_;
	return result;
}

GearyImapDataFormatQuoting
geary_imap_data_format_is_quoting_required (const gchar* str)
{
	gint index = 0;
	GearyImapDataFormatQuoting result;
	g_return_val_if_fail (str != NULL, 0);
	if (geary_string_is_empty (str)) {
		result = GEARY_IMAP_DATA_FORMAT_QUOTING_REQUIRED;
		return result;
	}
	index = 0;
	{
		gboolean _tmp0_ = FALSE;
		_tmp0_ = TRUE;
		while (TRUE) {
			gchar ch = '\0';
			gint _tmp1_;
			if (!_tmp0_) {
			}
			_tmp0_ = FALSE;
			_tmp1_ = index;
			index = _tmp1_ + 1;
			ch = string_get (str, (glong) _tmp1_);
			if (ch == GEARY_STRING_EOS) {
				break;
			}
			if (((gint) ch) > 0x7F) {
				result = GEARY_IMAP_DATA_FORMAT_QUOTING_UNALLOWED;
				return result;
			}
			switch (ch) {
				case '\n':
				case '\r':
				{
					result = GEARY_IMAP_DATA_FORMAT_QUOTING_UNALLOWED;
					return result;
				}
				default:
				{
					if (geary_imap_data_format_is_atom_special (ch, NULL)) {
						result = GEARY_IMAP_DATA_FORMAT_QUOTING_REQUIRED;
						return result;
					}
					break;
				}
			}
		}
	}
	result = GEARY_IMAP_DATA_FORMAT_QUOTING_OPTIONAL;
	return result;
}

static gboolean
_vala_char_array_contains (gchar * stack,
                           gssize stack_length,
                           const gchar needle)
{
	gssize i;
	for (i = 0; i < stack_length; i++) {
		if (needle == stack[i]) {
			return TRUE;
		}
	}
	return FALSE;
}

inline gboolean
geary_imap_data_format_is_special_char (gchar ch,
                                        gchar* ar,
                                        gint ar_length1,
                                        const gchar* exceptions)
{
	gboolean _tmp0_ = FALSE;
	gboolean result;
	if (((gint) ch) <= 0x1F) {
		_tmp0_ = TRUE;
	} else {
		_tmp0_ = ((gint) ch) >= 0x7F;
	}
	if (_tmp0_) {
		result = TRUE;
		return result;
	}
	if (_vala_char_array_contains (ar, ar_length1, ch)) {
		gboolean _tmp1_ = FALSE;
		if (exceptions != NULL) {
			_tmp1_ = geary_ascii_index_of (exceptions, ch) < 0;
		} else {
			_tmp1_ = TRUE;
		}
		result = _tmp1_;
		return result;
	}
	result = FALSE;
	return result;
}

