[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 2/2] gui: Make lex_gtk_text_buffer_read() count bytes, not charac
From: |
Ben Pfaff |
Subject: |
[PATCH 2/2] gui: Make lex_gtk_text_buffer_read() count bytes, not characters. |
Date: |
Sat, 5 May 2012 22:14:16 -0700 |
The N parameter to lex_gtk_text_buffer_read() is a count of bytes,
but the implementation treated it as characters.
Also fixes a memory leak, since gtk_text_iter_get_text()'s caller
is responsible for freeing the memory that it returns.
Reported by Alle <address@hidden>.
First investigated by John Darrington <address@hidden>.
---
This fixes the problem that I saw with valgrind, but I didn't see the
same problem as John, so I'd like some confirmation that it fixes
that problem too.
src/ui/gui/psppire-lex-reader.c | 54 ++++++++++++++++++++++++++++----------
1 files changed, 40 insertions(+), 14 deletions(-)
diff --git a/src/ui/gui/psppire-lex-reader.c b/src/ui/gui/psppire-lex-reader.c
index ae043b0..d8e53c4 100644
--- a/src/ui/gui/psppire-lex-reader.c
+++ b/src/ui/gui/psppire-lex-reader.c
@@ -26,15 +26,24 @@
#include "libpspp/cast.h"
+#include "gl/minmax.h"
+
static const struct lex_reader_class lex_gtk_text_buffer_reader_class ;
struct lex_gtk_text_buffer_reader
{
struct lex_reader reader;
+
+ /* The GtkTextBuffer from which we are reading. */
GtkTextBuffer *buffer;
GtkTextIter start;
GtkTextIter stop;
+
+ /* Text pulled from part of the GtkTextBuffer. */
+ gchar *part;
+ gsize part_len; /* Number of bytes in 'part'. */
+ gsize part_ofs; /* Current offset into 'part'. */
};
static struct lex_gtk_text_buffer_reader *
@@ -57,6 +66,10 @@ lex_reader_for_gtk_text_buffer (GtkTextBuffer *buffer,
GtkTextIter start, GtkTex
r->start = start;
r->stop = stop;
+ r->part = NULL;
+ r->part_len = 0;
+ r->part_ofs = 0;
+
return &r->reader;
}
@@ -66,26 +79,38 @@ lex_gtk_text_buffer_read (struct lex_reader *r_, char *buf,
size_t n,
enum prompt_style prompt_style UNUSED)
{
struct lex_gtk_text_buffer_reader *r = lex_gtk_text_buffer_reader_cast (r_);
- int n_chars = n;
- char *s;
+ gsize chunk;
+
+ if (r->part_ofs == r->part_len)
+ {
+ /* Read up to N characters into r->part. N characters might be more than
+ N bytes, but that's OK: we'll just buffer up some of those bytes for
+ the next read. */
+ int n_chars = n;
+
+ GtkTextIter iter = r->start ;
+
+ int offset = gtk_text_iter_get_offset (&iter);
+ int end_offset = gtk_text_iter_get_offset (&r->stop);
- GtkTextIter iter = r->start ;
-
- int offset = gtk_text_iter_get_offset (&iter);
- int end_offset = gtk_text_iter_get_offset (&r->stop);
+ if ( end_offset - offset < n)
+ n_chars = end_offset - offset;
- if ( end_offset - offset < n)
- n_chars = end_offset - offset;
-
- gtk_text_iter_set_offset (&iter, offset + n_chars);
+ gtk_text_iter_set_offset (&iter, offset + n_chars);
- s = gtk_text_iter_get_text (&r->start, &iter);
+ g_free (r->part);
+ r->part = gtk_text_iter_get_text (&r->start, &iter);
+ r->part_len = strlen (r->part);
+ r->part_ofs = 0;
- strncpy (buf, s, n_chars);
+ r->start = iter;
+ }
- r->start = iter;
+ chunk = MIN (r->part_len - r->part_ofs, n);
+ memcpy (buf, r->part + r->part_ofs, chunk);
+ r->part_ofs += chunk;
- return strlen (s);
+ return chunk;
}
@@ -96,6 +121,7 @@ lex_gtk_text_buffer_close (struct lex_reader *r_)
struct lex_gtk_text_buffer_reader *r = lex_gtk_text_buffer_reader_cast (r_);
g_object_unref (r->buffer);
+ g_free (r->part);
}
--
1.7.2.5