diff options
Diffstat (limited to 'plugins/yaml/node.c')
-rw-r--r-- | plugins/yaml/node.c | 192 |
1 files changed, 124 insertions, 68 deletions
diff --git a/plugins/yaml/node.c b/plugins/yaml/node.c index b0229c0..57eb3d2 100644 --- a/plugins/yaml/node.c +++ b/plugins/yaml/node.c @@ -28,6 +28,9 @@ #include <string.h> +#include "collection.h" + + /* Noeud d'une arborescence au format Yaml (instance) */ struct _GYamlNode @@ -35,9 +38,7 @@ struct _GYamlNode GObject parent; /* A laisser en premier */ GYamlLine *key; /* Clef principale du noeud */ - - GYamlNode **children; /* Sous-noeuds intégrés */ - size_t count; /* Nombre de ces enfants */ + GYamlCollection *collection; /* Collection de noeuds */ }; @@ -106,9 +107,7 @@ static void g_yaml_node_class_init(GYamlNodeClass *klass) static void g_yaml_node_init(GYamlNode *node) { node->key = NULL; - - node->children = NULL; - node->count = 0; + node->collection = NULL; } @@ -127,12 +126,9 @@ static void g_yaml_node_init(GYamlNode *node) static void g_yaml_node_dispose(GYamlNode *node) { - size_t i; /* Boucle de parcours */ - g_clear_object(&node->key); - for (i = 0; i < node->count; i++) - g_clear_object(&node->children[i]); + g_clear_object(&node->collection); G_OBJECT_CLASS(g_yaml_node_parent_class)->dispose(G_OBJECT(node)); @@ -153,9 +149,6 @@ static void g_yaml_node_dispose(GYamlNode *node) static void g_yaml_node_finalize(GYamlNode *node) { - if (node->children != NULL) - free(node->children); - G_OBJECT_CLASS(g_yaml_node_parent_class)->finalize(G_OBJECT(node)); } @@ -179,8 +172,18 @@ GYamlNode *g_yaml_node_new(GYamlLine *key) result = g_object_new(G_TYPE_YAML_NODE, NULL); - result->key = key; - g_object_ref(G_OBJECT(key)); + /** + * Le paragraphe "3.2.2.1. Keys Order" des spécifications précise + * qu'une séquence n'est qu'un noeud sans correspondance clef/valeur. + * + * Cette situation doit donc être prise en compte. + */ + + if (key != NULL) + { + result->key = key; + g_object_ref(G_OBJECT(key)); + } return result; @@ -189,7 +192,7 @@ GYamlNode *g_yaml_node_new(GYamlLine *key) /****************************************************************************** * * -* Paramètres : node = noeud d'arborescence Yaml à consulter. * +* Paramètres : node = noeud d'arborescence Yaml à consulter. * * * * Description : Fournit la ligne principale associée à un noeud. * * * @@ -205,7 +208,8 @@ GYamlLine *g_yaml_node_get_yaml_line(const GYamlNode *node) result = node->key; - g_object_ref(G_OBJECT(result)); + if (result != NULL) + g_object_ref(G_OBJECT(result)); return result; @@ -214,10 +218,10 @@ GYamlLine *g_yaml_node_get_yaml_line(const GYamlNode *node) /****************************************************************************** * * -* Paramètres : node = noeud d'arborescence Yaml à compléter. * -* child = noeud à rattacher. * +* Paramètres : node = noeud d'arborescence Yaml à compléter. * +* collec = collection de noeuds Yaml. * * * -* Description : Ajoute un noeud à un noeud d'une arborescence Yaml. * +* Description : Attache une collection de noeuds Yaml à un noeud. * * * * Retour : - * * * @@ -225,43 +229,36 @@ GYamlLine *g_yaml_node_get_yaml_line(const GYamlNode *node) * * ******************************************************************************/ -void g_yaml_node_add_child(GYamlNode *node, GYamlNode *child) +void g_yaml_node_set_collection(GYamlNode *node, GYamlCollection *collec) { - node->children = realloc(node->children, ++node->count * sizeof(GYamlNode *)); + g_clear_object(&node->collection); - node->children[node->count - 1] = child; - g_object_ref_sink(G_OBJECT(child)); + g_object_ref_sink(G_OBJECT(collec)); + node->collection = collec; } /****************************************************************************** * * -* Paramètres : node = noeud d'arborescence Yaml à consulter. * -* count = taille de la liste constituée. [OUT] * +* Paramètres : node = noeud d'arborescence Yaml à consulter. * * * -* Description : Fournit la liste des noeuds intégrés dans un noeud Yaml. * +* Description : Fournit une éventuelle collection rattachée à un noeud. * * * -* Retour : Enfants d'un noeud issu d'une arborescence Yaml. * +* Retour : Collection de noeuds Yaml ou NULL. * * * * Remarques : - * * * ******************************************************************************/ -GYamlNode **g_yaml_node_get_children(const GYamlNode *node, size_t *count) +GYamlCollection *g_yaml_node_get_collection(const GYamlNode *node) { - GYamlNode **result; /* Liste à retourner */ - size_t i; /* Boucle de parcours */ + GYamlCollection *result; /* Collection à renvoyer */ - *count = node->count; + result = node->collection; - result = malloc(*count * sizeof(GYamlNode *)); - - for (i = 0; i < *count; i++) - { - result[i] = node->children[i]; - g_object_ref(G_OBJECT(result[i])); - } + if (result != NULL) + g_object_ref(G_OBJECT(result)); return result; @@ -270,66 +267,125 @@ GYamlNode **g_yaml_node_get_children(const GYamlNode *node, size_t *count) /****************************************************************************** * * -* Paramètres : node = noeud d'arborescence Yaml à consulter. * -* path = chemin d'accès à parcourir. * +* Paramètres : node = noeud d'arborescence Yaml à consulter. * +* path = chemin d'accès à parcourir. * +* nodes = liste de noeuds avec correspondance établie. [OUT] * +* count = quantité de ces noeuds. [OUT] * * * -* Description : Recherche le noeud correspondant à un chemin. * +* Description : Recherche les noeuds correspondant à un chemin. * * * -* Retour : Eventuel noeud trouvé ou NULL si aucun. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -GYamlNode *g_yaml_node_find_node_by_path(GYamlNode *node, const char *path) +void _g_yaml_node_find_by_path(GYamlNode *node, const char *path, GYamlNode ***nodes, size_t *count) { - GYamlNode *result; /* Trouvaille à retourner */ + GYamlLine *line; /* Ligne Yaml liée au noeud */ + const char *key; /* Clef associée au noeud */ + bool matched; /* Correspondance établie ? */ char *next; /* Prochaine partie du chemin */ size_t cmplen; /* Etendue de la comparaison */ - size_t i; /* Boucle de parcours */ - GYamlLine *line; /* Ligne Yaml d'un enfant */ - const char *key; /* Clef d'un noeud */ int ret; /* Bilan d'une comparaison */ + GYamlCollection *collec; /* Collection de noeuds */ - result = NULL; + if (path[0] == '/') + path++; - if (path[0] == '\0') - result = node; + /* Correspondance au niveau du noeud ? */ - else if (path[0] == '/') - { - next = strchr(path + 1, '/'); + line = g_yaml_node_get_yaml_line(node); - cmplen = (next == NULL ? strlen(path + 1) : next - path - 1); + if (line != NULL) + { + key = g_yaml_line_get_key(line); - if (cmplen == 0) - result = node; + if (path[0] == '\0') + matched = true; - for (i = 0; i < node->count && result == NULL; i++) + else { - line = g_yaml_node_get_yaml_line(node->children[i]); + next = strchr(path, '/'); + + cmplen = (next == NULL ? strlen(path) : next - path); + + if (cmplen == 0) + goto cont; - key = g_yaml_line_get_key(line); + ret = strncmp(path, key, cmplen); - ret = strncmp(path + 1, key, cmplen); + if (ret != 0) + goto done; - if (ret == 0) + else { - if (next != NULL) - result = g_yaml_node_find_node_by_path(node->children[i], next); + if (next == NULL) + matched = true; else - result = node->children[i]; + { + path += cmplen; + goto cont; + } } } + if (matched) + { + *nodes = realloc(*nodes, ++(*count) * sizeof(GYamlNode **)); + + g_object_ref(G_OBJECT(node)); + (*nodes)[*count - 1] = node; + + goto done; + + } + } - if (result != NULL) - g_object_ref(G_OBJECT(result)); + cont: - return result; + collec = g_yaml_node_get_collection(node); + + if (collec != NULL) + { + _g_yaml_collection_find_by_path(collec, path, nodes, count); + + g_object_unref(G_OBJECT(collec)); + + } + + done: + + if (line != NULL) + g_object_unref(G_OBJECT(line)); + +} + + +/****************************************************************************** +* * +* Paramètres : node = noeud d'arborescence Yaml à consulter. * +* path = chemin d'accès à parcourir. * +* nodes = liste de noeuds avec correspondance établie. [OUT] * +* count = quantité de ces noeuds. [OUT] * +* * +* Description : Recherche les noeuds correspondant à un chemin. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_yaml_node_find_by_path(GYamlNode *node, const char *path, GYamlNode ***nodes, size_t *count) +{ + *nodes = NULL; + *count = 0; + + _g_yaml_node_find_by_path(node, path, nodes, count); } |