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

/* New version supporting byte order, alignment and size options,
   character strings, and unsigned numbers */

#define PY_SSIZE_T_CLEAN

#include "Python.h"
#include "structseq.h"
#include "structmember.h"
#include <ctype.h>

static PyTypeObject PyStructType;

/* If PY_STRUCT_OVERFLOW_MASKING is defined, the struct module will wrap all input
   numbers for explicit endians such that they fit in the given type, much
   like explicit casting in C. A warning will be raised if the number did
   not originally fit within the range of the requested type. If it is
   not defined, then all range errors and overflow will be struct.error
   exceptions. */

#define PY_STRUCT_OVERFLOW_MASKING 1

#ifdef PY_STRUCT_OVERFLOW_MASKING
static PyObject *pylong_ulong_mask = NULL;
static PyObject *pyint_zero = NULL;
#endif

/* If PY_STRUCT_FLOAT_COERCE is defined, the struct module will allow float
   arguments for integer formats with a warning for backwards
   compatibility. */

#define PY_STRUCT_FLOAT_COERCE 1

#ifdef PY_STRUCT_FLOAT_COERCE
#define FLOAT_COERCE "integer argument expected, got float"
#endif


/* The translation function for each format character is table driven */
typedef struct _formatdef {
	char format;
	Py_ssize_t size;
	Py_ssize_t alignment;
	PyObject* (*unpack)(const char *,
			    const struct _formatdef *);
	int (*pack)(char *, PyObject *,
		    const struct _formatdef *);
} formatdef;

typedef struct _formatcode {
	const struct _formatdef *fmtdef;
	Py_ssize_t offset;
	Py_ssize_t size;
} formatcode;

/* Struct object interface */

typedef struct {
	PyObject_HEAD
	Py_ssize_t s_size;
	Py_ssize_t s_len;
	formatcode *s_codes;
	PyObject *s_format;
	PyObject *weakreflist; /* List of weak references */
} PyStructObject;


#define PyStruct_Check(op) PyObject_TypeCheck(op, &PyStructType)
#define PyStruct_CheckExact(op) (Py_TYPE(op) == &PyStructType)


/* Exception */

static PyObject *StructError;


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


typedef struct { char c; short x; } st_short;
typedef struct { char c; int x; } st_int;
typedef struct { char c; long x; } st_long;
typedef struct { char c; float x; } st_float;
typedef struct { char c; double x; } st_double;
typedef struct { char c; void *x; } st_void_p;

#define SHORT_ALIGN (sizeof(st_short) - sizeof(short))
#define INT_ALIGN (sizeof(st_int) - sizeof(int))
#define LONG_ALIGN (sizeof(st_long) - sizeof(long))
#define FLOAT_ALIGN (sizeof(st_float) - sizeof(float))
#define DOUBLE_ALIGN (sizeof(st_double) - sizeof(double))
#define VOID_P_ALIGN (sizeof(st_void_p) - sizeof(void *))

/* We can't support q and Q in native mode unless the compiler does;
   in std mode, they're 8 bytes on all platforms. */
#ifdef HAVE_LONG_LONG
typedef struct { char c; PY_LONG_LONG x; } s_long_long;
#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(PY_LONG_LONG))
#endif

#ifdef HAVE_C99_BOOL
#define BOOL_TYPE _Bool
typedef struct { char c; _Bool x; } s_bool;
#define BOOL_ALIGN (sizeof(s_bool) - sizeof(BOOL_TYPE))
#else
#define BOOL_TYPE char
#define BOOL_ALIGN 0
#endif

#define STRINGIFY(x)    #x

#ifdef __powerc
#pragma options align=reset
#endif

/* Helper to get a PyLongObject by hook or by crook.  Caller should decref. */

static PyObject *
get_pylong(PyObject *v)
{
	PyNumberMethods *m;

	assert(v != NULL);
	if (PyLong_Check(v)) {
		Py_INCREF(v);
		return v;
	}
	m = Py_TYPE(v)->tp_as_number;
	if (m != NULL && m->nb_long != NULL) {
		v = m->nb_long(v);
		if (v == NULL)
			return NULL;
		if (PyLong_Check(v))
			return v;
		Py_DECREF(v);
	}
	PyErr_SetString(StructError,
			"cannot convert argument to long");
	return NULL;
}

/* Helper routine to get a Python integer and raise the appropriate error
   if it isn't one */

static int
get_long(PyObject *v, long *p)
{
	long x = PyLong_AsLong(v);
	if (x == -1 && PyErr_Occurred()) {
#ifdef PY_STRUCT_FLOAT_COERCE
		if (PyFloat_Check(v)) {
			PyObject *o;
			int res;
			PyErr_Clear();
			if (PyErr_WarnEx(PyExc_DeprecationWarning, FLOAT_COERCE, 2) < 0)
				return -1;
			o = PyNumber_Int(v);
			if (o == NULL)
				return -1;
			res = get_long(o, p);
			Py_DECREF(o);
			return res;
		}
#endif
		if (PyErr_ExceptionMatches(PyExc_TypeError))
			PyErr_SetString(StructError,
					"required argument is not an integer");
		return -1;
	}
	*p = x;
	return 0;
}


/* Same, but handling unsigned long */

static int
get_ulong(PyObject *v, unsigned long *p)
{
	if (PyLong_Check(v)) {
		unsigned long x = PyLong_AsUnsignedLong(v);
		if (x == (unsigned long)(-1) && PyErr_Occurred())
			return -1;
		*p = x;
		return 0;
	}
	if (get_long(v, (long *)p) < 0)
		return -1;
	if (((long)*p) < 0) {
		PyErr_SetString(StructError,
				"unsigned argument is < 0");
		return -1;
	}
	return 0;
}

#ifdef HAVE_LONG_LONG

/* Same, but handling native long long. */

static int
get_longlong(PyObject *v, PY_LONG_LONG *p)
{
	PY_LONG_LONG x;

	v = get_pylong(v);
	if (v == NULL)
		return -1;
	assert(PyLong_Check(v));
	x = PyLong_AsLongLong(v);
	Py_DECREF(v);
	if (x == (PY_LONG_LONG)-1 && PyErr_Occurred())
		return -1;
	*p = x;
	return 0;
}

/* Same, but handling native unsigned long long. */

static int
get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p)
{
	unsigned PY_LONG_LONG x;

	v = get_pylong(v);
	if (v == NULL)
		return -1;
	assert(PyLong_Check(v));
	x = PyLong_AsUnsignedLongLong(v);
	Py_DECREF(v);
	if (x == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())
		return -1;
	*p = x;
	return 0;
}

#endif

#ifdef PY_STRUCT_OVERFLOW_MASKING

/* Helper routine to get a Python integer and raise the appropriate error
   if it isn't one */

#define INT_OVERFLOW "struct integer overflow masking is deprecated"

static int
get_wrapped_long(PyObject *v, long *p)
{
	if (get_long(v, p) < 0) {
		if (PyLong_Check(v) &&
		    PyErr_ExceptionMatches(PyExc_OverflowError)) {
			PyObject *wrapped;
			long x;
			PyErr_Clear();
#ifdef PY_STRUCT_FLOAT_COERCE
			if (PyFloat_Check(v)) {
				PyObject *o;
				int res;
				PyErr_Clear();
				if (PyErr_WarnEx(PyExc_DeprecationWarning, FLOAT_COERCE, 2) < 0)
					return -1;
				o = PyNumber_Int(v);
				if (o == NULL)
					return -1;
				res = get_wrapped_long(o, p);
				Py_DECREF(o);
				return res;
			}
#endif
			if (PyErr_WarnEx(PyExc_DeprecationWarning, INT_OVERFLOW, 2) < 0)
				return -1;
			wrapped = PyNumber_And(v, pylong_ulong_mask);
			if (wrapped == NULL)
				return -1;
			x = (long)PyLong_AsUnsignedLong(wrapped);
			Py_DECREF(wrapped);
			if (x == -1 && PyErr_Occurred())
				return -1;
			*p = x;
		} else {
			return -1;
		}
	}
	return 0;
}

