X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fui%2Fgui%2Fpsppire-lex-reader.c;h=d8e53c446122b339b17cb61d80daacd24779800d;hb=5841c349770a82f091e77dfe90fd68eee6032f66;hp=ae043b0b7b252cedea40bf1634a0895aad20f748;hpb=0838c7ce8528a241fd6bb422767e187af4b5d9a7;p=pspp diff --git a/src/ui/gui/psppire-lex-reader.c b/src/ui/gui/psppire-lex-reader.c index ae043b0b7b..d8e53c4461 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); }