~jtaylor/ubuntu/precise/python-numpy/multiarch-fix-818867

« back to all changes in this revision

Viewing changes to numpy/core/src/multiarray/convert_datatype.c

  • Committer: Bazaar Package Importer
  • Author(s): Sandro Tosi
  • Date: 2010-10-07 10:19:13 UTC
  • mfrom: (7.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20101007101913-8b1kmt8ho4upcl9s
Tags: 1:1.4.1-5
* debian/patches/10_use_local_python.org_object.inv_sphinx.diff
  - fixed small typo in description
* debian/patches/changeset_r8364.diff
  - fix memory corruption (double free); thanks to Joseph Barillari for the
    report and to Michael Gilbert for pushing resolution; Closes: #581058

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#define PY_SSIZE_T_CLEAN
 
2
#include <Python.h>
 
3
#include "structmember.h"
 
4
 
 
5
#define _MULTIARRAYMODULE
 
6
#define NPY_NO_PREFIX
 
7
#include "numpy/arrayobject.h"
 
8
#include "numpy/arrayscalars.h"
 
9
 
 
10
#include "npy_config.h"
 
11
 
 
12
#include "common.h"
 
13
#include "scalartypes.h"
 
14
#include "mapping.h"
 
15
 
 
16
#include "convert_datatype.h"
 
17
 
 
18
/*NUMPY_API
 
19
 * For backward compatibility
 
20
 *
 
21
 * Cast an array using typecode structure.
 
22
 * steals reference to at --- cannot be NULL
 
23
 */
 
24
NPY_NO_EXPORT PyObject *
 
25
PyArray_CastToType(PyArrayObject *mp, PyArray_Descr *at, int fortran)
 
26
{
 
27
    PyObject *out;
 
28
    int ret;
 
29
    PyArray_Descr *mpd;
 
30
 
 
31
    mpd = mp->descr;
 
32
 
 
33
    if (((mpd == at) ||
 
34
                ((mpd->type_num == at->type_num) &&
 
35
                 PyArray_EquivByteorders(mpd->byteorder, at->byteorder) &&
 
36
                 ((mpd->elsize == at->elsize) || (at->elsize==0)))) &&
 
37
                 PyArray_ISBEHAVED_RO(mp)) {
 
38
        Py_DECREF(at);
 
39
        Py_INCREF(mp);
 
40
        return (PyObject *)mp;
 
41
    }
 
42
 
 
43
    if (at->elsize == 0) {
 
44
        PyArray_DESCR_REPLACE(at);
 
45
        if (at == NULL) {
 
46
            return NULL;
 
47
        }
 
48
        if (mpd->type_num == PyArray_STRING &&
 
49
            at->type_num == PyArray_UNICODE) {
 
50
            at->elsize = mpd->elsize << 2;
 
51
        }
 
52
        if (mpd->type_num == PyArray_UNICODE &&
 
53
            at->type_num == PyArray_STRING) {
 
54
            at->elsize = mpd->elsize >> 2;
 
55
        }
 
56
        if (at->type_num == PyArray_VOID) {
 
57
            at->elsize = mpd->elsize;
 
58
        }
 
59
    }
 
60
 
 
61
    out = PyArray_NewFromDescr(mp->ob_type, at,
 
62
                               mp->nd,
 
63
                               mp->dimensions,
 
64
                               NULL, NULL,
 
65
                               fortran,
 
66
                               (PyObject *)mp);
 
67
 
 
68
    if (out == NULL) {
 
69
        return NULL;
 
70
    }
 
71
    ret = PyArray_CastTo((PyArrayObject *)out, mp);
 
72
    if (ret != -1) {
 
73
        return out;
 
74
    }
 
75
 
 
76
    Py_DECREF(out);
 
77
    return NULL;
 
78
 
 
79
}
 
80
 
 
81
/*NUMPY_API
 
82
 * Get a cast function to cast from the input descriptor to the
 
83
 * output type_number (must be a registered data-type).
 
84
 * Returns NULL if un-successful.
 
85
 */
 
86
NPY_NO_EXPORT PyArray_VectorUnaryFunc *
 
87
PyArray_GetCastFunc(PyArray_Descr *descr, int type_num)
 
88
{
 
89
    PyArray_VectorUnaryFunc *castfunc = NULL;
 
90
 
 
91
    if (type_num < PyArray_NTYPES) {
 
92
        castfunc = descr->f->cast[type_num];
 
93
    }
 
94
    if (castfunc == NULL) {
 
95
        PyObject *obj = descr->f->castdict;
 
96
        if (obj && PyDict_Check(obj)) {
 
97
            PyObject *key;
 
98
            PyObject *cobj;
 
99
 
 
100
            key = PyInt_FromLong(type_num);
 
101
            cobj = PyDict_GetItem(obj, key);
 
102
            Py_DECREF(key);
 
103
            if (PyCObject_Check(cobj)) {
 
104
                castfunc = PyCObject_AsVoidPtr(cobj);
 
105
            }
 
106
        }
 
107
        if (castfunc) {
 
108
            return castfunc;
 
109
        }
 
110
    }
 
111
    else {
 
112
        return castfunc;
 
113
    }
 
114
 
 
115
    PyErr_SetString(PyExc_ValueError, "No cast function available.");
 
116
    return NULL;
 
117
}
 
118
 
 
119
/*
 
120
 * Reference counts:
 
121
 * copyswapn is used which increases and decreases reference counts for OBJECT arrays.
 
122
 * All that needs to happen is for any reference counts in the buffers to be
 
123
 * decreased when completely finished with the buffers.
 
124
 *
 
125
 * buffers[0] is the destination
 
126
 * buffers[1] is the source
 
127
 */
 
128
static void
 
129
_strided_buffered_cast(char *dptr, intp dstride, int delsize, int dswap,
 
130
                       PyArray_CopySwapNFunc *dcopyfunc,
 
131
                       char *sptr, intp sstride, int selsize, int sswap,
 
132
                       PyArray_CopySwapNFunc *scopyfunc,
 
133
                       intp N, char **buffers, int bufsize,
 
134
                       PyArray_VectorUnaryFunc *castfunc,
 
135
                       PyArrayObject *dest, PyArrayObject *src)
 
136
{
 
137
    int i;
 
138
    if (N <= bufsize) {
 
139
        /*
 
140
         * 1. copy input to buffer and swap
 
141
         * 2. cast input to output
 
142
         * 3. swap output if necessary and copy from output buffer
 
143
         */
 
144
        scopyfunc(buffers[1], selsize, sptr, sstride, N, sswap, src);
 
145
        castfunc(buffers[1], buffers[0], N, src, dest);
 
146
        dcopyfunc(dptr, dstride, buffers[0], delsize, N, dswap, dest);
 
147
        return;
 
148
    }
 
149
 
 
150
    /* otherwise we need to divide up into bufsize pieces */
 
151
    i = 0;
 
152
    while (N > 0) {
 
153
        int newN = MIN(N, bufsize);
 
154
 
 
155
        _strided_buffered_cast(dptr+i*dstride, dstride, delsize,
 
156
                               dswap, dcopyfunc,
 
157
                               sptr+i*sstride, sstride, selsize,
 
158
                               sswap, scopyfunc,
 
159
                               newN, buffers, bufsize, castfunc, dest, src);
 
160
        i += newN;
 
161
        N -= bufsize;
 
162
    }
 
163
    return;
 
164
}
 
165
 
 
166
static int
 
167
_broadcast_cast(PyArrayObject *out, PyArrayObject *in,
 
168
                PyArray_VectorUnaryFunc *castfunc, int iswap, int oswap)
 
169
{
 
170
    int delsize, selsize, maxaxis, i, N;
 
171
    PyArrayMultiIterObject *multi;
 
172
    intp maxdim, ostrides, istrides;
 
173
    char *buffers[2];
 
174
    PyArray_CopySwapNFunc *ocopyfunc, *icopyfunc;
 
175
    char *obptr;
 
176
    NPY_BEGIN_THREADS_DEF;
 
177
 
 
178
    delsize = PyArray_ITEMSIZE(out);
 
179
    selsize = PyArray_ITEMSIZE(in);
 
180
    multi = (PyArrayMultiIterObject *)PyArray_MultiIterNew(2, out, in);
 
181
    if (multi == NULL) {
 
182
        return -1;
 
183
    }
 
184
 
 
185
    if (multi->size != PyArray_SIZE(out)) {
 
186
        PyErr_SetString(PyExc_ValueError,
 
187
                "array dimensions are not "\
 
188
                "compatible for copy");
 
189
        Py_DECREF(multi);
 
190
        return -1;
 
191
    }
 
192
 
 
193
    icopyfunc = in->descr->f->copyswapn;
 
194
    ocopyfunc = out->descr->f->copyswapn;
 
195
    maxaxis = PyArray_RemoveSmallest(multi);
 
196
    if (maxaxis < 0) {
 
197
        /* cast 1 0-d array to another */
 
198
        N = 1;
 
199
        maxdim = 1;
 
200
        ostrides = delsize;
 
201
        istrides = selsize;
 
202
    }
 
203
    else {
 
204
        maxdim = multi->dimensions[maxaxis];
 
205
        N = (int) (MIN(maxdim, PyArray_BUFSIZE));
 
206
        ostrides = multi->iters[0]->strides[maxaxis];
 
207
        istrides = multi->iters[1]->strides[maxaxis];
 
208
 
 
209
    }
 
210
    buffers[0] = _pya_malloc(N*delsize);
 
211
    if (buffers[0] == NULL) {
 
212
        PyErr_NoMemory();
 
213
        return -1;
 
214
    }
 
215
    buffers[1] = _pya_malloc(N*selsize);
 
216
    if (buffers[1] == NULL) {
 
217
        _pya_free(buffers[0]);
 
218
        PyErr_NoMemory();
 
219
        return -1;
 
220
    }
 
221
    if (PyDataType_FLAGCHK(out->descr, NPY_NEEDS_INIT)) {
 
222
        memset(buffers[0], 0, N*delsize);
 
223
    }
 
224
    if (PyDataType_FLAGCHK(in->descr, NPY_NEEDS_INIT)) {
 
225
        memset(buffers[1], 0, N*selsize);
 
226
    }
 
227
 
 
228
#if NPY_ALLOW_THREADS
 
229
    if (PyArray_ISNUMBER(in) && PyArray_ISNUMBER(out)) {
 
230
        NPY_BEGIN_THREADS;
 
231
    }
 
232
#endif
 
233
 
 
234
    while (multi->index < multi->size) {
 
235
        _strided_buffered_cast(multi->iters[0]->dataptr,
 
236
                ostrides,
 
237
                delsize, oswap, ocopyfunc,
 
238
                multi->iters[1]->dataptr,
 
239
                istrides,
 
240
                selsize, iswap, icopyfunc,
 
241
                maxdim, buffers, N,
 
242
                castfunc, out, in);
 
243
        PyArray_MultiIter_NEXT(multi);
 
244
    }
 
245
#if NPY_ALLOW_THREADS
 
246
    if (PyArray_ISNUMBER(in) && PyArray_ISNUMBER(out)) {
 
247
        NPY_END_THREADS;
 
248
    }
 
249
#endif
 
250
    Py_DECREF(multi);
 
251
    if (PyDataType_REFCHK(in->descr)) {
 
252
        obptr = buffers[1];
 
253
        for (i = 0; i < N; i++, obptr+=selsize) {
 
254
            PyArray_Item_XDECREF(obptr, out->descr);
 
255
        }
 
256
    }
 
257
    if (PyDataType_REFCHK(out->descr)) {
 
258
        obptr = buffers[0];
 
259
        for (i = 0; i < N; i++, obptr+=delsize) {
 
260
            PyArray_Item_XDECREF(obptr, out->descr);
 
261
        }
 
262
    }
 
263
    _pya_free(buffers[0]);
 
264
    _pya_free(buffers[1]);
 
265
    if (PyErr_Occurred()) {
 
266
        return -1;
 
267
    }
 
268
 
 
269
    return 0;
 
270
}
 
271
 
 
272
 
 
273
 
 
274
/*
 
275
 * Must be broadcastable.
 
276
 * This code is very similar to PyArray_CopyInto/PyArray_MoveInto
 
277
 * except casting is done --- PyArray_BUFSIZE is used
 
278
 * as the size of the casting buffer.
 
279
 */
 
280
 
 
281
/*NUMPY_API
 
282
 * Cast to an already created array.
 
283
 */
 
284
NPY_NO_EXPORT int
 
285
PyArray_CastTo(PyArrayObject *out, PyArrayObject *mp)
 
286
{
 
287
    int simple;
 
288
    int same;
 
289
    PyArray_VectorUnaryFunc *castfunc = NULL;
 
290
    intp mpsize = PyArray_SIZE(mp);
 
291
    int iswap, oswap;
 
292
    NPY_BEGIN_THREADS_DEF;
 
293
 
 
294
    if (mpsize == 0) {
 
295
        return 0;
 
296
    }
 
297
    if (!PyArray_ISWRITEABLE(out)) {
 
298
        PyErr_SetString(PyExc_ValueError, "output array is not writeable");
 
299
        return -1;
 
300
    }
 
301
 
 
302
    castfunc = PyArray_GetCastFunc(mp->descr, out->descr->type_num);
 
303
    if (castfunc == NULL) {
 
304
        return -1;
 
305
    }
 
306
 
 
307
    same = PyArray_SAMESHAPE(out, mp);
 
308
    simple = same && ((PyArray_ISCARRAY_RO(mp) && PyArray_ISCARRAY(out)) ||
 
309
            (PyArray_ISFARRAY_RO(mp) && PyArray_ISFARRAY(out)));
 
310
    if (simple) {
 
311
#if NPY_ALLOW_THREADS
 
312
        if (PyArray_ISNUMBER(mp) && PyArray_ISNUMBER(out)) {
 
313
            NPY_BEGIN_THREADS;
 
314
        }
 
315
#endif
 
316
        castfunc(mp->data, out->data, mpsize, mp, out);
 
317
 
 
318
#if NPY_ALLOW_THREADS
 
319
        if (PyArray_ISNUMBER(mp) && PyArray_ISNUMBER(out)) {
 
320
            NPY_END_THREADS;
 
321
        }
 
322
#endif
 
323
        if (PyErr_Occurred()) {
 
324
            return -1;
 
325
        }
 
326
        return 0;
 
327
    }
 
328
 
 
329
    /*
 
330
     * If the input or output is OBJECT, STRING, UNICODE, or VOID
 
331
     *  then getitem and setitem are used for the cast
 
332
     *  and byteswapping is handled by those methods
 
333
     */
 
334
    if (PyArray_ISFLEXIBLE(mp) || PyArray_ISOBJECT(mp) || PyArray_ISOBJECT(out) ||
 
335
            PyArray_ISFLEXIBLE(out)) {
 
336
        iswap = oswap = 0;
 
337
    }
 
338
    else {
 
339
        iswap = PyArray_ISBYTESWAPPED(mp);
 
340
        oswap = PyArray_ISBYTESWAPPED(out);
 
341
    }
 
342
 
 
343
    return _broadcast_cast(out, mp, castfunc, iswap, oswap);
 
344
}
 
345
 
 
346
 
 
347
static int
 
348
_bufferedcast(PyArrayObject *out, PyArrayObject *in,
 
349
              PyArray_VectorUnaryFunc *castfunc)
 
350
{
 
351
    char *inbuffer, *bptr, *optr;
 
352
    char *outbuffer=NULL;
 
353
    PyArrayIterObject *it_in = NULL, *it_out = NULL;
 
354
    intp i, index;
 
355
    intp ncopies = PyArray_SIZE(out) / PyArray_SIZE(in);
 
356
    int elsize=in->descr->elsize;
 
357
    int nels = PyArray_BUFSIZE;
 
358
    int el;
 
359
    int inswap, outswap = 0;
 
360
    int obuf=!PyArray_ISCARRAY(out);
 
361
    int oelsize = out->descr->elsize;
 
362
    PyArray_CopySwapFunc *in_csn;
 
363
    PyArray_CopySwapFunc *out_csn;
 
364
    int retval = -1;
 
365
 
 
366
    in_csn = in->descr->f->copyswap;
 
367
    out_csn = out->descr->f->copyswap;
 
368
 
 
369
    /*
 
370
     * If the input or output is STRING, UNICODE, or VOID
 
371
     * then getitem and setitem are used for the cast
 
372
     *  and byteswapping is handled by those methods
 
373
     */
 
374
 
 
375
    inswap = !(PyArray_ISFLEXIBLE(in) || PyArray_ISNOTSWAPPED(in));
 
376
 
 
377
    inbuffer = PyDataMem_NEW(PyArray_BUFSIZE*elsize);
 
378
    if (inbuffer == NULL) {
 
379
        return -1;
 
380
    }
 
381
    if (PyArray_ISOBJECT(in)) {
 
382
        memset(inbuffer, 0, PyArray_BUFSIZE*elsize);
 
383
    }
 
384
    it_in = (PyArrayIterObject *)PyArray_IterNew((PyObject *)in);
 
385
    if (it_in == NULL) {
 
386
        goto exit;
 
387
    }
 
388
    if (obuf) {
 
389
        outswap = !(PyArray_ISFLEXIBLE(out) ||
 
390
                    PyArray_ISNOTSWAPPED(out));
 
391
        outbuffer = PyDataMem_NEW(PyArray_BUFSIZE*oelsize);
 
392
        if (outbuffer == NULL) {
 
393
            goto exit;
 
394
        }
 
395
        if (PyArray_ISOBJECT(out)) {
 
396
            memset(outbuffer, 0, PyArray_BUFSIZE*oelsize);
 
397
        }
 
398
        it_out = (PyArrayIterObject *)PyArray_IterNew((PyObject *)out);
 
399
        if (it_out == NULL) {
 
400
            goto exit;
 
401
        }
 
402
        nels = MIN(nels, PyArray_BUFSIZE);
 
403
    }
 
404
 
 
405
    optr = (obuf) ? outbuffer: out->data;
 
406
    bptr = inbuffer;
 
407
    el = 0;
 
408
    while (ncopies--) {
 
409
        index = it_in->size;
 
410
        PyArray_ITER_RESET(it_in);
 
411
        while (index--) {
 
412
            in_csn(bptr, it_in->dataptr, inswap, in);
 
413
            bptr += elsize;
 
414
            PyArray_ITER_NEXT(it_in);
 
415
            el += 1;
 
416
            if ((el == nels) || (index == 0)) {
 
417
                /* buffer filled, do cast */
 
418
                castfunc(inbuffer, optr, el, in, out);
 
419
                if (obuf) {
 
420
                    /* Copy from outbuffer to array */
 
421
                    for (i = 0; i < el; i++) {
 
422
                        out_csn(it_out->dataptr,
 
423
                                optr, outswap,
 
424
                                out);
 
425
                        optr += oelsize;
 
426
                        PyArray_ITER_NEXT(it_out);
 
427
                    }
 
428
                    optr = outbuffer;
 
429
                }
 
430
                else {
 
431
                    optr += out->descr->elsize * nels;
 
432
                }
 
433
                el = 0;
 
434
                bptr = inbuffer;
 
435
            }
 
436
        }
 
437
    }
 
438
    retval = 0;
 
439
 
 
440
 exit:
 
441
    Py_XDECREF(it_in);
 
442
    PyDataMem_FREE(inbuffer);
 
443
    PyDataMem_FREE(outbuffer);
 
444
    if (obuf) {
 
445
        Py_XDECREF(it_out);
 
446
    }
 
447
    return retval;
 
448
}
 
449
 
 
450
/*NUMPY_API
 
451
 * Cast to an already created array.  Arrays don't have to be "broadcastable"
 
452
 * Only requirement is they have the same number of elements.
 
453
 */
 
454
NPY_NO_EXPORT int
 
455
PyArray_CastAnyTo(PyArrayObject *out, PyArrayObject *mp)
 
456
{
 
457
    int simple;
 
458
    PyArray_VectorUnaryFunc *castfunc = NULL;
 
459
    npy_intp mpsize = PyArray_SIZE(mp);
 
460
 
 
461
    if (mpsize == 0) {
 
462
        return 0;
 
463
    }
 
464
    if (!PyArray_ISWRITEABLE(out)) {
 
465
        PyErr_SetString(PyExc_ValueError, "output array is not writeable");
 
466
        return -1;
 
467
    }
 
468
 
 
469
    if (!(mpsize == PyArray_SIZE(out))) {
 
470
        PyErr_SetString(PyExc_ValueError,
 
471
                        "arrays must have the same number of"
 
472
                        " elements for the cast.");
 
473
        return -1;
 
474
    }
 
475
 
 
476
    castfunc = PyArray_GetCastFunc(mp->descr, out->descr->type_num);
 
477
    if (castfunc == NULL) {
 
478
        return -1;
 
479
    }
 
480
    simple = ((PyArray_ISCARRAY_RO(mp) && PyArray_ISCARRAY(out)) ||
 
481
              (PyArray_ISFARRAY_RO(mp) && PyArray_ISFARRAY(out)));
 
482
    if (simple) {
 
483
        castfunc(mp->data, out->data, mpsize, mp, out);
 
484
        return 0;
 
485
    }
 
486
    if (PyArray_SAMESHAPE(out, mp)) {
 
487
        int iswap, oswap;
 
488
        iswap = PyArray_ISBYTESWAPPED(mp) && !PyArray_ISFLEXIBLE(mp);
 
489
        oswap = PyArray_ISBYTESWAPPED(out) && !PyArray_ISFLEXIBLE(out);
 
490
        return _broadcast_cast(out, mp, castfunc, iswap, oswap);
 
491
    }
 
492
    return _bufferedcast(out, mp, castfunc);
 
493
}
 
494
 
 
495
/*NUMPY_API
 
496
 *Check the type coercion rules.
 
497
 */
 
498
NPY_NO_EXPORT int
 
499
PyArray_CanCastSafely(int fromtype, int totype)
 
500
{
 
501
    PyArray_Descr *from, *to;
 
502
    int felsize, telsize;
 
503
 
 
504
    if (fromtype == totype) {
 
505
        return 1;
 
506
    }
 
507
    if (fromtype == PyArray_BOOL) {
 
508
        return 1;
 
509
    }
 
510
    if (totype == PyArray_BOOL) {
 
511
        return 0;
 
512
    }
 
513
    if (totype == PyArray_OBJECT || totype == PyArray_VOID) {
 
514
        return 1;
 
515
    }
 
516
    if (fromtype == PyArray_OBJECT || fromtype == PyArray_VOID) {
 
517
        return 0;
 
518
    }
 
519
    from = PyArray_DescrFromType(fromtype);
 
520
    /*
 
521
     * cancastto is a PyArray_NOTYPE terminated C-int-array of types that
 
522
     * the data-type can be cast to safely.
 
523
     */
 
524
    if (from->f->cancastto) {
 
525
        int *curtype;
 
526
        curtype = from->f->cancastto;
 
527
        while (*curtype != PyArray_NOTYPE) {
 
528
            if (*curtype++ == totype) {
 
529
                return 1;
 
530
            }
 
531
        }
 
532
    }
 
533
    if (PyTypeNum_ISUSERDEF(totype)) {
 
534
        return 0;
 
535
    }
 
536
    to = PyArray_DescrFromType(totype);
 
537
    telsize = to->elsize;
 
538
    felsize = from->elsize;
 
539
    Py_DECREF(from);
 
540
    Py_DECREF(to);
 
541
 
 
542
    switch(fromtype) {
 
543
    case PyArray_BYTE:
 
544
    case PyArray_SHORT:
 
545
    case PyArray_INT:
 
546
    case PyArray_LONG:
 
547
    case PyArray_LONGLONG:
 
548
        if (PyTypeNum_ISINTEGER(totype)) {
 
549
            if (PyTypeNum_ISUNSIGNED(totype)) {
 
550
                return 0;
 
551
            }
 
552
            else {
 
553
                return telsize >= felsize;
 
554
            }
 
555
        }
 
556
        else if (PyTypeNum_ISFLOAT(totype)) {
 
557
            if (felsize < 8) {
 
558
                return telsize > felsize;
 
559
            }
 
560
            else {
 
561
                return telsize >= felsize;
 
562
            }
 
563
        }
 
564
        else if (PyTypeNum_ISCOMPLEX(totype)) {
 
565
            if (felsize < 8) {
 
566
                return (telsize >> 1) > felsize;
 
567
            }
 
568
            else {
 
569
                return (telsize >> 1) >= felsize;
 
570
            }
 
571
        }
 
572
        else {
 
573
            return totype > fromtype;
 
574
        }
 
575
    case PyArray_UBYTE:
 
576
    case PyArray_USHORT:
 
577
    case PyArray_UINT:
 
578
    case PyArray_ULONG:
 
579
    case PyArray_ULONGLONG:
 
580
        if (PyTypeNum_ISINTEGER(totype)) {
 
581
            if (PyTypeNum_ISSIGNED(totype)) {
 
582
                return telsize > felsize;
 
583
            }
 
584
            else {
 
585
                return telsize >= felsize;
 
586
            }
 
587
        }
 
588
        else if (PyTypeNum_ISFLOAT(totype)) {
 
589
            if (felsize < 8) {
 
590
                return telsize > felsize;
 
591
            }
 
592
            else {
 
593
                return telsize >= felsize;
 
594
            }
 
595
        }
 
596
        else if (PyTypeNum_ISCOMPLEX(totype)) {
 
597
            if (felsize < 8) {
 
598
                return (telsize >> 1) > felsize;
 
599
            }
 
600
            else {
 
601
                return (telsize >> 1) >= felsize;
 
602
            }
 
603
        }
 
604
        else {
 
605
            return totype > fromtype;
 
606
        }
 
607
    case PyArray_FLOAT:
 
608
    case PyArray_DOUBLE:
 
609
    case PyArray_LONGDOUBLE:
 
610
        if (PyTypeNum_ISCOMPLEX(totype)) {
 
611
            return (telsize >> 1) >= felsize;
 
612
        }
 
613
        else {
 
614
            return totype > fromtype;
 
615
        }
 
616
    case PyArray_CFLOAT:
 
617
    case PyArray_CDOUBLE:
 
618
    case PyArray_CLONGDOUBLE:
 
619
        return totype > fromtype;
 
620
    case PyArray_STRING:
 
621
    case PyArray_UNICODE:
 
622
        return totype > fromtype;
 
623
    default:
 
624
        return 0;
 
625
    }
 
626
}
 
627
 
 
628
/*NUMPY_API
 
629
 * leaves reference count alone --- cannot be NULL
 
630
 */
 
631
NPY_NO_EXPORT Bool
 
632
PyArray_CanCastTo(PyArray_Descr *from, PyArray_Descr *to)
 
633
{
 
634
    int fromtype=from->type_num;
 
635
    int totype=to->type_num;
 
636
    Bool ret;
 
637
 
 
638
    ret = (Bool) PyArray_CanCastSafely(fromtype, totype);
 
639
    if (ret) {
 
640
        /* Check String and Unicode more closely */
 
641
        if (fromtype == PyArray_STRING) {
 
642
            if (totype == PyArray_STRING) {
 
643
                ret = (from->elsize <= to->elsize);
 
644
            }
 
645
            else if (totype == PyArray_UNICODE) {
 
646
                ret = (from->elsize << 2 <= to->elsize);
 
647
            }
 
648
        }
 
649
        else if (fromtype == PyArray_UNICODE) {
 
650
            if (totype == PyArray_UNICODE) {
 
651
                ret = (from->elsize <= to->elsize);
 
652
            }
 
653
        }
 
654
        /*
 
655
         * TODO: If totype is STRING or unicode
 
656
         * see if the length is long enough to hold the
 
657
         * stringified value of the object.
 
658
         */
 
659
    }
 
660
    return ret;
 
661
}
 
662
 
 
663
/*NUMPY_API
 
664
 * See if array scalars can be cast.
 
665
 */
 
666
NPY_NO_EXPORT Bool
 
667
PyArray_CanCastScalar(PyTypeObject *from, PyTypeObject *to)
 
668
{
 
669
    int fromtype;
 
670
    int totype;
 
671
 
 
672
    fromtype = _typenum_fromtypeobj((PyObject *)from, 0);
 
673
    totype = _typenum_fromtypeobj((PyObject *)to, 0);
 
674
    if (fromtype == PyArray_NOTYPE || totype == PyArray_NOTYPE) {
 
675
        return FALSE;
 
676
    }
 
677
    return (Bool) PyArray_CanCastSafely(fromtype, totype);
 
678
}
 
679
 
 
680
/*NUMPY_API
 
681
 * Is the typenum valid?
 
682
 */
 
683
NPY_NO_EXPORT int
 
684
PyArray_ValidType(int type)
 
685
{
 
686
    PyArray_Descr *descr;
 
687
    int res=TRUE;
 
688
 
 
689
    descr = PyArray_DescrFromType(type);
 
690
    if (descr == NULL) {
 
691
        res = FALSE;
 
692
    }
 
693
    Py_DECREF(descr);
 
694
    return res;
 
695
}
 
696
 
 
697
/* Backward compatibility only */
 
698
/* In both Zero and One
 
699
 
 
700
***You must free the memory once you are done with it
 
701
using PyDataMem_FREE(ptr) or you create a memory leak***
 
702
 
 
703
If arr is an Object array you are getting a
 
704
BORROWED reference to Zero or One.
 
705
Do not DECREF.
 
706
Please INCREF if you will be hanging on to it.
 
707
 
 
708
The memory for the ptr still must be freed in any case;
 
709
*/
 
710
 
 
711
static int
 
712
_check_object_rec(PyArray_Descr *descr)
 
713
{
 
714
    if (PyDataType_HASFIELDS(descr) && PyDataType_REFCHK(descr)) {
 
715
        PyErr_SetString(PyExc_TypeError, "Not supported for this data-type.");
 
716
        return -1;
 
717
    }
 
718
    return 0;
 
719
}
 
720
 
 
721
/*NUMPY_API
 
722
  Get pointer to zero of correct type for array.
 
723
*/
 
724
NPY_NO_EXPORT char *
 
725
PyArray_Zero(PyArrayObject *arr)
 
726
{
 
727
    char *zeroval;
 
728
    int ret, storeflags;
 
729
    PyObject *obj;
 
730
 
 
731
    if (_check_object_rec(arr->descr) < 0) {
 
732
        return NULL;
 
733
    }
 
734
    zeroval = PyDataMem_NEW(arr->descr->elsize);
 
735
    if (zeroval == NULL) {
 
736
        PyErr_SetNone(PyExc_MemoryError);
 
737
        return NULL;
 
738
    }
 
739
 
 
740
    obj=PyInt_FromLong((long) 0);
 
741
    if (PyArray_ISOBJECT(arr)) {
 
742
        memcpy(zeroval, &obj, sizeof(PyObject *));
 
743
        Py_DECREF(obj);
 
744
        return zeroval;
 
745
    }
 
746
    storeflags = arr->flags;
 
747
    arr->flags |= BEHAVED;
 
748
    ret = arr->descr->f->setitem(obj, zeroval, arr);
 
749
    arr->flags = storeflags;
 
750
    Py_DECREF(obj);
 
751
    if (ret < 0) {
 
752
        PyDataMem_FREE(zeroval);
 
753
        return NULL;
 
754
    }
 
755
    return zeroval;
 
756
}
 
757
 
 
758
/*NUMPY_API
 
759
  Get pointer to one of correct type for array
 
760
*/
 
761
NPY_NO_EXPORT char *
 
762
PyArray_One(PyArrayObject *arr)
 
763
{
 
764
    char *oneval;
 
765
    int ret, storeflags;
 
766
    PyObject *obj;
 
767
 
 
768
    if (_check_object_rec(arr->descr) < 0) {
 
769
        return NULL;
 
770
    }
 
771
    oneval = PyDataMem_NEW(arr->descr->elsize);
 
772
    if (oneval == NULL) {
 
773
        PyErr_SetNone(PyExc_MemoryError);
 
774
        return NULL;
 
775
    }
 
776
 
 
777
    obj = PyInt_FromLong((long) 1);
 
778
    if (PyArray_ISOBJECT(arr)) {
 
779
        memcpy(oneval, &obj, sizeof(PyObject *));
 
780
        Py_DECREF(obj);
 
781
        return oneval;
 
782
    }
 
783
 
 
784
    storeflags = arr->flags;
 
785
    arr->flags |= BEHAVED;
 
786
    ret = arr->descr->f->setitem(obj, oneval, arr);
 
787
    arr->flags = storeflags;
 
788
    Py_DECREF(obj);
 
789
    if (ret < 0) {
 
790
        PyDataMem_FREE(oneval);
 
791
        return NULL;
 
792
    }
 
793
    return oneval;
 
794
}
 
795
 
 
796
/* End deprecated */
 
797
 
 
798
/*NUMPY_API
 
799
 * Return the typecode of the array a Python object would be converted to
 
800
 */
 
801
NPY_NO_EXPORT int
 
802
PyArray_ObjectType(PyObject *op, int minimum_type)
 
803
{
 
804
    PyArray_Descr *intype;
 
805
    PyArray_Descr *outtype;
 
806
    int ret;
 
807
 
 
808
    intype = PyArray_DescrFromType(minimum_type);
 
809
    if (intype == NULL) {
 
810
        PyErr_Clear();
 
811
    }
 
812
    outtype = _array_find_type(op, intype, MAX_DIMS);
 
813
    ret = outtype->type_num;
 
814
    Py_DECREF(outtype);
 
815
    Py_XDECREF(intype);
 
816
    return ret;
 
817
}
 
818
 
 
819
/* Raises error when len(op) == 0 */
 
820
 
 
821
/*NUMPY_API*/
 
822
NPY_NO_EXPORT PyArrayObject **
 
823
PyArray_ConvertToCommonType(PyObject *op, int *retn)
 
824
{
 
825
    int i, n, allscalars = 0;
 
826
    PyArrayObject **mps = NULL;
 
827
    PyObject *otmp;
 
828
    PyArray_Descr *intype = NULL, *stype = NULL;
 
829
    PyArray_Descr *newtype = NULL;
 
830
    NPY_SCALARKIND scalarkind = NPY_NOSCALAR, intypekind = NPY_NOSCALAR;
 
831
 
 
832
    *retn = n = PySequence_Length(op);
 
833
    if (n == 0) {
 
834
        PyErr_SetString(PyExc_ValueError, "0-length sequence.");
 
835
    }
 
836
    if (PyErr_Occurred()) {
 
837
        *retn = 0;
 
838
        return NULL;
 
839
    }
 
840
    mps = (PyArrayObject **)PyDataMem_NEW(n*sizeof(PyArrayObject *));
 
841
    if (mps == NULL) {
 
842
        *retn = 0;
 
843
        return (void*)PyErr_NoMemory();
 
844
    }
 
845
 
 
846
    if (PyArray_Check(op)) {
 
847
        for (i = 0; i < n; i++) {
 
848
            mps[i] = (PyArrayObject *) array_big_item((PyArrayObject *)op, i);
 
849
        }
 
850
        if (!PyArray_ISCARRAY(op)) {
 
851
            for (i = 0; i < n; i++) {
 
852
                PyObject *obj;
 
853
                obj = PyArray_NewCopy(mps[i], NPY_CORDER);
 
854
                Py_DECREF(mps[i]);
 
855
                mps[i] = (PyArrayObject *)obj;
 
856
            }
 
857
        }
 
858
        return mps;
 
859
    }
 
860
 
 
861
    for (i = 0; i < n; i++) {
 
862
        otmp = PySequence_GetItem(op, i);
 
863
        if (!PyArray_CheckAnyScalar(otmp)) {
 
864
            newtype = PyArray_DescrFromObject(otmp, intype);
 
865
            Py_XDECREF(intype);
 
866
            intype = newtype;
 
867
            mps[i] = NULL;
 
868
            intypekind = PyArray_ScalarKind(intype->type_num, NULL);
 
869
        }
 
870
        else {
 
871
            newtype = PyArray_DescrFromObject(otmp, stype);
 
872
            Py_XDECREF(stype);
 
873
            stype = newtype;
 
874
            scalarkind = PyArray_ScalarKind(newtype->type_num, NULL);
 
875
            mps[i] = (PyArrayObject *)Py_None;
 
876
            Py_INCREF(Py_None);
 
877
        }
 
878
        Py_XDECREF(otmp);
 
879
    }
 
880
    if (intype==NULL) {
 
881
        /* all scalars */
 
882
        allscalars = 1;
 
883
        intype = stype;
 
884
        Py_INCREF(intype);
 
885
        for (i = 0; i < n; i++) {
 
886
            Py_XDECREF(mps[i]);
 
887
            mps[i] = NULL;
 
888
        }
 
889
    }
 
890
    else if ((stype != NULL) && (intypekind != scalarkind)) {
 
891
        /*
 
892
         * we need to upconvert to type that
 
893
         * handles both intype and stype
 
894
         * also don't forcecast the scalars.
 
895
         */
 
896
        if (!PyArray_CanCoerceScalar(stype->type_num,
 
897
                                     intype->type_num,
 
898
                                     scalarkind)) {
 
899
            newtype = _array_small_type(intype, stype);
 
900
            Py_XDECREF(intype);
 
901
            intype = newtype;
 
902
        }
 
903
        for (i = 0; i < n; i++) {
 
904
            Py_XDECREF(mps[i]);
 
905
            mps[i] = NULL;
 
906
        }
 
907
    }
 
908
 
 
909
 
 
910
    /* Make sure all arrays are actual array objects. */
 
911
    for (i = 0; i < n; i++) {
 
912
        int flags = CARRAY;
 
913
 
 
914
        if ((otmp = PySequence_GetItem(op, i)) == NULL) {
 
915
            goto fail;
 
916
        }
 
917
        if (!allscalars && ((PyObject *)(mps[i]) == Py_None)) {
 
918
            /* forcecast scalars */
 
919
            flags |= FORCECAST;
 
920
            Py_DECREF(Py_None);
 
921
        }
 
922
        Py_INCREF(intype);
 
923
        mps[i] = (PyArrayObject*)
 
924
            PyArray_FromAny(otmp, intype, 0, 0, flags, NULL);
 
925
        Py_DECREF(otmp);
 
926
        if (mps[i] == NULL) {
 
927
            goto fail;
 
928
        }
 
929
    }
 
930
    Py_DECREF(intype);
 
931
    Py_XDECREF(stype);
 
932
    return mps;
 
933
 
 
934
 fail:
 
935
    Py_XDECREF(intype);
 
936
    Py_XDECREF(stype);
 
937
    *retn = 0;
 
938
    for (i = 0; i < n; i++) {
 
939
        Py_XDECREF(mps[i]);
 
940
    }
 
941
    PyDataMem_FREE(mps);
 
942
    return NULL;
 
943
}
 
944