Re: Patch for TnyGtkTextBufferStream



On Tue, Feb 12, 2008 at 08:08:57PM +0100, Alberto Garcia wrote:

> However if it detects that an input buffer begins with non-UTF-8
> text then in this case it writes it, as there's not much to do about
> it anyway.

Second version of the patch. This is like the first one but if it
detects non-UTF-8 text in the middle of the buffer (not just in the
beginning, like the previous patch) then it writes it.

-- 
Alberto García González
http://people.igalia.com/berto/
Index: libtinymailui-gtk/tny-gtk-text-buffer-stream.c
===================================================================
--- libtinymailui-gtk/tny-gtk-text-buffer-stream.c	(revision 3399)
+++ libtinymailui-gtk/tny-gtk-text-buffer-stream.c	(working copy)
@@ -46,7 +46,7 @@
 {
 	GtkTextBuffer *buffer;
 	GtkTextIter cur;
-
+	GByteArray *pending_bytes;
 };
 
 #define TNY_GTK_TEXT_BUFFER_STREAM_GET_PRIVATE(o)	\
@@ -136,12 +136,32 @@
 {
 	TnyGtkTextBufferStreamPriv *priv = TNY_GTK_TEXT_BUFFER_STREAM_GET_PRIVATE (self);
 	const gchar *end;
+	gint nb_written;
 
-	if (g_utf8_validate (buffer, n, &end))
-		gtk_text_buffer_insert (priv->buffer, &(priv->cur), buffer, (gint)n);
-	else
-		gtk_text_buffer_insert (priv->buffer, &(priv->cur), end, (gint) (end - buffer));
+	g_byte_array_append (priv->pending_bytes, buffer, n);
 
+	/* GtkTextBuffer only accepts full UTF-8 chars, but we might
+	 * receive a single UTF-8 char split into two different
+	 * buffers -see camel_stream_write_to_stream()- so we write
+	 * only the part of the buffer that is valid UTF-8 text and
+	 * leave the rest for later */
+	g_utf8_validate (priv->pending_bytes->data, priv->pending_bytes->len, &end);
+	nb_written = (gint) (end - ((char *) priv->pending_bytes->data));
+
+	/* However if the rest of the buffer is more than 4 bytes long
+	 * (4 bytes being the max size of a UTF-8 char) then it's
+	 * certainly not a UTF-8 char divided in two. In this case it
+	 * means that the buffer is corrupt. There's not much to do
+	 * about it but to write it anyway */
+	if (priv->pending_bytes->len - nb_written >= 4) {
+		nb_written = priv->pending_bytes->len;
+	}
+
+	gtk_text_buffer_insert (priv->buffer, &(priv->cur), priv->pending_bytes->data, nb_written);
+
+	/* Leave the unwritten chars in priv->pending_bytes for later */
+	g_byte_array_remove_range (priv->pending_bytes, 0, nb_written);
+
 	return (gssize) n;
 }
 
@@ -154,6 +174,12 @@
 static gint
 tny_gtk_text_buffer_stream_flush_default (TnyStream *self)
 {
+	TnyGtkTextBufferStreamPriv *priv = TNY_GTK_TEXT_BUFFER_STREAM_GET_PRIVATE (self);
+	if (priv->pending_bytes->len > 0) {
+		gtk_text_buffer_insert (priv->buffer, &(priv->cur),
+					priv->pending_bytes->data, priv->pending_bytes->len);
+		g_byte_array_set_size (priv->pending_bytes, 0);
+	}
 	return 0;
 }
 
@@ -211,6 +237,7 @@
 {
 	TnyGtkTextBufferStreamPriv *priv = TNY_GTK_TEXT_BUFFER_STREAM_GET_PRIVATE (self);
 
+	tny_gtk_text_buffer_stream_flush (self);
 	return tny_gtk_text_buffer_stream_reset_priv (priv);
 }
 
@@ -236,6 +263,11 @@
 	g_object_ref (G_OBJECT (buffer));
 	priv->buffer = buffer;
 
+	if (!priv->pending_bytes)
+		priv->pending_bytes = g_byte_array_new ();
+
+	g_byte_array_set_size (priv->pending_bytes, 0);
+
 	tny_gtk_text_buffer_stream_reset_priv (priv);
 
 	return;
@@ -268,6 +300,7 @@
 	TnyGtkTextBufferStreamPriv *priv = TNY_GTK_TEXT_BUFFER_STREAM_GET_PRIVATE (self);
 
 	priv->buffer = NULL;
+	priv->pending_bytes = NULL;
 
 	return;
 }
@@ -278,8 +311,13 @@
 	TnyGtkTextBufferStream *self = (TnyGtkTextBufferStream *)object;	
 	TnyGtkTextBufferStreamPriv *priv = TNY_GTK_TEXT_BUFFER_STREAM_GET_PRIVATE (self);
 
+	if (priv->buffer && priv->pending_bytes)
+		tny_gtk_text_buffer_stream_flush (self);
+
 	if (priv->buffer)
 		g_object_unref (G_OBJECT (priv->buffer));
+	if (priv->pending_bytes)
+		g_byte_array_free (priv->pending_bytes, TRUE);
 
 	(*parent_class->finalize) (object);
 
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 3399)
+++ ChangeLog	(working copy)
@@ -1,3 +1,10 @@
+2008-02-12  Alberto Garcia Gonzalez <agarcia igalia com>
+
+	* libtinymailui-gtk/tny-gtk-text-buffer-stream.c:
+	Write only full UTF-8 characters into the GtkTextBuffer. If an
+	input buffer contains incomplete UTF-8 chars, save those bytes and
+	write them with the following buffer.
+
 2008-02-11  Alberto Garcia Gonzalez <agarcia igalia com>
 
 	* libtinymail-gnomevfs/tny-vfs-stream.c:


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]