From 01f20dc6887fc1d45e026306a4364c9e7b256250 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Thu, 21 Jan 2016 15:34:53 +0100
Subject: Enabled the buffer scan again and updated its code.

---
 ChangeLog                 |  10 +++
 src/glibext/gcodebuffer.c | 188 +++++++++++++++++++++++-----------------------
 src/glibext/gcodebuffer.h |   8 +-
 src/gui/dialogs/export.c  |  97 ++++++++++++++++++++++--
 4 files changed, 199 insertions(+), 104 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 5fad957..a843b9c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+16-01-21  Cyrille Bagard <nocbos@gmail.com>
+
+	* src/glibext/gcodebuffer.c:
+	* src/glibext/gcodebuffer.h:
+	Enable the buffer scan again and update its code. Delete the
+	g_buffer_view_export() function.
+
+	* src/gui/dialogs/export.c:
+	Update code.
+
 16-01-18  Cyrille Bagard <nocbos@gmail.com>
 
 	* src/gtkext/easygtk.c:
diff --git a/src/glibext/gcodebuffer.c b/src/glibext/gcodebuffer.c
index 5644552..e00b127 100644
--- a/src/glibext/gcodebuffer.c
+++ b/src/glibext/gcodebuffer.c
@@ -53,8 +53,10 @@ typedef struct _GBufferScan
 
     GCodeBuffer *buffer;                    /* Tampon à manipuler          */
 
-    vmpa_t start;                           /* Début du parcours ou 0      */
-    vmpa_t end;                             /* Fin du parcours ou VMPA_MAX */
+    vmpa2t start;                           /* Début du parcours           */
+    bool has_start;                         /* Validité des données #1     */
+    vmpa2t end;                             /* Fin du parcours             */
+    bool has_end;                           /* Validité des données #2     */
 
     char *message;                          /* Message de progression      */
 
@@ -80,8 +82,14 @@ static void g_buffer_scan_class_init(GBufferScanClass *);
 /* Initialise une tâche d'exportation différée. */
 static void g_buffer_scan_init(GBufferScan *);
 
