/**
 * \file AllocateurXMLTag.cpp
 * Classe de gestion d'un allocateur d'objets XMLTag.
 * 
 * @author Nicolas Janey
 * @author nicolas.janey@univ-fcomte.fr
 * @version 1.0, 01/01/10
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <exception>

#include "AllocateurXMLTag.h"
#include "XMLTag.h"

using namespace std;

#define UNREFERENCED_PARAMETER(P) (P)

/**
 * Constructeur pour un objet AllocateurXMLTag.
 *
 * @param size La taille d'allocation pour les bancs memoire.
 * @author Nicolas Janey
 * @author nicolas.janey@univ-fcomte.fr
 * @version 1.0, 01/01/10
 */
AllocateurXMLTag::AllocateurXMLTag(int size) {
  this->size = size;
  this->sp = 0;
  this->spt = 1;
  t =(XMLTag **) calloc(1,sizeof(XMLTag *));
  t[0] = new XMLTag[size];
}

/**
 * Destructeur pour un objet AllocateurXMLTag.
 *
 * @author Nicolas Janey
 * @author nicolas.janey@univ-fcomte.fr
 * @version 1.0, 01/01/10
 */
AllocateurXMLTag::~AllocateurXMLTag(void) {
  for ( int i = 0 ; i < spt ; i++ )
    delete [] t[i];
  free(t);
}

/**
 * Allocation d'un objet XMLTag.
 *
 * @return Le tag alloue.
 * @author Nicolas Janey
 * @author nicolas.janey@univ-fcomte.fr
 * @version 1.0, 01/01/10
 */
XMLTag *AllocateurXMLTag::mynew(void) {
  if ( sp >= size ) {
    spt++;
    sp = 0;
    t =(XMLTag **) realloc(t,spt*sizeof(XMLTag *));
    if ( !t )
      printf("Out of memory\n");
    try {
      t[spt-1] = new XMLTag[size]; }
    catch (exception &e) {
      printf("Erreur: %s\n",e.what()); } }
  XMLTag *p = &t[spt-1][sp];
  sp++;
  return(p);
}

/**
 * Allocation d'un objet XMLTag.
 *
 * @param Le nom a donner au tag.
 * @return Le tag alloue.
 * @author Nicolas Janey
 * @author nicolas.janey@univ-fcomte.fr
 * @version 1.0, 01/01/10
 */
XMLTag *AllocateurXMLTag::mynew(char *name) {
  if ( sp >= size ) {
    spt++;
    sp = 0;
    t =(XMLTag **) realloc(t,spt*sizeof(XMLTag *));
    if ( !t )
      printf("Out of memory\n");
    try {
      t[spt-1] = new XMLTag[size]; }
    catch (exception &e) {
      printf("Erreur: %s\n",e.what()); } }
  XMLTag *p = &t[spt-1][sp];
  p->name = name;
  sp++;
  return(p);
}

/**
 * Retour du nombre de XMLTag alloues.
 *
 * @return Le nombre de XMLTag alloues.
 * @author Nicolas Janey
 * @author nicolas.janey@univ-fcomte.fr
 * @version 1.0, 01/01/10
 */
int AllocateurXMLTag::getNombreXMLTagAlloues(void) {
  return((spt-1)*size+sp);
}

/**
 * Retour de la quantite de memoire occupee par this.
 *
 * @return La quantite de memoire occupee par this.
 * @author Nicolas Janey
 * @author nicolas.janey@univ-fcomte.fr
 * @version 1.0, 01/01/10
 */
size_t AllocateurXMLTag::getUsedMemory(void) {
  size_t mem = sizeof(AllocateurXMLTag)+spt*(sizeof(XMLTag *));
  for ( int i = 0 ; i < spt ; i++ )
    for ( int j = 0 ; j < size ; j++ )
      mem += t[i][j].getUsedMemory();
  return(mem);
}

/**
 * Retour du nombre de handles memoire occupes par this.
 *
 * @return Le nombre de handle memoire occupes par this.
 * @author Nicolas Janey
 * @author nicolas.janey@univ-fcomte.fr
 * @version 1.0, 01/01/10
 */
long AllocateurXMLTag::getUsedHandles(void) {
  long mem = 2+spt;
  for ( int i = 0 ; i < spt ; i++ )
    for ( int j = 0 ; j < size ; j++ )
      mem += (t[i][j].getUsedHandles()-1);
  return(mem);
}
