1896 lines · 42.7 KB · C
RawDownload
/* struct module -- pack values into and (out of) strings */ /* 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; /* compatibility macros */#if (PY_VERSION_HEX < 0x02050000)typedef int Py_ssize_t;#endif /* 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_MASKINGstatic 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) ((op)->ob_type == &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_LONGtypedef struct { char c; PY_LONG_LONG x; } s_long_long;#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(PY_LONG_LONG))#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 (PyInt_Check(v))		return PyLong_FromLong(PyInt_AS_LONG(v));	if (PyLong_Check(v)) {		Py_INCREF(v);		return v;	}	m = v->ob_type->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 intget_long(PyObject *v, long *p){	long x = PyInt_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 intget_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 intget_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 intget_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 intget_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 intget_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,				    PyString_AS_STRING(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 PyString_FromStringAndSize(p, 1);} static PyObject *nu_byte(const char *p, const formatdef *f){	return PyInt_FromLong((long) *(signed char *)p);} static PyObject *nu_ubyte(const char *p, const formatdef *f){	return PyInt_FromLong((long) *(unsigned char *)p);} static PyObject *nu_short(const char *p, const formatdef *f){	short x;	memcpy((char *)&x, p, sizeof x);	return PyInt_FromLong((long)x);} static PyObject *nu_ushort(const char *p, const formatdef *f){	unsigned short x;	memcpy((char *)&x, p, sizeof x);	return PyInt_FromLong((long)x);} static PyObject *nu_int(const char *p, const formatdef *f){	int x;	memcpy((char *)&x, p, sizeof x);	return PyInt_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 PyInt_FromLong((long)x);#else	if (x <= ((unsigned int)LONG_MAX))		return PyInt_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 PyInt_FromLong(x);} 

Lines 1–500 of 1896.