diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2019-06-16 20:20:46 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2019-11-01 10:16:01 (GMT) |
commit | 33b5dc9af0404eabeb0e60245ab1ca1dc3713a17 (patch) | |
tree | fda7b9996c7e90b96507988d54cc73161b309621 /plugins/yaml/tree.c | |
parent | a8598ae89acd2963143b7a6b248fbecbc0e16025 (diff) |
Added support for Yaml content.
Diffstat (limited to 'plugins/yaml/tree.c')
-rw-r--r-- | plugins/yaml/tree.c | 383 |
1 files changed, 383 insertions, 0 deletions
diff --git a/plugins/yaml/tree.c b/plugins/yaml/tree.c new file mode 100644 index 0000000..98ee30c --- /dev/null +++ b/plugins/yaml/tree.c @@ -0,0 +1,383 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * tree.c - ligne de contenu Yaml + * + * Copyright (C) 2019 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "tree.h" + + +#include <malloc.h> +#include <string.h> + + + +/* Arborescence de lignes au format Yaml (instance) */ +struct _GYamlTree +{ + GObject parent; /* A laisser en premier */ + + size_t indent; /* Niveau d'indentation */ + + GYamlNode **nodes; /* Liste de noeuds à la racine */ + size_t count; /* Quantité de ces noeuds */ + +}; + +/* Arborescence de lignes au format Yaml (classe) */ +struct _GYamlTreeClass +{ + GObjectClass parent; /* A laisser en premier */ + +}; + + +/* Initialise la classe des arborescence de lignes Yaml. */ +static void g_yaml_tree_class_init(GYamlTreeClass *); + +/* Initialise une instance d'arborescence de lignes Yaml. */ +static void g_yaml_tree_init(GYamlTree *); + +/* Supprime toutes les références externes. */ +static void g_yaml_tree_dispose(GYamlTree *); + +/* Procède à la libération totale de la mémoire. */ +static void g_yaml_tree_finalize(GYamlTree *); + +/* Construit un nouveau noeud dans une arborescence Yaml. */ +static GYamlNode *g_yaml_tree_build_node(GYamlLine **, size_t, size_t *); + + + +/* Indique le type défini pour une arborescence de lignes au format Yaml. */ +G_DEFINE_TYPE(GYamlTree, g_yaml_tree, G_TYPE_OBJECT); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des arborescence de lignes Yaml. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_yaml_tree_class_init(GYamlTreeClass *klass) +{ + GObjectClass *object; /* Autre version de la classe */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_yaml_tree_dispose; + object->finalize = (GObjectFinalizeFunc)g_yaml_tree_finalize; + +} + + +/****************************************************************************** +* * +* Paramètres : tree = instance à initialiser. * +* * +* Description : Initialise une instance d'arborescence de lignes Yaml. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_yaml_tree_init(GYamlTree *tree) +{ + tree->indent = 0; + + tree->nodes = NULL; + tree->count = 0; + +} + + +/****************************************************************************** +* * +* Paramètres : tree = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_yaml_tree_dispose(GYamlTree *tree) +{ + size_t i; /* Boucle de parcours */ + + for (i = 0; i < tree->count; i++) + g_clear_object(&tree->nodes[i]); + + G_OBJECT_CLASS(g_yaml_tree_parent_class)->dispose(G_OBJECT(tree)); + +} + + +/****************************************************************************** +* * +* Paramètres : tree = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_yaml_tree_finalize(GYamlTree *tree) +{ + if (tree->nodes != NULL) + free(tree->nodes); + + G_OBJECT_CLASS(g_yaml_tree_parent_class)->finalize(G_OBJECT(tree)); + +} + + +/****************************************************************************** +* * +* Paramètres : indent = indentation nominale pour les lignes à traiter. * +* lines = ensemble de lignes à constituer en arborescence. * +* count = taille de cet ensemble de lignes. * +* * +* Description : Construit une arborescence à partir de lignes Yaml. * +* * +* Retour : Instance mise en place ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GYamlTree *g_yaml_tree_new(size_t indent, GYamlLine **lines, size_t count) +{ + GYamlTree *result; /* Structure à retourner */ + size_t cur; /* Boucle de parcours */ + GYamlNode *node; /* Nouveau noeud à intéger */ + + result = g_object_new(G_TYPE_YAML_TREE, NULL); + + result->indent = indent; + + for (cur = 0; cur < count; ) + { + node = g_yaml_tree_build_node(lines, count, &cur); + + if (node == NULL) + break; + + result->nodes = realloc(result->nodes, ++result->count * sizeof(GYamlNode *)); + + g_object_ref_sink(G_OBJECT(node)); + result->nodes[result->count - 1] = node; + + } + + if (cur < count) + { + g_object_unref(G_OBJECT(result)); + result = NULL; + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : lines = ensemble de lignes à constituer en arborescence. * +* count = taille de cet ensemble de lignes. * +* cur = position courante dans les lignes. [OUT] * +* * +* Description : Construit un nouveau noeud dans une arborescence Yaml. * +* * +* Retour : Noeud mis en place ou NULL en cas d'erreur. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GYamlNode *g_yaml_tree_build_node(GYamlLine **lines, size_t count, size_t *cur) +{ + GYamlNode *result; /* Structure à retourner */ + GYamlLine *line; /* Ligne de parcours courante */ + size_t cur_indent; /* Indentation courante */ + bool same_indent; /* Comparaison pour les enfants*/ + size_t next_indent; /* Indentation de la ligne */ + GYamlNode *child; /* Sous-noeud mis en place */ + + line = lines[(*cur)++]; + + result = g_yaml_node_new(line); + + /* Détermination de l'indentation associée */ + + cur_indent = g_yaml_line_count_indent(line); + + same_indent = g_yaml_line_is_list_item(line); + + /* Parcours du reste des lignes */ + + for (; *cur < count; ) + { + line = lines[*cur]; + + next_indent = g_yaml_line_count_indent(line); + + if ((same_indent && next_indent > cur_indent) + || (!same_indent && next_indent <= cur_indent)) + break; + + child = g_yaml_tree_build_node(lines, count, cur); + + if (child == NULL) + goto build_error; + + g_yaml_node_add_child(result, child); + + } + + return result; + + build_error: + + g_object_unref(G_OBJECT(result)); + + return NULL; + +} + + +/****************************************************************************** +* * +* Paramètres : tree = ligne au format Yaml à consulter. * +* * +* Description : Fournit la taille de l'indentation nomilae d'un arbre Yaml. * +* * +* Retour : Taille de l'indentation associée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +size_t g_yaml_tree_get_indent(const GYamlTree *tree) +{ + size_t result; /* Quantité à retourner */ + + result = tree->indent; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : tree = ligne au format Yaml à consulter. * +* count = taille de la liste constituée. [OUT] * +* * +* Description : Fournit la liste des premiers noeuds de l'arborescence Yaml. * +* * +* Retour : Noeuds constituant les racines de l'arborescence. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GYamlNode **g_yaml_tree_get_root_nodes(const GYamlTree *tree, size_t *count) +{ + GYamlNode **result; /* Liste à retourner */ + size_t i; /* Boucle de parcours */ + + *count = tree->count; + + result = malloc(*count * sizeof(GYamlNode *)); + + for (i = 0; i < *count; i++) + { + result[i] = tree->nodes[i]; + g_object_ref(G_OBJECT(result[i])); + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : tree = ligne au format Yaml à consulter. * +* path = chemin d'accès à parcourir. * +* * +* Description : Recherche le noeud correspondant à un chemin. * +* * +* Retour : Eventuel noeud trouvé ou NULL si aucun. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GYamlNode *g_yaml_tree_find_node_by_path(const GYamlTree *tree, const char *path) +{ + GYamlNode *result; /* Trouvaille à retourner */ + 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 */ + + result = NULL; + + if (path[0] == '/' && path[0] != '\0') + { + next = strchr(path + 1, '/'); + + cmplen = (next == NULL ? strlen(path + 1) : next - path - 1); + + for (i = 0; i < tree->count && result == NULL; i++) + { + line = g_yaml_node_get_yaml_line(tree->nodes[i]); + + key = g_yaml_line_get_key(line); + + ret = strncmp(path + 1, key, cmplen); + + if (ret == 0) + result = g_yaml_node_find_node_by_path(tree->nodes[i], next); + + } + + } + + return result; + +} |