[gedit/docstream2: 1/16] Add gedit-document-input-stream and test.



commit 28b5d00aa3b4eb7f84dbe51b7e83d05de56d39c7
Author: Ignacio Casal Quinteiro <icq gnome org>
Date:   Mon Jan 18 20:45:38 2010 +0100

    Add gedit-document-input-stream and test.

 gedit/Makefile.am                   |    2 +
 gedit/gedit-document-input-stream.c |  320 +++++++++++++++++++++++++++++++++++
 gedit/gedit-document-input-stream.h |   65 +++++++
 tests/Makefile.am                   |    3 +
 tests/document-input-stream.c       |  118 +++++++++++++
 5 files changed, 508 insertions(+), 0 deletions(-)
---
diff --git a/gedit/Makefile.am b/gedit/Makefile.am
index 295d0bf..9836e77 100644
--- a/gedit/Makefile.am
+++ b/gedit/Makefile.am
@@ -65,6 +65,7 @@ endif
 NOINST_H_FILES =			\
 	gedit-close-button.h		\
 	gedit-dirs.h			\
+	gedit-document-input-stream.h	\
 	gedit-document-loader.h		\
 	gedit-document-saver.h		\
 	gedit-documents-panel.h		\
@@ -151,6 +152,7 @@ libgedit_la_SOURCES = 			\
 	gedit-debug.c			\
 	gedit-dirs.c			\
 	gedit-document.c 		\
+	gedit-document-input-stream.c	\
 	gedit-document-loader.c		\
 	gedit-gio-document-loader.c	\
 	gedit-document-saver.c		\
