From d9d887e226902905ef56d0ccf1107df50e5e4463 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Fri, 17 May 2024 07:50:05 +0200
Subject: Define datatypes.h and move the remaining endianness.[ch] content
 into io.[ch].

---
 src/arch/vmpa.h         |   5 +-
 src/common/Makefile.am  |   2 +-
 src/common/bits.h       |   3 +-
 src/common/datatypes.h  |  56 ++++
 src/common/endianness.c | 871 ------------------------------------------------
 src/common/endianness.h | 132 --------
 src/common/io.c         | 851 +++++++++++++++++++++++++++++++++++++++++++++-
 src/common/io.h         |  92 ++++-
 src/glibext/Makefile.am |   6 +-
 src/gtkext/Makefile.am  |   2 +-
 10 files changed, 1007 insertions(+), 1013 deletions(-)
 create mode 100644 src/common/datatypes.h
 delete mode 100644 src/common/endianness.c
 delete mode 100644 src/common/endianness.h

diff --git a/src/arch/vmpa.h b/src/arch/vmpa.h
index 4f35ebe..fe98ed4 100644
--- a/src/arch/vmpa.h
+++ b/src/arch/vmpa.h
@@ -32,6 +32,7 @@
 
 #include "archbase.h"
 #include "../common/cpp.h"
+#include "../common/datatypes.h"
 #include "../common/packed.h"
 #include "../common/sqlite.h"
 
@@ -48,8 +49,8 @@
 
 
 /* Types pour respectivement une position physique et une adresse virtuelle */
-#define phys_t uint64_t
-#define virt_t uint64_t
+//#define phys_t uint64_t
+//#define virt_t uint64_t
 
 /* Equivalents pour GLib */
 #define G_TYPE_PHYS uint64_t
diff --git a/src/common/Makefile.am b/src/common/Makefile.am
index 7da1a13..1c2d11a 100644
--- a/src/common/Makefile.am
+++ b/src/common/Makefile.am
@@ -11,7 +11,6 @@ libcommon_la_SOURCES =					\
 	cpp.h								\
 	cpu.h cpu.c							\
 	dllist.h dllist.c					\
-	endianness.h endianness.c			\
 	environment.h environment.c			\
 	extstr.h extstr.c					\
 	hex.h hex.c							\
@@ -56,6 +55,7 @@ libcommon4_la_SOURCES =						\
 	asm.h asm.c								\
 	bits.h bits.c							\
 	compiler.h								\
+	datatypes.h								\
 	environment.h environment.c				\
 	extstr.h extstr.c						\
 	io.h io.c								\
diff --git a/src/common/bits.h b/src/common/bits.h
index 608db39..a66c6f0 100644
--- a/src/common/bits.h
+++ b/src/common/bits.h
@@ -25,7 +25,8 @@
 #define _COMMON_BITS_H
 
 
-#include "../arch/vmpa.h"
+#include <stdbool.h>
+#include <sys/types.h>
 
 
 
