/*

fmlib.h

Header della fm.lib.
Funzioni per: Apertura e chiusura files.
              Allocazione di un buffer e suo rilascio.
              Lettura dati da file in buffer.
              Gestione di due righe di informazioni ad uso delle funzioni
                per i propri messaggi.
              Gestione di una funzione che chiama una funzione utente con
                le due righe info come parametri.

*/

#include <exec/types.h>

#define H_FMLIB 1

#define NOME_DOS 34         /* lunghezza massima filename ADOS */
#define CAR_NOME 108
#define CAR_PATH 512

#define AF_RIGHTSEL 0
#define AF_RCLOSED  1
#define AF_BADSEL   2
#define AF_NOTSEL   3

/*

Nota: Le seguenti typedefs servono al passaggio dei parametri con le funzioni
      che  ritornano,  fino ad un certo livello, un intero che, se non nullo,
      indica  una  eccezione.   I  nomi  sono  composti  dalle iniziali della
      funzione  a  cui  il tipo si riferisce e da PB per Parameter Block o RB
      per  Result Block; cercando di rimanere nelle quattro lettere si lascia
      aperta  la porta alla possibilita` diagnostica di scrivere le strutture
      in files IFF.
            (vedi in proposito il FORM PGTB P)roG)ram T)race B)ack,
            di John Toebes in: Amiga ROM KERNEL Include & AutoDocs)

*/

typedef struct datifile {
    struct FileHandle *df_fh;
    char df_nome[ CAR_NOME ];
    char df_path[ CAR_PATH ];
    LONG df_protection;
    LONG df_size;
    char df_date[9];
    char df_time[9];
} FDAT;

typedef struct aprifile_p {
    char *fp_title;
    int   fp_modo;      /* 1=MODE_OLDFILE ; 0=MODE_NEWFILE */
} AFPB;

typedef FDAT AFRB;

typedef struct datibuf {
    UBYTE *bd_buf;              /* puntatore al buffer */
    long   bd_len;              /* lunghezza (del file o del buffer) */
} BUFD;

typedef struct leggi_pb {
    char *lf_nome;
    BOOL nome_vuoto;            /* TRUE se il nome non e` assegnato */
} LFPB;

typedef BUFD LFRB;  /* typedef struct leggi_rb { BUFD } LFRB */
typedef LFPB SFPB;  /* typedef struct scrivi_pb { LFPB } SFPB */
typedef BUFD SFRB;  /* typedef struct scrivi_rb { BUFD } SFRB */

/*

Funzioni per la gestione di due linee di messaggio e loro output.

INFO_SET  Riceve  e custodisce due stringhe da 75 caratteri; se piu` lunghe le
          tronca automaticamente.

INFORMA   Invoca la funzione passata come parametro con le due stringhe di cui
          sopra.   In  tale  modo,  le  funzioni  che  hanno  un  messaggio da
          inoltrare  usano  le due stringhe (tipicamente un errore), ritornano
          un   valore   non   nullo,  quindi  il   programma  principale  puo`
          visualizzare le stringhe secondo una propria modalita`.

            NOTA  IMPORTANTE:  Questo sistema e` propriamente un gestore
            di  MESSAGGI  di  ERRORE,  non  degli errori stessi.  Questo
            perche` ogni funzione possa contenere i messaggi appropriati
            senza  costringere  il  programma a mappare gli errori con i
            messaggi.   In  assenza  (per  ora) di una codifica omogenea
            degli  errori  (cioe`  anche  non  sovrapposta  agli  errori
            predefiniti  di  Amiga),  si  rende necessario un sistema di
            output  che  permetta  all'utente la scelta tra continuare o
            terminare,  eventualmente  specificando,  come e` il caso di
            ALLOCA_BUFFER, che tale errore non e` rimediabile.  Il tutto
            perche` allo stato attuale non e` codificata una convenzione
            interna alla libreria per distinguere gli errori, ad esempio
            come  in <libraries/dos.h>.
            (Bastava poco, sara` senz'altro nella prossima versione!)

*/

extern void INFO_SET();     /* void INFO_SET( char * , char * ) */
extern int  INFORMA();      /*  int INFORMA( int (*fn)(char * , char *) */

/*

ARPFREQ  Richiama il File Requester  di Arp ritornando  un codice sensato. Se
         il valore di ritorno e` != 0, l'utente ha chiuso il requester oppure
         ha digitato un filename errato. La funzione avra` gia` notificato la
         natura del guaio in INFO_SET.

*/

