/***********************************************************
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.

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

/* struct module -- pack values into and (out of) strings */

#include "allobjects.h"
#include "modsupport.h"

static object *StructError;


/* Define various structs to figure out the alignments of types */

typedef struct { char c; short x; } s_short;
typedef struct { char c; int x; } s_int;
typedef struct { char c; long x; } s_long;
typedef struct { char c; float x; } s_float;
typedef struct { char c; double x; } s_double;

#define SHORT_ALIGN (sizeof(s_short) - sizeof(short))
#define INT_ALIGN (sizeof(s_int) - sizeof(int))
#define LONG_ALIGN (sizeof(s_long) - sizeof(long))
#define FLOAT_ALIGN (sizeof(s_float) - sizeof(float))
#define DOUBLE_ALIGN (sizeof(s_double) - sizeof(double))


/* Align a size according to a format code */

static int
align(size, c)
	int size;
	int c;
{
	int a;

	switch (c) {
	case 'h': a = SHORT_ALIGN; break;
	case 'i': a = INT_ALIGN; break;
	case 'l': a = LONG_ALIGN; break;
	case 'f': a = FLOAT_ALIGN; break;
	case 'd': a = DOUBLE_ALIGN; break;
	default: return size;
	}
	return (size + a - 1) / a * a;
}


/* calculate the size of a format string */

static int
calcsize(fmt)
	char *fmt;
{
	char *s;
	char c;
	int size,  num, itemsize, x;

	s = fmt;
	size = 0;
	while ((c = *s++) != '\0') {
		if ('0' <= c && c <= '9') {
			num = c - '0';
			while ('0' <= (c = *s++) && c <= '9') {
				x = num*10 + (c - '0');
				if (x/10 != num) {
					err_setstr(StructError,
						   "int overflow in fmt");
					return -1;
				}
				num = x;
			}
			if (c == '\0')
				break;
		}
		else
			num = 1;
		
		size = align(size, c);
		
		switch (c) {
			
		case 'x': /* pad byte */
		case 'b': /* byte-sized int */
		case 'c': /* char */
			itemsize = 1;
			break;

		case 'h': /* short ("half-size)" int */
			itemsize = sizeof(short);
			break;

		case 'i': /* natural-size int */
			itemsize = sizeof(int);
			break;

		case 'l': /* long int */
			itemsize = sizeof(long);
			break;

		case 'f': /* float */
			itemsize = sizeof(float);
			break;

		case 'd': /* double */
			itemsize = sizeof(double);
			break;

		default:
			err_setstr(StructError, "bad char in fmt");
			return -1;

		}
		
		x = num * itemsize;
		size += x;
		if (x/itemsize != num || size < 0) {
			err_setstr(StructError, "total struct size too long");
			return -1;
		}
			
	}

	return size;
}


/* pack(fmt, v1, v2, ...) --> string */

static object *
struct_calcsize(self, args)
	object *self; /* Not used */
	object *args;
{
	char *fmt;
	int size;

	if (!getargs(args, "s", &fmt))
		return NULL;
	size = calcsize(fmt);
	if (size < 0)
		return NULL;
	return newintobject((long)size);
}


/* pack(fmt, v1, v2, ...) --> string */

static object *
struct_pack(self, args)
	object *self; /* Not used */
	object *args;
{
	object *format, *result, *v;
	char *fmt;
	int size, num;
	int i, n;
	char *s, *res, *restart;
	char c;
	long ival;
	double fval;

	if (args == NULL || !is_tupleobject(args) ||
	    (n = gettuplesize(args)) < 1) {
		err_badarg();
		return NULL;
	}
	format = gettupleitem(args, 0);
	if (!getargs(format, "s", &fmt))
		return NULL;
	size = calcsize(fmt);
	if (size < 0)
		return NULL;
	result = newsizedstringobject((char *)NULL, size);
	if (result == NULL)
		return NULL;

	s = fmt;
	i = 1;
	res = restart = getstringvalue(result);

