diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2023-10-08 13:39:00 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2023-10-08 13:39:00 (GMT) |
commit | 22d7a5277e2526514b8b01983f502c26aeff5747 (patch) | |
tree | 1acad2eded62412c5f7a4337830208094ed39323 /plugins/kaitai/parsers | |
parent | cc43f73bbbdfd1cb6d7129c82e2d221181a3cac3 (diff) |
Import external Kaitai definitions when needed.
Diffstat (limited to 'plugins/kaitai/parsers')
-rw-r--r-- | plugins/kaitai/parsers/meta-int.h | 3 | ||||
-rw-r--r-- | plugins/kaitai/parsers/meta.c | 81 | ||||
-rw-r--r-- | plugins/kaitai/parsers/meta.h | 3 | ||||
-rw-r--r-- | plugins/kaitai/parsers/struct-int.h | 2 | ||||
-rw-r--r-- | plugins/kaitai/parsers/struct.c | 68 | ||||
-rw-r--r-- | plugins/kaitai/parsers/type-int.h | 3 | ||||
-rw-r--r-- | plugins/kaitai/parsers/type.c | 58 | ||||
-rw-r--r-- | plugins/kaitai/parsers/type.h | 3 |
8 files changed, 216 insertions, 5 deletions
diff --git a/plugins/kaitai/parsers/meta-int.h b/plugins/kaitai/parsers/meta-int.h index 7d847ef..5fe9174 100644 --- a/plugins/kaitai/parsers/meta-int.h +++ b/plugins/kaitai/parsers/meta-int.h @@ -39,6 +39,9 @@ struct _GKaitaiMeta SourceEndian endian; /* Boutisme par défaut */ + char **dependencies; /* Définitions à importer */ + size_t dep_count; /* Nombre de ces définitions */ + }; /* Description globale d'une définition Kaitai (classe) */ diff --git a/plugins/kaitai/parsers/meta.c b/plugins/kaitai/parsers/meta.c index dc30c73..132eefd 100644 --- a/plugins/kaitai/parsers/meta.c +++ b/plugins/kaitai/parsers/meta.c @@ -97,6 +97,9 @@ static void g_kaitai_meta_init(GKaitaiMeta *meta) meta->endian = SRE_LITTLE; + meta->dependencies = NULL; + meta->dep_count = 0; + } @@ -133,12 +136,20 @@ static void g_kaitai_meta_dispose(GKaitaiMeta *meta) 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)); } @@ -188,6 +199,9 @@ 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; @@ -245,6 +259,45 @@ bool g_kaitai_meta_create(GKaitaiMeta *meta, GYamlNode *parent) } + /* 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; } @@ -279,7 +332,7 @@ const char *g_kaitai_meta_get_id(const GKaitaiMeta *meta) * * * Description : Fournit la désignation humaine d'une définiton Kaitai. * * * -* Retour : Intitulé de définition OU NULL. * +* Retour : Intitulé de définition ou NULL. * * * * Remarques : - * * * @@ -317,3 +370,29 @@ SourceEndian g_kaitai_meta_get_endian(const GKaitaiMeta *meta) 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; + +} diff --git a/plugins/kaitai/parsers/meta.h b/plugins/kaitai/parsers/meta.h index 3797823..b8b685d 100644 --- a/plugins/kaitai/parsers/meta.h +++ b/plugins/kaitai/parsers/meta.h @@ -63,6 +63,9 @@ const char *g_kaitai_meta_get_title(const GKaitaiMeta *); /* Indique le boustime observé par défaut par une définiton. */ SourceEndian g_kaitai_meta_get_endian(const GKaitaiMeta *); +/* Indique la liste des définitions à importer. */ +const char * const *g_kaitai_meta_get_dependencies(const GKaitaiMeta *, size_t *); + #endif /* _PLUGINS_KAITAI_PARSERS_META_H */ diff --git a/plugins/kaitai/parsers/struct-int.h b/plugins/kaitai/parsers/struct-int.h index f34be32..6eb6e53 100644 --- a/plugins/kaitai/parsers/struct-int.h +++ b/plugins/kaitai/parsers/struct-int.h @@ -37,6 +37,8 @@ struct _GKaitaiStruct { GKaitaiParser parent; /* A laisser en premier */ + char *filename; /* Eventuelle source de données*/ + GKaitaiMeta *meta; /* Description globale */ GKaitaiAttribute **seq_items; /* Sous-attributs présents */ diff --git a/plugins/kaitai/parsers/struct.c b/plugins/kaitai/parsers/struct.c index 128a788..07126c6 100644 --- a/plugins/kaitai/parsers/struct.c +++ b/plugins/kaitai/parsers/struct.c @@ -33,6 +33,7 @@ #include "struct-int.h" +#include "../import.h" #include "../parser.h" #include "../records/empty.h" #include "../records/group.h" @@ -54,6 +55,9 @@ static void g_kaitai_structure_dispose(GKaitaiStruct *); /* Procède à la libération totale de la mémoire. */ static void g_kaitai_structure_finalize(GKaitaiStruct *); +/* Charge les éventuelles dépendances de la définition. */ +static bool g_kaitai_structure_load_imports(GKaitaiStruct *); + /* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ @@ -116,6 +120,8 @@ static void g_kaitai_structure_class_init(GKaitaiStructClass *klass) static void g_kaitai_structure_init(GKaitaiStruct *kstruct) { + kstruct->filename = NULL; + kstruct->meta = NULL; kstruct->seq_items = NULL; @@ -182,6 +188,9 @@ static void g_kaitai_structure_dispose(GKaitaiStruct *kstruct) static void g_kaitai_structure_finalize(GKaitaiStruct *kstruct) { + if (kstruct->filename != NULL) + free(kstruct->filename); + if (kstruct->seq_items != NULL) free(kstruct->seq_items); @@ -305,6 +314,8 @@ bool g_kaitai_structure_create_from_file(GKaitaiStruct *kstruct, const char *fil bool result; /* Bilan à retourner */ GYamlNode *root; /* Noeud racine YAML */ + kstruct->filename = strdup(filename); + root = parse_yaml_from_file(filename); if (root != NULL) @@ -343,6 +354,7 @@ bool g_kaitai_structure_create(GKaitaiStruct *kstruct, GYamlNode *parent) GYamlNode **nodes; /* Eventuels noeuds trouvés */ size_t count; /* Quantité de ces noeuds */ size_t i; /* Boucle de parcours */ + size_t first; /* Premier emplacement dispo. */ bool failed; /* Détection d'un échec */ result = false; @@ -352,6 +364,9 @@ bool g_kaitai_structure_create(GKaitaiStruct *kstruct, GYamlNode *parent) kstruct->meta = g_kaitai_meta_new(parent); assert(kstruct->meta != NULL); + result = g_kaitai_structure_load_imports(kstruct); + if (!result) goto bad_loading; + /* Séquence */ collec = g_yaml_node_find_first_by_path(parent, "/seq/"); @@ -406,13 +421,15 @@ bool g_kaitai_structure_create(GKaitaiStruct *kstruct, GYamlNode *parent) if (count > 0) { - kstruct->types = calloc(count, sizeof(GKaitaiType *)); - kstruct->types_count = count; + first = kstruct->types_count; + + kstruct->types_count += count; + kstruct->types = realloc(kstruct->types, kstruct->types_count * sizeof(GKaitaiType *)); for (i = 0; i < count; i++) { - kstruct->types[i] = g_kaitai_type_new(nodes[i]); - if (kstruct->types[i] == NULL) break; + kstruct->types[first + i] = g_kaitai_type_new(nodes[i]); + if (kstruct->types[first + i] == NULL) break; g_object_unref(G_OBJECT(nodes[i])); @@ -529,6 +546,49 @@ bool g_kaitai_structure_create(GKaitaiStruct *kstruct, GYamlNode *parent) /****************************************************************************** * * +* Paramètres : kstruct = lecteur de définition à initialiser pleinement. * +* * +* Description : Charge les éventuelles dépendances de la définition. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_kaitai_structure_load_imports(GKaitaiStruct *kstruct) +{ + bool result; /* Bilan d'opération à renvoyer*/ + const char * const *dependencies; /* Liste d'imports requis */ + size_t count; /* Quantité de ces imports */ + size_t i; /* Boucle de parcours */ + GKaitaiType *imported; /* Structure importée */ + + result = true; + + dependencies = g_kaitai_meta_get_dependencies(kstruct->meta, &count); + + for (i = 0; i < count; i++) + { + imported = import_kaitai_definition(dependencies[i], kstruct->filename); + if (imported == NULL) break; + + kstruct->types_count++; + kstruct->types = realloc(kstruct->types, kstruct->types_count * sizeof(GKaitaiType *)); + + kstruct->types[kstruct->types_count - 1] = imported; + + } + + result = (i == count); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : kstruct = structure Kaitai à consulter. * * * * Description : Fournit la description globale d'une définition Kaitai. * diff --git a/plugins/kaitai/parsers/type-int.h b/plugins/kaitai/parsers/type-int.h index 4a4d939..535ce57 100644 --- a/plugins/kaitai/parsers/type-int.h +++ b/plugins/kaitai/parsers/type-int.h @@ -50,6 +50,9 @@ struct _GKaitaiTypeClass /* Met en place un lecteur de type pour Kaitai. */ bool g_kaitai_type_create(GKaitaiType *, GYamlNode *); +/* Met en place un lecteur de type externe pour Kaitai. */ +bool g_kaitai_type_create_as_import(GKaitaiType *, const char *, const char *); + #endif /* PLUGINS_KAITAI_PARSERS_TYPE_INT_H */ diff --git a/plugins/kaitai/parsers/type.c b/plugins/kaitai/parsers/type.c index 30d0373..81efbeb 100644 --- a/plugins/kaitai/parsers/type.c +++ b/plugins/kaitai/parsers/type.c @@ -215,6 +215,64 @@ bool g_kaitai_type_create(GKaitaiType *type, GYamlNode *parent) /****************************************************************************** * * +* Paramètres : name = nom à attribuer au futur type. * +* filename = chemin vers une définition Kaitai à charger. * +* * +* Description : Construit un lecteur de type externe pour Kaitai. * +* * +* Retour : Instance mise en place ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GKaitaiType *g_kaitai_type_new_as_import(const char *name, const char *filename) +{ + GKaitaiType *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_KAITAI_TYPE, NULL); + + if (!g_kaitai_type_create_as_import(result, name, filename)) + g_clear_object(&result); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : type = lecteur de type Kaitai à initialiser pleinement. * +* name = nom à attribuer au futur type. * +* filename = chemin vers une définition Kaitai à charger. * +* * +* Description : Met en place un lecteur de type externe pour Kaitai. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_kaitai_type_create_as_import(GKaitaiType *type, const char *name, const char *filename) +{ + bool result; /* Bilan à retourner */ + + /* Extraction du nom */ + + type->name = strdup(name); + + /* Extraction des bases du type */ + + result = g_kaitai_structure_create_from_file(G_KAITAI_STRUCT(type), filename); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : type = définition de type particulier à consulter. * * * * Description : Indique le nom de scène du type représenté. * diff --git a/plugins/kaitai/parsers/type.h b/plugins/kaitai/parsers/type.h index 0656c64..d19ab90 100644 --- a/plugins/kaitai/parsers/type.h +++ b/plugins/kaitai/parsers/type.h @@ -54,6 +54,9 @@ GType g_kaitai_type_get_type(void); /* Construit un lecteur de type pour Kaitai. */ GKaitaiType *g_kaitai_type_new(GYamlNode *); +/* Construit un lecteur de type externe pour Kaitai. */ +GKaitaiType *g_kaitai_type_new_as_import(const char *, const char *); + /* Indique le nom de scène du type représenté. */ const char *g_kaitai_type_get_name(const GKaitaiType *); |