/* rfc822-gmime-filter-blockquotes.c generated by valac 0.56.19, the Vala compiler
 * generated from rfc822-gmime-filter-blockquotes.vala, do not modify */

/* Copyright 2016 Software Freedom Conservancy Inc.
*
* This software is licensed under the GNU Lesser General Public License
* (version 2.1 or later).  See the COPYING file in this distribution.
*/
/* Filter to insert blockquotes, put a div around the signature marker, and wrap the whole thing*/
/* in a styled div.*/

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

#define GEARY_RF_C822_TYPE_FILTER_BLOCKQUOTES (geary_rf_c822_filter_blockquotes_get_type ())
#define GEARY_RF_C822_FILTER_BLOCKQUOTES(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEARY_RF_C822_TYPE_FILTER_BLOCKQUOTES, GearyRFC822FilterBlockquotes))
#define GEARY_RF_C822_FILTER_BLOCKQUOTES_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEARY_RF_C822_TYPE_FILTER_BLOCKQUOTES, GearyRFC822FilterBlockquotesClass))
#define GEARY_RF_C822_IS_FILTER_BLOCKQUOTES(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEARY_RF_C822_TYPE_FILTER_BLOCKQUOTES))
#define GEARY_RF_C822_IS_FILTER_BLOCKQUOTES_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEARY_RF_C822_TYPE_FILTER_BLOCKQUOTES))
#define GEARY_RF_C822_FILTER_BLOCKQUOTES_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEARY_RF_C822_TYPE_FILTER_BLOCKQUOTES, GearyRFC822FilterBlockquotesClass))

typedef struct _GearyRFC822FilterBlockquotes GearyRFC822FilterBlockquotes;
typedef struct _GearyRFC822FilterBlockquotesClass GearyRFC822FilterBlockquotesClass;
typedef struct _GearyRFC822FilterBlockquotesPrivate GearyRFC822FilterBlockquotesPrivate;
enum  {
	GEARY_RF_C822_FILTER_BLOCKQUOTES_0_PROPERTY,
	GEARY_RF_C822_FILTER_BLOCKQUOTES_NUM_PROPERTIES
};
static GParamSpec* geary_rf_c822_filter_blockquotes_properties[GEARY_RF_C822_FILTER_BLOCKQUOTES_NUM_PROPERTIES];

struct _GearyRFC822FilterBlockquotes {
	GMimeFilter parent_instance;
	GearyRFC822FilterBlockquotesPrivate * priv;
};

struct _GearyRFC822FilterBlockquotesClass {
	GMimeFilterClass parent_class;
};

struct _GearyRFC822FilterBlockquotesPrivate {
	gboolean in_prefix;
	gboolean in_tag;
	guint last_quote_level;
	guint current_quote_level;
	gboolean initial_element;
};

static gint GearyRFC822FilterBlockquotes_private_offset;
static gpointer geary_rf_c822_filter_blockquotes_parent_class = NULL;

VALA_EXTERN GType geary_rf_c822_filter_blockquotes_get_type (void) G_GNUC_CONST ;
VALA_EXTERN GearyRFC822FilterBlockquotes* geary_rf_c822_filter_blockquotes_new (void);
VALA_EXTERN GearyRFC822FilterBlockquotes* geary_rf_c822_filter_blockquotes_construct (GType object_type);
static void geary_rf_c822_filter_blockquotes_real_reset (GMimeFilter* base);
static GMimeFilter* geary_rf_c822_filter_blockquotes_real_copy (GMimeFilter* base);
static void geary_rf_c822_filter_blockquotes_do_filter (GearyRFC822FilterBlockquotes* self,
                                                 guint8* inbuf,
                                                 gsize inbuf_length1,
                                                 gsize prespace,
                                                 guint8** processed_buffer,
                                                 gsize* processed_buffer_length1,
                                                 gsize* outprespace,
                                                 gboolean flush);
