[Python-checkins] r46240 - python/trunk/Modules/_struct.c

Neal Norwitz nnorwitz at gmail.com
Sun May 28 04:22:09 CEST 2006


All occurrences of *p & 0xFF where p is a char* should use Py_CHARMASK().

On 5/25/06, bob.ippolito <python-checkins at python.org> wrote:
> Author: bob.ippolito
> Date: Thu May 25 20:44:50 2006
> New Revision: 46240
>
> Modified:
>    python/trunk/Modules/_struct.c
> Log:
> 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)
>
> Modified: python/trunk/Modules/_struct.c
> ==============================================================================
> --- python/trunk/Modules/_struct.c      (original)
> +++ python/trunk/Modules/_struct.c      Thu May 25 20:44:50 2006
> @@ -15,6 +15,12 @@
>  typedef int Py_ssize_t;
>  #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 */
> @@ -284,6 +290,10 @@
>  {
>         unsigned int 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);
>  }
>
> @@ -300,6 +310,10 @@
>  {
>         unsigned long 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);
>  }
>
> @@ -313,6 +327,10 @@
>  {
>         PY_LONG_LONG 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);
>  }
>
> @@ -321,6 +339,10 @@
>  {
>         unsigned PY_LONG_LONG 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);
>  }
>
> @@ -584,28 +606,58 @@
>         do {
>                 x = (x<<8) | (*p++ & 0xFF);
>         } while (--i > 0);
> -       if (f->size >= 4)
> -               return PyLong_FromUnsignedLong(x);
> -       else
> +#ifdef PY_USE_INT_WHEN_POSSIBLE
> +       if (x <= INT_MAX)
>                 return PyInt_FromLong((long)x);
> +#endif
> +       return PyLong_FromUnsignedLong(x);
>  }
>
>  static PyObject *
>  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,
>                                       8,
>                                       0, /* little-endian */
>                                       1  /* signed */);
> +#endif
>  }
>
>  static PyObject *
>  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,
>                                       8,
>                                       0, /* little-endian */
>                                       0  /* signed */);
> +#endif
>  }
>
>  static PyObject *
> @@ -750,28 +802,58 @@
>         do {
>                 x = (x<<8) | (p[--i] & 0xFF);
>         } while (i > 0);
> -       if (f->size >= 4)
> -               return PyLong_FromUnsignedLong(x);
> -       else
> +#ifdef PY_USE_INT_WHEN_POSSIBLE
> +       if (x <= INT_MAX)
>                 return PyInt_FromLong((long)x);
> +#endif
> +       return PyLong_FromUnsignedLong((long)x);
>  }
>
>  static PyObject *
>  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,
>                                       8,
>                                       1, /* little-endian */
>                                       1  /* signed */);
> +#endif
>  }
>
>  static PyObject *
>  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,
>                                       8,
>                                       1, /* little-endian */
>                                       0  /* signed */);
> +#endif
>  }
>
>  static PyObject *
> _______________________________________________
> Python-checkins mailing list
> Python-checkins at python.org
> http://mail.python.org/mailman/listinfo/python-checkins
>


More information about the Python-checkins mailing list