diff --git a/gedit/gedit-document-input-stream.c b/gedit/gedit-document-input-stream.c
new file mode 100644
index 0000000..73a27eb
--- /dev/null
+++ b/gedit/gedit-document-input-stream.c
@@ -0,0 +1,320 @@
+/*
+ * gedit-document-input-stream.c
+ * This file is part of gedit
+ *
+ * Copyright (C) 2010 - Ignacio Casal Quinteiro
+ *
+ * gedit is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * gedit is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with gedit; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+
+#include "config.h"
+
+#include <glib.h>
+#include <gio/gio.h>
+#include <string.h>
+
+#include "gedit-document-input-stream.h"
+
+G_DEFINE_TYPE (GeditDocumentInputStream, gedit_document_input_stream, G_TYPE_INPUT_STREAM);
+
+struct _GeditDocumentInputStreamPrivate
+{
+	GtkTextBuffer *buffer;
+	GtkTextMark   *pos;
+
+	/* store the trailing line */
+	gchar *line;
+	gsize  line_len;
+};
+
+enum
+{
+	PROP_0,
+	PROP_BUFFER
+};
+
+static gssize     gedit_document_input_stream_read     (GInputStream      *stream,
+							void              *buffer,
+							gsize              count,
+							GCancellable      *cancellable,
+							GError           **error);
+static gboolean   gedit_document_input_stream_close    (GInputStream      *stream,
+							GCancellable      *cancellable,
+							GError           **error);
+
+static void
+gedit_document_input_stream_finalize (GObject *object)
+{
+	GeditDocumentInputStream *stream = GEDIT_DOCUMENT_INPUT_STREAM (object);
+
+	g_free (stream->priv->line);
+
+	G_OBJECT_CLASS (gedit_document_input_stream_parent_class)->finalize (object);
+}
+
+static void
+gedit_document_input_stream_dispose (GObject *object)
+{
+	GeditDocumentInputStream *stream = GEDIT_DOCUMENT_INPUT_STREAM (object);
+
+	if (stream->priv->pos != NULL)
+	{
+		gtk_text_buffer_delete_mark (stream->priv->buffer,
+					     stream->priv->pos);
+
+		stream->priv->pos = NULL;
+	}
+
+	G_OBJECT_CLASS (gedit_document_input_stream_parent_class)->dispose (object);
+}
+
+static void
+gedit_document_input_stream_set_property (GObject      *object,
+					  guint         prop_id,
+					  const GValue *value,
+					  GParamSpec   *pspec)
+{
+	GeditDocumentInputStream *stream = GEDIT_DOCUMENT_INPUT_STREAM (object);
+
+	switch (prop_id)
+	{
+		case PROP_BUFFER:
+			stream->priv->buffer = GTK_TEXT_BUFFER (g_value_get_object (value));
+			break;
+
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+			break;
+	}
+}
+
+static void
+gedit_document_input_stream_get_property (GObject    *object,
+					  guint       prop_id,
+					  GValue     *value,
+					  GParamSpec *pspec)
+{
+	GeditDocumentInputStream *stream = GEDIT_DOCUMENT_INPUT_STREAM (object);
+
+	switch (prop_id)
+	{
+		case PROP_BUFFER:
+			g_value_set_object (value, stream->priv->buffer);
+			break;
+
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+			break;
+	}
+}
+
+static void
+gedit_document_input_stream_class_init (GeditDocumentInputStreamClass *klass)
+{
+	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+	GInputStreamClass *stream_class = G_INPUT_STREAM_CLASS (klass);
+
+	g_type_class_add_private (klass, sizeof (GeditDocumentInputStreamPrivate));
+
+	gobject_class->finalize = gedit_document_input_stream_finalize;
+	gobject_class->dispose = gedit_document_input_stream_dispose;
+	gobject_class->get_property = gedit_document_input_stream_get_property;
+	gobject_class->set_property = gedit_document_input_stream_set_property;
+
+	stream_class->read_fn = gedit_document_input_stream_read;
+	stream_class->close_fn = gedit_document_input_stream_close;
+
+	g_object_class_install_property (gobject_class,
+					 PROP_BUFFER,
+					 g_param_spec_object ("buffer",
+							      "Buffer",
+							      "The buffer which is read",
+							      GTK_TYPE_TEXT_BUFFER,
+							      G_PARAM_READWRITE |
+							      G_PARAM_CONSTRUCT_ONLY));
+}
+
+static void
+gedit_document_input_stream_init (GeditDocumentInputStream *stream)
+{
+	stream->priv = G_TYPE_INSTANCE_GET_PRIVATE (stream,
+						    GEDIT_TYPE_DOCUMENT_INPUT_STREAM,
+						    GeditDocumentInputStreamPrivate);
+
+	stream->priv->line = NULL;
+	stream->priv->line_len = 0;
+	stream->priv->pos = NULL;
+}
+
+/**
+ * gedit_document_input_stream_new:
+ * @buffer: a #GtkTextBuffer
+ *
+ * Reads the data from @buffer.
+ *
+ * Returns: a new #GInputStream to read @buffer
+ */
+GInputStream *
+gedit_document_input_stream_new (GtkTextBuffer *buffer)
+{
+	GeditDocumentInputStream *stream;
+
+	g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
+
+	stream = g_object_new (GEDIT_TYPE_DOCUMENT_INPUT_STREAM,
+			       "buffer", buffer,
+			       NULL);
+
+	return G_INPUT_STREAM (stream);
+}
+
+gsize
+gedit_document_input_stream_get_total_size (GeditDocumentInputStream *stream)
+{
+	g_return_val_if_fail (GEDIT_IS_DOCUMENT_INPUT_STREAM (stream), 0);
+
+	return gtk_text_buffer_get_char_count (stream->priv->buffer);
+}
+
+gsize
+gedit_document_input_stream_tell (GeditDocumentInputStream *stream)
+{
+	GtkTextIter iter;
+
+	g_return_val_if_fail (GEDIT_IS_DOCUMENT_INPUT_STREAM (stream), 0);
+
+	gtk_text_buffer_get_iter_at_mark (stream->priv->buffer,
+					  &iter,
+					  stream->priv->pos);
+
+	return gtk_text_iter_get_offset (&iter);
+}
+
+static gsize
+read_line (GeditDocumentInputStream *stream,
+	   gchar                    *outbuf,
+	   gsize                     space_left)
+{
+	GtkTextIter start, next, end;
+	gchar *buf;
+	gsize read, bytes;
+
+	gtk_text_buffer_get_iter_at_mark (stream->priv->buffer,
+					  &start,
+					  stream->priv->pos);
+
+	end = next = start;
+
+	if (gtk_text_iter_is_end (&start))
+		return 0;
+
+	if (!gtk_text_iter_ends_line (&end))
+		gtk_text_iter_forward_line (&end);
+
+	buf = gtk_text_iter_get_slice (&start, &end);
+	bytes = gtk_text_iter_get_bytes_in_line (&start);
+
+	if (bytes > space_left)
+	{
+		gchar *ptr;
+		gint offset;
+
+		ptr = buf;
+
+		while ((ptr - buf) < space_left)
+			ptr = g_utf8_next_char (ptr);
+
+		if ((ptr - buf) > space_left)
+			ptr = g_utf8_prev_char (ptr);
+
+		memcpy (outbuf + read, buf, (ptr - buf));
+		read = (ptr - buf);
+
+		offset = gtk_text_iter_get_line_offset (&start);
+		gtk_text_iter_set_line_offset (&start, offset + read);
+	}
+	else
+	{
+		memcpy (outbuf + read, buf, bytes);
+		read = bytes;
+
+		start = end;
+	}
+
+	g_free (buf);
+
+	gtk_text_buffer_move_mark (stream->priv->buffer,
+				   stream->priv->pos,
+				   &start);
+
+	return read;
+}
+
+static gssize
+gedit_document_input_stream_read (GInputStream  *stream,
+				  void          *buffer,
+				  gsize          count,
+				  GCancellable  *cancellable,
+				  GError       **error)
+{
+	GeditDocumentInputStream *dstream;
+	gssize space_left, read, n;
+
+	dstream = GEDIT_DOCUMENT_INPUT_STREAM (stream);
+
+	if (g_cancellable_set_error_if_cancelled (cancellable, error))
+		return -1;
+
+	if (dstream->priv->pos == NULL)
+	{
+		GtkTextIter start;
+
+		gtk_text_buffer_get_start_iter (dstream->priv->buffer, &start);
+
+		dstream->priv->pos = gtk_text_mark_new (NULL, TRUE);
+
+		gtk_text_buffer_add_mark (dstream->priv->buffer,
+					  dstream->priv->pos,
+					  &start);
+	}
+
+	space_left = count;
+	read = 0;
+
+	do
+	{
+		n = read_line (dstream, buffer + read, space_left);
+		read += n;
+		space_left -= n;
+	} while (space_left > 0 && n != 0);
+
+	return read;
+}
+
+static gboolean
+gedit_document_input_stream_close (GInputStream  *stream,
+				   GCancellable  *cancellable,
+				   GError       **error)
+{
+	GeditDocumentInputStream *dstream = GEDIT_DOCUMENT_INPUT_STREAM (stream);
+
+	g_free (dstream->priv->line);
+	dstream->priv->line = NULL;
+	dstream->priv->line_len = 0;
+
+	return TRUE;
+}
diff --git a/gedit/gedit-document-input-stream.h b/gedit/gedit-document-input-stream.h
new file mode 100644
index 0000000..ec686fa
--- /dev/null
+++ b/gedit/gedit-document-input-stream.h
@@ -0,0 +1,65 @@
+/*
+ * gedit-document-input-stream.h
+ * This file is part of gedit
+ *
+ * Copyright (C) 2010 - Ignacio Casal Quinteiro
+ *
+ * gedit is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * gedit is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with gedit; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifndef __GEDIT_DOCUMENT_INPUT_STREAM_H__
+#define __GEDIT_DOCUMENT_INPUT_STREAM_H__
+
+#include <gio/gio.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GEDIT_TYPE_DOCUMENT_INPUT_STREAM		(gedit_document_input_stream_get_type ())
+#define GEDIT_DOCUMENT_INPUT_STREAM(obj)		(G_TYPE_CHECK_INSTANCE_CAST ((obj), GEDIT_TYPE_DOCUMENT_INPUT_STREAM, GeditDocumentInputStream))
+#define GEDIT_DOCUMENT_INPUT_STREAM_CONST(obj)		(G_TYPE_CHECK_INSTANCE_CAST ((obj), GEDIT_TYPE_DOCUMENT_INPUT_STREAM, GeditDocumentInputStream const))
+#define GEDIT_DOCUMENT_INPUT_STREAM_CLASS(klass)	(G_TYPE_CHECK_CLASS_CAST ((klass), GEDIT_TYPE_DOCUMENT_INPUT_STREAM, GeditDocumentInputStreamClass))
+#define GEDIT_IS_DOCUMENT_INPUT_STREAM(obj)		(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEDIT_TYPE_DOCUMENT_INPUT_STREAM))
+#define GEDIT_IS_DOCUMENT_INPUT_STREAM_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE ((klass), GEDIT_TYPE_DOCUMENT_INPUT_STREAM))
+#define GEDIT_DOCUMENT_INPUT_STREAM_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS ((obj), GEDIT_TYPE_DOCUMENT_INPUT_STREAM, GeditDocumentInputStreamClass))
+
+typedef struct _GeditDocumentInputStream	GeditDocumentInputStream;
+typedef struct _GeditDocumentInputStreamClass	GeditDocumentInputStreamClass;
+typedef struct _GeditDocumentInputStreamPrivate	GeditDocumentInputStreamPrivate;
+
+struct _GeditDocumentInputStream
+{
+	GInputStream parent;
+	
+	GeditDocumentInputStreamPrivate *priv;
+};
+
+struct _GeditDocumentInputStreamClass
+{
+	GInputStreamClass parent_class;
+};
+
+GType				 gedit_document_input_stream_get_type		(void) G_GNUC_CONST;
+
+GInputStream			*gedit_document_input_stream_new		(GtkTextBuffer *buffer);
+
+gsize				 gedit_document_input_stream_get_total_size	(GeditDocumentInputStream *stream);
+
+gsize				 gedit_document_input_stream_tell		(GeditDocumentInputStream *stream);
+
+G_END_DECLS
+
+#endif /* __GEDIT_DOCUMENT_INPUT_STREAM_H__ */
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 0b5248e..ed07cd4 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -8,3 +8,6 @@ TEST_PROGS			= smart-converter
 smart_converter_SOURCES		= smart-converter.c
 smart_converter_LDADD		= $(progs_ldadd)
 
