summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/glibext/linesegment.h12
-rw-r--r--src/glibext/seq.c3
-rw-r--r--src/gui/dialogs/export_disass.c285
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 <i18n.h>
+#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, "<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");
- export_line_segment_style(ctx, type);
- dprintf(ctx->fd, "</STYLE>\n");
- dprintf(ctx->fd, "<TABLE>\n");
+ dprintf(template->fd, "<HTML>\n");
+ dprintf(template->fd, "<HEAD>\n");
+ dprintf(template->fd, "\t<META http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"/>\n");
+ dprintf(template->fd, "</HEAD>\n");
+ dprintf(template->fd, "<BODY>\n");
+ dprintf(template->fd, "<STYLE type=\"text/css\">\n");
+ dprintf(template->fd, "TABLE {\n");
+ dprintf(template->fd, "\tbackground-color: %s;\n", template->bg_color);
+ dprintf(template->fd, "\tborder: 0px;\n");
+ dprintf(template->fd, "\tfont-family: %s;\n", template->font_name);
+ dprintf(template->fd, "}\n");
+ dprintf(template->fd, "TD {\n");
+ dprintf(template->fd, "\tborder: 0px;\n");
+ dprintf(template->fd, "\tpadding-left: 8px;\n");
+ dprintf(template->fd, "\tpadding-right: 8px;\n");
+ dprintf(template->fd, "}\n");
+ export_line_segment_style(template, type);
+ dprintf(template->fd, "</STYLE>\n");
+ dprintf(template->fd, "<TABLE>\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, "</TABLE>\n");
+ dprintf(info->ctx->fd, "</BODY>\n");
+ dprintf(info->ctx->fd, "</HTML>\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, "</TABLE>\n");
- dprintf(ctx->fd, "</BODY>\n");
- dprintf(ctx->fd, "</HTML>\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);
+
}