static int
get_wrapped_ulong(PyObject *v, unsigned long *p)
{
	long x = (long)PyLong_AsUnsignedLong(v);
	if (x == -1 && PyErr_Occurred()) {
		PyObject *wrapped;
		PyErr_Clear();
#ifdef PY_STRUCT_FLOAT_COERCE
		if (PyFloat_Check(v)) {
			PyObject *o;
			int res;
			PyErr_Clear();
			if (PyErr_WarnEx(PyExc_DeprecationWarning, FLOAT_COERCE, 2) < 0)
				return -1;
			o = PyNumber_Int(v);
			if (o == NULL)
				return -1;
			res = get_wrapped_ulong(o, p);
			Py_DECREF(o);
			return res;
		}
#endif
		wrapped = PyNumber_And(v, pylong_ulong_mask);
		if (wrapped == NULL)
			return -1;
		if (PyErr_WarnEx(PyExc_DeprecationWarning, INT_OVERFLOW, 2) < 0) {
			Py_DECREF(wrapped);
			return -1;
		}
		x = (long)PyLong_AsUnsignedLong(wrapped);
		Py_DECREF(wrapped);
		if (x == -1 && PyErr_Occurred())
			return -1;
	}
	*p = (unsigned long)x;
	return 0;
}

#define RANGE_ERROR(x, f, flag, mask) \
	do { \
		if (_range_error(f, flag) < 0) \
			return -1; \
		else \
			(x) &= (mask); \
	} while (0)

#else

#define get_wrapped_long get_long
#define get_wrapped_ulong get_ulong
#define RANGE_ERROR(x, f, flag, mask) return _range_error(f, flag)

#endif

/* Floating point helpers */

static PyObject *
unpack_float(const char *p,  /* start of 4-byte string */
             int le)	     /* true for little-endian, false for big-endian */
{
	double x;

	x = _PyFloat_Unpack4((unsigned char *)p, le);
	if (x == -1.0 && PyErr_Occurred())
		return NULL;
	return PyFloat_FromDouble(x);
}

static PyObject *
unpack_double(const char *p,  /* start of 8-byte string */
              int le)         /* true for little-endian, false for big-endian */
{
	double x;

	x = _PyFloat_Unpack8((unsigned char *)p, le);
	if (x == -1.0 && PyErr_Occurred())
		return NULL;
	return PyFloat_FromDouble(x);
}

/* Helper to format the range error exceptions */
static int
_range_error(const formatdef *f, int is_unsigned)
{
	/* ulargest is the largest unsigned value with f->size bytes.
	 * Note that the simpler:
	 *     ((size_t)1 << (f->size * 8)) - 1
	 * doesn't work when f->size == sizeof(size_t) because C doesn't
	 * define what happens when a left shift count is >= the number of
	 * bits in the integer being shifted; e.g., on some boxes it doesn't
	 * shift at all when they're equal.
	 */
	const size_t ulargest = (size_t)-1 >> ((SIZEOF_SIZE_T - f->size)*8);
	assert(f->size >= 1 && f->size <= SIZEOF_SIZE_T);
	if (is_unsigned)
		PyErr_Format(StructError,
			"'%c' format requires 0 <= number <= %zu",
			f->format,
			ulargest);
	else {
		const Py_ssize_t largest = (Py_ssize_t)(ulargest >> 1);
		PyErr_Format(StructError,
			"'%c' format requires %zd <= number <= %zd",
			f->format,
			~ largest,
			largest);
	}
#ifdef PY_STRUCT_OVERFLOW_MASKING
	{
		PyObject *ptype, *pvalue, *ptraceback;
		PyObject *msg;
		int rval;
		PyErr_Fetch(&ptype, &pvalue, &ptraceback);
		assert(pvalue != NULL);
		msg = PyObject_Str(pvalue);
		Py_XDECREF(ptype);
		Py_XDECREF(pvalue);
		Py_XDECREF(ptraceback);
		if (msg == NULL)
			return -1;
		rval = PyErr_WarnEx(PyExc_DeprecationWarning,
				    _PyUnicode_AsString(msg), 2);
		Py_DECREF(msg);
		if (rval == 0)
			return 0;
	}
#endif
	return -1;
}



/* A large number of small routines follow, with names of the form

   [bln][up]_TYPE

   [bln] distiguishes among big-endian, little-endian and native.
   [pu] distiguishes between pack (to struct) and unpack (from struct).
   TYPE is one of char, byte, ubyte, etc.
*/

/* Native mode routines. ****************************************************/
/* NOTE:
   In all n[up]_<type> routines handling types larger than 1 byte, there is
   *no* guarantee that the p pointer is properly aligned for each type,
   therefore memcpy is called.  An intermediate variable is used to
   compensate for big-endian architectures.
   Normally both the intermediate variable and the memcpy call will be
   skipped by C optimisation in little-endian architectures (gcc >= 2.91
   does this). */

static PyObject *
nu_char(const char *p, const formatdef *f)
{
	return PyBytes_FromStringAndSize(p, 1);
}

static PyObject *
nu_byte(const char *p, const formatdef *f)
{
	return PyLong_FromLong((long) *(signed char *)p);
}

static PyObject *
nu_ubyte(const char *p, const formatdef *f)
{
	return PyLong_FromLong((long) *(unsigned char *)p);
}

static PyObject *
nu_short(const char *p, const formatdef *f)
{
	short x;
	memcpy((char *)&x, p, sizeof x);
	return PyLong_FromLong((long)x);
}

static PyObject *
nu_ushort(const char *p, const formatdef *f)
{
	unsigned short x;
	memcpy((char *)&x, p, sizeof x);
	return PyLong_FromLong((long)x);
}

static PyObject *
nu_int(const char *p, const formatdef *f)
{
	int x;
	memcpy((char *)&x, p, sizeof x);
	return PyLong_FromLong((long)x);
}

static PyObject *
nu_uint(const char *p, const formatdef *f)
{
	unsigned int x;
	memcpy((char *)&x, p, sizeof x);
#if (SIZEOF_LONG > SIZEOF_INT)
	return PyLong_FromLong((long)x);
#else
	if (x <= ((unsigned int)LONG_MAX))
		return PyLong_FromLong((long)x);
	return PyLong_FromUnsignedLong((unsigned long)x);
#endif
}

static PyObject *
nu_long(const char *p, const formatdef *f)
{
	long x;
	memcpy((char *)&x, p, sizeof x);
	return PyLong_FromLong(x);
}

static PyObject *
nu_ulong(const char *p, const formatdef *f)
{
	unsigned long x;
	memcpy((char *)&x, p, sizeof x);
	if (x <= LONG_MAX)
		return PyLong_FromLong((long)x);
	return PyLong_FromUnsignedLong(x);
}

/* Native mode doesn't support q or Q unless the platform C supports
   long long (or, on Windows, __int64). */

#ifdef HAVE_LONG_LONG

static PyObject *
nu_longlong(const char *p, const formatdef *f)
{
	PY_LONG_LONG x;
	memcpy((char *)&x, p, sizeof x);
	if (x >= LONG_MIN && x <= LONG_MAX)
		return PyLong_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
	return PyLong_FromLongLong(x);
}

static PyObject *
nu_ulonglong(const char *p, const formatdef *f)
{
	unsigned PY_LONG_LONG x;
	memcpy((char *)&x, p, sizeof x);
	if (x <= LONG_MAX)
		return PyLong_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
	return PyLong_FromUnsignedLongLong(x);
}

#endif

static PyObject *
nu_bool(const char *p, const formatdef *f)
{
	BOOL_TYPE x;
	memcpy((char *)&x, p, sizeof x);
	return PyBool_FromLong(x != 0);
}


static PyObject *
nu_float(const char *p, const formatdef *f)
{
	float x;
	memcpy((char *)&x, p, sizeof x);
	return PyFloat_FromDouble((double)x);
}

static PyObject *
nu_double(const char *p, const formatdef *f)
{
	double x;
	memcpy((char *)&x, p, sizeof x);
	return PyFloat_FromDouble(x);
}