+TEST_PROGS			+= document-input-stream
+document_input_stream_SOURCES	= document-input-stream.c
+document_input_stream_LDADD	= $(progs_ldadd)
diff --git a/tests/document-input-stream.c b/tests/document-input-stream.c
new file mode 100644
index 0000000..5af9a44
--- /dev/null
+++ b/tests/document-input-stream.c
@@ -0,0 +1,118 @@
+/*
+ * document-input-stream.c
+ * This file is part of gedit
+ *
+ * Copyright (C) 2010 - Ignacio Casal Quinteiro
+ *
+ * gedit is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * gedit is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with gedit; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+
+#include "gedit-document-input-stream.h"
+#include <gio/gio.h>
+#include <gtk/gtk.h>
+#include <glib.h>
+#include <string.h>
+
+#define TEXT_TO_TEST "hello this is some text\nsencond line of the text"
+
+static void
+test_single_read ()
+{
+	GtkTextBuffer *buf;
+	GInputStream *in;
+	gsize r;
+	GError *err = NULL;
+	gchar *b;
+
+	buf = gtk_text_buffer_new (NULL);
+
+	gtk_text_buffer_set_text (buf, TEXT_TO_TEST, -1);
+
+	b = g_malloc (200);
+	in = gedit_document_input_stream_new (buf);
+
+	r = g_input_stream_read (in, b, strlen (TEXT_TO_TEST), NULL, &err);
+
+	g_assert_no_error (err);
+
+	g_assert_cmpint (r, >, 0);
+
+	b[strlen (TEXT_TO_TEST)] = '\0';
+
+	g_assert_cmpstr (b, ==, TEXT_TO_TEST);
+}
+
+static void
+test_consecutive_read ()
+{
+	GtkTextBuffer *buf;
+	GInputStream *in;
+	gsize r, n;
+	GError *err = NULL;
+	gchar *b;
+
+	buf = gtk_text_buffer_new (NULL);
+
+	gtk_text_buffer_set_text (buf, TEXT_TO_TEST, -1);
+
+	b = g_malloc (200);
+	in = gedit_document_input_stream_new (buf);
+
+	n = 0;
+
+	do
+	{
+		r = g_input_stream_read (in, b + n, 6, NULL, &err);
+		n += r;
+		g_assert_no_error (err);
+	} while (r != 0);
+
+	g_assert_cmpint (n, >, 0);
+
+	g_assert_cmpstr (b, ==, TEXT_TO_TEST);
+}
+
+static void
+test_size ()
+{
+	GtkTextBuffer *buf;
+	GInputStream *in;
+	gsize size;
+
+	buf = gtk_text_buffer_new (NULL);
+
+	gtk_text_buffer_set_text (buf, TEXT_TO_TEST, -1);
+
+	in = gedit_document_input_stream_new (buf);
+
+	size = gedit_document_input_stream_get_total_size (GEDIT_DOCUMENT_INPUT_STREAM (in));
+
+	g_assert_cmpint (size, ==, strlen (TEXT_TO_TEST));
+}
+
+int main (int   argc,
+          char *argv[])
+{
+	g_type_init ();
+	g_test_init (&argc, &argv, NULL);
+
+	g_test_add_func ("/document-input-stream/single_read", test_single_read);
+	g_test_add_func ("/document-input-stream/consecutive_read", test_consecutive_read);
+	g_test_add_func ("/document-input-stream/size", test_size);
+
+	return g_test_run ();
+}



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