static void geary_rf_c822_filter_blockquotes_insert_string (GearyRFC822FilterBlockquotes* self,
                                                     const gchar* str,
                                                     guint* out_index);
VALA_EXTERN gboolean geary_rf_c822_utils_comp_char_arr_slice (guint8* array,
                                                  gint array_length1,
                                                  guint start,
                                                  const gchar* comp);
static void geary_rf_c822_filter_blockquotes_real_filter (GMimeFilter* base,
                                                   guint8* inbuf,
                                                   gsize inbuf_length1,
                                                   gsize prespace,
                                                   guint8** processed_buffer,
                                                   gsize* processed_buffer_length1,
                                                   gsize* outprespace);
static void geary_rf_c822_filter_blockquotes_real_complete (GMimeFilter* base,
                                                     guint8* inbuf,
                                                     gsize inbuf_length1,
                                                     gsize prespace,
                                                     guint8** processed_buffer,
                                                     gsize* processed_buffer_length1,
                                                     gsize* outprespace);
static void geary_rf_c822_filter_blockquotes_finalize (GObject * obj);
static GType geary_rf_c822_filter_blockquotes_get_type_once (void);

static inline gpointer
geary_rf_c822_filter_blockquotes_get_instance_private (GearyRFC822FilterBlockquotes* self)
{
	return G_STRUCT_MEMBER_P (self, GearyRFC822FilterBlockquotes_private_offset);
}

GearyRFC822FilterBlockquotes*
geary_rf_c822_filter_blockquotes_construct (GType object_type)
{
	GearyRFC822FilterBlockquotes * self = NULL;
	self = (GearyRFC822FilterBlockquotes*) g_object_new (object_type, NULL);
	g_mime_filter_reset (G_TYPE_CHECK_INSTANCE_CAST (self, g_mime_filter_get_type (), GMimeFilter));
	return self;
}

GearyRFC822FilterBlockquotes*
geary_rf_c822_filter_blockquotes_new (void)
{
	return geary_rf_c822_filter_blockquotes_construct (GEARY_RF_C822_TYPE_FILTER_BLOCKQUOTES);
}

static void
geary_rf_c822_filter_blockquotes_real_reset (GMimeFilter* base)
{
	GearyRFC822FilterBlockquotes * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (base, GEARY_RF_C822_TYPE_FILTER_BLOCKQUOTES, GearyRFC822FilterBlockquotes);
	self->priv->in_prefix = TRUE;
	self->priv->in_tag = FALSE;
	self->priv->last_quote_level = (guint) 0;
	self->priv->current_quote_level = (guint) 0;
	self->priv->initial_element = FALSE;
}

static GMimeFilter*
geary_rf_c822_filter_blockquotes_real_copy (GMimeFilter* base)
{
	GearyRFC822FilterBlockquotes * self;
	GearyRFC822FilterBlockquotes* new_filter = NULL;
	GearyRFC822FilterBlockquotes* _tmp0_;
	GMimeFilter* result;
	self = G_TYPE_CHECK_INSTANCE_CAST (base, GEARY_RF_C822_TYPE_FILTER_BLOCKQUOTES, GearyRFC822FilterBlockquotes);
	_tmp0_ = geary_rf_c822_filter_blockquotes_new ();
	new_filter = _tmp0_;
	new_filter->priv->in_prefix = self->priv->in_prefix;
	new_filter->priv->in_tag = self->priv->in_tag;
	new_filter->priv->last_quote_level = self->priv->last_quote_level;
	new_filter->priv->current_quote_level = self->priv->current_quote_level;
	new_filter->priv->initial_element = self->priv->initial_element;
	result = G_TYPE_CHECK_INSTANCE_CAST (new_filter, g_mime_filter_get_type (), GMimeFilter);
	return result;
}