static PyObject *
nu_void_p(const char *p, const formatdef *f)
{
	void *x;
	memcpy((char *)&x, p, sizeof x);
	return PyLong_FromVoidPtr(x);
}

static int
np_byte(char *p, PyObject *v, const formatdef *f)
{
	long x;
	if (get_long(v, &x) < 0)
		return -1;
	if (x < -128 || x > 127){
		PyErr_SetString(StructError,
				"byte format requires -128 <= number <= 127");
		return -1;
	}
	*p = (char)x;
	return 0;
}

static int
np_ubyte(char *p, PyObject *v, const formatdef *f)
{
	long x;
	if (get_long(v, &x) < 0)
		return -1;
	if (x < 0 || x > 255){
		PyErr_SetString(StructError,
				"ubyte format requires 0 <= number <= 255");
		return -1;
	}
	*p = (char)x;
	return 0;
}

static int
np_char(char *p, PyObject *v, const formatdef *f)
{
	if (PyUnicode_Check(v)) {
		v = _PyUnicode_AsDefaultEncodedString(v, NULL);
		if (v == NULL)
			return -1;
	}
	if (!PyBytes_Check(v) || PyBytes_Size(v) != 1) {
		PyErr_SetString(StructError,
				"char format requires bytes or string of length 1");
		return -1;
	}
	*p = *PyBytes_AsString(v);
	return 0;
}

static int
np_short(char *p, PyObject *v, const formatdef *f)
{
	long x;
	short y;
	if (get_long(v, &x) < 0)
		return -1;
	if (x < SHRT_MIN || x > SHRT_MAX){
		PyErr_SetString(StructError,
				"short format requires " STRINGIFY(SHRT_MIN)
				" <= number <= " STRINGIFY(SHRT_MAX));
		return -1;
	}
	y = (short)x;
	memcpy(p, (char *)&y, sizeof y);
	return 0;
}

static int
np_ushort(char *p, PyObject *v, const formatdef *f)
{
	long x;
	unsigned short y;
	if (get_long(v, &x) < 0)
		return -1;
	if (x < 0 || x > USHRT_MAX){
		PyErr_SetString(StructError,
				"short format requires 0 <= number <= " STRINGIFY(USHRT_MAX));
		return -1;
	}
	y = (unsigned short)x;
	memcpy(p, (char *)&y, sizeof y);
	return 0;
}

static int
np_int(char *p, PyObject *v, const formatdef *f)
{
	long x;
	int y;
	if (get_long(v, &x) < 0)
		return -1;
#if (SIZEOF_LONG > SIZEOF_INT)
	if ((x < ((long)INT_MIN)) || (x > ((long)INT_MAX)))
		return _range_error(f, 0);
#endif
	y = (int)x;
	memcpy(p, (char *)&y, sizeof y);
	return 0;
}

static int
np_uint(char *p, PyObject *v, const formatdef *f)
{
	unsigned long x;
	unsigned int y;
	if (get_ulong(v, &x) < 0)
		return _range_error(f, 1);
	y = (unsigned int)x;
#if (SIZEOF_LONG > SIZEOF_INT)
	if (x > ((unsigned long)UINT_MAX))
		return _range_error(f, 1);
#endif
	memcpy(p, (char *)&y, sizeof y);
	return 0;
}

static int
np_long(char *p, PyObject *v, const formatdef *f)
{
	long x;
	if (get_long(v, &x) < 0)
		return -1;
	memcpy(p, (char *)&x, sizeof x);
	return 0;
}

static int
np_ulong(char *p, PyObject *v, const formatdef *f)
{
	unsigned long x;
	if (get_ulong(v, &x) < 0)
		return _range_error(f, 1);
	memcpy(p, (char *)&x, sizeof x);
	return 0;
}

#ifdef HAVE_LONG_LONG

static int
np_longlong(char *p, PyObject *v, const formatdef *f)
{
	PY_LONG_LONG x;
	if (get_longlong(v, &x) < 0)
		return -1;
	memcpy(p, (char *)&x, sizeof x);
	return 0;
}

static int
np_ulonglong(char *p, PyObject *v, const formatdef *f)
{
	unsigned PY_LONG_LONG x;
	if (get_ulonglong(v, &x) < 0)
		return -1;
	memcpy(p, (char *)&x, sizeof x);
	return 0;
}
#endif


static int
np_bool(char *p, PyObject *v, const formatdef *f)
{
	BOOL_TYPE y; 
	y = PyObject_IsTrue(v);
	memcpy(p, (char *)&y, sizeof y);
	return 0;
}

static int
np_float(char *p, PyObject *v, const formatdef *f)
{
	float x = (float)PyFloat_AsDouble(v);
	if (x == -1 && PyErr_Occurred()) {
		PyErr_SetString(StructError,
				"required argument is not a float");
		return -1;
	}
	memcpy(p, (char *)&x, sizeof x);
	return 0;
}

static int
np_double(char *p, PyObject *v, const formatdef *f)
{
	double x = PyFloat_AsDouble(v);
	if (x == -1 && PyErr_Occurred()) {
		PyErr_SetString(StructError,
				"required argument is not a float");
		return -1;
	}
	memcpy(p, (char *)&x, sizeof(double));
	return 0;
}

static int
np_void_p(char *p, PyObject *v, const formatdef *f)
{
	void *x;

	v = get_pylong(v);
	if (v == NULL)
		return -1;
	assert(PyLong_Check(v));
	x = PyLong_AsVoidPtr(v);
	Py_DECREF(v);
	if (x == NULL && PyErr_Occurred())
		return -1;
	memcpy(p, (char *)&x, sizeof x);
	return 0;
}

static formatdef native_table[] = {
	{'x',	sizeof(char),	0,		NULL},
	{'b',	sizeof(char),	0,		nu_byte,	np_byte},
	{'B',	sizeof(char),	0,		nu_ubyte,	np_ubyte},
	{'c',	sizeof(char),	0,		nu_char,	np_char},
	{'s',	sizeof(char),	0,		NULL},
	{'p',	sizeof(char),	0,		NULL},
	{'h',	sizeof(short),	SHORT_ALIGN,	nu_short,	np_short},
	{'H',	sizeof(short),	SHORT_ALIGN,	nu_ushort,	np_ushort},
	{'i',	sizeof(int),	INT_ALIGN,	nu_int,		np_int},
	{'I',	sizeof(int),	INT_ALIGN,	nu_uint,	np_uint},
	{'l',	sizeof(long),	LONG_ALIGN,	nu_long,	np_long},
	{'L',	sizeof(long),	LONG_ALIGN,	nu_ulong,	np_ulong},
#ifdef HAVE_LONG_LONG
	{'q',	sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_longlong, np_longlong},
	{'Q',	sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong},
#endif
	{'?',	sizeof(BOOL_TYPE),	BOOL_ALIGN,	nu_bool,	np_bool},
	{'f',	sizeof(float),	FLOAT_ALIGN,	nu_float,	np_float},
	{'d',	sizeof(double),	DOUBLE_ALIGN,	nu_double,	np_double},
	{'P',	sizeof(void *),	VOID_P_ALIGN,	nu_void_p,	np_void_p},
	{0}
};

/* Big-endian routines. *****************************************************/

static PyObject *
bu_int(const char *p, const formatdef *f)
{
	long x = 0;
	Py_ssize_t i = f->size;
	const unsigned char *bytes = (const unsigned char *)p;
	do {
		x = (x<<8) | *bytes++;
	} while (--i > 0);
	/* Extend the sign bit. */
	if (SIZEOF_LONG > f->size)
		x |= -(x & (1L << ((8 * f->size) - 1)));
	return PyLong_FromLong(x);
}

static PyObject *
bu_uint(const char *p, const formatdef *f)
{
	unsigned long x = 0;
	Py_ssize_t i = f->size;
	const unsigned char *bytes = (const unsigned char *)p;
	do {
		x = (x<<8) | *bytes++;
	} while (--i > 0);
	if (x <= LONG_MAX)
		return PyLong_FromLong((long)x);
	return PyLong_FromUnsignedLong(x);
}

