summaryrefslogtreecommitdiff
path: root/plugins/yaml
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2023-02-04 16:36:10 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2023-02-04 16:36:10 (GMT)
commite85f35454bf94b7414dd9d2f5e6609601951293c (patch)
treef8cf3afe5b2ed34949878552b663d4b037e16238 /plugins/yaml
parentdb3b204dd7a71b2f74a4e69b2159a96e3ab66614 (diff)
Provide constructor to load Yaml contents without external files.
Diffstat (limited to 'plugins/yaml')
-rw-r--r--plugins/yaml/line.c5
-rw-r--r--plugins/yaml/line.h2
-rw-r--r--plugins/yaml/python/line.c3
-rw-r--r--plugins/yaml/python/reader.c151
-rw-r--r--plugins/yaml/reader-int.h61
-rw-r--r--plugins/yaml/reader.c171
-rw-r--r--plugins/yaml/reader.h4
7 files changed, 219 insertions, 178 deletions
diff --git a/plugins/yaml/line.c b/plugins/yaml/line.c
index 26a1012..3466bb8 100644
--- a/plugins/yaml/line.c
+++ b/plugins/yaml/line.c
@@ -177,6 +177,7 @@ static void g_yaml_line_finalize(GYamlLine *line)
/******************************************************************************
* *
* Paramètres : raw = contenu brut d'une ligne au format Yaml. *
+* rlen = taille de ce contenu brut. *
* number = indice associé à la ligne. *
* *
* Description : Met en place un gestionnaire pour ligne au format Yaml. *
@@ -187,7 +188,7 @@ static void g_yaml_line_finalize(GYamlLine *line)
* *
******************************************************************************/
-GYamlLine *g_yaml_line_new(const char *raw, size_t number)
+GYamlLine *g_yaml_line_new(const char *raw, size_t rlen, size_t number)
{
GYamlLine *result; /* Structure à retourner */
char *iter; /* Boucle de parcours */
@@ -196,7 +197,7 @@ GYamlLine *g_yaml_line_new(const char *raw, size_t number)
result = g_object_new(G_TYPE_YAML_LINE, NULL);
- result->raw = strdup(raw);
+ result->raw = strndup(raw, rlen);
result->number = number;
/* Indentation */
diff --git a/plugins/yaml/line.h b/plugins/yaml/line.h
index 00f019e..5a3f942 100644
--- a/plugins/yaml/line.h
+++ b/plugins/yaml/line.h
@@ -49,7 +49,7 @@ typedef struct _GYamlLineClass GYamlLineClass;
GType g_yaml_line_get_type(void);
/* Met en place un gestionnaire pour ligne au format Yaml. */
-GYamlLine *g_yaml_line_new(const char *, size_t);
+GYamlLine *g_yaml_line_new(const char *, size_t, size_t);
/* Fournit la taille de l'indentation d'une ligne Yaml. */
size_t g_yaml_line_count_indent(const GYamlLine *);
diff --git a/plugins/yaml/python/line.c b/plugins/yaml/python/line.c
index 11898d2..f098273 100644
--- a/plugins/yaml/python/line.c
+++ b/plugins/yaml/python/line.c
@@ -26,6 +26,7 @@
#include <pygobject.h>
+#include <string.h>
#include <plugins/pychrysalide/helpers.h>
@@ -92,7 +93,7 @@ static PyObject *py_yaml_line_new(PyTypeObject *type, PyObject *args, PyObject *
ret = PyArg_ParseTuple(args, "sn", &raw, &index);
if (!ret) return NULL;
- line = g_yaml_line_new(raw, index);
+ line = g_yaml_line_new(raw, strlen(raw), index);
if (line == NULL)
{
diff --git a/plugins/yaml/python/reader.c b/plugins/yaml/python/reader.c
index 74fd2b3..795b60c 100644
--- a/plugins/yaml/python/reader.c
+++ b/plugins/yaml/python/reader.c
@@ -28,25 +28,20 @@
#include <pygobject.h>
+#include <i18n.h>
+#include <plugins/pychrysalide/access.h>
#include <plugins/pychrysalide/helpers.h>
+#include <plugins/pychrysalide/analysis/content.h>
-#include "../reader.h"
+#include "../reader-int.h"
-#define YAML_READER_DOC \
- "YamlReader is the class which aims to provide a reader interface to Yaml content.\n" \
- "\n" \
- "When no input error, the Yaml content can be retrieved line by line or thanks to a tree."
+CREATE_DYN_CONSTRUCTOR(yaml_reader, G_TYPE_YAML_READER);
-
-
-/* Crée un lecteur pour contenu au format Yaml. */
-static PyObject *py_yaml_reader_new_from_content(PyObject *, PyObject *);
-
-/* Crée un lecteur pour contenu au format Yaml. */
-static PyObject *py_yaml_reader_new_from_path(PyObject *, PyObject *);
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_yaml_reader_init(PyObject *, PyObject *, PyObject *);
/* Fournit la liste des lignes lues depuis un contenu Yaml. */
static PyObject *py_yaml_reader_get_lines(PyObject *, void *);
@@ -58,108 +53,90 @@ static PyObject *py_yaml_reader_get_tree(PyObject *, void *);
/******************************************************************************
* *
-* Paramètres : self = variable non utilisée ici. *
+* Paramètres : self = objet à initialiser (théoriquement). *
* args = arguments fournis à l'appel. *
+* kwds = arguments de type key=val fournis. *
* *
-* Description : Crée un lecteur pour contenu au format Yaml. *
+* Description : Initialise une instance sur la base du dérivé de GObject. *
* *
-* Retour : Instance mise en place ou None en cas d'échec. *
+* Retour : 0. *
* *
* Remarques : - *
* *
******************************************************************************/
-static PyObject *py_yaml_reader_new_from_content(PyObject *self, PyObject *args)
+static int py_yaml_reader_init(PyObject *self, PyObject *args, PyObject *kwds)
{
- PyObject *result; /* Instance à retourner */
- const char *content; /* Contenu brut au format Yaml */
- Py_ssize_t length; /* Taille de ce contenu */
+ const char *text; /* Contenu de règles à traiter */
+ const char *filename; /* Fichier de définitions */
int ret; /* Bilan de lecture des args. */
GYamlReader *reader; /* Création GLib à transmettre */
-#define YAML_READER_NEW_FROM_CONTENT_METHOD PYTHON_METHOD_DEF \
-( \
- new_from_content, "content", \
- METH_STATIC | METH_VARARGS, py_yaml_reader, \
- "Load a Yaml content." \
-)
+ static char *kwlist[] = { "text", "filename", NULL };
- /**
- * La taille doit être de type 'int' et non 'Py_ssize_t', sinon les 32 bits
- * de poids fort ne sont pas initialisés !
- */
+#define YAML_READER_DOC \
+ "YamlReader is the class which aims to provide a reader interface" \
+ " to Yaml content.\n" \
+ "\n" \
+ "Instances can be created using one of the following" \
+ " constructors:\n" \
+ "\n" \
+ " YamlReader(text=str)" \
+ "\n" \
+ " YamlReader(filename=str)" \
+ "\n" \
+ "Where *text* is a string containg a markup content to parse;" \
+ " the *filename* argument is an alternative string for a path" \
+ " pointing to the same kind of content. This path can be a real" \
+ " filename or a resource URI." \
+ "\n" \
+ "When parsing is successful, the Yaml content can be retrieved" \
+ " line by line or thanks to a tree."
- ret = PyArg_ParseTuple(args, "s#", &content, &length);
- if (!ret) return NULL;
+ /* Récupération des paramètres */
- reader = g_yaml_reader_new_from_content(content, length);
+ text = NULL;
+ filename = NULL;
- if (reader == NULL)
- {
- result = Py_None;
- Py_INCREF(result);
- }
+ ret = PyArg_ParseTupleAndKeywords(args, kwds, "|ss", kwlist, &text, &filename);
+ if (!ret) return -1;
- else
- {
- g_object_ref_sink(G_OBJECT(reader));
- result = pygobject_new(G_OBJECT(reader));
- g_object_unref(reader);
- }
+ /* Initialisation d'un objet GLib */
- return result;
+ ret = forward_pygobjet_init(self);
+ if (ret == -1) return -1;
-}
+ /* Eléments de base */
+ reader = G_YAML_READER(pygobject_get(self));
-/******************************************************************************
-* *
-* Paramètres : self = variable non utilisée ici. *
-* args = arguments fournis à l'appel. *
-* *
-* Description : Crée un lecteur pour contenu au format Yaml. *
-* *
-* Retour : Instance mise en place ou None en cas d'échec. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static PyObject *py_yaml_reader_new_from_path(PyObject *self, PyObject *args)
-{
- PyObject *result; /* Instance à retourner */
- const char *path; /* Chemin d'accès à un contenu */
- int ret; /* Bilan de lecture des args. */
- GYamlReader *reader; /* Création GLib à transmettre */
-
-#define YAML_READER_NEW_FROM_PATH_METHOD PYTHON_METHOD_DEF \
-( \
- new_from_path, "path", \
- METH_STATIC | METH_VARARGS, py_yaml_reader, \
- "Load a Yaml content from a path.\n" \
- "\n" \
- "The path can be a filename or a resource URI." \
-)
-
- ret = PyArg_ParseTuple(args, "s", &path);
- if (!ret) return NULL;
+ if (text != NULL)
+ {
+ if (!g_yaml_reader_create_from_text(reader, text))
+ {
+ PyErr_SetString(PyExc_ValueError, _("Unable to create Yaml reader."));
+ return -1;
+ }
- reader = g_yaml_reader_new_from_path(path);
+ }
- if (reader == NULL)
+ else if (filename != NULL)
{
- result = Py_None;
- Py_INCREF(result);
+ if (!g_yaml_reader_create_from_file(reader, filename))
+ {
+ PyErr_SetString(PyExc_ValueError, _("Unable to create Yaml reader."));
+ return -1;
+ }
+
}
else
{
- g_object_ref_sink(G_OBJECT(reader));
- result = pygobject_new(G_OBJECT(reader));
- g_object_unref(reader);
+ PyErr_SetString(PyExc_ValueError, _("Unable to create empty Yaml reader."));
+ return -1;
}
- return result;
+ return 0;
}
@@ -281,8 +258,6 @@ static PyObject *py_yaml_reader_get_tree(PyObject *self, void *closure)
PyTypeObject *get_python_yaml_reader_type(void)
{
static PyMethodDef py_yaml_reader_methods[] = {
- YAML_READER_NEW_FROM_CONTENT_METHOD,
- YAML_READER_NEW_FROM_PATH_METHOD,
{ NULL }
};
@@ -305,7 +280,9 @@ PyTypeObject *get_python_yaml_reader_type(void)
.tp_methods = py_yaml_reader_methods,
.tp_getset = py_yaml_reader_getseters,
- .tp_new = no_python_constructor_allowed
+
+ .tp_init = py_yaml_reader_init,
+ .tp_new = py_yaml_reader_new,
};
diff --git a/plugins/yaml/reader-int.h b/plugins/yaml/reader-int.h
new file mode 100644
index 0000000..aa985a1
--- /dev/null
+++ b/plugins/yaml/reader-int.h
@@ -0,0 +1,61 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * reader-int.h - prototypes internes pour le lecteur de contenu Yaml
+ *
+ * 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_YAML_READER_INT_H
+#define PLUGINS_YAML_READER_INT_H
+
+
+#include "reader.h"
+
+
+
+/* Lecteur de contenu Yaml (instance) */
+struct _GYamlReader
+{
+ GObject parent; /* A laisser en premier */
+
+ GYamlLine **lines; /* Lignes Yaml chargées */
+ size_t count; /* Quantié de ces lignes */
+
+ GYamlTree *tree; /* Arborescence constituée */
+
+};
+
+/* Lecteur de contenu Yaml (classe) */
+struct _GYamlReaderClass
+{
+ GObjectClass parent; /* A laisser en premier */
+
+};
+
+
+
+/* Met en place un lecteur pour contenu au format Yaml. */
+bool g_yaml_reader_create_from_text(GYamlReader *, const char *);
+
+/* Met en place un lecteur pour contenu au format Yaml. */
+bool g_yaml_reader_create_from_file(GYamlReader *, const char *);
+
+
+
+#endif /* PLUGINS_YAML_READER_INT_H */
diff --git a/plugins/yaml/reader.c b/plugins/yaml/reader.c
index eebc02b..665e811 100644
--- a/plugins/yaml/reader.c
+++ b/plugins/yaml/reader.c
@@ -29,28 +29,12 @@
#include <gio/gio.h>
-#include "line.h"
-
-
-
-/* Lecteur de contenu Yaml (instance) */
-struct _GYamlReader
-{
- GObject parent; /* A laisser en premier */
-
- GYamlLine **lines; /* Lignes Yaml chargées */
- size_t count; /* Quantié de ces lignes */
+#include <analysis/contents/file.h>
- GYamlTree *tree; /* Arborescence constituée */
-};
-
-/* Lecteur de contenu Yaml (classe) */
-struct _GYamlReaderClass
-{
- GObjectClass parent; /* A laisser en premier */
+#include "line.h"
+#include "reader-int.h"
-};
/* Initialise la classe des lecteurs de contenus Yaml. */
@@ -167,8 +151,7 @@ static void g_yaml_reader_finalize(GYamlReader *reader)
/******************************************************************************
* *
-* Paramètres : content = données brutes au format Yaml à charger. *
-* length = quantité de ces données. *
+* Paramètres : text = définitions textuelles d'un contenu brut. *
* *
* Description : Crée un lecteur pour contenu au format Yaml. *
* *
@@ -178,39 +161,64 @@ static void g_yaml_reader_finalize(GYamlReader *reader)
* *
******************************************************************************/
-GYamlReader *g_yaml_reader_new_from_content(const char *content, size_t length)
+GYamlReader *g_yaml_reader_new_from_text(const char *text)
{
GYamlReader *result; /* Structure à retourner */
- char *dumped; /* Contenu manipulable */
- char *saved; /* Sauvegarde de position */
- char *iter; /* Boucle de parcours */
- size_t number; /* Indice de ligne courante */
- GYamlLine *line; /* Nouvelle ligne Yaml */
result = g_object_new(G_TYPE_YAML_READER, NULL);
- dumped = malloc(length * sizeof(char));
+ if (!g_yaml_reader_create_from_text(result, text))
+ g_clear_object(&result);
- memcpy(dumped, content, length);
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : reader = lecteur de définition à initialiser pleinement. *
+* text = définitions textuelles d'un contenu brut. *
+* *
+* Description : Met en place un lecteur pour contenu au format Yaml. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_yaml_reader_create_from_text(GYamlReader *reader, const char *text)
+{
+ bool result; /* Bilan à retourner */
+ const char *saved; /* Sauvegarde de position */
+ const char *iter; /* Boucle de parcours */
+ size_t number; /* Indice de ligne courante */
+ size_t rlen; /* Taille d'un contenu brut */
+ GYamlLine *line; /* Nouvelle ligne Yaml */
- for (iter = dumped, saved = strchr(iter, '\n'), number = 0;
+ result = false;
+
+ for (iter = text, saved = strchr(iter, '\n'), number = 0;
*iter != '\0';
iter = ++saved, saved = strchr(iter, '\n'), number++)
{
- if (saved != NULL)
- *saved = '\0';
+ if (saved == NULL)
+ rlen = strlen(iter);
+ else
+ rlen = saved - iter;
- if (*iter != '\0')
+ if (rlen > 0)
{
- line = g_yaml_line_new(iter, number);
+ line = g_yaml_line_new(iter, rlen, number);
if (line == NULL)
goto format_error;
- result->lines = realloc(result->lines, ++result->count * sizeof(GYamlLine *));
+ reader->lines = realloc(reader->lines, ++reader->count * sizeof(GYamlLine *));
g_object_ref_sink(G_OBJECT(line));
- result->lines[result->count - 1] = line;
+ reader->lines[reader->count - 1] = line;
}
@@ -219,24 +227,20 @@ GYamlReader *g_yaml_reader_new_from_content(const char *content, size_t length)
}
- free(dumped);
+ reader->tree = g_yaml_tree_new(reader->lines, reader->count);
- result->tree = g_yaml_tree_new(result->lines, result->count);
-
- return result;
+ result = (reader->tree != NULL);
format_error:
- g_object_unref(G_OBJECT(result));
-
- return NULL;
+ return result;
}
/******************************************************************************
* *
-* Paramètres : path = chemin d'accès à un contenu à charger. *
+* Paramètres : filename = chemin vers des définitions de règles. *
* *
* Description : Crée un lecteur pour contenu au format Yaml. *
* *
@@ -246,68 +250,65 @@ GYamlReader *g_yaml_reader_new_from_content(const char *content, size_t length)
* *
******************************************************************************/
-GYamlReader *g_yaml_reader_new_from_path(const char *path)
+GYamlReader *g_yaml_reader_new_from_file(const char *filename)
{
GYamlReader *result; /* Structure à retourner */
- char *scheme; /* Préfixe d'URI identifié */
- GFile *file; /* Accès au contenu visé */
- GFileInputStream *stream; /* Flux ouvert en lecture */
- GFileInfo *info; /* Informations du flux */
- size_t length; /* Quantité d'octets présents */
- char *content; /* Données obtenues par lecture*/
- result = NULL;
-
- /* Ouverture du fichier */
-
- scheme = g_uri_parse_scheme(path);
-
- if (scheme != NULL)
- {
- g_free(scheme);
- file = g_file_new_for_uri(path);
- }
-
- else
- file = g_file_new_for_path(path);
+ result = g_object_new(G_TYPE_YAML_READER, NULL);
- stream = g_file_read(file, NULL, NULL);
+ if (!g_yaml_reader_create_from_file(result, filename))
+ g_clear_object(&result);
- if (stream == NULL)
- goto no_content;
+ return result;
- /* Détermination de sa taille */
+}
- info = g_file_input_stream_query_info(stream, G_FILE_ATTRIBUTE_STANDARD_SIZE, NULL, NULL);
- if (info == NULL)
- goto no_size_info;
+/******************************************************************************
+* *
+* Paramètres : reader = lecteur de définition à initialiser pleinement. *
+* filename = chemin vers des définitions de règles. *
+* *
+* Description : Met en place un lecteur pour contenu au format Yaml. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
- length = g_file_info_get_size(info);
+bool g_yaml_reader_create_from_file(GYamlReader *reader, const char *filename)
+{
+ bool result; /* Bilan à retourner */
+ GBinContent *content; /* Fichier à parcourir */
+ phys_t size; /* Taille du contenu associé */
+ vmpa2t start; /* Tête de lecture */
+ const bin_t *data; /* Données à consulter */
+ char *dumped; /* Contenu manipulable */
- /* Lecture des données */
+ result = false;
- content = malloc(length + 1 * sizeof(char));
+ content = g_file_content_new(filename);
+ if (content == NULL) goto no_content;
- if (!g_input_stream_read_all(G_INPUT_STREAM(stream), content, length, (gsize []) { 0 }, NULL, NULL))
- goto read_error;
+ size = g_binary_content_compute_size(content);
- content[length] = '\0';
+ g_binary_content_compute_start_pos(content, &start);
+ data = g_binary_content_get_raw_access(content, &start, size);
- result = g_yaml_reader_new_from_content(content, length + 1);
+ dumped = malloc((size + 1) * sizeof(char));
- read_error:
+ memcpy(dumped, data, size);
+ dumped[size] = '\0';
- free(content);
+ result = g_yaml_reader_create_from_text(reader, dumped);
- no_size_info:
+ free(dumped);
- g_object_unref(G_OBJECT(stream));
+ g_object_unref(G_OBJECT(content));
no_content:
- g_object_unref(G_OBJECT(file));
-
return result;
}
diff --git a/plugins/yaml/reader.h b/plugins/yaml/reader.h
index 3e5ce48..51bd7e2 100644
--- a/plugins/yaml/reader.h
+++ b/plugins/yaml/reader.h
@@ -53,10 +53,10 @@ typedef struct _GYamlReaderClass GYamlReaderClass;
GType g_yaml_reader_get_type(void);
/* Crée un lecteur pour contenu au format Yaml. */
-GYamlReader *g_yaml_reader_new_from_content(const char *, size_t);
+GYamlReader *g_yaml_reader_new_from_text(const char *);
/* Crée un lecteur pour contenu au format Yaml. */
-GYamlReader *g_yaml_reader_new_from_path(const char *);
+GYamlReader *g_yaml_reader_new_from_file(const char *);
/* Fournit la liste des lignes lues depuis un contenu Yaml. */
GYamlLine **g_yaml_reader_get_lines(const GYamlReader *, size_t *);