/*

$FILE		:	buffer.c
$VERSIONE	:	1.00
$DATA		:	Novembre 1991
$PROGETTO	:	Tecniche OOP in C, seconda soluzione
$AUTORE		:	Paolo Sommaruga
$RUOLO		:	File di codifica del dispatcher e dei metodi di BUFFER.
$USO		:	E` il file principale dell'oggetto BUFFER.

*/

#include "libraries/dos.h"
#include "exec/exec.h"

#include "buffer.h"

extern CLS CommonClass;

static int fPrimaVolta = TRUE;

static int M_ALLOC();
static int M_FREE();
static int M_DIST();
static MTD BufferMetodi[] =
    {
        { MSG_ALLOC , M_ALLOC },
        { MSG_FREE , M_FREE },
		{ MSG_OFF , M_DIST },		/* MSG_OFF e` in oopc.h, unico per tutti */
        { MSG_NULL, NULL }			/* lo stesso per MSG_NULL */
    };

static CLS *pAncestor = &CommonClass;
static CLS BufferClass = { "BUFFER", (MTD *)&BufferMetodi, NULL };

/*--------------------------------
	BUFFER: Constructor di buffer.
*/

int BUFFER( pNew )
POGT pNew;

{
#define METODO_CB  "Metodo di creazione BUFFER."
#define E_NOMEM_BD "ERRORE: Fallita AllocMem per BUFFER: area dati."

int errore;
BDB *pTempBdb;

/* Se e` la prima chiamata, inizializza bene BufferClass */
if ( fPrimaVolta )
	{
	CCLS( BufferClass.cls_pAncestor , pAncestor );
	fPrimaVolta = FALSE;
	} /* if */

/* alloca la memoria per la struttura di controllo dell'oggetto */
errore = NSC( pNew );
    if ( errore )	return errore;

/* alloca la memoria per le proprieta` dell'oggetto BUFFER */
    /* nessuna proprieta`*/

/* alloca la memoria per i dati pubblici dell'oggetto BUFFER */
pNew->ogt_pPublic = (BDB *)AllocMem( sizeof( BDB ) , MEMF_PUBLIC|MEMF_CLEAR );

if ( !pNew->ogt_pPublic ) {
    DSC( pNew );
    INFO_SET( METODO_CB , E_NOMEM_BD );
    return RETURN_FAIL;
} /* if */

			/* assegna la classe */
CCLS( &BufferClass , pNew->ogt_pClass );

			/* assegna le proprieta` */
pNew->ogt_pProps = NULL;

			/* assegna i dati pubblici */
pTempBdb = (BDB *)pNew->ogt_pPublic;
	pTempBdb->bdb_pBuf = NULL;
	pTempBdb->bdb_Len  = 0L;

return RETURN_OK;
} /* Fine di BUFFER */

/*----------------------------------------------------------------
    M_ALLOC: Alloca un blocco di memoria lungo p_map->map_Len e lo
                linka all'oggetto puntato, con la lunghezza.
*/

static int M_ALLOC( oGen )
POGT oGen;

{
#define METODO_AB "Metodo di allocazione BUFFER."
#define E_NOMEM_B "ERRORE FATALE: Fallita AllocMem per BUFFER."

/* Assegno un ptr temporaneo con un cast per evitare casini */
BDB *pDati;
pDati = (BDB *)oGen->ogt_pPublic;

pDati->bdb_pBuf = (UBYTE *)AllocMem( pDati->bdb_Len , MEMF_PUBLIC|MEMF_CLEAR );

if ( !pDati->bdb_pBuf ) {
    INFO_SET( METODO_AB , E_NOMEM_B );
    return RETURN_FAIL;
} /* if */

return RETURN_OK;
} /* Fine di M_ALLOC */

/*----------------------------------------------------------
    M_FREE: De-alloca il buffer lasciando in vita l'oggetto.
*/

static int M_FREE( oGen )
POGT oGen;

{
/* Assegno un ptr temporaneo con un cast per evitare casini */
BDB *pDati;
pDati = (BDB *)oGen->ogt_pPublic;

FreeMem( pDati->bdb_pBuf , pDati->bdb_Len );

return RETURN_OK;
} /* Fine di M_FREE */

/*---------------------------------------------------------------------
    M_DIST: De-alloca il buffer e distrugge l'oggetto.
            IMPORTANTE: il puntatore all'oggetto DEVE essere invalidato
            dal programma client. ( per ora! )
*/

static int M_DIST( oOld )
POGT oOld;

{
(void)M_FREE( oOld );	/* con questa chiudo il buffer vero */

FreeMem( oOld->ogt_pPublic , sizeof( BDB ) );	/* qui libero l'area dati */

DSC( oOld );			/* questa DeAlloca l'oggetto */

return RETURN_OK;
} /* Fine di M_DIST */

/* fine del file */