static PyObject *
bu_longlong(const char *p, const formatdef *f)
{
#ifdef HAVE_LONG_LONG
	PY_LONG_LONG x = 0;
	Py_ssize_t i = f->size;
	const unsigned char *bytes = (const unsigned char *)p;
	do {
		x = (x<<8) | *bytes++;
	} while (--i > 0);
	/* Extend the sign bit. */
	if (SIZEOF_LONG_LONG > f->size)
		x |= -(x & ((PY_LONG_LONG)1 << ((8 * f->size) - 1)));
	if (x >= LONG_MIN && x <= LONG_MAX)
		return PyLong_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
	return PyLong_FromLongLong(x);
#else
	return _PyLong_FromByteArray((const unsigned char *)p,
				      8,
				      0, /* little-endian */
				      1  /* signed */);
#endif
}

static PyObject *
bu_ulonglong(const char *p, const formatdef *f)
{
#ifdef HAVE_LONG_LONG
	unsigned PY_LONG_LONG x = 0;
	Py_ssize_t i = f->size;
	const unsigned char *bytes = (const unsigned char *)p;
	do {
		x = (x<<8) | *bytes++;
	} while (--i > 0);
	if (x <= LONG_MAX)
		return PyLong_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
	return PyLong_FromUnsignedLongLong(x);
#else
	return _PyLong_FromByteArray((const unsigned char *)p,
				      8,
				      0, /* little-endian */
				      0  /* signed */);
#endif
}

static PyObject *
bu_float(const char *p, const formatdef *f)
{
	return unpack_float(p, 0);
}

static PyObject *
bu_double(const char *p, const formatdef *f)
{
	return unpack_double(p, 0);
}

static PyObject *
bu_bool(const char *p, const formatdef *f)
{
	char x;
	memcpy((char *)&x, p, sizeof x);
	return PyBool_FromLong(x != 0);
}

static int
bp_int(char *p, PyObject *v, const formatdef *f)
{
	long x;
	Py_ssize_t i;
	if (get_wrapped_long(v, &x) < 0)
		return -1;
	i = f->size;
	if (i != SIZEOF_LONG) {
		if ((i == 2) && (x < -32768 || x > 32767))
			RANGE_ERROR(x, f, 0, 0xffffL);
#if (SIZEOF_LONG != 4)
		else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
			RANGE_ERROR(x, f, 0, 0xffffffffL);
#endif
#ifdef PY_STRUCT_OVERFLOW_MASKING
		else if ((i == 1) && (x < -128 || x > 127))
			RANGE_ERROR(x, f, 0, 0xffL);
#endif
	}
	do {
		p[--i] = (char)x;
		x >>= 8;
	} while (i > 0);
	return 0;
}

static int
bp_uint(char *p, PyObject *v, const formatdef *f)
{
	unsigned long x;
	Py_ssize_t i;
	if (get_wrapped_ulong(v, &x) < 0)
		return -1;
	i = f->size;
	if (i != SIZEOF_LONG) {
		unsigned long maxint = 1;
		maxint <<= (unsigned long)(i * 8);
		if (x >= maxint)
			RANGE_ERROR(x, f, 1, maxint - 1);
	}
	do {
		p[--i] = (char)x;
		x >>= 8;
	} while (i > 0);
	return 0;
}

static int
bp_longlong(char *p, PyObject *v, const formatdef *f)
{
	int res;
	v = get_pylong(v);
	if (v == NULL)
		return -1;
	res = _PyLong_AsByteArray((PyLongObject *)v,
			   	  (unsigned char *)p,
				  8,
				  0, /* little_endian */
				  1  /* signed */);
	Py_DECREF(v);
	return res;
}

static int
bp_ulonglong(char *p, PyObject *v, const formatdef *f)
{
	int res;
	v = get_pylong(v);
	if (v == NULL)
		return -1;
	res = _PyLong_AsByteArray((PyLongObject *)v,
			   	  (unsigned char *)p,
				  8,
				  0, /* little_endian */
				  0  /* signed */);
	Py_DECREF(v);
	return res;
}

static int
bp_float(char *p, PyObject *v, const formatdef *f)
{
	double x = PyFloat_AsDouble(v);
	if (x == -1 && PyErr_Occurred()) {
		PyErr_SetString(StructError,
				"required argument is not a float");
		return -1;
	}
	return _PyFloat_Pack4(x, (unsigned char *)p, 0);
}

static int
bp_double(char *p, PyObject *v, const formatdef *f)
{
	double x = PyFloat_AsDouble(v);
	if (x == -1 && PyErr_Occurred()) {
		PyErr_SetString(StructError,
				"required argument is not a float");
		return -1;
	}
	return _PyFloat_Pack8(x, (unsigned char *)p, 0);
}

static int
bp_bool(char *p, PyObject *v, const formatdef *f)
{
	char y; 
	y = PyObject_IsTrue(v);
	memcpy(p, (char *)&y, sizeof y);
	return 0;
}

static formatdef bigendian_table[] = {
	{'x',	1,		0,		NULL},
#ifdef PY_STRUCT_OVERFLOW_MASKING
	/* Native packers do range checking without overflow masking. */
	{'b',	1,		0,		nu_byte,	bp_int},
	{'B',	1,		0,		nu_ubyte,	bp_uint},
#else
	{'b',	1,		0,		nu_byte,	np_byte},
	{'B',	1,		0,		nu_ubyte,	np_ubyte},
#endif
	{'c',	1,		0,		nu_char,	np_char},
	{'s',	1,		0,		NULL},
	{'p',	1,		0,		NULL},
	{'h',	2,		0,		bu_int,		bp_int},
	{'H',	2,		0,		bu_uint,	bp_uint},
	{'i',	4,		0,		bu_int,		bp_int},
	{'I',	4,		0,		bu_uint,	bp_uint},
	{'l',	4,		0,		bu_int,		bp_int},
	{'L',	4,		0,		bu_uint,	bp_uint},
	{'q',	8,		0,		bu_longlong,	bp_longlong},
	{'Q',	8,		0,		bu_ulonglong,	bp_ulonglong},
	{'?',	1,		0,		bu_bool,	bp_bool},
	{'f',	4,		0,		bu_float,	bp_float},
	{'d',	8,		0,		bu_double,	bp_double},
	{0}
};

/* Little-endian routines. *****************************************************/

static PyObject *
lu_int(const char *p, const formatdef *f)
{
	long x = 0;
	Py_ssize_t i = f->size;
	const unsigned char *bytes = (const unsigned char *)p;
	do {
		x = (x<<8) | bytes[--i];
	} while (i > 0);
	/* Extend the sign bit. */
	if (SIZEOF_LONG > f->size)
		x |= -(x & (1L << ((8 * f->size) - 1)));
	return PyLong_FromLong(x);
}

static PyObject *
lu_uint(const char *p, const formatdef *f)
{
	unsigned long x = 0;
	Py_ssize_t i = f->size;
	const unsigned char *bytes = (const unsigned char *)p;
	do {
		x = (x<<8) | bytes[--i];
	} while (i > 0);
	if (x <= LONG_MAX)
		return PyLong_FromLong((long)x);
	return PyLong_FromUnsignedLong((long)x);
}

static PyObject *
lu_longlong(const char *p, const formatdef *f)
{
#ifdef HAVE_LONG_LONG
	PY_LONG_LONG x = 0;
	Py_ssize_t i = f->size;
	const unsigned char *bytes = (const unsigned char *)p;
	do {
		x = (x<<8) | bytes[--i];
	} while (i > 0);
	/* Extend the sign bit. */
	if (SIZEOF_LONG_LONG > f->size)
		x |= -(x & ((PY_LONG_LONG)1 << ((8 * f->size) - 1)));
	if (x >= LONG_MIN && x <= LONG_MAX)
		return PyLong_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
	return PyLong_FromLongLong(x);
#else
	return _PyLong_FromByteArray((const unsigned char *)p,
				      8,
				      1, /* little-endian */
				      1  /* signed */);
#endif
}

