Patch for TnyGtkTextBufferStream
- From: Alberto Garcia <agarcia igalia com>
- To: tinymail-devel-list gnome org
- Subject: Patch for TnyGtkTextBufferStream
- Date: Tue, 12 Feb 2008 20:08:57 +0100
I'm attaching a patch against tny-gtk-text-buffer-stream.c that
addresses two related problems:
First, the TnyGtkTextBufferStream isn't treating properly non-UTF8
input (in fact, non-UTF8 input could cause a crash).
Second, if a buffer is written to a TnyGtkTextBufferStream divided
into several chunks of bytes (like camel_stream_write_to_stream()
does, for example), chances are that some multibyte UTF-8 characters
are split into two different chunks.
As GtkTextBuffer only admits full UTF-8 chars, this wouldn't work and
those divided UTF-8 chars would be lost.
With this patch, TnyGtkTextBufferStream keeps the trailing bytes of
an input buffer (those that are not full UTF-8 chars) and writes then
with the following buffer.
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.
--
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,30 @@
{
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));
+
+ /* If the buffer begins with non-UTF8 text it means that it's
+ * corrupt, so there's not much to do about it: write it anyway.
+ * (4 is the max length in bytes of a UTF-8 char) */
+ if (nb_written == 0 && priv->pending_bytes->len >= 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 +172,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 +235,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 +261,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 +298,7 @@
TnyGtkTextBufferStreamPriv *priv = TNY_GTK_TEXT_BUFFER_STREAM_GET_PRIVATE (self);
priv->buffer = NULL;
+ priv->pending_bytes = NULL;
return;
}
@@ -278,8 +309,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]