/* classes: src_files */

/*	Copyright (C) 1995 Free Software Foundation, Inc.
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this software; see the file COPYING.  If not, write to
 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 */




#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "scm.h"



/* Turning files into strings */
static char s_map_file[]="map-file";

#define CHUNK_SIZE 4096

static SCM
map_file (filename)
     SCM filename;
{
  char * name;
  SCM answer;

  ASSERT(NIMP(filename) && STRINGP(filename), filename, ARG1, s_map_file);
  name = CHARS(filename);

  NEWCELL(answer);

  /* Not as fast as possible, but fast and portable. */
  DEFER_INTS;
  {
    int fd;
    char * bytes;
    int allocated;
    int used;
    int last_read;
    int approx_size;

    fd = open (name, O_RDONLY);

    if (fd < 0)
      return EOF_VAL;

    {
      struct stat statb;

      if (fstat (fd, &statb) < 0)
	{
	  close (fd);
	  return EOF_VAL;
	}
      approx_size = 1 + statb.st_size;
    }

    bytes = scm_must_malloc (approx_size, s_map_file);
    allocated = approx_size;
    used = 0;
    while ((last_read = read (fd, bytes + used, allocated - used)))
      {
	if (used + last_read == allocated)
	  {
	    bytes = scm_must_realloc (bytes,
				  allocated,
				  last_read + used + CHUNK_SIZE,
				  s_map_file);
	    allocated = last_read + used + CHUNK_SIZE;
	  }
	used += last_read;
      }

    if (allocated != used + 1)
      bytes = scm_must_realloc (bytes, allocated, used + 1, s_map_file);
    bytes[used] = 0;
    SETCHARS(answer, bytes);
    SETLENGTH(answer, used, tc7_string);
  }
  ALLOW_INTS;
  return answer;
}



void
scm_init_fastio ()
{
  scm_make_gsubr (s_map_file, 1, 0, 0, map_file);
}