static PyObject *
lu_ulonglong(const char *p, const formatdef *f)
{
#ifdef HAVE_LONG_LONG
	unsigned PY_LONG_LONG x = 0;
	Py_ssize_t i = f->size;
	const unsigned char *bytes = (const unsigned char *)p;
	do {
		x = (x<<8) | bytes[--i];
	} while (i > 0);
	if (x <= LONG_MAX)
		return PyLong_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
	return PyLong_FromUnsignedLongLong(x);
#else
	return _PyLong_FromByteArray((const unsigned char *)p,
				      8,
				      1, /* little-endian */
				      0  /* signed */);
#endif
}

static PyObject *
lu_float(const char *p, const formatdef *f)
{
	return unpack_float(p, 1);
}

static PyObject *
lu_double(const char *p, const formatdef *f)
{
	return unpack_double(p, 1);
}

static int
lp_int(char *p, PyObject *v, const formatdef *f)
{
	long x;
	Py_ssize_t i;
	if (get_wrapped_long(v, &x) < 0)
		return -1;
	i = f->size;
	if (i != SIZEOF_LONG) {
		if ((i == 2) && (x < -32768 || x > 32767))
			RANGE_ERROR(x, f, 0, 0xffffL);
#if (SIZEOF_LONG != 4)
		else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
			RANGE_ERROR(x, f, 0, 0xffffffffL);
#endif
#ifdef PY_STRUCT_OVERFLOW_MASKING
		else if ((i == 1) && (x < -128 || x > 127))
			RANGE_ERROR(x, f, 0, 0xffL);
#endif
	}
	do {
		*p++ = (char)x;
		x >>= 8;
	} while (--i > 0);
	return 0;
}

static int
lp_uint(char *p, PyObject *v, const formatdef *f)
{
	unsigned long x;
	Py_ssize_t i;
	if (get_wrapped_ulong(v, &x) < 0)
		return -1;
	i = f->size;
	if (i != SIZEOF_LONG) {
		unsigned long maxint = 1;
		maxint <<= (unsigned long)(i * 8);
		if (x >= maxint)
			RANGE_ERROR(x, f, 1, maxint - 1);
	}
	do {
		*p++ = (char)x;
		x >>= 8;
	} while (--i > 0);
	return 0;
}

static int
lp_longlong(char *p, PyObject *v, const formatdef *f)
{
	int res;
	v = get_pylong(v);
	if (v == NULL)
		return -1;
	res = _PyLong_AsByteArray((PyLongObject*)v,
			   	  (unsigned char *)p,
				  8,
				  1, /* little_endian */
				  1  /* signed */);
	Py_DECREF(v);
	return res;
}

static int
lp_ulonglong(char *p, PyObject *v, const formatdef *f)
{
	int res;
	v = get_pylong(v);
	if (v == NULL)
		return -1;
	res = _PyLong_AsByteArray((PyLongObject*)v,
			   	  (unsigned char *)p,
				  8,
				  1, /* little_endian */
				  0  /* signed */);
	Py_DECREF(v);
	return res;
}

static int
lp_float(char *p, PyObject *v, const formatdef *f)
{
	double x = PyFloat_AsDouble(v);
	if (x == -1 && PyErr_Occurred()) {
		PyErr_SetString(StructError,
				"required argument is not a float");
		return -1;
	}
	return _PyFloat_Pack4(x, (unsigned char *)p, 1);
}

static int
lp_double(char *p, PyObject *v, const formatdef *f)
{
	double x = PyFloat_AsDouble(v);
	if (x == -1 && PyErr_Occurred()) {
		PyErr_SetString(StructError,
				"required argument is not a float");
		return -1;
	}
	return _PyFloat_Pack8(x, (unsigned char *)p, 1);
}

static formatdef lilendian_table[] = {
	{'x',	1,		0,		NULL},
#ifdef PY_STRUCT_OVERFLOW_MASKING
	/* Native packers do range checking without overflow masking. */
	{'b',	1,		0,		nu_byte,	lp_int},
	{'B',	1,		0,		nu_ubyte,	lp_uint},
#else
	{'b',	1,		0,		nu_byte,	np_byte},
	{'B',	1,		0,		nu_ubyte,	np_ubyte},
#endif
	{'c',	1,		0,		nu_char,	np_char},
	{'s',	1,		0,		NULL},
	{'p',	1,		0,		NULL},
	{'h',	2,		0,		lu_int,		lp_int},
	{'H',	2,		0,		lu_uint,	lp_uint},
	{'i',	4,		0,		lu_int,		lp_int},
	{'I',	4,		0,		lu_uint,	lp_uint},
	{'l',	4,		0,		lu_int,		lp_int},
	{'L',	4,		0,		lu_uint,	lp_uint},
	{'q',	8,		0,		lu_longlong,	lp_longlong},
	{'Q',	8,		0,		lu_ulonglong,	lp_ulonglong},
	{'?',	1,		0,		bu_bool,	bp_bool}, /* Std rep not endian dep,
		but potentially different from native rep -- reuse bx_bool funcs. */
	{'f',	4,		0,		lu_float,	lp_float},
	{'d',	8,		0,		lu_double,	lp_double},
	{0}
};


static const formatdef *
whichtable(char **pfmt)
{
	const char *fmt = (*pfmt)++; /* May be backed out of later */
	switch (*fmt) {
	case '<':
		return lilendian_table;
	case '>':
	case '!': /* Network byte order is big-endian */
		return bigendian_table;
	case '=': { /* Host byte order -- different from native in aligment! */
		int n = 1;
		char *p = (char *) &n;
		if (*p == 1)
			return lilendian_table;
		else
			return bigendian_table;
	}
	default:
		--*pfmt; /* Back out of pointer increment */
		/* Fall through */
	case '@':
		return native_table;
	}
}


/* Get the table entry for a format code */

static const formatdef *
getentry(int c, const formatdef *f)
{
	for (; f->format != '\0'; f++) {
		if (f->format == c) {
			return f;
		}
	}
	PyErr_SetString(StructError, "bad char in struct format");
	return NULL;
}


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

static int
align(Py_ssize_t size, char c, const formatdef *e)
{
	if (e->format == c) {
		if (e->alignment) {
			size = ((size + e->alignment - 1)
				/ e->alignment)
				* e->alignment;
		}
	}
	return size;
}


/* calculate the size of a format string */

static int
prepare_s(PyStructObject *self)
{
	const formatdef *f;
	const formatdef *e;
	formatcode *codes;

	const char *s;
	const char *fmt;
	char c;
	Py_ssize_t size, len, num, itemsize, x;

	fmt = PyBytes_AS_STRING(self->s_format);

	f = whichtable((char **)&fmt);

	s = fmt;
	size = 0;
	len = 0;
	while ((c = *s++) != '\0') {
		if (isspace(Py_CHARMASK(c)))
			continue;
		if ('0' <= c && c <= '9') {
			num = c - '0';
			while ('0' <= (c = *s++) && c <= '9') {
				x = num*10 + (c - '0');
				if (x/10 != num) {
					PyErr_SetString(
						StructError,
						"overflow in item count");
					return -1;
				}
				num = x;
			}
			if (c == '\0')
				break;
		}
		else
			num = 1;

		e = getentry(c, f);
		if (e == NULL)
			return -1;

		switch (c) {
			case 's': /* fall through */
			case 'p': len++; break;
			case 'x': break;
			default: len += num; break;
		}

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

	/* check for overflow */
	if ((len + 1) > (PY_SSIZE_T_MAX / sizeof(formatcode))) {
		PyErr_NoMemory();
		return -1;
	}

	self->s_size = size;
	self->s_len = len;
	codes = PyMem_MALLOC((len + 1) * sizeof(formatcode));
	if (codes == NULL) {
		PyErr_NoMemory();
		return -1;
	}
	self->s_codes = codes;

	s = fmt;
	size = 0;
	while ((c = *s++) != '\0') {
		if (isspace(Py_CHARMASK(c)))
			continue;
		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;

		e = getentry(c, f);

		size = align(size, c, e);
		if (c == 's' || c == 'p') {
			codes->offset = size;
			codes->size = num;
			codes->fmtdef = e;
			codes++;
			size += num;
		} else if (c == 'x') {
			size += num;
		} else {
			while (--num >= 0) {
				codes->offset = size;
				codes->size = e->size;
				codes->fmtdef = e;
				codes++;
				size += e->size;
			}
		}
	}
	codes->fmtdef = NULL;
	codes->offset = size;
	codes->size = 0;

	return 0;
}

static PyObject *
s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
	PyObject *self;

	assert(type != NULL && type->tp_alloc != NULL);

	self = type->tp_alloc(type, 0);
	if (self != NULL) {
		PyStructObject *s = (PyStructObject*)self;
		Py_INCREF(Py_None);
		s->s_format = Py_None;
		s->s_codes = NULL;
		s->s_size = -1;
		s->s_len = -1;
	}
	return self;
}

