/* Chrysalide - Outil d'analyse de fichiers binaires
 * data.c - opérandes de manipulation de données
 *
 * Copyright (C) 2012 Cyrille Bagard
 *
 *  This file is part of Chrysalide.
 *
 *  OpenIDA 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.
 *
 *  OpenIDA 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 <http://www.gnu.org/licenses/>.
 */


#include "data.h"


#include "../register.h"
#include "../../operand-int.h"



/* Définition d'un opérande x86 de manipulation de données (instance) */
struct _GX86DataOperand
{
    GArchOperand parent;                    /* Instance parente            */

    GX86Register *reg;                      /* Registre représenté         */
    bool dest;                              /* Déduction du type de segment*/

};

/* Définition d'un opérande x86 de manipulation de données (classe) */
struct _GX86DataOperandClass
{
    GArchOperandClass parent;               /* Classe parente              */

};


/* Initialise la classe des opérandes x86 pointant des données. */
static void g_x86_data_operand_class_init(GX86DataOperandClass *);

/* Initialise une instance d'opérande x86 pointant des données. */
static void g_x86_data_operand_init(GX86DataOperand *);



/* Indique le type défini par la GLib pour un opérande x86 de manipulation de données. */
G_DEFINE_TYPE(GX86DataOperand, g_x86_data_operand, G_TYPE_ARCH_OPERAND);


/******************************************************************************
*                                                                             *
*  Paramètres  : klass = classe à initialiser.                                *
*                                                                             *
*  Description : Initialise la classe des opérandes x86 pointant des données. *
*                                                                             *
*  Retour      : -                                                            *
*                                                                             *
*  Remarques   : -                                                            *
*                                                                             *
******************************************************************************/

static void g_x86_data_operand_class_init(GX86DataOperandClass *klass)
{

}


/******************************************************************************
*                                                                             *
*  Paramètres  : operand = instance à initialiser.                            *
*                                                                             *
*  Description : Initialise une instance d'opérande pointant des données.     *
*                                                                             *
*  Retour      : -                                                            *
*                                                                             *
*  Remarques   : -                                                            *
*                                                                             *
******************************************************************************/

static void g_x86_data_operand_init(GX86DataOperand *operand)
{

}


/******************************************************************************
*                                                                             *
*  Paramètres  : size = taille de l'opérande, et donc du registre.            *
*                dest = indique si la cible est une destination ou une source.*
*                                                                             *
*  Description : Crée un opérande x86 de manipulation de données.             *
*                                                                             *
*  Retour      : Opérande mis en place.                                       *
*                                                                             *
*  Remarques   : -                                                            *
*                                                                             *
******************************************************************************/

GArchOperand *g_x86_data_operand_new(MemoryDataSize size, bool dest)
{
    GX86DataOperand *result;                /* Structure à retourner       */

    result = g_object_new(G_TYPE_X86_DATA_OPERAND, NULL);

    result->reg = g_x86_register_new(MDS_32_BITS/* FIXME size*/, dest ? 0x07 : 0x06);
    result->dest = dest;

    return G_ARCH_OPERAND(result);

}


#if 0
/******************************************************************************
*                                                                             *
*  Paramètres  : operand = opérande à transcrire.                             *
*                options   = options de rendu.                                *
*                rendering = support effectif final des lignes de code.       *
*                stream    = flux ouvert en écriture.                         *
*                                                                             *
*  Description : Ajoute du texte simple à un fichier ouvert en écriture.      *
*                                                                             *
*  Retour      : -                                                            *
*                                                                             *
*  Remarques   : -                                                            *
*                                                                             *
******************************************************************************/

static void g_x86_data_operand_add_text(const GX86DataOperand *operand, GRenderingOptions *options, MainRendering rendering, FILE *stream)
{
    GContentExporter *exporter;             /* Autre vision de l'opérande  */

    exporter = G_CONTENT_EXPORTER(operand);

    if (operand->dest)
        g_content_exporter_insert_text(exporter, stream, "es:", 3, RTT_SEGMENT);
    else
        g_content_exporter_insert_text(exporter, stream, "ds:", 3, RTT_SEGMENT);

    g_content_exporter_insert_text(exporter, stream, "[", 1, RTT_HOOK);

    g_content_exporter_add_text(G_CONTENT_EXPORTER(operand->reg), options, rendering, stream);

    g_content_exporter_insert_text(exporter, stream, "]", 1, RTT_HOOK);

}


/******************************************************************************
*                                                                             *
*  Paramètres  : operand = opérande à transcrire.                             *
*                buffer  = espace où placer ledit contenu.                    *
*                options = options de rendu.                                  *
*                                                                             *
*  Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée.  *
*                                                                             *
*  Retour      : -                                                            *
*                                                                             *
*  Remarques   : -                                                            *
*                                                                             *
******************************************************************************/

static void g_x86_data_operand_to_buffer(const GX86DataOperand *operand, GBufferLine *buffer, GRenderingOptions *options)
{
    GContentExporter *exporter;             /* Autre vision de l'opérande  */

    exporter = G_CONTENT_EXPORTER(operand);

    if (operand->dest)
        g_content_exporter_insert_into_buffer(G_CONTENT_EXPORTER(operand), buffer, BLC_ASSEMBLY,
                                              "es:", 3, RTT_SEGMENT);
    else
        g_content_exporter_insert_into_buffer(G_CONTENT_EXPORTER(operand), buffer, BLC_ASSEMBLY,
                                              "ds:", 3, RTT_SEGMENT);

    g_content_exporter_insert_into_buffer(G_CONTENT_EXPORTER(operand), buffer, BLC_ASSEMBLY,
                                          "[", 1, RTT_HOOK);

    g_content_exporter_to_buffer(G_CONTENT_EXPORTER(operand->reg), buffer, options);

    g_content_exporter_insert_into_buffer(G_CONTENT_EXPORTER(operand), buffer, BLC_ASSEMBLY,
                                          "]", 1, RTT_HOOK);

}
#endif