diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2017-04-19 19:25:04 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2017-04-19 19:25:04 (GMT) |
commit | c177597d6da5dedb32aa176e8370db8ffb7f87aa (patch) | |
tree | 26f7eb2702ba4aa3dfd7267d74fe78ad79791a8c /src/analysis | |
parent | 35f37c72e9d81e478395914da6c10b3c546761a7 (diff) |
Handled static strings as well as dynamic strings in comments.
Diffstat (limited to 'src/analysis')
-rw-r--r-- | src/analysis/db/cdb.c | 4 | ||||
-rw-r--r-- | src/analysis/db/client.c | 4 | ||||
-rw-r--r-- | src/analysis/db/item.c | 2 | ||||
-rw-r--r-- | src/analysis/db/items/bookmark.c | 2 | ||||
-rw-r--r-- | src/analysis/db/items/comment.c | 300 | ||||
-rw-r--r-- | src/analysis/db/items/comment.h | 10 | ||||
-rw-r--r-- | src/analysis/db/misc/rlestr.c | 107 | ||||
-rw-r--r-- | src/analysis/db/misc/rlestr.h | 25 | ||||
-rw-r--r-- | src/analysis/db/server.c | 2 |
9 files changed, 393 insertions, 63 deletions
diff --git a/src/analysis/db/cdb.c b/src/analysis/db/cdb.c index 49662e8..78f2aa8 100644 --- a/src/analysis/db/cdb.c +++ b/src/analysis/db/cdb.c @@ -287,7 +287,7 @@ GCdbArchive *g_cdb_archive_new(const char *basedir, const rle_string *hash, cons result = g_object_new(G_TYPE_CDB_ARCHIVE, NULL); - dup_rle_string(&result->hash, hash); + dup_into_rle_string(&result->hash, get_rle_string(hash)); /* Chemin de l'archive */ @@ -1061,7 +1061,7 @@ DBError g_cdb_archive_add_client(GCdbArchive *archive, int fd, const rle_string archive->clients = (cdb_client *)realloc(archive->clients, ++archive->count * sizeof(cdb_client)); archive->clients[archive->count - 1].fd = fd; - dup_rle_string(&archive->clients[archive->count - 1].user, user); + dup_into_rle_string(&archive->clients[archive->count - 1].user, get_rle_string(user)); /* Démarrage ou redémarrage du processus d'écoute */ diff --git a/src/analysis/db/client.c b/src/analysis/db/client.c index 309d9ed..769eab7 100644 --- a/src/analysis/db/client.c +++ b/src/analysis/db/client.c @@ -187,7 +187,7 @@ GDbClient *g_db_client_new(char *author, char *kfile, const char *name, const ch result->name = name; - set_rle_string(&result->hash, hash); + init_static_rle_string(&result->hash, hash); result->collections = collections; return result; @@ -386,7 +386,7 @@ static bool g_db_client_start_common(GDbClient *client, const char *desc) status = pack_rle_string(&client->hash, &out_pbuf); if (!status) goto gdcs_error; - init_rle_string(&user, client->author); + dup_into_rle_string(&user, client->author); /* FIXME : src ? */ status = pack_rle_string(&user, &out_pbuf); if (!status) goto gdcs_error; diff --git a/src/analysis/db/item.c b/src/analysis/db/item.c index 20276d6..d2c1652 100644 --- a/src/analysis/db/item.c +++ b/src/analysis/db/item.c @@ -122,7 +122,7 @@ static void g_db_item_init(GDbItem *item) status = g_generic_config_get_value(get_main_configuration(), MPK_AUTHOR_NAME, &author); assert(status); - set_rle_string(&item->author, author); + set_static_rle_string(&item->author, author); item->is_volatile = false; diff --git a/src/analysis/db/items/bookmark.c b/src/analysis/db/items/bookmark.c index 9d3b691..0db847b 100644 --- a/src/analysis/db/items/bookmark.c +++ b/src/analysis/db/items/bookmark.c @@ -604,7 +604,7 @@ const char *g_db_bookmark_get_comment(const GDbBookmark *bookmark) void g_db_bookmark_set_comment(GDbBookmark *bookmark, const char *comment) { - set_rle_string(&bookmark->comment, comment); + dup_into_rle_string(&bookmark->comment, comment); } diff --git a/src/analysis/db/items/comment.c b/src/analysis/db/items/comment.c index b43c1e6..beec629 100644 --- a/src/analysis/db/items/comment.c +++ b/src/analysis/db/items/comment.c @@ -36,6 +36,7 @@ #include "../collection-int.h" #include "../item-int.h" #include "../../human/asm/lang.h" +#include "../../../common/array.h" #include "../../../common/extstr.h" #include "../../../glibext/linegen-int.h" @@ -52,10 +53,8 @@ struct _GDbComment vmpa2t addr; /* Adresse du commentaire */ BufferLineFlags flags; /* Identification de l'accroche*/ - rle_string text; /* Contenu du commentaire */ - - char **lines; /* Lignes brutes à représenter */ - size_t count; /* Quantité de ces lignes */ + flat_array_t *text; /* Contenu du commentaire */ + size_t count; /* Quantité de lignes affichées*/ bool inlined; /* Intégration dans une ligne ?*/ @@ -99,7 +98,7 @@ static gint g_db_comment_cmp(GDbComment *, GDbComment *, bool); static bool g_db_comment_unpack(GDbComment *, packed_buffer *); /* Exporte la définition d'un commentaire dans un flux réseau. */ -static bool g_db_comment_pack(const GDbComment *, packed_buffer *); +static bool g_db_comment_pack(GDbComment *, packed_buffer *); /* Construit la description humaine d'un commentaire. */ static void g_db_comment_build_label(GDbComment *); @@ -114,19 +113,22 @@ static bool g_db_comment_apply(GDbComment *, GLoadedBinary *); static bool g_db_comment_cancel(GDbComment *, GLoadedBinary *); /* Constitue les champs destinés à une insertion / modification. */ -static bool g_db_comment_prepare_db_statement(const GDbComment *, bound_value **, size_t *); +static bool g_db_comment_prepare_db_statement(GDbComment *, bound_value **, size_t *); /* Charge les valeurs utiles pour un commentaire. */ static bool g_db_comment_load(GDbComment *, const bound_value *, size_t); -/* Définit le commentaire associé à un commentaire. */ -static void g_db_comment_set_text(GDbComment *, const char *); +/* Associe un contenu formaté supplémentaire à un commentaire. */ +static void g_db_comment_add_rle_string(GDbComment *, const rle_string *); /* ------------------------ OFFRE DE CAPACITES DE GENERATION ------------------------ */ +/* Calcule le nombre de lignes suite à un changement de contenu. */ +static void g_db_comment_update_count_lines(GDbComment *); + /* Indique le nombre de ligne prêtes à être générées. */ static size_t g_db_comment_count_lines(const GDbComment *); @@ -253,7 +255,7 @@ static void g_db_comment_class_init(GDbCommentClass *klass) static void g_db_comment_init(GDbComment *comment) { - comment->lines = NULL; + comment->text = NULL; comment->count = 0; } @@ -298,12 +300,6 @@ static void g_db_comment_dispose(GDbComment *comment) { size_t i; /* Boucle de parcours */ - for (i = 0; i < comment->count; i++) - free(comment->lines[i]); - - if (comment->lines != NULL) - free(comment->lines); - for (i = 0; i < comment->old_count; i++) g_object_unref(G_OBJECT(comment->old_inlined[i])); @@ -329,7 +325,25 @@ static void g_db_comment_dispose(GDbComment *comment) static void g_db_comment_finalize(GDbComment *comment) { - exit_rle_string(&comment->text); + size_t count; /* Nombre d'éléments textuels */ + size_t i; /* Boucle de parcours */ + rle_string *string; /* Chaîne à traiter */ + + lock_flat_array(&comment->text); + + count = count_flat_array_items(comment->text); + + for (i = 0; i < count; i++) + { + string = get_flat_array_item(comment->text, 0, sizeof(rle_string)); + + exit_rle_string(string); + + rem_item_from_flat_array(&comment->text, 0, sizeof(rle_string)); + + } + + unlock_flat_array(&comment->text); G_OBJECT_CLASS(g_db_comment_parent_class)->finalize(G_OBJECT(comment)); @@ -340,7 +354,6 @@ static void g_db_comment_finalize(GDbComment *comment) * * * Paramètres : addr = adresse inamovible localisant une position. * * flags = indentifiants supplémentaires de ligne visée. * -* text = commentaire construit ou NULL. * * repeatable = repétition aux instructions liées ? * * * * Description : Crée une définition de commentaire dans une zone de texte. * @@ -351,7 +364,7 @@ static void g_db_comment_finalize(GDbComment *comment) * * ******************************************************************************/ -GDbComment *g_db_comment_new_inlined(const vmpa2t *addr, BufferLineFlags flags, const char *text, bool repeatable) +GDbComment *g_db_comment_new_inlined(const vmpa2t *addr, BufferLineFlags flags, bool repeatable) { GDbComment *result; /* Instance à retourner */ @@ -361,8 +374,6 @@ GDbComment *g_db_comment_new_inlined(const vmpa2t *addr, BufferLineFlags flags, result->flags = flags; - g_db_comment_set_text(result, text); - result->inlined = true; result->repeatable = repeatable; @@ -397,7 +408,7 @@ GDbComment *g_db_comment_new_area(const vmpa2t *addr, BufferLineFlags flags, con result->flags = flags; - g_db_comment_set_text(result, text); + g_db_comment_add_dynamic_text(result, strdup(text)); result->inlined = false; @@ -425,11 +436,32 @@ GDbComment *g_db_comment_new_area(const vmpa2t *addr, BufferLineFlags flags, con static gint g_db_comment_cmp(GDbComment *a, GDbComment *b, bool with) { gint result; /* Bilan de la comparaison */ + char *string_a; /* Texte du commentaire A */ + char *string_b; /* Texte du commentaire B */ result = cmp_vmpa_by_phy(&a->addr, &b->addr); if (result == 0) - result = cmp_rle_string(&a->text, &b->text); + { + string_a = g_db_comment_get_text(a); + string_b = g_db_comment_get_text(b); + + if (string_a == NULL && string_b == NULL) + result = 0; + + else if (string_a != NULL && string_b == NULL) + result = 1; + + else if (string_a == NULL && string_b != NULL) + result = -1; + + else + result = strcmp(string_a, string_b); + + if (string_a != NULL) free(string_a); + if (string_b != NULL) free(string_b); + + } if (result == 0) result = G_DB_ITEM_CLASS(g_db_comment_parent_class)->cmp(G_DB_ITEM(a), G_DB_ITEM(b), with); @@ -456,6 +488,7 @@ static bool g_db_comment_unpack(GDbComment *comment, packed_buffer *pbuf) { bool result; /* Bilan à retourner */ uint32_t tmp32; /* Valeur sur 32 bits */ + rle_string string; /* Texte brut récupéré */ uint8_t tmp8; /* Valeur sur 8 bits */ result = G_DB_ITEM_CLASS(g_db_comment_parent_class)->unpack(G_DB_ITEM(comment), pbuf); @@ -470,7 +503,13 @@ static bool g_db_comment_unpack(GDbComment *comment, packed_buffer *pbuf) } if (result) - result = unpack_rle_string(&comment->text, pbuf); + { + result = unpack_rle_string(&string, pbuf); + + if (!is_rle_string_empty(&string) > 0) + g_db_comment_add_rle_string(comment, &string); + + } if (result) { @@ -502,9 +541,10 @@ static bool g_db_comment_unpack(GDbComment *comment, packed_buffer *pbuf) * * ******************************************************************************/ -static bool g_db_comment_pack(const GDbComment *comment, packed_buffer *pbuf) +static bool g_db_comment_pack(GDbComment *comment, packed_buffer *pbuf) { bool result; /* Bilan à retourner */ + rle_string text; /* Texte brut récupéré */ result = G_DB_ITEM_CLASS(g_db_comment_parent_class)->pack(G_DB_ITEM(comment), pbuf); @@ -515,7 +555,11 @@ static bool g_db_comment_pack(const GDbComment *comment, packed_buffer *pbuf) result = extend_packed_buffer(pbuf, (uint32_t []) { comment->flags }, sizeof(uint32_t), true); if (result) - result = pack_rle_string(&comment->text, pbuf); + { + init_dynamic_rle_string(&text, g_db_comment_get_text(comment)); + result = pack_rle_string(&text, pbuf); + exit_rle_string(&text); + } if (result) result = extend_packed_buffer(pbuf, (uint8_t []) { comment->inlined }, sizeof(uint8_t), true); @@ -543,10 +587,15 @@ static bool g_db_comment_pack(const GDbComment *comment, packed_buffer *pbuf) static void g_db_comment_build_label(GDbComment *comment) { VMPA_BUFFER(loc); /* Indication de position */ + size_t count; /* Nombre d'éléments textuels */ vmpa2_to_string(&comment->addr, MDS_UNDEFINED, loc, NULL); - if (is_rle_string_empty(&comment->text)) + lock_flat_array(&comment->text); + count = count_flat_array_items(comment->text); + unlock_flat_array(&comment->text); + + if (count == 0) asprintf(&G_DB_ITEM(comment)->label, _("Delete comment at %s"), loc); else @@ -917,10 +966,11 @@ static bool g_db_comment_cancel(GDbComment *comment, GLoadedBinary *binary) * * ******************************************************************************/ -static bool g_db_comment_prepare_db_statement(const GDbComment *comment, bound_value **values, size_t *count) +static bool g_db_comment_prepare_db_statement(GDbComment *comment, bound_value **values, size_t *count) { bool status; /* Bilan d'opération initiale */ bound_value *value; /* Valeur à éditer / définir */ + rle_string text; /* Texte brut récupéré */ status = G_DB_ITEM_CLASS(g_db_comment_parent_class)->prepare_stmt(G_DB_ITEM(comment), values, count); if (!status) return false; @@ -939,7 +989,10 @@ static bool g_db_comment_prepare_db_statement(const GDbComment *comment, bound_v value->integer = comment->flags; value->delete = NULL; - status &= prepare_db_statement_for_rle_string(&comment->text, "text", values, count); + init_dynamic_rle_string(&text, g_db_comment_get_text(comment)); + status &= prepare_db_statement_for_rle_string(&text, "text", values, count); + exit_rle_string(&text); + if (!status) return false; *count += 2; @@ -984,6 +1037,7 @@ static bool g_db_comment_load(GDbComment *comment, const bound_value *values, si { bool result; /* Bilan à faire remonter */ const bound_value *value; /* Valeur à éditer / définir */ + rle_string string; /* Texte brut récupéré */ result = G_DB_ITEM_CLASS(g_db_comment_parent_class)->load(G_DB_ITEM(comment), values, count); @@ -999,7 +1053,10 @@ static bool g_db_comment_load(GDbComment *comment, const bound_value *values, si } - result &= load_rle_string(&comment->text, "text", values, count); + result &= load_rle_string(&string, "text", values, count); + + if (result) + g_db_comment_add_rle_string(comment, &string); if (result) { @@ -1051,15 +1108,38 @@ const vmpa2t *g_db_comment_get_address(GDbComment *comment) * * * Description : Fournit le commentaire associé à un commentaire. * * * -* Retour : Commentaire existant ou NULL. * +* Retour : Commentaire existant à libérer après usage ou NULL. * * * * Remarques : - * * * ******************************************************************************/ -const char *g_db_comment_get_text(const GDbComment *comment) +char *g_db_comment_get_text(GDbComment *comment) { - return get_rle_string(&comment->text); + char *result; /* Chaîne constituée à renvoyer*/ + size_t count; /* Nombre d'éléments textuels */ + size_t i; /* Boucle de parcours */ + rle_string *string; /* Chaîne à consulter */ + + result = NULL; + + lock_flat_array(&comment->text); + + count = count_flat_array_items(comment->text); + + for (i = 0; i < count; i++) + { + string = get_flat_array_item(comment->text, 0, sizeof(rle_string)); + + assert(!is_rle_string_empty(string)); + + result = stradd(result, get_rle_string(string)); + + } + + unlock_flat_array(&comment->text); + + return result; } @@ -1069,7 +1149,7 @@ const char *g_db_comment_get_text(const GDbComment *comment) * Paramètres : comment = informations à consulter. * * text = commentaire construit ou NULL. * * * -* Description : Définit le commentaire associé à un commentaire. * +* Description : Associe un contenu supplémentaire à un commentaire. * * * * Retour : - * * * @@ -1077,19 +1157,81 @@ const char *g_db_comment_get_text(const GDbComment *comment) * * ******************************************************************************/ -static void g_db_comment_set_text(GDbComment *comment, const char *text) +void g_db_comment_add_dynamic_text(GDbComment *comment, char *text) { - GCodingLanguage *lang; /* Langage de sortie préféré */ + rle_string string; /* Fragment de texte à ajouter */ + + if (text != NULL) + { + init_dynamic_rle_string(&string, text); + + g_db_comment_add_rle_string(comment, &string); - set_rle_string(&comment->text, text); + } + + else + g_db_comment_update_count_lines(comment); + +} - lang = g_asm_language_new(); - comment->lines = strtoka(text, "\n", &comment->count); +/****************************************************************************** +* * +* Paramètres : comment = informations à consulter. * +* text = commentaire construit ou NULL. * +* * +* Description : Associe un contenu statique supplémentaire à un commentaire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ - g_coding_language_encapsulate_comments(lang, &comment->lines, &comment->count); +void g_db_comment_add_static_text(GDbComment *comment, const char *text) +{ + rle_string string; /* Fragment de texte à ajouter */ - g_object_unref(G_OBJECT(lang)); + if (text != NULL) + { + init_static_rle_string(&string, text); + + g_db_comment_add_rle_string(comment, &string); + + } + + else + g_db_comment_update_count_lines(comment); + +} + + +/****************************************************************************** +* * +* Paramètres : comment = informations à consulter. * +* string = commentaire établi à inétgrer. * +* * +* Description : Associe un contenu formaté supplémentaire à un commentaire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_db_comment_add_rle_string(GDbComment *comment, const rle_string *string) +{ + /* Extension du contenu */ + + lock_flat_array(&comment->text); + + add_item_to_flat_array(&comment->text, string, sizeof(rle_string)); + + unlock_flat_array(&comment->text); + + /* Mise à jour de la taille de rendu */ + + g_db_comment_update_count_lines(comment); } @@ -1102,6 +1244,51 @@ static void g_db_comment_set_text(GDbComment *comment, const char *text) /****************************************************************************** * * +* Paramètres : comment = informations à réactualiser. * +* * +* Description : Calcule le nombre de lignes suite à un changement de contenu.* +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_db_comment_update_count_lines(GDbComment *comment) +{ + char *full; /* Contenu textuel complet */ + char **lines; /* Lignes brutes à représenter */ + GCodingLanguage *lang; /* Langage de sortie préféré */ + size_t i; /* Boucle de parcours */ + + full = g_db_comment_get_text(comment); + + if (full == NULL) + comment->count = 0; + + else + { + lines = strtoka(full, "\n", &comment->count); + + lang = g_asm_language_new(); + g_coding_language_encapsulate_comments(lang, &lines, &comment->count); + g_object_unref(G_OBJECT(lang)); + + for (i = 0; i < comment->count; i++) + free(lines[i]); + + if (lines != NULL) + free(lines); + + free(full); + + } + +} + + +/****************************************************************************** +* * * Paramètres : comment = générateur à consulter. * * * * Description : Indique le nombre de ligne prêtes à être générées. * @@ -1206,7 +1393,38 @@ static BufferLineFlags g_db_comment_get_flags(const GDbComment *comment, size_t static void g_db_comment_print(GDbComment *comment, GBufferLine *line, size_t index, size_t repeat) { - g_buffer_line_append_text(line, BLC_COMMENTS, SL(comment->lines[repeat]), RTT_COMMENT, NULL); + char *full; /* Contenu textuel complet */ + size_t count; /* Quantité de ces lignes */ + char **lines; /* Lignes brutes à représenter */ + GCodingLanguage *lang; /* Langage de sortie préféré */ + size_t i; /* Boucle de parcours */ + + full = g_db_comment_get_text(comment); + + if (full != NULL) + { + lines = strtoka(full, "\n", &count); + + lang = g_asm_language_new(); + g_coding_language_encapsulate_comments(lang, &lines, &count); + g_object_unref(G_OBJECT(lang)); + + if (count != comment->count) + printf("full=%s\n", full); + + assert(count == comment->count); + + g_buffer_line_append_text(line, BLC_COMMENTS, SL(lines[repeat]), RTT_COMMENT, NULL); + + for (i = 0; i < count; i++) + free(lines[i]); + + if (lines != NULL) + free(lines); + + free(full); + + } } diff --git a/src/analysis/db/items/comment.h b/src/analysis/db/items/comment.h index 03d1bff..ee68491 100644 --- a/src/analysis/db/items/comment.h +++ b/src/analysis/db/items/comment.h @@ -58,7 +58,7 @@ typedef struct _GDbCommentClass GDbCommentClass; GType g_db_comment_get_type(void); /* Crée une définition de commentaire dans une zone de texte. */ -GDbComment *g_db_comment_new_inlined(const vmpa2t *, BufferLineFlags, const char *, bool); +GDbComment *g_db_comment_new_inlined(const vmpa2t *, BufferLineFlags, bool); /* Crée une définition de commentaire dans une zone de texte. */ GDbComment *g_db_comment_new_area(const vmpa2t *, BufferLineFlags, const char *, bool); @@ -67,7 +67,13 @@ GDbComment *g_db_comment_new_area(const vmpa2t *, BufferLineFlags, const char *, const vmpa2t *g_db_comment_get_address(GDbComment *); /* Fournit le commentaire associé à un commentaire. */ -const char *g_db_comment_get_text(const GDbComment *); +char *g_db_comment_get_text(GDbComment *); + +/* Associe un contenu supplémentaire à un commentaire. */ +void g_db_comment_add_dynamic_text(GDbComment *, char *); + +/* Associe un contenu statique supplémentaire à un commentaire. */ +void g_db_comment_add_static_text(GDbComment *, const char *); diff --git a/src/analysis/db/misc/rlestr.c b/src/analysis/db/misc/rlestr.c index 39e2d99..c1d2d95 100644 --- a/src/analysis/db/misc/rlestr.c +++ b/src/analysis/db/misc/rlestr.c @@ -43,12 +43,73 @@ * * ******************************************************************************/ -void init_rle_string(rle_string *str, const char *data) +void init_dynamic_rle_string(rle_string *str, char *data) +{ + if (data != NULL) + { + str->data = data; + str->length = strlen(data); + str->dynamic = true; + } + else + { + str->data = NULL; + str->length = 0; + } + +} + + +/****************************************************************************** +* * +* Paramètres : str = représentation de chaîne à traiter. * +* data = données à conserver en mémoire. * +* * +* Description : Définit une représentation de chaîne de caractères constante.* +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void init_static_rle_string(rle_string *str, const char *data) +{ + if (data != NULL) + { + str->cst_data = data; + str->length = strlen(data); + str->dynamic = false; + } + else + { + str->data = NULL; + str->length = 0; + } + +} + + +/****************************************************************************** +* * +* Paramètres : str = représentation de chaîne à traiter. * +* data = données à conserver en mémoire. * +* * +* Description : Copie une chaîne de caractères existante. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void dup_into_rle_string(rle_string *str, const char *data) { if (data != NULL) { str->data = strdup(data); str->length = strlen(data); + str->dynamic = true; } else { @@ -72,15 +133,44 @@ void init_rle_string(rle_string *str, const char *data) * * ******************************************************************************/ -void set_rle_string(rle_string *str, const char *data) +void set_dynamic_rle_string(rle_string *str, char *data) { if (str->data != NULL) unset_rle_string(str); if (data != NULL) { - str->data = strdup(data); + str->data = data; + str->length = strlen(data); + str->dynamic = true; + } + +} + + +/****************************************************************************** +* * +* Paramètres : str = représentation de chaîne à traiter. * +* data = données à conserver en mémoire. * +* * +* Description : Constitue une représentation de chaîne de caractères stable. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void set_static_rle_string(rle_string *str, const char *data) +{ + if (str->data != NULL) + unset_rle_string(str); + + if (data != NULL) + { + str->cst_data = data; str->length = strlen(data); + str->dynamic = false; } } @@ -102,9 +192,10 @@ void unset_rle_string(rle_string *str) { if (str->data != NULL) { - free(str->data); - str->data = NULL; + if (str->dynamic) + free(str->data); + str->data = NULL; str->length = 0; } @@ -184,6 +275,7 @@ bool unpack_rle_string(rle_string *str, packed_buffer *pbuf) if (result && str->length > 0) { str->data = (char *)malloc(str->length + 1); + str->dynamic = true; result = extract_packed_buffer(pbuf, str->data, str->length + 1, false); @@ -323,11 +415,12 @@ bool load_rle_string(rle_string *str, const char *name, const bound_value *value switch (value->type) { case SQLITE_TEXT: - set_rle_string(str, value->cstring); + unset_rle_string(str); + dup_into_rle_string(str, value->cstring); break; case SQLITE_NULL: - set_rle_string(str, NULL); + unset_rle_string(str); break; default: diff --git a/src/analysis/db/misc/rlestr.h b/src/analysis/db/misc/rlestr.h index be76f17..82a7d8c 100644 --- a/src/analysis/db/misc/rlestr.h +++ b/src/analysis/db/misc/rlestr.h @@ -38,18 +38,28 @@ /* Informations de base pour tout élément ajouté */ typedef struct _rle_string { - char *data; /* Chaîne de caractères */ - uint32_t length; /* Taille de la chaîne */ + union + { + char *data; /* Chaîne de caractères */ + const char *cst_data; /* Autre version de chaîne */ + }; + + uint16_t length; /* Taille de la chaîne */ + bool dynamic; /* Type d'allocation utilisée */ } rle_string; /* Définit une représentation de chaîne de caractères. */ -void init_rle_string(rle_string *, const char *); +void init_dynamic_rle_string(rle_string *, char *); + +/* Définit une représentation de chaîne de caractères constante. */ +void init_static_rle_string(rle_string *, const char *); -#define exit_rle_string(rle) /* TODO */ +/* Copie une chaîne de caractères existante. */ +void dup_into_rle_string(rle_string *, const char *); -#define dup_rle_string(dst, src) init_rle_string(dst, (src)->data); +#define exit_rle_string(rle) unset_rle_string(rle) #define get_rle_string(rle) (rle)->data @@ -58,7 +68,10 @@ void init_rle_string(rle_string *, const char *); #define is_rle_string_empty(rle) ((rle)->data == NULL) /* Constitue une représentation de chaîne de caractères. */ -void set_rle_string(rle_string *, const char *); +void set_dynamic_rle_string(rle_string *, char *); + +/* Constitue une représentation de chaîne de caractères stable. */ +void set_static_rle_string(rle_string *, const char *); /* Libère la mémoire associée à la représentation. */ void unset_rle_string(rle_string *); diff --git a/src/analysis/db/server.c b/src/analysis/db/server.c index 748af4e..0270201 100644 --- a/src/analysis/db/server.c +++ b/src/analysis/db/server.c @@ -394,7 +394,7 @@ static bool g_db_server_register_user(GDbServer *server, const char *author, cha server->users = (registered_user *)realloc(server->users, ++server->users_count * sizeof(registered_user)); - init_rle_string(&server->users[server->users_count - 1].author, author); + dup_into_rle_string(&server->users[server->users_count - 1].author, author); /* FIXME : src ? */ server->users[server->users_count - 1].key_file = kfile; return true; |