Mercurial > cpython-lru_cache-weakref
diff Modules/structmodule.c @ 25366:0b68d810a8be 2.2
Backport 2.57 from trunk:
(Most of) SF patch 601369 (Christos Georgiou): obmalloc,structmodule:
64bit, big endian (issue 2 only).
This adds a bunch of memcpy calls via a temporary variable to avoid
alignment errors. That's needed for some platforms.
| author | Guido van Rossum <guido@python.org> |
|---|---|
| date | Mon, 23 Sep 2002 20:54:04 +0000 |
| parents | edd9d0b3c47e |
| children | eec3fd164a7d |
line wrap: on
line diff
--- a/Modules/structmodule.c Mon Sep 23 20:49:43 2002 +0000 +++ b/Modules/structmodule.c Mon Sep 23 20:54:04 2002 +0000 @@ -1,4 +1,3 @@ - /* struct module -- pack values into and (out of) strings */ /* New version supporting byte order, alignment and size options, @@ -483,6 +482,14 @@ */ /* 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) @@ -505,38 +512,49 @@ static PyObject * nu_short(const char *p, const formatdef *f) { - return PyInt_FromLong((long) *(short *)p); + short x; + memcpy((char *)&x, p, sizeof x); + return PyInt_FromLong((long)x); } static PyObject * nu_ushort(const char *p, const formatdef *f) { - return PyInt_FromLong((long) *(unsigned short *)p); + unsigned short x; + memcpy((char *)&x, p, sizeof x); + return PyInt_FromLong((long)x); } static PyObject * nu_int(const char *p, const formatdef *f) { - return PyInt_FromLong((long) *(int *)p); + 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 = *(unsigned int *)p; + unsigned int x; + memcpy((char *)&x, p, sizeof x); return PyLong_FromUnsignedLong((unsigned long)x); } static PyObject * nu_long(const char *p, const formatdef *f) { - return PyInt_FromLong(*(long *)p); + long x; + memcpy((char *)&x, p, sizeof x); + return PyInt_FromLong(x); } static PyObject * nu_ulong(const char *p, const formatdef *f) { - return PyLong_FromUnsignedLong(*(unsigned long *)p); + unsigned long x; + memcpy((char *)&x, p, sizeof x); + return PyLong_FromUnsignedLong(x); } /* Native mode doesn't support q or Q unless the platform C supports @@ -547,27 +565,26 @@ static PyObject * nu_longlong(const char *p, const formatdef *f) { - /* p may not be properly aligned */ LONG_LONG x; - memcpy(&x, p, sizeof(LONG_LONG)); + memcpy((char *)&x, p, sizeof x); return PyLong_FromLongLong(x); } static PyObject * nu_ulonglong(const char *p, const formatdef *f) { - /* p may not be properly aligned */ unsigned LONG_LONG x; - memcpy(&x, p, sizeof(unsigned LONG_LONG)); + memcpy((char *)&x, p, sizeof x); return PyLong_FromUnsignedLongLong(x); } + #endif static PyObject * nu_float(const char *p, const formatdef *f) { float x; - memcpy((char *)&x, p, sizeof(float)); + memcpy((char *)&x, p, sizeof x); return PyFloat_FromDouble((double)x); } @@ -575,14 +592,16 @@ nu_double(const char *p, const formatdef *f) { double x; - memcpy((char *)&x, p, sizeof(double)); + memcpy((char *)&x, p, sizeof x); return PyFloat_FromDouble(x); } static PyObject * nu_void_p(const char *p, const formatdef *f) { - return PyLong_FromVoidPtr(*(void **)p); + void *x; + memcpy((char *)&x, p, sizeof x); + return PyLong_FromVoidPtr(x); } static int @@ -631,15 +650,17 @@ 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)); + "<=number<=" STRINGIFY(SHRT_MAX)); return -1; } - * (short *)p = (short)x; + y = (short)x; + memcpy(p, (char *)&y, sizeof y); return 0; } @@ -647,6 +668,7 @@ 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){ @@ -654,7 +676,8 @@ "short format requires 0<=number<=" STRINGIFY(USHRT_MAX)); return -1; } - * (unsigned short *)p = (unsigned short)x; + y = (unsigned short)x; + memcpy(p, (char *)&y, sizeof y); return 0; } @@ -662,9 +685,11 @@ np_int(char *p, PyObject *v, const formatdef *f) { long x; + int y; if (get_long(v, &x) < 0) return -1; - * (int *)p = x; + y = (int)x; + memcpy(p, (char *)&y, sizeof y); return 0; } @@ -672,9 +697,11 @@ np_uint(char *p, PyObject *v, const formatdef *f) { unsigned long x; + unsigned int y; if (get_ulong(v, &x) < 0) return -1; - * (unsigned int *)p = x; + y = (unsigned int)x; + memcpy(p, (char *)&y, sizeof y); return 0; } @@ -684,7 +711,7 @@ long x; if (get_long(v, &x) < 0) return -1; - * (long *)p = x; + memcpy(p, (char *)&x, sizeof x); return 0; } @@ -694,7 +721,7 @@ unsigned long x; if (get_ulong(v, &x) < 0) return -1; - * (unsigned long *)p = x; + memcpy(p, (char *)&x, sizeof x); return 0; } @@ -706,7 +733,7 @@ LONG_LONG x; if (get_longlong(v, &x) < 0) return -1; - memcpy(p, &x, sizeof(LONG_LONG)); + memcpy(p, (char *)&x, sizeof x); return 0; } @@ -716,7 +743,7 @@ unsigned LONG_LONG x; if (get_ulonglong(v, &x) < 0) return -1; - memcpy(p, &x, sizeof(unsigned LONG_LONG)); + memcpy(p, (char *)&x, sizeof x); return 0; } #endif @@ -730,7 +757,7 @@ "required argument is not a float"); return -1; } - memcpy(p, (char *)&x, sizeof(float)); + memcpy(p, (char *)&x, sizeof x); return 0; } @@ -758,7 +785,7 @@ "required argument is not an integer"); return -1; } - *(void **)p = x; + memcpy(p, (char *)&x, sizeof x); return 0; } @@ -1218,7 +1245,7 @@ size += x; if (x/itemsize != num || size < 0) { PyErr_SetString(StructError, - "total struct size too long"); + "total struct size too long"); return -1; } } @@ -1267,7 +1294,7 @@ if (args == NULL || !PyTuple_Check(args) || (n = PyTuple_Size(args)) < 1) - { + { PyErr_SetString(PyExc_TypeError, "struct.pack requires at least one argument"); return NULL;
