summaryrefslogtreecommitdiff
path: root/src/analysis/db
diff options
context:
space:
mode:
Diffstat (limited to 'src/analysis/db')
-rw-r--r--src/analysis/db/cdb.c4
-rw-r--r--src/analysis/db/client.c4
-rw-r--r--src/analysis/db/item.c2
-rw-r--r--src/analysis/db/items/bookmark.c2
-rw-r--r--src/analysis/db/items/comment.c300
-rw-r--r--src/analysis/db/items/comment.h10
-rw-r--r--src/analysis/db/misc/rlestr.c107
-rw-r--r--src/analysis/db/misc/rlestr.h25
-rw-r--r--src/analysis/db/server.c2
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;