/***********************************************************
Copyright 1991, 1992 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 not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior permission.

STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM 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.

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

/* Write Python objects to files and read them back.
   This is intended for writing and reading compiled Python code only;
   a true persistent storage facility would be much harder, since
   it would have to take circular links and sharing into account. */

#include "allobjects.h"
#include "modsupport.h"
#include "longintrepr.h"
#include "compile.h"
#include "marshal.h"

#include <errno.h>
extern int errno;

#define TYPE_NULL	'0'
#define TYPE_NONE	'N'
#define TYPE_INT	'i'
#define TYPE_FLOAT	'f'
#define TYPE_LONG	'l'
#define TYPE_STRING	's'
#define TYPE_TUPLE	'('
#define TYPE_LIST	'['
#define TYPE_DICT	'{'
#define TYPE_CODE	'C'
#define TYPE_UNKNOWN	'?'

#define wr_byte(c, fp) putc((c), (fp))

void
wr_short(x, fp)
	int x;
	FILE *fp;
{
	wr_byte( x      & 0xff, fp);
	wr_byte((x>> 8) & 0xff, fp);
}

void
wr_long(x, fp)
	long x;
	FILE *fp;
{
	wr_byte((int)( x      & 0xff), fp);
	wr_byte((int)((x>> 8) & 0xff), fp);
	wr_byte((int)((x>>16) & 0xff), fp);
	wr_byte((int)((x>>24) & 0xff), fp);
}

void
wr_object(v, fp)
	object *v;
	FILE *fp;
{
	long i, n;
	
	if (v == NULL)
		wr_byte(TYPE_NULL, fp);
	else if (v == None)
		wr_byte(TYPE_NONE, fp);
	else if (is_intobject(v)) {
		wr_byte(TYPE_INT, fp);
		wr_long(getintvalue(v), fp);
	}
	else if (is_longobject(v)) {
		longobject *ob = (longobject *)v;
		wr_byte(TYPE_LONG, fp);
		n = ob->ob_size;
		wr_long((long)n, fp);
		if (n < 0)
			n = -n;
		for (i = 0; i < n; i++)
			wr_short(ob->ob_digit[i], fp);
	}
	else if (is_floatobject(v)) {
		extern void float_buf_repr PROTO((char *, floatobject *));
		char buf[256]; /* Plenty to format any double */
		float_buf_repr(buf, (floatobject *)v);
		n = strlen(buf);
		wr_byte(TYPE_FLOAT, fp);
		wr_byte((int)n, fp);
		fwrite(buf, 1, (int)n, fp);
	}
	else if (is_stringobject(v)) {
		wr_byte(TYPE_STRING, fp);
		n = getstringsize(v);
		wr_long(n, fp);
		fwrite(getstringvalue(v), 1, (int)n, fp);
	}
	else if (is_tupleobject(v)) {
		wr_byte(TYPE_TUPLE, fp);
		n = gettuplesize(v);
		wr_long(n, fp);
		for (i = 0; i < n; i++) {
			wr_object(gettupleitem(v, (int)i), fp);
		}
	}
	else if (is_listobject(v)) {
		wr_byte(TYPE_LIST, fp);
		n = getlistsize(v);
		wr_long(n, fp);
		for (i = 0; i < n; i++) {
			wr_object(getlistitem(v, (int)i), fp);
		}
	}
	else if (is_dictobject(v)) {
		wr_byte(TYPE_DICT, fp);
		/* This one is NULL object terminated! */
		n = getdictsize(v);
		for (i = 0; i < n; i++) {
			object *key, *val;
			key = getdict2key(v, (int)i);
			if (key != NULL) {
				val = dict2lookup(v, key); /* Can't be NULL */
				wr_object(key, fp);
				wr_object(val, fp);
			}
		}
		wr_object((object *)NULL, fp);
	}
	else if (is_codeobject(v)) {
		codeobject *co = (codeobject *)v;
		wr_byte(TYPE_CODE, fp);
		wr_object((object *)co->co_code, fp);
		wr_object(co->co_consts, fp);
		wr_object(co->co_names, fp);
		wr_object(co->co_filename, fp);
	}
	else {
		wr_byte(TYPE_UNKNOWN, fp);
	}
}

#define rd_byte(fp) getc(fp)

int
rd_short(fp)
	FILE *fp;
{
	register short x;
	x = rd_byte(fp);
	x |= rd_byte(fp) << 8;
	/* XXX If your short is > 16 bits, add sign-extension here!!! */
	return x;
}