static int
s_init(PyObject *self, PyObject *args, PyObject *kwds)
{
	PyStructObject *soself = (PyStructObject *)self;
	PyObject *o_format = NULL;
	int ret = 0;
	static char *kwlist[] = {"format", 0};

	assert(PyStruct_Check(self));

	if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:Struct", kwlist,
					 &o_format))
		return -1;

	if (PyUnicode_Check(o_format)) {
		o_format = PyUnicode_AsASCIIString(o_format);
		if (o_format == NULL)
			return -1;
	}
	/* XXX support buffer interface, too */
	else {
		Py_INCREF(o_format);
	}

	if (!PyBytes_Check(o_format)) {
		Py_DECREF(o_format);
		PyErr_Format(PyExc_TypeError,
			     "Struct() argument 1 must be bytes, not %.200s",
			     Py_TYPE(o_format)->tp_name);
		return -1;
	}

	Py_CLEAR(soself->s_format);
	soself->s_format = o_format;

	ret = prepare_s(soself);
	return ret;
}

static void
s_dealloc(PyStructObject *s)
{
	if (s->weakreflist != NULL)
		PyObject_ClearWeakRefs((PyObject *)s);
	if (s->s_codes != NULL) {
		PyMem_FREE(s->s_codes);
	}
	Py_XDECREF(s->s_format);
	Py_TYPE(s)->tp_free((PyObject *)s);
}

static PyObject *
s_unpack_internal(PyStructObject *soself, char *startfrom) {
	formatcode *code;
	Py_ssize_t i = 0;
	PyObject *result = PyTuple_New(soself->s_len);
	if (result == NULL)
		return NULL;

	for (code = soself->s_codes; code->fmtdef != NULL; code++) {
		PyObject *v;
		const formatdef *e = code->fmtdef;
		const char *res = startfrom + code->offset;
		if (e->format == 's') {
			v = PyBytes_FromStringAndSize(res, code->size);
		} else if (e->format == 'p') {
			Py_ssize_t n = *(unsigned char*)res;
			if (n >= code->size)
				n = code->size - 1;
			v = PyBytes_FromStringAndSize(res + 1, n);
		} else {
			v = e->unpack(res, e);
		}
		if (v == NULL)
			goto fail;
		PyTuple_SET_ITEM(result, i++, v);
	}

	return result;
fail:
	Py_DECREF(result);
	return NULL;
}


PyDoc_STRVAR(s_unpack__doc__,
"S.unpack(buffer) -> (v1, v2, ...)\n\
\n\
Return tuple containing values unpacked according to this Struct's format.\n\
Requires len(buffer) == self.size. See struct.__doc__ for more on format\n\
strings.");

static PyObject *
s_unpack(PyObject *self, PyObject *input)
{
	Py_buffer vbuf;
	PyObject *result;
	PyStructObject *soself = (PyStructObject *)self;

	assert(PyStruct_Check(self));
	assert(soself->s_codes != NULL);
	if (PyObject_GetBuffer(input, &vbuf, PyBUF_SIMPLE) < 0)
		return NULL;
	if (vbuf.len != soself->s_size) {
		PyErr_Format(StructError,
			     "unpack requires a bytes argument of length %zd",
			     soself->s_size);
                PyBuffer_Release(&vbuf);
		return NULL;
	}
	result = s_unpack_internal(soself, vbuf.buf);
	PyBuffer_Release(&vbuf);
	return result;
}

PyDoc_STRVAR(s_unpack_from__doc__,
"S.unpack_from(buffer[, offset]) -> (v1, v2, ...)\n\
\n\
Return tuple containing values unpacked according to this Struct's format.\n\
Unlike unpack, unpack_from can unpack values from any object supporting\n\
the buffer API, not just str. Requires len(buffer[offset:]) >= self.size.\n\
See struct.__doc__ for more on format strings.");

static PyObject *
s_unpack_from(PyObject *self, PyObject *args, PyObject *kwds)
{
	static char *kwlist[] = {"buffer", "offset", 0};

	PyObject *input;
	Py_ssize_t offset = 0;
	Py_buffer vbuf;
	PyObject *result;
	PyStructObject *soself = (PyStructObject *)self;

	assert(PyStruct_Check(self));
	assert(soself->s_codes != NULL);

	if (!PyArg_ParseTupleAndKeywords(args, kwds,
					 "O|n:unpack_from", kwlist,
					 &input, &offset))
		return NULL;
	if (PyObject_GetBuffer(input, &vbuf, PyBUF_SIMPLE) < 0)
		return NULL;
	if (offset < 0)
		offset += vbuf.len;
	if (offset < 0 || vbuf.len - offset < soself->s_size) {
		PyErr_Format(StructError,
			"unpack_from requires a buffer of at least %zd bytes",
			soself->s_size);
                PyBuffer_Release(&vbuf);
		return NULL;
	}
	result = s_unpack_internal(soself, (char*)vbuf.buf + offset);
	PyBuffer_Release(&vbuf);
	return result;
}


/*
 * Guts of the pack function.
 *
 * Takes a struct object, a tuple of arguments, and offset in that tuple of
 * argument for where to start processing the arguments for packing, and a
 * character buffer for writing the packed string.  The caller must insure
 * that the buffer may contain the required length for packing the arguments.
 * 0 is returned on success, 1 is returned if there is an error.
 *
 */
static int
s_pack_internal(PyStructObject *soself, PyObject *args, int offset, char* buf)
{
	formatcode *code;
	/* XXX(nnorwitz): why does i need to be a local?  can we use
	   the offset parameter or do we need the wider width? */
	Py_ssize_t i;

	memset(buf, '\0', soself->s_size);
	i = offset;
	for (code = soself->s_codes; code->fmtdef != NULL; code++) {
		Py_ssize_t n;
		PyObject *v = PyTuple_GET_ITEM(args, i++);
		const formatdef *e = code->fmtdef;
		char *res = buf + code->offset;
		if (e->format == 's') {
			int isstring;
			void *p;
			if (PyUnicode_Check(v)) {
				v = _PyUnicode_AsDefaultEncodedString(v, NULL);
				if (v == NULL)
					return -1;
			}
			isstring = PyBytes_Check(v);
			if (!isstring && !PyByteArray_Check(v)) {
				PyErr_SetString(StructError,
						"argument for 's' must be a bytes or string");
				return -1;
			}
			if (isstring) {
				n = PyBytes_GET_SIZE(v);
				p = PyBytes_AS_STRING(v);
			}
			else {
				n = PyByteArray_GET_SIZE(v);
				p = PyByteArray_AS_STRING(v);
			}
			if (n > code->size)
				n = code->size;
			if (n > 0)
				memcpy(res, p, n);
		} else if (e->format == 'p') {
			int isstring;
			void *p;
			if (PyUnicode_Check(v)) {
				v = _PyUnicode_AsDefaultEncodedString(v, NULL);
				if (v == NULL)
					return -1;
			}
			isstring = PyBytes_Check(v);
			if (!isstring && !PyByteArray_Check(v)) {
				PyErr_SetString(StructError,
						"argument for 'p' must be a bytes or string");
				return -1;
			}
			if (isstring) {
				n = PyBytes_GET_SIZE(v);
				p = PyBytes_AS_STRING(v);
			}
			else {
				n = PyByteArray_GET_SIZE(v);
				p = PyByteArray_AS_STRING(v);
			}
			if (n > (code->size - 1))
				n = code->size - 1;
			if (n > 0)
				memcpy(res + 1, p, n);
			if (n > 255)
				n = 255;
			*res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char);
		} else {
			if (e->pack(res, v, e) < 0) {
				if (PyLong_Check(v) && PyErr_ExceptionMatches(PyExc_OverflowError))
					PyErr_SetString(StructError,
							"long too large to convert to int");
				return -1;
			}
		}
	}

	/* Success */
	return 0;
}


