/***********************************************************
Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
The Netherlands.

                        All Rights Reserved

Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the names of Stichting Mathematisch
Centrum or CWI or Corporation for National Research Initiatives or
CNRI not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.

While CWI is the initial source for this software, a modified version
is made available by the Corporation for National Research Initiatives
(CNRI) at the Internet address ftp://ftp.python.org.

STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.

******************************************************************/

/* File object implementation */

#include "allobjects.h"
#include "modsupport.h"
#include "structmember.h"
#include "ceval.h"

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

#ifdef THINK_C
#define HAVE_FOPENRF
#endif
#ifdef __MWERKS__
/* Mwerks fopen() doesn't always set errno */
#define NO_FOPEN_ERRNO
#endif

#define BUF(v) GETSTRINGVALUE((stringobject *)v)

#include <errno.h>

typedef struct {
	OB_HEAD
	FILE *f_fp;
	object *f_name;
	object *f_mode;
	int (*f_close) PROTO((FILE *));
	int f_softspace; /* Flag used by 'print' command */
} fileobject;

FILE *
getfilefile(f)
	object *f;
{
	if (f == NULL || !is_fileobject(f))
		return NULL;
	else
		return ((fileobject *)f)->f_fp;
}

object *
getfilename(f)
	object *f;
{
	if (f == NULL || !is_fileobject(f))
		return NULL;
	else
		return ((fileobject *)f)->f_name;
}

object *
newopenfileobject(fp, name, mode, close)
	FILE *fp;
	char *name;
	char *mode;
	int (*close) FPROTO((FILE *));
{
	fileobject *f = NEWOBJ(fileobject, &Filetype);
	if (f == NULL)
		return NULL;
	f->f_fp = NULL;
	f->f_name = newstringobject(name);
	f->f_mode = newstringobject(mode);
	f->f_close = close;
	f->f_softspace = 0;
	if (f->f_name == NULL || f->f_mode == NULL) {
		DECREF(f);
		return NULL;
	}
	f->f_fp = fp;
	return (object *) f;
}

object *
newfileobject(name, mode)
	char *name, *mode;
{
	extern int fclose PROTO((FILE *));
	fileobject *f;
	f = (fileobject *) newopenfileobject((FILE *)NULL, name, mode, fclose);
	if (f == NULL)
		return NULL;
#ifdef HAVE_FOPENRF
	if (*mode == '*') {
		FILE *fopenRF();
		f->f_fp = fopenRF(name, mode+1);
	}
	else
#endif
	{
		BGN_SAVE
		f->f_fp = fopen(name, mode);
		END_SAVE
	}
	if (f->f_fp == NULL) {
#ifdef NO_FOPEN_ERRNO
		if ( errno == 0 ) {
			err_setstr(IOError, "Cannot open file");
			DECREF(f);
			return NULL;
		}
#endif
		err_errno(IOError);
		DECREF(f);
		return NULL;
	}
	return (object *)f;
}

void
setfilebufsize(f, bufsize)
	object *f;
	int bufsize;
{
	if (bufsize >= 0) {
#ifdef HAVE_SETVBUF
		int type;
		switch (bufsize) {
		case 0:
			type = _IONBF;
			break;
		case 1:
			type = _IOLBF;
			bufsize = BUFSIZ;
			break;
		default:
			type = _IOFBF;
		}
		setvbuf(((fileobject *)f)->f_fp, (char *)NULL, type, bufsize);
#endif /* HAVE_SETVBUF */
	}
}

static object *
err_closed()
{
	err_setstr(ValueError, "I/O operation on closed file");
	return NULL;
}

/* Methods */

static void
file_dealloc(f)
	fileobject *f;
{
	if (f->f_fp != NULL && f->f_close != NULL) {
		BGN_SAVE
		(*f->f_close)(f->f_fp);
		END_SAVE
	}
	if (f->f_name != NULL)
		DECREF(f->f_name);
	if (f->f_mode != NULL)
		DECREF(f->f_mode);
	free((char *)f);
}

