/*
 * This file is part of the Poliqarp suite.
 * 
 * Copyright (C) 2004-2009 by Instytut Podstaw Informatyki Polskiej
 * Akademii Nauk (IPI PAN; Institute of Computer Science, Polish
 * Academy of Sciences; cf. www.ipipan.waw.pl).  All rights reserved.
 * 
 * This file may be distributed and/or modified under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation and appearing in the file gpl.txt included in the packaging
 * of this file.  (See http://www.gnu.org/licenses/translations.html for
 * unofficial translations.)
 * 
 * A commercial license is available from IPI PAN (contact
 * Michal.Ciesiolka@ipipan.waw.pl or ipi@ipipan.waw.pl for more
 * information).  Licensees holding a valid commercial license from IPI
 * PAN may use this file in accordance with that license.
 * 
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE.
 */

#include "lisp-file-stream.h"

int lisp_file_stream_read(struct lisp_stream *ls)
{
   struct lisp_file_stream *lfs;
   if (ls->unget_char != -1) {
      int c = ls->unget_char;
      ls->unget_char = -1;
      return c;
   }
   lfs = (void *) (((char *) ls) + sizeof *ls);
   if (lfs->curr == lfs->end) {
      size_t n_read = fread(lfs->buf, 1, lfs->size, lfs->stream);
      lfs->curr = lfs->buf;
      lfs->end = lfs->buf + n_read;
      if (n_read == 0)
         return -1;
   }
   return *lfs->curr++;
}

void lisp_file_stream_close(struct lisp_stream *ls)
{
   struct lisp_file_stream *lfs;
   lfs = (void *) (((char *) ls) + sizeof *ls);

   fclose(lfs->stream);
   free(lfs->buf);
   free(ls);
}

struct lisp_stream *make_file_stream(struct lisp_env *env,
   const char *pathname)
{
   struct lisp_stream *ls;
   struct lisp_file_stream *lfs;
   FILE *stream;

   stream = fopen(pathname, "rt");

   if (stream == NULL)
      return NULL;

   ls = malloc(sizeof *ls + sizeof *lfs);
   make_stream(env, ls);
   lfs = (void *) (((char *) ls) + sizeof *ls);

   ls->read = lisp_file_stream_read;
   ls->close = lisp_file_stream_close;

   lfs->stream = stream;
   lfs->size = 4096;
   lfs->buf = malloc(lfs->size);
   lfs->end = lfs->buf;
   lfs->curr = lfs->buf;

   return ls;
}
