/* Chrysalide - Outil d'analyse de fichiers binaires * scope.c - recherches d'éléments de lecture * * 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 "scope.h" #include "parsers/struct.h" /****************************************************************************** * * * Paramètres : locals = contexte de variables locales à initialiser. * * meta = informations générales à disposition. * * * * Description : Initialise un contexte pour correspondances Kaitai établies. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void init_record_scope(kaitai_scope_t *locals, GKaitaiMeta *meta) { locals->meta = meta; if (meta != NULL) g_object_ref(G_OBJECT(meta)); locals->root = NULL; locals->parent = NULL; locals->last = NULL; } /****************************************************************************** * * * Paramètres : locals = contexte de variables locales à réinitialiser. * * * * Description : Vide un contexte de correspondances Kaitai établies. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void reset_record_scope(kaitai_scope_t *locals) { g_clear_object(&locals->meta); g_clear_object(&locals->root); g_clear_object(&locals->parent); g_clear_object(&locals->last); } /****************************************************************************** * * * Paramètres : dest = contexte de variables locales à initialiser. * * src = contexte de variables locales à copier. * * * * Description : Copie un contexte de correspondances Kaitai établies. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void copy_record_scope(kaitai_scope_t *dest, const kaitai_scope_t *src) { reset_record_scope(dest); #define COPY_SCOPE_ITEM(itm) \ dest->itm = src->itm; \ if (dest->itm != NULL) \ g_object_ref(G_OBJECT(dest->itm)); COPY_SCOPE_ITEM(meta); COPY_SCOPE_ITEM(root); COPY_SCOPE_ITEM(parent); COPY_SCOPE_ITEM(last); } /****************************************************************************** * * * Paramètres : locals = variables locales pour les résolutions de types. * * * * Description : Retourne le souvenir d'une correspondance racine. * * * * Retour : Dernière correspondance établie ou NULL. * * * * Remarques : - * * * ******************************************************************************/ GMatchRecord *get_root_record(const kaitai_scope_t *locals) { GMatchRecord *result; /* Instance à retourner */ result = locals->root; if (result != NULL) g_object_ref(G_OBJECT(result)); return result; } /****************************************************************************** * * * Paramètres : locals = variables locales pour les résolutions de types. * * * * Description : Retourne le souvenir de la correspondance parente effectuée. * * * * Retour : Dernière correspondance établie ou NULL. * * * * Remarques : - * * * ******************************************************************************/ GMatchRecord *get_parent_record(const kaitai_scope_t *locals) { GMatchRecord *result; /* Instance à retourner */ result = locals->parent; if (result != NULL) g_object_ref(G_OBJECT(result)); return result; } /****************************************************************************** * * * Paramètres : locals = variables locales pour les résolutions de types. * * record = dernière correspondance établie. * * * * Description : Conserve le souvenir de la dernière correspondance effectuée.* * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void remember_last_record(kaitai_scope_t *locals, GMatchRecord *record) { g_clear_object(&locals->last); locals->last = record; if (record != NULL) g_object_ref(G_OBJECT(record)); } /****************************************************************************** * * * Paramètres : locals = variables locales pour les résolutions de types. * * * * Description : Retourne le souvenir de la dernière correspondance effectuée.* * * * Retour : Dernière correspondance établie ou NULL. * * * * Remarques : - * * * ******************************************************************************/ GMatchRecord *get_last_record(const kaitai_scope_t *locals) { GMatchRecord *result; /* Instance à retourner */ result = locals->last; if (result != NULL) g_object_ref(G_OBJECT(result)); return result; } /****************************************************************************** * * * Paramètres : locals = variables locales pour les résolutions de types. * * name = désignation du type particulier ciblé. * * * * Description : Recherche la définition d'un type nouveau pour Kaitai. * * * * Retour : Type prêt à emploi ou NULL si non trouvé. * * * * Remarques : - * * * ******************************************************************************/ GKaitaiType *find_sub_type(const kaitai_scope_t *locals, const char *name) { GKaitaiType *result; /* Instance à retourner */ size_t i; /* Boucle de parcours */ GKaitaiParser *parser; /* Lecteur d'origine */ GMatchRecord *list[] = { locals->last, locals->parent, locals->root }; result = NULL; for (i = 0; i < 3; i++) { if (list[i] == NULL) continue; parser = g_match_record_get_creator(list[i]); if (G_IS_KAITAI_STRUCT(parser)) result = g_kaitai_structure_find_sub_type(G_KAITAI_STRUCT(parser), name); g_object_unref(G_OBJECT(parser)); if (result != NULL) break; } return result; }