PyDoc_STRVAR(s_pack__doc__,
"S.pack(v1, v2, ...) -> bytes\n\
\n\
Return a bytes containing values v1, v2, ... packed according to this\n\
Struct's format. See struct.__doc__ for more on format strings.");

static PyObject *
s_pack(PyObject *self, PyObject *args)
{
	PyStructObject *soself;
	PyObject *result;

	/* Validate arguments. */
	soself = (PyStructObject *)self;
	assert(PyStruct_Check(self));
	assert(soself->s_codes != NULL);
	if (PyTuple_GET_SIZE(args) != soself->s_len)
	{
		PyErr_Format(StructError,
			"pack requires exactly %zd arguments", soself->s_len);
		return NULL;
	}

	/* Allocate a new string */
	result = PyBytes_FromStringAndSize((char *)NULL, soself->s_size);
	if (result == NULL)
		return NULL;

	/* Call the guts */
	if ( s_pack_internal(soself, args, 0, PyBytes_AS_STRING(result)) != 0 ) {
		Py_DECREF(result);
		return NULL;
	}

	return result;
}

PyDoc_STRVAR(s_pack_into__doc__,
"S.pack_into(buffer, offset, v1, v2, ...)\n\
\n\
Pack the values v1, v2, ... according to this Struct's format, write \n\
the packed bytes into the writable buffer buf starting at offset.  Note\n\
that the offset is not an optional argument.  See struct.__doc__ for \n\
more on format strings.");

static PyObject *
s_pack_into(PyObject *self, PyObject *args)
{
	PyStructObject *soself;
	char *buffer;
	Py_ssize_t buffer_len, offset;

	/* Validate arguments.  +1 is for the first arg as buffer. */
	soself = (PyStructObject *)self;
	assert(PyStruct_Check(self));
	assert(soself->s_codes != NULL);
	if (PyTuple_GET_SIZE(args) != (soself->s_len + 2))
	{
		PyErr_Format(StructError,
			     "pack_into requires exactly %zd arguments",
			     (soself->s_len + 2));
		return NULL;
	}

	/* Extract a writable memory buffer from the first argument */
	if ( PyObject_AsWriteBuffer(PyTuple_GET_ITEM(args, 0),
								(void**)&buffer, &buffer_len) == -1 ) {
		return NULL;
	}
	assert( buffer_len >= 0 );

	/* Extract the offset from the first argument */
	offset = PyLong_AsSsize_t(PyTuple_GET_ITEM(args, 1));

	/* Support negative offsets. */
	if (offset < 0)
		offset += buffer_len;

	/* Check boundaries */
	if (offset < 0 || (buffer_len - offset) < soself->s_size) {
		PyErr_Format(StructError,
			     "pack_into requires a buffer of at least %zd bytes",
			     soself->s_size);
		return NULL;
	}

	/* Call the guts */
	if ( s_pack_internal(soself, args, 2, buffer + offset) != 0 ) {
		return NULL;
	}

	Py_RETURN_NONE;
}

static PyObject *
s_get_format(PyStructObject *self, void *unused)
{
	Py_INCREF(self->s_format);
	return self->s_format;
}

static PyObject *
s_get_size(PyStructObject *self, void *unused)
{
    return PyLong_FromSsize_t(self->s_size);
}

/* List of functions */

static struct PyMethodDef s_methods[] = {
	{"pack",	s_pack,		METH_VARARGS, s_pack__doc__},
	{"pack_into",	s_pack_into,	METH_VARARGS, s_pack_into__doc__},
	{"unpack",	s_unpack,       METH_O, s_unpack__doc__},
	{"unpack_from",	(PyCFunction)s_unpack_from, METH_VARARGS|METH_KEYWORDS,
			s_unpack_from__doc__},
	{NULL,	 NULL}		/* sentinel */
};

PyDoc_STRVAR(s__doc__, "Compiled struct object");

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