long
rd_long(fp)
	FILE *fp;
{
	register long x;
	x = rd_byte(fp);
	x |= (long)rd_byte(fp) << 8;
	x |= (long)rd_byte(fp) << 16;
	x |= (long)rd_byte(fp) << 24;
	/* XXX If your long is > 32 bits, add sign-extension here!!! */
	return x;
}

object *
rd_object(fp)
	FILE *fp;
{
	object *v;
	long i, n;
	int type = rd_byte(fp);
	
	switch (type) {
	
	case EOF:
		err_setstr(EOFError, "EOF read where object expected");
		return NULL;
	
	case TYPE_NULL:
		return NULL;
	
	case TYPE_NONE:
		INCREF(None);
		return None;
	
	case TYPE_INT:
		return newintobject(rd_long(fp));
	
	case TYPE_LONG:
		{
			int size;
			longobject *ob;
			n = rd_long(fp);
			size = n<0 ? -n : n;
			ob = alloclongobject(size);
			if (ob == NULL)
				return NULL;
			ob->ob_size = n;
			for (i = 0; i < size; i++)
				ob->ob_digit[i] = rd_short(fp);
			return (object *)ob;
		}
	
	case TYPE_FLOAT:
		{
			extern double strtod PROTO((const char *, char **));
			char buf[256];
			double res;
			char *end;
			n = rd_byte(fp);
			if (fread(buf, 1, (int)n, fp) != n) {
				err_setstr(EOFError,
					"EOF read where object expected");
				return NULL;
			}
			buf[n] = '\0';
			errno = 0;
			res = strtod(buf, &end);
			if (*end != '\0') {
				err_setstr(ValueError, "bad float syntax");
				return NULL;
			}
			if (errno != 0) {
				err_setstr(ValueError,
					"float constant too large");
				return NULL;
			}
			return newfloatobject(res);
		}
	
	case TYPE_STRING:
		n = rd_long(fp);
		v = newsizedstringobject((char *)NULL, n);
		if (v != NULL) {
			if (fread(getstringvalue(v), 1, (int)n, fp) != n) {
				DECREF(v);
				v = NULL;
				err_setstr(EOFError,
					"EOF read where object expected");
			}
		}
		return v;
	
	case TYPE_TUPLE:
		n = rd_long(fp);
		v = newtupleobject((int)n);
		if (v == NULL)
			return v;
		for (i = 0; i < n; i++)
			settupleitem(v, (int)i, rd_object(fp));
		return v;
	
	case TYPE_LIST:
		n = rd_long(fp);
		v = newlistobject((int)n);
		if (v == NULL)
			return v;
		for (i = 0; i < n; i++)
			setlistitem(v, (int)i, rd_object(fp));
		return v;
	
	case TYPE_DICT:
		v = newdictobject();
		if (v == NULL)
			return NULL;
		for (;;) {
			object *key, *val;
			key = rd_object(fp);
			if (key == NULL)
				break;
			val = rd_object(fp);
			dict2insert(v, key, val);
			DECREF(key);
			XDECREF(val);
		}
		return v;
	
	case TYPE_CODE:
		{
			object *code = rd_object(fp);
			object *consts = rd_object(fp);
			object *names = rd_object(fp);
			object *filename = rd_object(fp);
			if (!err_occurred()) {
				v = (object *) newcodeobject(code,
						consts, names, filename);
			}
			else
				v = NULL;
			XDECREF(code);
			XDECREF(consts);
			XDECREF(names);
			XDECREF(filename);

		}
		return v;
	
	default:
		err_setstr(TypeError, "read unknown object");
		return NULL;
	
	}
}

/* And an interface for Python programs... */

static object *
dump(self, args)
	object *self;
	object *args;
{
	object *f;
	if (args == NULL || !is_tupleobject(args) || gettuplesize(args) != 2) {
		err_badarg();
		return NULL;
	}
	f = gettupleitem(args, 1);
	if (f == NULL || !is_fileobject(f)) {
		err_badarg();
		return NULL;
	}
	wr_object(gettupleitem(args, 0), getfilefile(f));
	INCREF(None);
	return None;
}

static object *
load(self, f)
	object *self;
	object *f;
{
	object *v;
	if (f == NULL || !is_fileobject(f)) {
		err_badarg();
		return NULL;
	}
	v = rd_object(getfilefile(f));
	if (err_occurred()) {
		XDECREF(v);
		v = NULL;
	}
	return v;
}

static struct methodlist marshal_methods[] = {
	{"dump",	dump},
	{"load",	load},
	{NULL,		NULL}		/* sentinel */
};

void
initmarshal()
{
	(void) initmodule("marshal", marshal_methods);
}
