/* Chrysalide - Outil d'analyse de fichiers binaires * meta.c - description globale d'une définition Kaitai * * Copyright (C) 2023 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 "meta.h" #include #include #include #include #include "meta-int.h" /* Initialise la classe des descriptions globales Kaitai. */ static void g_kaitai_meta_class_init(GKaitaiMetaClass *); /* Initialise une description globale de définition Kaitai. */ static void g_kaitai_meta_init(GKaitaiMeta *); /* Supprime toutes les références externes. */ static void g_kaitai_meta_dispose(GKaitaiMeta *); /* Procède à la libération totale de la mémoire. */ static void g_kaitai_meta_finalize(GKaitaiMeta *); /* Indique le type défini pour une description globale Kaitai. */ G_DEFINE_TYPE(GKaitaiMeta, g_kaitai_meta, G_TYPE_OBJECT); /****************************************************************************** * * * Paramètres : klass = classe à initialiser. * * * * Description : Initialise la classe des descriptions globales Kaitai. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_kaitai_meta_class_init(GKaitaiMetaClass *klass) { GObjectClass *object; /* Autre version de la classe */ object = G_OBJECT_CLASS(klass); object->dispose = (GObjectFinalizeFunc/* ! */)g_kaitai_meta_dispose; object->finalize = (GObjectFinalizeFunc)g_kaitai_meta_finalize; } /****************************************************************************** * * * Paramètres : meta = instance à initialiser. * * * * Description : Initialise une description globale de définition Kaitai. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_kaitai_meta_init(GKaitaiMeta *meta) { meta->id = NULL; meta->title = NULL; meta->endian = SRE_LITTLE; meta->dependencies = NULL; meta->dep_count = 0; } /****************************************************************************** * * * Paramètres : meta = instance d'objet GLib à traiter. * * * * Description : Supprime toutes les références externes. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_kaitai_meta_dispose(GKaitaiMeta *meta) { G_OBJECT_CLASS(g_kaitai_meta_parent_class)->dispose(G_OBJECT(meta)); } /****************************************************************************** * * * Paramètres : meta = instance d'objet GLib à traiter. * * * * Description : Procède à la libération totale de la mémoire. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_kaitai_meta_finalize(GKaitaiMeta *meta) { size_t i; /* Boucle de parcours */ if (meta->id != NULL) free(meta->id); if (meta->title != NULL) free(meta->title); for (i = 0; i < meta->dep_count; i++) free(meta->dependencies[i]); if (meta->dependencies != NULL) free(meta->dependencies); G_OBJECT_CLASS(g_kaitai_meta_parent_class)->finalize(G_OBJECT(meta)); } /****************************************************************************** * * * Paramètres : parent = noeud Yaml contenant l'attribut à constituer. * * * * Description : Construit une description globale Kaitai. * * * * Retour : Instance mise en place ou NULL en cas d'échec. * * * * Remarques : - * * * ******************************************************************************/ GKaitaiMeta *g_kaitai_meta_new(GYamlNode *parent) { GKaitaiMeta *result; /* Identifiant à retourner */ result = g_object_new(G_TYPE_KAITAI_META, NULL); if (!g_kaitai_meta_create(result, parent)) g_clear_object(&result); return result; } /****************************************************************************** * * * Paramètres : meta = description globale à initialiser pleinement. * * parent = noeud Yaml contenant l'attribut à constituer. * * * * Description : Met en place une description globale Kaitai. * * * * Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ bool g_kaitai_meta_create(GKaitaiMeta *meta, GYamlNode *parent) { bool result; /* Bilan à retourner */ GYamlNode *node; /* Noeud particulier présent */ const char *value; /* Valeur Yaml particulière */ GYamlNode **nodes; /* Eventuels noeuds trouvés */ size_t count; /* Quantité de ces noeuds */ size_t i; /* Boucle de parcours */ result = true; /* Identifiant */ node = g_yaml_node_find_first_by_path(parent, "/meta/id"); if (node != NULL) { assert(G_IS_YAML_PAIR(node)); value = g_yaml_pair_get_value(G_YAML_PAIR(node)); if (value != NULL) meta->id = strdup(value); g_object_unref(G_OBJECT(node)); } /* Titre */ node = g_yaml_node_find_first_by_path(parent, "/meta/title"); if (node != NULL) { assert(G_IS_YAML_PAIR(node)); value = g_yaml_pair_get_value(G_YAML_PAIR(node)); if (value != NULL) meta->title = strdup(value); g_object_unref(G_OBJECT(node)); } /* Boutisme */ node = g_yaml_node_find_first_by_path(parent, "/meta/endian"); if (node != NULL) { assert(G_IS_YAML_PAIR(node)); value = g_yaml_pair_get_value(G_YAML_PAIR(node)); if (strcmp(value, "le") == 0) meta->endian = SRE_LITTLE; else if (strcmp(value, "be") == 0) meta->endian = SRE_BIG; g_object_unref(G_OBJECT(node)); } /* Imports */ node = g_yaml_node_find_first_by_path(parent, "/meta/imports/"); if (node != NULL) { result = G_IS_YAML_COLLEC(node); if (result) { nodes = g_yaml_collection_get_nodes(G_YAML_COLLEC(node), &count); for (i = 0; i < count; i++) { if (!G_IS_YAML_PAIR(nodes[i])) break; value = g_yaml_pair_get_key(G_YAML_PAIR(nodes[i])); meta->dependencies = realloc(meta->dependencies, ++meta->dep_count * sizeof(char *)); meta->dependencies[meta->dep_count - 1] = strdup(value); g_object_unref(G_OBJECT(nodes[i])); } result = (i == count); for (; i < count; i++) g_object_unref(G_OBJECT(nodes[i])); if (nodes != NULL) free(nodes); } } return result; } /****************************************************************************** * * * Paramètres : meta = description globale à consulter. * * * * Description : Fournit l'identifié associé à une définiton Kaitai. * * * * Retour : Identifiant de définition complète ou NULL. * * * * Remarques : - * * * ******************************************************************************/ const char *g_kaitai_meta_get_id(const GKaitaiMeta *meta) { const char *result; /* Chaîne à retourner */ result = meta->id; return result; } /****************************************************************************** * * * Paramètres : meta = description globale à consulter. * * * * Description : Fournit la désignation humaine d'une définiton Kaitai. * * * * Retour : Intitulé de définition ou NULL. * * * * Remarques : - * * * ******************************************************************************/ const char *g_kaitai_meta_get_title(const GKaitaiMeta *meta) { const char *result; /* Chaîne à retourner */ result = meta->title; return result; } /****************************************************************************** * * * Paramètres : meta = description globale à consulter. * * * * Description : Indique le boustime observé par défaut par une définiton. * * * * Retour : Boustime, petit par défaut. * * * * Remarques : - * * * ******************************************************************************/ SourceEndian g_kaitai_meta_get_endian(const GKaitaiMeta *meta) { SourceEndian result; /* Chaîne à retourner */ result = meta->endian; return result; } /****************************************************************************** * * * Paramètres : meta = description globale à consulter. * * count = quantité de définitions à importer. [OUT] * * * * Description : Indique la liste des définitions à importer. * * * * Retour : Liste de désignations de définitions ou NULL. * * * * Remarques : - * * * ******************************************************************************/ const char * const *g_kaitai_meta_get_dependencies(const GKaitaiMeta *meta, size_t *count) { const char * const *result; /* Liste à retourner */ result = (const char * const *)meta->dependencies; *count = meta->dep_count; return result; }