static PyGetSetDef s_getsetlist[] = {
	{"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL},
	{"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL},
	{NULL} /* sentinel */
};

static
PyTypeObject PyStructType = {
	PyVarObject_HEAD_INIT(NULL, 0)
	"Struct",
	sizeof(PyStructObject),
	0,
	(destructor)s_dealloc,	/* tp_dealloc */
	0,					/* tp_print */
	0,					/* tp_getattr */
	0,					/* tp_setattr */
	0,					/* tp_compare */
	0,					/* tp_repr */
	0,					/* tp_as_number */
	0,					/* tp_as_sequence */
	0,					/* tp_as_mapping */
	0,					/* tp_hash */
	0,					/* tp_call */
	0,					/* tp_str */
	PyObject_GenericGetAttr,	/* tp_getattro */
	PyObject_GenericSetAttr,	/* tp_setattro */
	0,					/* tp_as_buffer */
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
	s__doc__,			/* tp_doc */
	0,					/* tp_traverse */
	0,					/* tp_clear */
	0,					/* tp_richcompare */
	offsetof(PyStructObject, weakreflist),	/* tp_weaklistoffset */
	0,					/* tp_iter */
	0,					/* tp_iternext */
	s_methods,			/* tp_methods */
	NULL,				/* tp_members */
	s_getsetlist,		/* tp_getset */
	0,					/* tp_base */
	0,					/* tp_dict */
	0,					/* tp_descr_get */
	0,					/* tp_descr_set */
	0,					/* tp_dictoffset */
	s_init,				/* tp_init */
	PyType_GenericAlloc,/* tp_alloc */
	s_new,				/* tp_new */
	PyObject_Del,		/* tp_free */
};


/* ---- Standalone functions  ---- */

#define MAXCACHE 100
static PyObject *cache = NULL;

static PyObject *
cache_struct(PyObject *fmt)
{
	PyObject * s_object;

	if (cache == NULL) {
		cache = PyDict_New();
		if (cache == NULL)
			return NULL;
	}

	s_object = PyDict_GetItem(cache, fmt);
	if (s_object != NULL) {
		Py_INCREF(s_object);
		return s_object;
	}

	s_object = PyObject_CallFunctionObjArgs((PyObject *)(&PyStructType), fmt, NULL);
	if (s_object != NULL) {
		if (PyDict_Size(cache) >= MAXCACHE)
			PyDict_Clear(cache);
		/* Attempt to cache the result */
		if (PyDict_SetItem(cache, fmt, s_object) == -1)
			PyErr_Clear();
	}
	return s_object;
}

PyDoc_STRVAR(clearcache_doc,
"Clear the internal cache.");

static PyObject *
clearcache(PyObject *self)
{
	Py_CLEAR(cache);
	Py_RETURN_NONE;
}

PyDoc_STRVAR(calcsize_doc,
"Return size of C struct described by format string fmt.");

static PyObject *
calcsize(PyObject *self, PyObject *fmt)
{
	Py_ssize_t n;
	PyObject *s_object = cache_struct(fmt);
	if (s_object == NULL)
		return NULL;
	n = ((PyStructObject *)s_object)->s_size;
	Py_DECREF(s_object);
    	return PyLong_FromSsize_t(n);
}

PyDoc_STRVAR(pack_doc,
"Return bytes containing values v1, v2, ... packed according to fmt.");

static PyObject *
pack(PyObject *self, PyObject *args)
{
	PyObject *s_object, *fmt, *newargs, *result;
	Py_ssize_t n = PyTuple_GET_SIZE(args);

	if (n == 0) {
		PyErr_SetString(PyExc_TypeError, "missing format argument");
		return NULL;
	}
	fmt = PyTuple_GET_ITEM(args, 0);
	newargs = PyTuple_GetSlice(args, 1, n);
	if (newargs == NULL)
		return NULL;

	s_object = cache_struct(fmt);
	if (s_object == NULL) {
		Py_DECREF(newargs);
		return NULL;
	}
    	result = s_pack(s_object, newargs);
	Py_DECREF(newargs);
	Py_DECREF(s_object);
	return result;
}

PyDoc_STRVAR(pack_into_doc,
"Pack the values v1, v2, ... according to fmt.\n\
Write the packed bytes into the writable buffer buf starting at offset.");

static PyObject *
pack_into(PyObject *self, PyObject *args)
{
	PyObject *s_object, *fmt, *newargs, *result;
	Py_ssize_t n = PyTuple_GET_SIZE(args);

	if (n == 0) {
		PyErr_SetString(PyExc_TypeError, "missing format argument");
		return NULL;
	}
	fmt = PyTuple_GET_ITEM(args, 0);
	newargs = PyTuple_GetSlice(args, 1, n);
	if (newargs == NULL)
		return NULL;

	s_object = cache_struct(fmt);
	if (s_object == NULL) {
		Py_DECREF(newargs);
		return NULL;
	}
    	result = s_pack_into(s_object, newargs);
	Py_DECREF(newargs);
	Py_DECREF(s_object);
	return result;
}

PyDoc_STRVAR(unpack_doc,
"Unpack the bytes containing packed C structure data, according to fmt.\n\
Requires len(bytes) == calcsize(fmt).");

static PyObject *
unpack(PyObject *self, PyObject *args)
{
	PyObject *s_object, *fmt, *inputstr, *result;

	if (!PyArg_UnpackTuple(args, "unpack", 2, 2, &fmt, &inputstr))
		return NULL;

	s_object = cache_struct(fmt);
	if (s_object == NULL)
		return NULL;
    	result = s_unpack(s_object, inputstr);
	Py_DECREF(s_object);
	return result;
}

PyDoc_STRVAR(unpack_from_doc,
"Unpack the buffer, containing packed C structure data, according to\n\
fmt, starting at offset. Requires len(buffer[offset:]) >= calcsize(fmt).");

static PyObject *
unpack_from(PyObject *self, PyObject *args, PyObject *kwds)
{
	PyObject *s_object, *fmt, *newargs, *result;
	Py_ssize_t n = PyTuple_GET_SIZE(args);

	if (n == 0) {
		PyErr_SetString(PyExc_TypeError, "missing format argument");
		return NULL;
	}
	fmt = PyTuple_GET_ITEM(args, 0);
	newargs = PyTuple_GetSlice(args, 1, n);
	if (newargs == NULL)
		return NULL;

	s_object = cache_struct(fmt);
	if (s_object == NULL) {
		Py_DECREF(newargs);
		return NULL;
	}
    	result = s_unpack_from(s_object, newargs, kwds);
	Py_DECREF(newargs);
	Py_DECREF(s_object);
	return result;
}

static struct PyMethodDef module_functions[] = {
	{"_clearcache",	(PyCFunction)clearcache,	METH_NOARGS, 	clearcache_doc},
	{"calcsize",	calcsize,	METH_O, 	calcsize_doc},
	{"pack",	pack,		METH_VARARGS, 	pack_doc},
	{"pack_into",	pack_into,	METH_VARARGS, 	pack_into_doc},
	{"unpack",	unpack,       	METH_VARARGS, 	unpack_doc},
	{"unpack_from",	(PyCFunction)unpack_from, 	
			METH_VARARGS|METH_KEYWORDS, 	unpack_from_doc},
	{NULL,	 NULL}		/* sentinel */
};


/* Module initialization */

PyDoc_STRVAR(module_doc,
"Functions to convert between Python values and C structs.\n\
Python bytes objects are used to hold the data representing the C struct\n\
and also as format strings to describe the layout of data in the C struct.\n\
\n\
The optional first format char indicates byte order, size and alignment:\n\
 @: native order, size & alignment (default)\n\
 =: native order, std. size & alignment\n\
 <: little-endian, std. size & alignment\n\
 >: big-endian, std. size & alignment\n\
 !: same as >\n\
\n\
The remaining chars indicate types of args and must match exactly;\n\
these can be preceded by a decimal repeat count:\n\
  x: pad byte (no data); c:char; b:signed byte; B:unsigned byte;\n\
  h:short; H:unsigned short; i:int; I:unsigned int;\n\
  l:long; L:unsigned long; f:float; d:double.\n\
Special cases (preceding decimal count indicates length):\n\
  s:string (array of char); p: pascal string (with count byte).\n\
Special case (only available in native format):\n\
  P:an integer type that is wide enough to hold a pointer.\n\
Special case (not in native mode unless 'long long' in platform C):\n\
  q:long long; Q:unsigned long long\n\
Whitespace between formats is ignored.\n\
\n\
The variable struct.error is an exception raised on errors.\n");


static struct PyModuleDef _structmodule = {
	PyModuleDef_HEAD_INIT,
	"_struct",
	module_doc,
	-1,
	module_functions,
	NULL,
	NULL,
	NULL,
	NULL
};

PyMODINIT_FUNC
PyInit__struct(void)
{
	PyObject *ver, *m;

	ver = PyBytes_FromString("0.2");
	if (ver == NULL)
		return NULL;

	m = PyModule_Create(&_structmodule);
	if (m == NULL)
		return NULL;

	Py_TYPE(&PyStructType) = &PyType_Type;
	if (PyType_Ready(&PyStructType) < 0)
		return NULL;

#ifdef PY_STRUCT_OVERFLOW_MASKING
	if (pyint_zero == NULL) {
		pyint_zero = PyLong_FromLong(0);
		if (pyint_zero == NULL)
			return NULL;
	}
	if (pylong_ulong_mask == NULL) {
#if (SIZEOF_LONG == 4)
		pylong_ulong_mask = PyLong_FromString("FFFFFFFF", NULL, 16);
#else
		pylong_ulong_mask = PyLong_FromString("FFFFFFFFFFFFFFFF", NULL, 16);
#endif
		if (pylong_ulong_mask == NULL)
			return NULL;
	}

#else
	/* This speed trick can't be used until overflow masking goes away, because
	   native endian always raises exceptions instead of overflow masking. */

	/* Check endian and swap in faster functions */
	{
		int one = 1;
		formatdef *native = native_table;
		formatdef *other, *ptr;
		if ((int)*(unsigned char*)&one)
			other = lilendian_table;
		else
			other = bigendian_table;
		/* Scan through the native table, find a matching
		   entry in the endian table and swap in the
		   native implementations whenever possible
		   (64-bit platforms may not have "standard" sizes) */
		while (native->format != '\0' && other->format != '\0') {
			ptr = other;
			while (ptr->format != '\0') {
				if (ptr->format == native->format) {
					/* Match faster when formats are
					   listed in the same order */
					if (ptr == other)
						other++;
					/* Only use the trick if the
					   size matches */
					if (ptr->size != native->size)
						break;
					/* Skip float and double, could be
					   "unknown" float format */
					if (ptr->format == 'd' || ptr->format == 'f')
						break;
					ptr->pack = native->pack;
					ptr->unpack = native->unpack;
					break;
				}
				ptr++;
			}
			native++;
		}
	}
#endif

	/* Add some symbolic constants to the module */
	if (StructError == NULL) {
		StructError = PyErr_NewException("struct.error", NULL, NULL);
		if (StructError == NULL)
			return NULL;
	}

	Py_INCREF(StructError);
	PyModule_AddObject(m, "error", StructError);

	Py_INCREF((PyObject*)&PyStructType);
	PyModule_AddObject(m, "Struct", (PyObject*)&PyStructType);

	PyModule_AddObject(m, "__version__", ver);

	PyModule_AddIntConstant(m, "_PY_STRUCT_RANGE_CHECKING", 1);
#ifdef PY_STRUCT_OVERFLOW_MASKING
	PyModule_AddIntConstant(m, "_PY_STRUCT_OVERFLOW_MASKING", 1);
#endif
#ifdef PY_STRUCT_FLOAT_COERCE
	PyModule_AddIntConstant(m, "_PY_STRUCT_FLOAT_COERCE", 1);
#endif
	return m;

}
