From e6f437296541fcc1a1b5d6fb693eeab963677f8b Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Fri, 3 Aug 2018 10:24:03 +0200
Subject: Populated the strings panel in a generic way.

---
 src/format/format.c      |   4 +-
 src/format/strsym.c      | 136 +++++++++++++++++++++++++++++++----------------
 src/format/strsym.h      |   3 ++
 src/gui/panels/strings.c |  19 ++-----
 4 files changed, 98 insertions(+), 64 deletions(-)

diff --git a/src/format/format.c b/src/format/format.c
index 91cca37..18b3b07 100644
--- a/src/format/format.c
+++ b/src/format/format.c
@@ -795,7 +795,9 @@ bool g_binary_format_add_symbol(GBinFormat *format, GBinSymbol *symbol)
     range = g_binary_symbol_get_range(symbol);
     addr = get_mrange_addr(range);
 
-    assert(has_phys_addr(addr) || g_binary_symbol_get_status(symbol) == SSS_IMPORTED);
+    assert(has_phys_addr(addr)
+           || g_binary_symbol_get_status(symbol) == SSS_IMPORTED
+           || g_binary_symbol_get_status(symbol) == SSS_DYNAMIC);
 #endif
 
     g_binary_format_lock_unlock_symbols_wr(format, true);
diff --git a/src/format/strsym.c b/src/format/strsym.c
index b709b93..b60bd02 100644
--- a/src/format/strsym.c
+++ b/src/format/strsym.c
@@ -48,7 +48,7 @@ struct _GStrSymbol
     union
     {
         GBinContent *content;               /* Conteneur d'origine         */
-        char *utf8;                         /* Données utilisables         */
+        char *string;                       /* Données utilisables         */
 
     };
 
@@ -76,6 +76,9 @@ static void g_string_symbol_dispose(GStrSymbol *);
 /* Procède à la libération totale de la mémoire. */
 static void g_string_symbol_finalize(GStrSymbol *);
 
+/* Vérifie la pertinence de l'encodage attribué à une chaîne. */
+static void g_string_symbol_check_encoding(GStrSymbol *);
+
 
 
 /* ---------------------------------------------------------------------------------- */
@@ -169,6 +172,9 @@ static void g_string_symbol_dispose(GStrSymbol *symbol)
 
 static void g_string_symbol_finalize(GStrSymbol *symbol)
 {
+    if (!symbol->has_content)
+        free(symbol->string);
+
     G_OBJECT_CLASS(g_string_symbol_parent_class)->finalize(G_OBJECT(symbol));
 
 }
