From 106e06d33196ca124d6d27cc00a5898d6f96121d Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Tue, 1 Dec 2015 22:07:32 +0100 Subject: Handled relative paths when loading and saving binary contents in projects. --- ChangeLog | 13 +++++++++++++ src/analysis/content-int.h | 2 +- src/analysis/content.c | 10 ++++++---- src/analysis/content.h | 4 ++-- src/analysis/contents/file.c | 26 +++++++++++++++++++------- src/analysis/contents/file.h | 2 +- src/analysis/project.c | 17 +++++++++++++---- src/common/xml.h | 1 - 8 files changed, 55 insertions(+), 20 deletions(-) diff --git a/ChangeLog b/ChangeLog index a06eeaf..1723878 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,18 @@ 15-12-01 Cyrille Bagard + * src/analysis/content-int.h: + * src/analysis/content.c: + * src/analysis/content.h: + * src/analysis/contents/file.c: + * src/analysis/contents/file.h: + * src/analysis/project.c: + Handle relative paths when loading and saving binary contents in projects. + + * src/common/xml.h: + Typo. + +15-12-01 Cyrille Bagard + * plugins/pychrysa/common/Makefile.am: Add the 'pathname.[ch]' files to libpychrysacommon_la_SOURCES. diff --git a/src/analysis/content-int.h b/src/analysis/content-int.h index 36168be..d9f9ef9 100644 --- a/src/analysis/content-int.h +++ b/src/analysis/content-int.h @@ -33,7 +33,7 @@ typedef const char * (* describe_content_fc) (const GBinContent *, bool); /* Ecrit une sauvegarde de contenu binaire dans un fichier XML. */ -typedef bool (* save_content_fc) (const GBinContent *, xmlDocPtr, xmlXPathContextPtr, const char *); +typedef bool (* save_content_fc) (const GBinContent *, xmlDocPtr, xmlXPathContextPtr, const char *, const char *); /* Fournit une empreinte unique (SHA256) pour les données. */ typedef const gchar * (* get_checksum_fc) (GBinContent *); diff --git a/src/analysis/content.c b/src/analysis/content.c index d86a351..01c9c99 100644 --- a/src/analysis/content.c +++ b/src/analysis/content.c @@ -63,6 +63,7 @@ static void g_binary_content_default_init(GBinContentInterface *iface) * * * Paramètres : context = contexte pour les recherches XPath. * * path = chemin d'accès au noeud XML à lire. * +* base = référence au lieu d'enregistrement du projet. * * * * Description : Charge en mémoire un contenu binaire à partir d'XML. * * * @@ -72,7 +73,7 @@ static void g_binary_content_default_init(GBinContentInterface *iface) * * ******************************************************************************/ -GBinContent *g_binary_content_new_from_xml(xmlXPathContextPtr context, const char *path) +GBinContent *g_binary_content_new_from_xml(xmlXPathContextPtr context, const char *path, const char *base) { GBinContent *result; /* Contenu en place à renvoyer */ char *type; /* Type de binaire à charger */ @@ -82,7 +83,7 @@ GBinContent *g_binary_content_new_from_xml(xmlXPathContextPtr context, const cha type = get_node_prop_value(context, path, "type"); if (strcmp(type, "file") == 0) - result = g_file_content_new_from_xml(context, path); + result = g_file_content_new_from_xml(context, path, base); free(type); @@ -121,6 +122,7 @@ const char *g_binary_content_describe(const GBinContent *content, bool full) * xdoc = structure XML en cours d'édition. * * context = contexte à utiliser pour les recherches. * * path = chemin d'accès réservé au binaire. * +* base = référence au lieu d'enregistrement du projet. * * * * Description : Ecrit une sauvegarde de contenu binaire dans un fichier XML. * * * @@ -130,13 +132,13 @@ const char *g_binary_content_describe(const GBinContent *content, bool full) * * ******************************************************************************/ -bool g_binary_content_save(const GBinContent *content, xmlDocPtr xdoc, xmlXPathContextPtr context, const char *path) +bool g_binary_content_save(const GBinContent *content, xmlDocPtr xdoc, xmlXPathContextPtr context, const char *path, const char *base) { GBinContentIface *iface; /* Interface utilisée */ iface = G_BIN_CONTENT_GET_IFACE(content); - return iface->save(content, xdoc, context, path); + return iface->save(content, xdoc, context, path, base); } diff --git a/src/analysis/content.h b/src/analysis/content.h index 591097d..1a61cb7 100644 --- a/src/analysis/content.h +++ b/src/analysis/content.h @@ -55,13 +55,13 @@ typedef struct _GBinContentIface GBinContentIface; GType g_binary_content_get_type(void) G_GNUC_CONST; /* Charge en mémoire un contenu binaire à partir d'XML. */ -GBinContent *g_binary_content_new_from_xml(xmlXPathContextPtr, const char *); +GBinContent *g_binary_content_new_from_xml(xmlXPathContextPtr, const char *, const char *); /* Fournit le nom associé au contenu binaire. */ const char *g_binary_content_describe(const GBinContent *, bool); /* Ecrit une sauvegarde de contenu binaire dans un fichier XML. */ -bool g_binary_content_save(const GBinContent *, xmlDocPtr, xmlXPathContextPtr, const char *); +bool g_binary_content_save(const GBinContent *, xmlDocPtr, xmlXPathContextPtr, const char *, const char *); /* Fournit une empreinte unique (SHA256) pour les données. */ const gchar *g_binary_content_get_cheksum(GBinContent *); diff --git a/src/analysis/contents/file.c b/src/analysis/contents/file.c index f24e930..8416348 100644 --- a/src/analysis/contents/file.c +++ b/src/analysis/contents/file.c @@ -35,6 +35,7 @@ #include "../content-int.h" #include "../../common/extstr.h" +#include "../../common/pathname.h" @@ -80,7 +81,7 @@ static void g_file_content_finalize(GFileContent *); static const char *g_file_content_describe(const GFileContent *, bool); /* Ecrit une sauvegarde de contenu binaire dans un fichier XML. */ -static bool g_file_content_save(const GFileContent *, xmlDocPtr, xmlXPathContextPtr, const char *); +static bool g_file_content_save(const GFileContent *, xmlDocPtr, xmlXPathContextPtr, const char *, const char *); /* Fournit une empreinte unique (SHA256) pour les données. */ static const gchar *g_file_content_get_checksum(GFileContent *); @@ -324,6 +325,7 @@ GBinContent *g_file_content_new(const char *filename) * * * Paramètres : context = contexte pour les recherches XPath. * * path = chemin d'accès au noeud XML à lire. * +* base = référence au lieu d'enregistrement du projet. * * * * Description : Charge en mémoire le contenu d'un fichier à partir d'XML. * * * @@ -333,11 +335,12 @@ GBinContent *g_file_content_new(const char *filename) * * ******************************************************************************/ -GBinContent *g_file_content_new_from_xml(xmlXPathContextPtr context, const char *path) +GBinContent *g_file_content_new_from_xml(xmlXPathContextPtr context, const char *path, const char *base) { GBinContent *result; /* Adresse à retourner */ char *access; /* Chemin pour une sous-config.*/ char *filename; /* Chemin du binaire à charger */ + char *absolute; /* Chemin absolu final */ result = NULL; @@ -352,10 +355,14 @@ GBinContent *g_file_content_new_from_xml(xmlXPathContextPtr context, const char /* Chargement */ - if (filename != NULL) + absolute = build_absolute_filename(base, filename); + + if (filename != NULL) free(filename); + + if (absolute != NULL) { - result = g_file_content_new(filename); - free(filename); + result = g_file_content_new(absolute); + free(absolute); } return result; @@ -396,6 +403,7 @@ static const char *g_file_content_describe(const GFileContent *content, bool ful * xdoc = structure XML en cours d'édition. * * context = contexte à utiliser pour les recherches. * * path = chemin d'accès réservé au binaire. * +* base = référence au lieu d'enregistrement du projet. * * * * Description : Ecrit une sauvegarde de contenu binaire dans un fichier XML. * * * @@ -405,10 +413,11 @@ static const char *g_file_content_describe(const GFileContent *content, bool ful * * ******************************************************************************/ -static bool g_file_content_save(const GFileContent *content, xmlDocPtr xdoc, xmlXPathContextPtr context, const char *path) +static bool g_file_content_save(const GFileContent *content, xmlDocPtr xdoc, xmlXPathContextPtr context, const char *path, const char *base) { bool result; /* Bilan à faire remonter */ char *access; /* Chemin d'accès à un élément */ + char *relative; /* Chemin d'accès relatif */ result = true; @@ -421,8 +430,11 @@ static bool g_file_content_save(const GFileContent *content, xmlDocPtr xdoc, xml access = strdup(path); access = stradd(access, "/Filename"); - result &= add_content_to_node(xdoc, context, access, content->filename); + relative = build_relative_filename(base, content->filename); + + result &= add_content_to_node(xdoc, context, access, relative); + free(relative); free(access); return result; diff --git a/src/analysis/contents/file.h b/src/analysis/contents/file.h index 0985f6b..90e292e 100644 --- a/src/analysis/contents/file.h +++ b/src/analysis/contents/file.h @@ -54,7 +54,7 @@ GType g_file_content_get_type(void); GBinContent *g_file_content_new(const char *); /* Charge en mémoire le contenu d'un fichier à partir d'XML. */ -GBinContent *g_file_content_new_from_xml(xmlXPathContextPtr, const char *); +GBinContent *g_file_content_new_from_xml(xmlXPathContextPtr, const char *, const char *); diff --git a/src/analysis/project.c b/src/analysis/project.c index ed60929..94b01a3 100644 --- a/src/analysis/project.c +++ b/src/analysis/project.c @@ -282,14 +282,20 @@ GStudyProject *g_study_project_open(GObject *ref, const char *filename) access = calloc(access_len, sizeof(char)); snprintf(access, access_len, "/ChrysalideProject/Contents/Content[position()=%u]", i + 1); - content = g_binary_content_new_from_xml(context, access); + content = g_binary_content_new_from_xml(context, access, filename); status = get_node_prop_long_value(context, access, "state", &state); free(access); + if (content == NULL) + { + log_variadic_message(LMT_ERROR, _("Unable to load the binary content #%u ; skipping..."), i); + continue; + } + if (!status) { - log_variadic_message(LMT_PROCESS, _("bad state for content '%s' ; skipping..."), + log_variadic_message(LMT_ERROR, _("Bad state for content '%s' ; skipping..."), g_binary_content_describe(content, true)); continue; } @@ -375,6 +381,7 @@ bool g_study_project_save(GStudyProject *project, const char *filename) bool result; /* Bilan à retourner */ xmlDocPtr xdoc; /* Document XML à créer */ xmlXPathContextPtr context; /* Contexte pour les recherches*/ + const char *final; /* Lieu d'enregistrement final */ size_t i; /* Boucle de parcours */ size_t access_len; /* Taille d'un chemin interne */ char *access; /* Chemin pour une sous-config.*/ @@ -383,6 +390,8 @@ bool g_study_project_save(GStudyProject *project, const char *filename) result &= (ensure_node_exist(xdoc, context, "/ChrysalideProject") != NULL); + final = filename != NULL ? filename : project->filename; + /* Enregistrement des contenus binaires attachés */ for (i = 0; i < project->contents_count && result; i++) @@ -394,7 +403,7 @@ bool g_study_project_save(GStudyProject *project, const char *filename) access = calloc(access_len, sizeof(char)); snprintf(access, access_len, "/ChrysalideProject/Contents/Content[position()=%zu]", i + 1); - result = g_binary_content_save(project->contents[i].content, xdoc, context, access); + result = g_binary_content_save(project->contents[i].content, xdoc, context, access, final); if (result) result = add_long_attribute_to_node(xdoc, context, access, "state", project->contents[i].state); @@ -420,7 +429,7 @@ bool g_study_project_save(GStudyProject *project, const char *filename) /* Sauvegarde finale */ - result &= save_xml_file(xdoc, filename != NULL ? filename : project->filename); + result &= save_xml_file(xdoc, final); if (result && filename != NULL) { diff --git a/src/common/xml.h b/src/common/xml.h index 60891f7..674bfd4 100644 --- a/src/common/xml.h +++ b/src/common/xml.h @@ -34,7 +34,6 @@ - /* Crée un nouveau fichier XML. */ bool create_new_xml_file(xmlDocPtr *, xmlXPathContextPtr *); -- cgit v0.11.2-87-g4458