/***********************************************************
Copyright 1991 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 "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;
			extern object *getdict2key();
			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();
			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);
}