@@ -192,9 +198,6 @@ GBinSymbol *g_string_symbol_new_read_only(GBinFormat *format, const mrange_t *ra
 {
     GStrSymbol *result;                     /* Nouveau symbole à renvoyer  */
     GBinSymbol *parent;                     /* Type d'instance parent      */
-    vmpa2t pos;                             /* Tête de lecture modifiable  */
-    phys_t length;                          /* Taille de la chaîne         */
-    const char *base;                       /* Contenu complet et original */
 
     result = g_object_new(G_TYPE_STR_SYMBOL, NULL);
 
@@ -208,7 +211,30 @@ GBinSymbol *g_string_symbol_new_read_only(GBinFormat *format, const mrange_t *ra
     result->content = g_binary_format_get_content(format);
     result->has_content = true;
 
-    switch (encoding)
+    g_string_symbol_check_encoding(result);
+
+    return G_BIN_SYMBOL(result);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : symbol = symbole à venir consulter.                          *
+*                                                                             *
+*  Description : Vérifie la pertinence de l'encodage attribué à une chaîne.   *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_string_symbol_check_encoding(GStrSymbol *symbol)
+{
+    const char *string;                     /* Données à analyser          */
+
+    switch (symbol->encoding)
     {
         case SET_ASCII:
             break;
@@ -216,38 +242,30 @@ GBinSymbol *g_string_symbol_new_read_only(GBinFormat *format, const mrange_t *ra
         case SET_UTF_8:
         case SET_MUTF_8:
 
-            copy_vmpa(&pos, get_mrange_addr(range));
-            length = get_mrange_length(range);
-
-            base = (const char *)g_binary_content_get_raw_access(result->content, &pos, length);
+            string = g_string_symbol_get_utf8(symbol);
 
-            if (!g_utf8_validate(base, -1, NULL))
-                result->encoding = SET_ASCII;
+            if (!g_utf8_validate(string, -1, NULL))
+                symbol->encoding = SET_ASCII;
 
             break;
 
         case SET_GUESS:
 
-            copy_vmpa(&pos, get_mrange_addr(range));
-            length = get_mrange_length(range);
+            string = g_string_symbol_get_utf8(symbol);
 
-            base = (const char *)g_binary_content_get_raw_access(result->content, &pos, length);
+            if (g_str_is_ascii(string))
+                symbol->encoding = SET_ASCII;
 
-            if (g_str_is_ascii(base))
-                result->encoding = SET_ASCII;
-
-            else if (g_utf8_validate(base, -1, NULL))
-                result->encoding = SET_UTF_8;
+            else if (g_utf8_validate(string, -1, NULL))
+                symbol->encoding = SET_UTF_8;
 
             else
-                result->encoding = SET_ASCII;
+                symbol->encoding = SET_ASCII;
 
             break;
 
     }
 
-    return G_BIN_SYMBOL(result);
-
 }
 
 
@@ -269,6 +287,47 @@ StringEncodingType g_string_symbol_get_encoding(const GStrSymbol *symbol)
 
     result = symbol->encoding;
 
+    assert(result != SET_GUESS);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : symbol = symbole à venir consulter.                          *
+*                                                                             *
+*  Description : Fournit la chaîne de caractères du symbole.                  *
+*                                                                             *
+*  Retour      : Chaîne de caractères, à priori en UTF-8.                     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+const char *g_string_symbol_get_utf8(const GStrSymbol *symbol)
+{
+    const char *result;                     /* Données à retourner         */
+    const mrange_t *range;                  /* Couverture du symbole       */
+    vmpa2t pos;                             /* Tête de lecture modifiable  */
+    phys_t length;                          /* Taille de la chaîne         */
+
+    if (symbol->has_content)
+    {
+        range = g_binary_symbol_get_range(G_BIN_SYMBOL(symbol));
+
+        copy_vmpa(&pos, get_mrange_addr(range));
+
+        length = get_mrange_length(range);
+
+        result = (const char *)g_binary_content_get_raw_access(symbol->content, &pos, length);
+
+    }
+
+    else
+        result = symbol->string;
+
     return result;
 
 }
@@ -289,10 +348,8 @@ StringEncodingType g_string_symbol_get_encoding(const GStrSymbol *symbol)
 
 bool g_string_symbol_build_label(GStrSymbol *symbol, GBinFormat *format)
 {
-    const mrange_t *range;                  /* Couverture du symbole       */
-    vmpa2t pos;                             /* Tête de lecture modifiable  */
-    phys_t length;                          /* Taille de la chaîne         */
     const char *base;                       /* Contenu complet et original */
+    size_t length;                          /* Taille de la chaîne         */
     size_t allocated;                       /* Taille réservée             */
     char *label;                            /* Etiquette à constituer      */
     size_t cur;                             /* Point d'écriture courant    */
@@ -304,36 +361,19 @@ bool g_string_symbol_build_label(GStrSymbol *symbol, GBinFormat *format)
     glong size;                             /* Taille du caractère         */
     bool empty;                             /* Base de l'étiquette vide ?  */
     GBinSymbol *found;                      /* Symbole similaire trouvé    */
+    const mrange_t *range;                  /* Couverture du symbole       */
+    vmpa2t pos;                             /* Tête de lecture modifiable  */
     VMPA_BUFFER(last_sfx);                  /* Dernier suffixe à intégrer  */
 
     /* Base de décision */
 
-    range = g_binary_symbol_get_range(G_BIN_SYMBOL(symbol));
-
-    copy_vmpa(&pos, get_mrange_addr(range));
-
-    switch (g_binary_symbol_get_target_type(G_BIN_SYMBOL(symbol)))
-    {
-        case STP_RO_STRING:
-            length = get_mrange_length(range);
-            base = (const char *)g_binary_content_get_raw_access(symbol->content, &pos, length);
-            break;
-
-        case STP_DYN_STRING:
-            base = symbol->utf8;
-            length = strlen((char *)base);
-            break;
-
-        default:
-            assert(false);
-            base = NULL;
-            break;
-
-    }
+    base = g_string_symbol_get_utf8(symbol);
 
     if (base == NULL)
         return false;
 
+    length = strlen(base);
+
     /* Phase de constitution */
 
     allocated = length + 5 + VMPA_MAX_LEN + 1;
@@ -448,6 +488,8 @@ bool g_string_symbol_build_label(GStrSymbol *symbol, GBinFormat *format)
             label[cur++] = '_';
         }
 
+        range = g_binary_symbol_get_range(G_BIN_SYMBOL(symbol));
+
         copy_vmpa(&pos, get_mrange_addr(range));
 
         assert(has_phys_addr(&pos) || has_virt_addr(&pos));
diff --git a/src/format/strsym.h b/src/format/strsym.h
index e827e6a..b3c7a44 100644
--- a/src/format/strsym.h
+++ b/src/format/strsym.h
@@ -72,6 +72,9 @@ GBinSymbol *g_string_symbol_new_read_only(GBinFormat *, const mrange_t *, String
 /* Fournit l'encodage d'une chaîne de caractères. */
 StringEncodingType g_string_symbol_get_encoding(const GStrSymbol *);
 
+/* Fournit la chaîne de caractères du symbole. */
+const char *g_string_symbol_get_utf8(const GStrSymbol *);
+
 /* Construit une désignation pour chaîne de caractères. */
 bool g_string_symbol_build_label(GStrSymbol *, GBinFormat *);
 
diff --git a/src/gui/panels/strings.c b/src/gui/panels/strings.c
index 895a1b9..9359432 100644
--- a/src/gui/panels/strings.c
+++ b/src/gui/panels/strings.c
@@ -745,8 +745,7 @@ static void reload_strings_for_new_list_view(const GStringsPanel *panel, GtkStat
     VMPA_BUFFER(virt);                      /* Adresse virtuelle           */
     GBinPortion *portion;                   /* Zone mémoire d'appartenance */
     const char *area;                       /* Description de la zone      */
-    char *text;                             /* Texte original référencé    */
-    vmpa2t pos;                             /* Tête de lecture modifiable  */
+    const char *text;                       /* Texte original référencé    */
     GtkTreeIter iter;                       /* Point d'insertion           */
 
     builder = G_PANEL_ITEM(panel)->builder;
@@ -780,18 +779,8 @@ static void reload_strings_for_new_list_view(const GStringsPanel *panel, GtkStat
         area = g_binary_portion_get_desc(portion);
         g_object_unref(G_OBJECT(portion));
 
-        text = (char *)calloc(get_mrange_length(range) + 1, sizeof(char));
-
-        copy_vmpa(&pos, addr);
-
-        if (!g_binary_content_read_raw(content, &pos, get_mrange_length(range), (uint8_t *)text))
-        {
-            free(text);
-            goto rsfnlv_next;
-        }
-
-        addr = get_mrange_addr(g_binary_symbol_get_range(symbol));
-        vmpa2_virt_to_string(addr, size, virt, NULL);
+        text = g_string_symbol_get_utf8(G_STR_SYMBOL(symbol));
+        if (text == NULL) goto rsfnlv_next;
 
         gtk_list_store_append(store, &iter);
         gtk_list_store_set(store, &iter,
@@ -809,8 +798,6 @@ static void reload_strings_for_new_list_view(const GStringsPanel *panel, GtkStat
 
         data->count++;
 
-        free(text);
-
  rsfnlv_next:
 
         g_object_unref(G_OBJECT(symbol));
-- 
cgit v0.11.2-87-g4458