	while ((c = *s++) != '\0') {
		if ('0' <= c && c <= '9') {
			num = c - '0';
			while ('0' <= (c = *s++) && c <= '9')
			       num = num*10 + (c - '0');
			if (c == '\0')
				break;
		}
		else
			num = 1;

		res = restart + align((int)(res-restart), c);

		while (--num >= 0) {
			switch (c) {

			case 'x': /* pad byte */
				*res++ = '\0';
				break;

			case 'l':
			case 'i':
			case 'h':
			case 'b':
				if (i >= n) {
					err_setstr(StructError,
					   "insufficient arguments to pack");
					goto fail;
				}
				v = gettupleitem(args, i++);
				if (!is_intobject(v)) {
					err_setstr(StructError,
					   "bad argument type to pack");
					goto fail;
				}
				ival = getintvalue(v);
				switch (c) {
				case 'b':
					*res++ = ival;
					break;
				case 'h':
					*(short*)res = ival;
					res += sizeof(short);
					break;
				case 'i':
					*(int*)res = ival;
					res += sizeof(int);
					break;
				case 'l':
					*(long*)res = ival;
					res += sizeof(long);
					break;
				}
				break;

			case 'c':
				if (i >= n) {
					err_setstr(StructError,
					   "insufficient arguments to pack");
					goto fail;
				}
				v = gettupleitem(args, i++);
				if (!is_stringobject(v) ||
				    getstringsize(v) != 1) {
					err_setstr(StructError,
					   "bad argument type to pack");
					goto fail;
				}
				*res++ = getstringvalue(v)[0];
				break;

			case 'd':
			case 'f':
				if (i >= n) {
					err_setstr(StructError,
					   "insufficient arguments to pack");
					goto fail;
				}
				v = gettupleitem(args, i++);
				if (!is_floatobject(v)) {
					err_setstr(StructError,
					   "bad argument type to pack");
					goto fail;
				}
				fval = getfloatvalue(v);
				switch (c) {
				case 'f':
					*(float*)res = (float)fval;
					res += sizeof(float);
					break;
				case 'd':
					*(double*)res = fval;
					res += sizeof(double);
					break;
				}
				break;

			default:
				err_setstr(StructError, "bad char in fmt");
				goto fail;

			}
		}
	}

	if (i < n) {
		err_setstr(StructError, "too many arguments for pack fmt");
		goto fail;
	}

	return result;

 fail:
	DECREF(result);
	return NULL;
}


/* Helper to convert a list to a tuple */

static object *
totuple(list)
	object *list;
{
	int len = getlistsize(list);
	object *tuple = newtupleobject(len);
	if (tuple != NULL) {
		int i;
		for (i = 0; i < len; i++) {
			object *v = getlistitem(list, i);
			INCREF(v);
			settupleitem(tuple, i, v);
		}
	}
	DECREF(list);
	return tuple;
}


/* unpack(fmt, string) --> (v1, v2, ...) */

static object *
struct_unpack(self, args)
	object *self; /* Not used */
	object *args;
{
	char *str, *start, *fmt, *s;
	char c;
	int len, size, num, x;
	object *res, *v;

	if (!getargs(args, "(ss#)", &fmt, &start, &len))
		return NULL;
	size = calcsize(fmt);
	if (size != len) {
		err_setstr(StructError, "unpack str size does not match fmt");
		return NULL;
	}
	res = newlistobject(0);
	if (res == NULL)
		return NULL;
	str = start;
	s = fmt;
	while ((c = *s++) != '\0') {
		if ('0' <= c && c <= '9') {
			num = c - '0';
			while ('0' <= (c = *s++) && c <= '9')
			       num = num*10 + (c - '0');
			if (c == '\0')
				break;
		}
		else
			num = 1;

		str = start + align((int)(str-start), c);

		while (--num >= 0) {
			switch (c) {

			case 'x':
				str++;
				continue;

			case 'b':
				x = *str++;
				if (x >= 128)
					x -= 256;
				v = newintobject((long)x);
				break;

			case 'c':
				v = newsizedstringobject(str, 1);
				str++;
				break;

			case 'h':
				v = newintobject((long)*(short*)str);
				str += sizeof(short);
				break;

			case 'i':
				v = newintobject((long)*(int*)str);
				str += sizeof(int);
				break;

			case 'l':
				v = newintobject(*(long*)str);
				str += sizeof(long);
				break;

			case 'f':
				v = newfloatobject((double)*(float*)str);
				str += sizeof(float);
				break;

			case 'd':
				v = newfloatobject(*(double*)str);
				str += sizeof(double);
				break;

			default:
				err_setstr(StructError, "bad char in fmt");
				goto fail;

			}
			if (v == NULL || addlistitem(res, v) < 0)
				goto fail;
			DECREF(v);
		}
	}

	return totuple(res);

 fail:
	DECREF(res);
	return NULL;
}


/* List of functions */

static struct methodlist struct_methods[] = {
	{"calcsize",	struct_calcsize},
	{"pack",	struct_pack,	1/*varargs*/},
	{"unpack",	struct_unpack},
	{NULL,		NULL}		/* sentinel */
};


/* Module initialization */

void
initstruct()
{
	object *m, *d;

	/* Create the module and add the functions */
	m = initmodule("struct", struct_methods);

	/* Add some symbolic constants to the module */
	d = getmoduledict(m);
	StructError = newstringobject("struct.error");
	dictinsert(d, "error", StructError);

	/* Check for errors */
	if (err_occurred())
		fatal("can't initialize module struct");
}