static object *
file_repr(f)
	fileobject *f;
{
	char buf[300];
	sprintf(buf, "<%s file '%.256s', mode '%.10s' at %lx>",
		f->f_fp == NULL ? "closed" : "open",
		getstringvalue(f->f_name),
		getstringvalue(f->f_mode),
		(long)f);
	return newstringobject(buf);
}

static object *
file_close(f, args)
	fileobject *f;
	object *args;
{
	int sts = 0;
	if (!getnoarg(args))
		return NULL;
	if (f->f_fp != NULL) {
		if (f->f_close != NULL) {
			BGN_SAVE
			errno = 0;
			sts = (*f->f_close)(f->f_fp);
			END_SAVE
		}
		f->f_fp = NULL;
	}
	if (sts == EOF)
		return err_errno(IOError);
	if (sts != 0)
		return newintobject((long)sts);
	INCREF(None);
	return None;
}

static object *
file_seek(f, args)
	fileobject *f;
	object *args;
{
	long offset;
	int whence;
	int ret;
	
	if (f->f_fp == NULL)
		return err_closed();
	whence = 0;
	if (!getargs(args, "l", &offset)) {
		err_clear();
		if (!getargs(args, "(li)", &offset, &whence))
			return NULL;
	}
	BGN_SAVE
	errno = 0;
	ret = fseek(f->f_fp, offset, whence);
	END_SAVE
	if (ret != 0) {
		err_errno(IOError);
		clearerr(f->f_fp);
		return NULL;
	}
	INCREF(None);
	return None;
}

#ifdef HAVE_FTRUNCATE
static object *
file_truncate(f, args)
	fileobject *f;
	object *args;
{
	long newsize;
	int ret;
	
	if (f->f_fp == NULL)
		return err_closed();
	if (!getargs(args, "l", &newsize)) {
		err_clear();
		if (!getnoarg(args))
		        return NULL;
		BGN_SAVE
		errno = 0;
		newsize =  ftell(f->f_fp); /* default to current position*/
		END_SAVE
		if (newsize == -1L) {
		        err_errno(IOError);
			clearerr(f->f_fp);
			return NULL;
		}
	}
	BGN_SAVE
	errno = 0;
	ret = fflush(f->f_fp);
	END_SAVE
	if (ret == 0) {
	        BGN_SAVE
		errno = 0;
		ret = ftruncate(fileno(f->f_fp), newsize);
		END_SAVE
	}
	if (ret != 0) {
		err_errno(IOError);
		clearerr(f->f_fp);
		return NULL;
	}
	INCREF(None);
	return None;
}
#endif /* HAVE_FTRUNCATE */

static object *
file_tell(f, args)
	fileobject *f;
	object *args;
{
	long offset;
	if (f->f_fp == NULL)
		return err_closed();
	if (!getnoarg(args))
		return NULL;
	BGN_SAVE
	errno = 0;
	offset = ftell(f->f_fp);
	END_SAVE
	if (offset == -1L) {
		err_errno(IOError);
		clearerr(f->f_fp);
		return NULL;
	}
	return newintobject(offset);
}

static object *
file_fileno(f, args)
	fileobject *f;
	object *args;
{
	if (f->f_fp == NULL)
		return err_closed();
	if (!getnoarg(args))
		return NULL;
	return newintobject((long) fileno(f->f_fp));
}

static object *
file_flush(f, args)
	fileobject *f;
	object *args;
{
	int res;
	
	if (f->f_fp == NULL)
		return err_closed();
	if (!getnoarg(args))
		return NULL;
	BGN_SAVE
	errno = 0;
	res = fflush(f->f_fp);
	END_SAVE
	if (res != 0) {
		err_errno(IOError);
		clearerr(f->f_fp);
		return NULL;
	}
	INCREF(None);
	return None;
}

