summaryrefslogtreecommitdiff
path: root/numpy/core/src
diff options
context:
space:
mode:
authorTravis Oliphant <oliphant@enthought.com>2006-02-11 10:31:32 +0000
committerTravis Oliphant <oliphant@enthought.com>2006-02-11 10:31:32 +0000
commit8ee6df7668b3ae0568573620153e71e36c9c399a (patch)
treeaf89f3e25fda05fff5de0dfdb98f31ae94f9957e /numpy/core/src
parent6fc0e44e5daab7dcaae4a3250b7545a263d6bfcb (diff)
downloadnumpy-8ee6df7668b3ae0568573620153e71e36c9c399a.tar.gz
Fixed UNICODE functions to handle misaligned and/or byte-swapped arrays.
Diffstat (limited to 'numpy/core/src')
-rw-r--r--numpy/core/src/arrayobject.c23
-rw-r--r--numpy/core/src/arraytypes.inc.src41
2 files changed, 52 insertions, 12 deletions
diff --git a/numpy/core/src/arrayobject.c b/numpy/core/src/arrayobject.c
index 76be69702..3e996d338 100644
--- a/numpy/core/src/arrayobject.c
+++ b/numpy/core/src/arrayobject.c
@@ -868,8 +868,9 @@ PyArray_Scalar(void *data, PyArray_Descr *descr, PyObject *base)
else if (type_num == PyArray_UNICODE) {
PyUnicodeObject *uni = (PyUnicodeObject*)obj;
int length = itemsize >> 2;
-
#ifndef Py_UNICODE_WIDE
+ char *buffer;
+ int alloc=1;
length *= 2;
#endif
/* Need an extra slot and need to use
@@ -887,15 +888,25 @@ PyArray_Scalar(void *data, PyArray_Descr *descr, PyObject *base)
uni->hash = -1;
uni->defenc = NULL;
#ifndef Py_UNICODE_WIDE
+ /* need aligned data buffer */
+ if (!PyArray_ISBEHAVED(base)) {
+ buffer = _pya_malloc(itemsize);
+ if (buffer == NULL)
+ return PyErr_NoMemory();
+ alloc = 1;
+ memcpy(buffer, data, itemsize);
+ if (!PyArray_ISNOTSWAPPED(base)) {
+ byte_swap_vector(buffer, itemsize >> 2, 4);
+ }
+ }
+ else buffer = data;
+
/* Allocated enough for 2-characters per itemsize.
Now convert from the data-buffer
*/
- if (!PyArray_ISNBO(descr->byteorder)) {
- /* byteswap the data */
- byte_swap_vector(data, itemsize >> 2, 4);
- }
- length = PyUCS2Buffer_FromUCS4(uni->str, (PyArray_UCS4 *)data,
+ length = PyUCS2Buffer_FromUCS4(uni->str, (PyArray_UCS4 *)buffer,
itemsize >> 2);
+ if (alloc) _pya_free(buffer);
/* Resize the unicode result */
if (MyPyUnicode_Resize(uni, length) < 0) {
Py_DECREF(obj);
diff --git a/numpy/core/src/arraytypes.inc.src b/numpy/core/src/arraytypes.inc.src
index e3acfcd73..30c254f65 100644
--- a/numpy/core/src/arraytypes.inc.src
+++ b/numpy/core/src/arraytypes.inc.src
@@ -220,28 +220,40 @@ UNICODE_getitem(char *ip, PyArrayObject *ap)
PyObject *obj;
int mysize;
PyArray_UCS4 *dptr;
+ char *buffer;
+ int alloc=0;
mysize = ap->descr->elsize >> 2;
dptr = (PyArray_UCS4 *)ip + mysize-1;
while(mysize > 0 && *dptr-- == 0) mysize--;
- if (!PyArray_ISNOTSWAPPED(ap) && (obj != NULL)) {
- byte_swap_vector(PyArray_BYTES(ap), mysize, 4);
+ if (!PyArray_ISBEHAVED(ap)) {
+ buffer = _pya_malloc(mysize << 2);
+ if (buffer == NULL)
+ return PyErr_NoMemory();
+ alloc = 1;
+ memcpy(buffer, ip, mysize << 2);
+ if (!PyArray_ISNOTSWAPPED(ap)) {
+ byte_swap_vector(buffer, mysize, 4);
+ }
}
+ else buffer = ip;
#ifdef Py_UNICODE_WIDE
- obj = PyUnicode_FromUnicode((const PyArray_UCS4 *)ip, mysize);
+ obj = PyUnicode_FromUnicode((const PyArray_UCS4 *)buffer, mysize);
#else
/* create new empty unicode object of length mysize*2 */
obj = MyPyUnicode_New(mysize*2);
if (obj == NULL) return obj;
mysize = PyUCS2Buffer_FromUCS4(((PyUnicodeObject *)obj)->str,
- (PyArray_UCS4 *)ip, mysize);
+ (PyArray_UCS4 *)buffer, mysize);
/* reset length of unicode object to ucs2size */
if (MyPyUnicode_Resize((PyUnicodeObject *)obj, mysize) < 0) {
+ if (alloc) _pya_free(buffer);
Py_DECREF(obj);
return NULL;
}
#endif
-
+ if (alloc) _pya_free(buffer);
+
return obj;
}
@@ -251,6 +263,9 @@ UNICODE_setitem(PyObject *op, char *ov, PyArrayObject *ap)
PyObject *temp;
Py_UNICODE *ptr;
int datalen;
+#ifndef Py_UNICODE_WIDE
+ char *buffer;
+#endif
if ((temp=PyObject_Unicode(op)) == NULL) return -1;
ptr = PyUnicode_AS_UNICODE(temp);
@@ -263,9 +278,23 @@ UNICODE_setitem(PyObject *op, char *ov, PyArrayObject *ap)
#ifdef Py_UNICODE_WIDE
memcpy(ov, ptr, MIN(ap->descr->elsize, datalen));
#else
- datalen = PyUCS2Buffer_AsUCS4(ptr, (PyArray_UCS4 *)ov, datalen >> 1,
+ if (!PyArray_ISALIGNED(ap)) {
+ buffer = _pya_malloc(ap->descr->elsize);
+ if (buffer == NULL) {
+ Py_DECREF(temp);
+ PyErr_NoMemory();
+ return -1;
+ }
+ }
+ else buffer = ov;
+ datalen = PyUCS2Buffer_AsUCS4(ptr, (PyArray_UCS4 *)buffer,
+ datalen >> 1,
ap->descr->elsize >> 2);
datalen <<= 2;
+ if (!PyArray_ISALIGNED(ap)) {
+ memcpy(ov, buffer, datalen);
+ _pya_free(buffer);
+ }
#endif
/* Fill in the rest of the space with 0 */
if (ap->descr->elsize > datalen) {