From dbd86cf5fc03d57cb9224d8c230b5d7ed5c0af21 Mon Sep 17 00:00:00 2001 From: grayTerminal-sh Date: Mon, 13 Jul 2026 12:21:18 +0200 Subject: [PATCH] feat(core): add investigation node hierarchy --- .../docs/tickets/closed/TICKET-009.md | 268 ++++++++++++++++++ .../docs/tickets/open/TICKET-009.md | 0 .../include/core/investigation_node.h | 40 +++ labfy-investigation/labfy-investigation | Bin 51408 -> 54160 bytes .../src/core/investigation_node.c | 110 ++++++- .../tests/test_investigation_node | Bin 16792 -> 17496 bytes .../tests/test_investigation_node.c | 151 +++++++++- 7 files changed, 561 insertions(+), 8 deletions(-) create mode 100644 labfy-investigation/docs/tickets/closed/TICKET-009.md delete mode 100644 labfy-investigation/docs/tickets/open/TICKET-009.md diff --git a/labfy-investigation/docs/tickets/closed/TICKET-009.md b/labfy-investigation/docs/tickets/closed/TICKET-009.md new file mode 100644 index 0000000..e187542 --- /dev/null +++ b/labfy-investigation/docs/tickets/closed/TICKET-009.md @@ -0,0 +1,268 @@ +# Ticket #009 + +## Titre + +Ajouter les relations parent/enfants à `InvestigationNode`. + +--- + +## Objectif + +Faire évoluer `InvestigationNode` afin qu'un nœud puisse appartenir à une arborescence. + +Chaque nœud pourra : + +- connaître son parent ; +- posséder plusieurs enfants ; +- exposer ses enfants en lecture seule via une API publique. + +--- + +## Responsabilités + +Le module `InvestigationNode` doit : + +- mémoriser un pointeur vers son parent ; +- posséder un tableau dynamique d'enfants ; +- ajouter un enfant ; +- retourner un enfant par son index ; +- retourner le nombre d'enfants ; +- retourner son parent ; +- détruire récursivement les enfants qu'il possède. + +--- + +## Hors périmètre + +Ce ticket ne doit pas : + +- parcourir le système de fichiers ; +- construire automatiquement une arborescence depuis un dossier ; +- afficher quoi que ce soit avec GTK ; +- communiquer avec SQLite ; +- gérer le tri des enfants ; +- gérer la suppression individuelle d'un enfant ; +- gérer le déplacement d'un nœud entre deux parents. + +--- + +## Architecture + +```text +InvestigationTreeModel + │ + ▼ +InvestigationNode + │ + ├── InvestigationNode + ├── InvestigationNode + └── InvestigationNode +``` + +Le module appartient à la couche `core`. + +Il peut dépendre de GLib, mais jamais de GTK. + +--- + +## Gestion de la propriété + +Un nœud devient propriétaire de chaque enfant ajouté avec : + +```c +investigation_node_add_child(parent, child); +``` + +Après un ajout réussi : + +- `parent` possède `child` ; +- le code appelant ne doit plus libérer `child` directement ; +- `child` conserve une référence non propriétaire vers `parent`. + +Lors de la destruction du parent, tous ses enfants sont détruits récursivement. + +--- + +## Structure interne attendue + +```c +struct InvestigationNode +{ + char *name; + InvestigationNodeType type; + InvestigationNode *parent; + GPtrArray *children; +}; +``` + +La structure reste privée dans `investigation_node.c`. + +--- + +## Interface publique attendue + +Les fonctions existantes sont conservées : + +```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 +); +``` + +Les fonctions suivantes sont ajoutées : + +```c +bool investigation_node_add_child( + InvestigationNode *parent, + InvestigationNode *child +); + +const InvestigationNode *investigation_node_get_child( + const InvestigationNode *node, + size_t index +); + +size_t investigation_node_get_children_count( + const InvestigationNode *node +); + +const InvestigationNode *investigation_node_get_parent( + const InvestigationNode *node +); +``` + +--- + +## Comportement attendu + +Exemple : + +```c +InvestigationNode *root = NULL; +InvestigationNode *child = NULL; + +root = investigation_node_new( + "Template", + INVESTIGATION_NODE_DIRECTORY +); + +child = investigation_node_new( + "00_BaseDeDonnees", + INVESTIGATION_NODE_DIRECTORY +); + +if (!investigation_node_add_child(root, child)) +{ + investigation_node_free(child); + investigation_node_free(root); + return; +} +``` + +Après l'ajout : + +```text +Template +└── 00_BaseDeDonnees +``` + +Le nœud `root` devient propriétaire de `child`. + +Le nettoyage correct est uniquement : + +```c +investigation_node_free(root); +``` + +--- + +## Règles d'ajout + +`investigation_node_add_child()` doit refuser : + +- un parent `NULL` ; +- un enfant `NULL` ; +- un parent qui représente un fichier ; +- l'ajout d'un nœud comme enfant de lui-même ; +- un enfant possédant déjà un parent. + +En cas d'échec, la propriété de l'enfant reste au code appelant. + +--- + +## Dépendances + +- C17 ; +- GLib. + +Aucune dépendance GTK ou SQLite. + +--- + +## Contraintes techniques + +- structure opaque ; +- aucun état global ; +- utilisation de `GPtrArray` ; +- tableau créé avec une fonction de destruction ; +- documentation Doxygen ; +- compilation sans warning ; +- respect des conventions de nommage ; +- aucune modification directe du tableau en dehors du module. + +--- + +## Critères d'acceptation + +- [ ] Le projet compile sans warning. +- [ ] Un dossier peut posséder plusieurs enfants. +- [ ] Un fichier ne peut pas recevoir d'enfant. +- [ ] Un enfant connaît son parent. +- [ ] Le nombre d'enfants est correct. +- [ ] Un enfant peut être récupéré par son index. +- [ ] Un index invalide retourne `NULL`. +- [ ] Un enfant ne peut pas avoir deux parents. +- [ ] Un nœud ne peut pas être son propre enfant. +- [ ] La destruction d'un parent détruit récursivement ses enfants. +- [ ] Aucun code GTK. +- [ ] Aucun code SQLite. + +--- + +## Tests + +- créer un parent dossier ; +- ajouter un enfant dossier ; +- ajouter un enfant fichier ; +- vérifier le nombre d'enfants ; +- récupérer chaque enfant ; +- vérifier le parent d'un enfant ; +- tester un index invalide ; +- refuser l'ajout à un fichier ; +- refuser un parent `NULL` ; +- refuser un enfant `NULL` ; +- refuser l'auto-référence ; +- refuser un enfant possédant déjà un parent ; +- détruire un arbre complet ; +- appeler les getters avec `NULL`. + +--- + +## Commit attendu + +```text +feat(core): add investigation node hierarchy +``` diff --git a/labfy-investigation/docs/tickets/open/TICKET-009.md b/labfy-investigation/docs/tickets/open/TICKET-009.md deleted file mode 100644 index e69de29..0000000 diff --git a/labfy-investigation/include/core/investigation_node.h b/labfy-investigation/include/core/investigation_node.h index fc81fbb..794fe34 100644 --- a/labfy-investigation/include/core/investigation_node.h +++ b/labfy-investigation/include/core/investigation_node.h @@ -6,6 +6,10 @@ #ifndef LABFY_INVESTIGATION_INVESTIGATION_NODE_H #define LABFY_INVESTIGATION_INVESTIGATION_NODE_H + +#include +#include + /** * @brief Représentation opaque d'un nœud d'enquête. * @@ -77,4 +81,40 @@ InvestigationNodeType investigation_node_get_type( const InvestigationNode *node ); +/** + * @brief Ajoute un enfant à un dossier. + * + * En cas de succès, le parent devient propriétaire de l'enfant. + * + * @return true si l'ajout a réussi. + */ +bool investigation_node_add_child( + InvestigationNode *parent, + InvestigationNode *child +); + +/** + * @brief Retourne un enfant. + * + * @return L'enfant ou NULL. + */ +const InvestigationNode *investigation_node_get_child( + const InvestigationNode *node, + size_t index +); + +/** + * @brief Retourne le nombre d'enfants. + */ +size_t investigation_node_get_children_count( + const InvestigationNode *node +); + +/** + * @brief Retourne le parent d'un nœud. + */ +const InvestigationNode *investigation_node_get_parent( + const InvestigationNode *node +); + #endif diff --git a/labfy-investigation/labfy-investigation b/labfy-investigation/labfy-investigation index 5bd18480006924ca15d41642c9a323011c6f52e5..521ce432c8617ce06da5a2b955702476a02b9021 100755 GIT binary patch delta 14105 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 diff --git a/labfy-investigation/src/core/investigation_node.c b/labfy-investigation/src/core/investigation_node.c index 5e2806f..79c4412 100644 --- a/labfy-investigation/src/core/investigation_node.c +++ b/labfy-investigation/src/core/investigation_node.c @@ -10,11 +10,16 @@ /** * @struct InvestigationNode * @brief Représentation interne d'un nœud. + * + * Le nœud possède son nom et ses enfants. + * Le pointeur parent est une simple référence non propriétaire. */ struct InvestigationNode { char *name; InvestigationNodeType type; + InvestigationNode *parent; + GPtrArray *children; }; InvestigationNode *investigation_node_new( @@ -29,10 +34,7 @@ InvestigationNode *investigation_node_new( return NULL; } - node = g_new0( - InvestigationNode, - 1 - ); + node = g_new0(InvestigationNode, 1); if (node == NULL) { @@ -47,6 +49,16 @@ InvestigationNode *investigation_node_new( return NULL; } + node->children = g_ptr_array_new_with_free_func( + (GDestroyNotify) investigation_node_free + ); + + if (node->children == NULL) + { + investigation_node_free(node); + return NULL; + } + node->type = type; return node; @@ -61,8 +73,16 @@ void investigation_node_free( return; } - g_free(node->name); + /* + * Le tableau possède les enfants. + * TRUE demande à GLib de libérer aussi le contenu du tableau. + */ + if (node->children != NULL) + { + g_ptr_array_free(node->children, TRUE); + } + g_free(node->name); g_free(node); } @@ -89,3 +109,83 @@ InvestigationNodeType investigation_node_get_type( return node->type; } + +bool investigation_node_add_child( + InvestigationNode *parent, + InvestigationNode *child +) +{ + if (parent == NULL || child == NULL) + { + return false; + } + + if (parent->type != INVESTIGATION_NODE_DIRECTORY) + { + return false; + } + + if (parent == child) + { + return false; + } + + if (child->parent != NULL) + { + return false; + } + + child->parent = parent; + + g_ptr_array_add( + parent->children, + child + ); + + return true; +} + +const InvestigationNode *investigation_node_get_child( + const InvestigationNode *node, + size_t index +) +{ + if (node == NULL || node->children == NULL) + { + return NULL; + } + + if (index >= node->children->len) + { + return NULL; + } + + return g_ptr_array_index( + node->children, + index + ); +} + +size_t investigation_node_get_children_count( + const InvestigationNode *node +) +{ + if (node == NULL || node->children == NULL) + { + return 0; + } + + return node->children->len; +} + +const InvestigationNode *investigation_node_get_parent( + const InvestigationNode *node +) +{ + if (node == NULL) + { + return NULL; + } + + return node->parent; +} diff --git a/labfy-investigation/tests/test_investigation_node b/labfy-investigation/tests/test_investigation_node index 440ea25c8c6f68b49c4fe6f97f7daa62b6f2ac4e..fc3622417445c8d2310145009b444d4060c96060 100755 GIT binary patch literal 17496 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 delta 3331 zcmZu!4Qx}_6~6by#*UXC+ri`q=g;{80zAjikpK9Fl=T%VHD#?tS(}hHp@anjjkBgL z%%LeX22zazli1R=B}J5uLe^>0h&By6Wr&Sca|^Ty+q5(Zdpq~%#ZI~_ z`JH>u`ObIGx%a$#pRWwkpAOJymivU0@TLhtu2df@d(&~sCWfbM$NsE34qC0c2C=L?_JNc+z&rXdXPQ`)Z&MzC5v`rFO!D& z^ELK_bCz=Y7)+wQ%9=%w!vofkYx|QO9ps5tCR%$spXq3aC5sM)lW6!IZTxpt&C zr!$$5ByvIO-aYo?MFcTpB0zGkUUcko9CeA#Zx-k^sn@jmcyoL%NTA48O>OX~Ei?N& zl8uRLK{3E-NeT?vo&v8uC3U$bv}`w%A=h3seAFJYLDW9}lJf*yaxQIFF&)D*qZ0D3 z?P_}d^Bk`a)$jEaq7PYjGEqGh^5{pbR}rKiJQqqfuBGSqGvIkC5#Px16*W-n^3tEf z7FS-`9mJE~wGZh7^@mwkk9;0V)sNIO9>ddz&)DOJVO+HS5l*=3!rRgaIm=k}$Y`tu zYf6u7n9>LKPm$gdeaLeF*IFN{*o-KQ>jz9k#zs66|M-6mLqCFe^wlsWJ@RWrrE=6o zJ#sm=837nOW2zKPcEJ>oOyMPxDm#J7gH+N>5ng{t<@4Vsy>g_}-|xidZ^YQ6pPqjR z^VJ7#I`z>FQ;1?wZ$YoKRJ!cLPC|-djO_h%2CLX3=7=zXIj)or2NLEG>%(%i@<@1& zdk`R_-6fbx1=D{d(<;eSnZUFbqaB!{p)g+>;Wm-N!%db+mP^WGIc&{V8;hKFZfv z%=~*aNJZ>5j5F4c+Zb!X`ifn~2To<-6r-_K==uSoiEzg)D$pbQV{mJ!x7NlDH@eQ^ zW|NQDPQ{k6KqDI_uo5RouLNwuT8r_`lQrj@g^k_m>&y`m`G zh?D+}nHtlahm@w&Mao}NYLJOc%%~!?=99A3X+wiHH@3PCQUJ9baH)@b(LA5_$nYF@J|5d!& zMAP8m@>WGFfsu06b&2n;X(FT${#u?1&VW7JjL5WY#117n$Q%gxX%yN5_k>@THyy77 zwEu}?(nzyUc(Fxd?I!*dl0u$!^C97Nf!!JWQIbY>NIV`kyty!KhHuFbV_qlNEoR$- z_IE|C+DTcDOrL+wmSesd~6P1Ld6Z31u zgzx9zED{Tv8X*DoZYWI3$UVh+80}J-E-yL+jiSDQBQynjB%4%e^Es}Y9M&(*USI}$ zPQ>a9unKaxl~mHlYAB)E!F5+=z{ji@L$$Q>!bMaA>KWU@nKv;nE4zSrgyCJ-b1B(G z(-Nq$`wY|Lievb^S%e@F)U)|c%bfeA{v_(1SS8JxR7i2R#GjD$#?KbCy(#cz-%9tF z(&3ieQU0c*!}~07dY(Tov1jgQh-9HJT(Hkk&y%wn*z>WCSdoLrty^)#zxiZ%1x%0W zY%!M)K3g{lyQ*w3R+&cwu)Auxvz&xFdP1$cd%L>$*Cc#gH3^rhOJHM72mG$a2gj{B zkX>6p+*8|5;Y!^#S_P-;{q6#*n8cL$-cHx6u34!zWe!v~_>;5PrysT~*xOKsDV_q7g!HWq3O+l)|-lm{uN4d~B<+|kJFb6I)t#tHN2uocOOgF7_yjvxP Kc@%2u^Zo~7+y}w{ diff --git a/labfy-investigation/tests/test_investigation_node.c b/labfy-investigation/tests/test_investigation_node.c index f99a828..07a3557 100644 --- a/labfy-investigation/tests/test_investigation_node.c +++ b/labfy-investigation/tests/test_investigation_node.c @@ -27,6 +27,8 @@ static void test_directory_node(void) investigation_node_get_type(node) == INVESTIGATION_NODE_DIRECTORY ); + assert(investigation_node_get_parent(node) == NULL); + assert(investigation_node_get_children_count(node) == 0); investigation_node_free(node); } @@ -53,6 +55,140 @@ static void test_file_node(void) investigation_node_free(node); } +static void test_add_children(void) +{ + InvestigationNode *root = NULL; + InvestigationNode *database_directory = NULL; + InvestigationNode *database_file = NULL; + const InvestigationNode *returned_child = NULL; + + root = investigation_node_new( + "Template", + INVESTIGATION_NODE_DIRECTORY + ); + + database_directory = investigation_node_new( + "00_BaseDeDonnees", + INVESTIGATION_NODE_DIRECTORY + ); + + database_file = investigation_node_new( + "Enquete.sqlite", + INVESTIGATION_NODE_FILE + ); + + assert(root != NULL); + assert(database_directory != NULL); + assert(database_file != NULL); + + assert( + investigation_node_add_child( + root, + database_directory + ) + ); + + assert( + investigation_node_add_child( + database_directory, + database_file + ) + ); + + assert(investigation_node_get_children_count(root) == 1); + assert( + investigation_node_get_children_count( + database_directory + ) == 1 + ); + + returned_child = investigation_node_get_child(root, 0); + + assert(returned_child == database_directory); + assert( + investigation_node_get_parent(database_directory) == + root + ); + assert( + investigation_node_get_parent(database_file) == + database_directory + ); + + /* + * root possède database_directory, + * qui possède database_file. + * La destruction est donc récursive. + */ + investigation_node_free(root); +} + +static void test_invalid_additions(void) +{ + InvestigationNode *directory = NULL; + InvestigationNode *file = NULL; + InvestigationNode *child = NULL; + InvestigationNode *second_parent = NULL; + + directory = investigation_node_new( + "Directory", + INVESTIGATION_NODE_DIRECTORY + ); + + file = investigation_node_new( + "File.txt", + INVESTIGATION_NODE_FILE + ); + + child = investigation_node_new( + "Child", + INVESTIGATION_NODE_DIRECTORY + ); + + second_parent = investigation_node_new( + "SecondParent", + INVESTIGATION_NODE_DIRECTORY + ); + + assert(directory != NULL); + assert(file != NULL); + assert(child != NULL); + assert(second_parent != NULL); + + assert(!investigation_node_add_child(NULL, child)); + assert(!investigation_node_add_child(directory, NULL)); + assert(!investigation_node_add_child(file, child)); + assert(!investigation_node_add_child(directory, directory)); + + assert(investigation_node_add_child(directory, child)); + + assert(!investigation_node_add_child(second_parent, child)); + + /* + * directory possède désormais child. + */ + investigation_node_free(directory); + investigation_node_free(file); + investigation_node_free(second_parent); +} + +static void test_invalid_index(void) +{ + InvestigationNode *node = NULL; + + node = investigation_node_new( + "Template", + INVESTIGATION_NODE_DIRECTORY + ); + + assert(node != NULL); + + assert(investigation_node_get_child(node, 0) == NULL); + assert(investigation_node_get_child(node, 42) == NULL); + assert(investigation_node_get_child(NULL, 0) == NULL); + + investigation_node_free(node); +} + static void test_invalid_names(void) { assert( @@ -70,8 +206,12 @@ static void test_invalid_names(void) ); } -static void test_null_free(void) +static void test_null_behaviour(void) { + assert(investigation_node_get_name(NULL) == NULL); + assert(investigation_node_get_children_count(NULL) == 0); + assert(investigation_node_get_parent(NULL) == NULL); + investigation_node_free(NULL); } @@ -79,10 +219,15 @@ int main(void) { test_directory_node(); test_file_node(); + test_add_children(); + test_invalid_additions(); + test_invalid_index(); test_invalid_names(); - test_null_free(); + test_null_behaviour(); - printf("InvestigationNode : tous les tests sont valides.\n"); + printf( + "InvestigationNode : tous les tests de hiérarchie sont valides.\n" + ); return 0; }