diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2023-10-09 22:49:59 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2023-10-09 22:49:59 (GMT) |
commit | 7c6fe94c90d320813d0d78a9dbef707696f31505 (patch) | |
tree | 912b5c51469c02e6ef680c0c60739787ccff4891 /plugins/kaitai/records | |
parent | cb05b99a8c451ff80d88f988e2654c794b0f3750 (diff) |
Support some last missing features from Kaitai: bit fields, instance search order and stream EOF.
Diffstat (limited to 'plugins/kaitai/records')
-rw-r--r-- | plugins/kaitai/records/Makefile.am | 8 | ||||
-rw-r--r-- | plugins/kaitai/records/bits-int.h | 59 | ||||
-rw-r--r-- | plugins/kaitai/records/bits.c | 283 | ||||
-rw-r--r-- | plugins/kaitai/records/bits.h | 62 | ||||
-rw-r--r-- | plugins/kaitai/records/delayed-int.h (renamed from plugins/kaitai/records/value-int.h) | 19 | ||||
-rw-r--r-- | plugins/kaitai/records/delayed.c (renamed from plugins/kaitai/records/value.c) | 128 | ||||
-rw-r--r-- | plugins/kaitai/records/delayed.h (renamed from plugins/kaitai/records/value.h) | 32 |
7 files changed, 508 insertions, 83 deletions
diff --git a/plugins/kaitai/records/Makefile.am b/plugins/kaitai/records/Makefile.am index c11e823..3884bfb 100644 --- a/plugins/kaitai/records/Makefile.am +++ b/plugins/kaitai/records/Makefile.am @@ -2,6 +2,10 @@ noinst_LTLIBRARIES = libkaitairecords.la libkaitairecords_la_SOURCES = \ + bits-int.h \ + bits.h bits.c \ + delayed-int.h \ + delayed.h delayed.c \ empty-int.h \ empty.h empty.c \ group-int.h \ @@ -9,9 +13,7 @@ libkaitairecords_la_SOURCES = \ item-int.h \ item.h item.c \ list-int.h \ - list.h list.c \ - value-int.h \ - value.h value.c + list.h list.c libkaitairecords_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) -I$(top_srcdir)/src diff --git a/plugins/kaitai/records/bits-int.h b/plugins/kaitai/records/bits-int.h new file mode 100644 index 0000000..7b03911 --- /dev/null +++ b/plugins/kaitai/records/bits-int.h @@ -0,0 +1,59 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * bits-int.h - prototypes internes pour la conservation d'un champ de bits entre attribut et binaire + * + * 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 <http://www.gnu.org/licenses/>. + */ + + +#ifndef _PLUGINS_KAITAI_RECORDS_BITS_INT_H +#define _PLUGINS_KAITAI_RECORDS_BITS_INT_H + + +#include "bits.h" + + +#include "../record-int.h" + + + +/* Correspondance de bits établie entre un attribut et du binaire (instance) */ +struct _GRecordBitField +{ + GMatchRecord parent; /* A laisser en premier */ + + ext_vmpa_t epos; /* Point de départ */ + uint8_t size; /* Quantité de bits concernés */ + SourceEndian endian; /* Boutisme des données imposé */ + +}; + +/* Correspondance de bits établie entre un attribut et du binaire (classe) */ +struct _GRecordBitFieldClass +{ + GMatchRecordClass parent; /* A laisser en premier */ + +}; + + +/* Met en place une correspondance entre attribut et binaire. */ +bool g_record_bit_field_create(GRecordBitField *, GKaitaiAttribute *, GBinContent *, const ext_vmpa_t *, uint8_t, SourceEndian); + + + +#endif /* _PLUGINS_KAITAI_RECORDS_BITS_INT_H */ diff --git a/plugins/kaitai/records/bits.c b/plugins/kaitai/records/bits.c new file mode 100644 index 0000000..d224112 --- /dev/null +++ b/plugins/kaitai/records/bits.c @@ -0,0 +1,283 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * bits.c - conservation d'un champ de bits entre attribut et binaire + * + * 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 <http://www.gnu.org/licenses/>. + */ + + +#include "bits.h" + + +#include <assert.h> +#include <string.h> + + +#include "bits-int.h" + + + +/* -------------------- DEFINITION D'UNE CORRESPONDANCE UNITAIRE -------------------- */ + + +/* Initialise la classe des correspondances attribut/binaire. */ +static void g_record_bit_field_class_init(GRecordBitFieldClass *); + +/* Initialise une correspondance entre attribut et binaire. */ +static void g_record_bit_field_init(GRecordBitField *); + +/* Supprime toutes les références externes. */ +static void g_record_bit_field_dispose(GRecordBitField *); + +/* Procède à la libération totale de la mémoire. */ +static void g_record_bit_field_finalize(GRecordBitField *); + + + +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ + + +/* Calcule ou fournit la zone couverte par une correspondance. */ +static void g_record_bit_field_get_range(const GRecordBitField *, mrange_t *); + + + +/* ---------------------------------------------------------------------------------- */ +/* DEFINITION D'UNE CORRESPONDANCE UNITAIRE */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini pour une correspondance entre un attribut et du binaire. */ +G_DEFINE_TYPE(GRecordBitField, g_record_bit_field, G_TYPE_MATCH_RECORD); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des correspondances attribut/binaire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_record_bit_field_class_init(GRecordBitFieldClass *klass) +{ + GObjectClass *object; /* Autre version de la classe */ + GMatchRecordClass *record; /* Version parente de la classe*/ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_record_bit_field_dispose; + object->finalize = (GObjectFinalizeFunc)g_record_bit_field_finalize; + + record = G_MATCH_RECORD_CLASS(klass); + + record->get_range = (get_record_range_fc)g_record_bit_field_get_range; + +} + + +/****************************************************************************** +* * +* Paramètres : field = instance à initialiser. * +* * +* Description : Initialise une correspondance entre attribut et binaire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_record_bit_field_init(GRecordBitField *field) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : field = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_record_bit_field_dispose(GRecordBitField *field) +{ + G_OBJECT_CLASS(g_record_bit_field_parent_class)->dispose(G_OBJECT(field)); + +} + + +/****************************************************************************** +* * +* Paramètres : field = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_record_bit_field_finalize(GRecordBitField *field) +{ + G_OBJECT_CLASS(g_record_bit_field_parent_class)->finalize(G_OBJECT(field)); + +} + + +/****************************************************************************** +* * +* Paramètres : attrib = analyseur à l'origine de la correspondance. * +* content = contenu binaire lié à la correspondance. * +* epos = tête de lecture avec granularité en bits. * +* size = quantité de bits à prendre en compte. * +* endian = boustime des données à respecter. * +* * +* Description : Crée une nouvelle correspondance entre attribut et binaire. * +* * +* Retour : Instance mise en place ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GMatchRecord *g_record_bit_field_new(GKaitaiAttribute *attrib, GBinContent *content, const ext_vmpa_t *epos, uint8_t size, SourceEndian endian) +{ + GMatchRecord *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_RECORD_BIT_FIELD, NULL); + + if (!g_record_bit_field_create(G_RECORD_BIT_FIELD(result), attrib, content, epos, size, endian)) + g_clear_object(&result); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : field = correspondance à initialiser pleinement. * +* attrib = analyseur à l'origine de la correspondance. * +* content = contenu binaire lié à la correspondance. * +* epos = tête de lecture avec granularité en bits. * +* size = quantité de bits à prendre en compte. * +* endian = boustime des données à respecter. * +* * +* Description : Met en place une correspondance entre attribut et binaire. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_record_bit_field_create(GRecordBitField *field, GKaitaiAttribute *attrib, GBinContent *content, const ext_vmpa_t *epos, uint8_t size, SourceEndian endian) +{ + bool result; /* Bilan à retourner */ + + result = g_match_record_create(G_MATCH_RECORD(field), G_KAITAI_PARSER(attrib), content); + + if (result) + { + copy_evmpa(&field->epos, epos); + field->size = size; + field->endian = endian; + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : field = correspondance à consulter. * +* out = valeur à sauvegarder sous une forme générique. [OUT] * +* * +* Description : Lit la valeur d'un élément Kaitai entier représenté. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_record_bit_field_get_value(const GRecordBitField *field, resolved_value_t *out) +{ + bool result; /* Bilan à retourner */ + GKaitaiParser *parser; /* Attribut associé à l'élément*/ + + parser = g_match_record_get_creator(G_MATCH_RECORD(field)); + assert(G_IS_KAITAI_ATTRIBUTE(parser)); + + result = g_kaitai_attribute_read_bit_field_value(G_KAITAI_ATTRIBUTE(parser), + G_MATCH_RECORD(field)->content, + &field->epos, field->size, + field->endian, out); + + g_object_unref(G_OBJECT(parser)); + + return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* IMPLEMENTATION DES FONCTIONS DE CLASSE */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : record = correspondance à consulter. * +* range = zone de couverture déterminée. [OUT] * +* * +* Description : Calcule ou fournit la zone couverte par une correspondance. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_record_bit_field_get_range(const GRecordBitField *record, mrange_t *range) +{ + phys_t len; /* Taille en octets */ + + len = record->size / 8; + + if (record->size % 8 > 0) + len ++; + + init_mrange(range, &record->epos.base, len); + +} diff --git a/plugins/kaitai/records/bits.h b/plugins/kaitai/records/bits.h new file mode 100644 index 0000000..923e8e3 --- /dev/null +++ b/plugins/kaitai/records/bits.h @@ -0,0 +1,62 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * bits.h - prototypes pour la conservation d'un champ de bits entre attribut et binaire + * + * 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 <http://www.gnu.org/licenses/>. + */ + + +#ifndef _PLUGINS_KAITAI_RECORDS_BITS_H +#define _PLUGINS_KAITAI_RECORDS_BITS_H + + +#include <glib-object.h> + + +#include "../record.h" +#include "../parsers/attribute.h" + + + +#define G_TYPE_RECORD_BIT_FIELD g_record_bit_field_get_type() +#define G_RECORD_BIT_FIELD(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_RECORD_BIT_FIELD, GRecordBitField)) +#define G_IS_RECORD_BIT_FIELD(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_RECORD_BIT_FIELD)) +#define G_RECORD_BIT_FIELD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_RECORD_BIT_FIELD, GRecordBitFieldClass)) +#define G_IS_RECORD_BIT_FIELD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_RECORD_BIT_FIELD)) +#define G_RECORD_BIT_FIELD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_RECORD_BIT_FIELD, GRecordBitFieldClass)) + + +/* Correspondance de bits établie entre un attribut et du binaire (instance) */ +typedef struct _GRecordBitField GRecordBitField; + +/* Correspondance de bits établie entre un attribut et du binaire (classe) */ +typedef struct _GRecordBitFieldClass GRecordBitFieldClass; + + +/* Indique le type défini pour une correspondance entre un attribut et du binaire. */ +GType g_record_bit_field_get_type(void); + +/* Crée une nouvelle correspondance entre attribut et binaire. */ +GMatchRecord *g_record_bit_field_new(GKaitaiAttribute *, GBinContent *, const ext_vmpa_t *, uint8_t, SourceEndian); + +/* Lit la valeur d'un élément Kaitai entier représenté. */ +bool g_record_bit_field_get_value(const GRecordBitField *, resolved_value_t *); + + + +#endif /* _PLUGINS_KAITAI_RECORDS_BITS_H */ diff --git a/plugins/kaitai/records/value-int.h b/plugins/kaitai/records/delayed-int.h index 6a84a7f..9275500 100644 --- a/plugins/kaitai/records/value-int.h +++ b/plugins/kaitai/records/delayed-int.h @@ -1,6 +1,6 @@ /* Chrysalide - Outil d'analyse de fichiers binaires - * value-int.h - prototypes internes pour la conservation d'une instance virtuelle + * delayed-int.h - prototypes internes pour la conservation d'une instance virtuelle * * Copyright (C) 2019 Cyrille Bagard * @@ -21,11 +21,11 @@ */ -#ifndef _PLUGINS_KAITAI_RECORDS_VALUE_INT_H -#define _PLUGINS_KAITAI_RECORDS_VALUE_INT_H +#ifndef _PLUGINS_KAITAI_RECORDS_DELAYED_INT_H +#define _PLUGINS_KAITAI_RECORDS_DELAYED_INT_H -#include "value.h" +#include "delayed.h" #include "../record-int.h" @@ -33,16 +33,19 @@ /* Valeur calculée selon des correspondances parallèles (instance) */ -struct _GRecordValue +struct _GRecordDelayed { GMatchRecord parent; /* A laisser en premier */ kaitai_scope_t locals; /* Sauvegarde de contexte */ + bool has_value; /* Port d'une valeur directe ? */ + GMatchRecord *real_record; /* Enregistrement effectif */ + }; /* Valeur calculée selon des correspondances parallèles (classe) */ -struct _GRecordValueClass +struct _GRecordDelayedClass { GMatchRecordClass parent; /* A laisser en premier */ @@ -50,8 +53,8 @@ struct _GRecordValueClass /* Met en place une valeur calculée selon des correspondances. */ -bool g_record_value_create(GRecordValue *, GKaitaiInstance *, const kaitai_scope_t *); +bool g_record_delayed_create(GRecordDelayed *, GKaitaiInstance *, const kaitai_scope_t *, GBinContent *); -#endif /* _PLUGINS_KAITAI_RECORDS_VALUE_INT_H */ +#endif /* _PLUGINS_KAITAI_RECORDS_DELAYED_INT_H */ diff --git a/plugins/kaitai/records/value.c b/plugins/kaitai/records/delayed.c index cafe5c3..8c1395c 100644 --- a/plugins/kaitai/records/value.c +++ b/plugins/kaitai/records/delayed.c @@ -1,6 +1,6 @@ /* Chrysalide - Outil d'analyse de fichiers binaires - * value.c - conservation d'une correspondance entre attribut et binaire + * delayed.c - conservation d'une correspondance entre attribut et binaire * * Copyright (C) 2019 Cyrille Bagard * @@ -21,7 +21,7 @@ */ -#include "value.h" +#include "delayed.h" #include <assert.h> @@ -29,7 +29,8 @@ #include <string.h> -#include "value-int.h" +#include "delayed-int.h" +#include "item.h" #include "../parsers/attribute.h" @@ -38,16 +39,16 @@ /* Initialise la classe des valeurs purement calculées. */ -static void g_record_value_class_init(GRecordValueClass *); +static void g_record_delayed_class_init(GRecordDelayedClass *); /* Initialise une correspondance entre attribut et binaire. */ -static void g_record_value_init(GRecordValue *); +static void g_record_delayed_init(GRecordDelayed *); /* Supprime toutes les références externes. */ -static void g_record_value_dispose(GRecordValue *); +static void g_record_delayed_dispose(GRecordDelayed *); /* Procède à la libération totale de la mémoire. */ -static void g_record_value_finalize(GRecordValue *); +static void g_record_delayed_finalize(GRecordDelayed *); @@ -55,7 +56,7 @@ static void g_record_value_finalize(GRecordValue *); /* Calcule ou fournit la zone couverte par une correspondance. */ -static void g_record_value_get_range(const GRecordValue *, mrange_t *); +static void g_record_delayed_get_range(const GRecordDelayed *, mrange_t *); @@ -65,7 +66,7 @@ static void g_record_value_get_range(const GRecordValue *, mrange_t *); /* Indique le type défini pour une valeur calculée selon des correspondances établies. */ -G_DEFINE_TYPE(GRecordValue, g_record_value, G_TYPE_MATCH_RECORD); +G_DEFINE_TYPE(GRecordDelayed, g_record_delayed, G_TYPE_MATCH_RECORD); /****************************************************************************** @@ -80,26 +81,26 @@ G_DEFINE_TYPE(GRecordValue, g_record_value, G_TYPE_MATCH_RECORD); * * ******************************************************************************/ -static void g_record_value_class_init(GRecordValueClass *klass) +static void g_record_delayed_class_init(GRecordDelayedClass *klass) { GObjectClass *object; /* Autre version de la classe */ GMatchRecordClass *record; /* Version parente de la classe*/ object = G_OBJECT_CLASS(klass); - object->dispose = (GObjectFinalizeFunc/* ! */)g_record_value_dispose; - object->finalize = (GObjectFinalizeFunc)g_record_value_finalize; + object->dispose = (GObjectFinalizeFunc/* ! */)g_record_delayed_dispose; + object->finalize = (GObjectFinalizeFunc)g_record_delayed_finalize; record = G_MATCH_RECORD_CLASS(klass); - record->get_range = (get_record_range_fc)g_record_value_get_range; + record->get_range = (get_record_range_fc)g_record_delayed_get_range; } /****************************************************************************** * * -* Paramètres : value = instance à initialiser. * +* Paramètres : delayed = instance à initialiser. * * * * Description : Initialise une correspondance entre attribut et binaire. * * * @@ -109,16 +110,18 @@ static void g_record_value_class_init(GRecordValueClass *klass) * * ******************************************************************************/ -static void g_record_value_init(GRecordValue *value) +static void g_record_delayed_init(GRecordDelayed *delayed) { - init_record_scope(&value->locals, NULL); + init_record_scope(&delayed->locals, NULL); + + delayed->real_record = NULL; } /****************************************************************************** * * -* Paramètres : value = instance d'objet GLib à traiter. * +* Paramètres : delayed = instance d'objet GLib à traiter. * * * * Description : Supprime toutes les références externes. * * * @@ -128,18 +131,18 @@ static void g_record_value_init(GRecordValue *value) * * ******************************************************************************/ -static void g_record_value_dispose(GRecordValue *value) +static void g_record_delayed_dispose(GRecordDelayed *delayed) { - reset_record_scope(&value->locals); + reset_record_scope(&delayed->locals); - G_OBJECT_CLASS(g_record_value_parent_class)->dispose(G_OBJECT(value)); + G_OBJECT_CLASS(g_record_delayed_parent_class)->dispose(G_OBJECT(delayed)); } /****************************************************************************** * * -* Paramètres : value = instance d'objet GLib à traiter. * +* Paramètres : delayed = instance d'objet GLib à traiter. * * * * Description : Procède à la libération totale de la mémoire. * * * @@ -149,17 +152,18 @@ static void g_record_value_dispose(GRecordValue *value) * * ******************************************************************************/ -static void g_record_value_finalize(GRecordValue *value) +static void g_record_delayed_finalize(GRecordDelayed *delayed) { - G_OBJECT_CLASS(g_record_value_parent_class)->finalize(G_OBJECT(value)); + G_OBJECT_CLASS(g_record_delayed_parent_class)->finalize(G_OBJECT(delayed)); } /****************************************************************************** * * -* Paramètres : inst = analyseur à l'origine de la correspondance. * -* locals = correspondances courantes pour résolutions. * +* Paramètres : inst = analyseur à l'origine de la correspondance. * +* locals = correspondances courantes pour résolutions. * +* content = contenu binaire lié à la correspondance. * * * * Description : Crée une nouvelle valeur calculée à partir d'une instance. * * * @@ -169,13 +173,13 @@ static void g_record_value_finalize(GRecordValue *value) * * ******************************************************************************/ -GRecordValue *g_record_value_new(GKaitaiInstance *inst, const kaitai_scope_t *locals) +GRecordDelayed *g_record_delayed_new(GKaitaiInstance *inst, const kaitai_scope_t *locals, GBinContent *content) { - GRecordValue *result; /* Structure à retourner */ + GRecordDelayed *result; /* Structure à retourner */ - result = g_object_new(G_TYPE_RECORD_VALUE, NULL); + result = g_object_new(G_TYPE_RECORD_DELAYED, NULL); - if (!g_record_value_create(result, inst, locals)) + if (!g_record_delayed_create(result, inst, locals, content)) g_clear_object(&result); return result; @@ -185,9 +189,10 @@ GRecordValue *g_record_value_new(GKaitaiInstance *inst, const kaitai_scope_t *lo /****************************************************************************** * * -* Paramètres : value = correspondance à initialiser pleinement. * -* inst = analyseur à l'origine de la correspondance. * -* locals = correspondances courantes pour résolutions. * +* Paramètres : delayed = correspondance à initialiser pleinement. * +* inst = analyseur à l'origine de la correspondance. * +* locals = correspondances courantes pour résolutions. * +* content = contenu binaire lié à la correspondance. * * * * Description : Met en place une valeur calculée à partir d'une instance. * * * @@ -197,14 +202,14 @@ GRecordValue *g_record_value_new(GKaitaiInstance *inst, const kaitai_scope_t *lo * * ******************************************************************************/ -bool g_record_value_create(GRecordValue *value, GKaitaiInstance *inst, const kaitai_scope_t *locals) +bool g_record_delayed_create(GRecordDelayed *delayed, GKaitaiInstance *inst, const kaitai_scope_t *locals, GBinContent *content) { bool result; /* Bilan à retourner */ - result = g_match_record_create(G_MATCH_RECORD(value), G_KAITAI_PARSER(inst), NULL); + result = g_match_record_create(G_MATCH_RECORD(delayed), G_KAITAI_PARSER(inst), content); if (result) - copy_record_scope(&value->locals, locals); + copy_record_scope(&delayed->locals, locals); return result; @@ -213,8 +218,8 @@ bool g_record_value_create(GRecordValue *value, GKaitaiInstance *inst, const kai /****************************************************************************** * * -* Paramètres : value = correspondance à consulter. * -* value = valeur à sauvegarder sous une forme générique. [OUT] * +* Paramètres : delayed = correspondance à consulter. * +* out = valeur à sauvegarder sous forme générique. [OUT] * * * * Description : Détermine la valeur d'un élément Kaitai calculé. * * * @@ -224,17 +229,36 @@ bool g_record_value_create(GRecordValue *value, GKaitaiInstance *inst, const kai * * ******************************************************************************/ -bool g_record_value_compute_value(const GRecordValue *value, resolved_value_t *out) +bool g_record_delayed_compute_value(GRecordDelayed *delayed, resolved_value_t *out) { bool result; /* Bilan à retourner */ GKaitaiParser *parser; /* Instance liée à l'élément */ - parser = g_match_record_get_creator(G_MATCH_RECORD(value)); + parser = g_match_record_get_creator(G_MATCH_RECORD(delayed)); assert(G_IS_KAITAI_ATTRIBUTE(parser)); - result = g_kaitai_instance_compute_value(G_KAITAI_INSTANCE(parser), - &value->locals, - out); + if (G_MATCH_RECORD(delayed)->content == NULL) + result = g_kaitai_instance_compute_value(G_KAITAI_INSTANCE(parser), + &delayed->locals, + out); + + else + { + if (delayed->real_record == NULL) + delayed->real_record = g_kaitai_instance_compute_real_record(G_KAITAI_INSTANCE(parser), + &delayed->locals, + G_MATCH_RECORD(delayed)->content); + + if (delayed->real_record == NULL) + result = false; + + else + { + assert(G_IS_RECORD_ITEM(delayed->real_record)); + result = g_record_item_get_value(G_RECORD_ITEM(delayed->real_record), out); + } + + } g_object_unref(G_OBJECT(parser)); @@ -245,8 +269,8 @@ bool g_record_value_compute_value(const GRecordValue *value, resolved_value_t *o /****************************************************************************** * * -* Paramètres : value = correspondance à consulter. * -* value = valeur à sauvegarder sous une forme générique. [OUT] * +* Paramètres : delayed = correspondance à consulter. * +* out = valeur à sauvegarder sous forme générique. [OUT] * * * * Description : Détermine et ajuste la valeur d'un élément Kaitai calculé. * * * @@ -256,20 +280,12 @@ bool g_record_value_compute_value(const GRecordValue *value, resolved_value_t *o * * ******************************************************************************/ -bool g_record_value_compute_and_aggregate_value(const GRecordValue *value, resolved_value_t *out) +bool g_record_delayed_compute_and_aggregate_value(GRecordDelayed *delayed, resolved_value_t *out) { bool result; /* Bilan à retourner */ - GKaitaiParser *parser; /* Instance liée à l'élément */ sized_string_t converted; /* Conversion finale ? */ - parser = g_match_record_get_creator(G_MATCH_RECORD(value)); - assert(G_IS_KAITAI_ATTRIBUTE(parser)); - - result = g_kaitai_instance_compute_value(G_KAITAI_INSTANCE(parser), - &value->locals, - out); - - g_object_unref(G_OBJECT(parser)); + result = g_record_delayed_compute_value(delayed, out); if (result) { @@ -318,7 +334,7 @@ bool g_record_value_compute_and_aggregate_value(const GRecordValue *value, resol /****************************************************************************** * * -* Paramètres : value = correspondance à consulter. * +* Paramètres : delayed = correspondance à consulter. * * range = zone de couverture déterminée. [OUT] * * * * Description : Calcule ou fournit la zone couverte par une correspondance. * @@ -329,7 +345,7 @@ bool g_record_value_compute_and_aggregate_value(const GRecordValue *value, resol * * ******************************************************************************/ -static void g_record_value_get_range(const GRecordValue *value, mrange_t *range) +static void g_record_delayed_get_range(const GRecordDelayed *delayed, mrange_t *range) { copy_mrange(range, UNUSED_MRANGE_PTR); diff --git a/plugins/kaitai/records/value.h b/plugins/kaitai/records/delayed.h index 8ee9cdd..e88bb6c 100644 --- a/plugins/kaitai/records/value.h +++ b/plugins/kaitai/records/delayed.h @@ -1,6 +1,6 @@ /* Chrysalide - Outil d'analyse de fichiers binaires - * value.h - prototypes pour la conservation d'une correspondance entre attribut et binaire + * delayed.h - prototypes pour la conservation d'une correspondance entre attribut et binaire * * Copyright (C) 2019 Cyrille Bagard * @@ -21,8 +21,8 @@ */ -#ifndef _PLUGINS_KAITAI_RECORDS_VALUE_H -#define _PLUGINS_KAITAI_RECORDS_VALUE_H +#ifndef _PLUGINS_KAITAI_RECORDS_DELAYED_H +#define _PLUGINS_KAITAI_RECORDS_DELAYED_H #include <glib-object.h> @@ -33,33 +33,33 @@ -#define G_TYPE_RECORD_VALUE g_record_value_get_type() -#define G_RECORD_VALUE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_RECORD_VALUE, GRecordValue)) -#define G_IS_RECORD_VALUE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_RECORD_VALUE)) -#define G_RECORD_VALUE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_RECORD_VALUE, GRecordValueClass)) -#define G_IS_RECORD_VALUE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_RECORD_VALUE)) -#define G_RECORD_VALUE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_RECORD_VALUE, GRecordValueClass)) +#define G_TYPE_RECORD_DELAYED g_record_delayed_get_type() +#define G_RECORD_DELAYED(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_RECORD_DELAYED, GRecordDelayed)) +#define G_IS_RECORD_DELAYED(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_RECORD_DELAYED)) +#define G_RECORD_DELAYED_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_RECORD_DELAYED, GRecordDelayedClass)) +#define G_IS_RECORD_DELAYED_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_RECORD_DELAYED)) +#define G_RECORD_DELAYED_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_RECORD_DELAYED, GRecordDelayedClass)) /* Valeur calculée selon des correspondances parallèles (instance) */ -typedef struct _GRecordValue GRecordValue; +typedef struct _GRecordDelayed GRecordDelayed; /* Valeur calculée selon des correspondances parallèles (classe) */ -typedef struct _GRecordValueClass GRecordValueClass; +typedef struct _GRecordDelayedClass GRecordDelayedClass; /* Indique le type défini pour une valeur calculée selon des correspondances établies. */ -GType g_record_value_get_type(void); +GType g_record_delayed_get_type(void); /* Crée une nouvelle valeur calculée à partir d'une instance. */ -GRecordValue *g_record_value_new(GKaitaiInstance *, const kaitai_scope_t *); +GRecordDelayed *g_record_delayed_new(GKaitaiInstance *, const kaitai_scope_t *, GBinContent *); /* Détermine la valeur d'un élément Kaitai entier calculé. */ -bool g_record_value_compute_value(const GRecordValue *, resolved_value_t *); +bool g_record_delayed_compute_value(GRecordDelayed *, resolved_value_t *); /* Détermine et ajuste la valeur d'un élément Kaitai calculé. */ -bool g_record_value_compute_and_aggregate_value(const GRecordValue *, resolved_value_t *); +bool g_record_delayed_compute_and_aggregate_value(GRecordDelayed *, resolved_value_t *); -#endif /* _PLUGINS_KAITAI_RECORDS_VALUE_H */ +#endif /* _PLUGINS_KAITAI_RECORDS_DELAYED_H */ |