static object *
file_isatty(f, args)
	fileobject *f;
	object *args;
{
	long res;
	if (f->f_fp == NULL)
		return err_closed();
	if (!getnoarg(args))
		return NULL;
	BGN_SAVE
	res = isatty((int)fileno(f->f_fp));
	END_SAVE
	return newintobject(res);
}

static object *
file_read(f, args)
	fileobject *f;
	object *args;
{
	int n, n1, n2, n3;
	object *v;
	
	if (f->f_fp == NULL)
		return err_closed();
	if (args == NULL)
		n = -1;
	else {
		if (!getargs(args, "i", &n))
			return NULL;
	}
	n2 = n >= 0 ? n : BUFSIZ;
	v = newsizedstringobject((char *)NULL, n2);
	if (v == NULL)
		return NULL;
	n1 = 0;
	BGN_SAVE
	for (;;) {
		n3 = fread(BUF(v)+n1, 1, n2-n1, f->f_fp);
		/* XXX Error check? */
		if (n3 == 0)
			break;
		n1 += n3;
		if (n1 == n)
			break;
		if (n < 0) {
			n2 = n1 + BUFSIZ;
			RET_SAVE
			if (resizestring(&v, n2) < 0)
				return NULL;
			RES_SAVE
		}
	}
	END_SAVE
	if (n1 != n2)
		resizestring(&v, n1);
	return v;
}

/* Internal routine to get a line.
   Size argument interpretation:
   > 0: max length;
   = 0: read arbitrary line;
   < 0: strip trailing '\n', raise EOFError if EOF reached immediately
*/

static object *
getline(f, n)
	fileobject *f;
	int n;
{
	register FILE *fp;
	register int c;
	register char *buf, *end;
	int n1, n2;
	object *v;

	fp = f->f_fp;
	n2 = n > 0 ? n : 100;
	v = newsizedstringobject((char *)NULL, n2);
	if (v == NULL)
		return NULL;
	buf = BUF(v);
	end = buf + n2;

	BGN_SAVE
	for (;;) {
		if ((c = getc(fp)) == EOF) {
			clearerr(fp);
			if (sigcheck()) {
				RET_SAVE
				DECREF(v);
				return NULL;
			}
			if (n < 0 && buf == BUF(v)) {
				RET_SAVE
				DECREF(v);
				err_setstr(EOFError,
					   "EOF when reading a line");
				return NULL;
			}
			break;
		}
		if ((*buf++ = c) == '\n') {
			if (n < 0)
				buf--;
			break;
		}
		if (buf == end) {
			if (n > 0)
				break;
			n1 = n2;
			n2 += 1000;
			RET_SAVE
			if (resizestring(&v, n2) < 0)
				return NULL;
			RES_SAVE
			buf = BUF(v) + n1;
			end = BUF(v) + n2;
		}
	}
	END_SAVE

	n1 = buf - BUF(v);
	if (n1 != n2)
		resizestring(&v, n1);
	return v;
}

/* External C interface */

object *
filegetline(f, n)
	object *f;
	int n;
{
	if (f == NULL) {
		err_badcall();
		return NULL;
	}
	if (!is_fileobject(f)) {
		object *reader;
		object *args;
		object *result;
		reader = getattr(f, "readline");
		if (reader == NULL)
			return NULL;
		if (n <= 0)
			args = mkvalue("()");
		else
			args = mkvalue("(i)", n);
		if (args == NULL) {
			DECREF(reader);
			return NULL;
		}
		result = call_object(reader, args);
		DECREF(reader);
		DECREF(args);
		if (result != NULL && !is_stringobject(result)) {
			DECREF(result);
			result = NULL;
			err_setstr(TypeError,
				   "object.readline() returned non-string");
		}
		if (n < 0 && result != NULL) {
			char *s = getstringvalue(result);
			int len = getstringsize(result);
			if (len == 0) {
				DECREF(result);
				result = NULL;
				err_setstr(EOFError,
					   "EOF when reading a line");
			}
			else if (s[len-1] == '\n') {
				if (result->ob_refcnt == 1)
					resizestring(&result, len-1);
				else {
					object *v;
					v = newsizedstringobject(s, len-1);
					DECREF(result);
					result = v;
				}
			}
		}
		return result;
	}
	if (((fileobject*)f)->f_fp == NULL)
		return err_closed();
	return getline((fileobject *)f, n);
}