diff --git a/src/common/datatypes.h b/src/common/datatypes.h
new file mode 100644
index 0000000..3983267
--- /dev/null
+++ b/src/common/datatypes.h
@@ -0,0 +1,56 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * datatypes.h - prototypes des définitions de base pour les données
+ *
+ * Copyright (C) 2024 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 _COMMON_DATATYPES_H
+#define _COMMON_DATATYPES_H
+
+
+#include <stdint.h>
+
+
+
+/* Octet de données binaires */
+typedef uint8_t bin_t;
+
+/* Types pour respectivement une position physique et une adresse virtuelle */
+typedef uint64_t phys_t;
+typedef uint64_t virt_t;
+
+
+#define NO_PHYSICAL ((phys_t)-1)
+#define NO_VIRTUAL  ((virt_t)-2)
+
+
+/* Type de boutismes existants */
+typedef enum _SourceEndian
+{
+    SRE_LITTLE,                             /* Petits boutistes            */
+    SRE_LITTLE_WORD,                        /* Moyens, façon Honeywell     */
+    SRE_BIG_WORD,                           /* Moyens, façon PDP-11        */
+    SRE_BIG                                 /* Gros boutistes              */
+
+} SourceEndian;
+
+
+
+#endif  /* _COMMON_DATATYPES_H */
diff --git a/src/common/endianness.c b/src/common/endianness.c
deleted file mode 100644
index 53dc19d..0000000
--- a/src/common/endianness.c
+++ /dev/null
@@ -1,871 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * endianness.c - manipulation abstraite des nombres
- *
- * Copyright (C) 2009-2018 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 "endianness.h"
-
-
-#include <assert.h>
-#include <stdarg.h>
-#include <string.h>
-
-
-
-/**
- * Mutualisation des aiguillages...
- */
-
-#if __BYTE_ORDER != __LITTLE_ENDIAN && __BYTE_ORDER != __BIG_ENDIAN
-
-    /* __PDP_ENDIAN et Cie... */
-#   error "Congratulations! Your byte order is not supported!"
-
-#endif
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/*                             CONVERSION ENTRE BOUTISMES                             */
-/* ---------------------------------------------------------------------------------- */
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : value  = valeur d'origine à manipuler.                       *
-*                endian = ordre des bits dans la source.                      *
-*                                                                             *
-*  Description : Adapte un nombre sur 16 bits à un boutisme donné.            *
-*                                                                             *
-*  Retour      : Valeur transformée au besoin.                                *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-uint16_t swap_u16(const uint16_t *value, SourceEndian endian)
-{
-    uint16_t result;                        /* Valeur à retourner          */
-
-    switch (endian)
-    {
-        case SRE_LITTLE:
-
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-
-            result = *value;
-
-#elif __BYTE_ORDER == __BIG_ENDIAN
-
-            result = ((*value >> 0) & 0xff) << 8 | ((*value >> 8) & 0xff) << 0;
-
-#endif
-
-            break;
-
-        case SRE_BIG:
-
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-
-            result = ((*value >> 0) & 0xff) << 8 | ((*value >> 8) & 0xff) << 0;
-
-#elif __BYTE_ORDER == __BIG_ENDIAN
-
-            result = *value;
-
-#endif
-
-            break;
-
-        default:
-            assert(false);
-            result = -1;
-            break;
-
-    }
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : value  = valeur d'origine à manipuler.                       *
-*                endian = ordre des bits dans la source.                      *
-*                                                                             *
-*  Description : Adapte un nombre sur 16 bits à un boutisme donné.            *
-*                                                                             *
-*  Retour      : Valeur transformée au besoin.                                *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-uint32_t swap_u32(const uint32_t *value, SourceEndian endian)
-{
-    uint32_t result;                        /* Valeur à retourner          */
-
-    switch (endian)
-    {
-        case SRE_LITTLE:
-
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-
-            result = *value;
-
-#elif __BYTE_ORDER == __BIG_ENDIAN
-
-            result = ((*value >>  0) & 0xff) << 24 | ((*value >>  8) & 0xff) << 16
-                   | ((*value >> 16) & 0xff) << 8  | ((*value >> 24) & 0xff) << 0;
-
-#endif
-
-            break;
-
-        case SRE_BIG:
-
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-
-            result = ((*value >>  0) & 0xff) << 24 | ((*value >>  8) & 0xff) << 16
-                   | ((*value >> 16) & 0xff) << 8  | ((*value >> 24) & 0xff) << 0;
-
-#elif __BYTE_ORDER == __BIG_ENDIAN
-
-            result = *value;
-
-#endif
-
-            break;
-
-        default:
-            assert(false);
-            result = -1;
-            break;
-
-    }
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : value  = valeur d'origine à manipuler.                       *
-*                endian = ordre des bits dans la source.                      *
-*                                                                             *
-*  Description : Adapte un nombre sur 16 bits à un boutisme donné.            *
-*                                                                             *
-*  Retour      : Valeur transformée au besoin.                                *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-uint64_t swap_u64(const uint64_t *value, SourceEndian endian)
-{
-    uint64_t result;                        /* Valeur à retourner          */
-
-    switch (endian)
-    {
-        case SRE_LITTLE:
-
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-
-            result = *value;
-
-#elif __BYTE_ORDER == __BIG_ENDIAN
-
-            result = ((*value >>  0) & 0xff) << 56 | ((*value >>  8) & 0xff) << 48
-                   | ((*value >> 16) & 0xff) << 40 | ((*value >> 24) & 0xff) << 32
-                   | ((*value >> 32) & 0xff) << 24 | ((*value >> 40) & 0xff) << 16
-                   | ((*value >> 48) & 0xff) << 8  | ((*value >> 56) & 0xff) << 0;
-
-#endif
-
-            break;
-
-        case SRE_BIG:
-
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-
-            result = ((*value >>  0) & 0xff) << 56 | ((*value >>  8) & 0xff) << 48
-                   | ((*value >> 16) & 0xff) << 40 | ((*value >> 24) & 0xff) << 32
-                   | ((*value >> 32) & 0xff) << 24 | ((*value >> 40) & 0xff) << 16
-                   | ((*value >> 48) & 0xff) << 8  | ((*value >> 56) & 0xff) << 0;
-
-#elif __BYTE_ORDER == __BIG_ENDIAN
-
-            result = *value;
-
-#endif
-
-            break;
-
-        default:
-            assert(false);
-            result = -1;
-            break;
-
-    }
-
-    return result;
-
-}
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/*                           BOUTISME DES ENTREES / SORTIES                           */
-/* ---------------------------------------------------------------------------------- */
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : target = lieu d'enregistrement de la lecture. [OUT]          *
-*                data   = flux de données à analyser.                         *
-*                pos    = position courante dans ce flux. [OUT]               *
-*                end    = limite des données à analyser.                      *
-*                low    = position éventuelle des 4 bits visés. [OUT]         *
-*                                                                             *
-*  Description : Lit un nombre non signé sur 4 bits.                          *
-*                                                                             *
-*  Retour      : Bilan de l'opération : true en cas de succès, false sinon.   *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool read_u4(uint8_t *target, const bin_t *data, phys_t *pos, phys_t end, bool *low)
-{
-    if (end < 1) return false;
-    if (*pos > (end - 1)) return false;
-
-    if (*low)
-    {
-        *target = data[*pos] & 0x0f;
-        *low = false;
-    }
-    else
-    {
-        *target = (data[*pos] & 0xf0) >> 4;
-        *low = true;
-        *pos += 1;
-    }
-
-    return true;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : target = lieu d'enregistrement de la lecture. [OUT]          *
-*                data   = flux de données à analyser.                         *
-*                pos    = position courante dans ce flux. [OUT]               *
-*                end    = limite des données à analyser.                      *
-*                                                                             *
-*  Description : Lit un nombre non signé sur un octet.                        *
-*                                                                             *
-*  Retour      : Bilan de l'opération : true en cas de succès, false sinon.   *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool read_u8(uint8_t *target, const bin_t *data, phys_t *pos, phys_t end)
-{
-    if (end < 1) return false;
-    if (*pos > (end - 1)) return false;
-
-    *target = data[*pos];
-
-    *pos += 1;
-
-    return true;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : target = lieu d'enregistrement de la lecture. [OUT]          *
-*                data   = flux de données à analyser.                         *
-*                pos    = position courante dans ce flux. [OUT]               *
-*                end    = limite des données à analyser.                      *
-*                endian = ordre des bits dans la source.                      *
-*                                                                             *
-*  Description : Lit un nombre non signé sur deux octets.                     *
-*                                                                             *
-*  Retour      : Bilan de l'opération : true en cas de succès, false sinon.   *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool read_u16(uint16_t *target, const bin_t *data, phys_t *pos, phys_t end, SourceEndian endian)
-{
-    if (end < 2) return false;
-    if (*pos > (end - 2)) return false;
-
-    switch (endian)
-    {
-        case SRE_LITTLE:
-
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-
-            *target = data[*pos] | (uint16_t)data[*pos + 1] << 8;
-
-#elif __BYTE_ORDER == __BIG_ENDIAN
-
-            *target = data[*pos + 1] | (uint16_t)data[*pos] << 8;
-
-#endif
-
-            break;
-
-        case SRE_LITTLE_WORD:
-
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-
-            *target = data[*pos] << 8 | (uint16_t)data[*pos + 1];
-
-#elif __BYTE_ORDER == __BIG_ENDIAN
-
-            *target = data[*pos + 1] << 8 | (uint16_t)data[*pos];
-
-#endif
-
-            break;
-
-        case SRE_BIG_WORD:
-
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-
-            *target = data[*pos + 1] << 8 | (uint16_t)data[*pos];
-
-#elif __BYTE_ORDER == __BIG_ENDIAN
-
-            *target = data[*pos] << 8 | (uint16_t)data[*pos + 1];
-
-#endif
-
-            break;
-
-        case SRE_BIG:
-
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-
-            *target = data[*pos + 1] | (uint16_t)data[*pos] << 8;
-
-#elif __BYTE_ORDER == __BIG_ENDIAN
-
-            *target = data[*pos] | (uint16_t)data[*pos + 1] << 8;
-
-#endif
-
-            break;
-
-        default:
-            return false;
-            break;
-
-    }
-
-    *pos += 2;
-
-    return true;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : target = lieu d'enregistrement de la lecture. [OUT]          *
-*                data   = flux de données à analyser.                         *
-*                pos    = position courante dans ce flux. [OUT]               *
-*                end    = limite des données à analyser.                      *
-*                endian = ordre des bits dans la source.                      *
-*                                                                             *
-*  Description : Lit un nombre non signé sur quatre octets.                   *
-*                                                                             *
-*  Retour      : Bilan de l'opération : true en cas de succès, false sinon.   *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool read_u32(uint32_t *target, const bin_t *data, phys_t *pos, phys_t end, SourceEndian endian)
-{
-    if (end < 4) return false;
-    if (*pos > (end - 4)) return false;
-
-    switch (endian)
-    {
-        case SRE_LITTLE:
-
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-
-            *target = data[*pos] | (uint32_t)data[*pos + 1] << 8;
-            *target |= data[*pos + 2] << 16 | (uint32_t)data[*pos + 3] << 24;
-
-#elif __BYTE_ORDER == __BIG_ENDIAN
-
-            *target = data[*pos + 3] | (uint32_t)data[*pos + 2] << 8;
-            *target |= data[*pos + 1] << 16 | (uint32_t)data[*pos] << 24;
-
-#endif
-
-            break;
-
-        case SRE_LITTLE_WORD:
-
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-
-            *target = data[*pos] << 8 | (uint32_t)data[*pos + 1];
-            *target |= data[*pos + 2] << 24 | (uint32_t)data[*pos + 3] << 16;
-
-#elif __BYTE_ORDER == __BIG_ENDIAN
-
-            *target = data[*pos + 3] << 8 | (uint32_t)data[*pos + 2];
-            *target |= data[*pos + 1] << 24 | (uint32_t)data[*pos] << 16;
-
-#endif
-
-            break;
-
-        case SRE_BIG_WORD:
-
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-
-            *target = data[*pos + 3] << 8 | (uint32_t)data[*pos + 2];
-            *target |= data[*pos + 1] << 24 | (uint32_t)data[*pos] << 16;
-
-#elif __BYTE_ORDER == __BIG_ENDIAN
-
-            *target = data[*pos] << 8 | (uint32_t)data[*pos + 1];
-            *target |= data[*pos + 2] << 24 | (uint32_t)data[*pos + 3] << 16;
-
-#endif
-
-            break;
-
-        case SRE_BIG:
-
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-
-            *target = data[*pos + 3] | (uint32_t)data[*pos + 2] << 8;
-            *target |= data[*pos + 1] << 16 | (uint32_t)data[*pos] << 24;
-
-#elif __BYTE_ORDER == __BIG_ENDIAN
-
-            *target = data[*pos] | (uint32_t)data[*pos + 1] << 8;
-            *target |= data[*pos + 2] << 16 | (uint32_t)data[*pos + 3] << 24;
-
-#endif
-
-            break;
-
-    default:
-        return false;
-        break;
-
-    }
-
-    *pos += 4;
-
-    return true;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : target = lieu d'enregistrement de la lecture. [OUT]          *
-*                data   = flux de données à analyser.                         *
-*                pos    = position courante dans ce flux. [OUT]               *
-*                end    = limite des données à analyser.                      *
-*                endian = ordre des bits dans la source.                      *
-*                                                                             *
-*  Description : Lit un nombre non signé sur huit octets.                     *
-*                                                                             *
-*  Retour      : Bilan de l'opération : true en cas de succès, false sinon.   *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool read_u64(uint64_t *target, const bin_t *data, phys_t *pos, phys_t end, SourceEndian endian)
-{
-    if (end < 8) return false;
-    if (*pos > (end - 8)) return false;
-
-    switch (endian)
-    {
-        case SRE_LITTLE:
-
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-
-            *target = (uint64_t)data[*pos] | (uint64_t)data[*pos + 1] << 8;
-            *target |= (uint64_t)data[*pos + 2] << 16 | (uint64_t)data[*pos + 3] << 24;
-            *target |= (uint64_t)data[*pos + 4] << 32 | (uint64_t)data[*pos + 5] << 40;
-            *target |= (uint64_t)data[*pos + 6] << 48 | (uint64_t)data[*pos + 7] << 56;
-
-#elif __BYTE_ORDER == __BIG_ENDIAN
-
-            *target = (uint64_t)data[*pos + 7] | (uint64_t)data[*pos + 6] << 8;
-            *target |= (uint64_t)data[*pos + 5] << 16 | (uint64_t)data[*pos + 4] << 24;
-            *target |= (uint64_t)data[*pos + 3] << 32 | (uint64_t)data[*pos + 2] << 40;
-            *target |= (uint64_t)data[*pos + 1] << 48 | (uint64_t)data[*pos] << 56;
-
-#endif
-
-            break;
-
-        case SRE_LITTLE_WORD:
-
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-
-            *target = (uint64_t)data[*pos] << 8 | (uint64_t)data[*pos + 1];
-            *target |= (uint64_t)data[*pos + 2] << 24 | (uint64_t)data[*pos + 3] << 16;
-            *target |= (uint64_t)data[*pos + 4] << 40 | (uint64_t)data[*pos + 5] << 32;
-            *target |= (uint64_t)data[*pos + 6] << 56 | (uint64_t)data[*pos + 7] << 48;
-
-#elif __BYTE_ORDER == __BIG_ENDIAN
-
-            *target = (uint64_t)data[*pos + 7] << 8 | (uint64_t)data[*pos + 6];
-            *target |= (uint64_t)data[*pos + 5] << 24 | (uint64_t)data[*pos + 4] << 16;
-            *target |= (uint64_t)data[*pos + 3] << 40 | (uint64_t)data[*pos + 2] << 32;
-            *target |= (uint64_t)data[*pos + 1] << 56 | (uint64_t)data[*pos] << 48;
-
-#endif
-
-            break;
-
-        case SRE_BIG_WORD:
-
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-
-            *target = (uint64_t)data[*pos + 7] << 8 | (uint64_t)data[*pos + 6];
-            *target |= (uint64_t)data[*pos + 5] << 24 | (uint64_t)data[*pos + 4] << 16;
-            *target |= (uint64_t)data[*pos + 3] << 40 | (uint64_t)data[*pos + 2] << 32;
-            *target |= (uint64_t)data[*pos + 1] << 56 | (uint64_t)data[*pos] << 48;
-
-#elif __BYTE_ORDER == __BIG_ENDIAN
-
-            *target = (uint64_t)data[*pos] << 8| (uint64_t)data[*pos + 1];
-            *target |= (uint64_t)data[*pos + 2] << 24 | (uint64_t)data[*pos + 3] << 16;
-            *target |= (uint64_t)data[*pos + 4] << 40 | (uint64_t)data[*pos + 5] << 32;
-            *target |= (uint64_t)data[*pos + 6] << 56 | (uint64_t)data[*pos + 7] << 48;
-
-#endif
-
-            break;
-
-        case SRE_BIG:
-
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-
-            *target = (uint64_t)data[*pos + 7] | (uint64_t)data[*pos + 6] << 8;
-            *target |= (uint64_t)data[*pos + 5] << 16 | (uint64_t)data[*pos + 4] << 24;
-            *target |= (uint64_t)data[*pos + 3] << 32 | (uint64_t)data[*pos + 2] << 40;
-            *target |= (uint64_t)data[*pos + 1] << 48 | (uint64_t)data[*pos] << 56;
-
-#elif __BYTE_ORDER == __BIG_ENDIAN
-
-            *target = (uint64_t)data[*pos] | (uint64_t)data[*pos + 1] << 8;
-            *target |= (uint64_t)data[*pos + 2] << 16 | (uint64_t)data[*pos + 3] << 24;
-            *target |= (uint64_t)data[*pos + 4] << 32 | (uint64_t)data[*pos + 5] << 40;
-            *target |= (uint64_t)data[*pos + 6] << 48 | (uint64_t)data[*pos + 7] << 56;
-
-#endif
-
-            break;
-
-        default:
-            return false;
-            break;
-
-    }
-
-    *pos += 8;
-
-    return true;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : value  = source de la valeur à transcrire.                   *
-*                size   = taille de cette source de données.                  *
-*                data   = flux de données à modifier. [OUT]                   *
-*                pos    = position courante dans ce flux. [OUT]               *
-*                end    = limite des données à analyser.                      *
-*                endian = ordre des bits dans la source.                      *
-*                                                                             *
-*  Description : Ecrit un nombre non signé sur n octets.                      *
-*                                                                             *
-*  Retour      : Bilan de l'opération : true en cas de succès, false sinon.   *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool _write_un(const bin_t *value, size_t size, bin_t *data, off_t *pos, off_t end, SourceEndian endian)
-{
-    size_t i;                               /* Boucle de parcours          */
-
-    if (end < size) return false;
-    if (*pos > (end - size)) return false;
-
-    switch (endian)
-    {
-        case SRE_LITTLE:
-
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-
-            memcpy(&data[*pos], value, size);
-            (*pos) += size;
-
-#elif __BYTE_ORDER == __BIG_ENDIAN
-
-            for (i = 0; i < size; i++, (*pos)++)
-                *(data + *pos) = *(value + size - i - 1);
-
-#endif
-
-            break;
-
-        case SRE_BIG:
-
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-
-            for (i = 0; i < size; i++, (*pos)++)
-                *(data + *pos) = *(value + size - i - 1);
-
-#elif __BYTE_ORDER == __BIG_ENDIAN
-
-            memcpy(&data[*pos], value, size);
-            (*pos) += size;
-
-#endif
-
-            break;
-
-        default:
-            return false;
-            break;
-
-    }
-
-    return true;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : target = lieu d'enregistrement de la lecture. [OUT]          *
-*                data   = flux de données à analyser.                         *
-*                pos    = position courante dans ce flux. [OUT]               *
-*                end    = limite des données à analyser.                      *
-*                endian = ordre des bits dans la source.                      *
-*                                                                             *
-*  Description : Lit un nombre hexadécimal non signé sur deux octets.         *
-*                                                                             *
-*  Retour      : Bilan de l'opération : true en cas de succès, false sinon.   *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool strtou8(uint8_t *target, const char *data, size_t *pos, size_t end, SourceEndian endian)
-{
-    size_t i;                               /* Boucle de parcours          */
-
-    if (end < 2) return false;
-    if (*pos > (end - 2)) return false;
-
-    *target = 0;
-
-    for (i = 0; i < 2; i++)
-        switch (data[*pos + i])
-        {
-            case '0' ... '9':
-                *target |= ((data[*pos + i] - '0') << (4 * (1 - i)));
-                break;
-
-            case 'A' ... 'F':
-                *target |= ((data[*pos + i] + 10 - 'A') << (4 * (1 - i)));
-                break;
-
-            case 'a' ... 'f':
-                *target |= ((data[*pos + i] + 10 - 'a') << (4 * (1 - i)));
-                break;
-
-        }
-
-    *pos += 2;
-
-    return true;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : n      = nombre d'octets constituant le nombre à lire.       *
-*                data   = flux de données à analyser.                         *
-*                pos    = position courante dans ce flux. [OUT]               *
-*                end    = limite des données à analyser.                      *
-*                endian = ordre des bits dans la source.                      *
-*                ...    = lieu d'enregistrement de la lecture. [OUT]          *
-*                                                                             *
-*  Description : Lit un nombre hexadécimal non signé sur n octets.            *
-*                                                                             *
-*  Retour      : Bilan de l'opération : true en cas de succès, false sinon.   *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool _strtoun(uint8_t n, const char *data, size_t *pos, size_t end, SourceEndian endian, ...)
-{
-    bool result;                            /* Bilan à renvoyer            */
-    va_list ap;                             /* Arguments variables         */
-    uint8_t *target8;                       /* Enregistrement sur 8 bits   */
-    uint16_t *target16;                     /* Enregistrement sur 16 bits  */
-    uint32_t *target32;                     /* Enregistrement sur 32 bits  */
-    uint64_t *target64;                     /* Enregistrement sur 64 bits  */
-    uint8_t i;                              /* Boucle de parcours #1       */
-    size_t j;                               /* Boucle de parcours #2       */
-    uint8_t tmp;                            /* Valeur temporaire de 8 bits */
-
-    if (end < (n * 2)) return false;
-    if (*pos > (end - (n * 2))) return false;
-
-    /* Récupération de la destination */
-
-    va_start(ap, endian);
-
-    switch (n)
-    {
-        case 1:
-            target8 = va_arg(ap, uint8_t *);
-            *target8 = 0;
-            target64 = (uint64_t *)target8;
-            break;
-        case 2:
-            target16 = va_arg(ap, uint16_t *);
-            *target16 = 0;
-            target64 = (uint64_t *)target16;
-            break;
-        case 4:
-            target32 = va_arg(ap, uint32_t *);
-            *target32 = 0;
-            target64 = (uint64_t *)target32;
-            break;
-        case 8:
-            target64 = va_arg(ap, uint64_t *);
-            *target64 = 0ull;
-            break;
-        default:
-            va_end(ap);
-            return false;
-            break;
-    }
-
-    va_end(ap);
-
-    /* Lecture des données */
-
-    result = true;
-
-    for (i = 0; i < n && result; i++)
-    {
-        tmp = 0;
-
-        for (j = 0; j < 2 && result; j++)
-            switch (data[*pos + j])
-            {
-                case '0' ... '9':
-                    tmp |= ((data[*pos + j] - '0') << (4 * (1 - j)));
-                    break;
-
-                case 'A' ... 'F':
-                    tmp |= ((data[*pos + j] + 10 - 'A') << (4 * (1 - j)));
-                    break;
-
-                case 'a' ... 'f':
-                    tmp |= ((data[*pos + j] + 10 - 'a') << (4 * (1 - j)));
-                    break;
-
-                default:
-                    result = false;
-                    break;
-
-            }
-
-        *pos += 2;
-
-        switch (endian)
-        {
-            case SRE_LITTLE:
-
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-
-                *target64 |= ((uint64_t)tmp) << (8 * i);
-
-#elif __BYTE_ORDER == __BIG_ENDIAN
-
-                *target64 |= ((uint64_t)tmp) << (8 * (n - 1 - i));
-
-#endif
-
-                break;
-
-            case SRE_BIG:
-
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-
-                *target64 |= ((uint64_t)tmp) << (8 * (n - 1 - i));
-
-#elif __BYTE_ORDER == __BIG_ENDIAN
-
-                *target64 |= ((uint64_t)tmp) << (8 * i);
-
-#endif
-
-                break;
-
-        default:
-            return false;
-            break;
-
-        }
-
-    }
-
-    return result;
-
-}
diff --git a/src/common/endianness.h b/src/common/endianness.h
deleted file mode 100644
index aabdb57..0000000
--- a/src/common/endianness.h
+++ /dev/null
@@ -1,132 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * endianness.h - prototypes pour la manipulation abstraite des nombres
- *
- * Copyright (C) 2009-2018 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 _COMMON_ENDIANNESS_H
-#define _COMMON_ENDIANNESS_H
-
-
-#include <stdbool.h>
-
-
-#include "../arch/archbase.h"
-#include "../arch/vmpa.h"
-
-
-
-/* Type de boutismes existants */
-typedef enum _SourceEndian
-{
-    SRE_LITTLE,                             /* Petits boutistes            */
-    SRE_LITTLE_WORD,                        /* Moyens, façon Honeywell     */
-    SRE_BIG_WORD,                           /* Moyens, façon PDP-11        */
-    SRE_BIG                                 /* Gros boutistes              */
-
-} SourceEndian;
-
-
-
-/* --------------------------- CONVERSION ENTRE BOUTISMES --------------------------- */
-
-
-/* Adapte un nombre sur 16 bits à un boutisme donné. */
-uint16_t swap_u16(const uint16_t *, SourceEndian);
-
-/* Adapte un nombre sur 16 bits à un boutisme donné. */
-uint32_t swap_u32(const uint32_t *, SourceEndian);
-
-/* Adapte un nombre sur 16 bits à un boutisme donné. */
-uint64_t swap_u64(const uint64_t *, SourceEndian);
-
-
-#define from_u16(v, e) swap_u16(v, e)
-#define from_u32(v, e) swap_u32(v, e)
-#define from_u64(v, e) swap_u64(v, e)
-
-
-#define to_u16(v, e) swap_u16(v, e)
-#define to_u32(v, e) swap_u32(v, e)
-#define to_u64(v, e) swap_u64(v, e)
-
-
-
-/* ------------------------- BOUTISME DES ENTREES / SORTIES ------------------------- */
-
-
-/* Lit un nombre non signé sur 4 bits. */
-bool read_u4(uint8_t *, const bin_t *, phys_t *, phys_t, bool *);
-
-/* Lit un nombre non signé sur un octet. */
-bool read_u8(uint8_t *, const bin_t *, phys_t *, phys_t);
-
-/* Lit un nombre non signé sur deux octets. */
-bool read_u16(uint16_t *, const bin_t *, phys_t *, phys_t, SourceEndian);
-
-/* Lit un nombre non signé sur quatre octets. */
-bool read_u32(uint32_t *, const bin_t *, phys_t *, phys_t, SourceEndian);
-
-/* Lit un nombre non signé sur huit octets. */
-bool read_u64(uint64_t *, const bin_t *, phys_t *, phys_t, SourceEndian);
-
-
-#define read_s4(target, data, pos, len, low) read_u4((uint8_t *)target, data, pos, len, low)
-#define read_s8(target, data, pos, len) read_u8((uint8_t *)target, data, pos, len)
-#define read_s16(target, data, pos, len, endian) read_u16((uint16_t *)target, data, pos, len, endian)
-#define read_s32(target, data, pos, len, endian) read_u32((uint32_t *)target, data, pos, len, endian)
-#define read_s64(target, data, pos, len, endian) read_u64((uint64_t *)target, data, pos, len, endian)
-
-
-/* Ecrit un nombre non signé sur n octets. */
-bool _write_un(const bin_t *, size_t, bin_t *, off_t *, off_t, SourceEndian);
-
-
-#define write_un(value, data, pos, len, endian, type)                       \
-    ({                                                                      \
-        type __tmp;                                                         \
-        (void)(value == &__tmp);                                            \
-        _write_un((bin_t *)value, sizeof(type), data, pos, len, endian);    \
-    })
-
-
-#define write_u8(value, data, pos, len, endian) write_un(value, data, pos, len, endian, uint8_t)
-#define write_u16(value, data, pos, len, endian) write_un(value, data, pos, len, endian, uint16_t)
-#define write_u32(value, data, pos, len, endian) write_un(value, data, pos, len, endian, uint32_t)
-#define write_u64(value, data, pos, len, endian) write_un(value, data, pos, len, endian, uint64_t)
-
-#define write_s8(value, data, pos, len, endian) write_un(value, data, pos, len, endian, sint8_t)
-#define write_s16(value, data, pos, len, endian) write_un(value, data, pos, len, endian, sint16_t)
-#define write_s32(value, data, pos, len, endian) write_un(value, data, pos, len, endian, sint32_t)
-#define write_s64(value, data, pos, len, endian) write_un(value, data, pos, len, endian, sint64_t)
-
-
-/* Lit un nombre hexadécimal non signé sur deux octets. */
-bool strtou8(uint8_t *, const char *, size_t *, size_t, SourceEndian);
-
-/* Lit un nombre hexadécimal non signé sur n octets. */
-bool _strtoun(uint8_t, const char *, size_t *, size_t, SourceEndian, ...);
-
-
-#define strtou32(target, data, pos, len, endian) _strtoun(4, data, pos, len, endian, target)
-
-
-
-#endif  /* _COMMON_ENDIANNESS_H */
diff --git a/src/common/io.c b/src/common/io.c
index 3208a2a..f325e7d 100644
--- a/src/common/io.c
+++ b/src/common/io.c
@@ -1,6 +1,6 @@
 
 /* Chrysalide - Outil d'analyse de fichiers binaires
- * io.c - entrées sorties fiables
+ * io.c - entrées sorties fiables et manipulation des nombres
  *
  * Copyright (C) 2014-2019 Cyrille Bagard
  *
@@ -24,8 +24,10 @@
 #include "io.h"
 
 
+#include <assert.h>
 #include <errno.h>
 #include <malloc.h>
+#include <stdarg.h>
 #include <stdint.h>
 #include <string.h>
 #include <unistd.h>
@@ -37,6 +39,24 @@
 
 
 
+/**
+ * Mutualisation des aiguillages...
+ */
+
+#if __BYTE_ORDER != __LITTLE_ENDIAN && __BYTE_ORDER != __BIG_ENDIAN
+
+    /* __PDP_ENDIAN et Cie... */
+#   error "Congratulations! Your byte order is not supported!"
+
+#endif
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                          ENTREES/SORTIES BRUTES ENCADREES                          */
+/* ---------------------------------------------------------------------------------- */
+
+
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : fd    = flux ouvert en lecture.                              *
@@ -284,3 +304,832 @@ bool safe_send(int sockfd, const void *buf, size_t len, int flags)
     return (remaining == 0);
 
 }
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                             CONVERSION ENTRE BOUTISMES                             */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : value  = valeur d'origine à manipuler.                       *
+*                endian = ordre des bits dans la source.                      *
+*                                                                             *
+*  Description : Adapte un nombre sur 16 bits à un boutisme donné.            *
+*                                                                             *
+*  Retour      : Valeur transformée au besoin.                                *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+uint16_t swap_u16(const uint16_t *value, SourceEndian endian)
+{
+    uint16_t result;                        /* Valeur à retourner          */
+
+    switch (endian)
+    {
+        case SRE_LITTLE:
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+            result = *value;
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+            result = ((*value >> 0) & 0xff) << 8 | ((*value >> 8) & 0xff) << 0;
+
+#endif
+
+            break;
+
+        case SRE_BIG:
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+            result = ((*value >> 0) & 0xff) << 8 | ((*value >> 8) & 0xff) << 0;
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+            result = *value;
+
+#endif
+
+            break;
+
+        default:
+            assert(false);
+            result = -1;
+            break;
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : value  = valeur d'origine à manipuler.                       *
+*                endian = ordre des bits dans la source.                      *
+*                                                                             *
+*  Description : Adapte un nombre sur 16 bits à un boutisme donné.            *
+*                                                                             *
+*  Retour      : Valeur transformée au besoin.                                *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+uint32_t swap_u32(const uint32_t *value, SourceEndian endian)
+{
+    uint32_t result;                        /* Valeur à retourner          */
+
+    switch (endian)
+    {
+        case SRE_LITTLE:
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+            result = *value;
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+            result = ((*value >>  0) & 0xff) << 24 | ((*value >>  8) & 0xff) << 16
+                   | ((*value >> 16) & 0xff) << 8  | ((*value >> 24) & 0xff) << 0;
+
+#endif
+
+            break;
+
+        case SRE_BIG:
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+            result = ((*value >>  0) & 0xff) << 24 | ((*value >>  8) & 0xff) << 16
+                   | ((*value >> 16) & 0xff) << 8  | ((*value >> 24) & 0xff) << 0;
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+            result = *value;
+
+#endif
+
+            break;
+
+        default:
+            assert(false);
+            result = -1;
+            break;
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : value  = valeur d'origine à manipuler.                       *
+*                endian = ordre des bits dans la source.                      *
+*                                                                             *
+*  Description : Adapte un nombre sur 16 bits à un boutisme donné.            *
+*                                                                             *
+*  Retour      : Valeur transformée au besoin.                                *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+uint64_t swap_u64(const uint64_t *value, SourceEndian endian)
+{
+    uint64_t result;                        /* Valeur à retourner          */
+
+    switch (endian)
+    {
+        case SRE_LITTLE:
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+            result = *value;
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+            result = ((*value >>  0) & 0xff) << 56 | ((*value >>  8) & 0xff) << 48
+                   | ((*value >> 16) & 0xff) << 40 | ((*value >> 24) & 0xff) << 32
+                   | ((*value >> 32) & 0xff) << 24 | ((*value >> 40) & 0xff) << 16
+                   | ((*value >> 48) & 0xff) << 8  | ((*value >> 56) & 0xff) << 0;
+
+#endif
+
+            break;
+
+        case SRE_BIG:
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+            result = ((*value >>  0) & 0xff) << 56 | ((*value >>  8) & 0xff) << 48
+                   | ((*value >> 16) & 0xff) << 40 | ((*value >> 24) & 0xff) << 32
+                   | ((*value >> 32) & 0xff) << 24 | ((*value >> 40) & 0xff) << 16
+                   | ((*value >> 48) & 0xff) << 8  | ((*value >> 56) & 0xff) << 0;
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+            result = *value;
+
+#endif
+
+            break;
+
+        default:
+            assert(false);
+            result = -1;
+            break;
+
+    }
+
+    return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                           BOUTISME DES ENTREES / SORTIES                           */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : target = lieu d'enregistrement de la lecture. [OUT]          *
+*                data   = flux de données à analyser.                         *
+*                pos    = position courante dans ce flux. [OUT]               *
+*                end    = limite des données à analyser.                      *
+*                low    = position éventuelle des 4 bits visés. [OUT]         *
+*                                                                             *
+*  Description : Lit un nombre non signé sur 4 bits.                          *
+*                                                                             *
+*  Retour      : Bilan de l'opération : true en cas de succès, false sinon.   *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool read_u4(uint8_t *target, const bin_t *data, phys_t *pos, phys_t end, bool *low)
+{
+    if (end < 1) return false;
+    if (*pos > (end - 1)) return false;
+
+    if (*low)
+    {
+        *target = data[*pos] & 0x0f;
+        *low = false;
+    }
+    else
+    {
+        *target = (data[*pos] & 0xf0) >> 4;
+        *low = true;
+        *pos += 1;
+    }
+
+    return true;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : target = lieu d'enregistrement de la lecture. [OUT]          *
+*                data   = flux de données à analyser.                         *
+*                pos    = position courante dans ce flux. [OUT]               *
+*                end    = limite des données à analyser.                      *
+*                                                                             *
+*  Description : Lit un nombre non signé sur un octet.                        *
+*                                                                             *
+*  Retour      : Bilan de l'opération : true en cas de succès, false sinon.   *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool read_u8(uint8_t *target, const bin_t *data, phys_t *pos, phys_t end)
+{
+    if (end < 1) return false;
+    if (*pos > (end - 1)) return false;
+
+    *target = data[*pos];
+
+    *pos += 1;
+
+    return true;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : target = lieu d'enregistrement de la lecture. [OUT]          *
+*                data   = flux de données à analyser.                         *
+*                pos    = position courante dans ce flux. [OUT]               *
+*                end    = limite des données à analyser.                      *
+*                endian = ordre des bits dans la source.                      *
+*                                                                             *
+*  Description : Lit un nombre non signé sur deux octets.                     *
+*                                                                             *
+*  Retour      : Bilan de l'opération : true en cas de succès, false sinon.   *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool read_u16(uint16_t *target, const bin_t *data, phys_t *pos, phys_t end, SourceEndian endian)
+{
+    if (end < 2) return false;
+    if (*pos > (end - 2)) return false;
+
+    switch (endian)
+    {
+        case SRE_LITTLE:
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+            *target = data[*pos] | (uint16_t)data[*pos + 1] << 8;
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+            *target = data[*pos + 1] | (uint16_t)data[*pos] << 8;
+
+#endif
+
+            break;
+
+        case SRE_LITTLE_WORD:
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+            *target = data[*pos] << 8 | (uint16_t)data[*pos + 1];
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+            *target = data[*pos + 1] << 8 | (uint16_t)data[*pos];
+
+#endif
+
+            break;
+
+        case SRE_BIG_WORD:
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+            *target = data[*pos + 1] << 8 | (uint16_t)data[*pos];
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+            *target = data[*pos] << 8 | (uint16_t)data[*pos + 1];
+
+#endif
+
+            break;
+
+        case SRE_BIG:
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+            *target = data[*pos + 1] | (uint16_t)data[*pos] << 8;
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+            *target = data[*pos] | (uint16_t)data[*pos + 1] << 8;
+
+#endif
+
+            break;
+
+        default:
+            return false;
+            break;
+
+    }
+
+    *pos += 2;
+
+    return true;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : target = lieu d'enregistrement de la lecture. [OUT]          *
+*                data   = flux de données à analyser.                         *
+*                pos    = position courante dans ce flux. [OUT]               *
+*                end    = limite des données à analyser.                      *
+*                endian = ordre des bits dans la source.                      *
+*                                                                             *
+*  Description : Lit un nombre non signé sur quatre octets.                   *
+*                                                                             *
+*  Retour      : Bilan de l'opération : true en cas de succès, false sinon.   *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool read_u32(uint32_t *target, const bin_t *data, phys_t *pos, phys_t end, SourceEndian endian)
+{
+    if (end < 4) return false;
+    if (*pos > (end - 4)) return false;
+
+    switch (endian)
+    {
+        case SRE_LITTLE:
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+            *target = data[*pos] | (uint32_t)data[*pos + 1] << 8;
+            *target |= data[*pos + 2] << 16 | (uint32_t)data[*pos + 3] << 24;
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+            *target = data[*pos + 3] | (uint32_t)data[*pos + 2] << 8;
+            *target |= data[*pos + 1] << 16 | (uint32_t)data[*pos] << 24;
+
+#endif
+
+            break;
+
+        case SRE_LITTLE_WORD:
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+            *target = data[*pos] << 8 | (uint32_t)data[*pos + 1];
+            *target |= data[*pos + 2] << 24 | (uint32_t)data[*pos + 3] << 16;
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+            *target = data[*pos + 3] << 8 | (uint32_t)data[*pos + 2];
+            *target |= data[*pos + 1] << 24 | (uint32_t)data[*pos] << 16;
+
+#endif
+
+            break;
+
+        case SRE_BIG_WORD:
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+            *target = data[*pos + 3] << 8 | (uint32_t)data[*pos + 2];
+            *target |= data[*pos + 1] << 24 | (uint32_t)data[*pos] << 16;
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+            *target = data[*pos] << 8 | (uint32_t)data[*pos + 1];
+            *target |= data[*pos + 2] << 24 | (uint32_t)data[*pos + 3] << 16;
+
+#endif
+
+            break;
+
+        case SRE_BIG:
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+            *target = data[*pos + 3] | (uint32_t)data[*pos + 2] << 8;
+            *target |= data[*pos + 1] << 16 | (uint32_t)data[*pos] << 24;
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+            *target = data[*pos] | (uint32_t)data[*pos + 1] << 8;
+            *target |= data[*pos + 2] << 16 | (uint32_t)data[*pos + 3] << 24;
+
+#endif
+
+            break;
+
+    default:
+        return false;
+        break;
+
+    }
+
+    *pos += 4;
+
+    return true;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : target = lieu d'enregistrement de la lecture. [OUT]          *
+*                data   = flux de données à analyser.                         *
+*                pos    = position courante dans ce flux. [OUT]               *
+*                end    = limite des données à analyser.                      *
+*                endian = ordre des bits dans la source.                      *
+*                                                                             *
+*  Description : Lit un nombre non signé sur huit octets.                     *
+*                                                                             *
+*  Retour      : Bilan de l'opération : true en cas de succès, false sinon.   *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool read_u64(uint64_t *target, const bin_t *data, phys_t *pos, phys_t end, SourceEndian endian)
+{
+    if (end < 8) return false;
+    if (*pos > (end - 8)) return false;
+
+    switch (endian)
+    {
+        case SRE_LITTLE:
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+            *target = (uint64_t)data[*pos] | (uint64_t)data[*pos + 1] << 8;
+            *target |= (uint64_t)data[*pos + 2] << 16 | (uint64_t)data[*pos + 3] << 24;
+            *target |= (uint64_t)data[*pos + 4] << 32 | (uint64_t)data[*pos + 5] << 40;
+            *target |= (uint64_t)data[*pos + 6] << 48 | (uint64_t)data[*pos + 7] << 56;
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+            *target = (uint64_t)data[*pos + 7] | (uint64_t)data[*pos + 6] << 8;
+            *target |= (uint64_t)data[*pos + 5] << 16 | (uint64_t)data[*pos + 4] << 24;
+            *target |= (uint64_t)data[*pos + 3] << 32 | (uint64_t)data[*pos + 2] << 40;
+            *target |= (uint64_t)data[*pos + 1] << 48 | (uint64_t)data[*pos] << 56;
+
+#endif
+
+            break;
+
+        case SRE_LITTLE_WORD:
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+            *target = (uint64_t)data[*pos] << 8 | (uint64_t)data[*pos + 1];
+            *target |= (uint64_t)data[*pos + 2] << 24 | (uint64_t)data[*pos + 3] << 16;
+            *target |= (uint64_t)data[*pos + 4] << 40 | (uint64_t)data[*pos + 5] << 32;
+            *target |= (uint64_t)data[*pos + 6] << 56 | (uint64_t)data[*pos + 7] << 48;
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+            *target = (uint64_t)data[*pos + 7] << 8 | (uint64_t)data[*pos + 6];
+            *target |= (uint64_t)data[*pos + 5] << 24 | (uint64_t)data[*pos + 4] << 16;
+            *target |= (uint64_t)data[*pos + 3] << 40 | (uint64_t)data[*pos + 2] << 32;
+            *target |= (uint64_t)data[*pos + 1] << 56 | (uint64_t)data[*pos] << 48;
+
+#endif
+
+            break;
+
+        case SRE_BIG_WORD:
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+            *target = (uint64_t)data[*pos + 7] << 8 | (uint64_t)data[*pos + 6];
+            *target |= (uint64_t)data[*pos + 5] << 24 | (uint64_t)data[*pos + 4] << 16;
+            *target |= (uint64_t)data[*pos + 3] << 40 | (uint64_t)data[*pos + 2] << 32;
+            *target |= (uint64_t)data[*pos + 1] << 56 | (uint64_t)data[*pos] << 48;
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+            *target = (uint64_t)data[*pos] << 8| (uint64_t)data[*pos + 1];
+            *target |= (uint64_t)data[*pos + 2] << 24 | (uint64_t)data[*pos + 3] << 16;
+            *target |= (uint64_t)data[*pos + 4] << 40 | (uint64_t)data[*pos + 5] << 32;
+            *target |= (uint64_t)data[*pos + 6] << 56 | (uint64_t)data[*pos + 7] << 48;
+
+#endif
+
+            break;
+
+        case SRE_BIG:
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+            *target = (uint64_t)data[*pos + 7] | (uint64_t)data[*pos + 6] << 8;
+            *target |= (uint64_t)data[*pos + 5] << 16 | (uint64_t)data[*pos + 4] << 24;
+            *target |= (uint64_t)data[*pos + 3] << 32 | (uint64_t)data[*pos + 2] << 40;
+            *target |= (uint64_t)data[*pos + 1] << 48 | (uint64_t)data[*pos] << 56;
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+            *target = (uint64_t)data[*pos] | (uint64_t)data[*pos + 1] << 8;
+            *target |= (uint64_t)data[*pos + 2] << 16 | (uint64_t)data[*pos + 3] << 24;
+            *target |= (uint64_t)data[*pos + 4] << 32 | (uint64_t)data[*pos + 5] << 40;
+            *target |= (uint64_t)data[*pos + 6] << 48 | (uint64_t)data[*pos + 7] << 56;
+
+#endif
+
+            break;
+
+        default:
+            return false;
+            break;
+
+    }
+
+    *pos += 8;
+
+    return true;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : value  = source de la valeur à transcrire.                   *
+*                size   = taille de cette source de données.                  *
+*                data   = flux de données à modifier. [OUT]                   *
+*                pos    = position courante dans ce flux. [OUT]               *
+*                end    = limite des données à analyser.                      *
+*                endian = ordre des bits dans la source.                      *
+*                                                                             *
+*  Description : Ecrit un nombre non signé sur n octets.                      *
+*                                                                             *
+*  Retour      : Bilan de l'opération : true en cas de succès, false sinon.   *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool _write_un(const bin_t *value, size_t size, bin_t *data, off_t *pos, off_t end, SourceEndian endian)
+{
+    size_t i;                               /* Boucle de parcours          */
+
+    if (end < size) return false;
+    if (*pos > (end - size)) return false;
+
+    switch (endian)
+    {
+        case SRE_LITTLE:
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+            memcpy(&data[*pos], value, size);
+            (*pos) += size;
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+            for (i = 0; i < size; i++, (*pos)++)
+                *(data + *pos) = *(value + size - i - 1);
+
+#endif
+
+            break;
+
+        case SRE_BIG:
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+            for (i = 0; i < size; i++, (*pos)++)
+                *(data + *pos) = *(value + size - i - 1);
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+            memcpy(&data[*pos], value, size);
+            (*pos) += size;
+
+#endif
+
+            break;
+
+        default:
+            return false;
+            break;
+
+    }
+
+    return true;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : target = lieu d'enregistrement de la lecture. [OUT]          *
+*                data   = flux de données à analyser.                         *
+*                pos    = position courante dans ce flux. [OUT]               *
+*                end    = limite des données à analyser.                      *
+*                endian = ordre des bits dans la source.                      *
+*                                                                             *
+*  Description : Lit un nombre hexadécimal non signé sur deux octets.         *
+*                                                                             *
+*  Retour      : Bilan de l'opération : true en cas de succès, false sinon.   *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool strtou8(uint8_t *target, const char *data, size_t *pos, size_t end, SourceEndian endian)
+{
+    size_t i;                               /* Boucle de parcours          */
+
+    if (end < 2) return false;
+    if (*pos > (end - 2)) return false;
+
+    *target = 0;
+
+    for (i = 0; i < 2; i++)
+        switch (data[*pos + i])
+        {
+            case '0' ... '9':
+                *target |= ((data[*pos + i] - '0') << (4 * (1 - i)));
+                break;
+
+            case 'A' ... 'F':
+                *target |= ((data[*pos + i] + 10 - 'A') << (4 * (1 - i)));
+                break;
+
+            case 'a' ... 'f':
+                *target |= ((data[*pos + i] + 10 - 'a') << (4 * (1 - i)));
+                break;
+
+        }
+
+    *pos += 2;
+
+    return true;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : n      = nombre d'octets constituant le nombre à lire.       *
+*                data   = flux de données à analyser.                         *
+*                pos    = position courante dans ce flux. [OUT]               *
+*                end    = limite des données à analyser.                      *
+*                endian = ordre des bits dans la source.                      *
+*                ...    = lieu d'enregistrement de la lecture. [OUT]          *
+*                                                                             *
+*  Description : Lit un nombre hexadécimal non signé sur n octets.            *
+*                                                                             *
+*  Retour      : Bilan de l'opération : true en cas de succès, false sinon.   *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool _strtoun(uint8_t n, const char *data, size_t *pos, size_t end, SourceEndian endian, ...)
+{
+    bool result;                            /* Bilan à renvoyer            */
+    va_list ap;                             /* Arguments variables         */
+    uint8_t *target8;                       /* Enregistrement sur 8 bits   */
+    uint16_t *target16;                     /* Enregistrement sur 16 bits  */
+    uint32_t *target32;                     /* Enregistrement sur 32 bits  */
+    uint64_t *target64;                     /* Enregistrement sur 64 bits  */
+    uint8_t i;                              /* Boucle de parcours #1       */
+    size_t j;                               /* Boucle de parcours #2       */
+    uint8_t tmp;                            /* Valeur temporaire de 8 bits */
+
+    if (end < (n * 2)) return false;
+    if (*pos > (end - (n * 2))) return false;
+
+    /* Récupération de la destination */
+
+    va_start(ap, endian);
+
+    switch (n)
+    {
+        case 1:
+            target8 = va_arg(ap, uint8_t *);
+            *target8 = 0;
+            target64 = (uint64_t *)target8;
+            break;
+        case 2:
+            target16 = va_arg(ap, uint16_t *);
+            *target16 = 0;
+            target64 = (uint64_t *)target16;
+            break;
+        case 4:
+            target32 = va_arg(ap, uint32_t *);
+            *target32 = 0;
+            target64 = (uint64_t *)target32;
+            break;
+        case 8:
+            target64 = va_arg(ap, uint64_t *);
+            *target64 = 0ull;
+            break;
+        default:
+            va_end(ap);
+            return false;
+            break;
+    }
+
+    va_end(ap);
+
+    /* Lecture des données */
+
+    result = true;
+
+    for (i = 0; i < n && result; i++)
+    {
+        tmp = 0;
+
+        for (j = 0; j < 2 && result; j++)
+            switch (data[*pos + j])
+            {
+                case '0' ... '9':
+                    tmp |= ((data[*pos + j] - '0') << (4 * (1 - j)));
+                    break;
+
+                case 'A' ... 'F':
+                    tmp |= ((data[*pos + j] + 10 - 'A') << (4 * (1 - j)));
+                    break;
+
+                case 'a' ... 'f':
+                    tmp |= ((data[*pos + j] + 10 - 'a') << (4 * (1 - j)));
+                    break;
+
+                default:
+                    result = false;
+                    break;
+
+            }
+
+        *pos += 2;
+
+        switch (endian)
+        {
+            case SRE_LITTLE:
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+                *target64 |= ((uint64_t)tmp) << (8 * i);
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+                *target64 |= ((uint64_t)tmp) << (8 * (n - 1 - i));
+
+#endif
+
+                break;
+
+            case SRE_BIG:
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+                *target64 |= ((uint64_t)tmp) << (8 * (n - 1 - i));
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+                *target64 |= ((uint64_t)tmp) << (8 * i);
+
+#endif
+
+                break;
+
+        default:
+            return false;
+            break;
+
+        }
+
+    }
+
+    return result;
+
+}
diff --git a/src/common/io.h b/src/common/io.h
index 82fb41e..7fe9d9d 100644
--- a/src/common/io.h
+++ b/src/common/io.h
@@ -1,6 +1,6 @@
 
 /* Chrysalide - Outil d'analyse de fichiers binaires
- * io.h - prototypes pour des entrées sorties fiables
+ * io.h - prototypes pour des entrées sorties fiables et la manipulation des nombres
  *
  * Copyright (C) 2014-2019 Cyrille Bagard
  *
@@ -29,6 +29,12 @@
 #include <sys/types.h>
 
 
+#include "datatypes.h"
+
+
+
+/* ------------------------ ENTREES/SORTIES BRUTES ENCADREES ------------------------ */
+
 
 /* Lit des données depuis un flux local. */
 bool safe_read(int, void *, size_t);
@@ -47,4 +53,88 @@ bool safe_send(int, const void *, size_t, int);
 
 
 
+/* --------------------------- CONVERSION ENTRE BOUTISMES --------------------------- */
+
+
+/* Adapte un nombre sur 16 bits à un boutisme donné. */
+uint16_t swap_u16(const uint16_t *, SourceEndian);
+
+/* Adapte un nombre sur 16 bits à un boutisme donné. */
+uint32_t swap_u32(const uint32_t *, SourceEndian);
+
+/* Adapte un nombre sur 16 bits à un boutisme donné. */
+uint64_t swap_u64(const uint64_t *, SourceEndian);
+
+
+#define from_u16(v, e) swap_u16(v, e)
+#define from_u32(v, e) swap_u32(v, e)
+#define from_u64(v, e) swap_u64(v, e)
+
+
+#define to_u16(v, e) swap_u16(v, e)
+#define to_u32(v, e) swap_u32(v, e)
+#define to_u64(v, e) swap_u64(v, e)
+
+
+
+/* ------------------------- BOUTISME DES ENTREES / SORTIES ------------------------- */
+
+
+/* Lit un nombre non signé sur 4 bits. */
+bool read_u4(uint8_t *, const bin_t *, phys_t *, phys_t, bool *);
+
+/* Lit un nombre non signé sur un octet. */
+bool read_u8(uint8_t *, const bin_t *, phys_t *, phys_t);
+
+/* Lit un nombre non signé sur deux octets. */
+bool read_u16(uint16_t *, const bin_t *, phys_t *, phys_t, SourceEndian);
+
+/* Lit un nombre non signé sur quatre octets. */
+bool read_u32(uint32_t *, const bin_t *, phys_t *, phys_t, SourceEndian);
+
+/* Lit un nombre non signé sur huit octets. */
+bool read_u64(uint64_t *, const bin_t *, phys_t *, phys_t, SourceEndian);
+
+
+#define read_s4(target, data, pos, len, low) read_u4((uint8_t *)target, data, pos, len, low)
+#define read_s8(target, data, pos, len) read_u8((uint8_t *)target, data, pos, len)
+#define read_s16(target, data, pos, len, endian) read_u16((uint16_t *)target, data, pos, len, endian)
+#define read_s32(target, data, pos, len, endian) read_u32((uint32_t *)target, data, pos, len, endian)
+#define read_s64(target, data, pos, len, endian) read_u64((uint64_t *)target, data, pos, len, endian)
+
+
+/* Ecrit un nombre non signé sur n octets. */
+bool _write_un(const bin_t *, size_t, bin_t *, off_t *, off_t, SourceEndian);
+
+
+#define write_un(value, data, pos, len, endian, type)                       \
+    ({                                                                      \
+        type __tmp;                                                         \
+        (void)(value == &__tmp);                                            \
+        _write_un((bin_t *)value, sizeof(type), data, pos, len, endian);    \
+    })
+
+
+#define write_u8(value, data, pos, len, endian) write_un(value, data, pos, len, endian, uint8_t)
+#define write_u16(value, data, pos, len, endian) write_un(value, data, pos, len, endian, uint16_t)
+#define write_u32(value, data, pos, len, endian) write_un(value, data, pos, len, endian, uint32_t)
+#define write_u64(value, data, pos, len, endian) write_un(value, data, pos, len, endian, uint64_t)
+
+#define write_s8(value, data, pos, len, endian) write_un(value, data, pos, len, endian, sint8_t)
+#define write_s16(value, data, pos, len, endian) write_un(value, data, pos, len, endian, sint16_t)
+#define write_s32(value, data, pos, len, endian) write_un(value, data, pos, len, endian, sint32_t)
+#define write_s64(value, data, pos, len, endian) write_un(value, data, pos, len, endian, sint64_t)
+
+
+/* Lit un nombre hexadécimal non signé sur deux octets. */
+bool strtou8(uint8_t *, const char *, size_t *, size_t, SourceEndian);
+
+/* Lit un nombre hexadécimal non signé sur n octets. */
+bool _strtoun(uint8_t, const char *, size_t *, size_t, SourceEndian, ...);
+
+
+#define strtou32(target, data, pos, len, endian) _strtoun(4, data, pos, len, endian, target)
+
+
+
 #endif  /* _COMMON_IO_H */
diff --git a/src/glibext/Makefile.am b/src/glibext/Makefile.am
index 58ddb93..860f3b9 100644
--- a/src/glibext/Makefile.am
+++ b/src/glibext/Makefile.am
@@ -48,8 +48,8 @@ endif
 
 libglibext_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS)
 
-libglibext_la_LIBADD = 					\
-	generators/libglibextgenerators.la
+#libglibext_la_LIBADD = 					\
+#	generators/libglibextgenerators.la
 
 
 libglibext4_la_SOURCES =					\
@@ -63,7 +63,7 @@ devdir = $(includedir)/chrysalide/$(subdir:src/%=core/%)
 dev_HEADERS = $(libglibext_la_SOURCES:%c=)
 
 
-SUBDIRS = generators
+#SUBDIRS = generators
 
 
 chrysamarshal.h: chrysamarshal.list
diff --git a/src/gtkext/Makefile.am b/src/gtkext/Makefile.am
index 45c9a1c..9d3d16c 100644
--- a/src/gtkext/Makefile.am
+++ b/src/gtkext/Makefile.am
@@ -53,7 +53,7 @@ devdir = $(includedir)/chrysalide/$(subdir:src/%=core/%)
 dev_HEADERS = $(libgtkext_la_SOURCES:%c=)
 
 
-SUBDIRS = graph
+#SUBDIRS = graph
 
 
 resources.c: gresource.xml $(UI_FILES_4_)
-- 
cgit v0.11.2-87-g4458