static void
geary_rf_c822_filter_blockquotes_do_filter (GearyRFC822FilterBlockquotes* self,
                                            guint8* inbuf,
                                            gsize inbuf_length1,
                                            gsize prespace,
                                            guint8** processed_buffer,
                                            gsize* processed_buffer_length1,
                                            gsize* outprespace,
                                            gboolean flush)
{
	guint8* _vala_processed_buffer = NULL;
	gsize _vala_processed_buffer_length1 = 0;
	gsize _vala_outprespace = 0UL;
	guint out_index = 0U;
	guint8* _tmp16_;
	gint _tmp16__length1;
	g_return_if_fail (GEARY_RF_C822_IS_FILTER_BLOCKQUOTES (self));
	g_mime_filter_set_size (G_TYPE_CHECK_INSTANCE_CAST (self, g_mime_filter_get_type (), GMimeFilter), (gsize) inbuf_length1, FALSE);
	out_index = (guint) 0;
	if (!self->priv->initial_element) {
		geary_rf_c822_filter_blockquotes_insert_string (self, "<div class=\"plaintext\" style=\"white-space: break-spaces;\">", &out_index);
		self->priv->initial_element = TRUE;
	}
	{
		guint i = 0U;
		i = (guint) 0;
		{
			gboolean _tmp0_ = FALSE;
			_tmp0_ = TRUE;
			while (TRUE) {
				guint8 c = 0U;
				guint8 _tmp2_;
				gboolean _tmp3_ = FALSE;
				if (!_tmp0_) {
					guint _tmp1_;
					_tmp1_ = i;
					i = _tmp1_ + 1;
				}
				_tmp0_ = FALSE;
				if (!(i < ((guint) inbuf_length1))) {
					break;
				}
				_tmp2_ = inbuf[i];
				c = _tmp2_;
				if (self->priv->in_prefix) {
					_tmp3_ = !self->priv->in_tag;
				} else {
					_tmp3_ = FALSE;
				}
				if (_tmp3_) {
					if (c == ((guint8) GEARY_RF_C822_UTILS_QUOTE_MARKER)) {
						guint _tmp4_;
						_tmp4_ = self->priv->current_quote_level;
						self->priv->current_quote_level = _tmp4_ + 1;
						continue;
					}
					if (c == ((guint8) '<')) {
						guint8* _tmp5_;
						gint _tmp5__length1;
						guint _tmp6_;
						guint8 _tmp7_;
						self->priv->in_tag = TRUE;
						_tmp5_ = G_TYPE_CHECK_INSTANCE_CAST (self, g_mime_filter_get_type (), GMimeFilter)->outbuf;
						_tmp5__length1 = G_TYPE_CHECK_INSTANCE_CAST (self, g_mime_filter_get_type (), GMimeFilter)->outsize;
						_tmp6_ = out_index;
						out_index = _tmp6_ + 1;
						_tmp7_ = c;
						_tmp5_[_tmp6_] = _tmp7_;
						continue;
					}
					while (TRUE) {
						if (!(self->priv->current_quote_level > self->priv->last_quote_level)) {
							break;
						}
						geary_rf_c822_filter_blockquotes_insert_string (self, "<blockquote>", &out_index);
						self->priv->last_quote_level = self->priv->last_quote_level + 1;
					}
					while (TRUE) {
						if (!(self->priv->current_quote_level < self->priv->last_quote_level)) {
							break;
						}
						geary_rf_c822_filter_blockquotes_insert_string (self, "</blockquote>", &out_index);
						self->priv->last_quote_level = self->priv->last_quote_level - 1;
					}
					self->priv->in_prefix = FALSE;
				}
				if (c == ((guint8) '\n')) {
					gboolean _tmp8_ = FALSE;
					if (out_index > ((guint) 3)) {
						guint8* _tmp9_;
						gint _tmp9__length1;
						_tmp9_ = G_TYPE_CHECK_INSTANCE_CAST (self, g_mime_filter_get_type (), GMimeFilter)->outbuf;
						_tmp9__length1 = G_TYPE_CHECK_INSTANCE_CAST (self, g_mime_filter_get_type (), GMimeFilter)->outsize;
						_tmp8_ = geary_rf_c822_utils_comp_char_arr_slice (_tmp9_, (gint) _tmp9__length1, out_index - 4, "\n-- ");
					} else {
						_tmp8_ = FALSE;
					}
					if (_tmp8_) {
						out_index -= (guint) 3;
						geary_rf_c822_filter_blockquotes_insert_string (self, "<div>-- \n</div>", &out_index);
					} else {
						guint8* _tmp10_;
						gint _tmp10__length1;
						guint _tmp11_;
						guint8 _tmp12_;
						_tmp10_ = G_TYPE_CHECK_INSTANCE_CAST (self, g_mime_filter_get_type (), GMimeFilter)->outbuf;
						_tmp10__length1 = G_TYPE_CHECK_INSTANCE_CAST (self, g_mime_filter_get_type (), GMimeFilter)->outsize;
						_tmp11_ = out_index;
						out_index = _tmp11_ + 1;
						_tmp12_ = c;
						_tmp10_[_tmp11_] = _tmp12_;
					}
					self->priv->in_prefix = TRUE;
					self->priv->current_quote_level = (guint) 0;
				} else {
					guint8* _tmp13_;
					gint _tmp13__length1;
					guint _tmp14_;
					guint8 _tmp15_;
					if (c == ((guint8) '>')) {
						self->priv->in_tag = FALSE;
					}
					_tmp13_ = G_TYPE_CHECK_INSTANCE_CAST (self, g_mime_filter_get_type (), GMimeFilter)->outbuf;
					_tmp13__length1 = G_TYPE_CHECK_INSTANCE_CAST (self, g_mime_filter_get_type (), GMimeFilter)->outsize;
					_tmp14_ = out_index;
					out_index = _tmp14_ + 1;
					_tmp15_ = c;
					_tmp13_[_tmp14_] = _tmp15_;
				}
			}
		}
	}
	if (flush) {
		while (TRUE) {
			if (!(self->priv->last_quote_level > ((guint) 0))) {
				break;
			}
			geary_rf_c822_filter_blockquotes_insert_string (self, "</blockquote>", &out_index);
			self->priv->last_quote_level = self->priv->last_quote_level - 1;
		}
		geary_rf_c822_filter_blockquotes_insert_string (self, "</div>", &out_index);
	}
	_tmp16_ = G_TYPE_CHECK_INSTANCE_CAST (self, g_mime_filter_get_type (), GMimeFilter)->outbuf;
	_tmp16__length1 = G_TYPE_CHECK_INSTANCE_CAST (self, g_mime_filter_get_type (), GMimeFilter)->outsize;
	_vala_processed_buffer = _tmp16_ + 0;
	_vala_processed_buffer_length1 = ((gint) out_index) - 0;
	_vala_outprespace = G_TYPE_CHECK_INSTANCE_CAST (self, g_mime_filter_get_type (), GMimeFilter)->outpre;
	if (processed_buffer) {
		*processed_buffer = _vala_processed_buffer;
	}
	if (processed_buffer_length1) {
		*processed_buffer_length1 = _vala_processed_buffer_length1;
	}
	if (outprespace) {
		*outprespace = _vala_outprespace;
	}
}