+/* Supprime toutes les références externes. */
+static void g_buffer_scan_dispose(GBufferScan *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_buffer_scan_finalize(GBufferScan *);
+
 /* Crée une tâche d'exportation différée. */
-static GBufferScan *g_buffer_scan_new(GCodeBuffer *, vmpa_t, vmpa_t, const char *, process_line_fc, void *);
+static GBufferScan *g_buffer_scan_new(GCodeBuffer *, const vmpa2t *, const vmpa2t *, const char *, process_line_fc, void *);
 
 /* Assure l'exportation en différé. */
 static void g_buffer_scan_process(GBufferScan *, GtkExtStatusBar *);
@@ -244,8 +252,14 @@ G_DEFINE_TYPE(GBufferScan, g_buffer_scan, G_TYPE_DELAYED_WORK);
 
 static void g_buffer_scan_class_init(GBufferScanClass *klass)
 {
+    GObjectClass *object;                   /* Autre version de la classe  */
     GDelayedWorkClass *work;                /* Version en classe parente   */
 
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_buffer_scan_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_buffer_scan_finalize;
+
     work = G_DELAYED_WORK_CLASS(klass);
 
     work->run = (run_task_fc)g_buffer_scan_process;
@@ -255,7 +269,7 @@ static void g_buffer_scan_class_init(GBufferScanClass *klass)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : disass = instance à initialiser.                             *
+*  Paramètres  : scan = instance à initialiser.                               *
 *                                                                             *
 *  Description : Initialise une tâche d'exportation différée.                 *
 *                                                                             *
@@ -265,7 +279,7 @@ static void g_buffer_scan_class_init(GBufferScanClass *klass)
 *                                                                             *
 ******************************************************************************/
 
-static void g_buffer_scan_init(GBufferScan *disass)
+static void g_buffer_scan_init(GBufferScan *scan)
 {
 
 }
@@ -273,9 +287,51 @@ static void g_buffer_scan_init(GBufferScan *disass)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : scan = instance d'objet GLib à traiter.                      *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_buffer_scan_dispose(GBufferScan *scan)
+{
+    g_object_unref(G_OBJECT(scan->buffer));
+
+    G_OBJECT_CLASS(g_buffer_scan_parent_class)->dispose(G_OBJECT(scan));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : scan = instance d'objet GLib à traiter.                      *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_buffer_scan_finalize(GBufferScan *scan)
+{
+    free(scan->message);
+
+    G_OBJECT_CLASS(g_buffer_scan_parent_class)->finalize(G_OBJECT(scan));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : buffer  = tampon à manipuler.                                *
-*                start   = première adresse visée ou 0.                       *
-*                end     = dernière adresse visée ou VMPA_MAX.                *
+*                start   = première adresse visée ou NULL.                    *
+*                end     = dernière adresse visée ou NULL.                    *
 *                message = message à afficher lors de la progression.         *
 *                process = fonction assurant le traitement effectif.          *
 *                data    = données utilisateur à faire suivre.                *
@@ -288,7 +344,7 @@ static void g_buffer_scan_init(GBufferScan *disass)
 *                                                                             *
 ******************************************************************************/
 
-static GBufferScan *g_buffer_scan_new(GCodeBuffer *buffer, vmpa_t start, vmpa_t end, const char *message, process_line_fc process, void *data)
+static GBufferScan *g_buffer_scan_new(GCodeBuffer *buffer, const vmpa2t *start, const vmpa2t *end, const char *message, process_line_fc process, void *data)
 {
     GBufferScan *result;            /* Tâche à retourner           */
 
@@ -297,8 +353,15 @@ static GBufferScan *g_buffer_scan_new(GCodeBuffer *buffer, vmpa_t start, vmpa_t
     result->buffer = buffer;
     g_object_ref(G_OBJECT(buffer));
 
-    result->start = start;
-    result->end = end;
+    result->has_start = (start != NULL);
+
+    if (result->has_start)
+        copy_vmpa(&result->start, start);
+
+    result->has_end = (end != NULL);
+
+    if (result->has_end)
+        copy_vmpa(&result->end, end);
 
     result->message = strdup(message);
 
@@ -328,17 +391,24 @@ static void g_buffer_scan_process(GBufferScan *scan, GtkExtStatusBar *statusbar)
     size_t first;                           /* Première ligne visée        */
     size_t last;                            /* Dernière ligne visée + 1    */
     GBufferLine **lines;                    /* Liste des lignes à traiter  */
-    bstatus_id_t id;                        /* Identifiant de statut       */
+    //bstatus_id_t id;                        /* Identifiant de statut       */
     size_t i;                               /* Boucle de parcours          */
 
     /* TODO : lock scan->buffer->lines */
 
-    first = g_code_buffer_get_index_from_address(scan->buffer, scan->start, true);
-    last = g_code_buffer_get_index_from_address(scan->buffer, scan->end, false);
+    if (scan->has_start)
+        first = g_code_buffer_get_index_from_address(scan->buffer, &scan->start, true);
+    else
+        first = 0;
+
+    if (scan->has_end)
+        last = g_code_buffer_get_index_from_address(scan->buffer, &scan->end, false);
+    else
+        last = scan->buffer->used - 1;
 
     lines = scan->buffer->lines;
 
-    id = gtk_extended_status_bar_push(statusbar, scan->message, true);
+    //id = gtk_extended_status_bar_push(statusbar, scan->message, true);
 
     if (scan->buffer->used > 0)
         for (i = first; i <= last; i++)
@@ -346,17 +416,16 @@ static void g_buffer_scan_process(GBufferScan *scan, GtkExtStatusBar *statusbar)
             if (!scan->process(scan->buffer, lines[i], scan->user_data))
                 break;
 
+            /*
             gtk_extended_status_bar_update_activity(statusbar, id,
                                                     (i - first) * 1.0 / (last - first));
+            */
 
         }
 
     /* TODO : unlock scan->buffer->lines */
 
-    gtk_extended_status_bar_remove(statusbar, id);
-
-    /* Avertit le commanditaire... */
-    scan->process(scan->buffer, NULL, scan->user_data);
+    //gtk_extended_status_bar_remove(statusbar, id);
 
 }
 
@@ -1100,15 +1169,18 @@ void g_code_buffer_dec_indentation(GCodeBuffer *buffer)
 *                                                                             *
 ******************************************************************************/
 
-void g_buffer_code_scan(GCodeBuffer *buffer, vmpa_t start, vmpa_t end, const char *message, process_line_fc process, void *data)
+GDelayedWork *g_buffer_code_scan(GCodeBuffer *buffer, const vmpa2t *start, const vmpa2t *end, const char *message, process_line_fc process, void *data)
 {
-    GBufferScan *scan;                      /* Procédure de parcours       */
+    GBufferScan *result;                    /* Procédure à créer / renvoyer*/
     GWorkQueue *queue;                      /* Gestionnaire de différés    */
 
-    scan = g_buffer_scan_new(buffer, start, end, message, process, data);
+    result = g_buffer_scan_new(buffer, start, end, message, process, data);
+    g_object_ref(G_OBJECT(result));
 
     queue = get_work_queue();
-    g_work_queue_schedule_work(queue, G_DELAYED_WORK(scan), DEFAULT_WORK_GROUP);
+    g_work_queue_schedule_work(queue, G_DELAYED_WORK(result), DEFAULT_WORK_GROUP);
+
+    return G_DELAYED_WORK(result);
 
 }
 
@@ -2172,78 +2244,6 @@ void g_buffer_view_draw(const GBufferView *view, cairo_t *cr, gint fake_x, gint
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : view    = visualisation à représenter.                       *
-*                ctx     = éléments à disposition pour l'exportation.         *
-*                type    = type d'exportation attendue.                       *
-*                display = règles d'affichage des colonnes modulables.        *
-*                                                                             *
-*  Description : Exporte le contenu du tampon de code désassemblé.            *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void g_buffer_view_export(const GBufferView *view, buffer_export_context *ctx, BufferExportType type, const bool *display)
-{
-    size_t start;                           /* Première ligne visée        */
-    size_t end;                             /* Dernière ligne avant limite */
-    GBufferLine **lines;                    /* Liste des lignes à traiter  */
-    size_t i;                               /* Boucle de parcours          */
-
-    start = g_code_buffer_get_index_from_address(view->buffer, view->start, true);
-    end = g_code_buffer_get_index_from_address(view->buffer, view->end, false);
-
-    lines = view->buffer->lines;
-
-    switch (type)
-    {
-        case BET_HTML:
-            dprintf(ctx->fd, "<HTML>\n");
-            dprintf(ctx->fd, "<HEAD>\n");
-            dprintf(ctx->fd, "\t<META http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"/>\n");
-            dprintf(ctx->fd, "</HEAD>\n");
-            dprintf(ctx->fd, "<BODY>\n");
-            dprintf(ctx->fd, "<STYLE  type=\"text/css\">\n");
-            dprintf(ctx->fd, "TABLE {\n");
-            dprintf(ctx->fd, "\tbackground-color: %s;\n", ctx->bg_color);
-            dprintf(ctx->fd, "\tborder: 0px;\n");
-            dprintf(ctx->fd, "\tfont-family: %s;\n", ctx->font_name);
-            dprintf(ctx->fd, "}\n");
-            dprintf(ctx->fd, "TD {\n");
-            dprintf(ctx->fd, "\tborder: 0px;\n");
-            dprintf(ctx->fd, "\tpadding-left: 8px;\n");
-            dprintf(ctx->fd, "\tpadding-right: 8px;\n");
-            dprintf(ctx->fd, "}\n");
-            g_buffer_segment_export_style(ctx, type);
-            dprintf(ctx->fd, "</STYLE>\n");
-            dprintf(ctx->fd, "<TABLE>\n");
-            break;
-        default:
-            break;
-    }
-
-    if (view->buffer->used > 0)
-        for (i = start; i <= end; i++)
-            g_buffer_line_export(lines[i], ctx, type, display);
-
-    switch (type)
-    {
-        case BET_HTML:
-            dprintf(ctx->fd, "</TABLE>\n");
-            dprintf(ctx->fd, "</BODY>\n");
-            dprintf(ctx->fd, "</HTML>\n");
-            break;
-        default:
-            break;
-    }
-
-}
-
-
-/******************************************************************************
-*                                                                             *
 *  Paramètres  : view  = visualisation à consulter.                           *
 *                addr  = adresse où retrouver la ligne recherchée.            *
 *                flags = propriétés à vérifier en tout ou partie.             *
diff --git a/src/glibext/gcodebuffer.h b/src/glibext/gcodebuffer.h
index 5cde79c..517cdce 100644
--- a/src/glibext/gcodebuffer.h
+++ b/src/glibext/gcodebuffer.h
@@ -28,6 +28,7 @@
 #include <glib-object.h>
 
 
+#include "delayed.h"
 #include "gbufferline.h"
 
 
@@ -84,8 +85,8 @@ void g_code_buffer_dec_indentation(GCodeBuffer *);
 /* Traitement d'une ligne parcourue. */
 typedef bool (* process_line_fc) (GCodeBuffer *, GBufferLine *, void *);
 
-/* Exporte dans un fichier le tampon de code désassemblé. */
-void g_buffer_code_scan(GCodeBuffer *, vmpa_t, vmpa_t, const char *, process_line_fc, void *) __attribute__ ((deprecated));
+/* Lance un parcours des différentes lignes du tampon de code. */
+GDelayedWork *g_buffer_code_scan(GCodeBuffer *, const vmpa2t *, const vmpa2t *, const char *, process_line_fc, void *);
 
 
 
@@ -155,9 +156,6 @@ bool g_buffer_view_highlight_segments(GBufferView *, gint, gint, const bool *);
 /* Imprime la visualisation du tampon de code désassemblé. */
 void g_buffer_view_draw(const GBufferView *, cairo_t *, gint, gint, const cairo_rectangle_int_t *, const bool *, const gint *);
 
-/* Exporte le contenu du tampon de code désassemblé. */
-void g_buffer_view_export(const GBufferView *, buffer_export_context *, BufferExportType, const bool *);
-
 /* Retrouve une ligne au sein d'un tampon avec une adresse. */
 GBufferLine *g_buffer_view_find_line_by_addr(const GBufferView *, const vmpa2t *, BufferLineFlags, size_t *);
 
diff --git a/src/gui/dialogs/export.c b/src/gui/dialogs/export.c
index 33fd0c5..0d7a12b 100644
--- a/src/gui/dialogs/export.c
+++ b/src/gui/dialogs/export.c
@@ -48,6 +48,9 @@ static void export_assistant_cancel(GtkAssistant *, gpointer);
 /* Ferme l'assistant et déroule la procédure. */
 static void export_assistant_close(GtkAssistant *, GObject *);
 
+/* Réalise l'exportation d'un contenu binaire comme demandé. */
+static void do_binary_export(GCodeBuffer *, const vmpa2t *, const vmpa2t *, buffer_export_context *, BufferExportType, const bool *);
+
 
 
 /* ----------------------- DEFINITION DU FORMAT D'EXPORTATION ----------------------- */
@@ -187,7 +190,6 @@ static void export_assistant_close(GtkAssistant *assistant, GObject *ref)
     bool display[BLC_DISPLAY];              /* Affichage à garantir        */
     GLoadedBinary *binary;                  /* Binaire chargé à parcourir  */
     GCodeBuffer *buffer;                    /* Tampon de code à traiter    */
-    GBufferView *view;                      /* Vue à exporter              */
     GObject *support;                       /* Support interne à supprimer */
 
     /* Type d'exportation */
@@ -259,9 +261,8 @@ static void export_assistant_close(GtkAssistant *assistant, GObject *ref)
     binary = G_LOADED_BINARY(g_object_get_data(ref, "binary"));
 
     buffer = g_loaded_binary_get_disassembled_buffer(binary);
-    view = g_buffer_view_new(buffer, NULL);
 
-    g_buffer_view_export(view, &ctx, type, display);
+    do_binary_export(buffer, NULL, NULL, &ctx, type, display);
 
     /* Conclusion */
 
@@ -277,8 +278,6 @@ static void export_assistant_close(GtkAssistant *assistant, GObject *ref)
 
     }
 
-    g_object_unref(view);
-
     support = G_OBJECT(g_object_get_data(G_OBJECT(assistant), "text_options"));
     if (support != NULL) g_object_unref(support);
 
@@ -290,6 +289,94 @@ static void export_assistant_close(GtkAssistant *assistant, GObject *ref)
 }
 
 
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : buffer = tampon de données à utiliser.                       *
+*                start   = première adresse visée ou 0.                       *
+*                end     = dernière adresse visée ou VMPA_MAX.                *
+*                ctx     = éléments à disposition pour l'exportation.         *
+*                type    = type d'exportation attendue.                       *
+*                display = règles d'affichage des colonnes modulables.        *
+*                                                                             *
+*  Description : Réalise l'exportation d'un contenu binaire comme demandé.    *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void do_binary_export(GCodeBuffer *buffer, const vmpa2t *start, const vmpa2t *end, buffer_export_context *ctx, BufferExportType type, const bool *display)
+{
+    typedef struct _export_data
+    {
+        buffer_export_context *ctx;         /* Contexte d'exportation      */
+        BufferExportType type;              /* Type d'exportation menée    */
+        const bool *display;                /* Paramètres d'affichage      */
+
+    } export_data;
+
+    export_data data;                       /* Données à faire suivre      */
+    GDelayedWork *work;                     /* Tâche laborieuse à attendre */
+
+    switch (type)
+    {
+        case BET_HTML:
+            dprintf(ctx->fd, "<HTML>\n");
+            dprintf(ctx->fd, "<HEAD>\n");
+            dprintf(ctx->fd, "\t<META http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"/>\n");
+            dprintf(ctx->fd, "</HEAD>\n");
+            dprintf(ctx->fd, "<BODY>\n");
+            dprintf(ctx->fd, "<STYLE  type=\"text/css\">\n");
+            dprintf(ctx->fd, "TABLE {\n");
+            dprintf(ctx->fd, "\tbackground-color: %s;\n", ctx->bg_color);
+            dprintf(ctx->fd, "\tborder: 0px;\n");
+            dprintf(ctx->fd, "\tfont-family: %s;\n", ctx->font_name);
+            dprintf(ctx->fd, "}\n");
+            dprintf(ctx->fd, "TD {\n");
+            dprintf(ctx->fd, "\tborder: 0px;\n");
+            dprintf(ctx->fd, "\tpadding-left: 8px;\n");
+            dprintf(ctx->fd, "\tpadding-right: 8px;\n");
+            dprintf(ctx->fd, "}\n");
+            g_buffer_segment_export_style(ctx, type);
+            dprintf(ctx->fd, "</STYLE>\n");
+            dprintf(ctx->fd, "<TABLE>\n");
+            break;
+        default:
+            break;
+    }
+
+    data.ctx = ctx;
+    data.type = type;
+    data.display = display;
+
+    bool export_line(GCodeBuffer *buf, GBufferLine *ln, export_data *d)
+    {
+        g_buffer_line_export(ln, d->ctx, d->type, d->display);
+
+        return true;
+
+    }
+
+    work = g_buffer_code_scan(buffer, start, end, _("Exporting binary content"),
+                              (process_line_fc)export_line, &data);
+
+    g_delayed_work_wait_for_completion(work);
+
+    switch (type)
+    {
+        case BET_HTML:
+            dprintf(ctx->fd, "</TABLE>\n");
+            dprintf(ctx->fd, "</BODY>\n");
+            dprintf(ctx->fd, "</HTML>\n");
+            break;
+        default:
+            break;
+    }
+
+}
+
+
 
 /* ---------------------------------------------------------------------------------- */
 /*                         DEFINITION DU FORMAT D'EXPORTATION                         */
-- 
cgit v0.11.2-87-g4458