diff options
Diffstat (limited to 'numpy/core/src/arrayconvert.c')
-rw-r--r-- | numpy/core/src/arrayconvert.c | 346 |
1 files changed, 346 insertions, 0 deletions
diff --git a/numpy/core/src/arrayconvert.c b/numpy/core/src/arrayconvert.c new file mode 100644 index 000000000..17cb9aad0 --- /dev/null +++ b/numpy/core/src/arrayconvert.c @@ -0,0 +1,346 @@ +#define PY_SSIZE_T_CLEAN +#include <Python.h> +#include "structmember.h" + +#define _MULTIARRAYMODULE +#define NPY_NO_PREFIX +#include "numpy/arrayobject.h" +#include "numpy/arrayscalars.h" + +#include "arrayobject.h" + +#include "arrayconvert.h" + +/*NUMPY_API + * To List + */ +NPY_NO_EXPORT PyObject * +PyArray_ToList(PyArrayObject *self) +{ + PyObject *lp; + PyArrayObject *v; + intp sz, i; + + if (!PyArray_Check(self)) { + return (PyObject *)self; + } + if (self->nd == 0) { + return self->descr->f->getitem(self->data,self); + } + + sz = self->dimensions[0]; + lp = PyList_New(sz); + for (i = 0; i < sz; i++) { + v = (PyArrayObject *)array_big_item(self, i); + if (PyArray_Check(v) && (v->nd >= self->nd)) { + PyErr_SetString(PyExc_RuntimeError, + "array_item not returning smaller-" \ + "dimensional array"); + Py_DECREF(v); + Py_DECREF(lp); + return NULL; + } + PyList_SetItem(lp, i, PyArray_ToList(v)); + Py_DECREF(v); + } + return lp; +} + +/* XXX: FIXME --- add ordering argument to + Allow Fortran ordering on write + This will need the addition of a Fortran-order iterator. + */ + +/*NUMPY_API + To File +*/ +NPY_NO_EXPORT int +PyArray_ToFile(PyArrayObject *self, FILE *fp, char *sep, char *format) +{ + intp size; + intp n, n2; + size_t n3, n4; + PyArrayIterObject *it; + PyObject *obj, *strobj, *tupobj; + + n3 = (sep ? strlen((const char *)sep) : 0); + if (n3 == 0) { + /* binary data */ + if (PyDataType_FLAGCHK(self->descr, NPY_LIST_PICKLE)) { + PyErr_SetString(PyExc_ValueError, "cannot write " \ + "object arrays to a file in " \ + "binary mode"); + return -1; + } + + if (PyArray_ISCONTIGUOUS(self)) { + size = PyArray_SIZE(self); + NPY_BEGIN_ALLOW_THREADS; + n = fwrite((const void *)self->data, + (size_t) self->descr->elsize, + (size_t) size, fp); + NPY_END_ALLOW_THREADS; + if (n < size) { + PyErr_Format(PyExc_ValueError, + "%ld requested and %ld written", + (long) size, (long) n); + return -1; + } + } + else { + NPY_BEGIN_THREADS_DEF; + + it = (PyArrayIterObject *) PyArray_IterNew((PyObject *)self); + NPY_BEGIN_THREADS; + while (it->index < it->size) { + if (fwrite((const void *)it->dataptr, + (size_t) self->descr->elsize, + 1, fp) < 1) { + NPY_END_THREADS; + PyErr_Format(PyExc_IOError, + "problem writing element"\ + " %"INTP_FMT" to file", + it->index); + Py_DECREF(it); + return -1; + } + PyArray_ITER_NEXT(it); + } + NPY_END_THREADS; + Py_DECREF(it); + } + } + else { + /* + * text data + */ + + it = (PyArrayIterObject *) + PyArray_IterNew((PyObject *)self); + n4 = (format ? strlen((const char *)format) : 0); + while (it->index < it->size) { + obj = self->descr->f->getitem(it->dataptr, self); + if (obj == NULL) { + Py_DECREF(it); + return -1; + } + if (n4 == 0) { + /* + * standard writing + */ + strobj = PyObject_Str(obj); + Py_DECREF(obj); + if (strobj == NULL) { + Py_DECREF(it); + return -1; + } + } + else { + /* + * use format string + */ + tupobj = PyTuple_New(1); + if (tupobj == NULL) { + Py_DECREF(it); + return -1; + } + PyTuple_SET_ITEM(tupobj,0,obj); + obj = PyString_FromString((const char *)format); + if (obj == NULL) { + Py_DECREF(tupobj); + Py_DECREF(it); + return -1; + } + strobj = PyString_Format(obj, tupobj); + Py_DECREF(obj); + Py_DECREF(tupobj); + if (strobj == NULL) { + Py_DECREF(it); + return -1; + } + } + NPY_BEGIN_ALLOW_THREADS; + n2 = PyString_GET_SIZE(strobj); + n = fwrite(PyString_AS_STRING(strobj), 1, n2, fp); + NPY_END_ALLOW_THREADS; + if (n < n2) { + PyErr_Format(PyExc_IOError, + "problem writing element %"INTP_FMT\ + " to file", it->index); + Py_DECREF(strobj); + Py_DECREF(it); + return -1; + } + /* write separator for all but last one */ + if (it->index != it->size-1) { + if (fwrite(sep, 1, n3, fp) < n3) { + PyErr_Format(PyExc_IOError, + "problem writing "\ + "separator to file"); + Py_DECREF(strobj); + Py_DECREF(it); + return -1; + } + } + Py_DECREF(strobj); + PyArray_ITER_NEXT(it); + } + Py_DECREF(it); + } + return 0; +} + +/*NUMPY_API*/ +NPY_NO_EXPORT PyObject * +PyArray_ToString(PyArrayObject *self, NPY_ORDER order) +{ + intp numbytes; + intp index; + char *dptr; + int elsize; + PyObject *ret; + PyArrayIterObject *it; + + if (order == NPY_ANYORDER) + order = PyArray_ISFORTRAN(self); + + /* if (PyArray_TYPE(self) == PyArray_OBJECT) { + PyErr_SetString(PyExc_ValueError, "a string for the data" \ + "in an object array is not appropriate"); + return NULL; + } + */ + + numbytes = PyArray_NBYTES(self); + if ((PyArray_ISCONTIGUOUS(self) && (order == NPY_CORDER)) + || (PyArray_ISFORTRAN(self) && (order == NPY_FORTRANORDER))) { + ret = PyString_FromStringAndSize(self->data, (Py_ssize_t) numbytes); + } + else { + PyObject *new; + if (order == NPY_FORTRANORDER) { + /* iterators are always in C-order */ + new = PyArray_Transpose(self, NULL); + if (new == NULL) { + return NULL; + } + } + else { + Py_INCREF(self); + new = (PyObject *)self; + } + it = (PyArrayIterObject *)PyArray_IterNew(new); + Py_DECREF(new); + if (it == NULL) { + return NULL; + } + ret = PyString_FromStringAndSize(NULL, (Py_ssize_t) numbytes); + if (ret == NULL) { + Py_DECREF(it); + return NULL; + } + dptr = PyString_AS_STRING(ret); + index = it->size; + elsize = self->descr->elsize; + while (index--) { + memcpy(dptr, it->dataptr, elsize); + dptr += elsize; + PyArray_ITER_NEXT(it); + } + Py_DECREF(it); + } + return ret; +} + +/*NUMPY_API*/ +NPY_NO_EXPORT int +PyArray_FillWithScalar(PyArrayObject *arr, PyObject *obj) +{ + PyObject *newarr; + int itemsize, swap; + void *fromptr; + PyArray_Descr *descr; + intp size; + PyArray_CopySwapFunc *copyswap; + + itemsize = arr->descr->elsize; + if (PyArray_ISOBJECT(arr)) { + fromptr = &obj; + swap = 0; + newarr = NULL; + } + else { + descr = PyArray_DESCR(arr); + Py_INCREF(descr); + newarr = PyArray_FromAny(obj, descr, 0,0, ALIGNED, NULL); + if (newarr == NULL) { + return -1; + } + fromptr = PyArray_DATA(newarr); + swap = (PyArray_ISNOTSWAPPED(arr) != PyArray_ISNOTSWAPPED(newarr)); + } + size=PyArray_SIZE(arr); + copyswap = arr->descr->f->copyswap; + if (PyArray_ISONESEGMENT(arr)) { + char *toptr=PyArray_DATA(arr); + PyArray_FillWithScalarFunc* fillwithscalar = + arr->descr->f->fillwithscalar; + if (fillwithscalar && PyArray_ISALIGNED(arr)) { + copyswap(fromptr, NULL, swap, newarr); + fillwithscalar(toptr, size, fromptr, arr); + } + else { + while (size--) { + copyswap(toptr, fromptr, swap, arr); + toptr += itemsize; + } + } + } + else { + PyArrayIterObject *iter; + + iter = (PyArrayIterObject *)\ + PyArray_IterNew((PyObject *)arr); + if (iter == NULL) { + Py_XDECREF(newarr); + return -1; + } + while (size--) { + copyswap(iter->dataptr, fromptr, swap, arr); + PyArray_ITER_NEXT(iter); + } + Py_DECREF(iter); + } + Py_XDECREF(newarr); + return 0; +} + +/*NUMPY_API + Copy an array. +*/ +NPY_NO_EXPORT PyObject * +PyArray_NewCopy(PyArrayObject *m1, NPY_ORDER fortran) +{ + PyArrayObject *ret; + if (fortran == PyArray_ANYORDER) + fortran = PyArray_ISFORTRAN(m1); + + Py_INCREF(m1->descr); + ret = (PyArrayObject *)PyArray_NewFromDescr(m1->ob_type, + m1->descr, + m1->nd, + m1->dimensions, + NULL, NULL, + fortran, + (PyObject *)m1); + if (ret == NULL) { + return NULL; + } + if (PyArray_CopyInto(ret, m1) == -1) { + Py_DECREF(ret); + return NULL; + } + + return (PyObject *)ret; +} + |