[gnome-builder/wip/libide] libide: add ide_buffer_get_content()



commit 52b09dbc8c1197a21fc147192b5aa6f38aef7ab6
Author: Christian Hergert <christian hergert me>
Date:   Thu Feb 26 16:42:23 2015 -0800

    libide: add ide_buffer_get_content()
    
    This helper returns a GBytes containing the buffer contents. As more
    subsystems need to access the buffer contents, this can help us avoid
    calling get_text() so much. Especially since we need to transform the
    buffer to include the trailing newline.
    
    Furthermore, it allows us a single point to update the IdeUnsavedFiles
    whenever the content is needed. This means that lost content will get
    automatically persisted to the drafts when closed.

 libide/ide-buffer.c |   68 +++++++++++++++++++++++++++++++++++++++++++++++---
 libide/ide-buffer.h |    1 +
 2 files changed, 64 insertions(+), 5 deletions(-)
---
diff --git a/libide/ide-buffer.c b/libide/ide-buffer.c
index 6c01294..73c470a 100644
--- a/libide/ide-buffer.c
+++ b/libide/ide-buffer.c
@@ -45,12 +45,13 @@ typedef struct _IdeBufferClass
 
 struct _IdeBuffer
 {
-  GtkSourceBuffer  parent_instance;
+  GtkSourceBuffer         parent_instance;
 
-  IdeContext      *context;
-  IdeDiagnostics  *diagnostics;
-  GHashTable      *diagnostics_line_cache;
-  IdeFile         *file;
+  IdeContext             *context;
+  IdeDiagnostics         *diagnostics;
+  GHashTable             *diagnostics_line_cache;
+  IdeFile                *file;
+  GBytes                 *content;
 
   guint            diagnose_timeout;
 
@@ -444,6 +445,8 @@ ide_buffer_changed (GtkTextBuffer *buffer)
 
   self->diagnostics_dirty = TRUE;
 
+  g_clear_pointer (&self->content, g_bytes_unref);
+
   if (self->highlight_diagnostics && !self->in_diagnose)
     ide_buffer_queue_diagnose (self);
 }
@@ -479,6 +482,7 @@ ide_buffer_dispose (GObject *object)
 
   g_clear_pointer (&self->diagnostics_line_cache, g_hash_table_unref);
   g_clear_pointer (&self->diagnostics, ide_diagnostics_unref);
+  g_clear_pointer (&self->content, g_bytes_unref);
   g_clear_object (&self->file);
 
   G_OBJECT_CLASS (ide_buffer_parent_class)->dispose (object);
@@ -804,3 +808,57 @@ ide_buffer_get_diagnostic_at_iter (IdeBuffer         *self,
 
   return NULL;
 }
+
+/**
+ * ide_buffer_get_content:
+ *
+ * Gets the contents of the buffer as GBytes.
+ *
+ * By using this function to get the bytes, you allow #IdeBuffer to avoid calculating the buffer
+ * text unnecessarily, potentially saving on allocations.
+ *
+ * Additionally, this allows the buffer to update the state in #IdeUnsavedFiles if the content
+ * is out of sync.
+ *
+ * Returns: (transfer full): A #GBytes containing the buffer content.
+ */
+GBytes *
+ide_buffer_get_content (IdeBuffer *self)
+{
+  g_return_val_if_fail (IDE_IS_BUFFER (self), NULL);
+
+  if (!self->content)
+    {
+      IdeUnsavedFiles *unsaved_files;
+      gchar *text;
+      GtkTextIter begin;
+      GtkTextIter end;
+      GFile *gfile = NULL;
+      gsize len;
+
+      gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (self), &begin, &end);
+      text = gtk_text_buffer_get_text (GTK_TEXT_BUFFER (self), &begin, &end, TRUE);
+
+      /*
+       * If implicit newline is set, add a \n in place of the \0 and avoid duplicating the buffer.
+       * Make sure to track length beforehand, since we would overwrite afterwards. Since
+       * conversion to \r\n is dealth with during save operations, this should be fine for both.
+       * The unsaved files will restore to a buffer, for which \n is acceptable.
+       */
+      len = strlen (text);
+      if (gtk_source_buffer_get_implicit_trailing_newline (GTK_SOURCE_BUFFER (self)))
+        text [len++] = '\n';
+
+      self->content = g_bytes_new_take (text, len);
+
+      if ((self->context != NULL) &&
+          (self->file != NULL) &&
+          (gfile = ide_file_get_file (self->file)))
+        {
+          unsaved_files = ide_context_get_unsaved_files (self->context);
+          ide_unsaved_files_update (unsaved_files, gfile, self->content);
+        }
+    }
+
+  return g_bytes_ref (self->content);
+}
diff --git a/libide/ide-buffer.h b/libide/ide-buffer.h
index 7e15f6b..d454989 100644
--- a/libide/ide-buffer.h
+++ b/libide/ide-buffer.h
@@ -60,6 +60,7 @@ void                ide_buffer_set_highlight_diagnostics (IdeBuffer         *sel
                                                           gboolean           highlight_diagnostics);
 IdeBufferLineFlags  ide_buffer_get_line_flags            (IdeBuffer         *buffer,
                                                           guint              line);
+GBytes             *ide_buffer_get_content               (IdeBuffer         *self);
 IdeDiagnostic      *ide_buffer_get_diagnostic_at_iter    (IdeBuffer         *self,
                                                           const GtkTextIter *iter);
 


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