import java.io.*;
import java.util.*;

/**
 * Classe che ingloba un file e fornisce alcune funzioni per leggere
 * stringhe, parole chiave, interi e double da tale file.
 * Ha anche una funzione per leggere una stringa contenente al suo
 * interno anche spazi, compresa fra due delimitatori (chiamiamo
 * "titolo" una tale stringa).
 * La classe Java FileInputStream (che e' anche un InputStream) 
 * non fornisce funzioni a questo scopo (devo leggere byte per byte).
 */
public class MyReader 
{
  /** File di input da cui leggere */ protected InputStream fd;

/** Apre file con nome dato e crea reader su quel file. */
  public MyReader(String name) throws IOException
  {  fd = new FileInputStream(name);  }

/** Crea reader su file gia' aperto. */
  public MyReader(InputStream ffdd) {  fd = ffdd;  }

/** Salta spazi e ritorna codice del primo carattere non 
    spazio (-1 se fine file). */
  protected int skipWhitespace() throws IOException
  {
    int cod = (int)(' ');
    while (Character.isWhitespace( (char)cod ))
    {
      cod = fd.read();
      if (cod == -1) return -1;
    } 
    return cod;
  }

/** Legge una stringa e la ritorna, lascia il file posizionato sul
    primo carattere seguente. */
  public String readString() throws IOException
  {
    StringBuffer s = new StringBuffer("");
    int cod = skipWhitespace();
    while ( (cod!=-1) && !Character.isWhitespace( (char)cod ))
    {
      s.append( (char)cod );
      cod = fd.read();
    }
    return new String(s);
  }

/** Controlla uguaglianza tra una stringa e una parola
    chiave assegnata, ritorna true se uguale e false se diversa. */
  public boolean isKeyword(String s, String kw)
  {
    return (kw.compareTo(s) == 0);
  }

/** Legge nel file una stringa e controlla che sia la parola 
    chiave indicata. */
  public boolean findKeyword(String kw)
  {
    try
    {
      String s = readString();
      return (isKeyword(s,kw));
    }
    catch (Exception excp) { return false; }
  }
  
/** Legge un intero e lo ritorna, lascia il file posizionato sul
    primo carattere seguente. */
  public int readInteger() throws IOException, NumberFormatException
  {
    String s = readString();
    if (s.length()==0) throw new IOException("Integer expected");
    return Integer.valueOf(s).intValue();
  } 

/** Legge un numero reale e lo ritorna, lascia il file posizionato sul
    primo carattere seguente. */
  public double readDouble() throws IOException, NumberFormatException
  {
    String s = readString();
    if (s.length()==0) throw new IOException("Float expected");
    return Double.valueOf(s).doubleValue();
  } 

  /** Delimitatore iniziale per stringa titolo. */
  public static final char INIZIO = '[';
  /** Delimitatore finale per stringa titolo. */
  public static final char FINE = ']';

  /** Legge un titolo (cioe' una stringa contenente anche spazi compresa
      tra delimitatore uno iniziale e uno finale). */
  public String readTitle() throws IOException
  {
    StringBuffer titolo = new StringBuffer();
    boolean trovatoInizio = false;
    boolean trovataFine = false; 
    int codice;
    char carattere;

    while (!trovatoInizio)
    {
       codice=fd.read();
       if ( codice != -1 )
       {  carattere = (char)codice;
          if (carattere==INIZIO) trovatoInizio = true;
       }
       else trovatoInizio = true;
    }
    while (!trovataFine)
    {
       codice=fd.read();
       if ( codice != -1 )
       {  carattere = (char)codice;
          if (carattere==FINE) trovataFine = true;
          else titolo.append(carattere);
       }
       else trovataFine = true;
    }
    return new String(titolo);
  }

};

