/** FILE: buffer.java **/

package BUFFER;

import java.io.*;

// Referenced classes of package BUFFER:
//            accex

/*
 * CLASS buffer
 *
 * classe Astratta buffer che contiene i due medodi di inserimento e cancellazione:
 * Put() e Get() operazioni basi (NESSUNA POLITICA)
 * le politiche verranno implementate nelle classi bufferan, bufferfi e buffermy.
 * Contiene tutte le variabili in comune alle tre politiche e il medo stampa()
 */

public abstract class buffer
{

  /* 
   * METODI PUT() e GET()
   * void PUT(String msg) per inserire una stringa nel buffer
   * String GET() per leggere una stringa dal buffer
   */

    public void put(String s)
        throws InterruptedException
    {
        aux[in] = s.length(); // salva la lunghezza
        for(int i = 0; i < s.length(); i++)
            buff[(in + i) % 200] = s.charAt(i); // copia carattere per carattere

        in = (in + s.length()) % 200; //incrementa con modulo l'indice di scrittura
        liberi -= s.length(); // aggiorna lo spazio libero
        stampa("PUT:" + s);
    }

    public String get()
        throws InterruptedException
    {
        int i = aux[out]; // ricorda la lunghezza
        char ac[] = new char[i]; 
        for(int j = 0; j < i; j++)
            ac[j] = buff[(out + j) % 200]; // legge il messaggio carattere per carattere

        out = (out + i) % 200; // aggiorna con modulo l'indice di lettura
        liberi += i; // aggiorna lo spazio libero
        stampa("GET:" + new String(ac));
        return new String(ac);
    }


   /*
    * METODO stampa()
    *
    * stampa su monitor le opeazioni di put e get e le stampa anche su il file di log "output.txt"
    */

    void stampa(String s)
    {
        try
        {
            if(fout == null)
                fout = new FileOutputStream("output.txt");
            System.out.println(s + " " + accessi);
            fout.write((s + "\n").getBytes());
            return;
        }
        catch(IOException _ex)
        {
            return;
        }
    }

    public void chiudifile()
    {
        try
        {
            fout.close();
            return;
        }
        catch(IOException _ex)
        {
            return;
        }
    }

    public buffer()
    {
        buff = new char[200];
        aux = new int[200];
        liberi = 200;
        accput = new accex();
        accget = new accex();
        Startaccput = accput;
        Startaccget = accget;
    }

    char buff[];
    int aux[];
    int in;
    int out;
    int liberi;
    public int accessi;
    accex accput;
    accex accget;
    public accex Startaccput;
    public accex Startaccget;
    FileOutputStream fout;
}