summaryrefslogtreecommitdiff
path: root/plugins/kaitai/parsers
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2023-10-08 13:39:00 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2023-10-08 13:39:00 (GMT)
commit22d7a5277e2526514b8b01983f502c26aeff5747 (patch)
tree1acad2eded62412c5f7a4337830208094ed39323 /plugins/kaitai/parsers
parentcc43f73bbbdfd1cb6d7129c82e2d221181a3cac3 (diff)
Import external Kaitai definitions when needed.
Diffstat (limited to 'plugins/kaitai/parsers')
-rw-r--r--plugins/kaitai/parsers/meta-int.h3
-rw-r--r--plugins/kaitai/parsers/meta.c81
-rw-r--r--plugins/kaitai/parsers/meta.h3
-rw-r--r--plugins/kaitai/parsers/struct-int.h2
-rw-r--r--plugins/kaitai/parsers/struct.c68
-rw-r--r--plugins/kaitai/parsers/type-int.h3
-rw-r--r--plugins/kaitai/parsers/type.c58
-rw-r--r--plugins/kaitai/parsers/type.h3
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 *);