extern int ARPFREQ();       /* int ARPFREQ( char * ) */

/*

Funzioni di gestione basilare dei files.

 Nel  programma  queste  funzioni  non sono menzionate, perche` il loro uso e`
nelle  successive, ad un livello piu` alto.  Tuttavia sono disponibili per una
chiamata diretta.

APRI_FILE  Il  codice  chiamante deve inizializzare due strutture AFPB & AFRB,
           oppure aver ricevuto i relativi puntatori, e chiamare ARPI_FILE con
           i puntatori alle strutture. AFRB conterra` i dati necessari.

CHIUDI_FILE  Chiude il file. La funzione e` void perche` questa libreria e` al
             momento preparata per programmi con UN file ed UN buffer; in tale
             ipotesi, APRI_FILE conserva una copia privata  del File Handle in
             uso; CHIUDI_FILE annulla  coerentemente  con  le  chiamate questa
             copia. In questo modo il programma prinicipale non  ha necessita`
             di conoscere e conservare il File Handle.

ESISTE_FILE  Una semplice funzione di supporto. Ritorna TRUE se il file esiste
             altrimenti FALSE. Nella attuale codifica questa funzione tenta un
             Lock sul file. Se non riesce, lo da` per inesistente.

*/

extern int  APRI_FILE();        /*  int APRI_FILE( AFPB * , AFRB * ) */
extern void CHIUDI_FILE();      /* void CHIUDI_FILE( void ) */
extern BOOL ESISTE_FILE();      /* BOOL ESISTE_FILE( char * ) */

/*

Funzioni di lettura e scrittura file ad alto livello.

 Queste funzioni sono la vera chiave dell'input/output. Si occupano di aprire
il file, allocare il buffer lungo come il file, leggere il  file nel buffer e
chiudere il file stesso. Contengono la completa gestione degli errori, sempre
secondo INFO_SET | INFORMA.

LEGGI_FILE  Il codice chiamante deve predisporre le strutture  LFPB & LFRB  e
            invocare la funzione passando gli indirizzi. In caso di funziona_
            mento corretto saranno noti indirizzo e lunghezza del buffer, al_
            trimenti l'errore sara` specificato nel solito modo.

SCRIVI_FILE  Con il solito metodo di chiamata, il contenuto  del buffer viene
             scritto nel file (sovrascritto se il file esiste !!). Al termine
             Il file viene chiuso ed il buffer deallocato. Sara`  compito del
             chiamante azzerare puntatore e lunghezza del buffer.

*/

extern int LEGGI_FILE();    /* int LEGGI_FILE( LFPB * , LFRB *) */
extern int SCRIVI_FILE();   /* int SCRIVI_FILE( SFPB * , SFRB *) */

/*

Funzioni di gestione di UN buffer.

 Anche queste funzioni non sono in  realta` usate direttamente dal programma,
ma chiamate da altre funzioni interne  alla libreria. Tuttavia sono anch'esse
disponibili per una chiamata diretta.

ALLOCA_BUFFER  In questo caso si setta BUFD.bd_len con la lunghezza desidera_
               ta, e ci  si trova con  bd_buf  contenente l'indirizzo. Poteva
               senza difficolta` essere codificata con:

                        buffer_ptr = ALLOCA_BUFFER( lunghezza )

               ma cio` interferiva con la catena di errori di ritorno. Invece
               codificare ABPB contenente la sola lunghezza e ABRB contenente
               il solo indirizzo era una ridondanza inutile, per  quanto piu`
               aperta ad eventali estensioni.

LIBERA_BUFFER  Come per il File Handle visto prima, anche in  questo  caso si
               conserva una copia privata del puntatore al buffer. Sebbene il
               programma principale debba conoscere tale valore, questo meto_
               do permette  di scrivere,  all'occorrenza,  funzioni di uscita
               anormale che sappiano di dover liberare il buffer senza sapere
               il valore dell'indirizzo. Come in CHIUDI_FILE, il valore della
               copia interna viene azzerato, con un check tale per cui in ca_
               so di valore nullo non viene eseguita la deallocazione ( e na_
               turalmente il valore interno puo` essere nullo SOLO SE e` gia`
               stata chiamata LIBERA_BUFFER e non e` stata ancora chiamata la
               sua controparte.

*/

extern int  ALLOCA_BUFFER();    /*  int ALLOCA_BUFFER( BUFD * ) */
extern void LIBERA_BUFFER();    /* void LIBERA_BUFFER( void ) */
