/* Chrysalide - Outil d'analyse de fichiers binaires
* variable.c - manipulation des variables en tout genre
*
* Copyright (C) 2009-2017 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 .
*/
#include "variable.h"
#include
#include
#include
#include "types/cse.h"
#include "../common/extstr.h"
/* ------------------- ASSOCIATION D'UN TYPE ET D'UNE DESIGNATION ------------------- */
/* Variable typée (instance) */
struct _GBinVariable
{
GObject parent; /* A laisser en premier */
GDataType *type; /* Type de la variable */
char *name; /* Désignation humaine */
GDataType *owner; /* Zone d'appartenance */
};
/* Variable typée (classe) */
struct _GBinVariableClass
{
GObjectClass parent; /* A laisser en premier */
};
/* Initialise la classe des variables. */
static void g_binary_variable_class_init(GBinVariableClass *);
/* Initialise l'instande d'une variable. */
static void g_binary_variable_init(GBinVariable *);
/* Supprime toutes les références externes. */
static void g_binary_variable_dispose(GBinVariable *);
/* Procède à la libération totale de la mémoire. */
static void g_binary_variable_finalize(GBinVariable *);
/* -------------------- BASE DE VARIABLES OU VARIABLES INCONNUES -------------------- */
/* Base de variable (instance) */
struct _GUnknownVariable
{
GObject parent; /* A laisser en premier */
size_t offset; /* Position abstraite associée */
size_t size; /* Taille en mémoire */
};
/* Base de variable (classe) */
struct _GUnknownVariableClass
{
GObjectClass parent; /* A laisser en premier */
};
/* Initialise la classe des bases de variables. */
static void g_unknown_variable_class_init(GUnknownVariableClass *);
/* Initialise l'instande d'une base de variable. */
static void g_unknown_variable_init(GUnknownVariable *);
/* ---------------------------------------------------------------------------------- */
/* ASSOCIATION D'UN TYPE ET D'UNE DESIGNATION */
/* ---------------------------------------------------------------------------------- */
/* Indique le type défini pour une base de variable. */
G_DEFINE_TYPE(GBinVariable, g_binary_variable, G_TYPE_OBJECT);
/******************************************************************************
* *
* Paramètres : klass = classe à initialiser. *
* *
* Description : Initialise la classe des variables. *
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
static void g_binary_variable_class_init(GBinVariableClass *klass)
{
GObjectClass *object; /* Autre version de la classe */
object = G_OBJECT_CLASS(klass);
object->dispose = (GObjectFinalizeFunc/* ! */)g_binary_variable_dispose;
object->finalize = (GObjectFinalizeFunc)g_binary_variable_finalize;
}
/******************************************************************************
* *
* Paramètres : var = instance à initialiser. *
* *
* Description : Initialise l'instande d'une variable. *
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
static void g_binary_variable_init(GBinVariable *var)
{
}
/******************************************************************************
* *
* Paramètres : var = instance d'objet GLib à traiter. *
* *
* Description : Supprime toutes les références externes. *
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
static void g_binary_variable_dispose(GBinVariable *var)
{
g_clear_object(&var->type);
g_clear_object(&var->owner);
G_OBJECT_CLASS(g_binary_variable_parent_class)->dispose(G_OBJECT(var));
}
/******************************************************************************
* *
* Paramètres : var = instance d'objet GLib à traiter. *
* *
* Description : Procède à la libération totale de la mémoire. *
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
static void g_binary_variable_finalize(GBinVariable *var)
{
if (var->name != NULL)
free(var->name);
G_OBJECT_CLASS(g_binary_variable_parent_class)->finalize(G_OBJECT(var));
}
/******************************************************************************
* *
* Paramètres : type = type de la variable à mettre en place. *
* *
* Description : Crée une représentation de variable de type donné. *
* *
* Retour : Variable mise en place. *
* *
* Remarques : - *
* *
******************************************************************************/
GBinVariable *g_binary_variable_new(GDataType *type)
{
GBinVariable *result; /* Variable à retourner */
result = g_object_new(G_TYPE_BIN_VARIABLE, NULL);
result->type = type;
///// A retirer /// g_object_ref(G_OBJECT(type));
return result;
}
/******************************************************************************
* *
* Paramètres : var = variable à consulter. *
* *
* Description : Fournit le type d'une variable donnée. *
* *
* Retour : Type de la variable. *
* *
* Remarques : - *
* *
******************************************************************************/
GDataType *g_binary_variable_get_vtype(const GBinVariable *var)
{
GDataType *result; /* Instance à retourner */
result = var->type;
g_object_ref(G_OBJECT(result));
return result;
}
/******************************************************************************
* *
* Paramètres : var = variable à consulter. *
* *
* Description : Fournit le nom d'une variable donnée. *
* *
* Retour : Nom de la variable ou NULL si non précisé. *
* *
* Remarques : - *
* *
******************************************************************************/
const char *g_binary_variable_get_name(const GBinVariable *var)
{
return var->name;
}
/******************************************************************************
* *
* Paramètres : var = variable à consulter. *
* name = désignation à associer à la variable, voire NULL. *
* *
* Description : Définit le nom d'une variable donnée. *
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
void g_binary_variable_set_name(GBinVariable *var, const char *name)
{
if (var->name != NULL)
free(var->name);
if (name == NULL) var->name = NULL;
else var->name = strdup(name);
}
/******************************************************************************
* *
* Paramètres : var = variable à consulter. *
* *
* Description : Fournit la zone d'appartenance d'une variable donnée. *
* *
* Retour : Zone d'appartenance de la variable ou NULL. *
* *
* Remarques : - *
* *
******************************************************************************/
GDataType *g_binary_variable_get_owner(const GBinVariable *var)
{
return var->owner;
}
/******************************************************************************
* *
* Paramètres : var = variable à consulter. *
* owner = type identifiant la zone d'appartenance. *
* *
* Description : Définit la zone d'appartenance d'une variable donnée. *
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
void g_binary_variable_set_owner(GBinVariable *var, GDataType *owner)
{
var->owner = owner;
}
/******************************************************************************
* *
* Paramètres : var = variable à convertir. *
* include = doit-on inclure les espaces de noms ? *
* *
* Description : Décrit la variable donnée sous forme de caractères. *
* *
* Retour : Chaîne à libérer de la mémoire après usage. *
* *
* Remarques : - *
* *
******************************************************************************/
char *g_binary_variable_to_string(const GBinVariable *var, bool include)
{
char *result; /* Valeur à retourner */
result = g_data_type_to_string(var->type, include);
if (var->name != NULL)
{
if (!(g_data_type_is_pointer(var->type) || g_data_type_is_reference(var->type)))
result = stradd(result, " ");
result = stradd(result, var->name);
}
return result;
}
/* ---------------------------------------------------------------------------------- */
/* BASE DE VARIABLES OU VARIABLES INCONNUES */
/* ---------------------------------------------------------------------------------- */
/* Indique le type défini pour une base de variable. */
G_DEFINE_TYPE(GUnknownVariable, g_unknown_variable, G_TYPE_OBJECT);
/******************************************************************************
* *
* Paramètres : klass = classe à initialiser. *
* *
* Description : Initialise la classe des bases de variables. *
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
static void g_unknown_variable_class_init(GUnknownVariableClass *klass)
{
}
/******************************************************************************
* *
* Paramètres : var = instance à initialiser. *
* *
* Description : Initialise l'instande d'une base de variable. *
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
static void g_unknown_variable_init(GUnknownVariable *var)
{
var->offset = SIZE_MAX;
var->size = SIZE_MAX;
}
/******************************************************************************
* *
* Paramètres : - *
* *
* Description : Crée une représentation de variable de type inconnu. *
* *
* Retour : Variable mise en place. *
* *
* Remarques : - *
* *
******************************************************************************/
GUnknownVariable *g_unknown_variable_new(void)
{
GUnknownVariable *result; /* Variable à retourner */
result = g_object_new(G_TYPE_UNKNOWN_VARIABLE, NULL);
return result;
}
/******************************************************************************
* *
* Paramètres : a = premières informations à consulter. *
* b = secondes informations à consulter. *
* *
* Description : Etablit la comparaison ascendante entre deux variables. *
* *
* Retour : Bilan : -1 (a < b), 0 (a == b) ou 1 (a > b). *
* *
* Remarques : - *
* *
******************************************************************************/
int g_unknown_variable_compare(const GUnknownVariable **a, const GUnknownVariable **b)
{
int result; /* Bilan à renvoyer */
if ((*a)->offset < (*b)->offset) result = -1;
else if((*a)->offset > (*b)->offset) result = 1;
else result = 0;
return result;
}
/******************************************************************************
* *
* Paramètres : var = variable à manipuler. *
* offset = position (abstraite ou non) à enregistrer. *
* *
* Description : Définit la position associée à une variable. *
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
void g_unknown_variable_set_offset(GUnknownVariable *var, size_t offset)
{
var->offset = offset;
}
/******************************************************************************
* *
* Paramètres : var = variable à manipuler. *
* *
* Description : Fournit la position associée à une variable. *
* *
* Retour : Position de la variable. *
* *
* Remarques : - *
* *
******************************************************************************/
size_t g_unknown_variable_get_offset(const GUnknownVariable *var)
{
return var->offset;
}
/******************************************************************************
* *
* Paramètres : var = variable à manipuler. *
* offset = position (abstraite ou non) à traiter. *
* *
* Description : Indique si une position est contenue dans une variable. *
* *
* Retour : Bilan de la consultation. *
* *
* Remarques : - *
* *
******************************************************************************/
bool g_unknown_variable_contains_offset(const GUnknownVariable *var, size_t offset)
{
bool result; /* Bilan à retourner */
if (var->offset == SIZE_MAX)
return false;
if (var->size == SIZE_MAX)
result = (var->offset == offset);
else result = (var->offset <= offset && offset < (var->offset + var->size));
return result;
}