static void
geary_rf_c822_filter_blockquotes_real_filter (GMimeFilter* base,
                                              guint8* inbuf,
                                              gsize inbuf_length1,
                                              gsize prespace,
                                              guint8** processed_buffer,
                                              gsize* processed_buffer_length1,
                                              gsize* outprespace)
{
	GearyRFC822FilterBlockquotes * self;
	guint8* _vala_processed_buffer = NULL;
	gsize _vala_processed_buffer_length1 = 0;
	gsize _vala_outprespace = 0UL;
	guint8* _tmp0_ = NULL;
	gsize _tmp1_ = 0;
	gsize _tmp2_ = 0UL;
	self = G_TYPE_CHECK_INSTANCE_CAST (base, GEARY_RF_C822_TYPE_FILTER_BLOCKQUOTES, GearyRFC822FilterBlockquotes);
	geary_rf_c822_filter_blockquotes_do_filter (self, inbuf, (gsize) inbuf_length1, prespace, &_tmp0_, &_tmp1_, &_tmp2_, FALSE);
	_vala_processed_buffer = _tmp0_;
	_vala_processed_buffer_length1 = _tmp1_;
	_vala_outprespace = _tmp2_;
	if (processed_buffer) {
		*processed_buffer = _vala_processed_buffer;
	}
	if (processed_buffer_length1) {
		*processed_buffer_length1 = _vala_processed_buffer_length1;
	}
	if (outprespace) {
		*outprespace = _vala_outprespace;
	}
}

