/* Chrysalide - Outil d'analyse de fichiers binaires * reader.c - lecteur de contenu Yaml * * Copyright (C) 2019-2020 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 . */ #include "reader.h" #include #include #include #include #include "line.h" #include "reader-int.h" /* Initialise la classe des lecteurs de contenus Yaml. */ static void g_yaml_reader_class_init(GYamlReaderClass *); /* Initialise une instance de lecteur de contenu Yaml. */ static void g_yaml_reader_init(GYamlReader *); /* Supprime toutes les références externes. */ static void g_yaml_reader_dispose(GYamlReader *); /* Procède à la libération totale de la mémoire. */ static void g_yaml_reader_finalize(GYamlReader *); /* Indique le type défini pour un lecteur de contenu Yaml. */ G_DEFINE_TYPE(GYamlReader, g_yaml_reader, G_TYPE_OBJECT); /****************************************************************************** * * * Paramètres : klass = classe à initialiser. * * * * Description : Initialise la classe des lecteurs de contenus Yaml. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_yaml_reader_class_init(GYamlReaderClass *klass) { GObjectClass *object; /* Autre version de la classe */ object = G_OBJECT_CLASS(klass); object->dispose = (GObjectFinalizeFunc/* ! */)g_yaml_reader_dispose; object->finalize = (GObjectFinalizeFunc)g_yaml_reader_finalize; } /****************************************************************************** * * * Paramètres : reader = instance à initialiser. * * * * Description : Initialise une instance de lecteur de contenu Yaml. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_yaml_reader_init(GYamlReader *reader) { reader->lines = NULL; reader->count = 0; reader->tree = NULL; } /****************************************************************************** * * * Paramètres : reader = instance d'objet GLib à traiter. * * * * Description : Supprime toutes les références externes. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_yaml_reader_dispose(GYamlReader *reader) { size_t i; /* Boucle de parcours */ for (i = 0; i < reader->count; i++) g_clear_object(&reader->lines[i]); g_clear_object(&reader->tree); G_OBJECT_CLASS(g_yaml_reader_parent_class)->dispose(G_OBJECT(reader)); } /****************************************************************************** * * * Paramètres : reader = instance d'objet GLib à traiter. * * * * Description : Procède à la libération totale de la mémoire. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_yaml_reader_finalize(GYamlReader *reader) { if (reader->lines != NULL) free(reader->lines); G_OBJECT_CLASS(g_yaml_reader_parent_class)->finalize(G_OBJECT(reader)); } /****************************************************************************** * * * Paramètres : text = définitions textuelles d'un contenu brut. * * * * Description : Crée un lecteur pour contenu au format Yaml. * * * * Retour : Instance mise en place ou NULL en cas d'échec. * * * * Remarques : - * * * ******************************************************************************/ GYamlReader *g_yaml_reader_new_from_text(const char *text) { GYamlReader *result; /* Structure à retourner */ result = g_object_new(G_TYPE_YAML_READER, NULL); if (!g_yaml_reader_create_from_text(result, text)) g_clear_object(&result); return result; } /****************************************************************************** * * * Paramètres : reader = lecteur de définition à initialiser pleinement. * * text = définitions textuelles d'un contenu brut. * * * * Description : Met en place un lecteur pour contenu au format Yaml. * * * * Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ bool g_yaml_reader_create_from_text(GYamlReader *reader, const char *text) { bool result; /* Bilan à retourner */ const char *saved; /* Sauvegarde de position */ const char *iter; /* Boucle de parcours */ size_t number; /* Indice de ligne courante */ size_t rlen; /* Taille d'un contenu brut */ GYamlLine *line; /* Nouvelle ligne Yaml */ result = false; for (iter = text, saved = strchr(iter, '\n'), number = 0; *iter != '\0'; iter = ++saved, saved = strchr(iter, '\n'), number++) { if (saved == NULL) rlen = strlen(iter); else rlen = saved - iter; if (rlen > 0) { line = g_yaml_line_new(iter, rlen, number); if (line == NULL) goto format_error; reader->lines = realloc(reader->lines, ++reader->count * sizeof(GYamlLine *)); g_object_ref_sink(G_OBJECT(line)); reader->lines[reader->count - 1] = line; } if (saved == NULL) break; } reader->tree = g_yaml_tree_new(reader->lines, reader->count); result = (reader->tree != NULL); format_error: return result; } /****************************************************************************** * * * Paramètres : filename = chemin vers des définitions de règles. * * * * Description : Crée un lecteur pour contenu au format Yaml. * * * * Retour : Instance mise en place ou NULL en cas d'échec. * * * * Remarques : - * * * ******************************************************************************/ GYamlReader *g_yaml_reader_new_from_file(const char *filename) { GYamlReader *result; /* Structure à retourner */ result = g_object_new(G_TYPE_YAML_READER, NULL); if (!g_yaml_reader_create_from_file(result, filename)) g_clear_object(&result); return result; } /****************************************************************************** * * * Paramètres : reader = lecteur de définition à initialiser pleinement. * * filename = chemin vers des définitions de règles. * * * * Description : Met en place un lecteur pour contenu au format Yaml. * * * * Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ bool g_yaml_reader_create_from_file(GYamlReader *reader, const char *filename) { bool result; /* Bilan à retourner */ GBinContent *content; /* Fichier à parcourir */ phys_t size; /* Taille du contenu associé */ vmpa2t start; /* Tête de lecture */ const bin_t *data; /* Données à consulter */ char *dumped; /* Contenu manipulable */ result = false; content = g_file_content_new(filename); if (content == NULL) goto no_content; size = g_binary_content_compute_size(content); g_binary_content_compute_start_pos(content, &start); data = g_binary_content_get_raw_access(content, &start, size); dumped = malloc((size + 1) * sizeof(char)); memcpy(dumped, data, size); dumped[size] = '\0'; result = g_yaml_reader_create_from_text(reader, dumped); free(dumped); g_object_unref(G_OBJECT(content)); no_content: return result; } /****************************************************************************** * * * Paramètres : reader = lecteur de contenu Yaml à consulter. * * count = taille de la liste constituée. [OUT] * * * * Description : Fournit la liste des lignes lues depuis un contenu Yaml. * * * * Retour : Liste de lignes correspondant au contenu Yaml lu. * * * * Remarques : - * * * ******************************************************************************/ GYamlLine **g_yaml_reader_get_lines(const GYamlReader *reader, size_t *count) { GYamlLine **result; /* Liste à retourner */ size_t i; /* Boucle de parcours */ *count = reader->count; result = malloc(*count * sizeof(GYamlLine *)); for (i = 0; i < *count; i++) { result[i] = reader->lines[i]; g_object_ref(result[i]); } return result; } /****************************************************************************** * * * Paramètres : reader = lecteur de contenu Yaml à consulter. * * * * Description : Fournit l'arborescence associée à la lecture de lignes Yaml. * * * * Retour : Arborescence constituée par la lecture du contenu Yaml. * * * * Remarques : - * * * ******************************************************************************/ GYamlTree *g_yaml_reader_get_tree(const GYamlReader *reader) { GYamlTree *result; /* Arborescence à retourner */ result = reader->tree; if (result != NULL) g_object_ref(G_OBJECT(result)); return result; }