mirror of https://github.com/python/cpython
Struct now unpacks to PY_LONG_LONG directly when possible, also include #ifdef'ed out code that will return int instead of long when in bounds (not active since it's an API and doc change)
This commit is contained in:
parent
c3434b3834
commit
94f68ee8ba
|
@ -15,6 +15,12 @@ static PyTypeObject PyStructType;
|
||||||
typedef int Py_ssize_t;
|
typedef int Py_ssize_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* PY_USE_INT_WHEN_POSSIBLE is an experimental flag that changes the
|
||||||
|
struct API to return int instead of long when possible. This is
|
||||||
|
often a significant performance improvement. */
|
||||||
|
/*
|
||||||
|
#define PY_USE_INT_WHEN_POSSIBLE 1
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
/* The translation function for each format character is table driven */
|
/* The translation function for each format character is table driven */
|
||||||
|
@ -284,6 +290,10 @@ nu_uint(const char *p, const formatdef *f)
|
||||||
{
|
{
|
||||||
unsigned int x;
|
unsigned int x;
|
||||||
memcpy((char *)&x, p, sizeof x);
|
memcpy((char *)&x, p, sizeof x);
|
||||||
|
#ifdef PY_USE_INT_WHEN_POSSIBLE
|
||||||
|
if (x <= INT_MAX)
|
||||||
|
return PyInt_FromLong((long)x);
|
||||||
|
#endif
|
||||||
return PyLong_FromUnsignedLong((unsigned long)x);
|
return PyLong_FromUnsignedLong((unsigned long)x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,6 +310,10 @@ nu_ulong(const char *p, const formatdef *f)
|
||||||
{
|
{
|
||||||
unsigned long x;
|
unsigned long x;
|
||||||
memcpy((char *)&x, p, sizeof x);
|
memcpy((char *)&x, p, sizeof x);
|
||||||
|
#ifdef PY_USE_INT_WHEN_POSSIBLE
|
||||||
|
if (x <= INT_MAX)
|
||||||
|
return PyInt_FromLong((long)x);
|
||||||
|
#endif
|
||||||
return PyLong_FromUnsignedLong(x);
|
return PyLong_FromUnsignedLong(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,6 +327,10 @@ nu_longlong(const char *p, const formatdef *f)
|
||||||
{
|
{
|
||||||
PY_LONG_LONG x;
|
PY_LONG_LONG x;
|
||||||
memcpy((char *)&x, p, sizeof x);
|
memcpy((char *)&x, p, sizeof x);
|
||||||
|
#ifdef PY_USE_INT_WHEN_POSSIBLE
|
||||||
|
if (x >= INT_MIN && x <= INT_MAX)
|
||||||
|
return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
|
||||||
|
#endif
|
||||||
return PyLong_FromLongLong(x);
|
return PyLong_FromLongLong(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,6 +339,10 @@ nu_ulonglong(const char *p, const formatdef *f)
|
||||||
{
|
{
|
||||||
unsigned PY_LONG_LONG x;
|
unsigned PY_LONG_LONG x;
|
||||||
memcpy((char *)&x, p, sizeof x);
|
memcpy((char *)&x, p, sizeof x);
|
||||||
|
#ifdef PY_USE_INT_WHEN_POSSIBLE
|
||||||
|
if (x <= INT_MAX)
|
||||||
|
return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
|
||||||
|
#endif
|
||||||
return PyLong_FromUnsignedLongLong(x);
|
return PyLong_FromUnsignedLongLong(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -584,28 +606,58 @@ bu_uint(const char *p, const formatdef *f)
|
||||||
do {
|
do {
|
||||||
x = (x<<8) | (*p++ & 0xFF);
|
x = (x<<8) | (*p++ & 0xFF);
|
||||||
} while (--i > 0);
|
} while (--i > 0);
|
||||||
if (f->size >= 4)
|
#ifdef PY_USE_INT_WHEN_POSSIBLE
|
||||||
return PyLong_FromUnsignedLong(x);
|
if (x <= INT_MAX)
|
||||||
else
|
|
||||||
return PyInt_FromLong((long)x);
|
return PyInt_FromLong((long)x);
|
||||||
|
#endif
|
||||||
|
return PyLong_FromUnsignedLong(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
bu_longlong(const char *p, const formatdef *f)
|
bu_longlong(const char *p, const formatdef *f)
|
||||||
{
|
{
|
||||||
|
#if HAVE_LONG_LONG
|
||||||
|
PY_LONG_LONG x = 0;
|
||||||
|
int i = f->size;
|
||||||
|
do {
|
||||||
|
x = (x<<8) | (*p++ & 0xFF);
|
||||||
|
} while (--i > 0);
|
||||||
|
/* Extend the sign bit. */
|
||||||
|
if (SIZEOF_LONG_LONG > f->size)
|
||||||
|
x |= -(x & (1L << (8 * f->size - 1)));
|
||||||
|
#ifdef PY_USE_INT_WHEN_POSSIBLE
|
||||||
|
if (x >= INT_MIN && x <= INT_MAX)
|
||||||
|
return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
|
||||||
|
#endif
|
||||||
|
return PyLong_FromLongLong(x);
|
||||||
|
#else
|
||||||
return _PyLong_FromByteArray((const unsigned char *)p,
|
return _PyLong_FromByteArray((const unsigned char *)p,
|
||||||
8,
|
8,
|
||||||
0, /* little-endian */
|
0, /* little-endian */
|
||||||
1 /* signed */);
|
1 /* signed */);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
bu_ulonglong(const char *p, const formatdef *f)
|
bu_ulonglong(const char *p, const formatdef *f)
|
||||||
{
|
{
|
||||||
|
#if HAVE_LONG_LONG
|
||||||
|
unsigned PY_LONG_LONG x = 0;
|
||||||
|
int i = f->size;
|
||||||
|
do {
|
||||||
|
x = (x<<8) | (*p++ & 0xFF);
|
||||||
|
} while (--i > 0);
|
||||||
|
#ifdef PY_USE_INT_WHEN_POSSIBLE
|
||||||
|
if (x <= INT_MAX)
|
||||||
|
return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
|
||||||
|
#endif
|
||||||
|
return PyLong_FromUnsignedLongLong(x);
|
||||||
|
#else
|
||||||
return _PyLong_FromByteArray((const unsigned char *)p,
|
return _PyLong_FromByteArray((const unsigned char *)p,
|
||||||
8,
|
8,
|
||||||
0, /* little-endian */
|
0, /* little-endian */
|
||||||
0 /* signed */);
|
0 /* signed */);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -750,28 +802,58 @@ lu_uint(const char *p, const formatdef *f)
|
||||||
do {
|
do {
|
||||||
x = (x<<8) | (p[--i] & 0xFF);
|
x = (x<<8) | (p[--i] & 0xFF);
|
||||||
} while (i > 0);
|
} while (i > 0);
|
||||||
if (f->size >= 4)
|
#ifdef PY_USE_INT_WHEN_POSSIBLE
|
||||||
return PyLong_FromUnsignedLong(x);
|
if (x <= INT_MAX)
|
||||||
else
|
|
||||||
return PyInt_FromLong((long)x);
|
return PyInt_FromLong((long)x);
|
||||||
|
#endif
|
||||||
|
return PyLong_FromUnsignedLong((long)x);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
lu_longlong(const char *p, const formatdef *f)
|
lu_longlong(const char *p, const formatdef *f)
|
||||||
{
|
{
|
||||||
|
#if HAVE_LONG_LONG
|
||||||
|
PY_LONG_LONG x = 0;
|
||||||
|
int i = f->size;
|
||||||
|
do {
|
||||||
|
x = (x<<8) | (p[--i] & 0xFF);
|
||||||
|
} while (i > 0);
|
||||||
|
/* Extend the sign bit. */
|
||||||
|
if (SIZEOF_LONG_LONG > f->size)
|
||||||
|
x |= -(x & (1L << (8 * f->size - 1)));
|
||||||
|
#ifdef PY_USE_INT_WHEN_POSSIBLE
|
||||||
|
if (x >= INT_MIN && x <= INT_MAX)
|
||||||
|
return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
|
||||||
|
#endif
|
||||||
|
return PyLong_FromLongLong(x);
|
||||||
|
#else
|
||||||
return _PyLong_FromByteArray((const unsigned char *)p,
|
return _PyLong_FromByteArray((const unsigned char *)p,
|
||||||
8,
|
8,
|
||||||
1, /* little-endian */
|
1, /* little-endian */
|
||||||
1 /* signed */);
|
1 /* signed */);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
lu_ulonglong(const char *p, const formatdef *f)
|
lu_ulonglong(const char *p, const formatdef *f)
|
||||||
{
|
{
|
||||||
|
#if HAVE_LONG_LONG
|
||||||
|
unsigned PY_LONG_LONG x = 0;
|
||||||
|
int i = f->size;
|
||||||
|
do {
|
||||||
|
x = (x<<8) | (p[--i] & 0xFF);
|
||||||
|
} while (i > 0);
|
||||||
|
#ifdef PY_USE_INT_WHEN_POSSIBLE
|
||||||
|
if (x <= INT_MAX)
|
||||||
|
return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
|
||||||
|
#endif
|
||||||
|
return PyLong_FromUnsignedLongLong(x);
|
||||||
|
#else
|
||||||
return _PyLong_FromByteArray((const unsigned char *)p,
|
return _PyLong_FromByteArray((const unsigned char *)p,
|
||||||
8,
|
8,
|
||||||
1, /* little-endian */
|
1, /* little-endian */
|
||||||
0 /* signed */);
|
0 /* signed */);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
|
Loading…
Reference in New Issue