/* Python method */

static object *
file_readline(f, args)
	fileobject *f;
	object *args;
{
	int n;

	if (f->f_fp == NULL)
		return err_closed();
	if (args == NULL)
		n = 0; /* Unlimited */
	else {
		if (!getintarg(args, &n))
			return NULL;
		if (n == 0)
			return newstringobject("");
		if (n < 0)
			n = 0;
	}

	return getline(f, n);
}

static object *
file_readlines(f, args)
	fileobject *f;
	object *args;
{
	object *list;
	object *line;

	if (f->f_fp == NULL)
		return err_closed();
	if (!getnoarg(args))
		return NULL;
	if ((list = newlistobject(0)) == NULL)
		return NULL;
	for (;;) {
		line = getline(f, 0);
		if (line != NULL && getstringsize(line) == 0) {
			DECREF(line);
			break;
		}
		if (line == NULL || addlistitem(list, line) != 0) {
			DECREF(list);
			XDECREF(line);
			return NULL;
		}
		DECREF(line);
	}
	return list;
}

static object *
file_write(f, args)
	fileobject *f;
	object *args;
{
	char *s;
	int n, n2;
	if (f->f_fp == NULL)
		return err_closed();
	if (!getargs(args, "s#", &s, &n))
		return NULL;
	f->f_softspace = 0;
	BGN_SAVE
	errno = 0;
	n2 = fwrite(s, 1, n, f->f_fp);
	END_SAVE
	if (n2 != n) {
		err_errno(IOError);
		clearerr(f->f_fp);
		return NULL;
	}
	INCREF(None);
	return None;
}

static object *
file_writelines(f, args)
	fileobject *f;
	object *args;
{
	int i, n;
	if (f->f_fp == NULL)
		return err_closed();
	if (args == NULL || !is_listobject(args)) {
		err_setstr(TypeError,
			   "writelines() requires list of strings");
		return NULL;
	}
	n = getlistsize(args);
	f->f_softspace = 0;
	BGN_SAVE
	errno = 0;
	for (i = 0; i < n; i++) {
		object *line = getlistitem(args, i);
		int len;
		int nwritten;
		if (!is_stringobject(line)) {
			RET_SAVE
			err_setstr(TypeError,
				   "writelines() requires list of strings");
			return NULL;
		}
		len = getstringsize(line);
		nwritten = fwrite(getstringvalue(line), 1, len, f->f_fp);
		if (nwritten != len) {
			RET_SAVE
			err_errno(IOError);
			clearerr(f->f_fp);
			return NULL;
		}
	}
	END_SAVE
	INCREF(None);
	return None;
}

static struct methodlist file_methods[] = {
	{"close",	(method)file_close, 0},
	{"flush",	(method)file_flush, 0},
	{"fileno",	(method)file_fileno, 0},
	{"isatty",	(method)file_isatty, 0},
	{"read",	(method)file_read, 0},
	{"readline",	(method)file_readline, 0},
	{"readlines",	(method)file_readlines, 0},
	{"seek",	(method)file_seek, 0},
#ifdef HAVE_FTRUNCATE
	{"truncate",	(method)file_truncate, 0},
#endif
	{"tell",	(method)file_tell, 0},
	{"write",	(method)file_write, 0},
	{"writelines",	(method)file_writelines, 0},
	{NULL,		NULL}		/* sentinel */
};

#define OFF(x) offsetof(fileobject, x)

