From 6876405cab150f08d2a81d5ecd777b4f0b9e8768 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Tue, 2 Jun 2020 16:40:46 +0200 Subject: Made the binary export working again. --- src/glibext/linesegment.h | 12 +- src/glibext/seq.c | 3 +- src/gui/dialogs/export_disass.c | 285 +++++++++++++++++++++++++++------------- 3 files changed, 203 insertions(+), 97 deletions(-) diff --git a/src/glibext/linesegment.h b/src/glibext/linesegment.h index cb809fc..3585ffb 100644 --- a/src/glibext/linesegment.h +++ b/src/glibext/linesegment.h @@ -152,22 +152,18 @@ typedef enum _BufferExportType /* Elements sur lesquels une exportation peut s'appuyer */ typedef struct _buffer_export_context { - union - { - int fd; /* Flux ouvert en écriture */ - - }; + int fd; /* Flux ouvert en écriture */ union { /* BET_TEXT */ - const char *sep; /* Séparation entre colonnes */ + char *sep; /* Séparation entre colonnes */ /* BET_HTML */ struct { - const char *font_name; /* Police d'impression */ - const char *bg_color; /* Fond du tableau HTML */ + char *font_name; /* Police d'impression */ + char *bg_color; /* Fond du tableau HTML */ }; diff --git a/src/glibext/seq.c b/src/glibext/seq.c index 487f4b4..3474d72 100644 --- a/src/glibext/seq.c +++ b/src/glibext/seq.c @@ -343,6 +343,7 @@ static void g_seq_work_process(GSeqWork *work, GtkStatusStack *status) } - *(work->status) = (i == work->end && state); + if (work->type == SWT_BOOLEAN) + *(work->status) = (i == work->end && state); } diff --git a/src/gui/dialogs/export_disass.c b/src/gui/dialogs/export_disass.c index 5bf4b80..beaa3c8 100644 --- a/src/gui/dialogs/export_disass.c +++ b/src/gui/dialogs/export_disass.c @@ -34,7 +34,12 @@ #include +#include "../core/global.h" #include "../../common/extstr.h" +#include "../../core/global.h" +#include "../../core/logs.h" +#include "../../core/queue.h" +#include "../../glibext/seq.h" #include "../../gtkext/easygtk.h" @@ -48,8 +53,27 @@ 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(void/*GCodeBuffer*/ *, const vmpa2t *, const vmpa2t *, buffer_export_context *, BufferExportType, const bool *); +/* Condensé des informations d'exportation */ +typedef struct _export_info_t +{ + GBufferCache *cache; /* Tampon à manipuler */ + + buffer_export_context *ctx; /* Contexte d'exportation */ + BufferExportType type; /* Type d'exportation menée */ + bool display[BLC_COUNT]; /* Paramètres d'affichage */ + + activity_id_t msg; /* Message de progression */ + +} export_info_t; + +/* Lance l'exportation d'un contenu binaire comme demandé. */ +static void start_binary_export(GBufferCache *, buffer_export_context *, BufferExportType, const bool *); + +/* Réalise l'exportation d'une ligne particulière. */ +static void export_one_binary_line(const export_info_t *, size_t, GtkStatusStack *, activity_id_t); + +/* Acquitte la fin d'une tâche d'exportation complète. */ +static void on_binary_export_completed(GSeqWork *, export_info_t *); @@ -181,8 +205,6 @@ static void export_assistant_cancel(GtkAssistant *assistant, gpointer data) static void export_assistant_close(GtkAssistant *assistant, GObject *ref) { -#if 0 - GtkComboBox *combo; /* Selection du format */ BufferExportType type; /* Type d'exportation requise */ buffer_export_context ctx; /* Contexte à constituer */ @@ -191,7 +213,7 @@ static void export_assistant_close(GtkAssistant *assistant, GObject *ref) GtkToggleButton *checkbutton; /* Coche à retrouver */ bool display[BLC_DISPLAY]; /* Affichage à garantir */ GLoadedBinary *binary; /* Binaire chargé à parcourir */ - GCodeBuffer *buffer; /* Tampon de code à traiter */ + GBufferCache *cache; /* Tampon de code à traiter */ GObject *support; /* Support interne à supprimer */ /* Type d'exportation */ @@ -205,22 +227,11 @@ static void export_assistant_close(GtkAssistant *assistant, GObject *ref) entry = GTK_ENTRY(g_object_get_data(ref, "filename")); filename = gtk_entry_get_text(entry); - switch (type) + ctx.fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR); + if (ctx.fd == -1) { - case BET_TEXT: - case BET_HTML: - ctx.fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR); - if (ctx.fd == -1) - { - perror("open"); - return; - } - break; - - default: - assert(false); - break; - + perror("open"); + return; } /* Eléments à afficher */ @@ -240,16 +251,20 @@ static void export_assistant_close(GtkAssistant *assistant, GObject *ref) { case BET_TEXT: entry = GTK_ENTRY(g_object_get_data(ref, "text_separator")); - ctx.sep = gtk_entry_get_text(entry); - if (strcmp(ctx.sep, "\\t") == 0) ctx.sep = "\t"; + ctx.sep = strdup(gtk_entry_get_text(entry)); + if (strcmp(ctx.sep, "\\t") == 0) + { + free(ctx.sep); + ctx.sep = strdup("\t"); + } break; case BET_HTML: entry = GTK_ENTRY(g_object_get_data(ref, "html_font_name")); - ctx.font_name = gtk_entry_get_text(entry); + ctx.font_name = strdup(gtk_entry_get_text(entry)); entry = GTK_ENTRY(g_object_get_data(ref, "html_bg_color")); - ctx.bg_color = gtk_entry_get_text(entry); + ctx.bg_color = strdup(gtk_entry_get_text(entry)); break; @@ -262,30 +277,20 @@ 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); + cache = g_loaded_binary_get_disassembly_cache(binary); - do_binary_export(buffer, NULL, NULL, &ctx, type, display); + start_binary_export(cache, &ctx, type, display); - /* Conclusion */ - - switch (type) - { - case BET_TEXT: - case BET_HTML: - close(ctx.fd); - break; + g_object_unref(G_OBJECT(cache)); - default: - break; - - } + /* Conclusion */ support = G_OBJECT(g_object_get_data(G_OBJECT(assistant), "text_options")); if (support != NULL) g_object_unref(support); support = G_OBJECT(g_object_get_data(G_OBJECT(assistant), "html_options")); if (support != NULL) g_object_unref(support); -#endif + gtk_widget_destroy(GTK_WIDGET(assistant)); } @@ -293,14 +298,12 @@ 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. * +* Paramètres : cache = tampon de données à utiliser. * +* template = paramètres dont s'inspirer 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é. * +* Description : Lance l'exportation d'un contenu binaire comme demandé. * * * * Retour : - * * * @@ -308,75 +311,181 @@ static void export_assistant_close(GtkAssistant *assistant, GObject *ref) * * ******************************************************************************/ -static void do_binary_export(void/*GCodeBuffer*/ *buffer, const vmpa2t *start, const vmpa2t *end, buffer_export_context *ctx, BufferExportType type, const bool *display) +static void start_binary_export(GBufferCache *cache, buffer_export_context *template, BufferExportType type, const bool *display) { -#if 0 - typedef struct _export_data + export_info_t *info; /* Infos à faire circuler */ + BufferLineColumn i; /* Boucle de parcours */ + GWorkQueue *queue; /* Gestionnaire de différés */ + size_t count; /* Quantité de lignes à traiter*/ + GSeqWork *work; /* Tâche de chargement à lancer*/ + + /* Copie des paramètres d'exportation */ + + info = calloc(1, sizeof(export_info_t)); + + info->cache = cache; + g_object_ref(G_OBJECT(cache)); + + info->ctx = malloc(sizeof(buffer_export_context)); + + info->ctx->fd = template->fd; + + switch (type) { - buffer_export_context *ctx; /* Contexte d'exportation */ - BufferExportType type; /* Type d'exportation menée */ - const bool *display; /* Paramètres d'affichage */ + case BET_TEXT: + info->ctx->sep = template->sep; + break; - } export_data; + case BET_HTML: + info->ctx->font_name = template->font_name; + info->ctx->bg_color = template->bg_color; + break; - export_data data; /* Données à faire suivre */ - GDelayedWork *work; /* Tâche laborieuse à attendre */ + default: + break; + + } + + info->type = type; + + for (i = 0; i < BLC_DISPLAY; i++) + info->display[i] = display[i]; + + /* Données exportées initiales */ switch (type) { case BET_HTML: - dprintf(ctx->fd, "\n"); - dprintf(ctx->fd, "\n"); - dprintf(ctx->fd, "\t\n"); - dprintf(ctx->fd, "\n"); - dprintf(ctx->fd, "\n"); - dprintf(ctx->fd, "\n"); - dprintf(ctx->fd, "\n"); + dprintf(template->fd, "\n"); + dprintf(template->fd, "\n"); + dprintf(template->fd, "\t\n"); + dprintf(template->fd, "\n"); + dprintf(template->fd, "\n"); + dprintf(template->fd, "\n"); + dprintf(template->fd, "
\n"); break; + default: break; + } - data.ctx = ctx; - data.type = type; - data.display = display; + /* Poursuite de l'opération */ - bool export_line(GCodeBuffer *buf, GBufferLine *ln, export_data *d) + queue = get_work_queue(); + + g_buffer_cache_lock(cache); + count = g_buffer_cache_count_lines(cache); + + info->msg = gtk_status_stack_add_activity(get_global_status(), _("Exporting binary content..."), count); + + work = g_seq_work_new(info, 0, count, info->msg, (seq_work_cb)export_one_binary_line); + + g_signal_connect(work, "work-completed", G_CALLBACK(on_binary_export_completed), info); + + g_work_queue_schedule_work(queue, G_DELAYED_WORK(work), DEFAULT_WORK_GROUP); + +} + + +/****************************************************************************** +* * +* Paramètres : info = ensemble d'informations utiles à l'opération. * +* i = indice des éléments à traiter. * +* status = barre de statut à tenir informée. * +* id = identifiant du message affiché à l'utilisateur. * +* * +* Description : Réalise l'exportation d'une ligne particulière. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void export_one_binary_line(const export_info_t *info, size_t i, GtkStatusStack *status, activity_id_t id) +{ + GBufferLine *line; /* Ligne particulière à traiter*/ + + line = g_buffer_cache_find_line_by_index(info->cache, i); + + g_buffer_line_export(line, info->ctx, info->type, info->display); + + g_object_unref(G_OBJECT(line)); + + gtk_status_stack_update_activity_value(status, id, 1); + +} + + +/****************************************************************************** +* * +* Paramètres : work = tâche de sauvegarde menée à son terme. * +* Paramètres : info = ensemble d'informations liées à l'opération terminée. * +* * +* Description : Acquitte la fin d'une tâche d'exportation complète. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void on_binary_export_completed(GSeqWork *work, export_info_t *info) +{ + switch (info->type) { - g_buffer_line_export(ln, d->ctx, d->type, d->display); + case BET_HTML: + dprintf(info->ctx->fd, "
\n"); + dprintf(info->ctx->fd, "\n"); + dprintf(info->ctx->fd, "\n"); + break; - return true; + default: + break; } - work = g_buffer_code_scan(buffer, start, end, _("Exporting binary content"), - (process_line_fc)export_line, &data); + log_simple_message(LMT_INFO, "Binary content exported!"); - g_delayed_work_wait_for_completion(work); + g_buffer_cache_unlock(info->cache); + g_object_unref(G_OBJECT(info->cache)); - switch (type) + close(info->ctx->fd); + + switch (info->type) { + case BET_TEXT: + free(info->ctx->sep); + break; + case BET_HTML: - dprintf(ctx->fd, "\n"); - dprintf(ctx->fd, "\n"); - dprintf(ctx->fd, "\n"); + free(info->ctx->font_name); + free(info->ctx->bg_color); break; + default: break; + } -#endif + + gtk_status_stack_remove_activity(get_global_status(), info->msg); + + free(info->ctx); + free(info); + } -- cgit v0.11.2-87-g4458