static void
geary_rf_c822_filter_blockquotes_real_complete (GMimeFilter* base,
                                                guint8* inbuf,
                                                gsize inbuf_length1,
                                                gsize prespace,
                                                guint8** processed_buffer,
                                                gsize* processed_buffer_length1,
                                                gsize* outprespace)
{
	GearyRFC822FilterBlockquotes * self;
	guint8* _vala_processed_buffer = NULL;
	gsize _vala_processed_buffer_length1 = 0;
	gsize _vala_outprespace = 0UL;
	guint8* _tmp0_ = NULL;
	gsize _tmp1_ = 0;
	gsize _tmp2_ = 0UL;
	self = G_TYPE_CHECK_INSTANCE_CAST (base, GEARY_RF_C822_TYPE_FILTER_BLOCKQUOTES, GearyRFC822FilterBlockquotes);
	geary_rf_c822_filter_blockquotes_do_filter (self, inbuf, (gsize) inbuf_length1, prespace, &_tmp0_, &_tmp1_, &_tmp2_, TRUE);
	_vala_processed_buffer = _tmp0_;
	_vala_processed_buffer_length1 = _tmp1_;
	_vala_outprespace = _tmp2_;
	if (processed_buffer) {
		*processed_buffer = _vala_processed_buffer;
	}
	if (processed_buffer_length1) {
		*processed_buffer_length1 = _vala_processed_buffer_length1;
	}
	if (outprespace) {
		*outprespace = _vala_outprespace;
	}
}

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;
}

static void
geary_rf_c822_filter_blockquotes_insert_string (GearyRFC822FilterBlockquotes* self,
                                                const gchar* str,
                                                guint* out_index)
{
	guint8* _tmp0_;
	gint _tmp0__length1;
	gint _tmp1_;
	gint _tmp2_;
	g_return_if_fail (GEARY_RF_C822_IS_FILTER_BLOCKQUOTES (self));
	g_return_if_fail (str != NULL);
	_tmp0_ = G_TYPE_CHECK_INSTANCE_CAST (self, g_mime_filter_get_type (), GMimeFilter)->outbuf;
	_tmp0__length1 = G_TYPE_CHECK_INSTANCE_CAST (self, g_mime_filter_get_type (), GMimeFilter)->outsize;
	_tmp1_ = strlen (str);
	_tmp2_ = _tmp1_;
	g_mime_filter_set_size (G_TYPE_CHECK_INSTANCE_CAST (self, g_mime_filter_get_type (), GMimeFilter), (gsize) (_tmp0__length1 + _tmp2_), TRUE);
	{
		gint i = 0;
		i = 0;
		{
			gboolean _tmp3_ = FALSE;
			_tmp3_ = TRUE;
			while (TRUE) {
				gint _tmp5_;
				gint _tmp6_;
				guint8* _tmp7_;
				gint _tmp7__length1;
				guint _tmp8_;
				if (!_tmp3_) {
					gint _tmp4_;
					_tmp4_ = i;
					i = _tmp4_ + 1;
				}
				_tmp3_ = FALSE;
				_tmp5_ = strlen (str);
				_tmp6_ = _tmp5_;
				if (!(i < _tmp6_)) {
					break;
				}
				_tmp7_ = G_TYPE_CHECK_INSTANCE_CAST (self, g_mime_filter_get_type (), GMimeFilter)->outbuf;
				_tmp7__length1 = G_TYPE_CHECK_INSTANCE_CAST (self, g_mime_filter_get_type (), GMimeFilter)->outsize;
				_tmp8_ = *out_index;
				*out_index = _tmp8_ + 1;
				_tmp7_[_tmp8_] = (guint8) string_get (str, (glong) i);
			}
		}
	}
}

