summaryrefslogtreecommitdiff
path: root/src/glibext/gbuffercache.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2020-07-23 11:21:16 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2020-07-23 11:21:16 (GMT)
commit19516ffcca14abb082c5109125b7249bdc7fc199 (patch)
tree5fec885bae9e08154e133a8302bfdd00397126cc /src/glibext/gbuffercache.c
parentb806230a94be8d3cefb79d7756c95660033596b2 (diff)
Renamed some files.
Diffstat (limited to 'src/glibext/gbuffercache.c')
-rw-r--r--src/glibext/gbuffercache.c1725
1 files changed, 0 insertions, 1725 deletions
diff --git a/src/glibext/gbuffercache.c b/src/glibext/gbuffercache.c
deleted file mode 100644
index b54de26..0000000
--- a/src/glibext/gbuffercache.c
+++ /dev/null
@@ -1,1725 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * gbuffercache.c - affichage à la demande d'un ensemble de lignes
- *
- * Copyright (C) 2016-2019 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 "gbuffercache.h"
-
-
-#include <assert.h>
-#include <malloc.h>
-#include <stdlib.h>
-
-
-#include "gbuffercache-int.h"
-#include "chrysamarshal.h"
-
-
-
-/* --------------------- FONCTIONS AUXILIAIRES DE MANIPULATIONS --------------------- */
-
-
-/* Gros verrou global pour alléger les structures... */
-G_LOCK_DEFINE_STATIC(_line_update);
-
-
-/* Met en place un nouvel ensemble d'information sur une ligne. */
-static void init_cache_info(cache_info *, GLineGenerator *, size_t, BufferLineFlags);
-
-/* Libère la mémoire occupée par des informations sur une ligne. */
-static void release_cache_info(cache_info *);
-
-/* Ajoute un générateur aux informations sur une ligne. */
-static void extend_cache_info(cache_info *, GLineGenerator *, BufferLineFlags);
-
-/* Retire un générateur aux informations d'une ligne. */
-static void remove_from_cache_info(cache_info *, GLineGenerator *);
-
-/* Retrouve l'emplacement correspondant à une position de ligne. */
-static void get_cache_info_cursor(const cache_info *, size_t, gint, GLineCursor **);
-
-/* Suivit les variations du compteur de références d'une ligne. */
-static void on_line_ref_toggle(cache_info *, GBufferLine *, gboolean);
-
-/* Fournit la ligne de tampon correspondant aux générateurs. */
-static GBufferLine *get_cache_info_line(cache_info *, size_t, const GBinContent *);
-
-/* Force la réinitialisation d'une éventuelle ligne cachée. */
-static void _reset_cache_info_line_unlocked(cache_info *);
-
-/* Force la réinitialisation d'une éventuelle ligne cachée. */
-static void reset_cache_info_line(cache_info *);
-
-
-
-/* -------------------------- TAMPON POUR CODE DESASSEMBLE -------------------------- */
-
-
-/* Taille des allocations de masse */
-#define LINE_ALLOC_BULK 1000
-
-
-/* Procède à l'initialisation d'une classe de tampon de lignes. */
-static void g_buffer_cache_class_init(GBufferCacheClass *);
-
-/* Procède à l'initialisation d'un tampon de gestion de lignes. */
-static void g_buffer_cache_init(GBufferCache *);
-
-/* Supprime toutes les références externes. */
-static void g_buffer_cache_dispose(GBufferCache *);
-
-/* Procède à la libération totale de la mémoire. */
-static void g_buffer_cache_finalize(GBufferCache *);
-
-/* Calcule l'indice d'apparition d'un générateur dans le tampon. */
-static size_t g_buffer_cache_compute_repetition(GBufferCache *, size_t, GLineGenerator *);
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/* FONCTIONS AUXILIAIRES DE MANIPULATIONS */
-/* ---------------------------------------------------------------------------------- */
-
-
-/******************************************************************************
-* *
-* Paramètres : info = informations concernant une ligne à constituer. *
-* generator = générateur à associer à toutes les lignes. *
-* repeat = compteur de répétition entre les lignes. *
-* flags = propriétés supplémentaires à associer à la ligne.*
-* *
-* Description : Met en place un nouvel ensemble d'information sur une ligne. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void init_cache_info(cache_info *info, GLineGenerator *generator, size_t repeat, BufferLineFlags flags)
-{
- info->generator.instance = generator;
- info->generator.repeat = repeat;
-
- g_object_ref(G_OBJECT(generator));
-
- info->count = 1;
-
- info->line = NULL;
-
- info->extra_flags = flags;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : info = informations concernant une ligne à constituer. *
-* *
-* Description : Libère la mémoire occupée par des informations sur une ligne.*
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void release_cache_info(cache_info *info)
-{
- size_t i; /* Boucle de parcours */
-
- if (info->count == 1)
- g_object_unref(G_OBJECT(info->generator.instance));
-
- else
- for (i = 0; i < info->count; i++)
- g_object_unref(G_OBJECT(info->generators[i].instance));
-
- reset_cache_info_line(info);
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : info = informations concernant une ligne à actualiser. *
-* generator = générateur à associer à toutes les lignes. *
-* flags = propriétés supplémentaires à associer à la ligne.*
-* *
-* Description : Ajoute un générateur aux informations sur une ligne. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void extend_cache_info(cache_info *info, GLineGenerator *generator, BufferLineFlags flags)
-{
- generator_link first; /* Générateur déjà en place */
- generator_link *new; /* Nouveau générateur placé */
-
- if (info->count == 1)
- {
- first = info->generator;
-
- info->generators = (generator_link *)calloc(2, sizeof(generator_link));
-
- info->generators[0] = first;
- info->count = 2;
-
- new = &info->generators[1];
-
- }
- else
- {
- info->generators = (generator_link *)realloc(info->generators,
- ++info->count * sizeof(generator_link));
-
- new = &info->generators[info->count - 1];
-
- }
-
- new->instance = generator;
- new->repeat = 0;
-
- g_object_ref(G_OBJECT(generator));
-
- reset_cache_info_line(info);
-
- /**
- * On peut rajouter des indications, mais, en cas de retrait d'un générateur,
- * on ne saura pas forcément lesquelles retirer puisque qu'on ne trace pas
- * leur origine.
- *
- * On considère donc que seul le premier générateur (le principal) a le
- * droit de poser des fanions.
- */
-
- assert(flags == BLF_NONE);
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : info = informations concernant une ligne à actualiser. *
-* generator = générateur à dissocier de toutes les lignes. *
-* *
-* Description : Retire un générateur aux informations d'une ligne. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void remove_from_cache_info(cache_info *info, GLineGenerator *generator)
-{
- generator_link *link; /* Accès simplifié */
- size_t i; /* Boucle de parcours */
- generator_link *old; /* Mémorisation avant opérat° */
-
- if (info->count == 1)
- {
- link = &info->generator;
-
- assert(link->instance == generator);
-
- g_object_unref(G_OBJECT(generator));
-
- info->count = 0;
-
- }
-
- else
- {
- for (i = 0; i < info->count; i++)
- {
- link = &info->generators[i];
-
- if (link->instance == generator)
- {
- if ((i + 1) < info->count)
- memmove(&info->generators[i], &info->generators[i + 1],
- (info->count - i - 1) * sizeof(generator_link));
-
- if (info->count == 2)
- {
- old = info->generators;
-
- info->count = 1;
- info->generator = info->generators[0];
-
- free(old);
-
- }
- else
- info->generators = (generator_link *)realloc(info->generators,
- --info->count * sizeof(generator_link));
-
- g_object_unref(G_OBJECT(generator));
-
- break;
-
- }
-
- }
-
-#ifndef NDEBUG
-
- /**
- * Attention : si l'élément était en dernière position,
- * l'indice de parcours est désormais égal au nombre de générateurs présents !
- */
- assert(i <= info->count);
-
- for ( ; i < info->count; i++)
- {
- link = &info->generators[i];
-
- assert(link->instance != generator);
-
- }
-
-#endif
-
- }
-
- reset_cache_info_line(info);
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : info = informations sur une ligne à venir consulter. *
-* index = indice de la ligne visée par la consultation. *
-* x = position géographique sur la ligne concernée. *
-* cursor = emplacement à constituer. [OUT] *
-* *
-* Description : Retrouve l'emplacement correspondant à une position de ligne.*
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void get_cache_info_cursor(const cache_info *info, size_t index, gint x, GLineCursor **cursor)
-{
- const generator_link *generator; /* Générateur retenu */
-
- if (info->count == 1)
- generator = &info->generator;
- else
- generator = &info->generators[0];
-
- *cursor = g_line_generator_compute_cursor(generator->instance, x, index, generator->repeat);
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : info = informations sur une ligne à venir manipuler. *
-* line = tampon de lignes à venir supprimer au besoin. *
-* last = indication sur la valeur du compteur de références. *
-* *
-* Description : Suivit les variations du compteur de références d'une ligne. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void on_line_ref_toggle(cache_info *info, GBufferLine *line, gboolean last)
-{
- if (last)
- {
- G_LOCK(_line_update);
-
- assert(info->line != NULL);
-
- _reset_cache_info_line_unlocked(info);
-
- G_UNLOCK(_line_update);
-
- }
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : info = informations sur une ligne à venir manipuler. *
-* index = indice de la ligne à constituer. *
-* content = éventuel contenu binaire brut à imprimer. *
-* *
-* Description : Fournit la ligne de tampon correspondant aux générateurs. *
-* *
-* Retour : Ligne déjà en place ou créée pour le besoin. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static GBufferLine *get_cache_info_line(cache_info *info, size_t index, const GBinContent *content)
-{
- GBufferLine *result; /* Construction à retourner */
- size_t i; /* Boucle de parcours */
-
- G_LOCK(_line_update);
-
- result = info->line;
-
- if (result == NULL)
- {
- result = g_buffer_line_new(UNUSED_MRANGE_PTR, 0/* !! */);
-
- g_object_add_toggle_ref(G_OBJECT(result), (GToggleNotify)on_line_ref_toggle, info);
-
- if (info->count == 1)
- g_line_generator_print(info->generator.instance, result, index,
- info->generator.repeat, content);
-
- else
- for (i = 0; i < info->count; i++)
- g_line_generator_print(info->generators[i].instance, result, index,
- info->generators[i].repeat, content);
-
- info->line = result;
-
- }
-
- else
- g_object_ref(G_OBJECT(result));
-
- G_UNLOCK(_line_update);
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : info = informations sur une ligne à venir manipuler. *
-* *
-* Description : Force la réinitialisation d'une éventuelle ligne cachée. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void _reset_cache_info_line_unlocked(cache_info *info)
-{
- if (info->line != NULL)
- {
- g_object_remove_toggle_ref(G_OBJECT(info->line), (GToggleNotify)on_line_ref_toggle, info);
-
- info->line = NULL;
-
- }
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : info = informations sur une ligne à venir manipuler. *
-* *
-* Description : Force la réinitialisation d'une éventuelle ligne cachée. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void reset_cache_info_line(cache_info *info)
-{
- G_LOCK(_line_update);
-
- _reset_cache_info_line_unlocked(info);
-
- G_UNLOCK(_line_update);
-
-}
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/* TAMPON POUR CODE DESASSEMBLE */
-/* ---------------------------------------------------------------------------------- */
-
-
-/* Détermine le type du composant de tampon pour gestion de lignes optimisée. */
-G_DEFINE_TYPE(GBufferCache, g_buffer_cache, G_TYPE_OBJECT);
-
-
-/******************************************************************************
-* *
-* Paramètres : class = classe de composant GLib à initialiser. *
-* *
-* Description : Procède à l'initialisation d'une classe de tampon de lignes. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_buffer_cache_class_init(GBufferCacheClass *class)
-{
- GObjectClass *object; /* Autre version de la classe */
-
- object = G_OBJECT_CLASS(class);
-
- object->dispose = (GObjectFinalizeFunc/* ! */)g_buffer_cache_dispose;
- object->finalize = (GObjectFinalizeFunc)g_buffer_cache_finalize;
-
- class->line_height = 17;
- class->left_margin = 2 * class->line_height;
- class->text_pos = 2.5 * class->line_height;
-
- /* Signaux */
-
- g_signal_new("size-changed",
- G_TYPE_BUFFER_CACHE,
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET(GBufferCacheClass, size_changed),
- NULL, NULL,
- g_cclosure_user_marshal_VOID__BOOLEAN_ULONG_ULONG,
- G_TYPE_NONE, 3, G_TYPE_BOOLEAN, G_TYPE_ULONG, G_TYPE_ULONG);
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : cache = composant GLib à initialiser. *
-* *
-* Description : Procède à l'initialisation d'un tampon de gestion de lignes. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_buffer_cache_init(GBufferCache *cache)
-{
- cache->content = NULL;
-
- cache->lines = NULL;
- cache->count = 0;
- cache->used = 0;
-
- cache->tracker = g_width_tracker_new(cache);
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : cache = instance d'objet GLib à traiter. *
-* *
-* Description : Supprime toutes les références externes. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_buffer_cache_dispose(GBufferCache *cache)
-{
- size_t i; /* Boucle de parcours #1 */
- cache_info *info; /* Accès direct à une ligne */
- size_t j; /* Boucle de parcours #2 */
-
- g_clear_object(&cache->content);
-
- for (i = 0; i < cache->used; i++)
- {
- info = &cache->lines[i];
-
- if (info->count == 1)
- g_clear_object(&info->generator.instance);
-
- else
- for (j = 0; j < info->count; j++)
- g_clear_object(&info->generators[j].instance);
-
- g_clear_object(&info->line);
-
- }
-
- g_clear_object(&cache->tracker);
-
- G_OBJECT_CLASS(g_buffer_cache_parent_class)->dispose(G_OBJECT(cache));
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : cache = instance d'objet GLib à traiter. *
-* *
-* Description : Procède à la libération totale de la mémoire. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_buffer_cache_finalize(GBufferCache *cache)
-{
- size_t i; /* Boucle de parcours */
- cache_info *info; /* Accès direct à une ligne */
-
- for (i = 0; i < cache->used; i++)
- {
- info = &cache->lines[i];
-
- if (info->count > 1)
- free(info->generators);
-
- }
-
- if (cache->lines != NULL)
- free(cache->lines);
-
- G_OBJECT_CLASS(g_buffer_cache_parent_class)->finalize(G_OBJECT(cache));
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : content = éventuel contenu binaire brut à référencer. *
-* *
-* Description : Crée un nouveau composant de tampon pour code désassemblé. *
-* *
-* Retour : Composant GLib créé. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GBufferCache *g_buffer_cache_new(GBinContent *content)
-{
- GBufferCache *result; /* Composant à retourner */
-
- result = g_object_new(G_TYPE_BUFFER_CACHE, NULL);
-
- if (content != NULL)
- {
- result->content = content;
- g_object_ref(G_OBJECT(content));
- }
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : cache = tampon de lignes à consulter. *
-* *
-* Description : Fournit la hauteur d'impression d'une ligne visualisée. *
-* *
-* Retour : Hauteur de ligne en pixels. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-gint g_buffer_cache_get_line_height(const GBufferCache *cache)
-{
- GBufferCacheClass *class; /* Classe des tampons */
-
- class = G_BUFFER_CACHE_GET_CLASS(cache);
-
- return class->line_height;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : cache = tampon de lignes à consulter. *
-* *
-* Description : Indique l'éventuel contenu binaire associé au cache. *
-* *
-* Retour : Eventuel contenu renseigné ou NULL. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GBinContent *g_buffer_cache_get_content(const GBufferCache *cache)
-{
- GBinContent *result; /* Contenu à retourner */
-
- result = cache->content;
-
- if (result != NULL)
- g_object_ref(G_OBJECT(result));
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : cache = tampon de lignes à consulter. *
-* *
-* Description : Fournit la taille réservée pour la marge gauche. *
-* *
-* Retour : Largeur en pixels. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-gint g_buffer_cache_get_left_margin(const GBufferCache *cache)
-{
- GBufferCacheClass *class; /* Classe des tampons */
-
- class = G_BUFFER_CACHE_GET_CLASS(cache);
-
- return class->left_margin;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : cache = tampon de lignes à consulter. *
-* *
-* Description : Fournit la position de départ pour l'impression de texte. *
-* *
-* Retour : Position en pixels. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-gint g_buffer_cache_get_text_position(const GBufferCache *cache)
-{
- GBufferCacheClass *class; /* Classe des tampons */
-
- class = G_BUFFER_CACHE_GET_CLASS(cache);
-
- return class->text_pos;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : cache = instance GLib à consulter. *
-* *
-* Description : Compte le nombre de lignes rassemblées dans un tampon. *
-* *
-* Retour : Nombre de lignes constituant le tampon. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-size_t g_buffer_cache_count_lines(const GBufferCache *cache)
-{
- return cache->used;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : cache = composant GLib à consulter. *
-* *
-* Description : Fournit un lien vers la structure de suivi de largeurs. *
-* *
-* Retour : Gestionnaire de largeurs de lignes. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GWidthTracker *g_buffer_cache_get_width_tracker(const GBufferCache *cache)
-{
- GWidthTracker *result; /* Instance à retourner * */
-
- result = cache->tracker;
-
- g_object_ref(G_OBJECT(result));
-
- return result;
-
-}
-
-
-
-
-
-/******************************************************************************
-* *
-* Paramètres : cache = instance GLib à consulter. *
-* index = indice de la ligne où se trouve le générateur. *
-* generator = générateur associé à au moins une ligne. *
-* *
-* Description : Calcule l'indice d'apparition d'un générateur dans le tampon.*
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static size_t g_buffer_cache_compute_repetition(GBufferCache *cache, size_t index, GLineGenerator *generator)
-{
- size_t result; /* Compteur à retourner */
- cache_info *info; /* Accès direct à une ligne */
- size_t i; /* Boucle de parcours */
-
- result = 0;
-
- if (index > 0)
- {
- info = &cache->lines[index - 1];
-
- if (info->count == 1)
- {
- if (info->generator.instance == generator)
- result = info->generator.repeat + 1;
-
- }
-
- else
- for (i = 0; i < info->count; i++)
- if (info->generators[i].instance == generator)
- {
- result = info->generators[i].repeat + 1;
- break;
- }
-
- }
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : cache = instance GLib à modifier. *
-* index = point d'insertion, puis de sauvegarde. *
-* generator = générateur à insérer dans les lignes. *
-* flags = propriétés supplémentaires à associer à la ligne.*
-* before = précise l'emplacement final des nouvelles lignes.*
-* after = précise l'emplacement final des nouvelles lignes.*
-* *
-* Description : Insère un générateur dans des lignes à une position donnée. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void g_buffer_cache_insert_at(GBufferCache *cache, size_t index, GLineGenerator *generator, BufferLineFlags flags, bool before, bool after)
-{
-#ifndef NDEBUG
- GLineCursor *gen_cursor; /* Position du générateur */
- GLineCursor *line_cursor; /* Position de la ligne */
- int ret; /* Bilan de comparaison */
-#endif
- size_t needed; /* Emplacements nécessaires */
- size_t i; /* Boucle de parcours */
-
- assert(index < cache->used);
-
- assert(!(before && after));
-
-#ifndef NDEBUG
-
- if (!before && !after)
- {
- gen_cursor = g_line_generator_compute_cursor(generator, 0, index, 0);
-
- get_cache_info_cursor(&cache->lines[index], index, 0, &line_cursor);
-
- ret = g_line_cursor_compare(gen_cursor, line_cursor);
-
- g_object_unref(G_OBJECT(line_cursor));
- g_object_unref(G_OBJECT(gen_cursor));
-
- assert(ret == 0);
-
- }
-
-#endif
-
- /* Cas particulier d'ajout en fin de cache... */
- if (after && (index + 1) == cache->used)
- {
- g_buffer_cache_append(cache, generator, flags);
- goto gbcia_done;
- }
-
- /* Adaptation de l'espace */
-
- needed = g_line_generator_count_lines(generator);
-
- if (before || after)
- {
- if ((cache->used + needed) >= cache->count)
- {
- cache->count += needed + LINE_ALLOC_BULK;
- cache->lines = (cache_info *)realloc(cache->lines, cache->count * sizeof(cache_info));
- }
- }
-
- else if (needed > 1)
- {
- if ((cache->used + needed - 1) >= cache->count)
- {
- cache->count += needed - 1 + LINE_ALLOC_BULK;
- cache->lines = (cache_info *)realloc(cache->lines, cache->count * sizeof(cache_info));
- }
- }
-
- /* Insertion du générateur */
-
- if (after)
- index++;
-
- if (before || after)
- {
- memmove(&cache->lines[index + needed], &cache->lines[index], (cache->used - index) * sizeof(cache_info));
-
- for (i = 0; i < needed; i++)
- init_cache_info(&cache->lines[index + i], generator, i, flags);
-
- cache->used += needed;
-
- g_width_tracker_update_added(cache->tracker, index, needed);
-
- g_signal_emit_by_name(cache, "size-changed", true, index, needed);
-
- }
-
- else
- {
- extend_cache_info(&cache->lines[index], generator, flags);
-
- g_width_tracker_update(cache->tracker, index);
-
- if (needed > 1)
- {
- /* On déborde sur les lignes suivantes, donc on crée de l'espace ! */
-
- memmove(&cache->lines[index + 1],
- &cache->lines[index + 1 + needed - 1], (cache->used - index - 1) * sizeof(cache_info));
-
- for (i = 1; i < needed; i++)
- init_cache_info(&cache->lines[index + i], generator, i, BLF_NONE);
-
- cache->used += needed - 1;
-
- g_width_tracker_update_added(cache->tracker, index + 1, needed - 1);
-
- }
-
- g_signal_emit_by_name(cache, "size-changed", true, index, needed - 1);
-
- }
-
- gbcia_done:
-
- ;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : cache = instance GLib à modifier. *
-* index = point de suppression. *
-* *
-* Description : Retire une ligne du tampon. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void g_buffer_cache_delete_at(GBufferCache *cache, size_t index)
-{
- cache_info *info; /* Accès direct à une ligne */
-
- assert(index < cache->used);
-
- info = &cache->lines[index];
-
- release_cache_info(info);
-
- if ((index + 1) < cache->used)
- memmove(&cache->lines[index], &cache->lines[index + 1],
- (cache->used - index - 1) * sizeof(cache_info));
-
- cache->used--;
-
- g_width_tracker_update_deleted(cache->tracker, index, index);
-
- g_signal_emit_by_name(cache, "size-changed", false, index, 1);
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : cache = instance GLib à modifier. *
-* index = point d'insertion, puis de sauvegarde. *
-* type = type de générateurs à retirer des lignes visées. *
-* before = précise l'emplacement final de l'élément visé. *
-* after = précise l'emplacement final de l'élément visé. *
-* *
-* Description : Retire un type de générateur de lignes. *
-* *
-* Retour : Générateur éventuellement trouvé ou NULL si aucun. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GLineGenerator *g_buffer_cache_delete_type_at(GBufferCache *cache, size_t index, GType type, bool before, bool after)
-{
- GLineGenerator *result; /* Prédécesseur à retourner */
- cache_info *info; /* Accès direct à une ligne */
- generator_link *link; /* Accès simplifié */
- size_t i; /* Boucle de parcours */
- size_t count; /* Emplacements occupés */
- size_t delete; /* Indice de suppression */
-
- assert(index < cache->used);
-
- assert(!(before && after));
-
- result = NULL;
-
- /* Recherche d'un générateur correspondant */
-
- if (before)
- info = &cache->lines[index - 1];
- else if (after)
- info = &cache->lines[index + 1];
- else
- info = &cache->lines[index];
-
- if (info->count == 1)
- {
- link = &info->generator;
-
- if (G_OBJECT_TYPE(link->instance) == type)
- result = link->instance;
-
- }
-
- else
- for (i = 0; i < info->count && result == NULL; i++)
- {
- link = &info->generators[i];
-
- if (G_OBJECT_TYPE(link->instance) == type)
- result = link->instance;
-
- }
-
- /* Retrait de l'instance trouvée */
-
- if (result != NULL)
- {
- count = g_line_generator_count_lines(result);
-
-#ifndef NDEBUG
- if (!before && !after)
- assert(count == 1);
-#endif
-
- g_object_ref(G_OBJECT(result));
-
- /* Suppression de l'élément */
-
- for (i = 0; i < count; i++)
- {
- if (before)
- info = &cache->lines[index - 1 - i];
- else if (after)
- info = &cache->lines[index + 1 + i];
- else
- info = &cache->lines[index];
-
- remove_from_cache_info(info, result);
-
- }
-
- /* Suppression des lignes associées */
-
- for (i = 0; i < count; i++)
- {
- if (before)
- delete = index - 1;
- else if (after)
- delete = index + 1;
- else
- delete = index;
-
- info = &cache->lines[delete];
-
- if (info->count == 0)
- {
- release_cache_info(info);
-
- if ((delete + 1) < cache->used)
- memmove(&cache->lines[delete], &cache->lines[delete + 1],
- (cache->used - delete - 1) * sizeof(cache_info));
-
- cache->used--;
-
- g_width_tracker_update_deleted(cache->tracker, delete, delete);
-
- g_signal_emit_by_name(cache, "size-changed", false, delete, 1);
-
- }
-
- }
-
- }
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : cache = instance GLib à modifier. *
-* generator = générateur à associer à toutes les lignes. *
-* flags = propriétés supplémentaires à associer à la ligne.*
-* *
-* Description : Ajoute en fin de tampon un générateur de lignes. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void g_buffer_cache_append(GBufferCache *cache, GLineGenerator *generator, BufferLineFlags flags)
-{
- size_t count; /* Nombre de lignes générées */
- size_t index; /* Point d'insertion */
- size_t i; /* Boucle de parcours */
- cache_info *info; /* Accès direct à une ligne */
-
- count = g_line_generator_count_lines(generator);
-
- assert(count > 0);
-
- assert((flags != BLF_NONE && count == 1) || flags == BLF_NONE);
-
- if ((cache->used + count) > cache->count)
- {
- cache->count += count + LINE_ALLOC_BULK;
- cache->lines = (cache_info *)realloc(cache->lines, cache->count * sizeof(cache_info));
- }
-
- index = cache->used;
-
- for (i = 0; i < count; i++)
- {
- info = &cache->lines[index + i];
-
- info->generator.instance = generator;
- info->generator.repeat = g_buffer_cache_compute_repetition(cache, index + i, generator);
-
- g_object_ref(G_OBJECT(generator));
-
- info->count = 1;
-
- info->line = NULL;
-
- info->extra_flags = flags;
-
- }
-
- cache->used += count;
-
- g_width_tracker_update_added(cache->tracker, index, count);
-
- g_signal_emit_by_name(cache, "size-changed", true, index, count);
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : cache = instance GLib à modifier. *
-* count = quantité totale de lignes à avoir à disposition. *
-* generator = générateur à associer à toutes les lignes. *
-* *
-* Description : Etend un tampon avec un générateur de lignes unique. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void g_buffer_cache_extend_with(GBufferCache *cache, size_t count, GLineGenerator *generator)
-{
- size_t index; /* Point d'insertion */
- size_t i; /* Boucle de parcours */
- cache_info *info; /* Accès direct à une ligne */
- size_t added; /* Nombre d'ajouts effectués */
-
- assert(count >= cache->used);
-
- if (count > cache->count)
- {
- cache->lines = (cache_info *)realloc(cache->lines, count * sizeof(cache_info));
- cache->count = count;
- }
-
- index = cache->used;
-
- for (i = index; i < count; i++)
- {
- info = &cache->lines[i];
-
- info->generator.instance = generator;
- info->generator.repeat = g_buffer_cache_compute_repetition(cache, i, generator);
-
- g_object_ref(G_OBJECT(generator));
-
- info->count = 1;
-
- info->line = NULL;
-
- }
-
- added = count - cache->used;
-
- cache->used = count;
-
- if (added > 0)
- {
- g_width_tracker_update_added(cache->tracker, index, added);
-
- g_signal_emit_by_name(cache, "size-changed", true, index, added);
-
- }
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : cache = instance GLib à modifier. *
-* max = nombre maximal de lignes à conserver. *
-* *
-* Description : Réduit le tampon à une quantité de lignes précise. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void g_buffer_cache_truncate(GBufferCache *cache, size_t max)
-{
- size_t i; /* Boucle de parcours #1 */
- cache_info *info; /* Accès direct à une ligne */
- size_t j; /* Boucle de parcours #2 */
- size_t removed; /* Nombre de retraits effectués*/
-
- for (i = max; i < cache->used; i++)
- {
- info = &cache->lines[i];
-
- if (info->count == 1)
- g_object_unref(G_OBJECT(info->generator.instance));
-
- else
- {
- for (j = 0; j < info->count; j++)
- g_object_unref(G_OBJECT(info->generators[j].instance));
-
- free(info->generators);
-
- }
-
- reset_cache_info_line(info);
-
- }
-
- if (max < cache->used)
- {
- removed = cache->used - max;
-
- cache->used = max;
-
- g_width_tracker_update_deleted(cache->tracker, max, max + removed - 1);
-
- g_signal_emit_by_name(cache, "size-changed", false, max, removed);
-
- }
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : cache = tampon de lignes à venir consulter. *
-* index = indice de la ligne visée par la consultation. *
-* x = position géographique sur la ligne concernée. *
-* cursor = emplacement à constituer. [OUT] *
-* *
-* Description : Retrouve l'emplacement correspondant à une position de ligne.*
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void g_buffer_cache_get_line_cursor(const GBufferCache *cache, size_t index, gint x, GLineCursor **cursor)
-{
- assert(index < cache->used);
-
- get_cache_info_cursor(&cache->lines[index], index, x, cursor);
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : cache = tampon de lignes à venir consulter. *
-* index = indice de la ligne visée par la consultation. *
-* *
-* Description : Détermine l'ensemble des propriétés attachées à une ligne. *
-* *
-* Retour : Somme de toutes les propriétés enregistrées. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-BufferLineFlags g_buffer_cache_get_line_flags(const GBufferCache *cache, size_t index)
-{
- BufferLineFlags result; /* Somme à renvoyer */
- cache_info *info; /* Accès direct à une ligne */
- const generator_link *generator; /* Générateur retenu */
- size_t i; /* Boucle de parcours */
-
- // TODO : check lock
-
- assert(index < cache->used);
-
- info = &cache->lines[index];
-
- result = info->extra_flags;
-
- if (info->count == 1)
- {
- generator = &info->generator;
- result |= g_line_generator_get_flags(generator->instance, index, generator->repeat);
- }
-
- else
- for (i = 0; i < info->count; i++)
- {
- generator = &info->generators[i];
- result |= g_line_generator_get_flags(generator->instance, index, generator->repeat);
- }
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : cache = tampon de lignes à consulter. *
-* index = indice de la ligne recherchée. *
-* *
-* Description : Retrouve une ligne au sein d'un tampon avec un indice. *
-* *
-* Retour : Line retrouvée ou NULL en cas d'échec. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GBufferLine *g_buffer_cache_find_line_by_index(const GBufferCache *cache, size_t index)
-{
- GBufferLine *result; /* Ligne trouvée à retourner */
-
- if (index < cache->used)
- result = get_cache_info_line(&cache->lines[index], index, cache->content);
- else
- result = NULL;
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : cache = tampon de lignes à venir consulter. *
-* index = indice de la ligne à mesurer. *
-* summary = largeurs maximales à faire évoluer. *
-* *
-* Description : Fait remonter les largeurs requises par une ligne donnée. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void g_buffer_cache_collect_widths(GBufferCache *cache, size_t index, line_width_summary *summary)
-{
- GBufferLine *line; /* Ligne éphémère à mesurer */
-
- line = get_cache_info_line(&cache->lines[index], index, cache->content);
-
- g_buffer_line_collect_widths(line, summary);
-
- g_object_unref(G_OBJECT(line));
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : cache = visualisation à représenter. *
-* cr = contexte graphique dédié à la procédure. *
-* first = première ligne à dessiner. *
-* last = dernière ligne à dessiner. *
-* area = position et surface à traiter. *
-* options = règles d'affichage des colonnes modulables. *
-* offsets = décalages supplémentaires à appliquer. *
-* selected = ordonnée d'une ligne sélectionnée ou NULL. *
-* list = liste de contenus à mettre en évidence. *
-* *
-* Description : Imprime une partie choisie du tampon contenant des lignes. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void g_buffer_cache_draw(const GBufferCache *cache, cairo_t *cr, size_t first, size_t last, const cairo_rectangle_int_t *area, const GDisplayOptions *options, const line_width_summary *offsets, const gint *selected, const segcnt_list *list)
-{
- GBufferCacheClass *class; /* Classe des tampons */
- gint y; /* Point de départ en ordonnée */
- bool wait_selection; /* Sélection déjà passée ? */
- size_t i; /* Boucle de parcours */
- cache_info *info; /* Accès direct à une ligne */
- line_width_summary summary; /* Résumé concis des largeurs */
- GBufferLine *line; /* Ligne à venir dessiner */
-
- class = G_BUFFER_CACHE_GET_CLASS(cache);
-
- y = 0;
-
- wait_selection = true;
-
- if (cache->used > 0)
- for (i = first; i <= last; i++)
- {
- /* Si sélection, on sousligne la ligne concernée */
- if (wait_selection && selected != NULL && *selected == y)
- {
- cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.05);
-
- cairo_rectangle(cr, area->x, y, area->width, class->line_height);
- cairo_fill(cr);
-
- wait_selection = false;
-
- }
-
- info = &cache->lines[i];
-
- if (i == first || (g_buffer_cache_get_line_flags(cache, i) & BLF_WIDTH_MANAGER))
- g_width_tracker_get_local_width_summary(cache->tracker, i, &summary);
-
- line = get_cache_info_line(info, i, cache->content);
-
- g_buffer_line_draw(line, cr, &summary, class->text_pos, y, options, offsets, list);
-
- g_object_unref(G_OBJECT(line));
-
- y += class->line_height;
-
- }
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : cache = tampon de lignes à consulter. *
-* cursor = emplacement à retrouver dans le tampon. *
-* first = indique si on l'arrête à la première ou la dernière.*
-* start = borne inférieure des recherches (incluse). *
-* end = borne supérieure des recherches (incluse). *
-* *
-* Description : Indique l'indice correspondant à une adresse donnée. *
-* *
-* Retour : Indice des infos à l'adresse demandée, ou nombre de lignes. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-size_t _g_buffer_cache_find_index_by_cursor(const GBufferCache *cache, const GLineCursor *cursor, bool first, size_t start, size_t end)
-{
- size_t result; /* Indice à retourner */
- cache_info *found; /* Eventuel élément trouvé */
-
- int find_containing_generator(const GLineCursor *c, const cache_info *i)
- {
- const generator_link *generator; /* Générateur retenu */
-
- if (i->count == 1)
- generator = &i->generator;
- else
- generator = &i->generators[0];
-
- return g_line_generator_contain_cursor(generator->instance,
- i - cache->lines, generator->repeat, c);
-
- }
-
- found = (cache_info *)bsearch(cursor, &cache->lines[start], end - start + 1,
- sizeof(cache_info), (__compar_fn_t)find_containing_generator);
-
- if (found == NULL)
- result = cache->used;
-
- else
- {
- result = (found - cache->lines);
- assert(start <= result && result <= end);
-
- /* On s'assure d'un arrêt sur la bonne ligne */
-
- if (first)
- for (; result > start; result--)
- {
- found = &cache->lines[result - 1];
-
- if (find_containing_generator(cursor, found) != 0)
- break;
-
- }
-
- else
- for (; result < end; result++)
- {
- found = &cache->lines[result + 1];
-
- if (find_containing_generator(cursor, found) != 0)
- break;
-
- }
-
- }
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : cache = tampon de lignes à consulter. *
-* cursor = emplacement à retrouver dans le tampon. *
-* first = indique si on l'arrête à la première ou la dernière.*
-* *
-* Description : Indique l'indice correspondant à une adresse donnée. *
-* *
-* Retour : Indice des infos à l'adresse demandée, ou nombre de lignes. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-size_t g_buffer_cache_find_index_by_cursor(const GBufferCache *cache, const GLineCursor *cursor, bool first)
-{
- size_t result; /* Indice à retourner */
-
- if (cache->used == 0)
- result = 0;
- else
- result = _g_buffer_cache_find_index_by_cursor(cache, cursor, first, 0, cache->used - 1);
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : cache = tampon de lignes à consulter. *
-* start = point de départ du parcours. *
-* flag = propriétés à retrouver si possible. *
-* *
-* Description : Avance autant que possible vers une ligne idéale. *
-* *
-* Retour : Indice de la ligne recherchée, si elle existe. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-size_t g_buffer_cache_look_for_flag(const GBufferCache *cache, size_t start, BufferLineFlags flag)
-{
- size_t result; /* Indice de ligne à retourner */
- GLineCursor *init; /* Localisation de départ */
- size_t i; /* Boucle de parcours */
- GLineCursor *next; /* Localisation suivante */
- int ret; /* Bilan de comparaison */
-
- // TODO : check lock
-
- assert(start < cache->used);
-
- result = start;
-
- get_cache_info_cursor(&cache->lines[start], start, 0, &init);
-
- for (i = start + 1; i < cache->used; i++)
- {
- get_cache_info_cursor(&cache->lines[i], i, 0, &next);
-
- ret = g_line_cursor_compare(init, next);
-
- g_object_unref(G_OBJECT(next));
-
- if (ret != 0)
- break;
-
- if ((g_buffer_cache_get_line_flags(cache, i) & flag) != 0)
- {
- result = i;
- break;
- }
-
- }
-
- g_object_unref(G_OBJECT(init));
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : cache = tampon de lignes à consulter. *
-* cursor = emplacement à présenter à l'écran. *
-* first = borne inférieure des recherches (incluse). *
-* last = borne supérieure des recherches (incluse). *
-* code = s'arrête si possible à une ligne avec code. *
-* x = position horizontale au sein du composant. [OUT] *
-* y = position verticale au sein du composant. [OUT] *
-* *
-* Description : Indique la position d'affichage d'une adresse donnée. *
-* *
-* Retour : true si l'adresse fait partie du composant, false sinon. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool g_buffer_cache_get_cursor_coordinates(const GBufferCache *cache, const GLineCursor *cursor, size_t first, size_t last, bool code, gint *x, gint *y)
-{
- bool result; /* Bilan à retourner */
- size_t index; /* Indice de correspondance */
- gint lheight; /* Hauteur d'une ligne */
- const cache_info *info; /* Infos sur une ligne donnée */
- const generator_link *generator; /* Générateur retenu */
-
- index = _g_buffer_cache_find_index_by_cursor(cache, cursor, true, first, last);
-
- result = (index < cache->used);
-
- if (result)
- {
- lheight = G_BUFFER_CACHE_GET_CLASS(cache)->line_height;
-
- *x = 0;
- *y = (index - first) * G_BUFFER_CACHE_GET_CLASS(cache)->line_height;
-
- for (; code && index <= last; index++)
- {
- if (g_buffer_cache_get_line_flags(cache, index) & BLF_HAS_CODE)
- break;
-
- if (index == last)
- break;
-
- info = &cache->lines[index + 1];
-
- if (info->count == 1)
- generator = &info->generator;
- else
- generator = &info->generators[0];
-
- if (!g_line_generator_contain_cursor(generator->instance, index + 1, generator->repeat, cursor))
- break;
-
- *y += lheight;
-
- }
-
- }
-
- return result;
-
-}