/* Chrysalide - Outil d'analyse de fichiers binaires
* pending.c - consolidation de correspondances partielles
*
* Copyright (C) 2023 Cyrille Bagard
*
* This file is part of Chrysalide.
*
* Chrysalide is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* Chrysalide is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see .
*/
#include "pending.h"
#include
#include
#include
#define PENDING_ALLOC_SIZE 10
/******************************************************************************
* *
* Paramètres : matches = suivi de correspondances à initialiser. *
* *
* Description : Initialise une structure de consolidation de correspondances.*
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
void init_pending_matches(pending_matches_t *matches)
{
matches->areas = NULL;
matches->allocated = 0;
matches->used = 0;
matches->initialized = false;
}
/******************************************************************************
* *
* Paramètres : matches = suivi de correspondances à purger. *
* *
* Description : Libère la mémoire utilisée par une consolidation. *
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
void exit_pending_matches(pending_matches_t *matches)
{
if (matches->areas != NULL)
free(matches->areas);
}
/******************************************************************************
* *
* Paramètres : matches = suivi de correspondances à consulter. *
* start = point de départ d'une suite pour de correspondance.*
* mindex = indice de départ et d'arrivée. [OUT] *
* *
* Description : Détermine la zone de correspondance idéale pour complément. *
* *
* Retour : Bilan de l'opération : true en cas de succès des recherches. *
* *
* Remarques : - *
* *
******************************************************************************/
bool find_target_in_pending_matches(pending_matches_t *matches, phys_t start, size_t *target)
{
bool result; /* Bilan à retourner */
size_t i; /* Boucle de parcours */
match_area_t *area; /* Zone à initialiser */
assert(*target <= matches->used);
result = false;
for (i = *target; i < matches->used; i++)
{
area = &matches->areas[i];
if ((area->start + area->length) == start)
{
*target = i;
result = true;
break;
}
}
return result;
}
/******************************************************************************
* *
* Paramètres : matches = suivi de correspondances à compléter. *
* start = point de départ d'une nouvelle correspondance. *
* length = taille de la zone couverte. *
* *
* Description : Ajoute au suivi la définition d'une nouvelle correspondance. *
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
void add_pending_matches(pending_matches_t *matches, phys_t start, phys_t length)
{
match_area_t *area; /* Zone à initialiser */
if (matches->used == matches->allocated)
{
matches->allocated += PENDING_ALLOC_SIZE;
matches->areas = realloc(matches->areas, matches->allocated * sizeof(match_area_t));
}
area = &matches->areas[matches->used++];
area->start = start;
area->length = length;
}
/******************************************************************************
* *
* Paramètres : matches = suivi de correspondances à compléter. *
* target = indice de la zone de correspondance concernée. *
* length = taille de la zone couverte supplémentaire. *
* *
* Description : Etend une zone couverte dans le suivi des correspondances. *
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
void extend_pending_matches(pending_matches_t *matches, size_t target, phys_t length)
{
assert(target < matches->used);
matches->areas[target].length += length;
}
/******************************************************************************
* *
* Paramètres : matches = suivi de correspondances à modifier. *
* target = indice de la zone de correspondance concernée. *
* *
* Description : Retire une correspondance finalement non établie du suivi. *
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
void remove_pending_matches(pending_matches_t *matches, size_t target)
{
assert(target < matches->used);
if ((target + 1) < matches->used)
memmove(&matches->areas[target], &matches->areas[target + 1],
(matches->used - target - 1) * sizeof(match_area_t));
matches->used--;
}