static void
geary_rf_c822_filter_blockquotes_class_init (GearyRFC822FilterBlockquotesClass * klass,
                                             gpointer klass_data)
{
	geary_rf_c822_filter_blockquotes_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &GearyRFC822FilterBlockquotes_private_offset);
	((GMimeFilterClass *) klass)->reset = (void (*) (GMimeFilter*)) geary_rf_c822_filter_blockquotes_real_reset;
	((GMimeFilterClass *) klass)->copy = (GMimeFilter* (*) (GMimeFilter*)) geary_rf_c822_filter_blockquotes_real_copy;
	((GMimeFilterClass *) klass)->filter = (void (*) (GMimeFilter*, guint8*, gsize, gsize, guint8**, gsize*, gsize*)) geary_rf_c822_filter_blockquotes_real_filter;
	((GMimeFilterClass *) klass)->complete = (void (*) (GMimeFilter*, guint8*, gsize, gsize, guint8**, gsize*, gsize*)) geary_rf_c822_filter_blockquotes_real_complete;
	G_OBJECT_CLASS (klass)->finalize = geary_rf_c822_filter_blockquotes_finalize;
}

static void
geary_rf_c822_filter_blockquotes_instance_init (GearyRFC822FilterBlockquotes * self,
                                                gpointer klass)
{
	self->priv = geary_rf_c822_filter_blockquotes_get_instance_private (self);
}

static void
geary_rf_c822_filter_blockquotes_finalize (GObject * obj)
{
	GearyRFC822FilterBlockquotes * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, GEARY_RF_C822_TYPE_FILTER_BLOCKQUOTES, GearyRFC822FilterBlockquotes);
	G_OBJECT_CLASS (geary_rf_c822_filter_blockquotes_parent_class)->finalize (obj);
}

 G_GNUC_NO_INLINE static GType
geary_rf_c822_filter_blockquotes_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (GearyRFC822FilterBlockquotesClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) geary_rf_c822_filter_blockquotes_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (GearyRFC822FilterBlockquotes), 0, (GInstanceInitFunc) geary_rf_c822_filter_blockquotes_instance_init, NULL };
	GType geary_rf_c822_filter_blockquotes_type_id;
	geary_rf_c822_filter_blockquotes_type_id = g_type_register_static (g_mime_filter_get_type (), "GearyRFC822FilterBlockquotes", &g_define_type_info, 0);
	GearyRFC822FilterBlockquotes_private_offset = g_type_add_instance_private (geary_rf_c822_filter_blockquotes_type_id, sizeof (GearyRFC822FilterBlockquotesPrivate));
	return geary_rf_c822_filter_blockquotes_type_id;
}

GType
geary_rf_c822_filter_blockquotes_get_type (void)
{
	static gsize geary_rf_c822_filter_blockquotes_type_id__once = 0;
	if (g_once_init_enter (&geary_rf_c822_filter_blockquotes_type_id__once)) {
		GType geary_rf_c822_filter_blockquotes_type_id;
		geary_rf_c822_filter_blockquotes_type_id = geary_rf_c822_filter_blockquotes_get_type_once ();
		g_once_init_leave (&geary_rf_c822_filter_blockquotes_type_id__once, geary_rf_c822_filter_blockquotes_type_id);
	}
	return geary_rf_c822_filter_blockquotes_type_id__once;
}

