From 1686194c1a1a053794419ec1cb3b237acf2c871a Mon Sep 17 00:00:00 2001 From: grayTerminal-sh Date: Mon, 13 Jul 2026 00:38:11 +0200 Subject: [PATCH] feat(core): create investigation node --- docs/tickets/closed/TICKET-007.md | 184 ++++++++++++++++++ .../include/core/investigation_node.h | 80 ++++++++ labfy-investigation/labfy-investigation | Bin 49320 -> 51408 bytes .../src/core/investigation_node.c | 91 +++++++++ .../tests/test_investigation_node | Bin 0 -> 16792 bytes .../tests/test_investigation_node.c | 88 +++++++++ 6 files changed, 443 insertions(+) create mode 100644 docs/tickets/closed/TICKET-007.md create mode 100644 labfy-investigation/include/core/investigation_node.h create mode 100644 labfy-investigation/src/core/investigation_node.c create mode 100755 labfy-investigation/tests/test_investigation_node create mode 100644 labfy-investigation/tests/test_investigation_node.c diff --git a/docs/tickets/closed/TICKET-007.md b/docs/tickets/closed/TICKET-007.md new file mode 100644 index 0000000..f17f0b8 --- /dev/null +++ b/docs/tickets/closed/TICKET-007.md @@ -0,0 +1,184 @@ +# Ticket #007 + +## Titre + +Créer le module `InvestigationNode`. + +--- + +## Objectif + +Créer une structure métier représentant un élément de l'arborescence d'une enquête. + +Un nœud peut représenter : + +- un dossier ; +- un fichier. + +Ce module servira de base au futur modèle d'arborescence. + +--- + +## Responsabilités + +Le module `InvestigationNode` doit : + +- mémoriser le nom d'un élément ; +- mémoriser son type ; +- gérer sa propre mémoire ; +- exposer ses informations en lecture seule. + +--- + +## Hors périmètre + +Ce ticket ne doit pas : + +- parcourir le système de fichiers ; +- construire une arborescence complète ; +- stocker des enfants ; +- afficher quoi que ce soit avec GTK ; +- communiquer avec SQLite ; +- ouvrir une enquête. + +--- + +## Architecture + +```text +InvestigationTreeModel + │ + └── InvestigationNode +``` + +Le module appartient à la couche `core`. + +Il ne doit contenir aucune dépendance vers GTK. + +--- + +## Fichiers concernés + +```text +include/core/investigation_node.h +src/core/investigation_node.c +``` + +--- + +## Type attendu + +```c +typedef enum +{ + INVESTIGATION_NODE_DIRECTORY, + INVESTIGATION_NODE_FILE +} InvestigationNodeType; +``` + +--- + +## Interface publique attendue + +```c +InvestigationNode *investigation_node_new( + const char *name, + InvestigationNodeType type +); + +void investigation_node_free( + InvestigationNode *node +); + +const char *investigation_node_get_name( + const InvestigationNode *node +); + +InvestigationNodeType investigation_node_get_type( + const InvestigationNode *node +); +``` + +--- + +## Comportement attendu + +Exemple d'utilisation : + +```c +InvestigationNode *node = NULL; + +node = investigation_node_new( + "01_Preuves_Originales", + INVESTIGATION_NODE_DIRECTORY +); + +if (node == NULL) +{ + /* Gestion de l'erreur */ +} + +const char *name = investigation_node_get_name(node); +InvestigationNodeType type = investigation_node_get_type(node); + +investigation_node_free(node); +``` + +--- + +## Cas à gérer + +- nom valide ; +- nom vide ; +- pointeur `NULL` ; +- type dossier ; +- type fichier ; +- libération avec `NULL`. + +--- + +## Contraintes techniques + +- C17 ; +- structure opaque ; +- aucun état global ; +- aucune dépendance GTK ; +- documentation Doxygen ; +- compilation sans warning ; +- noms conformes à `DEVELOPMENT.md`. + +--- + +## Critères d'acceptation + +- [ ] Le projet compile sans warning. +- [ ] La structure `InvestigationNode` est opaque. +- [ ] Un nœud peut représenter un fichier. +- [ ] Un nœud peut représenter un dossier. +- [ ] Le nom est copié et possédé par le nœud. +- [ ] Les getters retournent des données en lecture seule. +- [ ] `investigation_node_free(NULL)` est accepté. +- [ ] Aucun code GTK. +- [ ] Aucun code SQLite. +- [ ] Les fonctions publiques sont documentées avec Doxygen. + +--- + +## Tests + +- créer un nœud dossier ; +- créer un nœud fichier ; +- lire le nom ; +- lire le type ; +- tester un nom vide ; +- tester un nom `NULL` ; +- libérer un nœud valide ; +- appeler `investigation_node_free(NULL)`. + +--- + +## Commit attendu + +```text +feat(core): create investigation node +``` diff --git a/labfy-investigation/include/core/investigation_node.h b/labfy-investigation/include/core/investigation_node.h new file mode 100644 index 0000000..fc81fbb --- /dev/null +++ b/labfy-investigation/include/core/investigation_node.h @@ -0,0 +1,80 @@ +/****************************************************************************** + * @file investigation_node.h + * @brief Interface publique d'un nœud de l'arborescence d'une enquête. + ******************************************************************************/ + +#ifndef LABFY_INVESTIGATION_INVESTIGATION_NODE_H +#define LABFY_INVESTIGATION_INVESTIGATION_NODE_H + +/** + * @brief Représentation opaque d'un nœud d'enquête. + * + * La structure réelle est définie dans investigation_node.c. + * Les autres modules manipulent uniquement un pointeur vers + * InvestigationNode. + */ +typedef struct InvestigationNode InvestigationNode; + +/** + * @brief Type d'un nœud de l'arborescence. + */ +typedef enum +{ + INVESTIGATION_NODE_DIRECTORY, + INVESTIGATION_NODE_FILE +} InvestigationNodeType; + +/** + * @brief Crée un nouveau nœud d'enquête. + * + * Le nom fourni est copié. Le code appelant peut donc modifier ou libérer + * sa chaîne après l'appel sans affecter le nœud. + * + * @param name Nom du fichier ou du dossier. + * @param type Type du nœud. + * + * @return Un nouveau nœud, ou NULL si le nom est invalide ou si la création + * échoue. + */ +InvestigationNode *investigation_node_new( + const char *name, + InvestigationNodeType type +); + +/** + * @brief Libère les ressources associées à un nœud. + * + * Cette fonction accepte NULL. + * + * @param node Nœud à libérer. + */ +void investigation_node_free( + InvestigationNode *node +); + +/** + * @brief Retourne le nom du nœud. + * + * La chaîne retournée appartient au nœud et ne doit pas être modifiée + * ni libérée par le code appelant. + * + * @param node Nœud à consulter. + * + * @return Le nom en lecture seule, ou NULL si node vaut NULL. + */ +const char *investigation_node_get_name( + const InvestigationNode *node +); + +/** + * @brief Retourne le type du nœud. + * + * @param node Nœud à consulter. + * + * @return Le type du nœud. + */ +InvestigationNodeType investigation_node_get_type( + const InvestigationNode *node +); + +#endif diff --git a/labfy-investigation/labfy-investigation b/labfy-investigation/labfy-investigation index 962e4431c0bc78fe91d99f97a03a3af7bcb39b45..5bd18480006924ca15d41642c9a323011c6f52e5 100755 GIT binary patch delta 11242 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 GN&G*OgdD5@ delta 9161 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 b6}$6ok8F?(rHN+j?r%Hynl_q_NK*d;7^X=U diff --git a/labfy-investigation/src/core/investigation_node.c b/labfy-investigation/src/core/investigation_node.c new file mode 100644 index 0000000..5e2806f --- /dev/null +++ b/labfy-investigation/src/core/investigation_node.c @@ -0,0 +1,91 @@ +/****************************************************************************** + * @file investigation_node.c + * @brief Implémentation d'un nœud d'enquête. + ******************************************************************************/ + +#include "core/investigation_node.h" + +#include + +/** + * @struct InvestigationNode + * @brief Représentation interne d'un nœud. + */ +struct InvestigationNode +{ + char *name; + InvestigationNodeType type; +}; + +InvestigationNode *investigation_node_new( + const char *name, + InvestigationNodeType type +) +{ + InvestigationNode *node = NULL; + + if (name == NULL || name[0] == '\0') + { + return NULL; + } + + node = g_new0( + InvestigationNode, + 1 + ); + + if (node == NULL) + { + return NULL; + } + + node->name = g_strdup(name); + + if (node->name == NULL) + { + investigation_node_free(node); + return NULL; + } + + node->type = type; + + return node; +} + +void investigation_node_free( + InvestigationNode *node +) +{ + if (node == NULL) + { + return; + } + + g_free(node->name); + + g_free(node); +} + +const char *investigation_node_get_name( + const InvestigationNode *node +) +{ + if (node == NULL) + { + return NULL; + } + + return node->name; +} + +InvestigationNodeType investigation_node_get_type( + const InvestigationNode *node +) +{ + if (node == NULL) + { + return INVESTIGATION_NODE_FILE; + } + + return node->type; +} diff --git a/labfy-investigation/tests/test_investigation_node b/labfy-investigation/tests/test_investigation_node new file mode 100755 index 0000000000000000000000000000000000000000..440ea25c8c6f68b49c4fe6f97f7daa62b6f2ac4e GIT binary patch literal 16792 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 +#include +#include + +static void test_directory_node(void) +{ + InvestigationNode *node = NULL; + + node = investigation_node_new( + "01_Preuves_Originales", + INVESTIGATION_NODE_DIRECTORY + ); + + assert(node != NULL); + assert(strcmp( + investigation_node_get_name(node), + "01_Preuves_Originales" + ) == 0); + assert( + investigation_node_get_type(node) == + INVESTIGATION_NODE_DIRECTORY + ); + + investigation_node_free(node); +} + +static void test_file_node(void) +{ + InvestigationNode *node = NULL; + + node = investigation_node_new( + "Chronologie.md", + INVESTIGATION_NODE_FILE + ); + + assert(node != NULL); + assert(strcmp( + investigation_node_get_name(node), + "Chronologie.md" + ) == 0); + assert( + investigation_node_get_type(node) == + INVESTIGATION_NODE_FILE + ); + + investigation_node_free(node); +} + +static void test_invalid_names(void) +{ + assert( + investigation_node_new( + NULL, + INVESTIGATION_NODE_FILE + ) == NULL + ); + + assert( + investigation_node_new( + "", + INVESTIGATION_NODE_FILE + ) == NULL + ); +} + +static void test_null_free(void) +{ + investigation_node_free(NULL); +} + +int main(void) +{ + test_directory_node(); + test_file_node(); + test_invalid_names(); + test_null_free(); + + printf("InvestigationNode : tous les tests sont valides.\n"); + + return 0; +}