static struct memberlist file_memberlist[] = {
	{"softspace",	T_INT,		OFF(f_softspace)},
	{"mode",	T_OBJECT,	OFF(f_mode),	RO},
	{"name",	T_OBJECT,	OFF(f_name),	RO},
	/* getattr(f, "closed") is implemented without this table */
	{"closed",	T_INT,		0,		RO},
	{NULL}	/* Sentinel */
};

static object *
file_getattr(f, name)
	fileobject *f;
	char *name;
{
	object *res;

	res = findmethod(file_methods, (object *)f, name);
	if (res != NULL)
		return res;
	err_clear();
	if (strcmp(name, "closed") == 0)
		return newintobject((long)(f->f_fp == 0));
	return getmember((char *)f, file_memberlist, name);
}

static int
file_setattr(f, name, v)
	fileobject *f;
	char *name;
	object *v;
{
	if (v == NULL) {
		err_setstr(AttributeError, "can't delete file attributes");
		return -1;
	}
	return setmember((char *)f, file_memberlist, name, v);
}

typeobject Filetype = {
	OB_HEAD_INIT(&Typetype)
	0,
	"file",
	sizeof(fileobject),
	0,
	(destructor)file_dealloc, /*tp_dealloc*/
	0,		/*tp_print*/
	(getattrfunc)file_getattr, /*tp_getattr*/
	(setattrfunc)file_setattr, /*tp_setattr*/
	0,		/*tp_compare*/
	(reprfunc)file_repr, /*tp_repr*/
};

/* Interface for the 'soft space' between print items. */

int
softspace(f, newflag)
	object *f;
	int newflag;
{
	int oldflag = 0;
	if (f == NULL) {
		/* Do nothing */
	}
	else if (is_fileobject(f)) {
		oldflag = ((fileobject *)f)->f_softspace;
		((fileobject *)f)->f_softspace = newflag;
	}
	else {
		object *v;
		v = getattr(f, "softspace");
		if (v == NULL)
			err_clear();
		else {
			if (is_intobject(v))
				oldflag = getintvalue(v);
			DECREF(v);
		}
		v = newintobject((long)newflag);
		if (v == NULL)
			err_clear();
		else {
			if (setattr(f, "softspace", v) != 0)
				err_clear();
			DECREF(v);
		}
	}
	return oldflag;
}

/* Interfaces to write objects/strings to file-like objects */

int
writeobject(v, f, flags)
	object *v;
	object *f;
	int flags;
{
	object *writer, *value, *args, *result;
	if (f == NULL) {
		err_setstr(TypeError, "writeobject with NULL file");
		return -1;
	}
	else if (is_fileobject(f)) {
		FILE *fp = getfilefile(f);
		if (fp == NULL) {
			err_closed();
			return -1;
		}
		return printobject(v, fp, flags);
	}
	writer = getattr(f, "write");
	if (writer == NULL)
		return -1;
	if (flags & PRINT_RAW)
		value = strobject(v);
	else
		value = reprobject(v);
	if (value == NULL) {
		DECREF(writer);
		return -1;
	}
	args = mkvalue("(O)", value);
	if (value == NULL) {
		DECREF(value);
		DECREF(writer);
		return -1;
	}
	result = call_object(writer, args);
	DECREF(args);
	DECREF(value);
	DECREF(writer);
	if (result == NULL)
		return -1;
	DECREF(result);
	return 0;
}

void
writestring(s, f)
	char *s;
	object *f;
{
	if (f == NULL) {
		/* Do nothing */
	}
	else if (is_fileobject(f)) {
		FILE *fp = getfilefile(f);
		if (fp != NULL)
			fputs(s, fp);
	}
	else if (!err_occurred()) {
		object *v = newstringobject(s);
		if (v == NULL) {
			err_clear();
		}
		else {
			if (writeobject(v, f, PRINT_RAW) != 0)
				err_clear();
			DECREF(v);
		}
	}
}
