~ubuntu-branches/ubuntu/natty/python3.1/natty-security

« back to all changes in this revision

Viewing changes to Modules/_ctypes/_ctypes.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2010-07-06 16:52:42 UTC
  • mfrom: (1.2.1 upstream) (2.1.11 sid)
  • Revision ID: james.westby@ubuntu.com-20100706165242-2xv4i019r3et6c0j
Tags: 3.1.2+20100706-1ubuntu1
* Merge with Debian; remaining changes:
  - Regenerate the control file.
  - Add debian/patches/overwrite-semaphore-check for Lucid buildds.

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
 
21
21
/*
22
22
 
23
 
Name                    methods, members, getsets
 
23
Name                    methods, members, getsets
24
24
==============================================================================
25
25
 
26
 
PyCStructType_Type              __new__(), from_address(), __mul__(), from_param()
27
 
UnionType_Type          __new__(), from_address(), __mul__(), from_param()
28
 
PyCPointerType_Type     __new__(), from_address(), __mul__(), from_param(), set_type()
29
 
PyCArrayType_Type               __new__(), from_address(), __mul__(), from_param()
30
 
PyCSimpleType_Type              __new__(), from_address(), __mul__(), from_param()
 
26
PyCStructType_Type              __new__(), from_address(), __mul__(), from_param()
 
27
UnionType_Type          __new__(), from_address(), __mul__(), from_param()
 
28
PyCPointerType_Type     __new__(), from_address(), __mul__(), from_param(), set_type()
 
29
PyCArrayType_Type               __new__(), from_address(), __mul__(), from_param()
 
30
PyCSimpleType_Type              __new__(), from_address(), __mul__(), from_param()
31
31
 
32
32
PyCData_Type
33
 
  Struct_Type           __new__(), __init__()
34
 
  PyCPointer_Type               __new__(), __init__(), _as_parameter_, contents
35
 
  PyCArray_Type         __new__(), __init__(), _as_parameter_, __get/setitem__(), __len__()
36
 
  Simple_Type           __new__(), __init__(), _as_parameter_
 
33
  Struct_Type           __new__(), __init__()
 
34
  PyCPointer_Type               __new__(), __init__(), _as_parameter_, contents
 
35
  PyCArray_Type         __new__(), __init__(), _as_parameter_, __get/setitem__(), __len__()
 
36
  Simple_Type           __new__(), __init__(), _as_parameter_
37
37
 
38
38
PyCField_Type
39
39
PyCStgDict_Type
45
45
 
46
46
It has some similarity to the byref() construct compared to pointer()
47
47
from_address(addr)
48
 
        - construct an instance from a given memory block (sharing this memory block)
 
48
    - construct an instance from a given memory block (sharing this memory block)
49
49
 
50
50
from_param(obj)
51
 
        - typecheck and convert a Python object into a C function call parameter
52
 
          the result may be an instance of the type, or an integer or tuple
53
 
          (typecode, value[, obj])
 
51
    - typecheck and convert a Python object into a C function call parameter
 
52
      the result may be an instance of the type, or an integer or tuple
 
53
      (typecode, value[, obj])
54
54
 
55
55
instance methods/properties
56
56
---------------------------
57
57
 
58
58
_as_parameter_
59
 
        - convert self into a C function call parameter
60
 
          This is either an integer, or a 3-tuple (typecode, value, obj)
 
59
    - convert self into a C function call parameter
 
60
      This is either an integer, or a 3-tuple (typecode, value, obj)
61
61
 
62
62
functions
63
63
---------
64
64
 
65
65
sizeof(cdata)
66
 
        - return the number of bytes the buffer contains
 
66
    - return the number of bytes the buffer contains
67
67
 
68
68
sizeof(ctype)
69
 
        - return the number of bytes the buffer of an instance would contain
 
69
    - return the number of bytes the buffer of an instance would contain
70
70
 
71
71
byref(cdata)
72
72
 
77
77
POINTER(ctype)
78
78
 
79
79
bytes(cdata)
80
 
        - return the buffer contents as a sequence of bytes (which is currently a string)
 
80
    - return the buffer contents as a sequence of bytes (which is currently a string)
81
81
 
82
82
*/
83
83
 
98
98
 * PyCField_Type
99
99
 *
100
100
 */
101
 
 
 
101
 
102
102
#define PY_SSIZE_T_CLEAN
103
103
 
104
104
#include "Python.h"
135
135
char *_ctypes_conversion_encoding = NULL;
136
136
char *_ctypes_conversion_errors = NULL;
137
137
 
138
 
 
 
138
 
139
139
/****************************************************************/
140
140
 
141
141
typedef struct {
142
 
        PyObject_HEAD
143
 
        PyObject *key;
144
 
        PyObject *dict;
 
142
    PyObject_HEAD
 
143
    PyObject *key;
 
144
    PyObject *dict;
145
145
} DictRemoverObject;
146
146
 
147
147
static void
148
148
_DictRemover_dealloc(PyObject *_self)
149
149
{
150
 
        DictRemoverObject *self = (DictRemoverObject *)_self;
151
 
        Py_XDECREF(self->key);
152
 
        Py_XDECREF(self->dict);
153
 
        Py_TYPE(self)->tp_free(_self);
 
150
    DictRemoverObject *self = (DictRemoverObject *)_self;
 
151
    Py_XDECREF(self->key);
 
152
    Py_XDECREF(self->dict);
 
153
    Py_TYPE(self)->tp_free(_self);
154
154
}
155
155
 
156
156
static PyObject *
157
157
_DictRemover_call(PyObject *_self, PyObject *args, PyObject *kw)
158
158
{
159
 
        DictRemoverObject *self = (DictRemoverObject *)_self;
160
 
        if (self->key && self->dict) {
161
 
                if (-1 == PyDict_DelItem(self->dict, self->key))
162
 
                        /* XXX Error context */
163
 
                        PyErr_WriteUnraisable(Py_None);
164
 
                Py_DECREF(self->key);
165
 
                self->key = NULL;
166
 
                Py_DECREF(self->dict);
167
 
                self->dict = NULL;
168
 
        }
169
 
        Py_INCREF(Py_None);
170
 
        return Py_None;
 
159
    DictRemoverObject *self = (DictRemoverObject *)_self;
 
160
    if (self->key && self->dict) {
 
161
        if (-1 == PyDict_DelItem(self->dict, self->key))
 
162
            /* XXX Error context */
 
163
            PyErr_WriteUnraisable(Py_None);
 
164
        Py_DECREF(self->key);
 
165
        self->key = NULL;
 
166
        Py_DECREF(self->dict);
 
167
        self->dict = NULL;
 
168
    }
 
169
    Py_INCREF(Py_None);
 
170
    return Py_None;
171
171
}
172
172
 
173
173
static PyTypeObject DictRemover_Type = {
174
 
        PyVarObject_HEAD_INIT(NULL, 0)
175
 
        "_ctypes.DictRemover",                  /* tp_name */
176
 
        sizeof(DictRemoverObject),              /* tp_basicsize */
177
 
        0,                                      /* tp_itemsize */
178
 
        _DictRemover_dealloc,                   /* tp_dealloc */
179
 
        0,                                      /* tp_print */
180
 
        0,                                      /* tp_getattr */
181
 
        0,                                      /* tp_setattr */
182
 
        0,                                      /* tp_reserved */
183
 
        0,                                      /* tp_repr */
184
 
        0,                                      /* tp_as_number */
185
 
        0,                                      /* tp_as_sequence */
186
 
        0,                                      /* tp_as_mapping */
187
 
        0,                                      /* tp_hash */
188
 
        _DictRemover_call,                      /* tp_call */
189
 
        0,                                      /* tp_str */
190
 
        0,                                      /* tp_getattro */
191
 
        0,                                      /* tp_setattro */
192
 
        0,                                      /* tp_as_buffer */
 
174
    PyVarObject_HEAD_INIT(NULL, 0)
 
175
    "_ctypes.DictRemover",                      /* tp_name */
 
176
    sizeof(DictRemoverObject),                  /* tp_basicsize */
 
177
    0,                                          /* tp_itemsize */
 
178
    _DictRemover_dealloc,                       /* tp_dealloc */
 
179
    0,                                          /* tp_print */
 
180
    0,                                          /* tp_getattr */
 
181
    0,                                          /* tp_setattr */
 
182
    0,                                          /* tp_reserved */
 
183
    0,                                          /* tp_repr */
 
184
    0,                                          /* tp_as_number */
 
185
    0,                                          /* tp_as_sequence */
 
186
    0,                                          /* tp_as_mapping */
 
187
    0,                                          /* tp_hash */
 
188
    _DictRemover_call,                          /* tp_call */
 
189
    0,                                          /* tp_str */
 
190
    0,                                          /* tp_getattro */
 
191
    0,                                          /* tp_setattro */
 
192
    0,                                          /* tp_as_buffer */
193
193
/* XXX should participate in GC? */
194
 
        Py_TPFLAGS_DEFAULT,                     /* tp_flags */
195
 
        "deletes a key from a dictionary",      /* tp_doc */
196
 
        0,                                      /* tp_traverse */
197
 
        0,                                      /* tp_clear */
198
 
        0,                                      /* tp_richcompare */
199
 
        0,                                      /* tp_weaklistoffset */
200
 
        0,                                      /* tp_iter */
201
 
        0,                                      /* tp_iternext */
202
 
        0,                                      /* tp_methods */
203
 
        0,                                      /* tp_members */
204
 
        0,                                      /* tp_getset */
205
 
        0,                                      /* tp_base */
206
 
        0,                                      /* tp_dict */
207
 
        0,                                      /* tp_descr_get */
208
 
        0,                                      /* tp_descr_set */
209
 
        0,                                      /* tp_dictoffset */
210
 
        0,                                      /* tp_init */
211
 
        0,                                      /* tp_alloc */
212
 
        0,                                      /* tp_new */
213
 
        0,                                      /* tp_free */
 
194
    Py_TPFLAGS_DEFAULT,                         /* tp_flags */
 
195
    "deletes a key from a dictionary",          /* tp_doc */
 
196
    0,                                          /* tp_traverse */
 
197
    0,                                          /* tp_clear */
 
198
    0,                                          /* tp_richcompare */
 
199
    0,                                          /* tp_weaklistoffset */
 
200
    0,                                          /* tp_iter */
 
201
    0,                                          /* tp_iternext */
 
202
    0,                                          /* tp_methods */
 
203
    0,                                          /* tp_members */
 
204
    0,                                          /* tp_getset */
 
205
    0,                                          /* tp_base */
 
206
    0,                                          /* tp_dict */
 
207
    0,                                          /* tp_descr_get */
 
208
    0,                                          /* tp_descr_set */
 
209
    0,                                          /* tp_dictoffset */
 
210
    0,                                          /* tp_init */
 
211
    0,                                          /* tp_alloc */
 
212
    0,                                          /* tp_new */
 
213
    0,                                          /* tp_free */
214
214
};
215
215
 
216
216
int
217
217
PyDict_SetItemProxy(PyObject *dict, PyObject *key, PyObject *item)
218
218
{
219
 
        PyObject *obj;
220
 
        DictRemoverObject *remover;
221
 
        PyObject *proxy;
222
 
        int result;
223
 
 
224
 
        obj = PyObject_CallObject((PyObject *)&DictRemover_Type, NULL);
225
 
        if (obj == NULL)
226
 
                return -1;
227
 
 
228
 
        remover = (DictRemoverObject *)obj;
229
 
        assert(remover->key == NULL);
230
 
        assert(remover->dict == NULL);
231
 
        Py_INCREF(key);
232
 
        remover->key = key;
233
 
        Py_INCREF(dict);
234
 
        remover->dict = dict;
235
 
 
236
 
        proxy = PyWeakref_NewProxy(item, obj);
237
 
        Py_DECREF(obj);
238
 
        if (proxy == NULL)
239
 
                return -1;
240
 
 
241
 
        result = PyDict_SetItem(dict, key, proxy);
242
 
        Py_DECREF(proxy);
243
 
        return result;
 
219
    PyObject *obj;
 
220
    DictRemoverObject *remover;
 
221
    PyObject *proxy;
 
222
    int result;
 
223
 
 
224
    obj = PyObject_CallObject((PyObject *)&DictRemover_Type, NULL);
 
225
    if (obj == NULL)
 
226
        return -1;
 
227
 
 
228
    remover = (DictRemoverObject *)obj;
 
229
    assert(remover->key == NULL);
 
230
    assert(remover->dict == NULL);
 
231
    Py_INCREF(key);
 
232
    remover->key = key;
 
233
    Py_INCREF(dict);
 
234
    remover->dict = dict;
 
235
 
 
236
    proxy = PyWeakref_NewProxy(item, obj);
 
237
    Py_DECREF(obj);
 
238
    if (proxy == NULL)
 
239
        return -1;
 
240
 
 
241
    result = PyDict_SetItem(dict, key, proxy);
 
242
    Py_DECREF(proxy);
 
243
    return result;
244
244
}
245
245
 
246
246
PyObject *
247
247
PyDict_GetItemProxy(PyObject *dict, PyObject *key)
248
248
{
249
 
        PyObject *result;
250
 
        PyObject *item = PyDict_GetItem(dict, key);
 
249
    PyObject *result;
 
250
    PyObject *item = PyDict_GetItem(dict, key);
251
251
 
252
 
        if (item == NULL)
253
 
                return NULL;
254
 
        if (!PyWeakref_CheckProxy(item))
255
 
                return item;
256
 
        result = PyWeakref_GET_OBJECT(item);
257
 
        if (result == Py_None)
258
 
                return NULL;
259
 
        return result;
 
252
    if (item == NULL)
 
253
        return NULL;
 
254
    if (!PyWeakref_CheckProxy(item))
 
255
        return item;
 
256
    result = PyWeakref_GET_OBJECT(item);
 
257
    if (result == Py_None)
 
258
        return NULL;
 
259
    return result;
260
260
}
261
261
 
262
262
/******************************************************************/
269
269
char *
270
270
_ctypes_alloc_format_string(const char *prefix, const char *suffix)
271
271
{
272
 
        size_t len;
273
 
        char *result;
 
272
    size_t len;
 
273
    char *result;
274
274
 
275
 
        if (suffix == NULL) {
276
 
                assert(PyErr_Occurred());
277
 
                return NULL;
278
 
        }
279
 
        len = strlen(suffix);
280
 
        if (prefix)
281
 
                len += strlen(prefix);
282
 
        result = PyMem_Malloc(len + 1);
283
 
        if (result == NULL)
284
 
                return NULL;
285
 
        if (prefix)
286
 
                strcpy(result, prefix);
287
 
        else
288
 
                result[0] = '\0';
289
 
        strcat(result, suffix);
290
 
        return result;
 
275
    if (suffix == NULL) {
 
276
        assert(PyErr_Occurred());
 
277
        return NULL;
 
278
    }
 
279
    len = strlen(suffix);
 
280
    if (prefix)
 
281
        len += strlen(prefix);
 
282
    result = PyMem_Malloc(len + 1);
 
283
    if (result == NULL)
 
284
        return NULL;
 
285
    if (prefix)
 
286
        strcpy(result, prefix);
 
287
    else
 
288
        result[0] = '\0';
 
289
    strcat(result, suffix);
 
290
    return result;
291
291
}
292
292
 
293
293
/*
300
300
static PyCArgObject *
301
301
StructUnionType_paramfunc(CDataObject *self)
302
302
{
303
 
        PyCArgObject *parg;
304
 
        StgDictObject *stgdict;
305
 
        
306
 
        parg = PyCArgObject_new();
307
 
        if (parg == NULL)
308
 
                return NULL;
309
 
 
310
 
        parg->tag = 'V';
311
 
        stgdict = PyObject_stgdict((PyObject *)self);
312
 
        assert(stgdict); /* Cannot be NULL for structure/union instances */
313
 
        parg->pffi_type = &stgdict->ffi_type_pointer;
314
 
        /* For structure parameters (by value), parg->value doesn't contain the structure
315
 
           data itself, instead parg->value.p *points* to the structure's data
316
 
           See also _ctypes.c, function _call_function_pointer().
317
 
        */
318
 
        parg->value.p = self->b_ptr;
319
 
        parg->size = self->b_size;
320
 
        Py_INCREF(self);
321
 
        parg->obj = (PyObject *)self;
322
 
        return parg;    
 
303
    PyCArgObject *parg;
 
304
    StgDictObject *stgdict;
 
305
 
 
306
    parg = PyCArgObject_new();
 
307
    if (parg == NULL)
 
308
        return NULL;
 
309
 
 
310
    parg->tag = 'V';
 
311
    stgdict = PyObject_stgdict((PyObject *)self);
 
312
    assert(stgdict); /* Cannot be NULL for structure/union instances */
 
313
    parg->pffi_type = &stgdict->ffi_type_pointer;
 
314
    /* For structure parameters (by value), parg->value doesn't contain the structure
 
315
       data itself, instead parg->value.p *points* to the structure's data
 
316
       See also _ctypes.c, function _call_function_pointer().
 
317
    */
 
318
    parg->value.p = self->b_ptr;
 
319
    parg->size = self->b_size;
 
320
    Py_INCREF(self);
 
321
    parg->obj = (PyObject *)self;
 
322
    return parg;
323
323
}
324
324
 
325
325
static PyObject *
326
326
StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isStruct)
327
327
{
328
 
        PyTypeObject *result;
329
 
        PyObject *fields;
330
 
        StgDictObject *dict;
331
 
 
332
 
        /* create the new instance (which is a class,
333
 
           since we are a metatype!) */
334
 
        result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
335
 
        if (!result)
336
 
                return NULL;
337
 
 
338
 
        /* keep this for bw compatibility */
339
 
        if (PyDict_GetItemString(result->tp_dict, "_abstract_"))
340
 
                return (PyObject *)result;
341
 
 
342
 
        dict = (StgDictObject *)PyObject_CallObject((PyObject *)&PyCStgDict_Type, NULL);
343
 
        if (!dict) {
344
 
                Py_DECREF(result);
345
 
                return NULL;
346
 
        }
347
 
        /* replace the class dict by our updated stgdict, which holds info
348
 
           about storage requirements of the instances */
349
 
        if (-1 == PyDict_Update((PyObject *)dict, result->tp_dict)) {
350
 
                Py_DECREF(result);
351
 
                Py_DECREF((PyObject *)dict);
352
 
                return NULL;
353
 
        }
354
 
        Py_DECREF(result->tp_dict);
355
 
        result->tp_dict = (PyObject *)dict;
356
 
        dict->format = _ctypes_alloc_format_string(NULL, "B");
357
 
        if (dict->format == NULL) {
358
 
                Py_DECREF(result);
359
 
                return NULL;
360
 
        }
361
 
 
362
 
        dict->paramfunc = StructUnionType_paramfunc;
363
 
 
364
 
        fields = PyDict_GetItemString((PyObject *)dict, "_fields_");
365
 
        if (!fields) {
366
 
                StgDictObject *basedict = PyType_stgdict((PyObject *)result->tp_base);
367
 
 
368
 
                if (basedict == NULL)
369
 
                        return (PyObject *)result;
370
 
                /* copy base dict */
371
 
                if (-1 == PyCStgDict_clone(dict, basedict)) {
372
 
                        Py_DECREF(result);
373
 
                        return NULL;
374
 
                }
375
 
                dict->flags &= ~DICTFLAG_FINAL; /* clear the 'final' flag in the subclass dict */
376
 
                basedict->flags |= DICTFLAG_FINAL; /* set the 'final' flag in the baseclass dict */
377
 
                return (PyObject *)result;
378
 
        }
379
 
 
380
 
        if (-1 == PyObject_SetAttrString((PyObject *)result, "_fields_", fields)) {
381
 
                Py_DECREF(result);
382
 
                return NULL;
383
 
        }
384
 
        return (PyObject *)result;
 
328
    PyTypeObject *result;
 
329
    PyObject *fields;
 
330
    StgDictObject *dict;
 
331
 
 
332
    /* create the new instance (which is a class,
 
333
       since we are a metatype!) */
 
334
    result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
 
335
    if (!result)
 
336
        return NULL;
 
337
 
 
338
    /* keep this for bw compatibility */
 
339
    if (PyDict_GetItemString(result->tp_dict, "_abstract_"))
 
340
        return (PyObject *)result;
 
341
 
 
342
    dict = (StgDictObject *)PyObject_CallObject((PyObject *)&PyCStgDict_Type, NULL);
 
343
    if (!dict) {
 
344
        Py_DECREF(result);
 
345
        return NULL;
 
346
    }
 
347
    /* replace the class dict by our updated stgdict, which holds info
 
348
       about storage requirements of the instances */
 
349
    if (-1 == PyDict_Update((PyObject *)dict, result->tp_dict)) {
 
350
        Py_DECREF(result);
 
351
        Py_DECREF((PyObject *)dict);
 
352
        return NULL;
 
353
    }
 
354
    Py_DECREF(result->tp_dict);
 
355
    result->tp_dict = (PyObject *)dict;
 
356
    dict->format = _ctypes_alloc_format_string(NULL, "B");
 
357
    if (dict->format == NULL) {
 
358
        Py_DECREF(result);
 
359
        return NULL;
 
360
    }
 
361
 
 
362
    dict->paramfunc = StructUnionType_paramfunc;
 
363
 
 
364
    fields = PyDict_GetItemString((PyObject *)dict, "_fields_");
 
365
    if (!fields) {
 
366
        StgDictObject *basedict = PyType_stgdict((PyObject *)result->tp_base);
 
367
 
 
368
        if (basedict == NULL)
 
369
            return (PyObject *)result;
 
370
        /* copy base dict */
 
371
        if (-1 == PyCStgDict_clone(dict, basedict)) {
 
372
            Py_DECREF(result);
 
373
            return NULL;
 
374
        }
 
375
        dict->flags &= ~DICTFLAG_FINAL; /* clear the 'final' flag in the subclass dict */
 
376
        basedict->flags |= DICTFLAG_FINAL; /* set the 'final' flag in the baseclass dict */
 
377
        return (PyObject *)result;
 
378
    }
 
379
 
 
380
    if (-1 == PyObject_SetAttrString((PyObject *)result, "_fields_", fields)) {
 
381
        Py_DECREF(result);
 
382
        return NULL;
 
383
    }
 
384
    return (PyObject *)result;
385
385
}
386
386
 
387
387
static PyObject *
388
388
PyCStructType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
389
389
{
390
 
        return StructUnionType_new(type, args, kwds, 1);
 
390
    return StructUnionType_new(type, args, kwds, 1);
391
391
}
392
392
 
393
393
static PyObject *
394
394
UnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
395
395
{
396
 
        return StructUnionType_new(type, args, kwds, 0);
 
396
    return StructUnionType_new(type, args, kwds, 0);
397
397
}
398
398
 
399
399
static char from_address_doc[] =
402
402
static PyObject *
403
403
CDataType_from_address(PyObject *type, PyObject *value)
404
404
{
405
 
        void *buf;
406
 
        if (!PyLong_Check(value)) {
407
 
                PyErr_SetString(PyExc_TypeError,
408
 
                                "integer expected");
409
 
                return NULL;
410
 
        }
411
 
        buf = (void *)PyLong_AsVoidPtr(value);
412
 
        if (PyErr_Occurred())
413
 
                return NULL;
414
 
        return PyCData_AtAddress(type, buf);
 
405
    void *buf;
 
406
    if (!PyLong_Check(value)) {
 
407
        PyErr_SetString(PyExc_TypeError,
 
408
                        "integer expected");
 
409
        return NULL;
 
410
    }
 
411
    buf = (void *)PyLong_AsVoidPtr(value);
 
412
    if (PyErr_Occurred())
 
413
        return NULL;
 
414
    return PyCData_AtAddress(type, buf);
415
415
}
416
416
 
417
417
static char from_buffer_doc[] =
423
423
static PyObject *
424
424
CDataType_from_buffer(PyObject *type, PyObject *args)
425
425
{
426
 
        void *buffer;
427
 
        Py_ssize_t buffer_len;
428
 
        Py_ssize_t offset = 0;
429
 
        PyObject *obj, *result;
430
 
        StgDictObject *dict = PyType_stgdict(type);
431
 
        assert (dict);
432
 
 
433
 
        if (!PyArg_ParseTuple(args,
434
 
#if (PY_VERSION_HEX < 0x02050000)
435
 
                              "O|i:from_buffer",
436
 
#else
437
 
                              "O|n:from_buffer",
438
 
#endif
439
 
                              &obj, &offset))
440
 
                return NULL;
441
 
 
442
 
        if (-1 == PyObject_AsWriteBuffer(obj, &buffer, &buffer_len))
443
 
                return NULL;
444
 
 
445
 
        if (offset < 0) {
446
 
                PyErr_SetString(PyExc_ValueError,
447
 
                                "offset cannot be negative");
448
 
                return NULL;
449
 
        }
450
 
        if (dict->size > buffer_len - offset) {
451
 
                PyErr_Format(PyExc_ValueError,
452
 
#if (PY_VERSION_HEX < 0x02050000)
453
 
                             "Buffer size too small (%d instead of at least %d bytes)",
454
 
#else
455
 
                             "Buffer size too small (%zd instead of at least %zd bytes)",
456
 
#endif
457
 
                             buffer_len, dict->size + offset);
458
 
                return NULL;
459
 
        }
460
 
 
461
 
        result = PyCData_AtAddress(type, (char *)buffer + offset);
462
 
        if (result == NULL)
463
 
                return NULL;
464
 
 
465
 
        Py_INCREF(obj);
466
 
        if (-1 == KeepRef((CDataObject *)result, -1, obj)) {
467
 
                Py_DECREF(result);
468
 
                return NULL;
469
 
        }
470
 
        return result;
 
426
    void *buffer;
 
427
    Py_ssize_t buffer_len;
 
428
    Py_ssize_t offset = 0;
 
429
    PyObject *obj, *result;
 
430
    StgDictObject *dict = PyType_stgdict(type);
 
431
    assert (dict);
 
432
 
 
433
    if (!PyArg_ParseTuple(args,
 
434
#if (PY_VERSION_HEX < 0x02050000)
 
435
                          "O|i:from_buffer",
 
436
#else
 
437
                          "O|n:from_buffer",
 
438
#endif
 
439
                          &obj, &offset))
 
440
        return NULL;
 
441
 
 
442
    if (-1 == PyObject_AsWriteBuffer(obj, &buffer, &buffer_len))
 
443
        return NULL;
 
444
 
 
445
    if (offset < 0) {
 
446
        PyErr_SetString(PyExc_ValueError,
 
447
                        "offset cannot be negative");
 
448
        return NULL;
 
449
    }
 
450
    if (dict->size > buffer_len - offset) {
 
451
        PyErr_Format(PyExc_ValueError,
 
452
#if (PY_VERSION_HEX < 0x02050000)
 
453
                     "Buffer size too small (%d instead of at least %d bytes)",
 
454
#else
 
455
                     "Buffer size too small (%zd instead of at least %zd bytes)",
 
456
#endif
 
457
                     buffer_len, dict->size + offset);
 
458
        return NULL;
 
459
    }
 
460
 
 
461
    result = PyCData_AtAddress(type, (char *)buffer + offset);
 
462
    if (result == NULL)
 
463
        return NULL;
 
464
 
 
465
    Py_INCREF(obj);
 
466
    if (-1 == KeepRef((CDataObject *)result, -1, obj)) {
 
467
        Py_DECREF(result);
 
468
        return NULL;
 
469
    }
 
470
    return result;
471
471
}
472
472
 
473
473
static char from_buffer_copy_doc[] =
479
479
static PyObject *
480
480
CDataType_from_buffer_copy(PyObject *type, PyObject *args)
481
481
{
482
 
        const void *buffer;
483
 
        Py_ssize_t buffer_len;
484
 
        Py_ssize_t offset = 0;
485
 
        PyObject *obj, *result;
486
 
        StgDictObject *dict = PyType_stgdict(type);
487
 
        assert (dict);
488
 
 
489
 
        if (!PyArg_ParseTuple(args,
490
 
#if (PY_VERSION_HEX < 0x02050000)
491
 
                              "O|i:from_buffer",
492
 
#else
493
 
                              "O|n:from_buffer",
494
 
#endif
495
 
                              &obj, &offset))
496
 
                return NULL;
497
 
 
498
 
        if (-1 == PyObject_AsReadBuffer(obj, (const void**)&buffer, &buffer_len))
499
 
                return NULL;
500
 
 
501
 
        if (offset < 0) {
502
 
                PyErr_SetString(PyExc_ValueError,
503
 
                                "offset cannot be negative");
504
 
                return NULL;
505
 
        }
506
 
 
507
 
        if (dict->size > buffer_len - offset) {
508
 
                PyErr_Format(PyExc_ValueError,
509
 
#if (PY_VERSION_HEX < 0x02050000)
510
 
                             "Buffer size too small (%d instead of at least %d bytes)",
511
 
#else
512
 
                             "Buffer size too small (%zd instead of at least %zd bytes)",
513
 
#endif
514
 
                             buffer_len, dict->size + offset);
515
 
                return NULL;
516
 
        }
517
 
 
518
 
        result = GenericPyCData_new((PyTypeObject *)type, NULL, NULL);
519
 
        if (result == NULL)
520
 
                return NULL;
521
 
        memcpy(((CDataObject *)result)->b_ptr,
522
 
               (char *)buffer+offset, dict->size);
523
 
        return result;
 
482
    const void *buffer;
 
483
    Py_ssize_t buffer_len;
 
484
    Py_ssize_t offset = 0;
 
485
    PyObject *obj, *result;
 
486
    StgDictObject *dict = PyType_stgdict(type);
 
487
    assert (dict);
 
488
 
 
489
    if (!PyArg_ParseTuple(args,
 
490
#if (PY_VERSION_HEX < 0x02050000)
 
491
                          "O|i:from_buffer",
 
492
#else
 
493
                          "O|n:from_buffer",
 
494
#endif
 
495
                          &obj, &offset))
 
496
        return NULL;
 
497
 
 
498
    if (-1 == PyObject_AsReadBuffer(obj, (const void**)&buffer, &buffer_len))
 
499
        return NULL;
 
500
 
 
501
    if (offset < 0) {
 
502
        PyErr_SetString(PyExc_ValueError,
 
503
                        "offset cannot be negative");
 
504
        return NULL;
 
505
    }
 
506
 
 
507
    if (dict->size > buffer_len - offset) {
 
508
        PyErr_Format(PyExc_ValueError,
 
509
#if (PY_VERSION_HEX < 0x02050000)
 
510
                     "Buffer size too small (%d instead of at least %d bytes)",
 
511
#else
 
512
                     "Buffer size too small (%zd instead of at least %zd bytes)",
 
513
#endif
 
514
                     buffer_len, dict->size + offset);
 
515
        return NULL;
 
516
    }
 
517
 
 
518
    result = GenericPyCData_new((PyTypeObject *)type, NULL, NULL);
 
519
    if (result == NULL)
 
520
        return NULL;
 
521
    memcpy(((CDataObject *)result)->b_ptr,
 
522
           (char *)buffer+offset, dict->size);
 
523
    return result;
524
524
}
525
525
 
526
526
static char in_dll_doc[] =
529
529
static PyObject *
530
530
CDataType_in_dll(PyObject *type, PyObject *args)
531
531
{
532
 
        PyObject *dll;
533
 
        char *name;
534
 
        PyObject *obj;
535
 
        void *handle;
536
 
        void *address;
537
 
 
538
 
        if (!PyArg_ParseTuple(args, "Os:in_dll", &dll, &name))
539
 
                return NULL;
540
 
 
541
 
        obj = PyObject_GetAttrString(dll, "_handle");
542
 
        if (!obj)
543
 
                return NULL;
544
 
        if (!PyLong_Check(obj)) {
545
 
                PyErr_SetString(PyExc_TypeError,
546
 
                                "the _handle attribute of the second argument must be an integer");
547
 
                Py_DECREF(obj);
548
 
                return NULL;
549
 
        }
550
 
        handle = (void *)PyLong_AsVoidPtr(obj);
551
 
        Py_DECREF(obj);
552
 
        if (PyErr_Occurred()) {
553
 
                PyErr_SetString(PyExc_ValueError,
554
 
                                "could not convert the _handle attribute to a pointer");
555
 
                return NULL;
556
 
        }
 
532
    PyObject *dll;
 
533
    char *name;
 
534
    PyObject *obj;
 
535
    void *handle;
 
536
    void *address;
 
537
 
 
538
    if (!PyArg_ParseTuple(args, "Os:in_dll", &dll, &name))
 
539
        return NULL;
 
540
 
 
541
    obj = PyObject_GetAttrString(dll, "_handle");
 
542
    if (!obj)
 
543
        return NULL;
 
544
    if (!PyLong_Check(obj)) {
 
545
        PyErr_SetString(PyExc_TypeError,
 
546
                        "the _handle attribute of the second argument must be an integer");
 
547
        Py_DECREF(obj);
 
548
        return NULL;
 
549
    }
 
550
    handle = (void *)PyLong_AsVoidPtr(obj);
 
551
    Py_DECREF(obj);
 
552
    if (PyErr_Occurred()) {
 
553
        PyErr_SetString(PyExc_ValueError,
 
554
                        "could not convert the _handle attribute to a pointer");
 
555
        return NULL;
 
556
    }
557
557
 
558
558
#ifdef MS_WIN32
559
 
        address = (void *)GetProcAddress(handle, name);
560
 
        if (!address) {
561
 
                PyErr_Format(PyExc_ValueError,
562
 
                             "symbol '%s' not found",
563
 
                             name);
564
 
                return NULL;
565
 
        }
 
559
    address = (void *)GetProcAddress(handle, name);
 
560
    if (!address) {
 
561
        PyErr_Format(PyExc_ValueError,
 
562
                     "symbol '%s' not found",
 
563
                     name);
 
564
        return NULL;
 
565
    }
566
566
#else
567
 
        address = (void *)ctypes_dlsym(handle, name);
568
 
        if (!address) {
 
567
    address = (void *)ctypes_dlsym(handle, name);
 
568
    if (!address) {
569
569
#ifdef __CYGWIN__
570
570
/* dlerror() isn't very helpful on cygwin */
571
 
                PyErr_Format(PyExc_ValueError,
572
 
                             "symbol '%s' not found (%s) ",
573
 
                             name);
 
571
        PyErr_Format(PyExc_ValueError,
 
572
                     "symbol '%s' not found (%s) ",
 
573
                     name);
574
574
#else
575
 
                PyErr_SetString(PyExc_ValueError, ctypes_dlerror());
576
 
#endif
577
 
                return NULL;
578
 
        }
579
 
#endif
580
 
        return PyCData_AtAddress(type, address);
 
575
        PyErr_SetString(PyExc_ValueError, ctypes_dlerror());
 
576
#endif
 
577
        return NULL;
 
578
    }
 
579
#endif
 
580
    return PyCData_AtAddress(type, address);
581
581
}
582
582
 
583
583
static char from_param_doc[] =
586
586
static PyObject *
587
587
CDataType_from_param(PyObject *type, PyObject *value)
588
588
{
589
 
        PyObject *as_parameter;
590
 
        if (1 == PyObject_IsInstance(value, type)) {
591
 
                Py_INCREF(value);
592
 
                return value;
593
 
        }
594
 
        if (PyCArg_CheckExact(value)) {
595
 
                PyCArgObject *p = (PyCArgObject *)value;
596
 
                PyObject *ob = p->obj;
597
 
                const char *ob_name;
598
 
                StgDictObject *dict;
599
 
                dict = PyType_stgdict(type);
600
 
 
601
 
                /* If we got a PyCArgObject, we must check if the object packed in it
602
 
                   is an instance of the type's dict->proto */
603
 
                if(dict && ob
604
 
                   && PyObject_IsInstance(ob, dict->proto)) {
605
 
                        Py_INCREF(value);
606
 
                        return value;
607
 
                }
608
 
                ob_name = (ob) ? Py_TYPE(ob)->tp_name : "???";
609
 
                PyErr_Format(PyExc_TypeError,
610
 
                             "expected %s instance instead of pointer to %s",
611
 
                             ((PyTypeObject *)type)->tp_name, ob_name);
612
 
                return NULL;
613
 
        }
614
 
 
615
 
        as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
616
 
        if (as_parameter) {
617
 
                value = CDataType_from_param(type, as_parameter);
618
 
                Py_DECREF(as_parameter);
619
 
                return value;
620
 
        }
621
 
        PyErr_Format(PyExc_TypeError,
622
 
                     "expected %s instance instead of %s",
623
 
                     ((PyTypeObject *)type)->tp_name,
624
 
                     Py_TYPE(value)->tp_name);
625
 
        return NULL;
 
589
    PyObject *as_parameter;
 
590
    if (1 == PyObject_IsInstance(value, type)) {
 
591
        Py_INCREF(value);
 
592
        return value;
 
593
    }
 
594
    if (PyCArg_CheckExact(value)) {
 
595
        PyCArgObject *p = (PyCArgObject *)value;
 
596
        PyObject *ob = p->obj;
 
597
        const char *ob_name;
 
598
        StgDictObject *dict;
 
599
        dict = PyType_stgdict(type);
 
600
 
 
601
        /* If we got a PyCArgObject, we must check if the object packed in it
 
602
           is an instance of the type's dict->proto */
 
603
        if(dict && ob
 
604
           && PyObject_IsInstance(ob, dict->proto)) {
 
605
            Py_INCREF(value);
 
606
            return value;
 
607
        }
 
608
        ob_name = (ob) ? Py_TYPE(ob)->tp_name : "???";
 
609
        PyErr_Format(PyExc_TypeError,
 
610
                     "expected %s instance instead of pointer to %s",
 
611
                     ((PyTypeObject *)type)->tp_name, ob_name);
 
612
        return NULL;
 
613
    }
 
614
 
 
615
    as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
 
616
    if (as_parameter) {
 
617
        value = CDataType_from_param(type, as_parameter);
 
618
        Py_DECREF(as_parameter);
 
619
        return value;
 
620
    }
 
621
    PyErr_Format(PyExc_TypeError,
 
622
                 "expected %s instance instead of %s",
 
623
                 ((PyTypeObject *)type)->tp_name,
 
624
                 Py_TYPE(value)->tp_name);
 
625
    return NULL;
626
626
}
627
627
 
628
628
static PyMethodDef CDataType_methods[] = {
629
 
        { "from_param", CDataType_from_param, METH_O, from_param_doc },
630
 
        { "from_address", CDataType_from_address, METH_O, from_address_doc },
631
 
        { "from_buffer", CDataType_from_buffer, METH_VARARGS, from_buffer_doc, },
632
 
        { "from_buffer_copy", CDataType_from_buffer_copy, METH_VARARGS, from_buffer_copy_doc, },
633
 
        { "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc },
634
 
        { NULL, NULL },
 
629
    { "from_param", CDataType_from_param, METH_O, from_param_doc },
 
630
    { "from_address", CDataType_from_address, METH_O, from_address_doc },
 
631
    { "from_buffer", CDataType_from_buffer, METH_VARARGS, from_buffer_doc, },
 
632
    { "from_buffer_copy", CDataType_from_buffer_copy, METH_VARARGS, from_buffer_copy_doc, },
 
633
    { "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc },
 
634
    { NULL, NULL },
635
635
};
636
636
 
637
637
static PyObject *
638
638
CDataType_repeat(PyObject *self, Py_ssize_t length)
639
639
{
640
 
        if (length < 0)
641
 
                return PyErr_Format(PyExc_ValueError,
642
 
                                    "Array length must be >= 0, not %zd",
643
 
                                    length);
644
 
        return PyCArrayType_from_ctype(self, length);
 
640
    if (length < 0)
 
641
        return PyErr_Format(PyExc_ValueError,
 
642
                            "Array length must be >= 0, not %zd",
 
643
                            length);
 
644
    return PyCArrayType_from_ctype(self, length);
645
645
}
646
646
 
647
647
static PySequenceMethods CDataType_as_sequence = {
648
 
        0,                      /* inquiry sq_length; */
649
 
        0,                      /* binaryfunc sq_concat; */
650
 
        CDataType_repeat,       /* intargfunc sq_repeat; */
651
 
        0,                      /* intargfunc sq_item; */
652
 
        0,                      /* intintargfunc sq_slice; */
653
 
        0,                      /* intobjargproc sq_ass_item; */
654
 
        0,                      /* intintobjargproc sq_ass_slice; */
655
 
        0,                      /* objobjproc sq_contains; */
656
 
        
657
 
        0,                      /* binaryfunc sq_inplace_concat; */
658
 
        0,                      /* intargfunc sq_inplace_repeat; */
 
648
    0,                          /* inquiry sq_length; */
 
649
    0,                          /* binaryfunc sq_concat; */
 
650
    CDataType_repeat,           /* intargfunc sq_repeat; */
 
651
    0,                          /* intargfunc sq_item; */
 
652
    0,                          /* intintargfunc sq_slice; */
 
653
    0,                          /* intobjargproc sq_ass_item; */
 
654
    0,                          /* intintobjargproc sq_ass_slice; */
 
655
    0,                          /* objobjproc sq_contains; */
 
656
 
 
657
    0,                          /* binaryfunc sq_inplace_concat; */
 
658
    0,                          /* intargfunc sq_inplace_repeat; */
659
659
};
660
660
 
661
661
static int
662
662
CDataType_clear(PyTypeObject *self)
663
663
{
664
 
        StgDictObject *dict = PyType_stgdict((PyObject *)self);
665
 
        if (dict)
666
 
                Py_CLEAR(dict->proto);
667
 
        return PyType_Type.tp_clear((PyObject *)self);
 
664
    StgDictObject *dict = PyType_stgdict((PyObject *)self);
 
665
    if (dict)
 
666
        Py_CLEAR(dict->proto);
 
667
    return PyType_Type.tp_clear((PyObject *)self);
668
668
}
669
669
 
670
670
static int
671
671
CDataType_traverse(PyTypeObject *self, visitproc visit, void *arg)
672
672
{
673
 
        StgDictObject *dict = PyType_stgdict((PyObject *)self);
674
 
        if (dict)
675
 
                Py_VISIT(dict->proto);
676
 
        return PyType_Type.tp_traverse((PyObject *)self, visit, arg);
 
673
    StgDictObject *dict = PyType_stgdict((PyObject *)self);
 
674
    if (dict)
 
675
        Py_VISIT(dict->proto);
 
676
    return PyType_Type.tp_traverse((PyObject *)self, visit, arg);
677
677
}
678
678
 
679
679
static int
680
680
PyCStructType_setattro(PyObject *self, PyObject *key, PyObject *value)
681
681
{
682
 
        /* XXX Should we disallow deleting _fields_? */
683
 
        if (-1 == PyType_Type.tp_setattro(self, key, value))
684
 
                return -1;
685
 
        
686
 
        if (value && PyUnicode_Check(key) &&
687
 
            /* XXX struni _PyUnicode_AsString can fail (also in other places)! */
688
 
            0 == strcmp(_PyUnicode_AsString(key), "_fields_"))
689
 
                return PyCStructUnionType_update_stgdict(self, value, 1);
690
 
        return 0;
 
682
    /* XXX Should we disallow deleting _fields_? */
 
683
    if (-1 == PyType_Type.tp_setattro(self, key, value))
 
684
        return -1;
 
685
 
 
686
    if (value && PyUnicode_Check(key) &&
 
687
        /* XXX struni _PyUnicode_AsString can fail (also in other places)! */
 
688
        0 == strcmp(_PyUnicode_AsString(key), "_fields_"))
 
689
        return PyCStructUnionType_update_stgdict(self, value, 1);
 
690
    return 0;
691
691
}
692
692
 
693
693
 
694
694
static int
695
695
UnionType_setattro(PyObject *self, PyObject *key, PyObject *value)
696
696
{
697
 
        /* XXX Should we disallow deleting _fields_? */
698
 
        if (-1 == PyObject_GenericSetAttr(self, key, value))
699
 
                return -1;
700
 
        
701
 
        if (PyUnicode_Check(key) &&
702
 
            0 == strcmp(_PyUnicode_AsString(key), "_fields_"))
703
 
                return PyCStructUnionType_update_stgdict(self, value, 0);
704
 
        return 0;
 
697
    /* XXX Should we disallow deleting _fields_? */
 
698
    if (-1 == PyObject_GenericSetAttr(self, key, value))
 
699
        return -1;
 
700
 
 
701
    if (PyUnicode_Check(key) &&
 
702
        0 == strcmp(_PyUnicode_AsString(key), "_fields_"))
 
703
        return PyCStructUnionType_update_stgdict(self, value, 0);
 
704
    return 0;
705
705
}
706
706
 
707
707
 
708
708
PyTypeObject PyCStructType_Type = {
709
 
        PyVarObject_HEAD_INIT(NULL, 0)
710
 
        "_ctypes.PyCStructType",                        /* tp_name */
711
 
        0,                                      /* tp_basicsize */
712
 
        0,                                      /* tp_itemsize */
713
 
        0,                                      /* tp_dealloc */
714
 
        0,                                      /* tp_print */
715
 
        0,                                      /* tp_getattr */
716
 
        0,                                      /* tp_setattr */
717
 
        0,                                      /* tp_reserved */
718
 
        0,                                      /* tp_repr */
719
 
        0,                                      /* tp_as_number */
720
 
        &CDataType_as_sequence,                 /* tp_as_sequence */
721
 
        0,                                      /* tp_as_mapping */
722
 
        0,                                      /* tp_hash */
723
 
        0,                                      /* tp_call */
724
 
        0,                                      /* tp_str */
725
 
        0,                                      /* tp_getattro */
726
 
        PyCStructType_setattro,                 /* tp_setattro */
727
 
        0,                                      /* tp_as_buffer */
728
 
        Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
729
 
        "metatype for the CData Objects",       /* tp_doc */
730
 
        (traverseproc)CDataType_traverse,       /* tp_traverse */
731
 
        (inquiry)CDataType_clear,               /* tp_clear */
732
 
        0,                                      /* tp_richcompare */
733
 
        0,                                      /* tp_weaklistoffset */
734
 
        0,                                      /* tp_iter */
735
 
        0,                                      /* tp_iternext */
736
 
        CDataType_methods,                      /* tp_methods */
737
 
        0,                                      /* tp_members */
738
 
        0,                                      /* tp_getset */
739
 
        0,                                      /* tp_base */
740
 
        0,                                      /* tp_dict */
741
 
        0,                                      /* tp_descr_get */
742
 
        0,                                      /* tp_descr_set */
743
 
        0,                                      /* tp_dictoffset */
744
 
        0,                                      /* tp_init */
745
 
        0,                                      /* tp_alloc */
746
 
        PyCStructType_new,                              /* tp_new */
747
 
        0,                                      /* tp_free */
 
709
    PyVarObject_HEAD_INIT(NULL, 0)
 
710
    "_ctypes.PyCStructType",                            /* tp_name */
 
711
    0,                                          /* tp_basicsize */
 
712
    0,                                          /* tp_itemsize */
 
713
    0,                                          /* tp_dealloc */
 
714
    0,                                          /* tp_print */
 
715
    0,                                          /* tp_getattr */
 
716
    0,                                          /* tp_setattr */
 
717
    0,                                          /* tp_reserved */
 
718
    0,                                          /* tp_repr */
 
719
    0,                                          /* tp_as_number */
 
720
    &CDataType_as_sequence,                     /* tp_as_sequence */
 
721
    0,                                          /* tp_as_mapping */
 
722
    0,                                          /* tp_hash */
 
723
    0,                                          /* tp_call */
 
724
    0,                                          /* tp_str */
 
725
    0,                                          /* tp_getattro */
 
726
    PyCStructType_setattro,                     /* tp_setattro */
 
727
    0,                                          /* tp_as_buffer */
 
728
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
 
729
    "metatype for the CData Objects",           /* tp_doc */
 
730
    (traverseproc)CDataType_traverse,           /* tp_traverse */
 
731
    (inquiry)CDataType_clear,                   /* tp_clear */
 
732
    0,                                          /* tp_richcompare */
 
733
    0,                                          /* tp_weaklistoffset */
 
734
    0,                                          /* tp_iter */
 
735
    0,                                          /* tp_iternext */
 
736
    CDataType_methods,                          /* tp_methods */
 
737
    0,                                          /* tp_members */
 
738
    0,                                          /* tp_getset */
 
739
    0,                                          /* tp_base */
 
740
    0,                                          /* tp_dict */
 
741
    0,                                          /* tp_descr_get */
 
742
    0,                                          /* tp_descr_set */
 
743
    0,                                          /* tp_dictoffset */
 
744
    0,                                          /* tp_init */
 
745
    0,                                          /* tp_alloc */
 
746
    PyCStructType_new,                                  /* tp_new */
 
747
    0,                                          /* tp_free */
748
748
};
749
749
 
750
750
static PyTypeObject UnionType_Type = {
751
 
        PyVarObject_HEAD_INIT(NULL, 0)
752
 
        "_ctypes.UnionType",                    /* tp_name */
753
 
        0,                                      /* tp_basicsize */
754
 
        0,                                      /* tp_itemsize */
755
 
        0,                                      /* tp_dealloc */
756
 
        0,                                      /* tp_print */
757
 
        0,                                      /* tp_getattr */
758
 
        0,                                      /* tp_setattr */
759
 
        0,                                      /* tp_reserved */
760
 
        0,                                      /* tp_repr */
761
 
        0,                                      /* tp_as_number */
762
 
        &CDataType_as_sequence,         /* tp_as_sequence */
763
 
        0,                                      /* tp_as_mapping */
764
 
        0,                                      /* tp_hash */
765
 
        0,                                      /* tp_call */
766
 
        0,                                      /* tp_str */
767
 
        0,                                      /* tp_getattro */
768
 
        UnionType_setattro,                     /* tp_setattro */
769
 
        0,                                      /* tp_as_buffer */
770
 
        Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
771
 
        "metatype for the CData Objects",       /* tp_doc */
772
 
        (traverseproc)CDataType_traverse,       /* tp_traverse */
773
 
        (inquiry)CDataType_clear,               /* tp_clear */
774
 
        0,                                      /* tp_richcompare */
775
 
        0,                                      /* tp_weaklistoffset */
776
 
        0,                                      /* tp_iter */
777
 
        0,                                      /* tp_iternext */
778
 
        CDataType_methods,                      /* tp_methods */
779
 
        0,                                      /* tp_members */
780
 
        0,                                      /* tp_getset */
781
 
        0,                                      /* tp_base */
782
 
        0,                                      /* tp_dict */
783
 
        0,                                      /* tp_descr_get */
784
 
        0,                                      /* tp_descr_set */
785
 
        0,                                      /* tp_dictoffset */
786
 
        0,                                      /* tp_init */
787
 
        0,                                      /* tp_alloc */
788
 
        UnionType_new,                          /* tp_new */
789
 
        0,                                      /* tp_free */
 
751
    PyVarObject_HEAD_INIT(NULL, 0)
 
752
    "_ctypes.UnionType",                        /* tp_name */
 
753
    0,                                          /* tp_basicsize */
 
754
    0,                                          /* tp_itemsize */
 
755
    0,                                          /* tp_dealloc */
 
756
    0,                                          /* tp_print */
 
757
    0,                                          /* tp_getattr */
 
758
    0,                                          /* tp_setattr */
 
759
    0,                                          /* tp_reserved */
 
760
    0,                                          /* tp_repr */
 
761
    0,                                          /* tp_as_number */
 
762
    &CDataType_as_sequence,             /* tp_as_sequence */
 
763
    0,                                          /* tp_as_mapping */
 
764
    0,                                          /* tp_hash */
 
765
    0,                                          /* tp_call */
 
766
    0,                                          /* tp_str */
 
767
    0,                                          /* tp_getattro */
 
768
    UnionType_setattro,                         /* tp_setattro */
 
769
    0,                                          /* tp_as_buffer */
 
770
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
 
771
    "metatype for the CData Objects",           /* tp_doc */
 
772
    (traverseproc)CDataType_traverse,           /* tp_traverse */
 
773
    (inquiry)CDataType_clear,                   /* tp_clear */
 
774
    0,                                          /* tp_richcompare */
 
775
    0,                                          /* tp_weaklistoffset */
 
776
    0,                                          /* tp_iter */
 
777
    0,                                          /* tp_iternext */
 
778
    CDataType_methods,                          /* tp_methods */
 
779
    0,                                          /* tp_members */
 
780
    0,                                          /* tp_getset */
 
781
    0,                                          /* tp_base */
 
782
    0,                                          /* tp_dict */
 
783
    0,                                          /* tp_descr_get */
 
784
    0,                                          /* tp_descr_set */
 
785
    0,                                          /* tp_dictoffset */
 
786
    0,                                          /* tp_init */
 
787
    0,                                          /* tp_alloc */
 
788
    UnionType_new,                              /* tp_new */
 
789
    0,                                          /* tp_free */
790
790
};
791
791
 
792
 
 
 
792
 
793
793
/******************************************************************/
794
794
 
795
795
/*
809
809
static int
810
810
PyCPointerType_SetProto(StgDictObject *stgdict, PyObject *proto)
811
811
{
812
 
        if (!proto || !PyType_Check(proto)) {
813
 
                PyErr_SetString(PyExc_TypeError,
814
 
                                "_type_ must be a type");
815
 
                return -1;
816
 
        }
817
 
        if (!PyType_stgdict(proto)) {
818
 
                PyErr_SetString(PyExc_TypeError,
819
 
                                "_type_ must have storage info");
820
 
                return -1;
821
 
        }
822
 
        Py_INCREF(proto);
823
 
        Py_XDECREF(stgdict->proto);
824
 
        stgdict->proto = proto;
825
 
        return 0;
 
812
    if (!proto || !PyType_Check(proto)) {
 
813
        PyErr_SetString(PyExc_TypeError,
 
814
                        "_type_ must be a type");
 
815
        return -1;
 
816
    }
 
817
    if (!PyType_stgdict(proto)) {
 
818
        PyErr_SetString(PyExc_TypeError,
 
819
                        "_type_ must have storage info");
 
820
        return -1;
 
821
    }
 
822
    Py_INCREF(proto);
 
823
    Py_XDECREF(stgdict->proto);
 
824
    stgdict->proto = proto;
 
825
    return 0;
826
826
}
827
827
 
828
828
static PyCArgObject *
829
829
PyCPointerType_paramfunc(CDataObject *self)
830
830
{
831
 
        PyCArgObject *parg;
832
 
 
833
 
        parg = PyCArgObject_new();
834
 
        if (parg == NULL)
835
 
                return NULL;
836
 
 
837
 
        parg->tag = 'P';
838
 
        parg->pffi_type = &ffi_type_pointer;
839
 
        Py_INCREF(self);
840
 
        parg->obj = (PyObject *)self;
841
 
        parg->value.p = *(void **)self->b_ptr;
842
 
        return parg;
 
831
    PyCArgObject *parg;
 
832
 
 
833
    parg = PyCArgObject_new();
 
834
    if (parg == NULL)
 
835
        return NULL;
 
836
 
 
837
    parg->tag = 'P';
 
838
    parg->pffi_type = &ffi_type_pointer;
 
839
    Py_INCREF(self);
 
840
    parg->obj = (PyObject *)self;
 
841
    parg->value.p = *(void **)self->b_ptr;
 
842
    return parg;
843
843
}
844
844
 
845
845
static PyObject *
846
846
PyCPointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
847
847
{
848
 
        PyTypeObject *result;
849
 
        StgDictObject *stgdict;
850
 
        PyObject *proto;
851
 
        PyObject *typedict;
 
848
    PyTypeObject *result;
 
849
    StgDictObject *stgdict;
 
850
    PyObject *proto;
 
851
    PyObject *typedict;
852
852
 
853
 
        typedict = PyTuple_GetItem(args, 2);
854
 
        if (!typedict)
855
 
                return NULL;
 
853
    typedict = PyTuple_GetItem(args, 2);
 
854
    if (!typedict)
 
855
        return NULL;
856
856
/*
857
857
  stgdict items size, align, length contain info about pointers itself,
858
858
  stgdict->proto has info about the pointed to type!
859
859
*/
860
 
        stgdict = (StgDictObject *)PyObject_CallObject(
861
 
                (PyObject *)&PyCStgDict_Type, NULL);
862
 
        if (!stgdict)
863
 
                return NULL;
864
 
        stgdict->size = sizeof(void *);
865
 
        stgdict->align = _ctypes_get_fielddesc("P")->pffi_type->alignment;
866
 
        stgdict->length = 1;
867
 
        stgdict->ffi_type_pointer = ffi_type_pointer;
868
 
        stgdict->paramfunc = PyCPointerType_paramfunc;
869
 
        stgdict->flags |= TYPEFLAG_ISPOINTER;
870
 
 
871
 
        proto = PyDict_GetItemString(typedict, "_type_"); /* Borrowed ref */
872
 
        if (proto && -1 == PyCPointerType_SetProto(stgdict, proto)) {
873
 
                Py_DECREF((PyObject *)stgdict);
874
 
                return NULL;
875
 
        }
876
 
 
877
 
        if (proto) {
878
 
                StgDictObject *itemdict = PyType_stgdict(proto);
879
 
                assert(itemdict);
880
 
                /* If itemdict->format is NULL, then this is a pointer to an
881
 
                   incomplete type.  We create a generic format string
882
 
                   'pointer to bytes' in this case.  XXX Better would be to
883
 
                   fix the format string later...
884
 
                */
885
 
                stgdict->format = _ctypes_alloc_format_string("&",
886
 
                              itemdict->format ? itemdict->format : "B");
887
 
                if (stgdict->format == NULL) {
888
 
                        Py_DECREF((PyObject *)stgdict);
889
 
                        return NULL;
890
 
                }
891
 
        }
892
 
 
893
 
        /* create the new instance (which is a class,
894
 
           since we are a metatype!) */
895
 
        result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
896
 
        if (result == NULL) {
897
 
                Py_DECREF((PyObject *)stgdict);
898
 
                return NULL;
899
 
        }
900
 
 
901
 
        /* replace the class dict by our updated spam dict */
902
 
        if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
903
 
                Py_DECREF(result);
904
 
                Py_DECREF((PyObject *)stgdict);
905
 
                return NULL;
906
 
        }
907
 
        Py_DECREF(result->tp_dict);
908
 
        result->tp_dict = (PyObject *)stgdict;
909
 
 
910
 
        return (PyObject *)result;
 
860
    stgdict = (StgDictObject *)PyObject_CallObject(
 
861
        (PyObject *)&PyCStgDict_Type, NULL);
 
862
    if (!stgdict)
 
863
        return NULL;
 
864
    stgdict->size = sizeof(void *);
 
865
    stgdict->align = _ctypes_get_fielddesc("P")->pffi_type->alignment;
 
866
    stgdict->length = 1;
 
867
    stgdict->ffi_type_pointer = ffi_type_pointer;
 
868
    stgdict->paramfunc = PyCPointerType_paramfunc;
 
869
    stgdict->flags |= TYPEFLAG_ISPOINTER;
 
870
 
 
871
    proto = PyDict_GetItemString(typedict, "_type_"); /* Borrowed ref */
 
872
    if (proto && -1 == PyCPointerType_SetProto(stgdict, proto)) {
 
873
        Py_DECREF((PyObject *)stgdict);
 
874
        return NULL;
 
875
    }
 
876
 
 
877
    if (proto) {
 
878
        StgDictObject *itemdict = PyType_stgdict(proto);
 
879
        assert(itemdict);
 
880
        /* If itemdict->format is NULL, then this is a pointer to an
 
881
           incomplete type.  We create a generic format string
 
882
           'pointer to bytes' in this case.  XXX Better would be to
 
883
           fix the format string later...
 
884
        */
 
885
        stgdict->format = _ctypes_alloc_format_string("&",
 
886
                      itemdict->format ? itemdict->format : "B");
 
887
        if (stgdict->format == NULL) {
 
888
            Py_DECREF((PyObject *)stgdict);
 
889
            return NULL;
 
890
        }
 
891
    }
 
892
 
 
893
    /* create the new instance (which is a class,
 
894
       since we are a metatype!) */
 
895
    result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
 
896
    if (result == NULL) {
 
897
        Py_DECREF((PyObject *)stgdict);
 
898
        return NULL;
 
899
    }
 
900
 
 
901
    /* replace the class dict by our updated spam dict */
 
902
    if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
 
903
        Py_DECREF(result);
 
904
        Py_DECREF((PyObject *)stgdict);
 
905
        return NULL;
 
906
    }
 
907
    Py_DECREF(result->tp_dict);
 
908
    result->tp_dict = (PyObject *)stgdict;
 
909
 
 
910
    return (PyObject *)result;
911
911
}
912
912
 
913
913
 
914
914
static PyObject *
915
915
PyCPointerType_set_type(PyTypeObject *self, PyObject *type)
916
916
{
917
 
        StgDictObject *dict;
918
 
 
919
 
        dict = PyType_stgdict((PyObject *)self);
920
 
        assert(dict);
921
 
 
922
 
        if (-1 == PyCPointerType_SetProto(dict, type))
923
 
                return NULL;
924
 
 
925
 
        if (-1 == PyDict_SetItemString((PyObject *)dict, "_type_", type))
926
 
                return NULL;
927
 
 
928
 
        Py_INCREF(Py_None);
929
 
        return Py_None;
 
917
    StgDictObject *dict;
 
918
 
 
919
    dict = PyType_stgdict((PyObject *)self);
 
920
    assert(dict);
 
921
 
 
922
    if (-1 == PyCPointerType_SetProto(dict, type))
 
923
        return NULL;
 
924
 
 
925
    if (-1 == PyDict_SetItemString((PyObject *)dict, "_type_", type))
 
926
        return NULL;
 
927
 
 
928
    Py_INCREF(Py_None);
 
929
    return Py_None;
930
930
}
931
931
 
932
932
static PyObject *_byref(PyObject *);
934
934
static PyObject *
935
935
PyCPointerType_from_param(PyObject *type, PyObject *value)
936
936
{
937
 
        StgDictObject *typedict;
938
 
 
939
 
        if (value == Py_None) {
940
 
                /* ConvParam will convert to a NULL pointer later */
941
 
                Py_INCREF(value);
942
 
                return value;
943
 
        }
944
 
 
945
 
        typedict = PyType_stgdict(type);
946
 
        assert(typedict); /* Cannot be NULL for pointer types */
947
 
 
948
 
        /* If we expect POINTER(<type>), but receive a <type> instance, accept
949
 
           it by calling byref(<type>).
950
 
        */
951
 
        switch (PyObject_IsInstance(value, typedict->proto)) {
952
 
        case 1:
953
 
                Py_INCREF(value); /* _byref steals a refcount */
954
 
                return _byref(value);
955
 
        case -1:
956
 
                PyErr_Clear();
957
 
                break;
958
 
        default:
959
 
                break;
960
 
        }
961
 
 
962
 
        if (PointerObject_Check(value) || ArrayObject_Check(value)) {
963
 
                /* Array instances are also pointers when
964
 
                   the item types are the same.
965
 
                */
966
 
                StgDictObject *v = PyObject_stgdict(value);
967
 
                assert(v); /* Cannot be NULL for pointer or array objects */
968
 
                if (PyObject_IsSubclass(v->proto, typedict->proto)) {
969
 
                        Py_INCREF(value);
970
 
                        return value;
971
 
                }
972
 
        }
973
 
        return CDataType_from_param(type, value);
 
937
    StgDictObject *typedict;
 
938
 
 
939
    if (value == Py_None) {
 
940
        /* ConvParam will convert to a NULL pointer later */
 
941
        Py_INCREF(value);
 
942
        return value;
 
943
    }
 
944
 
 
945
    typedict = PyType_stgdict(type);
 
946
    assert(typedict); /* Cannot be NULL for pointer types */
 
947
 
 
948
    /* If we expect POINTER(<type>), but receive a <type> instance, accept
 
949
       it by calling byref(<type>).
 
950
    */
 
951
    switch (PyObject_IsInstance(value, typedict->proto)) {
 
952
    case 1:
 
953
        Py_INCREF(value); /* _byref steals a refcount */
 
954
        return _byref(value);
 
955
    case -1:
 
956
        PyErr_Clear();
 
957
        break;
 
958
    default:
 
959
        break;
 
960
    }
 
961
 
 
962
    if (PointerObject_Check(value) || ArrayObject_Check(value)) {
 
963
        /* Array instances are also pointers when
 
964
           the item types are the same.
 
965
        */
 
966
        StgDictObject *v = PyObject_stgdict(value);
 
967
        assert(v); /* Cannot be NULL for pointer or array objects */
 
968
        if (PyObject_IsSubclass(v->proto, typedict->proto)) {
 
969
            Py_INCREF(value);
 
970
            return value;
 
971
        }
 
972
    }
 
973
    return CDataType_from_param(type, value);
974
974
}
975
975
 
976
976
static PyMethodDef PyCPointerType_methods[] = {
977
 
        { "from_address", CDataType_from_address, METH_O, from_address_doc },
978
 
        { "from_buffer", CDataType_from_buffer, METH_VARARGS, from_buffer_doc, },
979
 
        { "from_buffer_copy", CDataType_from_buffer_copy, METH_VARARGS, from_buffer_copy_doc, },
980
 
        { "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc},
981
 
        { "from_param", (PyCFunction)PyCPointerType_from_param, METH_O, from_param_doc},
982
 
        { "set_type", (PyCFunction)PyCPointerType_set_type, METH_O },
983
 
        { NULL, NULL },
 
977
    { "from_address", CDataType_from_address, METH_O, from_address_doc },
 
978
    { "from_buffer", CDataType_from_buffer, METH_VARARGS, from_buffer_doc, },
 
979
    { "from_buffer_copy", CDataType_from_buffer_copy, METH_VARARGS, from_buffer_copy_doc, },
 
980
    { "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc},
 
981
    { "from_param", (PyCFunction)PyCPointerType_from_param, METH_O, from_param_doc},
 
982
    { "set_type", (PyCFunction)PyCPointerType_set_type, METH_O },
 
983
    { NULL, NULL },
984
984
};
985
985
 
986
986
PyTypeObject PyCPointerType_Type = {
987
 
        PyVarObject_HEAD_INIT(NULL, 0)
988
 
        "_ctypes.PyCPointerType",                               /* tp_name */
989
 
        0,                                      /* tp_basicsize */
990
 
        0,                                      /* tp_itemsize */
991
 
        0,                                      /* tp_dealloc */
992
 
        0,                                      /* tp_print */
993
 
        0,                                      /* tp_getattr */
994
 
        0,                                      /* tp_setattr */
995
 
        0,                                      /* tp_reserved */
996
 
        0,                                      /* tp_repr */
997
 
        0,                                      /* tp_as_number */
998
 
        &CDataType_as_sequence,         /* tp_as_sequence */
999
 
        0,                                      /* tp_as_mapping */
1000
 
        0,                                      /* tp_hash */
1001
 
        0,                                      /* tp_call */
1002
 
        0,                                      /* tp_str */
1003
 
        0,                                      /* tp_getattro */
1004
 
        0,                                      /* tp_setattro */
1005
 
        0,                                      /* tp_as_buffer */
1006
 
        Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1007
 
        "metatype for the Pointer Objects",     /* tp_doc */
1008
 
        (traverseproc)CDataType_traverse,       /* tp_traverse */
1009
 
        (inquiry)CDataType_clear,               /* tp_clear */
1010
 
        0,                                      /* tp_richcompare */
1011
 
        0,                                      /* tp_weaklistoffset */
1012
 
        0,                                      /* tp_iter */
1013
 
        0,                                      /* tp_iternext */
1014
 
        PyCPointerType_methods,                 /* tp_methods */
1015
 
        0,                                      /* tp_members */
1016
 
        0,                                      /* tp_getset */
1017
 
        0,                                      /* tp_base */
1018
 
        0,                                      /* tp_dict */
1019
 
        0,                                      /* tp_descr_get */
1020
 
        0,                                      /* tp_descr_set */
1021
 
        0,                                      /* tp_dictoffset */
1022
 
        0,                                      /* tp_init */
1023
 
        0,                                      /* tp_alloc */
1024
 
        PyCPointerType_new,                     /* tp_new */
1025
 
        0,                                      /* tp_free */
 
987
    PyVarObject_HEAD_INIT(NULL, 0)
 
988
    "_ctypes.PyCPointerType",                                   /* tp_name */
 
989
    0,                                          /* tp_basicsize */
 
990
    0,                                          /* tp_itemsize */
 
991
    0,                                          /* tp_dealloc */
 
992
    0,                                          /* tp_print */
 
993
    0,                                          /* tp_getattr */
 
994
    0,                                          /* tp_setattr */
 
995
    0,                                          /* tp_reserved */
 
996
    0,                                          /* tp_repr */
 
997
    0,                                          /* tp_as_number */
 
998
    &CDataType_as_sequence,             /* tp_as_sequence */
 
999
    0,                                          /* tp_as_mapping */
 
1000
    0,                                          /* tp_hash */
 
1001
    0,                                          /* tp_call */
 
1002
    0,                                          /* tp_str */
 
1003
    0,                                          /* tp_getattro */
 
1004
    0,                                          /* tp_setattro */
 
1005
    0,                                          /* tp_as_buffer */
 
1006
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
 
1007
    "metatype for the Pointer Objects",         /* tp_doc */
 
1008
    (traverseproc)CDataType_traverse,           /* tp_traverse */
 
1009
    (inquiry)CDataType_clear,                   /* tp_clear */
 
1010
    0,                                          /* tp_richcompare */
 
1011
    0,                                          /* tp_weaklistoffset */
 
1012
    0,                                          /* tp_iter */
 
1013
    0,                                          /* tp_iternext */
 
1014
    PyCPointerType_methods,                     /* tp_methods */
 
1015
    0,                                          /* tp_members */
 
1016
    0,                                          /* tp_getset */
 
1017
    0,                                          /* tp_base */
 
1018
    0,                                          /* tp_dict */
 
1019
    0,                                          /* tp_descr_get */
 
1020
    0,                                          /* tp_descr_set */
 
1021
    0,                                          /* tp_dictoffset */
 
1022
    0,                                          /* tp_init */
 
1023
    0,                                          /* tp_alloc */
 
1024
    PyCPointerType_new,                         /* tp_new */
 
1025
    0,                                          /* tp_free */
1026
1026
};
1027
1027
 
1028
 
 
 
1028
 
1029
1029
/******************************************************************/
1030
1030
/*
1031
1031
  PyCArrayType_Type
1038
1038
static int
1039
1039
CharArray_set_raw(CDataObject *self, PyObject *value)
1040
1040
{
1041
 
        char *ptr;
1042
 
        Py_ssize_t size;
1043
 
        Py_buffer view;
1044
 
 
1045
 
        if (PyObject_GetBuffer(value, &view, PyBUF_SIMPLE) < 0)
1046
 
                return -1;
1047
 
        size = view.len;
1048
 
        ptr = view.buf;
1049
 
        if (size > self->b_size) {
1050
 
                PyErr_SetString(PyExc_ValueError,
1051
 
                                "string too long");
1052
 
                goto fail;
1053
 
        }
1054
 
 
1055
 
        memcpy(self->b_ptr, ptr, size);
1056
 
 
1057
 
        PyBuffer_Release(&view);
1058
 
        return 0;
 
1041
    char *ptr;
 
1042
    Py_ssize_t size;
 
1043
    Py_buffer view;
 
1044
 
 
1045
    if (PyObject_GetBuffer(value, &view, PyBUF_SIMPLE) < 0)
 
1046
        return -1;
 
1047
    size = view.len;
 
1048
    ptr = view.buf;
 
1049
    if (size > self->b_size) {
 
1050
        PyErr_SetString(PyExc_ValueError,
 
1051
                        "string too long");
 
1052
        goto fail;
 
1053
    }
 
1054
 
 
1055
    memcpy(self->b_ptr, ptr, size);
 
1056
 
 
1057
    PyBuffer_Release(&view);
 
1058
    return 0;
1059
1059
 fail:
1060
 
        PyBuffer_Release(&view);
1061
 
        return -1;
 
1060
    PyBuffer_Release(&view);
 
1061
    return -1;
1062
1062
}
1063
1063
 
1064
1064
static PyObject *
1065
1065
CharArray_get_raw(CDataObject *self)
1066
1066
{
1067
 
        return PyBytes_FromStringAndSize(self->b_ptr, self->b_size);
 
1067
    return PyBytes_FromStringAndSize(self->b_ptr, self->b_size);
1068
1068
}
1069
1069
 
1070
1070
static PyObject *
1071
1071
CharArray_get_value(CDataObject *self)
1072
1072
{
1073
 
        int i;
1074
 
        char *ptr = self->b_ptr;
1075
 
        for (i = 0; i < self->b_size; ++i)
1076
 
                if (*ptr++ == '\0')
1077
 
                        break;
1078
 
        return PyBytes_FromStringAndSize(self->b_ptr, i);
 
1073
    int i;
 
1074
    char *ptr = self->b_ptr;
 
1075
    for (i = 0; i < self->b_size; ++i)
 
1076
        if (*ptr++ == '\0')
 
1077
            break;
 
1078
    return PyBytes_FromStringAndSize(self->b_ptr, i);
1079
1079
}
1080
1080
 
1081
1081
static int
1082
1082
CharArray_set_value(CDataObject *self, PyObject *value)
1083
1083
{
1084
 
        char *ptr;
1085
 
        Py_ssize_t size;
1086
 
 
1087
 
        if (value == NULL) {
1088
 
                PyErr_SetString(PyExc_TypeError,
1089
 
                                "can't delete attribute");
1090
 
                return -1;
1091
 
        }
1092
 
 
1093
 
        if (PyUnicode_Check(value)) {
1094
 
                value = PyUnicode_AsEncodedString(value,
1095
 
                                                  _ctypes_conversion_encoding,
1096
 
                                                  _ctypes_conversion_errors);
1097
 
                if (!value)
1098
 
                        return -1;
1099
 
        } else if (!PyBytes_Check(value)) {
1100
 
                PyErr_Format(PyExc_TypeError,
1101
 
                             "str/bytes expected instead of %s instance",
1102
 
                             Py_TYPE(value)->tp_name);
1103
 
                return -1;
1104
 
        } else
1105
 
                Py_INCREF(value);
1106
 
        size = PyBytes_GET_SIZE(value);
1107
 
        if (size > self->b_size) {
1108
 
                PyErr_SetString(PyExc_ValueError,
1109
 
                                "string too long");
1110
 
                Py_DECREF(value);
1111
 
                return -1;
1112
 
        }
1113
 
 
1114
 
        ptr = PyBytes_AS_STRING(value);
1115
 
        memcpy(self->b_ptr, ptr, size);
1116
 
        if (size < self->b_size)
1117
 
                self->b_ptr[size] = '\0';
1118
 
        Py_DECREF(value);
1119
 
 
1120
 
        return 0;
 
1084
    char *ptr;
 
1085
    Py_ssize_t size;
 
1086
 
 
1087
    if (value == NULL) {
 
1088
        PyErr_SetString(PyExc_TypeError,
 
1089
                        "can't delete attribute");
 
1090
        return -1;
 
1091
    }
 
1092
 
 
1093
    if (PyUnicode_Check(value)) {
 
1094
        value = PyUnicode_AsEncodedString(value,
 
1095
                                          _ctypes_conversion_encoding,
 
1096
                                          _ctypes_conversion_errors);
 
1097
        if (!value)
 
1098
            return -1;
 
1099
    } else if (!PyBytes_Check(value)) {
 
1100
        PyErr_Format(PyExc_TypeError,
 
1101
                     "str/bytes expected instead of %s instance",
 
1102
                     Py_TYPE(value)->tp_name);
 
1103
        return -1;
 
1104
    } else
 
1105
        Py_INCREF(value);
 
1106
    size = PyBytes_GET_SIZE(value);
 
1107
    if (size > self->b_size) {
 
1108
        PyErr_SetString(PyExc_ValueError,
 
1109
                        "string too long");
 
1110
        Py_DECREF(value);
 
1111
        return -1;
 
1112
    }
 
1113
 
 
1114
    ptr = PyBytes_AS_STRING(value);
 
1115
    memcpy(self->b_ptr, ptr, size);
 
1116
    if (size < self->b_size)
 
1117
        self->b_ptr[size] = '\0';
 
1118
    Py_DECREF(value);
 
1119
 
 
1120
    return 0;
1121
1121
}
1122
1122
 
1123
1123
static PyGetSetDef CharArray_getsets[] = {
1124
 
        { "raw", (getter)CharArray_get_raw, (setter)CharArray_set_raw,
1125
 
          "value", NULL },
1126
 
        { "value", (getter)CharArray_get_value, (setter)CharArray_set_value,
1127
 
          "string value"},
1128
 
        { NULL, NULL }
 
1124
    { "raw", (getter)CharArray_get_raw, (setter)CharArray_set_raw,
 
1125
      "value", NULL },
 
1126
    { "value", (getter)CharArray_get_value, (setter)CharArray_set_value,
 
1127
      "string value"},
 
1128
    { NULL, NULL }
1129
1129
};
1130
1130
 
1131
1131
#ifdef CTYPES_UNICODE
1132
1132
static PyObject *
1133
1133
WCharArray_get_value(CDataObject *self)
1134
1134
{
1135
 
        unsigned int i;
1136
 
        wchar_t *ptr = (wchar_t *)self->b_ptr;
1137
 
        for (i = 0; i < self->b_size/sizeof(wchar_t); ++i)
1138
 
                if (*ptr++ == (wchar_t)0)
1139
 
                        break;
1140
 
        return PyUnicode_FromWideChar((wchar_t *)self->b_ptr, i);
 
1135
    unsigned int i;
 
1136
    wchar_t *ptr = (wchar_t *)self->b_ptr;
 
1137
    for (i = 0; i < self->b_size/sizeof(wchar_t); ++i)
 
1138
        if (*ptr++ == (wchar_t)0)
 
1139
            break;
 
1140
    return PyUnicode_FromWideChar((wchar_t *)self->b_ptr, i);
1141
1141
}
1142
1142
 
1143
1143
static int
1144
1144
WCharArray_set_value(CDataObject *self, PyObject *value)
1145
1145
{
1146
 
        Py_ssize_t result = 0;
 
1146
    Py_ssize_t result = 0;
1147
1147
 
1148
 
        if (value == NULL) {
1149
 
                PyErr_SetString(PyExc_TypeError,
1150
 
                                "can't delete attribute");
1151
 
                return -1;
1152
 
        }
1153
 
        if (PyBytes_Check(value)) {
1154
 
                value = PyUnicode_FromEncodedObject(value,
1155
 
                                                    _ctypes_conversion_encoding,
1156
 
                                                    _ctypes_conversion_errors);
1157
 
                if (!value)
1158
 
                        return -1;
1159
 
        } else if (!PyUnicode_Check(value)) {
1160
 
                PyErr_Format(PyExc_TypeError,
1161
 
                                "unicode string expected instead of %s instance",
1162
 
                                Py_TYPE(value)->tp_name);
1163
 
                return -1;
1164
 
        } else
1165
 
                Py_INCREF(value);
1166
 
        if ((unsigned)PyUnicode_GET_SIZE(value) > self->b_size/sizeof(wchar_t)) {
1167
 
                PyErr_SetString(PyExc_ValueError,
1168
 
                                "string too long");
1169
 
                result = -1;
1170
 
                goto done;
1171
 
        }
1172
 
        result = PyUnicode_AsWideChar((PyUnicodeObject *)value,
1173
 
                                      (wchar_t *)self->b_ptr,
1174
 
                                      self->b_size/sizeof(wchar_t));
1175
 
        if (result >= 0 && (size_t)result < self->b_size/sizeof(wchar_t))
1176
 
                ((wchar_t *)self->b_ptr)[result] = (wchar_t)0;
 
1148
    if (value == NULL) {
 
1149
        PyErr_SetString(PyExc_TypeError,
 
1150
                        "can't delete attribute");
 
1151
        return -1;
 
1152
    }
 
1153
    if (PyBytes_Check(value)) {
 
1154
        value = PyUnicode_FromEncodedObject(value,
 
1155
                                            _ctypes_conversion_encoding,
 
1156
                                            _ctypes_conversion_errors);
 
1157
        if (!value)
 
1158
            return -1;
 
1159
    } else if (!PyUnicode_Check(value)) {
 
1160
        PyErr_Format(PyExc_TypeError,
 
1161
                        "unicode string expected instead of %s instance",
 
1162
                        Py_TYPE(value)->tp_name);
 
1163
        return -1;
 
1164
    } else
 
1165
        Py_INCREF(value);
 
1166
    if ((unsigned)PyUnicode_GET_SIZE(value) > self->b_size/sizeof(wchar_t)) {
 
1167
        PyErr_SetString(PyExc_ValueError,
 
1168
                        "string too long");
 
1169
        result = -1;
 
1170
        goto done;
 
1171
    }
 
1172
    result = PyUnicode_AsWideChar((PyUnicodeObject *)value,
 
1173
                                  (wchar_t *)self->b_ptr,
 
1174
                                  self->b_size/sizeof(wchar_t));
 
1175
    if (result >= 0 && (size_t)result < self->b_size/sizeof(wchar_t))
 
1176
        ((wchar_t *)self->b_ptr)[result] = (wchar_t)0;
1177
1177
  done:
1178
 
        Py_DECREF(value);
 
1178
    Py_DECREF(value);
1179
1179
 
1180
 
        return result >= 0 ? 0 : -1;
 
1180
    return result >= 0 ? 0 : -1;
1181
1181
}
1182
1182
 
1183
1183
static PyGetSetDef WCharArray_getsets[] = {
1184
 
        { "value", (getter)WCharArray_get_value, (setter)WCharArray_set_value,
1185
 
          "string value"},
1186
 
        { NULL, NULL }
 
1184
    { "value", (getter)WCharArray_get_value, (setter)WCharArray_set_value,
 
1185
      "string value"},
 
1186
    { NULL, NULL }
1187
1187
};
1188
1188
#endif
1189
1189
 
1198
1198
static int
1199
1199
add_methods(PyTypeObject *type, PyMethodDef *meth)
1200
1200
{
1201
 
        PyObject *dict = type->tp_dict;
1202
 
        for (; meth->ml_name != NULL; meth++) {
1203
 
                PyObject *descr;
1204
 
                descr = PyDescr_NewMethod(type, meth);
1205
 
                if (descr == NULL)
1206
 
                        return -1;
1207
 
                if (PyDict_SetItemString(dict,meth->ml_name, descr) < 0)
1208
 
                        return -1;
1209
 
                Py_DECREF(descr);
1210
 
        }
1211
 
        return 0;
 
1201
    PyObject *dict = type->tp_dict;
 
1202
    for (; meth->ml_name != NULL; meth++) {
 
1203
        PyObject *descr;
 
1204
        descr = PyDescr_NewMethod(type, meth);
 
1205
        if (descr == NULL)
 
1206
            return -1;
 
1207
        if (PyDict_SetItemString(dict,meth->ml_name, descr) < 0)
 
1208
            return -1;
 
1209
        Py_DECREF(descr);
 
1210
    }
 
1211
    return 0;
1212
1212
}
1213
1213
 
1214
1214
static int
1215
1215
add_members(PyTypeObject *type, PyMemberDef *memb)
1216
1216
{
1217
 
        PyObject *dict = type->tp_dict;
1218
 
        for (; memb->name != NULL; memb++) {
1219
 
                PyObject *descr;
1220
 
                descr = PyDescr_NewMember(type, memb);
1221
 
                if (descr == NULL)
1222
 
                        return -1;
1223
 
                if (PyDict_SetItemString(dict, memb->name, descr) < 0)
1224
 
                        return -1;
1225
 
                Py_DECREF(descr);
1226
 
        }
1227
 
        return 0;
 
1217
    PyObject *dict = type->tp_dict;
 
1218
    for (; memb->name != NULL; memb++) {
 
1219
        PyObject *descr;
 
1220
        descr = PyDescr_NewMember(type, memb);
 
1221
        if (descr == NULL)
 
1222
            return -1;
 
1223
        if (PyDict_SetItemString(dict, memb->name, descr) < 0)
 
1224
            return -1;
 
1225
        Py_DECREF(descr);
 
1226
    }
 
1227
    return 0;
1228
1228
}
1229
1229
*/
1230
1230
 
1231
1231
static int
1232
1232
add_getset(PyTypeObject *type, PyGetSetDef *gsp)
1233
1233
{
1234
 
        PyObject *dict = type->tp_dict;
1235
 
        for (; gsp->name != NULL; gsp++) {
1236
 
                PyObject *descr;
1237
 
                descr = PyDescr_NewGetSet(type, gsp);
1238
 
                if (descr == NULL)
1239
 
                        return -1;
1240
 
                if (PyDict_SetItemString(dict, gsp->name, descr) < 0)
1241
 
                        return -1;
1242
 
                Py_DECREF(descr);
1243
 
        }
1244
 
        return 0;
 
1234
    PyObject *dict = type->tp_dict;
 
1235
    for (; gsp->name != NULL; gsp++) {
 
1236
        PyObject *descr;
 
1237
        descr = PyDescr_NewGetSet(type, gsp);
 
1238
        if (descr == NULL)
 
1239
            return -1;
 
1240
        if (PyDict_SetItemString(dict, gsp->name, descr) < 0)
 
1241
            return -1;
 
1242
        Py_DECREF(descr);
 
1243
    }
 
1244
    return 0;
1245
1245
}
1246
1246
 
1247
1247
static PyCArgObject *
1248
1248
PyCArrayType_paramfunc(CDataObject *self)
1249
1249
{
1250
 
        PyCArgObject *p = PyCArgObject_new();
1251
 
        if (p == NULL)
1252
 
                return NULL;
1253
 
        p->tag = 'P';
1254
 
        p->pffi_type = &ffi_type_pointer;
1255
 
        p->value.p = (char *)self->b_ptr;
1256
 
        Py_INCREF(self);
1257
 
        p->obj = (PyObject *)self;
1258
 
        return p;
 
1250
    PyCArgObject *p = PyCArgObject_new();
 
1251
    if (p == NULL)
 
1252
        return NULL;
 
1253
    p->tag = 'P';
 
1254
    p->pffi_type = &ffi_type_pointer;
 
1255
    p->value.p = (char *)self->b_ptr;
 
1256
    Py_INCREF(self);
 
1257
    p->obj = (PyObject *)self;
 
1258
    return p;
1259
1259
}
1260
1260
 
1261
1261
static PyObject *
1262
1262
PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1263
1263
{
1264
 
        PyTypeObject *result;
1265
 
        StgDictObject *stgdict;
1266
 
        StgDictObject *itemdict;
1267
 
        PyObject *proto;
1268
 
        PyObject *typedict;
1269
 
        long length;
1270
 
        int overflow;
1271
 
        Py_ssize_t itemsize, itemalign;
1272
 
        char buf[32];
1273
 
 
1274
 
        typedict = PyTuple_GetItem(args, 2);
1275
 
        if (!typedict)
1276
 
                return NULL;
1277
 
 
1278
 
        proto = PyDict_GetItemString(typedict, "_length_"); /* Borrowed ref */
1279
 
        if (!proto || !PyLong_Check(proto)) {
1280
 
                PyErr_SetString(PyExc_AttributeError,
1281
 
                                "class must define a '_length_' attribute, "
1282
 
                                "which must be a positive integer");
1283
 
                return NULL;
1284
 
        }
1285
 
        length = PyLong_AsLongAndOverflow(proto, &overflow);
1286
 
        if (overflow) {
1287
 
                PyErr_SetString(PyExc_OverflowError,
1288
 
                                "The '_length_' attribute is too large");
1289
 
                return NULL;
1290
 
        }
1291
 
 
1292
 
        proto = PyDict_GetItemString(typedict, "_type_"); /* Borrowed ref */
1293
 
        if (!proto) {
1294
 
                PyErr_SetString(PyExc_AttributeError,
1295
 
                                "class must define a '_type_' attribute");
1296
 
                return NULL;
1297
 
        }
1298
 
 
1299
 
        stgdict = (StgDictObject *)PyObject_CallObject(
1300
 
                (PyObject *)&PyCStgDict_Type, NULL);
1301
 
        if (!stgdict)
1302
 
                return NULL;
1303
 
 
1304
 
        itemdict = PyType_stgdict(proto);
1305
 
        if (!itemdict) {
1306
 
                PyErr_SetString(PyExc_TypeError,
1307
 
                                "_type_ must have storage info");
1308
 
                Py_DECREF((PyObject *)stgdict);
1309
 
                return NULL;
1310
 
        }
1311
 
 
1312
 
        assert(itemdict->format);
1313
 
        if (itemdict->format[0] == '(') {
1314
 
                sprintf(buf, "(%ld,", length);
1315
 
                stgdict->format = _ctypes_alloc_format_string(buf, itemdict->format+1);
1316
 
        } else {
1317
 
                sprintf(buf, "(%ld)", length);
1318
 
                stgdict->format = _ctypes_alloc_format_string(buf, itemdict->format);
1319
 
        }
1320
 
        if (stgdict->format == NULL) {
1321
 
                Py_DECREF((PyObject *)stgdict);
1322
 
                return NULL;
1323
 
        }
1324
 
        stgdict->ndim = itemdict->ndim + 1;
1325
 
        stgdict->shape = PyMem_Malloc(sizeof(Py_ssize_t *) * stgdict->ndim);
1326
 
        if (stgdict->shape == NULL) {
1327
 
                Py_DECREF((PyObject *)stgdict);
1328
 
                return NULL;
1329
 
        }
1330
 
        stgdict->shape[0] = length;
1331
 
        memmove(&stgdict->shape[1], itemdict->shape,
1332
 
                sizeof(Py_ssize_t) * (stgdict->ndim - 1));
1333
 
 
1334
 
        itemsize = itemdict->size;
1335
 
        if (length * itemsize < 0) {
1336
 
                PyErr_SetString(PyExc_OverflowError,
1337
 
                                "array too large");
1338
 
                return NULL;
1339
 
        }
1340
 
 
1341
 
        itemalign = itemdict->align;
1342
 
 
1343
 
        if (itemdict->flags & (TYPEFLAG_ISPOINTER | TYPEFLAG_HASPOINTER))
1344
 
                stgdict->flags |= TYPEFLAG_HASPOINTER;
1345
 
 
1346
 
        stgdict->size = itemsize * length;
1347
 
        stgdict->align = itemalign;
1348
 
        stgdict->length = length;
1349
 
        Py_INCREF(proto);
1350
 
        stgdict->proto = proto;
1351
 
 
1352
 
        stgdict->paramfunc = &PyCArrayType_paramfunc;
1353
 
 
1354
 
        /* Arrays are passed as pointers to function calls. */
1355
 
        stgdict->ffi_type_pointer = ffi_type_pointer;
1356
 
 
1357
 
        /* create the new instance (which is a class,
1358
 
           since we are a metatype!) */
1359
 
        result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
1360
 
        if (result == NULL)
1361
 
                return NULL;
1362
 
 
1363
 
        /* replace the class dict by our updated spam dict */
1364
 
        if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
1365
 
                Py_DECREF(result);
1366
 
                Py_DECREF((PyObject *)stgdict);
1367
 
                return NULL;
1368
 
        }
1369
 
        Py_DECREF(result->tp_dict);
1370
 
        result->tp_dict = (PyObject *)stgdict;
1371
 
 
1372
 
        /* Special case for character arrays.
1373
 
           A permanent annoyance: char arrays are also strings!
1374
 
        */
1375
 
        if (itemdict->getfunc == _ctypes_get_fielddesc("c")->getfunc) {
1376
 
                if (-1 == add_getset(result, CharArray_getsets))
1377
 
                        return NULL;
 
1264
    PyTypeObject *result;
 
1265
    StgDictObject *stgdict;
 
1266
    StgDictObject *itemdict;
 
1267
    PyObject *proto;
 
1268
    PyObject *typedict;
 
1269
    long length;
 
1270
    int overflow;
 
1271
    Py_ssize_t itemsize, itemalign;
 
1272
    char buf[32];
 
1273
 
 
1274
    typedict = PyTuple_GetItem(args, 2);
 
1275
    if (!typedict)
 
1276
        return NULL;
 
1277
 
 
1278
    proto = PyDict_GetItemString(typedict, "_length_"); /* Borrowed ref */
 
1279
    if (!proto || !PyLong_Check(proto)) {
 
1280
        PyErr_SetString(PyExc_AttributeError,
 
1281
                        "class must define a '_length_' attribute, "
 
1282
                        "which must be a positive integer");
 
1283
        return NULL;
 
1284
    }
 
1285
    length = PyLong_AsLongAndOverflow(proto, &overflow);
 
1286
    if (overflow) {
 
1287
        PyErr_SetString(PyExc_OverflowError,
 
1288
                        "The '_length_' attribute is too large");
 
1289
        return NULL;
 
1290
    }
 
1291
 
 
1292
    proto = PyDict_GetItemString(typedict, "_type_"); /* Borrowed ref */
 
1293
    if (!proto) {
 
1294
        PyErr_SetString(PyExc_AttributeError,
 
1295
                        "class must define a '_type_' attribute");
 
1296
        return NULL;
 
1297
    }
 
1298
 
 
1299
    stgdict = (StgDictObject *)PyObject_CallObject(
 
1300
        (PyObject *)&PyCStgDict_Type, NULL);
 
1301
    if (!stgdict)
 
1302
        return NULL;
 
1303
 
 
1304
    itemdict = PyType_stgdict(proto);
 
1305
    if (!itemdict) {
 
1306
        PyErr_SetString(PyExc_TypeError,
 
1307
                        "_type_ must have storage info");
 
1308
        Py_DECREF((PyObject *)stgdict);
 
1309
        return NULL;
 
1310
    }
 
1311
 
 
1312
    assert(itemdict->format);
 
1313
    if (itemdict->format[0] == '(') {
 
1314
        sprintf(buf, "(%ld,", length);
 
1315
        stgdict->format = _ctypes_alloc_format_string(buf, itemdict->format+1);
 
1316
    } else {
 
1317
        sprintf(buf, "(%ld)", length);
 
1318
        stgdict->format = _ctypes_alloc_format_string(buf, itemdict->format);
 
1319
    }
 
1320
    if (stgdict->format == NULL) {
 
1321
        Py_DECREF((PyObject *)stgdict);
 
1322
        return NULL;
 
1323
    }
 
1324
    stgdict->ndim = itemdict->ndim + 1;
 
1325
    stgdict->shape = PyMem_Malloc(sizeof(Py_ssize_t *) * stgdict->ndim);
 
1326
    if (stgdict->shape == NULL) {
 
1327
        Py_DECREF((PyObject *)stgdict);
 
1328
        return NULL;
 
1329
    }
 
1330
    stgdict->shape[0] = length;
 
1331
    memmove(&stgdict->shape[1], itemdict->shape,
 
1332
        sizeof(Py_ssize_t) * (stgdict->ndim - 1));
 
1333
 
 
1334
    itemsize = itemdict->size;
 
1335
    if (length * itemsize < 0) {
 
1336
        PyErr_SetString(PyExc_OverflowError,
 
1337
                        "array too large");
 
1338
        return NULL;
 
1339
    }
 
1340
 
 
1341
    itemalign = itemdict->align;
 
1342
 
 
1343
    if (itemdict->flags & (TYPEFLAG_ISPOINTER | TYPEFLAG_HASPOINTER))
 
1344
        stgdict->flags |= TYPEFLAG_HASPOINTER;
 
1345
 
 
1346
    stgdict->size = itemsize * length;
 
1347
    stgdict->align = itemalign;
 
1348
    stgdict->length = length;
 
1349
    Py_INCREF(proto);
 
1350
    stgdict->proto = proto;
 
1351
 
 
1352
    stgdict->paramfunc = &PyCArrayType_paramfunc;
 
1353
 
 
1354
    /* Arrays are passed as pointers to function calls. */
 
1355
    stgdict->ffi_type_pointer = ffi_type_pointer;
 
1356
 
 
1357
    /* create the new instance (which is a class,
 
1358
       since we are a metatype!) */
 
1359
    result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
 
1360
    if (result == NULL)
 
1361
        return NULL;
 
1362
 
 
1363
    /* replace the class dict by our updated spam dict */
 
1364
    if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
 
1365
        Py_DECREF(result);
 
1366
        Py_DECREF((PyObject *)stgdict);
 
1367
        return NULL;
 
1368
    }
 
1369
    Py_DECREF(result->tp_dict);
 
1370
    result->tp_dict = (PyObject *)stgdict;
 
1371
 
 
1372
    /* Special case for character arrays.
 
1373
       A permanent annoyance: char arrays are also strings!
 
1374
    */
 
1375
    if (itemdict->getfunc == _ctypes_get_fielddesc("c")->getfunc) {
 
1376
        if (-1 == add_getset(result, CharArray_getsets))
 
1377
            return NULL;
1378
1378
#ifdef CTYPES_UNICODE
1379
 
        } else if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) {
1380
 
                if (-1 == add_getset(result, WCharArray_getsets))
1381
 
                        return NULL;
 
1379
    } else if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) {
 
1380
        if (-1 == add_getset(result, WCharArray_getsets))
 
1381
            return NULL;
1382
1382
#endif
1383
 
        }
 
1383
    }
1384
1384
 
1385
 
        return (PyObject *)result;
 
1385
    return (PyObject *)result;
1386
1386
}
1387
1387
 
1388
1388
PyTypeObject PyCArrayType_Type = {
1389
 
        PyVarObject_HEAD_INIT(NULL, 0)
1390
 
        "_ctypes.PyCArrayType",                 /* tp_name */
1391
 
        0,                                      /* tp_basicsize */
1392
 
        0,                                      /* tp_itemsize */
1393
 
        0,                                      /* tp_dealloc */
1394
 
        0,                                      /* tp_print */
1395
 
        0,                                      /* tp_getattr */
1396
 
        0,                                      /* tp_setattr */
1397
 
        0,                                      /* tp_reserved */
1398
 
        0,                                      /* tp_repr */
1399
 
        0,                                      /* tp_as_number */
1400
 
        &CDataType_as_sequence,                 /* tp_as_sequence */
1401
 
        0,                                      /* tp_as_mapping */
1402
 
        0,                                      /* tp_hash */
1403
 
        0,                                      /* tp_call */
1404
 
        0,                                      /* tp_str */
1405
 
        0,                                      /* tp_getattro */
1406
 
        0,                                      /* tp_setattro */
1407
 
        0,                                      /* tp_as_buffer */
1408
 
        Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
1409
 
        "metatype for the Array Objects",       /* tp_doc */
1410
 
        0,                                      /* tp_traverse */
1411
 
        0,                                      /* tp_clear */
1412
 
        0,                                      /* tp_richcompare */
1413
 
        0,                                      /* tp_weaklistoffset */
1414
 
        0,                                      /* tp_iter */
1415
 
        0,                                      /* tp_iternext */
1416
 
        CDataType_methods,                      /* tp_methods */
1417
 
        0,                                      /* tp_members */
1418
 
        0,                                      /* tp_getset */
1419
 
        0,                                      /* tp_base */
1420
 
        0,                                      /* tp_dict */
1421
 
        0,                                      /* tp_descr_get */
1422
 
        0,                                      /* tp_descr_set */
1423
 
        0,                                      /* tp_dictoffset */
1424
 
        0,                                      /* tp_init */
1425
 
        0,                                      /* tp_alloc */
1426
 
        PyCArrayType_new,                               /* tp_new */
1427
 
        0,                                      /* tp_free */
 
1389
    PyVarObject_HEAD_INIT(NULL, 0)
 
1390
    "_ctypes.PyCArrayType",                     /* tp_name */
 
1391
    0,                                          /* tp_basicsize */
 
1392
    0,                                          /* tp_itemsize */
 
1393
    0,                                          /* tp_dealloc */
 
1394
    0,                                          /* tp_print */
 
1395
    0,                                          /* tp_getattr */
 
1396
    0,                                          /* tp_setattr */
 
1397
    0,                                          /* tp_reserved */
 
1398
    0,                                          /* tp_repr */
 
1399
    0,                                          /* tp_as_number */
 
1400
    &CDataType_as_sequence,                     /* tp_as_sequence */
 
1401
    0,                                          /* tp_as_mapping */
 
1402
    0,                                          /* tp_hash */
 
1403
    0,                                          /* tp_call */
 
1404
    0,                                          /* tp_str */
 
1405
    0,                                          /* tp_getattro */
 
1406
    0,                                          /* tp_setattro */
 
1407
    0,                                          /* tp_as_buffer */
 
1408
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
 
1409
    "metatype for the Array Objects",           /* tp_doc */
 
1410
    0,                                          /* tp_traverse */
 
1411
    0,                                          /* tp_clear */
 
1412
    0,                                          /* tp_richcompare */
 
1413
    0,                                          /* tp_weaklistoffset */
 
1414
    0,                                          /* tp_iter */
 
1415
    0,                                          /* tp_iternext */
 
1416
    CDataType_methods,                          /* tp_methods */
 
1417
    0,                                          /* tp_members */
 
1418
    0,                                          /* tp_getset */
 
1419
    0,                                          /* tp_base */
 
1420
    0,                                          /* tp_dict */
 
1421
    0,                                          /* tp_descr_get */
 
1422
    0,                                          /* tp_descr_set */
 
1423
    0,                                          /* tp_dictoffset */
 
1424
    0,                                          /* tp_init */
 
1425
    0,                                          /* tp_alloc */
 
1426
    PyCArrayType_new,                                   /* tp_new */
 
1427
    0,                                          /* tp_free */
1428
1428
};
1429
1429
 
1430
 
 
 
1430
 
1431
1431
/******************************************************************/
1432
1432
/*
1433
1433
  PyCSimpleType_Type
1444
1444
static PyObject *
1445
1445
c_wchar_p_from_param(PyObject *type, PyObject *value)
1446
1446
{
1447
 
        PyObject *as_parameter;
1448
 
        if (value == Py_None) {
1449
 
                Py_INCREF(Py_None);
1450
 
                return Py_None;
1451
 
        }
1452
 
        if (PyUnicode_Check(value) || PyBytes_Check(value)) {
1453
 
                PyCArgObject *parg;
1454
 
                struct fielddesc *fd = _ctypes_get_fielddesc("Z");
1455
 
 
1456
 
                parg = PyCArgObject_new();
1457
 
                if (parg == NULL)
1458
 
                        return NULL;
1459
 
                parg->pffi_type = &ffi_type_pointer;
1460
 
                parg->tag = 'Z';
1461
 
                parg->obj = fd->setfunc(&parg->value, value, 0);
1462
 
                if (parg->obj == NULL) {
1463
 
                        Py_DECREF(parg);
1464
 
                        return NULL;
1465
 
                }
1466
 
                return (PyObject *)parg;
1467
 
        }
1468
 
        if (PyObject_IsInstance(value, type)) {
1469
 
                Py_INCREF(value);
1470
 
                return value;
1471
 
        }
1472
 
        if (ArrayObject_Check(value) || PointerObject_Check(value)) {
1473
 
                /* c_wchar array instance or pointer(c_wchar(...)) */
1474
 
                StgDictObject *dt = PyObject_stgdict(value);
1475
 
                StgDictObject *dict;
1476
 
                assert(dt); /* Cannot be NULL for pointer or array objects */
1477
 
                dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL;
1478
 
                if (dict && (dict->setfunc == _ctypes_get_fielddesc("u")->setfunc)) {
1479
 
                        Py_INCREF(value);
1480
 
                        return value;
1481
 
                }
1482
 
        }
1483
 
        if (PyCArg_CheckExact(value)) {
1484
 
                /* byref(c_char(...)) */
1485
 
                PyCArgObject *a = (PyCArgObject *)value;
1486
 
                StgDictObject *dict = PyObject_stgdict(a->obj);
1487
 
                if (dict && (dict->setfunc == _ctypes_get_fielddesc("u")->setfunc)) {
1488
 
                        Py_INCREF(value);
1489
 
                        return value;
1490
 
                }
1491
 
        }
1492
 
 
1493
 
        as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
1494
 
        if (as_parameter) {
1495
 
                value = c_wchar_p_from_param(type, as_parameter);
1496
 
                Py_DECREF(as_parameter);
1497
 
                return value;
1498
 
        }
1499
 
        /* XXX better message */
1500
 
        PyErr_SetString(PyExc_TypeError,
1501
 
                        "wrong type");
1502
 
        return NULL;
 
1447
    PyObject *as_parameter;
 
1448
    if (value == Py_None) {
 
1449
        Py_INCREF(Py_None);
 
1450
        return Py_None;
 
1451
    }
 
1452
    if (PyUnicode_Check(value) || PyBytes_Check(value)) {
 
1453
        PyCArgObject *parg;
 
1454
        struct fielddesc *fd = _ctypes_get_fielddesc("Z");
 
1455
 
 
1456
        parg = PyCArgObject_new();
 
1457
        if (parg == NULL)
 
1458
            return NULL;
 
1459
        parg->pffi_type = &ffi_type_pointer;
 
1460
        parg->tag = 'Z';
 
1461
        parg->obj = fd->setfunc(&parg->value, value, 0);
 
1462
        if (parg->obj == NULL) {
 
1463
            Py_DECREF(parg);
 
1464
            return NULL;
 
1465
        }
 
1466
        return (PyObject *)parg;
 
1467
    }
 
1468
    if (PyObject_IsInstance(value, type)) {
 
1469
        Py_INCREF(value);
 
1470
        return value;
 
1471
    }
 
1472
    if (ArrayObject_Check(value) || PointerObject_Check(value)) {
 
1473
        /* c_wchar array instance or pointer(c_wchar(...)) */
 
1474
        StgDictObject *dt = PyObject_stgdict(value);
 
1475
        StgDictObject *dict;
 
1476
        assert(dt); /* Cannot be NULL for pointer or array objects */
 
1477
        dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL;
 
1478
        if (dict && (dict->setfunc == _ctypes_get_fielddesc("u")->setfunc)) {
 
1479
            Py_INCREF(value);
 
1480
            return value;
 
1481
        }
 
1482
    }
 
1483
    if (PyCArg_CheckExact(value)) {
 
1484
        /* byref(c_char(...)) */
 
1485
        PyCArgObject *a = (PyCArgObject *)value;
 
1486
        StgDictObject *dict = PyObject_stgdict(a->obj);
 
1487
        if (dict && (dict->setfunc == _ctypes_get_fielddesc("u")->setfunc)) {
 
1488
            Py_INCREF(value);
 
1489
            return value;
 
1490
        }
 
1491
    }
 
1492
 
 
1493
    as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
 
1494
    if (as_parameter) {
 
1495
        value = c_wchar_p_from_param(type, as_parameter);
 
1496
        Py_DECREF(as_parameter);
 
1497
        return value;
 
1498
    }
 
1499
    /* XXX better message */
 
1500
    PyErr_SetString(PyExc_TypeError,
 
1501
                    "wrong type");
 
1502
    return NULL;
1503
1503
}
1504
1504
 
1505
1505
static PyObject *
1506
1506
c_char_p_from_param(PyObject *type, PyObject *value)
1507
1507
{
1508
 
        PyObject *as_parameter;
1509
 
        if (value == Py_None) {
1510
 
                Py_INCREF(Py_None);
1511
 
                return Py_None;
1512
 
        }
1513
 
        if (PyBytes_Check(value) || PyUnicode_Check(value)) {
1514
 
                PyCArgObject *parg;
1515
 
                struct fielddesc *fd = _ctypes_get_fielddesc("z");
1516
 
 
1517
 
                parg = PyCArgObject_new();
1518
 
                if (parg == NULL)
1519
 
                        return NULL;
1520
 
                parg->pffi_type = &ffi_type_pointer;
1521
 
                parg->tag = 'z';
1522
 
                parg->obj = fd->setfunc(&parg->value, value, 0);
1523
 
                if (parg->obj == NULL) {
1524
 
                        Py_DECREF(parg);
1525
 
                        return NULL;
1526
 
                }
1527
 
                return (PyObject *)parg;
1528
 
        }
1529
 
        if (PyObject_IsInstance(value, type)) {
1530
 
                Py_INCREF(value);
1531
 
                return value;
1532
 
        }
1533
 
        if (ArrayObject_Check(value) || PointerObject_Check(value)) {
1534
 
                /* c_char array instance or pointer(c_char(...)) */
1535
 
                StgDictObject *dt = PyObject_stgdict(value);
1536
 
                StgDictObject *dict;
1537
 
                assert(dt); /* Cannot be NULL for pointer or array objects */
1538
 
                dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL;
1539
 
                if (dict && (dict->setfunc == _ctypes_get_fielddesc("c")->setfunc)) {
1540
 
                        Py_INCREF(value);
1541
 
                        return value;
1542
 
                }
1543
 
        }
1544
 
        if (PyCArg_CheckExact(value)) {
1545
 
                /* byref(c_char(...)) */
1546
 
                PyCArgObject *a = (PyCArgObject *)value;
1547
 
                StgDictObject *dict = PyObject_stgdict(a->obj);
1548
 
                if (dict && (dict->setfunc == _ctypes_get_fielddesc("c")->setfunc)) {
1549
 
                        Py_INCREF(value);
1550
 
                        return value;
1551
 
                }
1552
 
        }
1553
 
 
1554
 
        as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
1555
 
        if (as_parameter) {
1556
 
                value = c_char_p_from_param(type, as_parameter);
1557
 
                Py_DECREF(as_parameter);
1558
 
                return value;
1559
 
        }
1560
 
        /* XXX better message */
1561
 
        PyErr_SetString(PyExc_TypeError,
1562
 
                        "wrong type");
1563
 
        return NULL;
 
1508
    PyObject *as_parameter;
 
1509
    if (value == Py_None) {
 
1510
        Py_INCREF(Py_None);
 
1511
        return Py_None;
 
1512
    }
 
1513
    if (PyBytes_Check(value) || PyUnicode_Check(value)) {
 
1514
        PyCArgObject *parg;
 
1515
        struct fielddesc *fd = _ctypes_get_fielddesc("z");
 
1516
 
 
1517
        parg = PyCArgObject_new();
 
1518
        if (parg == NULL)
 
1519
            return NULL;
 
1520
        parg->pffi_type = &ffi_type_pointer;
 
1521
        parg->tag = 'z';
 
1522
        parg->obj = fd->setfunc(&parg->value, value, 0);
 
1523
        if (parg->obj == NULL) {
 
1524
            Py_DECREF(parg);
 
1525
            return NULL;
 
1526
        }
 
1527
        return (PyObject *)parg;
 
1528
    }
 
1529
    if (PyObject_IsInstance(value, type)) {
 
1530
        Py_INCREF(value);
 
1531
        return value;
 
1532
    }
 
1533
    if (ArrayObject_Check(value) || PointerObject_Check(value)) {
 
1534
        /* c_char array instance or pointer(c_char(...)) */
 
1535
        StgDictObject *dt = PyObject_stgdict(value);
 
1536
        StgDictObject *dict;
 
1537
        assert(dt); /* Cannot be NULL for pointer or array objects */
 
1538
        dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL;
 
1539
        if (dict && (dict->setfunc == _ctypes_get_fielddesc("c")->setfunc)) {
 
1540
            Py_INCREF(value);
 
1541
            return value;
 
1542
        }
 
1543
    }
 
1544
    if (PyCArg_CheckExact(value)) {
 
1545
        /* byref(c_char(...)) */
 
1546
        PyCArgObject *a = (PyCArgObject *)value;
 
1547
        StgDictObject *dict = PyObject_stgdict(a->obj);
 
1548
        if (dict && (dict->setfunc == _ctypes_get_fielddesc("c")->setfunc)) {
 
1549
            Py_INCREF(value);
 
1550
            return value;
 
1551
        }
 
1552
    }
 
1553
 
 
1554
    as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
 
1555
    if (as_parameter) {
 
1556
        value = c_char_p_from_param(type, as_parameter);
 
1557
        Py_DECREF(as_parameter);
 
1558
        return value;
 
1559
    }
 
1560
    /* XXX better message */
 
1561
    PyErr_SetString(PyExc_TypeError,
 
1562
                    "wrong type");
 
1563
    return NULL;
1564
1564
}
1565
1565
 
1566
1566
static PyObject *
1567
1567
c_void_p_from_param(PyObject *type, PyObject *value)
1568
1568
{
1569
 
        StgDictObject *stgd;
1570
 
        PyObject *as_parameter;
 
1569
    StgDictObject *stgd;
 
1570
    PyObject *as_parameter;
1571
1571
 
1572
1572
/* None */
1573
 
        if (value == Py_None) {
1574
 
                Py_INCREF(Py_None);
1575
 
                return Py_None;
1576
 
        }
1577
 
        /* Should probably allow buffer interface as well */
 
1573
    if (value == Py_None) {
 
1574
        Py_INCREF(Py_None);
 
1575
        return Py_None;
 
1576
    }
 
1577
    /* Should probably allow buffer interface as well */
1578
1578
/* int, long */
1579
 
        if (PyLong_Check(value)) {
1580
 
                PyCArgObject *parg;
1581
 
                struct fielddesc *fd = _ctypes_get_fielddesc("P");
 
1579
    if (PyLong_Check(value)) {
 
1580
        PyCArgObject *parg;
 
1581
        struct fielddesc *fd = _ctypes_get_fielddesc("P");
1582
1582
 
1583
 
                parg = PyCArgObject_new();
1584
 
                if (parg == NULL)
1585
 
                        return NULL;
1586
 
                parg->pffi_type = &ffi_type_pointer;
1587
 
                parg->tag = 'P';
1588
 
                parg->obj = fd->setfunc(&parg->value, value, 0);
1589
 
                if (parg->obj == NULL) {
1590
 
                        Py_DECREF(parg);
1591
 
                        return NULL;
1592
 
                }
1593
 
                return (PyObject *)parg;
1594
 
        }
1595
 
        /* XXX struni: remove later */
 
1583
        parg = PyCArgObject_new();
 
1584
        if (parg == NULL)
 
1585
            return NULL;
 
1586
        parg->pffi_type = &ffi_type_pointer;
 
1587
        parg->tag = 'P';
 
1588
        parg->obj = fd->setfunc(&parg->value, value, 0);
 
1589
        if (parg->obj == NULL) {
 
1590
            Py_DECREF(parg);
 
1591
            return NULL;
 
1592
        }
 
1593
        return (PyObject *)parg;
 
1594
    }
 
1595
    /* XXX struni: remove later */
1596
1596
/* string */
1597
 
        if (PyBytes_Check(value)) {
1598
 
                PyCArgObject *parg;
1599
 
                struct fielddesc *fd = _ctypes_get_fielddesc("z");
 
1597
    if (PyBytes_Check(value)) {
 
1598
        PyCArgObject *parg;
 
1599
        struct fielddesc *fd = _ctypes_get_fielddesc("z");
1600
1600
 
1601
 
                parg = PyCArgObject_new();
1602
 
                if (parg == NULL)
1603
 
                        return NULL;
1604
 
                parg->pffi_type = &ffi_type_pointer;
1605
 
                parg->tag = 'z';
1606
 
                parg->obj = fd->setfunc(&parg->value, value, 0);
1607
 
                if (parg->obj == NULL) {
1608
 
                        Py_DECREF(parg);
1609
 
                        return NULL;
1610
 
                }
1611
 
                return (PyObject *)parg;
1612
 
        }
 
1601
        parg = PyCArgObject_new();
 
1602
        if (parg == NULL)
 
1603
            return NULL;
 
1604
        parg->pffi_type = &ffi_type_pointer;
 
1605
        parg->tag = 'z';
 
1606
        parg->obj = fd->setfunc(&parg->value, value, 0);
 
1607
        if (parg->obj == NULL) {
 
1608
            Py_DECREF(parg);
 
1609
            return NULL;
 
1610
        }
 
1611
        return (PyObject *)parg;
 
1612
    }
1613
1613
/* bytes */
1614
 
        if (PyByteArray_Check(value)) {
1615
 
                PyCArgObject *parg;
1616
 
                struct fielddesc *fd = _ctypes_get_fielddesc("z");
 
1614
    if (PyByteArray_Check(value)) {
 
1615
        PyCArgObject *parg;
 
1616
        struct fielddesc *fd = _ctypes_get_fielddesc("z");
1617
1617
 
1618
 
                parg = PyCArgObject_new();
1619
 
                if (parg == NULL)
1620
 
                        return NULL;
1621
 
                parg->pffi_type = &ffi_type_pointer;
1622
 
                parg->tag = 'z';
1623
 
                parg->obj = fd->setfunc(&parg->value, value, 0);
1624
 
                if (parg->obj == NULL) {
1625
 
                        Py_DECREF(parg);
1626
 
                        return NULL;
1627
 
                }
1628
 
                return (PyObject *)parg;
1629
 
        }
 
1618
        parg = PyCArgObject_new();
 
1619
        if (parg == NULL)
 
1620
            return NULL;
 
1621
        parg->pffi_type = &ffi_type_pointer;
 
1622
        parg->tag = 'z';
 
1623
        parg->obj = fd->setfunc(&parg->value, value, 0);
 
1624
        if (parg->obj == NULL) {
 
1625
            Py_DECREF(parg);
 
1626
            return NULL;
 
1627
        }
 
1628
        return (PyObject *)parg;
 
1629
    }
1630
1630
/* unicode */
1631
 
        if (PyUnicode_Check(value)) {
1632
 
                PyCArgObject *parg;
1633
 
                struct fielddesc *fd = _ctypes_get_fielddesc("Z");
 
1631
    if (PyUnicode_Check(value)) {
 
1632
        PyCArgObject *parg;
 
1633
        struct fielddesc *fd = _ctypes_get_fielddesc("Z");
1634
1634
 
1635
 
                parg = PyCArgObject_new();
1636
 
                if (parg == NULL)
1637
 
                        return NULL;
1638
 
                parg->pffi_type = &ffi_type_pointer;
1639
 
                parg->tag = 'Z';
1640
 
                parg->obj = fd->setfunc(&parg->value, value, 0);
1641
 
                if (parg->obj == NULL) {
1642
 
                        Py_DECREF(parg);
1643
 
                        return NULL;
1644
 
                }
1645
 
                return (PyObject *)parg;
1646
 
        }
 
1635
        parg = PyCArgObject_new();
 
1636
        if (parg == NULL)
 
1637
            return NULL;
 
1638
        parg->pffi_type = &ffi_type_pointer;
 
1639
        parg->tag = 'Z';
 
1640
        parg->obj = fd->setfunc(&parg->value, value, 0);
 
1641
        if (parg->obj == NULL) {
 
1642
            Py_DECREF(parg);
 
1643
            return NULL;
 
1644
        }
 
1645
        return (PyObject *)parg;
 
1646
    }
1647
1647
/* c_void_p instance (or subclass) */
1648
 
        if (PyObject_IsInstance(value, type)) {
1649
 
                /* c_void_p instances */
1650
 
                Py_INCREF(value);
1651
 
                return value;
1652
 
        }
 
1648
    if (PyObject_IsInstance(value, type)) {
 
1649
        /* c_void_p instances */
 
1650
        Py_INCREF(value);
 
1651
        return value;
 
1652
    }
1653
1653
/* ctypes array or pointer instance */
1654
 
        if (ArrayObject_Check(value) || PointerObject_Check(value)) {
1655
 
                /* Any array or pointer is accepted */
1656
 
                Py_INCREF(value);
1657
 
                return value;
1658
 
        }
 
1654
    if (ArrayObject_Check(value) || PointerObject_Check(value)) {
 
1655
        /* Any array or pointer is accepted */
 
1656
        Py_INCREF(value);
 
1657
        return value;
 
1658
    }
1659
1659
/* byref(...) */
1660
 
        if (PyCArg_CheckExact(value)) {
1661
 
                /* byref(c_xxx()) */
1662
 
                PyCArgObject *a = (PyCArgObject *)value;
1663
 
                if (a->tag == 'P') {
1664
 
                        Py_INCREF(value);
1665
 
                        return value;
1666
 
                }
1667
 
        }
 
1660
    if (PyCArg_CheckExact(value)) {
 
1661
        /* byref(c_xxx()) */
 
1662
        PyCArgObject *a = (PyCArgObject *)value;
 
1663
        if (a->tag == 'P') {
 
1664
            Py_INCREF(value);
 
1665
            return value;
 
1666
        }
 
1667
    }
1668
1668
/* function pointer */
1669
 
        if (PyCFuncPtrObject_Check(value)) {
1670
 
                PyCArgObject *parg;
1671
 
                PyCFuncPtrObject *func;
1672
 
                func = (PyCFuncPtrObject *)value;
1673
 
                parg = PyCArgObject_new();
1674
 
                if (parg == NULL)
1675
 
                        return NULL;
1676
 
                parg->pffi_type = &ffi_type_pointer;
1677
 
                parg->tag = 'P';
1678
 
                Py_INCREF(value);
1679
 
                parg->value.p = *(void **)func->b_ptr;
1680
 
                parg->obj = value;
1681
 
                return (PyObject *)parg;
1682
 
        }
 
1669
    if (PyCFuncPtrObject_Check(value)) {
 
1670
        PyCArgObject *parg;
 
1671
        PyCFuncPtrObject *func;
 
1672
        func = (PyCFuncPtrObject *)value;
 
1673
        parg = PyCArgObject_new();
 
1674
        if (parg == NULL)
 
1675
            return NULL;
 
1676
        parg->pffi_type = &ffi_type_pointer;
 
1677
        parg->tag = 'P';
 
1678
        Py_INCREF(value);
 
1679
        parg->value.p = *(void **)func->b_ptr;
 
1680
        parg->obj = value;
 
1681
        return (PyObject *)parg;
 
1682
    }
1683
1683
/* c_char_p, c_wchar_p */
1684
 
        stgd = PyObject_stgdict(value);
1685
 
        if (stgd && CDataObject_Check(value) && stgd->proto && PyUnicode_Check(stgd->proto)) {
1686
 
                PyCArgObject *parg;
1687
 
 
1688
 
                switch (_PyUnicode_AsString(stgd->proto)[0]) {
1689
 
                case 'z': /* c_char_p */
1690
 
                case 'Z': /* c_wchar_p */
1691
 
                        parg = PyCArgObject_new();
1692
 
                        if (parg == NULL)
1693
 
                                return NULL;
1694
 
                        parg->pffi_type = &ffi_type_pointer;
1695
 
                        parg->tag = 'Z';
1696
 
                        Py_INCREF(value);
1697
 
                        parg->obj = value;
1698
 
                        /* Remember: b_ptr points to where the pointer is stored! */
1699
 
                        parg->value.p = *(void **)(((CDataObject *)value)->b_ptr);
1700
 
                        return (PyObject *)parg;
1701
 
                }
1702
 
        }
1703
 
 
1704
 
        as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
1705
 
        if (as_parameter) {
1706
 
                value = c_void_p_from_param(type, as_parameter);
1707
 
                Py_DECREF(as_parameter);
1708
 
                return value;
1709
 
        }
1710
 
        /* XXX better message */
1711
 
        PyErr_SetString(PyExc_TypeError,
1712
 
                        "wrong type");
1713
 
        return NULL;
 
1684
    stgd = PyObject_stgdict(value);
 
1685
    if (stgd && CDataObject_Check(value) && stgd->proto && PyUnicode_Check(stgd->proto)) {
 
1686
        PyCArgObject *parg;
 
1687
 
 
1688
        switch (_PyUnicode_AsString(stgd->proto)[0]) {
 
1689
        case 'z': /* c_char_p */
 
1690
        case 'Z': /* c_wchar_p */
 
1691
            parg = PyCArgObject_new();
 
1692
            if (parg == NULL)
 
1693
                return NULL;
 
1694
            parg->pffi_type = &ffi_type_pointer;
 
1695
            parg->tag = 'Z';
 
1696
            Py_INCREF(value);
 
1697
            parg->obj = value;
 
1698
            /* Remember: b_ptr points to where the pointer is stored! */
 
1699
            parg->value.p = *(void **)(((CDataObject *)value)->b_ptr);
 
1700
            return (PyObject *)parg;
 
1701
        }
 
1702
    }
 
1703
 
 
1704
    as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
 
1705
    if (as_parameter) {
 
1706
        value = c_void_p_from_param(type, as_parameter);
 
1707
        Py_DECREF(as_parameter);
 
1708
        return value;
 
1709
    }
 
1710
    /* XXX better message */
 
1711
    PyErr_SetString(PyExc_TypeError,
 
1712
                    "wrong type");
 
1713
    return NULL;
1714
1714
}
1715
1715
 
1716
1716
static PyMethodDef c_void_p_method = { "from_param", c_void_p_from_param, METH_O };
1718
1718
static PyMethodDef c_wchar_p_method = { "from_param", c_wchar_p_from_param, METH_O };
1719
1719
 
1720
1720
static PyObject *CreateSwappedType(PyTypeObject *type, PyObject *args, PyObject *kwds,
1721
 
                                   PyObject *proto, struct fielddesc *fmt)
 
1721
                                   PyObject *proto, struct fielddesc *fmt)
1722
1722
{
1723
 
        PyTypeObject *result;
1724
 
        StgDictObject *stgdict;
1725
 
        PyObject *name = PyTuple_GET_ITEM(args, 0);
1726
 
        PyObject *newname;
1727
 
        PyObject *swapped_args;
1728
 
        static PyObject *suffix;
1729
 
        Py_ssize_t i;
1730
 
 
1731
 
        swapped_args = PyTuple_New(PyTuple_GET_SIZE(args));
1732
 
        if (!swapped_args)
1733
 
                return NULL;
1734
 
 
1735
 
        if (suffix == NULL)
 
1723
    PyTypeObject *result;
 
1724
    StgDictObject *stgdict;
 
1725
    PyObject *name = PyTuple_GET_ITEM(args, 0);
 
1726
    PyObject *newname;
 
1727
    PyObject *swapped_args;
 
1728
    static PyObject *suffix;
 
1729
    Py_ssize_t i;
 
1730
 
 
1731
    swapped_args = PyTuple_New(PyTuple_GET_SIZE(args));
 
1732
    if (!swapped_args)
 
1733
        return NULL;
 
1734
 
 
1735
    if (suffix == NULL)
1736
1736
#ifdef WORDS_BIGENDIAN
1737
 
                suffix = PyUnicode_InternFromString("_le");
 
1737
        suffix = PyUnicode_InternFromString("_le");
1738
1738
#else
1739
 
                suffix = PyUnicode_InternFromString("_be");
 
1739
        suffix = PyUnicode_InternFromString("_be");
1740
1740
#endif
1741
1741
 
1742
 
        newname = PyUnicode_Concat(name, suffix);
1743
 
        if (newname == NULL) {
1744
 
                return NULL;
1745
 
        }
1746
 
 
1747
 
        PyTuple_SET_ITEM(swapped_args, 0, newname);
1748
 
        for (i=1; i<PyTuple_GET_SIZE(args); ++i) {
1749
 
                PyObject *v = PyTuple_GET_ITEM(args, i);
1750
 
                Py_INCREF(v);
1751
 
                PyTuple_SET_ITEM(swapped_args, i, v);
1752
 
        }
1753
 
 
1754
 
        /* create the new instance (which is a class,
1755
 
           since we are a metatype!) */
1756
 
        result = (PyTypeObject *)PyType_Type.tp_new(type, swapped_args, kwds);
1757
 
        Py_DECREF(swapped_args);
1758
 
        if (result == NULL)
1759
 
                return NULL;
1760
 
 
1761
 
        stgdict = (StgDictObject *)PyObject_CallObject(
1762
 
                (PyObject *)&PyCStgDict_Type, NULL);
1763
 
        if (!stgdict) /* XXX leaks result! */
1764
 
                return NULL;
1765
 
 
1766
 
        stgdict->ffi_type_pointer = *fmt->pffi_type;
1767
 
        stgdict->align = fmt->pffi_type->alignment;
1768
 
        stgdict->length = 0;
1769
 
        stgdict->size = fmt->pffi_type->size;
1770
 
        stgdict->setfunc = fmt->setfunc_swapped;
1771
 
        stgdict->getfunc = fmt->getfunc_swapped;
1772
 
 
1773
 
        Py_INCREF(proto);
1774
 
        stgdict->proto = proto;
1775
 
 
1776
 
        /* replace the class dict by our updated spam dict */
1777
 
        if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
1778
 
                Py_DECREF(result);
1779
 
                Py_DECREF((PyObject *)stgdict);
1780
 
                return NULL;
1781
 
        }
1782
 
        Py_DECREF(result->tp_dict);
1783
 
        result->tp_dict = (PyObject *)stgdict;
1784
 
 
1785
 
        return (PyObject *)result;
 
1742
    newname = PyUnicode_Concat(name, suffix);
 
1743
    if (newname == NULL) {
 
1744
        return NULL;
 
1745
    }
 
1746
 
 
1747
    PyTuple_SET_ITEM(swapped_args, 0, newname);
 
1748
    for (i=1; i<PyTuple_GET_SIZE(args); ++i) {
 
1749
        PyObject *v = PyTuple_GET_ITEM(args, i);
 
1750
        Py_INCREF(v);
 
1751
        PyTuple_SET_ITEM(swapped_args, i, v);
 
1752
    }
 
1753
 
 
1754
    /* create the new instance (which is a class,
 
1755
       since we are a metatype!) */
 
1756
    result = (PyTypeObject *)PyType_Type.tp_new(type, swapped_args, kwds);
 
1757
    Py_DECREF(swapped_args);
 
1758
    if (result == NULL)
 
1759
        return NULL;
 
1760
 
 
1761
    stgdict = (StgDictObject *)PyObject_CallObject(
 
1762
        (PyObject *)&PyCStgDict_Type, NULL);
 
1763
    if (!stgdict) /* XXX leaks result! */
 
1764
        return NULL;
 
1765
 
 
1766
    stgdict->ffi_type_pointer = *fmt->pffi_type;
 
1767
    stgdict->align = fmt->pffi_type->alignment;
 
1768
    stgdict->length = 0;
 
1769
    stgdict->size = fmt->pffi_type->size;
 
1770
    stgdict->setfunc = fmt->setfunc_swapped;
 
1771
    stgdict->getfunc = fmt->getfunc_swapped;
 
1772
 
 
1773
    Py_INCREF(proto);
 
1774
    stgdict->proto = proto;
 
1775
 
 
1776
    /* replace the class dict by our updated spam dict */
 
1777
    if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
 
1778
        Py_DECREF(result);
 
1779
        Py_DECREF((PyObject *)stgdict);
 
1780
        return NULL;
 
1781
    }
 
1782
    Py_DECREF(result->tp_dict);
 
1783
    result->tp_dict = (PyObject *)stgdict;
 
1784
 
 
1785
    return (PyObject *)result;
1786
1786
}
1787
1787
 
1788
1788
static PyCArgObject *
1789
1789
PyCSimpleType_paramfunc(CDataObject *self)
1790
1790
{
1791
 
        StgDictObject *dict;
1792
 
        char *fmt;
1793
 
        PyCArgObject *parg;
1794
 
        struct fielddesc *fd;
1795
 
        
1796
 
        dict = PyObject_stgdict((PyObject *)self);
1797
 
        assert(dict); /* Cannot be NULL for CDataObject instances */
1798
 
        fmt = _PyUnicode_AsString(dict->proto);
1799
 
        assert(fmt);
1800
 
 
1801
 
        fd = _ctypes_get_fielddesc(fmt);
1802
 
        assert(fd);
1803
 
        
1804
 
        parg = PyCArgObject_new();
1805
 
        if (parg == NULL)
1806
 
                return NULL;
1807
 
        
1808
 
        parg->tag = fmt[0];
1809
 
        parg->pffi_type = fd->pffi_type;
1810
 
        Py_INCREF(self);
1811
 
        parg->obj = (PyObject *)self;
1812
 
        memcpy(&parg->value, self->b_ptr, self->b_size);
1813
 
        return parg;    
 
1791
    StgDictObject *dict;
 
1792
    char *fmt;
 
1793
    PyCArgObject *parg;
 
1794
    struct fielddesc *fd;
 
1795
 
 
1796
    dict = PyObject_stgdict((PyObject *)self);
 
1797
    assert(dict); /* Cannot be NULL for CDataObject instances */
 
1798
    fmt = _PyUnicode_AsString(dict->proto);
 
1799
    assert(fmt);
 
1800
 
 
1801
    fd = _ctypes_get_fielddesc(fmt);
 
1802
    assert(fd);
 
1803
 
 
1804
    parg = PyCArgObject_new();
 
1805
    if (parg == NULL)
 
1806
        return NULL;
 
1807
 
 
1808
    parg->tag = fmt[0];
 
1809
    parg->pffi_type = fd->pffi_type;
 
1810
    Py_INCREF(self);
 
1811
    parg->obj = (PyObject *)self;
 
1812
    memcpy(&parg->value, self->b_ptr, self->b_size);
 
1813
    return parg;
1814
1814
}
1815
1815
 
1816
1816
static PyObject *
1817
1817
PyCSimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1818
1818
{
1819
 
        PyTypeObject *result;
1820
 
        StgDictObject *stgdict;
1821
 
        PyObject *proto;
1822
 
        const char *proto_str;
1823
 
        Py_ssize_t proto_len;
1824
 
        PyMethodDef *ml;
1825
 
        struct fielddesc *fmt;
1826
 
 
1827
 
        /* create the new instance (which is a class,
1828
 
           since we are a metatype!) */
1829
 
        result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
1830
 
        if (result == NULL)
1831
 
                return NULL;
1832
 
 
1833
 
        proto = PyObject_GetAttrString((PyObject *)result, "_type_"); /* new ref */
1834
 
        if (!proto) {
1835
 
                PyErr_SetString(PyExc_AttributeError,
1836
 
                                "class must define a '_type_' attribute");
 
1819
    PyTypeObject *result;
 
1820
    StgDictObject *stgdict;
 
1821
    PyObject *proto;
 
1822
    const char *proto_str;
 
1823
    Py_ssize_t proto_len;
 
1824
    PyMethodDef *ml;
 
1825
    struct fielddesc *fmt;
 
1826
 
 
1827
    /* create the new instance (which is a class,
 
1828
       since we are a metatype!) */
 
1829
    result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
 
1830
    if (result == NULL)
 
1831
        return NULL;
 
1832
 
 
1833
    proto = PyObject_GetAttrString((PyObject *)result, "_type_"); /* new ref */
 
1834
    if (!proto) {
 
1835
        PyErr_SetString(PyExc_AttributeError,
 
1836
                        "class must define a '_type_' attribute");
1837
1837
  error:
1838
 
                Py_XDECREF(proto);
1839
 
                Py_XDECREF(result);
1840
 
                return NULL;
1841
 
        }
1842
 
        if (PyUnicode_Check(proto)) {
1843
 
                PyObject *v = _PyUnicode_AsDefaultEncodedString(proto, NULL);
1844
 
                if (!v)
1845
 
                        goto error;
1846
 
                proto_str = PyBytes_AS_STRING(v);
1847
 
                proto_len = PyBytes_GET_SIZE(v);
1848
 
        } else {
1849
 
                PyErr_SetString(PyExc_TypeError,
1850
 
                        "class must define a '_type_' string attribute");
1851
 
                goto error;
1852
 
        }
1853
 
        if (proto_len != 1) {
1854
 
                PyErr_SetString(PyExc_ValueError,
1855
 
                                "class must define a '_type_' attribute "
1856
 
                                "which must be a string of length 1");
1857
 
                goto error;
1858
 
        }
1859
 
        if (!strchr(SIMPLE_TYPE_CHARS, *proto_str)) {
1860
 
                PyErr_Format(PyExc_AttributeError,
1861
 
                             "class must define a '_type_' attribute which must be\n"
1862
 
                             "a single character string containing one of '%s'.",
1863
 
                             SIMPLE_TYPE_CHARS);
1864
 
                goto error;
1865
 
        }
1866
 
        fmt = _ctypes_get_fielddesc(proto_str);
1867
 
        if (fmt == NULL) {
1868
 
                PyErr_Format(PyExc_ValueError,
1869
 
                             "_type_ '%s' not supported", proto_str);
1870
 
                goto error;
1871
 
        }
1872
 
 
1873
 
        stgdict = (StgDictObject *)PyObject_CallObject(
1874
 
                (PyObject *)&PyCStgDict_Type, NULL);
1875
 
        if (!stgdict)
1876
 
                goto error;
1877
 
 
1878
 
        stgdict->ffi_type_pointer = *fmt->pffi_type;
1879
 
        stgdict->align = fmt->pffi_type->alignment;
1880
 
        stgdict->length = 0;
1881
 
        stgdict->size = fmt->pffi_type->size;
1882
 
        stgdict->setfunc = fmt->setfunc;
1883
 
        stgdict->getfunc = fmt->getfunc;
 
1838
        Py_XDECREF(proto);
 
1839
        Py_XDECREF(result);
 
1840
        return NULL;
 
1841
    }
 
1842
    if (PyUnicode_Check(proto)) {
 
1843
        PyObject *v = _PyUnicode_AsDefaultEncodedString(proto, NULL);
 
1844
        if (!v)
 
1845
            goto error;
 
1846
        proto_str = PyBytes_AS_STRING(v);
 
1847
        proto_len = PyBytes_GET_SIZE(v);
 
1848
    } else {
 
1849
        PyErr_SetString(PyExc_TypeError,
 
1850
            "class must define a '_type_' string attribute");
 
1851
        goto error;
 
1852
    }
 
1853
    if (proto_len != 1) {
 
1854
        PyErr_SetString(PyExc_ValueError,
 
1855
                        "class must define a '_type_' attribute "
 
1856
                        "which must be a string of length 1");
 
1857
        goto error;
 
1858
    }
 
1859
    if (!strchr(SIMPLE_TYPE_CHARS, *proto_str)) {
 
1860
        PyErr_Format(PyExc_AttributeError,
 
1861
                     "class must define a '_type_' attribute which must be\n"
 
1862
                     "a single character string containing one of '%s'.",
 
1863
                     SIMPLE_TYPE_CHARS);
 
1864
        goto error;
 
1865
    }
 
1866
    fmt = _ctypes_get_fielddesc(proto_str);
 
1867
    if (fmt == NULL) {
 
1868
        PyErr_Format(PyExc_ValueError,
 
1869
                     "_type_ '%s' not supported", proto_str);
 
1870
        goto error;
 
1871
    }
 
1872
 
 
1873
    stgdict = (StgDictObject *)PyObject_CallObject(
 
1874
        (PyObject *)&PyCStgDict_Type, NULL);
 
1875
    if (!stgdict)
 
1876
        goto error;
 
1877
 
 
1878
    stgdict->ffi_type_pointer = *fmt->pffi_type;
 
1879
    stgdict->align = fmt->pffi_type->alignment;
 
1880
    stgdict->length = 0;
 
1881
    stgdict->size = fmt->pffi_type->size;
 
1882
    stgdict->setfunc = fmt->setfunc;
 
1883
    stgdict->getfunc = fmt->getfunc;
1884
1884
#ifdef WORDS_BIGENDIAN
1885
 
        stgdict->format = _ctypes_alloc_format_string(">", proto_str);
 
1885
    stgdict->format = _ctypes_alloc_format_string(">", proto_str);
1886
1886
#else
1887
 
        stgdict->format = _ctypes_alloc_format_string("<", proto_str);
 
1887
    stgdict->format = _ctypes_alloc_format_string("<", proto_str);
1888
1888
#endif
1889
 
        if (stgdict->format == NULL) {
1890
 
                Py_DECREF(result);
1891
 
                Py_DECREF(proto);
1892
 
                Py_DECREF((PyObject *)stgdict);
1893
 
                return NULL;
1894
 
        }
 
1889
    if (stgdict->format == NULL) {
 
1890
        Py_DECREF(result);
 
1891
        Py_DECREF(proto);
 
1892
        Py_DECREF((PyObject *)stgdict);
 
1893
        return NULL;
 
1894
    }
1895
1895
 
1896
 
        stgdict->paramfunc = PyCSimpleType_paramfunc;
 
1896
    stgdict->paramfunc = PyCSimpleType_paramfunc;
1897
1897
/*
1898
 
        if (result->tp_base != &Simple_Type) {
1899
 
                stgdict->setfunc = NULL;
1900
 
                stgdict->getfunc = NULL;
1901
 
        }
 
1898
    if (result->tp_base != &Simple_Type) {
 
1899
        stgdict->setfunc = NULL;
 
1900
        stgdict->getfunc = NULL;
 
1901
    }
1902
1902
*/
1903
1903
 
1904
 
        /* This consumes the refcount on proto which we have */
1905
 
        stgdict->proto = proto;
1906
 
 
1907
 
        /* replace the class dict by our updated spam dict */
1908
 
        if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
1909
 
                Py_DECREF(result);
1910
 
                Py_DECREF((PyObject *)stgdict);
1911
 
                return NULL;
1912
 
        }
1913
 
        Py_DECREF(result->tp_dict);
1914
 
        result->tp_dict = (PyObject *)stgdict;
1915
 
 
1916
 
        /* Install from_param class methods in ctypes base classes.
1917
 
           Overrides the PyCSimpleType_from_param generic method.
1918
 
         */
1919
 
        if (result->tp_base == &Simple_Type) {
1920
 
                switch (*proto_str) {
1921
 
                case 'z': /* c_char_p */
1922
 
                        ml = &c_char_p_method;
1923
 
                        stgdict->flags |= TYPEFLAG_ISPOINTER;
1924
 
                        break;
1925
 
                case 'Z': /* c_wchar_p */
1926
 
                        ml = &c_wchar_p_method;
1927
 
                        stgdict->flags |= TYPEFLAG_ISPOINTER;
1928
 
                        break;
1929
 
                case 'P': /* c_void_p */
1930
 
                        ml = &c_void_p_method;
1931
 
                        stgdict->flags |= TYPEFLAG_ISPOINTER;
1932
 
                        break;
1933
 
                case 's':
1934
 
                case 'X':
1935
 
                case 'O':
1936
 
                        ml = NULL;
1937
 
                        stgdict->flags |= TYPEFLAG_ISPOINTER;
1938
 
                        break;
1939
 
                default:
1940
 
                        ml = NULL;
1941
 
                        break;
1942
 
                }
1943
 
                        
1944
 
                if (ml) {
1945
 
                        PyObject *meth;
1946
 
                        int x;
1947
 
                        meth = PyDescr_NewClassMethod(result, ml);
1948
 
                        if (!meth)
1949
 
                                return NULL;
1950
 
                        x = PyDict_SetItemString(result->tp_dict,
1951
 
                                                 ml->ml_name,
1952
 
                                                 meth);
1953
 
                        Py_DECREF(meth);
1954
 
                        if (x == -1) {
1955
 
                                Py_DECREF(result);
1956
 
                                return NULL;
1957
 
                        }
1958
 
                }
1959
 
        }
1960
 
 
1961
 
        if (type == &PyCSimpleType_Type && fmt->setfunc_swapped && fmt->getfunc_swapped) {
1962
 
                PyObject *swapped = CreateSwappedType(type, args, kwds,
1963
 
                                                      proto, fmt);
1964
 
                StgDictObject *sw_dict;
1965
 
                if (swapped == NULL) {
1966
 
                        Py_DECREF(result);
1967
 
                        return NULL;
1968
 
                }
1969
 
                sw_dict = PyType_stgdict(swapped);
 
1904
    /* This consumes the refcount on proto which we have */
 
1905
    stgdict->proto = proto;
 
1906
 
 
1907
    /* replace the class dict by our updated spam dict */
 
1908
    if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
 
1909
        Py_DECREF(result);
 
1910
        Py_DECREF((PyObject *)stgdict);
 
1911
        return NULL;
 
1912
    }
 
1913
    Py_DECREF(result->tp_dict);
 
1914
    result->tp_dict = (PyObject *)stgdict;
 
1915
 
 
1916
    /* Install from_param class methods in ctypes base classes.
 
1917
       Overrides the PyCSimpleType_from_param generic method.
 
1918
     */
 
1919
    if (result->tp_base == &Simple_Type) {
 
1920
        switch (*proto_str) {
 
1921
        case 'z': /* c_char_p */
 
1922
            ml = &c_char_p_method;
 
1923
            stgdict->flags |= TYPEFLAG_ISPOINTER;
 
1924
            break;
 
1925
        case 'Z': /* c_wchar_p */
 
1926
            ml = &c_wchar_p_method;
 
1927
            stgdict->flags |= TYPEFLAG_ISPOINTER;
 
1928
            break;
 
1929
        case 'P': /* c_void_p */
 
1930
            ml = &c_void_p_method;
 
1931
            stgdict->flags |= TYPEFLAG_ISPOINTER;
 
1932
            break;
 
1933
        case 's':
 
1934
        case 'X':
 
1935
        case 'O':
 
1936
            ml = NULL;
 
1937
            stgdict->flags |= TYPEFLAG_ISPOINTER;
 
1938
            break;
 
1939
        default:
 
1940
            ml = NULL;
 
1941
            break;
 
1942
        }
 
1943
 
 
1944
        if (ml) {
 
1945
            PyObject *meth;
 
1946
            int x;
 
1947
            meth = PyDescr_NewClassMethod(result, ml);
 
1948
            if (!meth)
 
1949
                return NULL;
 
1950
            x = PyDict_SetItemString(result->tp_dict,
 
1951
                                     ml->ml_name,
 
1952
                                     meth);
 
1953
            Py_DECREF(meth);
 
1954
            if (x == -1) {
 
1955
                Py_DECREF(result);
 
1956
                return NULL;
 
1957
            }
 
1958
        }
 
1959
    }
 
1960
 
 
1961
    if (type == &PyCSimpleType_Type && fmt->setfunc_swapped && fmt->getfunc_swapped) {
 
1962
        PyObject *swapped = CreateSwappedType(type, args, kwds,
 
1963
                                              proto, fmt);
 
1964
        StgDictObject *sw_dict;
 
1965
        if (swapped == NULL) {
 
1966
            Py_DECREF(result);
 
1967
            return NULL;
 
1968
        }
 
1969
        sw_dict = PyType_stgdict(swapped);
1970
1970
#ifdef WORDS_BIGENDIAN
1971
 
                PyObject_SetAttrString((PyObject *)result, "__ctype_le__", swapped);
1972
 
                PyObject_SetAttrString((PyObject *)result, "__ctype_be__", (PyObject *)result);
1973
 
                PyObject_SetAttrString(swapped, "__ctype_be__", (PyObject *)result);
1974
 
                PyObject_SetAttrString(swapped, "__ctype_le__", swapped);
1975
 
                /* We are creating the type for the OTHER endian */
1976
 
                sw_dict->format = _ctypes_alloc_format_string("<", stgdict->format+1);
 
1971
        PyObject_SetAttrString((PyObject *)result, "__ctype_le__", swapped);
 
1972
        PyObject_SetAttrString((PyObject *)result, "__ctype_be__", (PyObject *)result);
 
1973
        PyObject_SetAttrString(swapped, "__ctype_be__", (PyObject *)result);
 
1974
        PyObject_SetAttrString(swapped, "__ctype_le__", swapped);
 
1975
        /* We are creating the type for the OTHER endian */
 
1976
        sw_dict->format = _ctypes_alloc_format_string("<", stgdict->format+1);
1977
1977
#else
1978
 
                PyObject_SetAttrString((PyObject *)result, "__ctype_be__", swapped);
1979
 
                PyObject_SetAttrString((PyObject *)result, "__ctype_le__", (PyObject *)result);
1980
 
                PyObject_SetAttrString(swapped, "__ctype_le__", (PyObject *)result);
1981
 
                PyObject_SetAttrString(swapped, "__ctype_be__", swapped);
1982
 
                /* We are creating the type for the OTHER endian */
1983
 
                sw_dict->format = _ctypes_alloc_format_string(">", stgdict->format+1);
 
1978
        PyObject_SetAttrString((PyObject *)result, "__ctype_be__", swapped);
 
1979
        PyObject_SetAttrString((PyObject *)result, "__ctype_le__", (PyObject *)result);
 
1980
        PyObject_SetAttrString(swapped, "__ctype_le__", (PyObject *)result);
 
1981
        PyObject_SetAttrString(swapped, "__ctype_be__", swapped);
 
1982
        /* We are creating the type for the OTHER endian */
 
1983
        sw_dict->format = _ctypes_alloc_format_string(">", stgdict->format+1);
1984
1984
#endif
1985
 
                Py_DECREF(swapped);
1986
 
                if (PyErr_Occurred()) {
1987
 
                        Py_DECREF(result);
1988
 
                        return NULL;
1989
 
                }
1990
 
        };
 
1985
        Py_DECREF(swapped);
 
1986
        if (PyErr_Occurred()) {
 
1987
            Py_DECREF(result);
 
1988
            return NULL;
 
1989
        }
 
1990
    };
1991
1991
 
1992
 
        return (PyObject *)result;
 
1992
    return (PyObject *)result;
1993
1993
}
1994
1994
 
1995
1995
/*
1999
1999
static PyObject *
2000
2000
PyCSimpleType_from_param(PyObject *type, PyObject *value)
2001
2001
{
2002
 
        StgDictObject *dict;
2003
 
        char *fmt;
2004
 
        PyCArgObject *parg;
2005
 
        struct fielddesc *fd;
2006
 
        PyObject *as_parameter;
2007
 
 
2008
 
        /* If the value is already an instance of the requested type,
2009
 
           we can use it as is */
2010
 
        if (1 == PyObject_IsInstance(value, type)) {
2011
 
                Py_INCREF(value);
2012
 
                return value;
2013
 
        }
2014
 
 
2015
 
        dict = PyType_stgdict(type);
2016
 
        assert(dict);
2017
 
 
2018
 
        /* I think we can rely on this being a one-character string */
2019
 
        fmt = _PyUnicode_AsString(dict->proto);
2020
 
        assert(fmt);
2021
 
        
2022
 
        fd = _ctypes_get_fielddesc(fmt);
2023
 
        assert(fd);
2024
 
        
2025
 
        parg = PyCArgObject_new();
2026
 
        if (parg == NULL)
2027
 
                return NULL;
2028
 
 
2029
 
        parg->tag = fmt[0];
2030
 
        parg->pffi_type = fd->pffi_type;
2031
 
        parg->obj = fd->setfunc(&parg->value, value, 0);
2032
 
        if (parg->obj)
2033
 
                return (PyObject *)parg;
2034
 
        PyErr_Clear();
2035
 
        Py_DECREF(parg);
2036
 
 
2037
 
        as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
2038
 
        if (as_parameter) {
2039
 
                value = PyCSimpleType_from_param(type, as_parameter);
2040
 
                Py_DECREF(as_parameter);
2041
 
                return value;
2042
 
        }
2043
 
        PyErr_SetString(PyExc_TypeError,
2044
 
                        "wrong type");
2045
 
        return NULL;
 
2002
    StgDictObject *dict;
 
2003
    char *fmt;
 
2004
    PyCArgObject *parg;
 
2005
    struct fielddesc *fd;
 
2006
    PyObject *as_parameter;
 
2007
 
 
2008
    /* If the value is already an instance of the requested type,
 
2009
       we can use it as is */
 
2010
    if (1 == PyObject_IsInstance(value, type)) {
 
2011
        Py_INCREF(value);
 
2012
        return value;
 
2013
    }
 
2014
 
 
2015
    dict = PyType_stgdict(type);
 
2016
    assert(dict);
 
2017
 
 
2018
    /* I think we can rely on this being a one-character string */
 
2019
    fmt = _PyUnicode_AsString(dict->proto);
 
2020
    assert(fmt);
 
2021
 
 
2022
    fd = _ctypes_get_fielddesc(fmt);
 
2023
    assert(fd);
 
2024
 
 
2025
    parg = PyCArgObject_new();
 
2026
    if (parg == NULL)
 
2027
        return NULL;
 
2028
 
 
2029
    parg->tag = fmt[0];
 
2030
    parg->pffi_type = fd->pffi_type;
 
2031
    parg->obj = fd->setfunc(&parg->value, value, 0);
 
2032
    if (parg->obj)
 
2033
        return (PyObject *)parg;
 
2034
    PyErr_Clear();
 
2035
    Py_DECREF(parg);
 
2036
 
 
2037
    as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
 
2038
    if (as_parameter) {
 
2039
        value = PyCSimpleType_from_param(type, as_parameter);
 
2040
        Py_DECREF(as_parameter);
 
2041
        return value;
 
2042
    }
 
2043
    PyErr_SetString(PyExc_TypeError,
 
2044
                    "wrong type");
 
2045
    return NULL;
2046
2046
}
2047
2047
 
2048
2048
static PyMethodDef PyCSimpleType_methods[] = {
2049
 
        { "from_param", PyCSimpleType_from_param, METH_O, from_param_doc },
2050
 
        { "from_address", CDataType_from_address, METH_O, from_address_doc },
2051
 
        { "from_buffer", CDataType_from_buffer, METH_VARARGS, from_buffer_doc, },
2052
 
        { "from_buffer_copy", CDataType_from_buffer_copy, METH_VARARGS, from_buffer_copy_doc, },
2053
 
        { "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc},
2054
 
        { NULL, NULL },
 
2049
    { "from_param", PyCSimpleType_from_param, METH_O, from_param_doc },
 
2050
    { "from_address", CDataType_from_address, METH_O, from_address_doc },
 
2051
    { "from_buffer", CDataType_from_buffer, METH_VARARGS, from_buffer_doc, },
 
2052
    { "from_buffer_copy", CDataType_from_buffer_copy, METH_VARARGS, from_buffer_copy_doc, },
 
2053
    { "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc},
 
2054
    { NULL, NULL },
2055
2055
};
2056
2056
 
2057
2057
PyTypeObject PyCSimpleType_Type = {
2058
 
        PyVarObject_HEAD_INIT(NULL, 0)
2059
 
        "_ctypes.PyCSimpleType",                                /* tp_name */
2060
 
        0,                                      /* tp_basicsize */
2061
 
        0,                                      /* tp_itemsize */
2062
 
        0,                                      /* tp_dealloc */
2063
 
        0,                                      /* tp_print */
2064
 
        0,                                      /* tp_getattr */
2065
 
        0,                                      /* tp_setattr */
2066
 
        0,                                      /* tp_reserved */
2067
 
        0,                                      /* tp_repr */
2068
 
        0,                                      /* tp_as_number */
2069
 
        &CDataType_as_sequence,         /* tp_as_sequence */
2070
 
        0,                                      /* tp_as_mapping */
2071
 
        0,                                      /* tp_hash */
2072
 
        0,                                      /* tp_call */
2073
 
        0,                                      /* tp_str */
2074
 
        0,                                      /* tp_getattro */
2075
 
        0,                                      /* tp_setattro */
2076
 
        0,                                      /* tp_as_buffer */
2077
 
        Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2078
 
        "metatype for the PyCSimpleType Objects",       /* tp_doc */
2079
 
        0,                                      /* tp_traverse */
2080
 
        0,                                      /* tp_clear */
2081
 
        0,                                      /* tp_richcompare */
2082
 
        0,                                      /* tp_weaklistoffset */
2083
 
        0,                                      /* tp_iter */
2084
 
        0,                                      /* tp_iternext */
2085
 
        PyCSimpleType_methods,                  /* tp_methods */
2086
 
        0,                                      /* tp_members */
2087
 
        0,                                      /* tp_getset */
2088
 
        0,                                      /* tp_base */
2089
 
        0,                                      /* tp_dict */
2090
 
        0,                                      /* tp_descr_get */
2091
 
        0,                                      /* tp_descr_set */
2092
 
        0,                                      /* tp_dictoffset */
2093
 
        0,                                      /* tp_init */
2094
 
        0,                                      /* tp_alloc */
2095
 
        PyCSimpleType_new,                              /* tp_new */
2096
 
        0,                                      /* tp_free */
 
2058
    PyVarObject_HEAD_INIT(NULL, 0)
 
2059
    "_ctypes.PyCSimpleType",                                    /* tp_name */
 
2060
    0,                                          /* tp_basicsize */
 
2061
    0,                                          /* tp_itemsize */
 
2062
    0,                                          /* tp_dealloc */
 
2063
    0,                                          /* tp_print */
 
2064
    0,                                          /* tp_getattr */
 
2065
    0,                                          /* tp_setattr */
 
2066
    0,                                          /* tp_reserved */
 
2067
    0,                                          /* tp_repr */
 
2068
    0,                                          /* tp_as_number */
 
2069
    &CDataType_as_sequence,             /* tp_as_sequence */
 
2070
    0,                                          /* tp_as_mapping */
 
2071
    0,                                          /* tp_hash */
 
2072
    0,                                          /* tp_call */
 
2073
    0,                                          /* tp_str */
 
2074
    0,                                          /* tp_getattro */
 
2075
    0,                                          /* tp_setattro */
 
2076
    0,                                          /* tp_as_buffer */
 
2077
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
 
2078
    "metatype for the PyCSimpleType Objects",           /* tp_doc */
 
2079
    0,                                          /* tp_traverse */
 
2080
    0,                                          /* tp_clear */
 
2081
    0,                                          /* tp_richcompare */
 
2082
    0,                                          /* tp_weaklistoffset */
 
2083
    0,                                          /* tp_iter */
 
2084
    0,                                          /* tp_iternext */
 
2085
    PyCSimpleType_methods,                      /* tp_methods */
 
2086
    0,                                          /* tp_members */
 
2087
    0,                                          /* tp_getset */
 
2088
    0,                                          /* tp_base */
 
2089
    0,                                          /* tp_dict */
 
2090
    0,                                          /* tp_descr_get */
 
2091
    0,                                          /* tp_descr_set */
 
2092
    0,                                          /* tp_dictoffset */
 
2093
    0,                                          /* tp_init */
 
2094
    0,                                          /* tp_alloc */
 
2095
    PyCSimpleType_new,                                  /* tp_new */
 
2096
    0,                                          /* tp_free */
2097
2097
};
2098
2098
 
2099
2099
/******************************************************************/
2104
2104
static PyObject *
2105
2105
converters_from_argtypes(PyObject *ob)
2106
2106
{
2107
 
        PyObject *converters;
2108
 
        Py_ssize_t i;
2109
 
        Py_ssize_t nArgs;
2110
 
 
2111
 
        ob = PySequence_Tuple(ob); /* new reference */
2112
 
        if (!ob) {
2113
 
                PyErr_SetString(PyExc_TypeError,
2114
 
                                "_argtypes_ must be a sequence of types");
2115
 
                return NULL;
2116
 
        }
2117
 
 
2118
 
        nArgs = PyTuple_GET_SIZE(ob);
2119
 
        converters = PyTuple_New(nArgs);
2120
 
        if (!converters)
2121
 
                return NULL;
2122
 
                
2123
 
        /* I have to check if this is correct. Using c_char, which has a size
2124
 
           of 1, will be assumed to be pushed as only one byte!
2125
 
           Aren't these promoted to integers by the C compiler and pushed as 4 bytes?
2126
 
        */
2127
 
 
2128
 
        for (i = 0; i < nArgs; ++i) {
2129
 
                PyObject *tp = PyTuple_GET_ITEM(ob, i);
2130
 
                PyObject *cnv = PyObject_GetAttrString(tp, "from_param");
2131
 
                if (!cnv)
2132
 
                        goto argtypes_error_1;
2133
 
                PyTuple_SET_ITEM(converters, i, cnv);
2134
 
        }
2135
 
        Py_DECREF(ob);
2136
 
        return converters;
 
2107
    PyObject *converters;
 
2108
    Py_ssize_t i;
 
2109
    Py_ssize_t nArgs;
 
2110
 
 
2111
    ob = PySequence_Tuple(ob); /* new reference */
 
2112
    if (!ob) {
 
2113
        PyErr_SetString(PyExc_TypeError,
 
2114
                        "_argtypes_ must be a sequence of types");
 
2115
        return NULL;
 
2116
    }
 
2117
 
 
2118
    nArgs = PyTuple_GET_SIZE(ob);
 
2119
    converters = PyTuple_New(nArgs);
 
2120
    if (!converters)
 
2121
        return NULL;
 
2122
 
 
2123
    /* I have to check if this is correct. Using c_char, which has a size
 
2124
       of 1, will be assumed to be pushed as only one byte!
 
2125
       Aren't these promoted to integers by the C compiler and pushed as 4 bytes?
 
2126
    */
 
2127
 
 
2128
    for (i = 0; i < nArgs; ++i) {
 
2129
        PyObject *tp = PyTuple_GET_ITEM(ob, i);
 
2130
        PyObject *cnv = PyObject_GetAttrString(tp, "from_param");
 
2131
        if (!cnv)
 
2132
            goto argtypes_error_1;
 
2133
        PyTuple_SET_ITEM(converters, i, cnv);
 
2134
    }
 
2135
    Py_DECREF(ob);
 
2136
    return converters;
2137
2137
 
2138
2138
  argtypes_error_1:
2139
 
        Py_XDECREF(converters);
2140
 
        Py_DECREF(ob);
2141
 
        PyErr_Format(PyExc_TypeError,
2142
 
                     "item %zd in _argtypes_ has no from_param method",
2143
 
                     i+1);
2144
 
        return NULL;
 
2139
    Py_XDECREF(converters);
 
2140
    Py_DECREF(ob);
 
2141
    PyErr_Format(PyExc_TypeError,
 
2142
                 "item %zd in _argtypes_ has no from_param method",
 
2143
                 i+1);
 
2144
    return NULL;
2145
2145
}
2146
2146
 
2147
2147
static int
2148
2148
make_funcptrtype_dict(StgDictObject *stgdict)
2149
2149
{
2150
 
        PyObject *ob;
2151
 
        PyObject *converters = NULL;
2152
 
 
2153
 
        stgdict->align = _ctypes_get_fielddesc("P")->pffi_type->alignment;
2154
 
        stgdict->length = 1;
2155
 
        stgdict->size = sizeof(void *);
2156
 
        stgdict->setfunc = NULL;
2157
 
        stgdict->getfunc = NULL;
2158
 
        stgdict->ffi_type_pointer = ffi_type_pointer;
2159
 
 
2160
 
        ob = PyDict_GetItemString((PyObject *)stgdict, "_flags_");
2161
 
        if (!ob || !PyLong_Check(ob)) {
2162
 
                PyErr_SetString(PyExc_TypeError,
2163
 
                    "class must define _flags_ which must be an integer");
2164
 
                return -1;
2165
 
        }
2166
 
        stgdict->flags = PyLong_AS_LONG(ob) | TYPEFLAG_ISPOINTER;
2167
 
 
2168
 
        /* _argtypes_ is optional... */
2169
 
        ob = PyDict_GetItemString((PyObject *)stgdict, "_argtypes_");
2170
 
        if (ob) {
2171
 
                converters = converters_from_argtypes(ob);
2172
 
                if (!converters)
2173
 
                        goto error;
2174
 
                Py_INCREF(ob);
2175
 
                stgdict->argtypes = ob;
2176
 
                stgdict->converters = converters;
2177
 
        }
2178
 
 
2179
 
        ob = PyDict_GetItemString((PyObject *)stgdict, "_restype_");
2180
 
        if (ob) {
2181
 
                if (ob != Py_None && !PyType_stgdict(ob) && !PyCallable_Check(ob)) {
2182
 
                        PyErr_SetString(PyExc_TypeError,
2183
 
                                "_restype_ must be a type, a callable, or None");
2184
 
                        return -1;
2185
 
                }
2186
 
                Py_INCREF(ob);
2187
 
                stgdict->restype = ob;
2188
 
                stgdict->checker = PyObject_GetAttrString(ob, "_check_retval_");
2189
 
                if (stgdict->checker == NULL)
2190
 
                        PyErr_Clear();
2191
 
        }
 
2150
    PyObject *ob;
 
2151
    PyObject *converters = NULL;
 
2152
 
 
2153
    stgdict->align = _ctypes_get_fielddesc("P")->pffi_type->alignment;
 
2154
    stgdict->length = 1;
 
2155
    stgdict->size = sizeof(void *);
 
2156
    stgdict->setfunc = NULL;
 
2157
    stgdict->getfunc = NULL;
 
2158
    stgdict->ffi_type_pointer = ffi_type_pointer;
 
2159
 
 
2160
    ob = PyDict_GetItemString((PyObject *)stgdict, "_flags_");
 
2161
    if (!ob || !PyLong_Check(ob)) {
 
2162
        PyErr_SetString(PyExc_TypeError,
 
2163
            "class must define _flags_ which must be an integer");
 
2164
        return -1;
 
2165
    }
 
2166
    stgdict->flags = PyLong_AS_LONG(ob) | TYPEFLAG_ISPOINTER;
 
2167
 
 
2168
    /* _argtypes_ is optional... */
 
2169
    ob = PyDict_GetItemString((PyObject *)stgdict, "_argtypes_");
 
2170
    if (ob) {
 
2171
        converters = converters_from_argtypes(ob);
 
2172
        if (!converters)
 
2173
            goto error;
 
2174
        Py_INCREF(ob);
 
2175
        stgdict->argtypes = ob;
 
2176
        stgdict->converters = converters;
 
2177
    }
 
2178
 
 
2179
    ob = PyDict_GetItemString((PyObject *)stgdict, "_restype_");
 
2180
    if (ob) {
 
2181
        if (ob != Py_None && !PyType_stgdict(ob) && !PyCallable_Check(ob)) {
 
2182
            PyErr_SetString(PyExc_TypeError,
 
2183
                "_restype_ must be a type, a callable, or None");
 
2184
            return -1;
 
2185
        }
 
2186
        Py_INCREF(ob);
 
2187
        stgdict->restype = ob;
 
2188
        stgdict->checker = PyObject_GetAttrString(ob, "_check_retval_");
 
2189
        if (stgdict->checker == NULL)
 
2190
            PyErr_Clear();
 
2191
    }
2192
2192
/* XXX later, maybe.
2193
 
        ob = PyDict_GetItemString((PyObject *)stgdict, "_errcheck_");
2194
 
        if (ob) {
2195
 
                if (!PyCallable_Check(ob)) {
2196
 
                        PyErr_SetString(PyExc_TypeError,
2197
 
                                "_errcheck_ must be callable");
2198
 
                        return -1;
2199
 
                }
2200
 
                Py_INCREF(ob);
2201
 
                stgdict->errcheck = ob;
2202
 
        }
 
2193
    ob = PyDict_GetItemString((PyObject *)stgdict, "_errcheck_");
 
2194
    if (ob) {
 
2195
        if (!PyCallable_Check(ob)) {
 
2196
            PyErr_SetString(PyExc_TypeError,
 
2197
                "_errcheck_ must be callable");
 
2198
            return -1;
 
2199
        }
 
2200
        Py_INCREF(ob);
 
2201
        stgdict->errcheck = ob;
 
2202
    }
2203
2203
*/
2204
 
        return 0;
 
2204
    return 0;
2205
2205
 
2206
2206
  error:
2207
 
        Py_XDECREF(converters);
2208
 
        return -1;
 
2207
    Py_XDECREF(converters);
 
2208
    return -1;
2209
2209
 
2210
2210
}
2211
2211
 
2212
2212
static PyCArgObject *
2213
2213
PyCFuncPtrType_paramfunc(CDataObject *self)
2214
2214
{
2215
 
        PyCArgObject *parg;
2216
 
        
2217
 
        parg = PyCArgObject_new();
2218
 
        if (parg == NULL)
2219
 
                return NULL;
2220
 
        
2221
 
        parg->tag = 'P';
2222
 
        parg->pffi_type = &ffi_type_pointer;
2223
 
        Py_INCREF(self);
2224
 
        parg->obj = (PyObject *)self;
2225
 
        parg->value.p = *(void **)self->b_ptr;
2226
 
        return parg;    
 
2215
    PyCArgObject *parg;
 
2216
 
 
2217
    parg = PyCArgObject_new();
 
2218
    if (parg == NULL)
 
2219
        return NULL;
 
2220
 
 
2221
    parg->tag = 'P';
 
2222
    parg->pffi_type = &ffi_type_pointer;
 
2223
    Py_INCREF(self);
 
2224
    parg->obj = (PyObject *)self;
 
2225
    parg->value.p = *(void **)self->b_ptr;
 
2226
    return parg;
2227
2227
}
2228
2228
 
2229
2229
static PyObject *
2230
2230
PyCFuncPtrType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2231
2231
{
2232
 
        PyTypeObject *result;
2233
 
        StgDictObject *stgdict;
2234
 
 
2235
 
        stgdict = (StgDictObject *)PyObject_CallObject(
2236
 
                (PyObject *)&PyCStgDict_Type, NULL);
2237
 
        if (!stgdict)
2238
 
                return NULL;
2239
 
 
2240
 
        stgdict->paramfunc = PyCFuncPtrType_paramfunc;
2241
 
        /* We do NOT expose the function signature in the format string.  It
2242
 
           is impossible, generally, because the only requirement for the
2243
 
           argtypes items is that they have a .from_param method - we do not
2244
 
           know the types of the arguments (although, in practice, most
2245
 
           argtypes would be a ctypes type).
2246
 
        */
2247
 
        stgdict->format = _ctypes_alloc_format_string(NULL, "X{}");
2248
 
        stgdict->flags |= TYPEFLAG_ISPOINTER;
2249
 
 
2250
 
        /* create the new instance (which is a class,
2251
 
           since we are a metatype!) */
2252
 
        result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
2253
 
        if (result == NULL) {
2254
 
                Py_DECREF((PyObject *)stgdict);
2255
 
                return NULL;
2256
 
        }
2257
 
 
2258
 
        /* replace the class dict by our updated storage dict */
2259
 
        if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
2260
 
                Py_DECREF(result);
2261
 
                Py_DECREF((PyObject *)stgdict);
2262
 
                return NULL;
2263
 
        }
2264
 
        Py_DECREF(result->tp_dict);
2265
 
        result->tp_dict = (PyObject *)stgdict;
2266
 
 
2267
 
        if (-1 == make_funcptrtype_dict(stgdict)) {
2268
 
                Py_DECREF(result);
2269
 
                return NULL;
2270
 
        }
2271
 
 
2272
 
        return (PyObject *)result;
 
2232
    PyTypeObject *result;
 
2233
    StgDictObject *stgdict;
 
2234
 
 
2235
    stgdict = (StgDictObject *)PyObject_CallObject(
 
2236
        (PyObject *)&PyCStgDict_Type, NULL);
 
2237
    if (!stgdict)
 
2238
        return NULL;
 
2239
 
 
2240
    stgdict->paramfunc = PyCFuncPtrType_paramfunc;
 
2241
    /* We do NOT expose the function signature in the format string.  It
 
2242
       is impossible, generally, because the only requirement for the
 
2243
       argtypes items is that they have a .from_param method - we do not
 
2244
       know the types of the arguments (although, in practice, most
 
2245
       argtypes would be a ctypes type).
 
2246
    */
 
2247
    stgdict->format = _ctypes_alloc_format_string(NULL, "X{}");
 
2248
    stgdict->flags |= TYPEFLAG_ISPOINTER;
 
2249
 
 
2250
    /* create the new instance (which is a class,
 
2251
       since we are a metatype!) */
 
2252
    result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
 
2253
    if (result == NULL) {
 
2254
        Py_DECREF((PyObject *)stgdict);
 
2255
        return NULL;
 
2256
    }
 
2257
 
 
2258
    /* replace the class dict by our updated storage dict */
 
2259
    if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
 
2260
        Py_DECREF(result);
 
2261
        Py_DECREF((PyObject *)stgdict);
 
2262
        return NULL;
 
2263
    }
 
2264
    Py_DECREF(result->tp_dict);
 
2265
    result->tp_dict = (PyObject *)stgdict;
 
2266
 
 
2267
    if (-1 == make_funcptrtype_dict(stgdict)) {
 
2268
        Py_DECREF(result);
 
2269
        return NULL;
 
2270
    }
 
2271
 
 
2272
    return (PyObject *)result;
2273
2273
}
2274
2274
 
2275
2275
PyTypeObject PyCFuncPtrType_Type = {
2276
 
        PyVarObject_HEAD_INIT(NULL, 0)
2277
 
        "_ctypes.PyCFuncPtrType",                       /* tp_name */
2278
 
        0,                                      /* tp_basicsize */
2279
 
        0,                                      /* tp_itemsize */
2280
 
        0,                                      /* tp_dealloc */
2281
 
        0,                                      /* tp_print */
2282
 
        0,                                      /* tp_getattr */
2283
 
        0,                                      /* tp_setattr */
2284
 
        0,                                      /* tp_reserved */
2285
 
        0,                                      /* tp_repr */
2286
 
        0,                                      /* tp_as_number */
2287
 
        &CDataType_as_sequence,                 /* tp_as_sequence */
2288
 
        0,                                      /* tp_as_mapping */
2289
 
        0,                                      /* tp_hash */
2290
 
        0,                                      /* tp_call */
2291
 
        0,                                      /* tp_str */
2292
 
        0,                                      /* tp_getattro */
2293
 
        0,                                      /* tp_setattro */
2294
 
        0,                                      /* tp_as_buffer */
2295
 
        Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
2296
 
        "metatype for C function pointers",     /* tp_doc */
2297
 
        (traverseproc)CDataType_traverse,       /* tp_traverse */
2298
 
        (inquiry)CDataType_clear,               /* tp_clear */
2299
 
        0,                                      /* tp_richcompare */
2300
 
        0,                                      /* tp_weaklistoffset */
2301
 
        0,                                      /* tp_iter */
2302
 
        0,                                      /* tp_iternext */
2303
 
        CDataType_methods,                      /* tp_methods */
2304
 
        0,                                      /* tp_members */
2305
 
        0,                                      /* tp_getset */
2306
 
        0,                                      /* tp_base */
2307
 
        0,                                      /* tp_dict */
2308
 
        0,                                      /* tp_descr_get */
2309
 
        0,                                      /* tp_descr_set */
2310
 
        0,                                      /* tp_dictoffset */
2311
 
        0,                                      /* tp_init */
2312
 
        0,                                      /* tp_alloc */
2313
 
        PyCFuncPtrType_new,                     /* tp_new */
2314
 
        0,                                      /* tp_free */
 
2276
    PyVarObject_HEAD_INIT(NULL, 0)
 
2277
    "_ctypes.PyCFuncPtrType",                           /* tp_name */
 
2278
    0,                                          /* tp_basicsize */
 
2279
    0,                                          /* tp_itemsize */
 
2280
    0,                                          /* tp_dealloc */
 
2281
    0,                                          /* tp_print */
 
2282
    0,                                          /* tp_getattr */
 
2283
    0,                                          /* tp_setattr */
 
2284
    0,                                          /* tp_reserved */
 
2285
    0,                                          /* tp_repr */
 
2286
    0,                                          /* tp_as_number */
 
2287
    &CDataType_as_sequence,                     /* tp_as_sequence */
 
2288
    0,                                          /* tp_as_mapping */
 
2289
    0,                                          /* tp_hash */
 
2290
    0,                                          /* tp_call */
 
2291
    0,                                          /* tp_str */
 
2292
    0,                                          /* tp_getattro */
 
2293
    0,                                          /* tp_setattro */
 
2294
    0,                                          /* tp_as_buffer */
 
2295
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
 
2296
    "metatype for C function pointers",         /* tp_doc */
 
2297
    (traverseproc)CDataType_traverse,           /* tp_traverse */
 
2298
    (inquiry)CDataType_clear,                   /* tp_clear */
 
2299
    0,                                          /* tp_richcompare */
 
2300
    0,                                          /* tp_weaklistoffset */
 
2301
    0,                                          /* tp_iter */
 
2302
    0,                                          /* tp_iternext */
 
2303
    CDataType_methods,                          /* tp_methods */
 
2304
    0,                                          /* tp_members */
 
2305
    0,                                          /* tp_getset */
 
2306
    0,                                          /* tp_base */
 
2307
    0,                                          /* tp_dict */
 
2308
    0,                                          /* tp_descr_get */
 
2309
    0,                                          /* tp_descr_set */
 
2310
    0,                                          /* tp_dictoffset */
 
2311
    0,                                          /* tp_init */
 
2312
    0,                                          /* tp_alloc */
 
2313
    PyCFuncPtrType_new,                         /* tp_new */
 
2314
    0,                                          /* tp_free */
2315
2315
};
2316
2316
 
2317
 
 
 
2317
 
2318
2318
/*****************************************************************
2319
2319
 * Code to keep needed objects alive
2320
2320
 */
2322
2322
static CDataObject *
2323
2323
PyCData_GetContainer(CDataObject *self)
2324
2324
{
2325
 
        while (self->b_base)
2326
 
                self = self->b_base;
2327
 
        if (self->b_objects == NULL) {
2328
 
                if (self->b_length) {
2329
 
                        self->b_objects = PyDict_New();
2330
 
                } else {
2331
 
                        Py_INCREF(Py_None);
2332
 
                        self->b_objects = Py_None;
2333
 
                }
2334
 
        }
2335
 
        return self;
 
2325
    while (self->b_base)
 
2326
        self = self->b_base;
 
2327
    if (self->b_objects == NULL) {
 
2328
        if (self->b_length) {
 
2329
            self->b_objects = PyDict_New();
 
2330
        } else {
 
2331
            Py_INCREF(Py_None);
 
2332
            self->b_objects = Py_None;
 
2333
        }
 
2334
    }
 
2335
    return self;
2336
2336
}
2337
2337
 
2338
2338
static PyObject *
2339
2339
GetKeepedObjects(CDataObject *target)
2340
2340
{
2341
 
        return PyCData_GetContainer(target)->b_objects;
 
2341
    return PyCData_GetContainer(target)->b_objects;
2342
2342
}
2343
2343
 
2344
2344
static PyObject *
2345
2345
unique_key(CDataObject *target, Py_ssize_t index)
2346
2346
{
2347
 
        char string[256];
2348
 
        char *cp = string;
2349
 
        size_t bytes_left;
 
2347
    char string[256];
 
2348
    char *cp = string;
 
2349
    size_t bytes_left;
2350
2350
 
2351
 
        assert(sizeof(string) - 1 > sizeof(Py_ssize_t) * 2);
2352
 
        cp += sprintf(cp, "%x", Py_SAFE_DOWNCAST(index, Py_ssize_t, int));
2353
 
        while (target->b_base) {
2354
 
                bytes_left = sizeof(string) - (cp - string) - 1;
2355
 
                /* Hex format needs 2 characters per byte */
2356
 
                if (bytes_left < sizeof(Py_ssize_t) * 2) {
2357
 
                        PyErr_SetString(PyExc_ValueError,
2358
 
                                        "ctypes object structure too deep");
2359
 
                        return NULL;
2360
 
                }
2361
 
                cp += sprintf(cp, ":%x", Py_SAFE_DOWNCAST(target->b_index, Py_ssize_t, int));
2362
 
                target = target->b_base;
2363
 
        }
2364
 
        return PyUnicode_FromStringAndSize(string, cp-string);
 
2351
    assert(sizeof(string) - 1 > sizeof(Py_ssize_t) * 2);
 
2352
    cp += sprintf(cp, "%x", Py_SAFE_DOWNCAST(index, Py_ssize_t, int));
 
2353
    while (target->b_base) {
 
2354
        bytes_left = sizeof(string) - (cp - string) - 1;
 
2355
        /* Hex format needs 2 characters per byte */
 
2356
        if (bytes_left < sizeof(Py_ssize_t) * 2) {
 
2357
            PyErr_SetString(PyExc_ValueError,
 
2358
                            "ctypes object structure too deep");
 
2359
            return NULL;
 
2360
        }
 
2361
        cp += sprintf(cp, ":%x", Py_SAFE_DOWNCAST(target->b_index, Py_ssize_t, int));
 
2362
        target = target->b_base;
 
2363
    }
 
2364
    return PyUnicode_FromStringAndSize(string, cp-string);
2365
2365
}
2366
2366
 
2367
2367
/*
2385
2385
static int
2386
2386
KeepRef(CDataObject *target, Py_ssize_t index, PyObject *keep)
2387
2387
{
2388
 
        int result;
2389
 
        CDataObject *ob;
2390
 
        PyObject *key;
 
2388
    int result;
 
2389
    CDataObject *ob;
 
2390
    PyObject *key;
2391
2391
 
2392
2392
/* Optimization: no need to store None */
2393
 
        if (keep == Py_None) {
2394
 
                Py_DECREF(Py_None);
2395
 
                return 0;
2396
 
        }
2397
 
        ob = PyCData_GetContainer(target);
2398
 
        if (ob->b_objects == NULL || !PyDict_CheckExact(ob->b_objects)) {
2399
 
                Py_XDECREF(ob->b_objects);
2400
 
                ob->b_objects = keep; /* refcount consumed */
2401
 
                return 0;
2402
 
        }
2403
 
        key = unique_key(target, index);
2404
 
        if (key == NULL) {
2405
 
                Py_DECREF(keep);
2406
 
                return -1;
2407
 
        }
2408
 
        result = PyDict_SetItem(ob->b_objects, key, keep);
2409
 
        Py_DECREF(key);
2410
 
        Py_DECREF(keep);
2411
 
        return result;
 
2393
    if (keep == Py_None) {
 
2394
        Py_DECREF(Py_None);
 
2395
        return 0;
 
2396
    }
 
2397
    ob = PyCData_GetContainer(target);
 
2398
    if (ob->b_objects == NULL || !PyDict_CheckExact(ob->b_objects)) {
 
2399
        Py_XDECREF(ob->b_objects);
 
2400
        ob->b_objects = keep; /* refcount consumed */
 
2401
        return 0;
 
2402
    }
 
2403
    key = unique_key(target, index);
 
2404
    if (key == NULL) {
 
2405
        Py_DECREF(keep);
 
2406
        return -1;
 
2407
    }
 
2408
    result = PyDict_SetItem(ob->b_objects, key, keep);
 
2409
    Py_DECREF(key);
 
2410
    Py_DECREF(keep);
 
2411
    return result;
2412
2412
}
2413
2413
 
2414
2414
/******************************************************************/
2418
2418
static int
2419
2419
PyCData_traverse(CDataObject *self, visitproc visit, void *arg)
2420
2420
{
2421
 
        Py_VISIT(self->b_objects);
2422
 
        Py_VISIT((PyObject *)self->b_base);
2423
 
        return 0;
 
2421
    Py_VISIT(self->b_objects);
 
2422
    Py_VISIT((PyObject *)self->b_base);
 
2423
    return 0;
2424
2424
}
2425
2425
 
2426
2426
static int
2427
2427
PyCData_clear(CDataObject *self)
2428
2428
{
2429
 
        StgDictObject *dict = PyObject_stgdict((PyObject *)self);
2430
 
        assert(dict); /* Cannot be NULL for CDataObject instances */
2431
 
        Py_CLEAR(self->b_objects);
2432
 
        if ((self->b_needsfree)
2433
 
            && ((size_t)dict->size > sizeof(self->b_value)))
2434
 
                PyMem_Free(self->b_ptr);
2435
 
        self->b_ptr = NULL;
2436
 
        Py_CLEAR(self->b_base);
2437
 
        return 0;
 
2429
    StgDictObject *dict = PyObject_stgdict((PyObject *)self);
 
2430
    assert(dict); /* Cannot be NULL for CDataObject instances */
 
2431
    Py_CLEAR(self->b_objects);
 
2432
    if ((self->b_needsfree)
 
2433
        && ((size_t)dict->size > sizeof(self->b_value)))
 
2434
        PyMem_Free(self->b_ptr);
 
2435
    self->b_ptr = NULL;
 
2436
    Py_CLEAR(self->b_base);
 
2437
    return 0;
2438
2438
}
2439
2439
 
2440
2440
static void
2441
2441
PyCData_dealloc(PyObject *self)
2442
2442
{
2443
 
        PyCData_clear((CDataObject *)self);
2444
 
        Py_TYPE(self)->tp_free(self);
 
2443
    PyCData_clear((CDataObject *)self);
 
2444
    Py_TYPE(self)->tp_free(self);
2445
2445
}
2446
2446
 
2447
2447
static PyMemberDef PyCData_members[] = {
2448
 
        { "_b_base_", T_OBJECT,
2449
 
          offsetof(CDataObject, b_base), READONLY,
2450
 
          "the base object" },
2451
 
        { "_b_needsfree_", T_INT,
2452
 
          offsetof(CDataObject, b_needsfree), READONLY,
2453
 
          "whether the object owns the memory or not" },
2454
 
        { "_objects", T_OBJECT,
2455
 
          offsetof(CDataObject, b_objects), READONLY,
2456
 
          "internal objects tree (NEVER CHANGE THIS OBJECT!)"},
2457
 
        { NULL },
 
2448
    { "_b_base_", T_OBJECT,
 
2449
      offsetof(CDataObject, b_base), READONLY,
 
2450
      "the base object" },
 
2451
    { "_b_needsfree_", T_INT,
 
2452
      offsetof(CDataObject, b_needsfree), READONLY,
 
2453
      "whether the object owns the memory or not" },
 
2454
    { "_objects", T_OBJECT,
 
2455
      offsetof(CDataObject, b_objects), READONLY,
 
2456
      "internal objects tree (NEVER CHANGE THIS OBJECT!)"},
 
2457
    { NULL },
2458
2458
};
2459
2459
 
2460
2460
static int PyCData_NewGetBuffer(PyObject *_self, Py_buffer *view, int flags)
2461
2461
{
2462
 
        CDataObject *self = (CDataObject *)_self;
2463
 
        StgDictObject *dict = PyObject_stgdict(_self);
2464
 
        Py_ssize_t i;
2465
 
 
2466
 
        if (view == NULL) return 0;
2467
 
 
2468
 
        view->buf = self->b_ptr;
2469
 
        view->obj = _self;
2470
 
        Py_INCREF(_self);
2471
 
        view->len = self->b_size;
2472
 
        view->readonly = 0;
2473
 
        /* use default format character if not set */
2474
 
        view->format = dict->format ? dict->format : "B";
2475
 
        view->ndim = dict->ndim;
2476
 
        view->shape = dict->shape;
2477
 
        view->itemsize = self->b_size;
2478
 
        for (i = 0; i < view->ndim; ++i) {
2479
 
                view->itemsize /= dict->shape[i];
2480
 
        }
2481
 
        view->strides = NULL;
2482
 
        view->suboffsets = NULL;
2483
 
        view->internal = NULL;
2484
 
        return 0;
 
2462
    CDataObject *self = (CDataObject *)_self;
 
2463
    StgDictObject *dict = PyObject_stgdict(_self);
 
2464
    Py_ssize_t i;
 
2465
 
 
2466
    if (view == NULL) return 0;
 
2467
 
 
2468
    view->buf = self->b_ptr;
 
2469
    view->obj = _self;
 
2470
    Py_INCREF(_self);
 
2471
    view->len = self->b_size;
 
2472
    view->readonly = 0;
 
2473
    /* use default format character if not set */
 
2474
    view->format = dict->format ? dict->format : "B";
 
2475
    view->ndim = dict->ndim;
 
2476
    view->shape = dict->shape;
 
2477
    view->itemsize = self->b_size;
 
2478
    for (i = 0; i < view->ndim; ++i) {
 
2479
        view->itemsize /= dict->shape[i];
 
2480
    }
 
2481
    view->strides = NULL;
 
2482
    view->suboffsets = NULL;
 
2483
    view->internal = NULL;
 
2484
    return 0;
2485
2485
}
2486
2486
 
2487
2487
static PyBufferProcs PyCData_as_buffer = {
2488
 
        PyCData_NewGetBuffer,
2489
 
        NULL,
 
2488
    PyCData_NewGetBuffer,
 
2489
    NULL,
2490
2490
};
2491
2491
 
2492
2492
/*
2495
2495
static long
2496
2496
PyCData_nohash(PyObject *self)
2497
2497
{
2498
 
        PyErr_SetString(PyExc_TypeError, "unhashable type");
2499
 
        return -1;
 
2498
    PyErr_SetString(PyExc_TypeError, "unhashable type");
 
2499
    return -1;
2500
2500
}
2501
2501
 
2502
2502
static PyObject *
2503
2503
PyCData_reduce(PyObject *_self, PyObject *args)
2504
2504
{
2505
 
        CDataObject *self = (CDataObject *)_self;
 
2505
    CDataObject *self = (CDataObject *)_self;
2506
2506
 
2507
 
        if (PyObject_stgdict(_self)->flags & (TYPEFLAG_ISPOINTER|TYPEFLAG_HASPOINTER)) {
2508
 
                PyErr_SetString(PyExc_ValueError,
2509
 
                                "ctypes objects containing pointers cannot be pickled");
2510
 
                return NULL;
2511
 
        }
2512
 
        return Py_BuildValue("O(O(NN))",
2513
 
                             _unpickle,
2514
 
                             Py_TYPE(_self),
2515
 
                             PyObject_GetAttrString(_self, "__dict__"),
2516
 
                             PyBytes_FromStringAndSize(self->b_ptr, self->b_size));
 
2507
    if (PyObject_stgdict(_self)->flags & (TYPEFLAG_ISPOINTER|TYPEFLAG_HASPOINTER)) {
 
2508
        PyErr_SetString(PyExc_ValueError,
 
2509
                        "ctypes objects containing pointers cannot be pickled");
 
2510
        return NULL;
 
2511
    }
 
2512
    return Py_BuildValue("O(O(NN))",
 
2513
                         _unpickle,
 
2514
                         Py_TYPE(_self),
 
2515
                         PyObject_GetAttrString(_self, "__dict__"),
 
2516
                         PyBytes_FromStringAndSize(self->b_ptr, self->b_size));
2517
2517
}
2518
2518
 
2519
2519
static PyObject *
2520
2520
PyCData_setstate(PyObject *_self, PyObject *args)
2521
2521
{
2522
 
        void *data;
2523
 
        Py_ssize_t len;
2524
 
        int res;
2525
 
        PyObject *dict, *mydict;
2526
 
        CDataObject *self = (CDataObject *)_self;
2527
 
        if (!PyArg_ParseTuple(args, "Os#", &dict, &data, &len))
2528
 
                return NULL;
2529
 
        if (len > self->b_size)
2530
 
                len = self->b_size;
2531
 
        memmove(self->b_ptr, data, len);
2532
 
        mydict = PyObject_GetAttrString(_self, "__dict__");
2533
 
        res = PyDict_Update(mydict, dict);
2534
 
        Py_DECREF(mydict);
2535
 
        if (res == -1)
2536
 
                return NULL;
2537
 
        Py_INCREF(Py_None);
2538
 
        return Py_None;
 
2522
    void *data;
 
2523
    Py_ssize_t len;
 
2524
    int res;
 
2525
    PyObject *dict, *mydict;
 
2526
    CDataObject *self = (CDataObject *)_self;
 
2527
    if (!PyArg_ParseTuple(args, "Os#", &dict, &data, &len))
 
2528
        return NULL;
 
2529
    if (len > self->b_size)
 
2530
        len = self->b_size;
 
2531
    memmove(self->b_ptr, data, len);
 
2532
    mydict = PyObject_GetAttrString(_self, "__dict__");
 
2533
    res = PyDict_Update(mydict, dict);
 
2534
    Py_DECREF(mydict);
 
2535
    if (res == -1)
 
2536
        return NULL;
 
2537
    Py_INCREF(Py_None);
 
2538
    return Py_None;
2539
2539
}
2540
2540
 
2541
2541
/*
2544
2544
static PyObject *
2545
2545
PyCData_from_outparam(PyObject *self, PyObject *args)
2546
2546
{
2547
 
        Py_INCREF(self);
2548
 
        return self;
 
2547
    Py_INCREF(self);
 
2548
    return self;
2549
2549
}
2550
2550
 
2551
2551
static PyMethodDef PyCData_methods[] = {
2552
 
        { "__ctypes_from_outparam__", PyCData_from_outparam, METH_NOARGS, },
2553
 
        { "__reduce__", PyCData_reduce, METH_NOARGS, },
2554
 
        { "__setstate__", PyCData_setstate, METH_VARARGS, },
2555
 
        { NULL, NULL },
 
2552
    { "__ctypes_from_outparam__", PyCData_from_outparam, METH_NOARGS, },
 
2553
    { "__reduce__", PyCData_reduce, METH_NOARGS, },
 
2554
    { "__setstate__", PyCData_setstate, METH_VARARGS, },
 
2555
    { NULL, NULL },
2556
2556
};
2557
2557
 
2558
2558
PyTypeObject PyCData_Type = {
2559
 
        PyVarObject_HEAD_INIT(NULL, 0)
2560
 
        "_ctypes._CData",
2561
 
        sizeof(CDataObject),                    /* tp_basicsize */
2562
 
        0,                                      /* tp_itemsize */
2563
 
        PyCData_dealloc,                                /* tp_dealloc */
2564
 
        0,                                      /* tp_print */
2565
 
        0,                                      /* tp_getattr */
2566
 
        0,                                      /* tp_setattr */
2567
 
        0,                                      /* tp_reserved */
2568
 
        0,                                      /* tp_repr */
2569
 
        0,                                      /* tp_as_number */
2570
 
        0,                                      /* tp_as_sequence */
2571
 
        0,                                      /* tp_as_mapping */
2572
 
        PyCData_nohash,                         /* tp_hash */
2573
 
        0,                                      /* tp_call */
2574
 
        0,                                      /* tp_str */
2575
 
        0,                                      /* tp_getattro */
2576
 
        0,                                      /* tp_setattro */
2577
 
        &PyCData_as_buffer,                     /* tp_as_buffer */
2578
 
        Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2579
 
        "XXX to be provided",                   /* tp_doc */
2580
 
        (traverseproc)PyCData_traverse,         /* tp_traverse */
2581
 
        (inquiry)PyCData_clear,                 /* tp_clear */
2582
 
        0,                                      /* tp_richcompare */
2583
 
        0,                                      /* tp_weaklistoffset */
2584
 
        0,                                      /* tp_iter */
2585
 
        0,                                      /* tp_iternext */
2586
 
        PyCData_methods,                                /* tp_methods */
2587
 
        PyCData_members,                                /* tp_members */
2588
 
        0,                                      /* tp_getset */
2589
 
        0,                                      /* tp_base */
2590
 
        0,                                      /* tp_dict */
2591
 
        0,                                      /* tp_descr_get */
2592
 
        0,                                      /* tp_descr_set */
2593
 
        0,                                      /* tp_dictoffset */
2594
 
        0,                                      /* tp_init */
2595
 
        0,                                      /* tp_alloc */
2596
 
        0,                                      /* tp_new */
2597
 
        0,                                      /* tp_free */
 
2559
    PyVarObject_HEAD_INIT(NULL, 0)
 
2560
    "_ctypes._CData",
 
2561
    sizeof(CDataObject),                        /* tp_basicsize */
 
2562
    0,                                          /* tp_itemsize */
 
2563
    PyCData_dealloc,                                    /* tp_dealloc */
 
2564
    0,                                          /* tp_print */
 
2565
    0,                                          /* tp_getattr */
 
2566
    0,                                          /* tp_setattr */
 
2567
    0,                                          /* tp_reserved */
 
2568
    0,                                          /* tp_repr */
 
2569
    0,                                          /* tp_as_number */
 
2570
    0,                                          /* tp_as_sequence */
 
2571
    0,                                          /* tp_as_mapping */
 
2572
    PyCData_nohash,                             /* tp_hash */
 
2573
    0,                                          /* tp_call */
 
2574
    0,                                          /* tp_str */
 
2575
    0,                                          /* tp_getattro */
 
2576
    0,                                          /* tp_setattro */
 
2577
    &PyCData_as_buffer,                         /* tp_as_buffer */
 
2578
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
 
2579
    "XXX to be provided",                       /* tp_doc */
 
2580
    (traverseproc)PyCData_traverse,             /* tp_traverse */
 
2581
    (inquiry)PyCData_clear,                     /* tp_clear */
 
2582
    0,                                          /* tp_richcompare */
 
2583
    0,                                          /* tp_weaklistoffset */
 
2584
    0,                                          /* tp_iter */
 
2585
    0,                                          /* tp_iternext */
 
2586
    PyCData_methods,                                    /* tp_methods */
 
2587
    PyCData_members,                                    /* tp_members */
 
2588
    0,                                          /* tp_getset */
 
2589
    0,                                          /* tp_base */
 
2590
    0,                                          /* tp_dict */
 
2591
    0,                                          /* tp_descr_get */
 
2592
    0,                                          /* tp_descr_set */
 
2593
    0,                                          /* tp_dictoffset */
 
2594
    0,                                          /* tp_init */
 
2595
    0,                                          /* tp_alloc */
 
2596
    0,                                          /* tp_new */
 
2597
    0,                                          /* tp_free */
2598
2598
};
2599
2599
 
2600
2600
static int PyCData_MallocBuffer(CDataObject *obj, StgDictObject *dict)
2601
2601
{
2602
 
        if ((size_t)dict->size <= sizeof(obj->b_value)) {
2603
 
                /* No need to call malloc, can use the default buffer */
2604
 
                obj->b_ptr = (char *)&obj->b_value;
2605
 
                /* The b_needsfree flag does not mean that we actually did
2606
 
                   call PyMem_Malloc to allocate the memory block; instead it
2607
 
                   means we are the *owner* of the memory and are responsible
2608
 
                   for freeing resources associated with the memory.  This is
2609
 
                   also the reason that b_needsfree is exposed to Python.
2610
 
                 */
2611
 
                obj->b_needsfree = 1;
2612
 
        } else {
2613
 
                /* In python 2.4, and ctypes 0.9.6, the malloc call took about
2614
 
                   33% of the creation time for c_int().
2615
 
                */
2616
 
                obj->b_ptr = (char *)PyMem_Malloc(dict->size);
2617
 
                if (obj->b_ptr == NULL) {
2618
 
                        PyErr_NoMemory();
2619
 
                        return -1;
2620
 
                }
2621
 
                obj->b_needsfree = 1;
2622
 
                memset(obj->b_ptr, 0, dict->size);
2623
 
        }
2624
 
        obj->b_size = dict->size;
2625
 
        return 0;
 
2602
    if ((size_t)dict->size <= sizeof(obj->b_value)) {
 
2603
        /* No need to call malloc, can use the default buffer */
 
2604
        obj->b_ptr = (char *)&obj->b_value;
 
2605
        /* The b_needsfree flag does not mean that we actually did
 
2606
           call PyMem_Malloc to allocate the memory block; instead it
 
2607
           means we are the *owner* of the memory and are responsible
 
2608
           for freeing resources associated with the memory.  This is
 
2609
           also the reason that b_needsfree is exposed to Python.
 
2610
         */
 
2611
        obj->b_needsfree = 1;
 
2612
    } else {
 
2613
        /* In python 2.4, and ctypes 0.9.6, the malloc call took about
 
2614
           33% of the creation time for c_int().
 
2615
        */
 
2616
        obj->b_ptr = (char *)PyMem_Malloc(dict->size);
 
2617
        if (obj->b_ptr == NULL) {
 
2618
            PyErr_NoMemory();
 
2619
            return -1;
 
2620
        }
 
2621
        obj->b_needsfree = 1;
 
2622
        memset(obj->b_ptr, 0, dict->size);
 
2623
    }
 
2624
    obj->b_size = dict->size;
 
2625
    return 0;
2626
2626
}
2627
2627
 
2628
2628
PyObject *
2629
2629
PyCData_FromBaseObj(PyObject *type, PyObject *base, Py_ssize_t index, char *adr)
2630
2630
{
2631
 
        CDataObject *cmem;
2632
 
        StgDictObject *dict;
2633
 
 
2634
 
        assert(PyType_Check(type));
2635
 
        dict = PyType_stgdict(type);
2636
 
        if (!dict) {
2637
 
                PyErr_SetString(PyExc_TypeError,
2638
 
                                "abstract class");
2639
 
                return NULL;
2640
 
        }
2641
 
        dict->flags |= DICTFLAG_FINAL;
2642
 
        cmem = (CDataObject *)((PyTypeObject *)type)->tp_alloc((PyTypeObject *)type, 0);
2643
 
        if (cmem == NULL)
2644
 
                return NULL;
2645
 
        assert(CDataObject_Check(cmem));
2646
 
 
2647
 
        cmem->b_length = dict->length;
2648
 
        cmem->b_size = dict->size;
2649
 
        if (base) { /* use base's buffer */
2650
 
                assert(CDataObject_Check(base));
2651
 
                cmem->b_ptr = adr;
2652
 
                cmem->b_needsfree = 0;
2653
 
                Py_INCREF(base);
2654
 
                cmem->b_base = (CDataObject *)base;
2655
 
                cmem->b_index = index;
2656
 
        } else { /* copy contents of adr */
2657
 
                if (-1 == PyCData_MallocBuffer(cmem, dict)) {
2658
 
                        return NULL;
2659
 
                        Py_DECREF(cmem);
2660
 
                }
2661
 
                memcpy(cmem->b_ptr, adr, dict->size);
2662
 
                cmem->b_index = index;
2663
 
        }
2664
 
        return (PyObject *)cmem;
 
2631
    CDataObject *cmem;
 
2632
    StgDictObject *dict;
 
2633
 
 
2634
    assert(PyType_Check(type));
 
2635
    dict = PyType_stgdict(type);
 
2636
    if (!dict) {
 
2637
        PyErr_SetString(PyExc_TypeError,
 
2638
                        "abstract class");
 
2639
        return NULL;
 
2640
    }
 
2641
    dict->flags |= DICTFLAG_FINAL;
 
2642
    cmem = (CDataObject *)((PyTypeObject *)type)->tp_alloc((PyTypeObject *)type, 0);
 
2643
    if (cmem == NULL)
 
2644
        return NULL;
 
2645
    assert(CDataObject_Check(cmem));
 
2646
 
 
2647
    cmem->b_length = dict->length;
 
2648
    cmem->b_size = dict->size;
 
2649
    if (base) { /* use base's buffer */
 
2650
        assert(CDataObject_Check(base));
 
2651
        cmem->b_ptr = adr;
 
2652
        cmem->b_needsfree = 0;
 
2653
        Py_INCREF(base);
 
2654
        cmem->b_base = (CDataObject *)base;
 
2655
        cmem->b_index = index;
 
2656
    } else { /* copy contents of adr */
 
2657
        if (-1 == PyCData_MallocBuffer(cmem, dict)) {
 
2658
            return NULL;
 
2659
            Py_DECREF(cmem);
 
2660
        }
 
2661
        memcpy(cmem->b_ptr, adr, dict->size);
 
2662
        cmem->b_index = index;
 
2663
    }
 
2664
    return (PyObject *)cmem;
2665
2665
}
2666
2666
 
2667
2667
/*
2670
2670
PyObject *
2671
2671
PyCData_AtAddress(PyObject *type, void *buf)
2672
2672
{
2673
 
        CDataObject *pd;
2674
 
        StgDictObject *dict;
2675
 
 
2676
 
        assert(PyType_Check(type));
2677
 
        dict = PyType_stgdict(type);
2678
 
        if (!dict) {
2679
 
                PyErr_SetString(PyExc_TypeError,
2680
 
                                "abstract class");
2681
 
                return NULL;
2682
 
        }
2683
 
        dict->flags |= DICTFLAG_FINAL;
2684
 
 
2685
 
        pd = (CDataObject *)((PyTypeObject *)type)->tp_alloc((PyTypeObject *)type, 0);
2686
 
        if (!pd)
2687
 
                return NULL;
2688
 
        assert(CDataObject_Check(pd));
2689
 
        pd->b_ptr = (char *)buf;
2690
 
        pd->b_length = dict->length;
2691
 
        pd->b_size = dict->size;
2692
 
        return (PyObject *)pd;
 
2673
    CDataObject *pd;
 
2674
    StgDictObject *dict;
 
2675
 
 
2676
    assert(PyType_Check(type));
 
2677
    dict = PyType_stgdict(type);
 
2678
    if (!dict) {
 
2679
        PyErr_SetString(PyExc_TypeError,
 
2680
                        "abstract class");
 
2681
        return NULL;
 
2682
    }
 
2683
    dict->flags |= DICTFLAG_FINAL;
 
2684
 
 
2685
    pd = (CDataObject *)((PyTypeObject *)type)->tp_alloc((PyTypeObject *)type, 0);
 
2686
    if (!pd)
 
2687
        return NULL;
 
2688
    assert(CDataObject_Check(pd));
 
2689
    pd->b_ptr = (char *)buf;
 
2690
    pd->b_length = dict->length;
 
2691
    pd->b_size = dict->size;
 
2692
    return (PyObject *)pd;
2693
2693
}
2694
2694
 
2695
2695
/*
2699
2699
*/
2700
2700
int _ctypes_simple_instance(PyObject *obj)
2701
2701
{
2702
 
        PyTypeObject *type = (PyTypeObject *)obj;
 
2702
    PyTypeObject *type = (PyTypeObject *)obj;
2703
2703
 
2704
 
        if (PyCSimpleTypeObject_Check(type))
2705
 
                return type->tp_base != &Simple_Type;
2706
 
        return 0;
 
2704
    if (PyCSimpleTypeObject_Check(type))
 
2705
        return type->tp_base != &Simple_Type;
 
2706
    return 0;
2707
2707
}
2708
2708
 
2709
2709
PyObject *
2710
2710
PyCData_get(PyObject *type, GETFUNC getfunc, PyObject *src,
2711
 
          Py_ssize_t index, Py_ssize_t size, char *adr)
 
2711
          Py_ssize_t index, Py_ssize_t size, char *adr)
2712
2712
{
2713
 
        StgDictObject *dict;
2714
 
        if (getfunc)
2715
 
                return getfunc(adr, size);
2716
 
        assert(type);
2717
 
        dict = PyType_stgdict(type);
2718
 
        if (dict && dict->getfunc && !_ctypes_simple_instance(type))
2719
 
                return dict->getfunc(adr, size);
2720
 
        return PyCData_FromBaseObj(type, src, index, adr);
 
2713
    StgDictObject *dict;
 
2714
    if (getfunc)
 
2715
        return getfunc(adr, size);
 
2716
    assert(type);
 
2717
    dict = PyType_stgdict(type);
 
2718
    if (dict && dict->getfunc && !_ctypes_simple_instance(type))
 
2719
        return dict->getfunc(adr, size);
 
2720
    return PyCData_FromBaseObj(type, src, index, adr);
2721
2721
}
2722
2722
 
2723
2723
/*
2725
2725
*/
2726
2726
static PyObject *
2727
2727
_PyCData_set(CDataObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
2728
 
           Py_ssize_t size, char *ptr)
 
2728
           Py_ssize_t size, char *ptr)
2729
2729
{
2730
 
        CDataObject *src;
2731
 
 
2732
 
        if (setfunc)
2733
 
                return setfunc(ptr, value, size);
2734
 
        
2735
 
        if (!CDataObject_Check(value)) {
2736
 
                StgDictObject *dict = PyType_stgdict(type);
2737
 
                if (dict && dict->setfunc)
2738
 
                        return dict->setfunc(ptr, value, size);
2739
 
                /*
2740
 
                   If value is a tuple, we try to call the type with the tuple
2741
 
                   and use the result!
2742
 
                */
2743
 
                assert(PyType_Check(type));
2744
 
                if (PyTuple_Check(value)) {
2745
 
                        PyObject *ob;
2746
 
                        PyObject *result;
2747
 
                        ob = PyObject_CallObject(type, value);
2748
 
                        if (ob == NULL) {
2749
 
                                _ctypes_extend_error(PyExc_RuntimeError, "(%s) ",
2750
 
                                                  ((PyTypeObject *)type)->tp_name);
2751
 
                                return NULL;
2752
 
                        }
2753
 
                        result = _PyCData_set(dst, type, setfunc, ob,
2754
 
                                            size, ptr);
2755
 
                        Py_DECREF(ob);
2756
 
                        return result;
2757
 
                } else if (value == Py_None && PyCPointerTypeObject_Check(type)) {
2758
 
                        *(void **)ptr = NULL;
2759
 
                        Py_INCREF(Py_None);
2760
 
                        return Py_None;
2761
 
                } else {
2762
 
                        PyErr_Format(PyExc_TypeError,
2763
 
                                     "expected %s instance, got %s",
2764
 
                                     ((PyTypeObject *)type)->tp_name,
2765
 
                                     Py_TYPE(value)->tp_name);
2766
 
                        return NULL;
2767
 
                }
2768
 
        }
2769
 
        src = (CDataObject *)value;
2770
 
 
2771
 
        if (PyObject_IsInstance(value, type)) {
2772
 
                memcpy(ptr,
2773
 
                       src->b_ptr,
2774
 
                       size);
2775
 
 
2776
 
                if (PyCPointerTypeObject_Check(type))
2777
 
                        /* XXX */;
2778
 
 
2779
 
                value = GetKeepedObjects(src);
2780
 
                Py_INCREF(value);
2781
 
                return value;
2782
 
        }
2783
 
 
2784
 
        if (PyCPointerTypeObject_Check(type)
2785
 
            && ArrayObject_Check(value)) {
2786
 
                StgDictObject *p1, *p2;
2787
 
                PyObject *keep;
2788
 
                p1 = PyObject_stgdict(value);
2789
 
                assert(p1); /* Cannot be NULL for array instances */
2790
 
                p2 = PyType_stgdict(type);
2791
 
                assert(p2); /* Cannot be NULL for pointer types */
2792
 
 
2793
 
                if (p1->proto != p2->proto) {
2794
 
                        PyErr_Format(PyExc_TypeError,
2795
 
                                     "incompatible types, %s instance instead of %s instance",
2796
 
                                     Py_TYPE(value)->tp_name,
2797
 
                                     ((PyTypeObject *)type)->tp_name);
2798
 
                        return NULL;
2799
 
                }
2800
 
                *(void **)ptr = src->b_ptr;
2801
 
 
2802
 
                keep = GetKeepedObjects(src);
2803
 
                /*
2804
 
                  We are assigning an array object to a field which represents
2805
 
                  a pointer. This has the same effect as converting an array
2806
 
                  into a pointer. So, again, we have to keep the whole object
2807
 
                  pointed to (which is the array in this case) alive, and not
2808
 
                  only it's object list.  So we create a tuple, containing
2809
 
                  b_objects list PLUS the array itself, and return that!
2810
 
                */
2811
 
                return PyTuple_Pack(2, keep, value);
2812
 
        }
2813
 
        PyErr_Format(PyExc_TypeError,
2814
 
                     "incompatible types, %s instance instead of %s instance",
2815
 
                     Py_TYPE(value)->tp_name,
2816
 
                     ((PyTypeObject *)type)->tp_name);
2817
 
        return NULL;
 
2730
    CDataObject *src;
 
2731
 
 
2732
    if (setfunc)
 
2733
        return setfunc(ptr, value, size);
 
2734
 
 
2735
    if (!CDataObject_Check(value)) {
 
2736
        StgDictObject *dict = PyType_stgdict(type);
 
2737
        if (dict && dict->setfunc)
 
2738
            return dict->setfunc(ptr, value, size);
 
2739
        /*
 
2740
           If value is a tuple, we try to call the type with the tuple
 
2741
           and use the result!
 
2742
        */
 
2743
        assert(PyType_Check(type));
 
2744
        if (PyTuple_Check(value)) {
 
2745
            PyObject *ob;
 
2746
            PyObject *result;
 
2747
            ob = PyObject_CallObject(type, value);
 
2748
            if (ob == NULL) {
 
2749
                _ctypes_extend_error(PyExc_RuntimeError, "(%s) ",
 
2750
                                  ((PyTypeObject *)type)->tp_name);
 
2751
                return NULL;
 
2752
            }
 
2753
            result = _PyCData_set(dst, type, setfunc, ob,
 
2754
                                size, ptr);
 
2755
            Py_DECREF(ob);
 
2756
            return result;
 
2757
        } else if (value == Py_None && PyCPointerTypeObject_Check(type)) {
 
2758
            *(void **)ptr = NULL;
 
2759
            Py_INCREF(Py_None);
 
2760
            return Py_None;
 
2761
        } else {
 
2762
            PyErr_Format(PyExc_TypeError,
 
2763
                         "expected %s instance, got %s",
 
2764
                         ((PyTypeObject *)type)->tp_name,
 
2765
                         Py_TYPE(value)->tp_name);
 
2766
            return NULL;
 
2767
        }
 
2768
    }
 
2769
    src = (CDataObject *)value;
 
2770
 
 
2771
    if (PyObject_IsInstance(value, type)) {
 
2772
        memcpy(ptr,
 
2773
               src->b_ptr,
 
2774
               size);
 
2775
 
 
2776
        if (PyCPointerTypeObject_Check(type))
 
2777
            /* XXX */;
 
2778
 
 
2779
        value = GetKeepedObjects(src);
 
2780
        Py_INCREF(value);
 
2781
        return value;
 
2782
    }
 
2783
 
 
2784
    if (PyCPointerTypeObject_Check(type)
 
2785
        && ArrayObject_Check(value)) {
 
2786
        StgDictObject *p1, *p2;
 
2787
        PyObject *keep;
 
2788
        p1 = PyObject_stgdict(value);
 
2789
        assert(p1); /* Cannot be NULL for array instances */
 
2790
        p2 = PyType_stgdict(type);
 
2791
        assert(p2); /* Cannot be NULL for pointer types */
 
2792
 
 
2793
        if (p1->proto != p2->proto) {
 
2794
            PyErr_Format(PyExc_TypeError,
 
2795
                         "incompatible types, %s instance instead of %s instance",
 
2796
                         Py_TYPE(value)->tp_name,
 
2797
                         ((PyTypeObject *)type)->tp_name);
 
2798
            return NULL;
 
2799
        }
 
2800
        *(void **)ptr = src->b_ptr;
 
2801
 
 
2802
        keep = GetKeepedObjects(src);
 
2803
        /*
 
2804
          We are assigning an array object to a field which represents
 
2805
          a pointer. This has the same effect as converting an array
 
2806
          into a pointer. So, again, we have to keep the whole object
 
2807
          pointed to (which is the array in this case) alive, and not
 
2808
          only it's object list.  So we create a tuple, containing
 
2809
          b_objects list PLUS the array itself, and return that!
 
2810
        */
 
2811
        return PyTuple_Pack(2, keep, value);
 
2812
    }
 
2813
    PyErr_Format(PyExc_TypeError,
 
2814
                 "incompatible types, %s instance instead of %s instance",
 
2815
                 Py_TYPE(value)->tp_name,
 
2816
                 ((PyTypeObject *)type)->tp_name);
 
2817
    return NULL;
2818
2818
}
2819
2819
 
2820
2820
/*
2823
2823
 */
2824
2824
int
2825
2825
PyCData_set(PyObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
2826
 
          Py_ssize_t index, Py_ssize_t size, char *ptr)
 
2826
          Py_ssize_t index, Py_ssize_t size, char *ptr)
2827
2827
{
2828
 
        CDataObject *mem = (CDataObject *)dst;
2829
 
        PyObject *result;
2830
 
 
2831
 
        if (!CDataObject_Check(dst)) {
2832
 
                PyErr_SetString(PyExc_TypeError,
2833
 
                                "not a ctype instance");
2834
 
                return -1;
2835
 
        }
2836
 
 
2837
 
        result = _PyCData_set(mem, type, setfunc, value,
2838
 
                            size, ptr);
2839
 
        if (result == NULL)
2840
 
                return -1;
2841
 
 
2842
 
        /* KeepRef steals a refcount from it's last argument */
2843
 
        /* If KeepRef fails, we are stumped.  The dst memory block has already
2844
 
           been changed */
2845
 
        return KeepRef(mem, index, result);
 
2828
    CDataObject *mem = (CDataObject *)dst;
 
2829
    PyObject *result;
 
2830
 
 
2831
    if (!CDataObject_Check(dst)) {
 
2832
        PyErr_SetString(PyExc_TypeError,
 
2833
                        "not a ctype instance");
 
2834
        return -1;
 
2835
    }
 
2836
 
 
2837
    result = _PyCData_set(mem, type, setfunc, value,
 
2838
                        size, ptr);
 
2839
    if (result == NULL)
 
2840
        return -1;
 
2841
 
 
2842
    /* KeepRef steals a refcount from it's last argument */
 
2843
    /* If KeepRef fails, we are stumped.  The dst memory block has already
 
2844
       been changed */
 
2845
    return KeepRef(mem, index, result);
2846
2846
}
2847
2847
 
2848
 
 
 
2848
 
2849
2849
/******************************************************************/
2850
2850
static PyObject *
2851
2851
GenericPyCData_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2852
2852
{
2853
 
        CDataObject *obj;
2854
 
        StgDictObject *dict;
2855
 
 
2856
 
        dict = PyType_stgdict((PyObject *)type);
2857
 
        if (!dict) {
2858
 
                PyErr_SetString(PyExc_TypeError,
2859
 
                                "abstract class");
2860
 
                return NULL;
2861
 
        }
2862
 
        dict->flags |= DICTFLAG_FINAL;
2863
 
 
2864
 
        obj = (CDataObject *)type->tp_alloc(type, 0);
2865
 
        if (!obj)
2866
 
                return NULL;
2867
 
 
2868
 
        obj->b_base = NULL;
2869
 
        obj->b_index = 0;
2870
 
        obj->b_objects = NULL;
2871
 
        obj->b_length = dict->length;
2872
 
                        
2873
 
        if (-1 == PyCData_MallocBuffer(obj, dict)) {
2874
 
                Py_DECREF(obj);
2875
 
                return NULL;
2876
 
        }
2877
 
        return (PyObject *)obj;
 
2853
    CDataObject *obj;
 
2854
    StgDictObject *dict;
 
2855
 
 
2856
    dict = PyType_stgdict((PyObject *)type);
 
2857
    if (!dict) {
 
2858
        PyErr_SetString(PyExc_TypeError,
 
2859
                        "abstract class");
 
2860
        return NULL;
 
2861
    }
 
2862
    dict->flags |= DICTFLAG_FINAL;
 
2863
 
 
2864
    obj = (CDataObject *)type->tp_alloc(type, 0);
 
2865
    if (!obj)
 
2866
        return NULL;
 
2867
 
 
2868
    obj->b_base = NULL;
 
2869
    obj->b_index = 0;
 
2870
    obj->b_objects = NULL;
 
2871
    obj->b_length = dict->length;
 
2872
 
 
2873
    if (-1 == PyCData_MallocBuffer(obj, dict)) {
 
2874
        Py_DECREF(obj);
 
2875
        return NULL;
 
2876
    }
 
2877
    return (PyObject *)obj;
2878
2878
}
2879
2879
/*****************************************************************/
2880
2880
/*
2884
2884
static int
2885
2885
PyCFuncPtr_set_errcheck(PyCFuncPtrObject *self, PyObject *ob)
2886
2886
{
2887
 
        if (ob && !PyCallable_Check(ob)) {
2888
 
                PyErr_SetString(PyExc_TypeError,
2889
 
                                "the errcheck attribute must be callable");
2890
 
                return -1;
2891
 
        }
2892
 
        Py_XDECREF(self->errcheck);
2893
 
        Py_XINCREF(ob);
2894
 
        self->errcheck = ob;
2895
 
        return 0;
 
2887
    if (ob && !PyCallable_Check(ob)) {
 
2888
        PyErr_SetString(PyExc_TypeError,
 
2889
                        "the errcheck attribute must be callable");
 
2890
        return -1;
 
2891
    }
 
2892
    Py_XDECREF(self->errcheck);
 
2893
    Py_XINCREF(ob);
 
2894
    self->errcheck = ob;
 
2895
    return 0;
2896
2896
}
2897
2897
 
2898
2898
static PyObject *
2899
2899
PyCFuncPtr_get_errcheck(PyCFuncPtrObject *self)
2900
2900
{
2901
 
        if (self->errcheck) {
2902
 
                Py_INCREF(self->errcheck);
2903
 
                return self->errcheck;
2904
 
        }
2905
 
        Py_INCREF(Py_None);
2906
 
        return Py_None;
 
2901
    if (self->errcheck) {
 
2902
        Py_INCREF(self->errcheck);
 
2903
        return self->errcheck;
 
2904
    }
 
2905
    Py_INCREF(Py_None);
 
2906
    return Py_None;
2907
2907
}
2908
2908
 
2909
2909
static int
2910
2910
PyCFuncPtr_set_restype(PyCFuncPtrObject *self, PyObject *ob)
2911
2911
{
2912
 
        if (ob == NULL) {
2913
 
                Py_XDECREF(self->restype);
2914
 
                self->restype = NULL;
2915
 
                Py_XDECREF(self->checker);
2916
 
                self->checker = NULL;
2917
 
                return 0;
2918
 
        }
2919
 
        if (ob != Py_None && !PyType_stgdict(ob) && !PyCallable_Check(ob)) {
2920
 
                PyErr_SetString(PyExc_TypeError,
2921
 
                                "restype must be a type, a callable, or None");
2922
 
                return -1;
2923
 
        }
2924
 
        Py_XDECREF(self->checker);
2925
 
        Py_XDECREF(self->restype);
2926
 
        Py_INCREF(ob);
2927
 
        self->restype = ob;
2928
 
        self->checker = PyObject_GetAttrString(ob, "_check_retval_");
2929
 
        if (self->checker == NULL)
2930
 
                PyErr_Clear();
2931
 
        return 0;
 
2912
    if (ob == NULL) {
 
2913
        Py_XDECREF(self->restype);
 
2914
        self->restype = NULL;
 
2915
        Py_XDECREF(self->checker);
 
2916
        self->checker = NULL;
 
2917
        return 0;
 
2918
    }
 
2919
    if (ob != Py_None && !PyType_stgdict(ob) && !PyCallable_Check(ob)) {
 
2920
        PyErr_SetString(PyExc_TypeError,
 
2921
                        "restype must be a type, a callable, or None");
 
2922
        return -1;
 
2923
    }
 
2924
    Py_XDECREF(self->checker);
 
2925
    Py_XDECREF(self->restype);
 
2926
    Py_INCREF(ob);
 
2927
    self->restype = ob;
 
2928
    self->checker = PyObject_GetAttrString(ob, "_check_retval_");
 
2929
    if (self->checker == NULL)
 
2930
        PyErr_Clear();
 
2931
    return 0;
2932
2932
}
2933
2933
 
2934
2934
static PyObject *
2935
2935
PyCFuncPtr_get_restype(PyCFuncPtrObject *self)
2936
2936
{
2937
 
        StgDictObject *dict;
2938
 
        if (self->restype) {
2939
 
                Py_INCREF(self->restype);
2940
 
                return self->restype;
2941
 
        }
2942
 
        dict = PyObject_stgdict((PyObject *)self);
2943
 
        assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */
2944
 
        if (dict->restype) {
2945
 
                Py_INCREF(dict->restype);
2946
 
                return dict->restype;
2947
 
        } else {
2948
 
                Py_INCREF(Py_None);
2949
 
                return Py_None;
2950
 
        }
 
2937
    StgDictObject *dict;
 
2938
    if (self->restype) {
 
2939
        Py_INCREF(self->restype);
 
2940
        return self->restype;
 
2941
    }
 
2942
    dict = PyObject_stgdict((PyObject *)self);
 
2943
    assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */
 
2944
    if (dict->restype) {
 
2945
        Py_INCREF(dict->restype);
 
2946
        return dict->restype;
 
2947
    } else {
 
2948
        Py_INCREF(Py_None);
 
2949
        return Py_None;
 
2950
    }
2951
2951
}
2952
2952
 
2953
2953
static int
2954
2954
PyCFuncPtr_set_argtypes(PyCFuncPtrObject *self, PyObject *ob)
2955
2955
{
2956
 
        PyObject *converters;
 
2956
    PyObject *converters;
2957
2957
 
2958
 
        if (ob == NULL || ob == Py_None) {
2959
 
                Py_XDECREF(self->converters);
2960
 
                self->converters = NULL;
2961
 
                Py_XDECREF(self->argtypes);
2962
 
                self->argtypes = NULL;
2963
 
        } else {
2964
 
                converters = converters_from_argtypes(ob);
2965
 
                if (!converters)
2966
 
                        return -1;
2967
 
                Py_XDECREF(self->converters);
2968
 
                self->converters = converters;
2969
 
                Py_XDECREF(self->argtypes);
2970
 
                Py_INCREF(ob);
2971
 
                self->argtypes = ob;
2972
 
        }
2973
 
        return 0;
 
2958
    if (ob == NULL || ob == Py_None) {
 
2959
        Py_XDECREF(self->converters);
 
2960
        self->converters = NULL;
 
2961
        Py_XDECREF(self->argtypes);
 
2962
        self->argtypes = NULL;
 
2963
    } else {
 
2964
        converters = converters_from_argtypes(ob);
 
2965
        if (!converters)
 
2966
            return -1;
 
2967
        Py_XDECREF(self->converters);
 
2968
        self->converters = converters;
 
2969
        Py_XDECREF(self->argtypes);
 
2970
        Py_INCREF(ob);
 
2971
        self->argtypes = ob;
 
2972
    }
 
2973
    return 0;
2974
2974
}
2975
2975
 
2976
2976
static PyObject *
2977
2977
PyCFuncPtr_get_argtypes(PyCFuncPtrObject *self)
2978
2978
{
2979
 
        StgDictObject *dict;
2980
 
        if (self->argtypes) {
2981
 
                Py_INCREF(self->argtypes);
2982
 
                return self->argtypes;
2983
 
        }
2984
 
        dict = PyObject_stgdict((PyObject *)self);
2985
 
        assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */
2986
 
        if (dict->argtypes) {
2987
 
                Py_INCREF(dict->argtypes);
2988
 
                return dict->argtypes;
2989
 
        } else {
2990
 
                Py_INCREF(Py_None);
2991
 
                return Py_None;
2992
 
        }
 
2979
    StgDictObject *dict;
 
2980
    if (self->argtypes) {
 
2981
        Py_INCREF(self->argtypes);
 
2982
        return self->argtypes;
 
2983
    }
 
2984
    dict = PyObject_stgdict((PyObject *)self);
 
2985
    assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */
 
2986
    if (dict->argtypes) {
 
2987
        Py_INCREF(dict->argtypes);
 
2988
        return dict->argtypes;
 
2989
    } else {
 
2990
        Py_INCREF(Py_None);
 
2991
        return Py_None;
 
2992
    }
2993
2993
}
2994
2994
 
2995
2995
static PyGetSetDef PyCFuncPtr_getsets[] = {
2996
 
        { "errcheck", (getter)PyCFuncPtr_get_errcheck, (setter)PyCFuncPtr_set_errcheck,
2997
 
          "a function to check for errors", NULL },
2998
 
        { "restype", (getter)PyCFuncPtr_get_restype, (setter)PyCFuncPtr_set_restype,
2999
 
          "specify the result type", NULL },
3000
 
        { "argtypes", (getter)PyCFuncPtr_get_argtypes,
3001
 
          (setter)PyCFuncPtr_set_argtypes,
3002
 
          "specify the argument types", NULL },
3003
 
        { NULL, NULL }
 
2996
    { "errcheck", (getter)PyCFuncPtr_get_errcheck, (setter)PyCFuncPtr_set_errcheck,
 
2997
      "a function to check for errors", NULL },
 
2998
    { "restype", (getter)PyCFuncPtr_get_restype, (setter)PyCFuncPtr_set_restype,
 
2999
      "specify the result type", NULL },
 
3000
    { "argtypes", (getter)PyCFuncPtr_get_argtypes,
 
3001
      (setter)PyCFuncPtr_set_argtypes,
 
3002
      "specify the argument types", NULL },
 
3003
    { NULL, NULL }
3004
3004
};
3005
3005
 
3006
3006
#ifdef MS_WIN32
3007
3007
static PPROC FindAddress(void *handle, char *name, PyObject *type)
3008
3008
{
3009
3009
#ifdef MS_WIN64
3010
 
        /* win64 has no stdcall calling conv, so it should
3011
 
           also not have the name mangling of it.
3012
 
        */
3013
 
        return (PPROC)GetProcAddress(handle, name);
 
3010
    /* win64 has no stdcall calling conv, so it should
 
3011
       also not have the name mangling of it.
 
3012
    */
 
3013
    return (PPROC)GetProcAddress(handle, name);
3014
3014
#else
3015
 
        PPROC address;
3016
 
        char *mangled_name;
3017
 
        int i;
3018
 
        StgDictObject *dict;
3019
 
 
3020
 
        address = (PPROC)GetProcAddress(handle, name);
3021
 
        if (address)
3022
 
                return address;
3023
 
        if (((size_t)name & ~0xFFFF) == 0) {
3024
 
                return NULL;
3025
 
        }
3026
 
 
3027
 
        dict = PyType_stgdict((PyObject *)type);
3028
 
        /* It should not happen that dict is NULL, but better be safe */
3029
 
        if (dict==NULL || dict->flags & FUNCFLAG_CDECL)
3030
 
                return address;
3031
 
 
3032
 
        /* for stdcall, try mangled names:
3033
 
           funcname -> _funcname@<n>
3034
 
           where n is 0, 4, 8, 12, ..., 128
3035
 
         */
3036
 
        mangled_name = alloca(strlen(name) + 1 + 1 + 1 + 3); /* \0 _ @ %d */
3037
 
        if (!mangled_name)
3038
 
                return NULL;
3039
 
        for (i = 0; i < 32; ++i) {
3040
 
                sprintf(mangled_name, "_%s@%d", name, i*4);
3041
 
                address = (PPROC)GetProcAddress(handle, mangled_name);
3042
 
                if (address)
3043
 
                        return address;
3044
 
        }
3045
 
        return NULL;
 
3015
    PPROC address;
 
3016
    char *mangled_name;
 
3017
    int i;
 
3018
    StgDictObject *dict;
 
3019
 
 
3020
    address = (PPROC)GetProcAddress(handle, name);
 
3021
    if (address)
 
3022
        return address;
 
3023
    if (((size_t)name & ~0xFFFF) == 0) {
 
3024
        return NULL;
 
3025
    }
 
3026
 
 
3027
    dict = PyType_stgdict((PyObject *)type);
 
3028
    /* It should not happen that dict is NULL, but better be safe */
 
3029
    if (dict==NULL || dict->flags & FUNCFLAG_CDECL)
 
3030
        return address;
 
3031
 
 
3032
    /* for stdcall, try mangled names:
 
3033
       funcname -> _funcname@<n>
 
3034
       where n is 0, 4, 8, 12, ..., 128
 
3035
     */
 
3036
    mangled_name = alloca(strlen(name) + 1 + 1 + 1 + 3); /* \0 _ @ %d */
 
3037
    if (!mangled_name)
 
3038
        return NULL;
 
3039
    for (i = 0; i < 32; ++i) {
 
3040
        sprintf(mangled_name, "_%s@%d", name, i*4);
 
3041
        address = (PPROC)GetProcAddress(handle, mangled_name);
 
3042
        if (address)
 
3043
            return address;
 
3044
    }
 
3045
    return NULL;
3046
3046
#endif
3047
3047
}
3048
3048
#endif
3051
3051
static int
3052
3052
_check_outarg_type(PyObject *arg, Py_ssize_t index)
3053
3053
{
3054
 
        StgDictObject *dict;
3055
 
 
3056
 
        if (PyCPointerTypeObject_Check(arg))
3057
 
                return 1;
3058
 
 
3059
 
        if (PyCArrayTypeObject_Check(arg))
3060
 
                return 1;
3061
 
 
3062
 
        dict = PyType_stgdict(arg);
3063
 
        if (dict
3064
 
            /* simple pointer types, c_void_p, c_wchar_p, BSTR, ... */
3065
 
            && PyUnicode_Check(dict->proto)
 
3054
    StgDictObject *dict;
 
3055
 
 
3056
    if (PyCPointerTypeObject_Check(arg))
 
3057
        return 1;
 
3058
 
 
3059
    if (PyCArrayTypeObject_Check(arg))
 
3060
        return 1;
 
3061
 
 
3062
    dict = PyType_stgdict(arg);
 
3063
    if (dict
 
3064
        /* simple pointer types, c_void_p, c_wchar_p, BSTR, ... */
 
3065
        && PyUnicode_Check(dict->proto)
3066
3066
/* We only allow c_void_p, c_char_p and c_wchar_p as a simple output parameter type */
3067
 
            && (strchr("PzZ", _PyUnicode_AsString(dict->proto)[0]))) {
3068
 
                return 1;
3069
 
        }
 
3067
        && (strchr("PzZ", _PyUnicode_AsString(dict->proto)[0]))) {
 
3068
        return 1;
 
3069
    }
3070
3070
 
3071
 
        PyErr_Format(PyExc_TypeError,
3072
 
                     "'out' parameter %d must be a pointer type, not %s",
3073
 
                     Py_SAFE_DOWNCAST(index, Py_ssize_t, int),
3074
 
                     PyType_Check(arg) ?
3075
 
                     ((PyTypeObject *)arg)->tp_name :
3076
 
                     Py_TYPE(arg)->tp_name);
3077
 
        return 0;
 
3071
    PyErr_Format(PyExc_TypeError,
 
3072
                 "'out' parameter %d must be a pointer type, not %s",
 
3073
                 Py_SAFE_DOWNCAST(index, Py_ssize_t, int),
 
3074
                 PyType_Check(arg) ?
 
3075
                 ((PyTypeObject *)arg)->tp_name :
 
3076
             Py_TYPE(arg)->tp_name);
 
3077
    return 0;
3078
3078
}
3079
3079
 
3080
3080
/* Returns 1 on success, 0 on error */
3081
3081
static int
3082
3082
_validate_paramflags(PyTypeObject *type, PyObject *paramflags)
3083
3083
{
3084
 
        Py_ssize_t i, len;
3085
 
        StgDictObject *dict;
3086
 
        PyObject *argtypes;
3087
 
 
3088
 
        dict = PyType_stgdict((PyObject *)type);
3089
 
        assert(dict); /* Cannot be NULL. 'type' is a PyCFuncPtr type. */
3090
 
        argtypes = dict->argtypes;
3091
 
 
3092
 
        if (paramflags == NULL || dict->argtypes == NULL)
3093
 
                return 1;
3094
 
 
3095
 
        if (!PyTuple_Check(paramflags)) {
3096
 
                PyErr_SetString(PyExc_TypeError,
3097
 
                                "paramflags must be a tuple or None");
3098
 
                return 0;
3099
 
        }
3100
 
 
3101
 
        len = PyTuple_GET_SIZE(paramflags);
3102
 
        if (len != PyTuple_GET_SIZE(dict->argtypes)) {
3103
 
                PyErr_SetString(PyExc_ValueError,
3104
 
                                "paramflags must have the same length as argtypes");
3105
 
                return 0;
3106
 
        }
3107
 
        
3108
 
        for (i = 0; i < len; ++i) {
3109
 
                PyObject *item = PyTuple_GET_ITEM(paramflags, i);
3110
 
                int flag;
3111
 
                char *name;
3112
 
                PyObject *defval;
3113
 
                PyObject *typ;
3114
 
                if (!PyArg_ParseTuple(item, "i|ZO", &flag, &name, &defval)) {
3115
 
                        PyErr_SetString(PyExc_TypeError,
3116
 
                               "paramflags must be a sequence of (int [,string [,value]]) tuples");
3117
 
                        return 0;
3118
 
                }
3119
 
                typ = PyTuple_GET_ITEM(argtypes, i);
3120
 
                switch (flag & (PARAMFLAG_FIN | PARAMFLAG_FOUT | PARAMFLAG_FLCID)) {
3121
 
                case 0:
3122
 
                case PARAMFLAG_FIN:
3123
 
                case PARAMFLAG_FIN | PARAMFLAG_FLCID:
3124
 
                case PARAMFLAG_FIN | PARAMFLAG_FOUT:
3125
 
                        break;
3126
 
                case PARAMFLAG_FOUT:
3127
 
                        if (!_check_outarg_type(typ, i+1))
3128
 
                                return 0;
3129
 
                        break;
3130
 
                default:
3131
 
                        PyErr_Format(PyExc_TypeError,
3132
 
                                     "paramflag value %d not supported",
3133
 
                                     flag);
3134
 
                        return 0;
3135
 
                }
3136
 
        }
3137
 
        return 1;
 
3084
    Py_ssize_t i, len;
 
3085
    StgDictObject *dict;
 
3086
    PyObject *argtypes;
 
3087
 
 
3088
    dict = PyType_stgdict((PyObject *)type);
 
3089
    assert(dict); /* Cannot be NULL. 'type' is a PyCFuncPtr type. */
 
3090
    argtypes = dict->argtypes;
 
3091
 
 
3092
    if (paramflags == NULL || dict->argtypes == NULL)
 
3093
        return 1;
 
3094
 
 
3095
    if (!PyTuple_Check(paramflags)) {
 
3096
        PyErr_SetString(PyExc_TypeError,
 
3097
                        "paramflags must be a tuple or None");
 
3098
        return 0;
 
3099
    }
 
3100
 
 
3101
    len = PyTuple_GET_SIZE(paramflags);
 
3102
    if (len != PyTuple_GET_SIZE(dict->argtypes)) {
 
3103
        PyErr_SetString(PyExc_ValueError,
 
3104
                        "paramflags must have the same length as argtypes");
 
3105
        return 0;
 
3106
    }
 
3107
 
 
3108
    for (i = 0; i < len; ++i) {
 
3109
        PyObject *item = PyTuple_GET_ITEM(paramflags, i);
 
3110
        int flag;
 
3111
        char *name;
 
3112
        PyObject *defval;
 
3113
        PyObject *typ;
 
3114
        if (!PyArg_ParseTuple(item, "i|ZO", &flag, &name, &defval)) {
 
3115
            PyErr_SetString(PyExc_TypeError,
 
3116
                   "paramflags must be a sequence of (int [,string [,value]]) tuples");
 
3117
            return 0;
 
3118
        }
 
3119
        typ = PyTuple_GET_ITEM(argtypes, i);
 
3120
        switch (flag & (PARAMFLAG_FIN | PARAMFLAG_FOUT | PARAMFLAG_FLCID)) {
 
3121
        case 0:
 
3122
        case PARAMFLAG_FIN:
 
3123
        case PARAMFLAG_FIN | PARAMFLAG_FLCID:
 
3124
        case PARAMFLAG_FIN | PARAMFLAG_FOUT:
 
3125
            break;
 
3126
        case PARAMFLAG_FOUT:
 
3127
            if (!_check_outarg_type(typ, i+1))
 
3128
                return 0;
 
3129
            break;
 
3130
        default:
 
3131
            PyErr_Format(PyExc_TypeError,
 
3132
                         "paramflag value %d not supported",
 
3133
                         flag);
 
3134
            return 0;
 
3135
        }
 
3136
    }
 
3137
    return 1;
3138
3138
}
3139
3139
 
3140
3140
static int
3141
3141
_get_name(PyObject *obj, char **pname)
3142
3142
{
3143
3143
#ifdef MS_WIN32
3144
 
        if (PyLong_Check(obj)) {
3145
 
                /* We have to use MAKEINTRESOURCEA for Windows CE.
3146
 
                   Works on Windows as well, of course.
3147
 
                */
3148
 
                *pname = MAKEINTRESOURCEA(PyLong_AsUnsignedLongMask(obj) & 0xFFFF);
3149
 
                return 1;
3150
 
        }
 
3144
    if (PyLong_Check(obj)) {
 
3145
        /* We have to use MAKEINTRESOURCEA for Windows CE.
 
3146
           Works on Windows as well, of course.
 
3147
        */
 
3148
        *pname = MAKEINTRESOURCEA(PyLong_AsUnsignedLongMask(obj) & 0xFFFF);
 
3149
        return 1;
 
3150
    }
3151
3151
#endif
3152
 
        if (PyBytes_Check(obj)) {
3153
 
                *pname = PyBytes_AS_STRING(obj);
3154
 
                return *pname ? 1 : 0;
3155
 
        }
3156
 
        if (PyUnicode_Check(obj)) {
3157
 
                *pname = _PyUnicode_AsString(obj);
3158
 
                return *pname ? 1 : 0;
3159
 
        }
3160
 
        PyErr_SetString(PyExc_TypeError,
3161
 
                        "function name must be string or integer");
3162
 
        return 0;
 
3152
    if (PyBytes_Check(obj)) {
 
3153
        *pname = PyBytes_AS_STRING(obj);
 
3154
        return *pname ? 1 : 0;
 
3155
    }
 
3156
    if (PyUnicode_Check(obj)) {
 
3157
        *pname = _PyUnicode_AsString(obj);
 
3158
        return *pname ? 1 : 0;
 
3159
    }
 
3160
    PyErr_SetString(PyExc_TypeError,
 
3161
                    "function name must be string or integer");
 
3162
    return 0;
3163
3163
}
3164
3164
 
3165
3165
 
3166
3166
static PyObject *
3167
3167
PyCFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds)
3168
3168
{
3169
 
        char *name;
3170
 
        int (* address)(void);
3171
 
        PyObject *dll;
3172
 
        PyObject *obj;
3173
 
        PyCFuncPtrObject *self;
3174
 
        void *handle;
3175
 
        PyObject *paramflags = NULL;
3176
 
 
3177
 
        if (!PyArg_ParseTuple(args, "(O&O)|O", _get_name, &name, &dll, &paramflags))
3178
 
                return NULL;
3179
 
        if (paramflags == Py_None)
3180
 
                paramflags = NULL;
3181
 
 
3182
 
        obj = PyObject_GetAttrString(dll, "_handle");
3183
 
        if (!obj)
3184
 
                return NULL;
3185
 
        if (!PyLong_Check(obj)) {
3186
 
                PyErr_SetString(PyExc_TypeError,
3187
 
                                "the _handle attribute of the second argument must be an integer");
3188
 
                Py_DECREF(obj);
3189
 
                return NULL;
3190
 
        }
3191
 
        handle = (void *)PyLong_AsVoidPtr(obj);
3192
 
        Py_DECREF(obj);
3193
 
        if (PyErr_Occurred()) {
3194
 
                PyErr_SetString(PyExc_ValueError,
3195
 
                                "could not convert the _handle attribute to a pointer");
3196
 
                return NULL;
3197
 
        }
 
3169
    char *name;
 
3170
    int (* address)(void);
 
3171
    PyObject *dll;
 
3172
    PyObject *obj;
 
3173
    PyCFuncPtrObject *self;
 
3174
    void *handle;
 
3175
    PyObject *paramflags = NULL;
 
3176
 
 
3177
    if (!PyArg_ParseTuple(args, "(O&O)|O", _get_name, &name, &dll, &paramflags))
 
3178
        return NULL;
 
3179
    if (paramflags == Py_None)
 
3180
        paramflags = NULL;
 
3181
 
 
3182
    obj = PyObject_GetAttrString(dll, "_handle");
 
3183
    if (!obj)
 
3184
        return NULL;
 
3185
    if (!PyLong_Check(obj)) {
 
3186
        PyErr_SetString(PyExc_TypeError,
 
3187
                        "the _handle attribute of the second argument must be an integer");
 
3188
        Py_DECREF(obj);
 
3189
        return NULL;
 
3190
    }
 
3191
    handle = (void *)PyLong_AsVoidPtr(obj);
 
3192
    Py_DECREF(obj);
 
3193
    if (PyErr_Occurred()) {
 
3194
        PyErr_SetString(PyExc_ValueError,
 
3195
                        "could not convert the _handle attribute to a pointer");
 
3196
        return NULL;
 
3197
    }
3198
3198
 
3199
3199
#ifdef MS_WIN32
3200
 
        address = FindAddress(handle, name, (PyObject *)type);
3201
 
        if (!address) {
3202
 
                if (!IS_INTRESOURCE(name))
3203
 
                        PyErr_Format(PyExc_AttributeError,
3204
 
                                     "function '%s' not found",
3205
 
                                     name);
3206
 
                else
3207
 
                        PyErr_Format(PyExc_AttributeError,
3208
 
                                     "function ordinal %d not found",
3209
 
                                     (WORD)(size_t)name);
3210
 
                return NULL;
3211
 
        }
 
3200
    address = FindAddress(handle, name, (PyObject *)type);
 
3201
    if (!address) {
 
3202
        if (!IS_INTRESOURCE(name))
 
3203
            PyErr_Format(PyExc_AttributeError,
 
3204
                         "function '%s' not found",
 
3205
                         name);
 
3206
        else
 
3207
            PyErr_Format(PyExc_AttributeError,
 
3208
                         "function ordinal %d not found",
 
3209
                         (WORD)(size_t)name);
 
3210
        return NULL;
 
3211
    }
3212
3212
#else
3213
 
        address = (PPROC)ctypes_dlsym(handle, name);
3214
 
        if (!address) {
 
3213
    address = (PPROC)ctypes_dlsym(handle, name);
 
3214
    if (!address) {
3215
3215
#ifdef __CYGWIN__
3216
3216
/* dlerror() isn't very helpful on cygwin */
3217
 
                PyErr_Format(PyExc_AttributeError,
3218
 
                             "function '%s' not found (%s) ",
3219
 
                             name);
 
3217
        PyErr_Format(PyExc_AttributeError,
 
3218
                     "function '%s' not found (%s) ",
 
3219
                     name);
3220
3220
#else
3221
 
                PyErr_SetString(PyExc_AttributeError, ctypes_dlerror());
3222
 
#endif
3223
 
                return NULL;
3224
 
        }
3225
 
#endif
3226
 
        if (!_validate_paramflags(type, paramflags))
3227
 
                return NULL;
3228
 
 
3229
 
        self = (PyCFuncPtrObject *)GenericPyCData_new(type, args, kwds);
3230
 
        if (!self)
3231
 
                return NULL;
3232
 
 
3233
 
        Py_XINCREF(paramflags);
3234
 
        self->paramflags = paramflags;
3235
 
 
3236
 
        *(void **)self->b_ptr = address;
3237
 
 
3238
 
        Py_INCREF((PyObject *)dll); /* for KeepRef */
3239
 
        if (-1 == KeepRef((CDataObject *)self, 0, dll)) {
3240
 
                Py_DECREF((PyObject *)self);
3241
 
                return NULL;
3242
 
        }
3243
 
 
3244
 
        Py_INCREF(self);
3245
 
        self->callable = (PyObject *)self;
3246
 
        return (PyObject *)self;
 
3221
        PyErr_SetString(PyExc_AttributeError, ctypes_dlerror());
 
3222
#endif
 
3223
        return NULL;
 
3224
    }
 
3225
#endif
 
3226
    if (!_validate_paramflags(type, paramflags))
 
3227
        return NULL;
 
3228
 
 
3229
    self = (PyCFuncPtrObject *)GenericPyCData_new(type, args, kwds);
 
3230
    if (!self)
 
3231
        return NULL;
 
3232
 
 
3233
    Py_XINCREF(paramflags);
 
3234
    self->paramflags = paramflags;
 
3235
 
 
3236
    *(void **)self->b_ptr = address;
 
3237
 
 
3238
    Py_INCREF((PyObject *)dll); /* for KeepRef */
 
3239
    if (-1 == KeepRef((CDataObject *)self, 0, dll)) {
 
3240
        Py_DECREF((PyObject *)self);
 
3241
        return NULL;
 
3242
    }
 
3243
 
 
3244
    Py_INCREF(self);
 
3245
    self->callable = (PyObject *)self;
 
3246
    return (PyObject *)self;
3247
3247
}
3248
3248
 
3249
3249
#ifdef MS_WIN32
3250
3250
static PyObject *
3251
3251
PyCFuncPtr_FromVtblIndex(PyTypeObject *type, PyObject *args, PyObject *kwds)
3252
3252
{
3253
 
        PyCFuncPtrObject *self;
3254
 
        int index;
3255
 
        char *name = NULL;
3256
 
        PyObject *paramflags = NULL;
3257
 
        GUID *iid = NULL;
3258
 
        Py_ssize_t iid_len = 0;
3259
 
 
3260
 
        if (!PyArg_ParseTuple(args, "is|Oz#", &index, &name, &paramflags, &iid, &iid_len))
3261
 
                return NULL;
3262
 
        if (paramflags == Py_None)
3263
 
                paramflags = NULL;
3264
 
 
3265
 
        if (!_validate_paramflags(type, paramflags))
3266
 
                return NULL;
3267
 
 
3268
 
        self = (PyCFuncPtrObject *)GenericPyCData_new(type, args, kwds);
3269
 
        self->index = index + 0x1000;
3270
 
        Py_XINCREF(paramflags);
3271
 
        self->paramflags = paramflags;
3272
 
        if (iid_len == sizeof(GUID))
3273
 
                self->iid = iid;
3274
 
        return (PyObject *)self;
 
3253
    PyCFuncPtrObject *self;
 
3254
    int index;
 
3255
    char *name = NULL;
 
3256
    PyObject *paramflags = NULL;
 
3257
    GUID *iid = NULL;
 
3258
    Py_ssize_t iid_len = 0;
 
3259
 
 
3260
    if (!PyArg_ParseTuple(args, "is|Oz#", &index, &name, &paramflags, &iid, &iid_len))
 
3261
        return NULL;
 
3262
    if (paramflags == Py_None)
 
3263
        paramflags = NULL;
 
3264
 
 
3265
    if (!_validate_paramflags(type, paramflags))
 
3266
        return NULL;
 
3267
 
 
3268
    self = (PyCFuncPtrObject *)GenericPyCData_new(type, args, kwds);
 
3269
    self->index = index + 0x1000;
 
3270
    Py_XINCREF(paramflags);
 
3271
    self->paramflags = paramflags;
 
3272
    if (iid_len == sizeof(GUID))
 
3273
        self->iid = iid;
 
3274
    return (PyObject *)self;
3275
3275
}
3276
3276
#endif
3277
3277
 
3291
3291
static PyObject *
3292
3292
PyCFuncPtr_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
3293
3293
{
3294
 
        PyCFuncPtrObject *self;
3295
 
        PyObject *callable;
3296
 
        StgDictObject *dict;
3297
 
        CThunkObject *thunk;
3298
 
 
3299
 
        if (PyTuple_GET_SIZE(args) == 0)
3300
 
                return GenericPyCData_new(type, args, kwds);
3301
 
 
3302
 
        if (1 <= PyTuple_GET_SIZE(args) && PyTuple_Check(PyTuple_GET_ITEM(args, 0)))
3303
 
                return PyCFuncPtr_FromDll(type, args, kwds);
 
3294
    PyCFuncPtrObject *self;
 
3295
    PyObject *callable;
 
3296
    StgDictObject *dict;
 
3297
    CThunkObject *thunk;
 
3298
 
 
3299
    if (PyTuple_GET_SIZE(args) == 0)
 
3300
        return GenericPyCData_new(type, args, kwds);
 
3301
 
 
3302
    if (1 <= PyTuple_GET_SIZE(args) && PyTuple_Check(PyTuple_GET_ITEM(args, 0)))
 
3303
        return PyCFuncPtr_FromDll(type, args, kwds);
3304
3304
 
3305
3305
#ifdef MS_WIN32
3306
 
        if (2 <= PyTuple_GET_SIZE(args) && PyLong_Check(PyTuple_GET_ITEM(args, 0)))
3307
 
                return PyCFuncPtr_FromVtblIndex(type, args, kwds);
 
3306
    if (2 <= PyTuple_GET_SIZE(args) && PyLong_Check(PyTuple_GET_ITEM(args, 0)))
 
3307
        return PyCFuncPtr_FromVtblIndex(type, args, kwds);
3308
3308
#endif
3309
3309
 
3310
 
        if (1 == PyTuple_GET_SIZE(args)
3311
 
            && (PyLong_Check(PyTuple_GET_ITEM(args, 0)))) {
3312
 
                CDataObject *ob;
3313
 
                void *ptr = PyLong_AsVoidPtr(PyTuple_GET_ITEM(args, 0));
3314
 
                if (ptr == NULL && PyErr_Occurred())
3315
 
                        return NULL;
3316
 
                ob = (CDataObject *)GenericPyCData_new(type, args, kwds);
3317
 
                if (ob == NULL)
3318
 
                        return NULL;
3319
 
                *(void **)ob->b_ptr = ptr;
3320
 
                return (PyObject *)ob;
3321
 
        }
3322
 
 
3323
 
        if (!PyArg_ParseTuple(args, "O", &callable))
3324
 
                return NULL;
3325
 
        if (!PyCallable_Check(callable)) {
3326
 
                PyErr_SetString(PyExc_TypeError,
3327
 
                                "argument must be callable or integer function address");
3328
 
                return NULL;
3329
 
        }
3330
 
 
3331
 
        /* XXX XXX This would allow to pass additional options.  For COM
3332
 
           method *implementations*, we would probably want different
3333
 
           behaviour than in 'normal' callback functions: return a HRESULT if
3334
 
           an exception occurrs in the callback, and print the traceback not
3335
 
           only on the console, but also to OutputDebugString() or something
3336
 
           like that.
3337
 
        */
 
3310
    if (1 == PyTuple_GET_SIZE(args)
 
3311
        && (PyLong_Check(PyTuple_GET_ITEM(args, 0)))) {
 
3312
        CDataObject *ob;
 
3313
        void *ptr = PyLong_AsVoidPtr(PyTuple_GET_ITEM(args, 0));
 
3314
        if (ptr == NULL && PyErr_Occurred())
 
3315
            return NULL;
 
3316
        ob = (CDataObject *)GenericPyCData_new(type, args, kwds);
 
3317
        if (ob == NULL)
 
3318
            return NULL;
 
3319
        *(void **)ob->b_ptr = ptr;
 
3320
        return (PyObject *)ob;
 
3321
    }
 
3322
 
 
3323
    if (!PyArg_ParseTuple(args, "O", &callable))
 
3324
        return NULL;
 
3325
    if (!PyCallable_Check(callable)) {
 
3326
        PyErr_SetString(PyExc_TypeError,
 
3327
                        "argument must be callable or integer function address");
 
3328
        return NULL;
 
3329
    }
 
3330
 
 
3331
    /* XXX XXX This would allow to pass additional options.  For COM
 
3332
       method *implementations*, we would probably want different
 
3333
       behaviour than in 'normal' callback functions: return a HRESULT if
 
3334
       an exception occurrs in the callback, and print the traceback not
 
3335
       only on the console, but also to OutputDebugString() or something
 
3336
       like that.
 
3337
    */
3338
3338
/*
3339
 
        if (kwds && PyDict_GetItemString(kwds, "options")) {
3340
 
                ...
3341
 
        }
 
3339
    if (kwds && PyDict_GetItemString(kwds, "options")) {
 
3340
        ...
 
3341
    }
3342
3342
*/
3343
3343
 
3344
 
        dict = PyType_stgdict((PyObject *)type);
3345
 
        /* XXXX Fails if we do: 'PyCFuncPtr(lambda x: x)' */
3346
 
        if (!dict || !dict->argtypes) {
3347
 
                PyErr_SetString(PyExc_TypeError,
3348
 
                       "cannot construct instance of this class:"
3349
 
                        " no argtypes");
3350
 
                return NULL;
3351
 
        }
3352
 
 
3353
 
        thunk = _ctypes_alloc_callback(callable,
3354
 
                                      dict->argtypes,
3355
 
                                      dict->restype,
3356
 
                                      dict->flags);
3357
 
        if (!thunk)
3358
 
                return NULL;
3359
 
 
3360
 
        self = (PyCFuncPtrObject *)GenericPyCData_new(type, args, kwds);
3361
 
        if (self == NULL) {
3362
 
                Py_DECREF(thunk);
3363
 
                return NULL;
3364
 
        }
3365
 
 
3366
 
        Py_INCREF(callable);
3367
 
        self->callable = callable;
3368
 
 
3369
 
        self->thunk = thunk;
3370
 
        *(void **)self->b_ptr = (void *)thunk->pcl;
3371
 
        
3372
 
        Py_INCREF((PyObject *)thunk); /* for KeepRef */
3373
 
        if (-1 == KeepRef((CDataObject *)self, 0, (PyObject *)thunk)) {
3374
 
                Py_DECREF((PyObject *)self);
3375
 
                return NULL;
3376
 
        }
3377
 
        return (PyObject *)self;
 
3344
    dict = PyType_stgdict((PyObject *)type);
 
3345
    /* XXXX Fails if we do: 'PyCFuncPtr(lambda x: x)' */
 
3346
    if (!dict || !dict->argtypes) {
 
3347
        PyErr_SetString(PyExc_TypeError,
 
3348
               "cannot construct instance of this class:"
 
3349
            " no argtypes");
 
3350
        return NULL;
 
3351
    }
 
3352
 
 
3353
    thunk = _ctypes_alloc_callback(callable,
 
3354
                                  dict->argtypes,
 
3355
                                  dict->restype,
 
3356
                                  dict->flags);
 
3357
    if (!thunk)
 
3358
        return NULL;
 
3359
 
 
3360
    self = (PyCFuncPtrObject *)GenericPyCData_new(type, args, kwds);
 
3361
    if (self == NULL) {
 
3362
        Py_DECREF(thunk);
 
3363
        return NULL;
 
3364
    }
 
3365
 
 
3366
    Py_INCREF(callable);
 
3367
    self->callable = callable;
 
3368
 
 
3369
    self->thunk = thunk;
 
3370
    *(void **)self->b_ptr = (void *)thunk->pcl;
 
3371
 
 
3372
    Py_INCREF((PyObject *)thunk); /* for KeepRef */
 
3373
    if (-1 == KeepRef((CDataObject *)self, 0, (PyObject *)thunk)) {
 
3374
        Py_DECREF((PyObject *)self);
 
3375
        return NULL;
 
3376
    }
 
3377
    return (PyObject *)self;
3378
3378
}
3379
3379
 
3380
3380
 
3384
3384
static PyObject *
3385
3385
_byref(PyObject *obj)
3386
3386
{
3387
 
        PyCArgObject *parg;
3388
 
        if (!CDataObject_Check(obj)) {
3389
 
                PyErr_SetString(PyExc_TypeError,
3390
 
                                "expected CData instance");
3391
 
                return NULL;
3392
 
        }
3393
 
 
3394
 
        parg = PyCArgObject_new();
3395
 
        if (parg == NULL) {
3396
 
                Py_DECREF(obj);
3397
 
                return NULL;
3398
 
        }
3399
 
 
3400
 
        parg->tag = 'P';
3401
 
        parg->pffi_type = &ffi_type_pointer;
3402
 
        parg->obj = obj;
3403
 
        parg->value.p = ((CDataObject *)obj)->b_ptr;
3404
 
        return (PyObject *)parg;
 
3387
    PyCArgObject *parg;
 
3388
    if (!CDataObject_Check(obj)) {
 
3389
        PyErr_SetString(PyExc_TypeError,
 
3390
                        "expected CData instance");
 
3391
        return NULL;
 
3392
    }
 
3393
 
 
3394
    parg = PyCArgObject_new();
 
3395
    if (parg == NULL) {
 
3396
        Py_DECREF(obj);
 
3397
        return NULL;
 
3398
    }
 
3399
 
 
3400
    parg->tag = 'P';
 
3401
    parg->pffi_type = &ffi_type_pointer;
 
3402
    parg->obj = obj;
 
3403
    parg->value.p = ((CDataObject *)obj)->b_ptr;
 
3404
    return (PyObject *)parg;
3405
3405
}
3406
3406
 
3407
3407
static PyObject *
3408
3408
_get_arg(int *pindex, PyObject *name, PyObject *defval, PyObject *inargs, PyObject *kwds)
3409
3409
{
3410
 
        PyObject *v;
 
3410
    PyObject *v;
3411
3411
 
3412
 
        if (*pindex < PyTuple_GET_SIZE(inargs)) {
3413
 
                v = PyTuple_GET_ITEM(inargs, *pindex);
3414
 
                ++*pindex;
3415
 
                Py_INCREF(v);
3416
 
                return v;
3417
 
        }
3418
 
        if (kwds && (v = PyDict_GetItem(kwds, name))) {
3419
 
                ++*pindex;
3420
 
                Py_INCREF(v);
3421
 
                return v;
3422
 
        }
3423
 
        if (defval) {
3424
 
                Py_INCREF(defval);
3425
 
                return defval;
3426
 
        }
3427
 
        /* we can't currently emit a better error message */
3428
 
        if (name)
3429
 
                PyErr_Format(PyExc_TypeError,
3430
 
                             "required argument '%S' missing", name);
3431
 
        else
3432
 
                PyErr_Format(PyExc_TypeError,
3433
 
                             "not enough arguments");
3434
 
        return NULL;
 
3412
    if (*pindex < PyTuple_GET_SIZE(inargs)) {
 
3413
        v = PyTuple_GET_ITEM(inargs, *pindex);
 
3414
        ++*pindex;
 
3415
        Py_INCREF(v);
 
3416
        return v;
 
3417
    }
 
3418
    if (kwds && (v = PyDict_GetItem(kwds, name))) {
 
3419
        ++*pindex;
 
3420
        Py_INCREF(v);
 
3421
        return v;
 
3422
    }
 
3423
    if (defval) {
 
3424
        Py_INCREF(defval);
 
3425
        return defval;
 
3426
    }
 
3427
    /* we can't currently emit a better error message */
 
3428
    if (name)
 
3429
        PyErr_Format(PyExc_TypeError,
 
3430
                     "required argument '%S' missing", name);
 
3431
    else
 
3432
        PyErr_Format(PyExc_TypeError,
 
3433
                     "not enough arguments");
 
3434
    return NULL;
3435
3435
}
3436
3436
 
3437
3437
/*
3454
3454
*/
3455
3455
static PyObject *
3456
3456
_build_callargs(PyCFuncPtrObject *self, PyObject *argtypes,
3457
 
                PyObject *inargs, PyObject *kwds,
3458
 
                int *poutmask, int *pinoutmask, unsigned int *pnumretvals)
 
3457
                PyObject *inargs, PyObject *kwds,
 
3458
                int *poutmask, int *pinoutmask, unsigned int *pnumretvals)
3459
3459
{
3460
 
        PyObject *paramflags = self->paramflags;
3461
 
        PyObject *callargs;
3462
 
        StgDictObject *dict;
3463
 
        Py_ssize_t i, len;
3464
 
        int inargs_index = 0;
3465
 
        /* It's a little bit difficult to determine how many arguments the
3466
 
        function call requires/accepts.  For simplicity, we count the consumed
3467
 
        args and compare this to the number of supplied args. */
3468
 
        Py_ssize_t actual_args;
3469
 
 
3470
 
        *poutmask = 0;
3471
 
        *pinoutmask = 0;
3472
 
        *pnumretvals = 0;
3473
 
 
3474
 
        /* Trivial cases, where we either return inargs itself, or a slice of it. */
3475
 
        if (argtypes == NULL || paramflags == NULL || PyTuple_GET_SIZE(argtypes) == 0) {
3476
 
#ifdef MS_WIN32
3477
 
                if (self->index)
3478
 
                        return PyTuple_GetSlice(inargs, 1, PyTuple_GET_SIZE(inargs));
3479
 
#endif
3480
 
                Py_INCREF(inargs);
3481
 
                return inargs;
3482
 
        }
3483
 
 
3484
 
        len = PyTuple_GET_SIZE(argtypes);
3485
 
        callargs = PyTuple_New(len); /* the argument tuple we build */
3486
 
        if (callargs == NULL)
3487
 
                return NULL;
3488
 
 
3489
 
#ifdef MS_WIN32
3490
 
        /* For a COM method, skip the first arg */
3491
 
        if (self->index) {
3492
 
                inargs_index = 1;
3493
 
        }
3494
 
#endif
3495
 
        for (i = 0; i < len; ++i) {
3496
 
                PyObject *item = PyTuple_GET_ITEM(paramflags, i);
3497
 
                PyObject *ob;
3498
 
                int flag;
3499
 
                PyObject *name = NULL;
3500
 
                PyObject *defval = NULL;
3501
 
 
3502
 
                /* This way seems to be ~2 us faster than the PyArg_ParseTuple
3503
 
                   calls below. */
3504
 
                /* We HAVE already checked that the tuple can be parsed with "i|ZO", so... */
3505
 
                Py_ssize_t tsize = PyTuple_GET_SIZE(item);
3506
 
                flag = PyLong_AS_LONG(PyTuple_GET_ITEM(item, 0));
3507
 
                name = tsize > 1 ? PyTuple_GET_ITEM(item, 1) : NULL;
3508
 
                defval = tsize > 2 ? PyTuple_GET_ITEM(item, 2) : NULL;
3509
 
 
3510
 
                switch (flag & (PARAMFLAG_FIN | PARAMFLAG_FOUT | PARAMFLAG_FLCID)) {
3511
 
                case PARAMFLAG_FIN | PARAMFLAG_FLCID:
3512
 
                        /* ['in', 'lcid'] parameter.  Always taken from defval,
3513
 
                         if given, else the integer 0. */
3514
 
                        if (defval == NULL) {
3515
 
                                defval = PyLong_FromLong(0);
3516
 
                                if (defval == NULL)
3517
 
                                        goto error;
3518
 
                        } else
3519
 
                                Py_INCREF(defval);
3520
 
                        PyTuple_SET_ITEM(callargs, i, defval);
3521
 
                        break;
3522
 
                case (PARAMFLAG_FIN | PARAMFLAG_FOUT):
3523
 
                        *pinoutmask |= (1 << i); /* mark as inout arg */
3524
 
                        (*pnumretvals)++;
3525
 
                        /* fall through to PARAMFLAG_FIN... */
3526
 
                case 0:
3527
 
                case PARAMFLAG_FIN:
3528
 
                        /* 'in' parameter.  Copy it from inargs. */
3529
 
                        ob =_get_arg(&inargs_index, name, defval, inargs, kwds);
3530
 
                        if (ob == NULL)
3531
 
                                goto error;
3532
 
                        PyTuple_SET_ITEM(callargs, i, ob);
3533
 
                        break;
3534
 
                case PARAMFLAG_FOUT:
3535
 
                        /* XXX Refactor this code into a separate function. */
3536
 
                        /* 'out' parameter.
3537
 
                           argtypes[i] must be a POINTER to a c type.
3538
 
 
3539
 
                           Cannot by supplied in inargs, but a defval will be used
3540
 
                           if available.  XXX Should we support getting it from kwds?
3541
 
                        */
3542
 
                        if (defval) {
3543
 
                                /* XXX Using mutable objects as defval will
3544
 
                                   make the function non-threadsafe, unless we
3545
 
                                   copy the object in each invocation */
3546
 
                                Py_INCREF(defval);
3547
 
                                PyTuple_SET_ITEM(callargs, i, defval);
3548
 
                                *poutmask |= (1 << i); /* mark as out arg */
3549
 
                                (*pnumretvals)++;
3550
 
                                break;
3551
 
                        }
3552
 
                        ob = PyTuple_GET_ITEM(argtypes, i);
3553
 
                        dict = PyType_stgdict(ob);
3554
 
                        if (dict == NULL) {
3555
 
                                /* Cannot happen: _validate_paramflags()
3556
 
                                  would not accept such an object */
3557
 
                                PyErr_Format(PyExc_RuntimeError,
3558
 
                                             "NULL stgdict unexpected");
3559
 
                                goto error;
3560
 
                        }
3561
 
                        if (PyUnicode_Check(dict->proto)) {
3562
 
                                PyErr_Format(
3563
 
                                        PyExc_TypeError,
3564
 
                                        "%s 'out' parameter must be passed as default value",
3565
 
                                        ((PyTypeObject *)ob)->tp_name);
3566
 
                                goto error;
3567
 
                        }
3568
 
                        if (PyCArrayTypeObject_Check(ob))
3569
 
                                ob = PyObject_CallObject(ob, NULL);
3570
 
                        else
3571
 
                                /* Create an instance of the pointed-to type */
3572
 
                                ob = PyObject_CallObject(dict->proto, NULL);
3573
 
                        /*                         
3574
 
                           XXX Is the following correct any longer?
3575
 
                           We must not pass a byref() to the array then but
3576
 
                           the array instance itself. Then, we cannot retrive
3577
 
                           the result from the PyCArgObject.
3578
 
                        */
3579
 
                        if (ob == NULL)
3580
 
                                goto error;
3581
 
                        /* The .from_param call that will ocurr later will pass this
3582
 
                           as a byref parameter. */
3583
 
                        PyTuple_SET_ITEM(callargs, i, ob);
3584
 
                        *poutmask |= (1 << i); /* mark as out arg */
3585
 
                        (*pnumretvals)++;
3586
 
                        break;
3587
 
                default:
3588
 
                        PyErr_Format(PyExc_ValueError,
3589
 
                                     "paramflag %d not yet implemented", flag);
3590
 
                        goto error;
3591
 
                        break;
3592
 
                }
3593
 
        }
3594
 
 
3595
 
        /* We have counted the arguments we have consumed in 'inargs_index'.  This
3596
 
           must be the same as len(inargs) + len(kwds), otherwise we have
3597
 
           either too much or not enough arguments. */
3598
 
 
3599
 
        actual_args = PyTuple_GET_SIZE(inargs) + (kwds ? PyDict_Size(kwds) : 0);
3600
 
        if (actual_args != inargs_index) {
3601
 
                /* When we have default values or named parameters, this error
3602
 
                   message is misleading.  See unittests/test_paramflags.py
3603
 
                 */
3604
 
                PyErr_Format(PyExc_TypeError,
3605
 
                             "call takes exactly %d arguments (%zd given)",
3606
 
                             inargs_index, actual_args);
3607
 
                goto error;
3608
 
        }
3609
 
 
3610
 
        /* outmask is a bitmask containing indexes into callargs.  Items at
3611
 
           these indexes contain values to return.
3612
 
         */
3613
 
        return callargs;
 
3460
    PyObject *paramflags = self->paramflags;
 
3461
    PyObject *callargs;
 
3462
    StgDictObject *dict;
 
3463
    Py_ssize_t i, len;
 
3464
    int inargs_index = 0;
 
3465
    /* It's a little bit difficult to determine how many arguments the
 
3466
    function call requires/accepts.  For simplicity, we count the consumed
 
3467
    args and compare this to the number of supplied args. */
 
3468
    Py_ssize_t actual_args;
 
3469
 
 
3470
    *poutmask = 0;
 
3471
    *pinoutmask = 0;
 
3472
    *pnumretvals = 0;
 
3473
 
 
3474
    /* Trivial cases, where we either return inargs itself, or a slice of it. */
 
3475
    if (argtypes == NULL || paramflags == NULL || PyTuple_GET_SIZE(argtypes) == 0) {
 
3476
#ifdef MS_WIN32
 
3477
        if (self->index)
 
3478
            return PyTuple_GetSlice(inargs, 1, PyTuple_GET_SIZE(inargs));
 
3479
#endif
 
3480
        Py_INCREF(inargs);
 
3481
        return inargs;
 
3482
    }
 
3483
 
 
3484
    len = PyTuple_GET_SIZE(argtypes);
 
3485
    callargs = PyTuple_New(len); /* the argument tuple we build */
 
3486
    if (callargs == NULL)
 
3487
        return NULL;
 
3488
 
 
3489
#ifdef MS_WIN32
 
3490
    /* For a COM method, skip the first arg */
 
3491
    if (self->index) {
 
3492
        inargs_index = 1;
 
3493
    }
 
3494
#endif
 
3495
    for (i = 0; i < len; ++i) {
 
3496
        PyObject *item = PyTuple_GET_ITEM(paramflags, i);
 
3497
        PyObject *ob;
 
3498
        int flag;
 
3499
        PyObject *name = NULL;
 
3500
        PyObject *defval = NULL;
 
3501
 
 
3502
        /* This way seems to be ~2 us faster than the PyArg_ParseTuple
 
3503
           calls below. */
 
3504
        /* We HAVE already checked that the tuple can be parsed with "i|ZO", so... */
 
3505
        Py_ssize_t tsize = PyTuple_GET_SIZE(item);
 
3506
        flag = PyLong_AS_LONG(PyTuple_GET_ITEM(item, 0));
 
3507
        name = tsize > 1 ? PyTuple_GET_ITEM(item, 1) : NULL;
 
3508
        defval = tsize > 2 ? PyTuple_GET_ITEM(item, 2) : NULL;
 
3509
 
 
3510
        switch (flag & (PARAMFLAG_FIN | PARAMFLAG_FOUT | PARAMFLAG_FLCID)) {
 
3511
        case PARAMFLAG_FIN | PARAMFLAG_FLCID:
 
3512
            /* ['in', 'lcid'] parameter.  Always taken from defval,
 
3513
             if given, else the integer 0. */
 
3514
            if (defval == NULL) {
 
3515
                defval = PyLong_FromLong(0);
 
3516
                if (defval == NULL)
 
3517
                    goto error;
 
3518
            } else
 
3519
                Py_INCREF(defval);
 
3520
            PyTuple_SET_ITEM(callargs, i, defval);
 
3521
            break;
 
3522
        case (PARAMFLAG_FIN | PARAMFLAG_FOUT):
 
3523
            *pinoutmask |= (1 << i); /* mark as inout arg */
 
3524
            (*pnumretvals)++;
 
3525
            /* fall through to PARAMFLAG_FIN... */
 
3526
        case 0:
 
3527
        case PARAMFLAG_FIN:
 
3528
            /* 'in' parameter.  Copy it from inargs. */
 
3529
            ob =_get_arg(&inargs_index, name, defval, inargs, kwds);
 
3530
            if (ob == NULL)
 
3531
                goto error;
 
3532
            PyTuple_SET_ITEM(callargs, i, ob);
 
3533
            break;
 
3534
        case PARAMFLAG_FOUT:
 
3535
            /* XXX Refactor this code into a separate function. */
 
3536
            /* 'out' parameter.
 
3537
               argtypes[i] must be a POINTER to a c type.
 
3538
 
 
3539
               Cannot by supplied in inargs, but a defval will be used
 
3540
               if available.  XXX Should we support getting it from kwds?
 
3541
            */
 
3542
            if (defval) {
 
3543
                /* XXX Using mutable objects as defval will
 
3544
                   make the function non-threadsafe, unless we
 
3545
                   copy the object in each invocation */
 
3546
                Py_INCREF(defval);
 
3547
                PyTuple_SET_ITEM(callargs, i, defval);
 
3548
                *poutmask |= (1 << i); /* mark as out arg */
 
3549
                (*pnumretvals)++;
 
3550
                break;
 
3551
            }
 
3552
            ob = PyTuple_GET_ITEM(argtypes, i);
 
3553
            dict = PyType_stgdict(ob);
 
3554
            if (dict == NULL) {
 
3555
                /* Cannot happen: _validate_paramflags()
 
3556
                  would not accept such an object */
 
3557
                PyErr_Format(PyExc_RuntimeError,
 
3558
                             "NULL stgdict unexpected");
 
3559
                goto error;
 
3560
            }
 
3561
            if (PyUnicode_Check(dict->proto)) {
 
3562
                PyErr_Format(
 
3563
                    PyExc_TypeError,
 
3564
                    "%s 'out' parameter must be passed as default value",
 
3565
                    ((PyTypeObject *)ob)->tp_name);
 
3566
                goto error;
 
3567
            }
 
3568
            if (PyCArrayTypeObject_Check(ob))
 
3569
                ob = PyObject_CallObject(ob, NULL);
 
3570
            else
 
3571
                /* Create an instance of the pointed-to type */
 
3572
                ob = PyObject_CallObject(dict->proto, NULL);
 
3573
            /*
 
3574
               XXX Is the following correct any longer?
 
3575
               We must not pass a byref() to the array then but
 
3576
               the array instance itself. Then, we cannot retrive
 
3577
               the result from the PyCArgObject.
 
3578
            */
 
3579
            if (ob == NULL)
 
3580
                goto error;
 
3581
            /* The .from_param call that will ocurr later will pass this
 
3582
               as a byref parameter. */
 
3583
            PyTuple_SET_ITEM(callargs, i, ob);
 
3584
            *poutmask |= (1 << i); /* mark as out arg */
 
3585
            (*pnumretvals)++;
 
3586
            break;
 
3587
        default:
 
3588
            PyErr_Format(PyExc_ValueError,
 
3589
                         "paramflag %d not yet implemented", flag);
 
3590
            goto error;
 
3591
            break;
 
3592
        }
 
3593
    }
 
3594
 
 
3595
    /* We have counted the arguments we have consumed in 'inargs_index'.  This
 
3596
       must be the same as len(inargs) + len(kwds), otherwise we have
 
3597
       either too much or not enough arguments. */
 
3598
 
 
3599
    actual_args = PyTuple_GET_SIZE(inargs) + (kwds ? PyDict_Size(kwds) : 0);
 
3600
    if (actual_args != inargs_index) {
 
3601
        /* When we have default values or named parameters, this error
 
3602
           message is misleading.  See unittests/test_paramflags.py
 
3603
         */
 
3604
        PyErr_Format(PyExc_TypeError,
 
3605
                     "call takes exactly %d arguments (%zd given)",
 
3606
                     inargs_index, actual_args);
 
3607
        goto error;
 
3608
    }
 
3609
 
 
3610
    /* outmask is a bitmask containing indexes into callargs.  Items at
 
3611
       these indexes contain values to return.
 
3612
     */
 
3613
    return callargs;
3614
3614
  error:
3615
 
        Py_DECREF(callargs);
3616
 
        return NULL;
 
3615
    Py_DECREF(callargs);
 
3616
    return NULL;
3617
3617
}
3618
3618
 
3619
3619
/* See also:
3626
3626
*/
3627
3627
static PyObject *
3628
3628
_build_result(PyObject *result, PyObject *callargs,
3629
 
              int outmask, int inoutmask, unsigned int numretvals)
 
3629
              int outmask, int inoutmask, unsigned int numretvals)
3630
3630
{
3631
 
        unsigned int i, index;
3632
 
        int bit;
3633
 
        PyObject *tup = NULL;
3634
 
 
3635
 
        if (callargs == NULL)
3636
 
                return result;
3637
 
        if (result == NULL || numretvals == 0) {
3638
 
                Py_DECREF(callargs);
3639
 
                return result;
3640
 
        }
3641
 
        Py_DECREF(result);
3642
 
 
3643
 
        /* tup will not be allocated if numretvals == 1 */
3644
 
        /* allocate tuple to hold the result */
3645
 
        if (numretvals > 1) {
3646
 
                tup = PyTuple_New(numretvals);
3647
 
                if (tup == NULL) {
3648
 
                        Py_DECREF(callargs);
3649
 
                        return NULL;
3650
 
                }
3651
 
        }
3652
 
 
3653
 
        index = 0;
3654
 
        for (bit = 1, i = 0; i < 32; ++i, bit <<= 1) {
3655
 
                PyObject *v;
3656
 
                if (bit & inoutmask) {
3657
 
                        v = PyTuple_GET_ITEM(callargs, i);
3658
 
                        Py_INCREF(v);
3659
 
                        if (numretvals == 1) {
3660
 
                                Py_DECREF(callargs);
3661
 
                                return v;
3662
 
                        }
3663
 
                        PyTuple_SET_ITEM(tup, index, v);
3664
 
                        index++;
3665
 
                } else if (bit & outmask) {
3666
 
                        v = PyTuple_GET_ITEM(callargs, i);
3667
 
                        v = PyObject_CallMethod(v, "__ctypes_from_outparam__", NULL);
3668
 
                        if (v == NULL || numretvals == 1) {
3669
 
                                Py_DECREF(callargs);
3670
 
                                return v;
3671
 
                        }
3672
 
                        PyTuple_SET_ITEM(tup, index, v);
3673
 
                        index++;
3674
 
                }
3675
 
                if (index == numretvals)
3676
 
                        break;
3677
 
        }
3678
 
 
3679
 
        Py_DECREF(callargs);
3680
 
        return tup;
 
3631
    unsigned int i, index;
 
3632
    int bit;
 
3633
    PyObject *tup = NULL;
 
3634
 
 
3635
    if (callargs == NULL)
 
3636
        return result;
 
3637
    if (result == NULL || numretvals == 0) {
 
3638
        Py_DECREF(callargs);
 
3639
        return result;
 
3640
    }
 
3641
    Py_DECREF(result);
 
3642
 
 
3643
    /* tup will not be allocated if numretvals == 1 */
 
3644
    /* allocate tuple to hold the result */
 
3645
    if (numretvals > 1) {
 
3646
        tup = PyTuple_New(numretvals);
 
3647
        if (tup == NULL) {
 
3648
            Py_DECREF(callargs);
 
3649
            return NULL;
 
3650
        }
 
3651
    }
 
3652
 
 
3653
    index = 0;
 
3654
    for (bit = 1, i = 0; i < 32; ++i, bit <<= 1) {
 
3655
        PyObject *v;
 
3656
        if (bit & inoutmask) {
 
3657
            v = PyTuple_GET_ITEM(callargs, i);
 
3658
            Py_INCREF(v);
 
3659
            if (numretvals == 1) {
 
3660
                Py_DECREF(callargs);
 
3661
                return v;
 
3662
            }
 
3663
            PyTuple_SET_ITEM(tup, index, v);
 
3664
            index++;
 
3665
        } else if (bit & outmask) {
 
3666
            v = PyTuple_GET_ITEM(callargs, i);
 
3667
            v = PyObject_CallMethod(v, "__ctypes_from_outparam__", NULL);
 
3668
            if (v == NULL || numretvals == 1) {
 
3669
                Py_DECREF(callargs);
 
3670
                return v;
 
3671
            }
 
3672
            PyTuple_SET_ITEM(tup, index, v);
 
3673
            index++;
 
3674
        }
 
3675
        if (index == numretvals)
 
3676
            break;
 
3677
    }
 
3678
 
 
3679
    Py_DECREF(callargs);
 
3680
    return tup;
3681
3681
}
3682
3682
 
3683
3683
static PyObject *
3684
3684
PyCFuncPtr_call(PyCFuncPtrObject *self, PyObject *inargs, PyObject *kwds)
3685
3685
{
3686
 
        PyObject *restype;
3687
 
        PyObject *converters;
3688
 
        PyObject *checker;
3689
 
        PyObject *argtypes;
3690
 
        StgDictObject *dict = PyObject_stgdict((PyObject *)self);
3691
 
        PyObject *result;
3692
 
        PyObject *callargs;
3693
 
        PyObject *errcheck;
 
3686
    PyObject *restype;
 
3687
    PyObject *converters;
 
3688
    PyObject *checker;
 
3689
    PyObject *argtypes;
 
3690
    StgDictObject *dict = PyObject_stgdict((PyObject *)self);
 
3691
    PyObject *result;
 
3692
    PyObject *callargs;
 
3693
    PyObject *errcheck;
3694
3694
#ifdef MS_WIN32
3695
 
        IUnknown *piunk = NULL;
 
3695
    IUnknown *piunk = NULL;
3696
3696
#endif
3697
 
        void *pProc = NULL;
3698
 
 
3699
 
        int inoutmask;
3700
 
        int outmask;
3701
 
        unsigned int numretvals;
3702
 
 
3703
 
        assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */
3704
 
        restype = self->restype ? self->restype : dict->restype;
3705
 
        converters = self->converters ? self->converters : dict->converters;
3706
 
        checker = self->checker ? self->checker : dict->checker;
3707
 
        argtypes = self->argtypes ? self->argtypes : dict->argtypes;
 
3697
    void *pProc = NULL;
 
3698
 
 
3699
    int inoutmask;
 
3700
    int outmask;
 
3701
    unsigned int numretvals;
 
3702
 
 
3703
    assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */
 
3704
    restype = self->restype ? self->restype : dict->restype;
 
3705
    converters = self->converters ? self->converters : dict->converters;
 
3706
    checker = self->checker ? self->checker : dict->checker;
 
3707
    argtypes = self->argtypes ? self->argtypes : dict->argtypes;
3708
3708
/* later, we probably want to have an errcheck field in stgdict */
3709
 
        errcheck = self->errcheck /* ? self->errcheck : dict->errcheck */;
3710
 
 
3711
 
 
3712
 
        pProc = *(void **)self->b_ptr;
3713
 
#ifdef MS_WIN32
3714
 
        if (self->index) {
3715
 
                /* It's a COM method */
3716
 
                CDataObject *this;
3717
 
                this = (CDataObject *)PyTuple_GetItem(inargs, 0); /* borrowed ref! */
3718
 
                if (!this) {
3719
 
                        PyErr_SetString(PyExc_ValueError,
3720
 
                                        "native com method call without 'this' parameter");
3721
 
                        return NULL;
3722
 
                }
3723
 
                if (!CDataObject_Check(this)) {
3724
 
                        PyErr_SetString(PyExc_TypeError,
3725
 
                                        "Expected a COM this pointer as first argument");
3726
 
                        return NULL;
3727
 
                }
3728
 
                /* there should be more checks? No, in Python */
3729
 
                /* First arg is an pointer to an interface instance */
3730
 
                if (!this->b_ptr || *(void **)this->b_ptr == NULL) {
3731
 
                        PyErr_SetString(PyExc_ValueError,
3732
 
                                        "NULL COM pointer access");
3733
 
                        return NULL;
3734
 
                }
3735
 
                piunk = *(IUnknown **)this->b_ptr;
3736
 
                if (NULL == piunk->lpVtbl) {
3737
 
                        PyErr_SetString(PyExc_ValueError,
3738
 
                                        "COM method call without VTable");
3739
 
                        return NULL;
3740
 
                }
3741
 
                pProc = ((void **)piunk->lpVtbl)[self->index - 0x1000];
3742
 
        }
3743
 
#endif
3744
 
        callargs = _build_callargs(self, argtypes,
3745
 
                                   inargs, kwds,
3746
 
                                   &outmask, &inoutmask, &numretvals);
3747
 
        if (callargs == NULL)
3748
 
                return NULL;
3749
 
 
3750
 
        if (converters) {
3751
 
                int required = Py_SAFE_DOWNCAST(PyTuple_GET_SIZE(converters),
3752
 
                                                Py_ssize_t, int);
3753
 
                int actual = Py_SAFE_DOWNCAST(PyTuple_GET_SIZE(callargs),
3754
 
                                              Py_ssize_t, int);
3755
 
 
3756
 
                if ((dict->flags & FUNCFLAG_CDECL) == FUNCFLAG_CDECL) {
3757
 
                        /* For cdecl functions, we allow more actual arguments
3758
 
                           than the length of the argtypes tuple.
3759
 
                        */
3760
 
                        if (required > actual) {
3761
 
                                Py_DECREF(callargs);
3762
 
                                PyErr_Format(PyExc_TypeError,
3763
 
                          "this function takes at least %d argument%s (%d given)",
3764
 
                                             required,
3765
 
                                             required == 1 ? "" : "s",
3766
 
                                             actual);
3767
 
                                return NULL;
3768
 
                        }
3769
 
                } else if (required != actual) {
3770
 
                        Py_DECREF(callargs);
3771
 
                        PyErr_Format(PyExc_TypeError,
3772
 
                             "this function takes %d argument%s (%d given)",
3773
 
                                     required,
3774
 
                                     required == 1 ? "" : "s",
3775
 
                                     actual);
3776
 
                        return NULL;
3777
 
                }
3778
 
        }
3779
 
 
3780
 
        result = _ctypes_callproc(pProc,
3781
 
                           callargs,
3782
 
#ifdef MS_WIN32
3783
 
                           piunk,
3784
 
                           self->iid,
3785
 
#endif
3786
 
                           dict->flags,
3787
 
                           converters,
3788
 
                           restype,
3789
 
                           checker);
 
3709
    errcheck = self->errcheck /* ? self->errcheck : dict->errcheck */;
 
3710
 
 
3711
 
 
3712
    pProc = *(void **)self->b_ptr;
 
3713
#ifdef MS_WIN32
 
3714
    if (self->index) {
 
3715
        /* It's a COM method */
 
3716
        CDataObject *this;
 
3717
        this = (CDataObject *)PyTuple_GetItem(inargs, 0); /* borrowed ref! */
 
3718
        if (!this) {
 
3719
            PyErr_SetString(PyExc_ValueError,
 
3720
                            "native com method call without 'this' parameter");
 
3721
            return NULL;
 
3722
        }
 
3723
        if (!CDataObject_Check(this)) {
 
3724
            PyErr_SetString(PyExc_TypeError,
 
3725
                            "Expected a COM this pointer as first argument");
 
3726
            return NULL;
 
3727
        }
 
3728
        /* there should be more checks? No, in Python */
 
3729
        /* First arg is an pointer to an interface instance */
 
3730
        if (!this->b_ptr || *(void **)this->b_ptr == NULL) {
 
3731
            PyErr_SetString(PyExc_ValueError,
 
3732
                            "NULL COM pointer access");
 
3733
            return NULL;
 
3734
        }
 
3735
        piunk = *(IUnknown **)this->b_ptr;
 
3736
        if (NULL == piunk->lpVtbl) {
 
3737
            PyErr_SetString(PyExc_ValueError,
 
3738
                            "COM method call without VTable");
 
3739
            return NULL;
 
3740
        }
 
3741
        pProc = ((void **)piunk->lpVtbl)[self->index - 0x1000];
 
3742
    }
 
3743
#endif
 
3744
    callargs = _build_callargs(self, argtypes,
 
3745
                               inargs, kwds,
 
3746
                               &outmask, &inoutmask, &numretvals);
 
3747
    if (callargs == NULL)
 
3748
        return NULL;
 
3749
 
 
3750
    if (converters) {
 
3751
        int required = Py_SAFE_DOWNCAST(PyTuple_GET_SIZE(converters),
 
3752
                                        Py_ssize_t, int);
 
3753
        int actual = Py_SAFE_DOWNCAST(PyTuple_GET_SIZE(callargs),
 
3754
                                      Py_ssize_t, int);
 
3755
 
 
3756
        if ((dict->flags & FUNCFLAG_CDECL) == FUNCFLAG_CDECL) {
 
3757
            /* For cdecl functions, we allow more actual arguments
 
3758
               than the length of the argtypes tuple.
 
3759
            */
 
3760
            if (required > actual) {
 
3761
                Py_DECREF(callargs);
 
3762
                PyErr_Format(PyExc_TypeError,
 
3763
              "this function takes at least %d argument%s (%d given)",
 
3764
                                 required,
 
3765
                                 required == 1 ? "" : "s",
 
3766
                                 actual);
 
3767
                return NULL;
 
3768
            }
 
3769
        } else if (required != actual) {
 
3770
            Py_DECREF(callargs);
 
3771
            PyErr_Format(PyExc_TypeError,
 
3772
                 "this function takes %d argument%s (%d given)",
 
3773
                     required,
 
3774
                     required == 1 ? "" : "s",
 
3775
                     actual);
 
3776
            return NULL;
 
3777
        }
 
3778
    }
 
3779
 
 
3780
    result = _ctypes_callproc(pProc,
 
3781
                       callargs,
 
3782
#ifdef MS_WIN32
 
3783
                       piunk,
 
3784
                       self->iid,
 
3785
#endif
 
3786
                       dict->flags,
 
3787
                       converters,
 
3788
                       restype,
 
3789
                       checker);
3790
3790
/* The 'errcheck' protocol */
3791
 
        if (result != NULL && errcheck) {
3792
 
                PyObject *v = PyObject_CallFunctionObjArgs(errcheck,
3793
 
                                                           result,
3794
 
                                                           self,
3795
 
                                                           callargs,
3796
 
                                                           NULL);
3797
 
                /* If the errcheck funtion failed, return NULL.
3798
 
                   If the errcheck function returned callargs unchanged,
3799
 
                   continue normal processing.
3800
 
                   If the errcheck function returned something else,
3801
 
                   use that as result.
3802
 
                */
3803
 
                if (v == NULL || v != callargs) {
3804
 
                        Py_DECREF(result);
3805
 
                        Py_DECREF(callargs);
3806
 
                        return v;
3807
 
                }
3808
 
                Py_DECREF(v);
3809
 
        }
 
3791
    if (result != NULL && errcheck) {
 
3792
        PyObject *v = PyObject_CallFunctionObjArgs(errcheck,
 
3793
                                                   result,
 
3794
                                                   self,
 
3795
                                                   callargs,
 
3796
                                                   NULL);
 
3797
        /* If the errcheck funtion failed, return NULL.
 
3798
           If the errcheck function returned callargs unchanged,
 
3799
           continue normal processing.
 
3800
           If the errcheck function returned something else,
 
3801
           use that as result.
 
3802
        */
 
3803
        if (v == NULL || v != callargs) {
 
3804
            Py_DECREF(result);
 
3805
            Py_DECREF(callargs);
 
3806
            return v;
 
3807
        }
 
3808
        Py_DECREF(v);
 
3809
    }
3810
3810
 
3811
 
        return _build_result(result, callargs,
3812
 
                             outmask, inoutmask, numretvals);
 
3811
    return _build_result(result, callargs,
 
3812
                         outmask, inoutmask, numretvals);
3813
3813
}
3814
3814
 
3815
3815
static int
3816
3816
PyCFuncPtr_traverse(PyCFuncPtrObject *self, visitproc visit, void *arg)
3817
3817
{
3818
 
        Py_VISIT(self->callable);
3819
 
        Py_VISIT(self->restype);
3820
 
        Py_VISIT(self->checker);
3821
 
        Py_VISIT(self->errcheck);
3822
 
        Py_VISIT(self->argtypes);
3823
 
        Py_VISIT(self->converters);
3824
 
        Py_VISIT(self->paramflags);
3825
 
        Py_VISIT(self->thunk);
3826
 
        return PyCData_traverse((CDataObject *)self, visit, arg);
 
3818
    Py_VISIT(self->callable);
 
3819
    Py_VISIT(self->restype);
 
3820
    Py_VISIT(self->checker);
 
3821
    Py_VISIT(self->errcheck);
 
3822
    Py_VISIT(self->argtypes);
 
3823
    Py_VISIT(self->converters);
 
3824
    Py_VISIT(self->paramflags);
 
3825
    Py_VISIT(self->thunk);
 
3826
    return PyCData_traverse((CDataObject *)self, visit, arg);
3827
3827
}
3828
3828
 
3829
3829
static int
3830
3830
PyCFuncPtr_clear(PyCFuncPtrObject *self)
3831
3831
{
3832
 
        Py_CLEAR(self->callable);
3833
 
        Py_CLEAR(self->restype);
3834
 
        Py_CLEAR(self->checker);
3835
 
        Py_CLEAR(self->errcheck);
3836
 
        Py_CLEAR(self->argtypes);
3837
 
        Py_CLEAR(self->converters);
3838
 
        Py_CLEAR(self->paramflags);
3839
 
        Py_CLEAR(self->thunk);
3840
 
        return PyCData_clear((CDataObject *)self);
 
3832
    Py_CLEAR(self->callable);
 
3833
    Py_CLEAR(self->restype);
 
3834
    Py_CLEAR(self->checker);
 
3835
    Py_CLEAR(self->errcheck);
 
3836
    Py_CLEAR(self->argtypes);
 
3837
    Py_CLEAR(self->converters);
 
3838
    Py_CLEAR(self->paramflags);
 
3839
    Py_CLEAR(self->thunk);
 
3840
    return PyCData_clear((CDataObject *)self);
3841
3841
}
3842
3842
 
3843
3843
static void
3844
3844
PyCFuncPtr_dealloc(PyCFuncPtrObject *self)
3845
3845
{
3846
 
        PyCFuncPtr_clear(self);
3847
 
        Py_TYPE(self)->tp_free((PyObject *)self);
 
3846
    PyCFuncPtr_clear(self);
 
3847
    Py_TYPE(self)->tp_free((PyObject *)self);
3848
3848
}
3849
3849
 
3850
3850
static PyObject *
3851
3851
PyCFuncPtr_repr(PyCFuncPtrObject *self)
3852
3852
{
3853
3853
#ifdef MS_WIN32
3854
 
        if (self->index)
3855
 
                return PyUnicode_FromFormat("<COM method offset %d: %s at %p>",
3856
 
                                           self->index - 0x1000,
3857
 
                                           Py_TYPE(self)->tp_name,
3858
 
                                           self);
 
3854
    if (self->index)
 
3855
        return PyUnicode_FromFormat("<COM method offset %d: %s at %p>",
 
3856
                                   self->index - 0x1000,
 
3857
                                   Py_TYPE(self)->tp_name,
 
3858
                                   self);
3859
3859
#endif
3860
 
        return PyUnicode_FromFormat("<%s object at %p>",
3861
 
                                   Py_TYPE(self)->tp_name,
3862
 
                                   self);
 
3860
    return PyUnicode_FromFormat("<%s object at %p>",
 
3861
                               Py_TYPE(self)->tp_name,
 
3862
                               self);
3863
3863
}
3864
3864
 
3865
3865
static int
3866
3866
PyCFuncPtr_bool(PyCFuncPtrObject *self)
3867
3867
{
3868
 
        return ((*(void **)self->b_ptr != NULL)
 
3868
    return ((*(void **)self->b_ptr != NULL)
3869
3869
#ifdef MS_WIN32
3870
 
                || (self->index != 0)
 
3870
        || (self->index != 0)
3871
3871
#endif
3872
 
                );
 
3872
        );
3873
3873
}
3874
3874
 
3875
3875
static PyNumberMethods PyCFuncPtr_as_number = {
3876
 
        0, /* nb_add */
3877
 
        0, /* nb_subtract */
3878
 
        0, /* nb_multiply */
3879
 
        0, /* nb_remainder */
3880
 
        0, /* nb_divmod */
3881
 
        0, /* nb_power */
3882
 
        0, /* nb_negative */
3883
 
        0, /* nb_positive */
3884
 
        0, /* nb_absolute */
3885
 
        (inquiry)PyCFuncPtr_bool, /* nb_bool */
 
3876
    0, /* nb_add */
 
3877
    0, /* nb_subtract */
 
3878
    0, /* nb_multiply */
 
3879
    0, /* nb_remainder */
 
3880
    0, /* nb_divmod */
 
3881
    0, /* nb_power */
 
3882
    0, /* nb_negative */
 
3883
    0, /* nb_positive */
 
3884
    0, /* nb_absolute */
 
3885
    (inquiry)PyCFuncPtr_bool, /* nb_bool */
3886
3886
};
3887
3887
 
3888
3888
PyTypeObject PyCFuncPtr_Type = {
3889
 
        PyVarObject_HEAD_INIT(NULL, 0)
3890
 
        "_ctypes.PyCFuncPtr",
3891
 
        sizeof(PyCFuncPtrObject),                       /* tp_basicsize */
3892
 
        0,                                      /* tp_itemsize */
3893
 
        (destructor)PyCFuncPtr_dealloc,         /* tp_dealloc */
3894
 
        0,                                      /* tp_print */
3895
 
        0,                                      /* tp_getattr */
3896
 
        0,                                      /* tp_setattr */
3897
 
        0,                                      /* tp_reserved */
3898
 
        (reprfunc)PyCFuncPtr_repr,              /* tp_repr */
3899
 
        &PyCFuncPtr_as_number,                  /* tp_as_number */
3900
 
        0,                                      /* tp_as_sequence */
3901
 
        0,                                      /* tp_as_mapping */
3902
 
        0,                                      /* tp_hash */
3903
 
        (ternaryfunc)PyCFuncPtr_call,           /* tp_call */
3904
 
        0,                                      /* tp_str */
3905
 
        0,                                      /* tp_getattro */
3906
 
        0,                                      /* tp_setattro */
3907
 
        &PyCData_as_buffer,                     /* tp_as_buffer */
3908
 
        Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3909
 
        "Function Pointer",                     /* tp_doc */
3910
 
        (traverseproc)PyCFuncPtr_traverse,      /* tp_traverse */
3911
 
        (inquiry)PyCFuncPtr_clear,              /* tp_clear */
3912
 
        0,                                      /* tp_richcompare */
3913
 
        0,                                      /* tp_weaklistoffset */
3914
 
        0,                                      /* tp_iter */
3915
 
        0,                                      /* tp_iternext */
3916
 
        0,                                      /* tp_methods */
3917
 
        0,                                      /* tp_members */
3918
 
        PyCFuncPtr_getsets,                     /* tp_getset */
3919
 
        0,                                      /* tp_base */
3920
 
        0,                                      /* tp_dict */
3921
 
        0,                                      /* tp_descr_get */
3922
 
        0,                                      /* tp_descr_set */
3923
 
        0,                                      /* tp_dictoffset */
3924
 
        0,                                      /* tp_init */
3925
 
        0,                                      /* tp_alloc */
3926
 
        PyCFuncPtr_new,                         /* tp_new */
3927
 
        0,                                      /* tp_free */
 
3889
    PyVarObject_HEAD_INIT(NULL, 0)
 
3890
    "_ctypes.PyCFuncPtr",
 
3891
    sizeof(PyCFuncPtrObject),                           /* tp_basicsize */
 
3892
    0,                                          /* tp_itemsize */
 
3893
    (destructor)PyCFuncPtr_dealloc,             /* tp_dealloc */
 
3894
    0,                                          /* tp_print */
 
3895
    0,                                          /* tp_getattr */
 
3896
    0,                                          /* tp_setattr */
 
3897
    0,                                          /* tp_reserved */
 
3898
    (reprfunc)PyCFuncPtr_repr,                  /* tp_repr */
 
3899
    &PyCFuncPtr_as_number,                      /* tp_as_number */
 
3900
    0,                                          /* tp_as_sequence */
 
3901
    0,                                          /* tp_as_mapping */
 
3902
    0,                                          /* tp_hash */
 
3903
    (ternaryfunc)PyCFuncPtr_call,               /* tp_call */
 
3904
    0,                                          /* tp_str */
 
3905
    0,                                          /* tp_getattro */
 
3906
    0,                                          /* tp_setattro */
 
3907
    &PyCData_as_buffer,                         /* tp_as_buffer */
 
3908
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
 
3909
    "Function Pointer",                         /* tp_doc */
 
3910
    (traverseproc)PyCFuncPtr_traverse,          /* tp_traverse */
 
3911
    (inquiry)PyCFuncPtr_clear,                  /* tp_clear */
 
3912
    0,                                          /* tp_richcompare */
 
3913
    0,                                          /* tp_weaklistoffset */
 
3914
    0,                                          /* tp_iter */
 
3915
    0,                                          /* tp_iternext */
 
3916
    0,                                          /* tp_methods */
 
3917
    0,                                          /* tp_members */
 
3918
    PyCFuncPtr_getsets,                         /* tp_getset */
 
3919
    0,                                          /* tp_base */
 
3920
    0,                                          /* tp_dict */
 
3921
    0,                                          /* tp_descr_get */
 
3922
    0,                                          /* tp_descr_set */
 
3923
    0,                                          /* tp_dictoffset */
 
3924
    0,                                          /* tp_init */
 
3925
    0,                                          /* tp_alloc */
 
3926
    PyCFuncPtr_new,                             /* tp_new */
 
3927
    0,                                          /* tp_free */
3928
3928
};
3929
 
 
 
3929
 
3930
3930
/*****************************************************************/
3931
3931
/*
3932
3932
  Struct_Type
3941
3941
 */
3942
3942
static int
3943
3943
_init_pos_args(PyObject *self, PyTypeObject *type,
3944
 
               PyObject *args, PyObject *kwds,
3945
 
               int index)
 
3944
               PyObject *args, PyObject *kwds,
 
3945
               int index)
3946
3946
{
3947
 
        StgDictObject *dict;
3948
 
        PyObject *fields;
3949
 
        int i;
3950
 
 
3951
 
        if (PyType_stgdict((PyObject *)type->tp_base)) {
3952
 
                index = _init_pos_args(self, type->tp_base,
3953
 
                                       args, kwds,
3954
 
                                       index);
3955
 
                if (index == -1)
3956
 
                        return -1;
3957
 
        }
3958
 
 
3959
 
        dict = PyType_stgdict((PyObject *)type);
3960
 
        fields = PyDict_GetItemString((PyObject *)dict, "_fields_");
3961
 
        if (fields == NULL)
3962
 
                return index;
3963
 
 
3964
 
        for (i = 0;
3965
 
             i < dict->length && (i+index) < PyTuple_GET_SIZE(args);
3966
 
             ++i) {
3967
 
                PyObject *pair = PySequence_GetItem(fields, i);
3968
 
                PyObject *name, *val;
3969
 
                int res;
3970
 
                if (!pair)
3971
 
                        return -1;
3972
 
                name = PySequence_GetItem(pair, 0);
3973
 
                if (!name) {
3974
 
                        Py_DECREF(pair);
3975
 
                        return -1;
3976
 
                }
3977
 
                val = PyTuple_GET_ITEM(args, i + index);
3978
 
                if (kwds && PyDict_GetItem(kwds, name)) {
3979
 
                        char *field = PyBytes_AsString(name);
3980
 
                        if (field == NULL) {
3981
 
                                PyErr_Clear();
3982
 
                                field = "???";
3983
 
                        }
3984
 
                        PyErr_Format(PyExc_TypeError,
3985
 
                                     "duplicate values for field '%s'",
3986
 
                                     field);
3987
 
                        Py_DECREF(pair);
3988
 
                        Py_DECREF(name);
3989
 
                        return -1;
3990
 
                }
3991
 
                
3992
 
                res = PyObject_SetAttr(self, name, val);
3993
 
                Py_DECREF(pair);
3994
 
                Py_DECREF(name);
3995
 
                if (res == -1)
3996
 
                        return -1;
3997
 
        }
3998
 
        return index + dict->length;
 
3947
    StgDictObject *dict;
 
3948
    PyObject *fields;
 
3949
    int i;
 
3950
 
 
3951
    if (PyType_stgdict((PyObject *)type->tp_base)) {
 
3952
        index = _init_pos_args(self, type->tp_base,
 
3953
                               args, kwds,
 
3954
                               index);
 
3955
        if (index == -1)
 
3956
            return -1;
 
3957
    }
 
3958
 
 
3959
    dict = PyType_stgdict((PyObject *)type);
 
3960
    fields = PyDict_GetItemString((PyObject *)dict, "_fields_");
 
3961
    if (fields == NULL)
 
3962
        return index;
 
3963
 
 
3964
    for (i = 0;
 
3965
         i < dict->length && (i+index) < PyTuple_GET_SIZE(args);
 
3966
         ++i) {
 
3967
        PyObject *pair = PySequence_GetItem(fields, i);
 
3968
        PyObject *name, *val;
 
3969
        int res;
 
3970
        if (!pair)
 
3971
            return -1;
 
3972
        name = PySequence_GetItem(pair, 0);
 
3973
        if (!name) {
 
3974
            Py_DECREF(pair);
 
3975
            return -1;
 
3976
        }
 
3977
        val = PyTuple_GET_ITEM(args, i + index);
 
3978
        if (kwds && PyDict_GetItem(kwds, name)) {
 
3979
            char *field = PyBytes_AsString(name);
 
3980
            if (field == NULL) {
 
3981
                PyErr_Clear();
 
3982
                field = "???";
 
3983
            }
 
3984
            PyErr_Format(PyExc_TypeError,
 
3985
                         "duplicate values for field '%s'",
 
3986
                         field);
 
3987
            Py_DECREF(pair);
 
3988
            Py_DECREF(name);
 
3989
            return -1;
 
3990
        }
 
3991
 
 
3992
        res = PyObject_SetAttr(self, name, val);
 
3993
        Py_DECREF(pair);
 
3994
        Py_DECREF(name);
 
3995
        if (res == -1)
 
3996
            return -1;
 
3997
    }
 
3998
    return index + dict->length;
3999
3999
}
4000
4000
 
4001
4001
static int
4004
4004
/* Optimization possible: Store the attribute names _fields_[x][0]
4005
4005
 * in C accessible fields somewhere ?
4006
4006
 */
4007
 
        if (!PyTuple_Check(args)) {
4008
 
                PyErr_SetString(PyExc_TypeError,
4009
 
                                "args not a tuple?");
4010
 
                return -1;
4011
 
        }
4012
 
        if (PyTuple_GET_SIZE(args)) {
4013
 
                int res = _init_pos_args(self, Py_TYPE(self),
4014
 
                                         args, kwds, 0);
4015
 
                if (res == -1)
4016
 
                        return -1;
4017
 
                if (res < PyTuple_GET_SIZE(args)) {
4018
 
                        PyErr_SetString(PyExc_TypeError,
4019
 
                                        "too many initializers");
4020
 
                        return -1;
4021
 
                }
4022
 
        }
 
4007
    if (!PyTuple_Check(args)) {
 
4008
        PyErr_SetString(PyExc_TypeError,
 
4009
                        "args not a tuple?");
 
4010
        return -1;
 
4011
    }
 
4012
    if (PyTuple_GET_SIZE(args)) {
 
4013
        int res = _init_pos_args(self, Py_TYPE(self),
 
4014
                                 args, kwds, 0);
 
4015
        if (res == -1)
 
4016
            return -1;
 
4017
        if (res < PyTuple_GET_SIZE(args)) {
 
4018
            PyErr_SetString(PyExc_TypeError,
 
4019
                            "too many initializers");
 
4020
            return -1;
 
4021
        }
 
4022
    }
4023
4023
 
4024
 
        if (kwds) {
4025
 
                PyObject *key, *value;
4026
 
                Py_ssize_t pos = 0;
4027
 
                while(PyDict_Next(kwds, &pos, &key, &value)) {
4028
 
                        if (-1 == PyObject_SetAttr(self, key, value))
4029
 
                                return -1;
4030
 
                }
4031
 
        }
4032
 
        return 0;
 
4024
    if (kwds) {
 
4025
        PyObject *key, *value;
 
4026
        Py_ssize_t pos = 0;
 
4027
        while(PyDict_Next(kwds, &pos, &key, &value)) {
 
4028
            if (-1 == PyObject_SetAttr(self, key, value))
 
4029
                return -1;
 
4030
        }
 
4031
    }
 
4032
    return 0;
4033
4033
}
4034
4034
 
4035
4035
static PyTypeObject Struct_Type = {
4036
 
        PyVarObject_HEAD_INIT(NULL, 0)
4037
 
        "_ctypes.Structure",
4038
 
        sizeof(CDataObject),                    /* tp_basicsize */
4039
 
        0,                                      /* tp_itemsize */
4040
 
        0,                                      /* tp_dealloc */
4041
 
        0,                                      /* tp_print */
4042
 
        0,                                      /* tp_getattr */
4043
 
        0,                                      /* tp_setattr */
4044
 
        0,                                      /* tp_reserved */
4045
 
        0,                                      /* tp_repr */
4046
 
        0,                                      /* tp_as_number */
4047
 
        0,                                      /* tp_as_sequence */
4048
 
        0,                                      /* tp_as_mapping */
4049
 
        0,                                      /* tp_hash */
4050
 
        0,                                      /* tp_call */
4051
 
        0,                                      /* tp_str */
4052
 
        0,                                      /* tp_getattro */
4053
 
        0,                                      /* tp_setattro */
4054
 
        &PyCData_as_buffer,                     /* tp_as_buffer */
4055
 
        Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4056
 
        "Structure base class",                 /* tp_doc */
4057
 
        (traverseproc)PyCData_traverse,         /* tp_traverse */
4058
 
        (inquiry)PyCData_clear,                 /* tp_clear */
4059
 
        0,                                      /* tp_richcompare */
4060
 
        0,                                      /* tp_weaklistoffset */
4061
 
        0,                                      /* tp_iter */
4062
 
        0,                                      /* tp_iternext */
4063
 
        0,                                      /* tp_methods */
4064
 
        0,                                      /* tp_members */
4065
 
        0,                                      /* tp_getset */
4066
 
        0,                                      /* tp_base */
4067
 
        0,                                      /* tp_dict */
4068
 
        0,                                      /* tp_descr_get */
4069
 
        0,                                      /* tp_descr_set */
4070
 
        0,                                      /* tp_dictoffset */
4071
 
        Struct_init,                            /* tp_init */
4072
 
        0,                                      /* tp_alloc */
4073
 
        GenericPyCData_new,                     /* tp_new */
4074
 
        0,                                      /* tp_free */
 
4036
    PyVarObject_HEAD_INIT(NULL, 0)
 
4037
    "_ctypes.Structure",
 
4038
    sizeof(CDataObject),                        /* tp_basicsize */
 
4039
    0,                                          /* tp_itemsize */
 
4040
    0,                                          /* tp_dealloc */
 
4041
    0,                                          /* tp_print */
 
4042
    0,                                          /* tp_getattr */
 
4043
    0,                                          /* tp_setattr */
 
4044
    0,                                          /* tp_reserved */
 
4045
    0,                                          /* tp_repr */
 
4046
    0,                                          /* tp_as_number */
 
4047
    0,                                          /* tp_as_sequence */
 
4048
    0,                                          /* tp_as_mapping */
 
4049
    0,                                          /* tp_hash */
 
4050
    0,                                          /* tp_call */
 
4051
    0,                                          /* tp_str */
 
4052
    0,                                          /* tp_getattro */
 
4053
    0,                                          /* tp_setattro */
 
4054
    &PyCData_as_buffer,                         /* tp_as_buffer */
 
4055
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
 
4056
    "Structure base class",                     /* tp_doc */
 
4057
    (traverseproc)PyCData_traverse,             /* tp_traverse */
 
4058
    (inquiry)PyCData_clear,                     /* tp_clear */
 
4059
    0,                                          /* tp_richcompare */
 
4060
    0,                                          /* tp_weaklistoffset */
 
4061
    0,                                          /* tp_iter */
 
4062
    0,                                          /* tp_iternext */
 
4063
    0,                                          /* tp_methods */
 
4064
    0,                                          /* tp_members */
 
4065
    0,                                          /* tp_getset */
 
4066
    0,                                          /* tp_base */
 
4067
    0,                                          /* tp_dict */
 
4068
    0,                                          /* tp_descr_get */
 
4069
    0,                                          /* tp_descr_set */
 
4070
    0,                                          /* tp_dictoffset */
 
4071
    Struct_init,                                /* tp_init */
 
4072
    0,                                          /* tp_alloc */
 
4073
    GenericPyCData_new,                         /* tp_new */
 
4074
    0,                                          /* tp_free */
4075
4075
};
4076
4076
 
4077
4077
static PyTypeObject Union_Type = {
4078
 
        PyVarObject_HEAD_INIT(NULL, 0)
4079
 
        "_ctypes.Union",
4080
 
        sizeof(CDataObject),                    /* tp_basicsize */
4081
 
        0,                                      /* tp_itemsize */
4082
 
        0,                                      /* tp_dealloc */
4083
 
        0,                                      /* tp_print */
4084
 
        0,                                      /* tp_getattr */
4085
 
        0,                                      /* tp_setattr */
4086
 
        0,                                      /* tp_reserved */
4087
 
        0,                                      /* tp_repr */
4088
 
        0,                                      /* tp_as_number */
4089
 
        0,                                      /* tp_as_sequence */
4090
 
        0,                                      /* tp_as_mapping */
4091
 
        0,                                      /* tp_hash */
4092
 
        0,                                      /* tp_call */
4093
 
        0,                                      /* tp_str */
4094
 
        0,                                      /* tp_getattro */
4095
 
        0,                                      /* tp_setattro */
4096
 
        &PyCData_as_buffer,                     /* tp_as_buffer */
4097
 
        Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4098
 
        "Union base class",                     /* tp_doc */
4099
 
        (traverseproc)PyCData_traverse,         /* tp_traverse */
4100
 
        (inquiry)PyCData_clear,                 /* tp_clear */
4101
 
        0,                                      /* tp_richcompare */
4102
 
        0,                                      /* tp_weaklistoffset */
4103
 
        0,                                      /* tp_iter */
4104
 
        0,                                      /* tp_iternext */
4105
 
        0,                                      /* tp_methods */
4106
 
        0,                                      /* tp_members */
4107
 
        0,                                      /* tp_getset */
4108
 
        0,                                      /* tp_base */
4109
 
        0,                                      /* tp_dict */
4110
 
        0,                                      /* tp_descr_get */
4111
 
        0,                                      /* tp_descr_set */
4112
 
        0,                                      /* tp_dictoffset */
4113
 
        Struct_init,                            /* tp_init */
4114
 
        0,                                      /* tp_alloc */
4115
 
        GenericPyCData_new,                     /* tp_new */
4116
 
        0,                                      /* tp_free */
 
4078
    PyVarObject_HEAD_INIT(NULL, 0)
 
4079
    "_ctypes.Union",
 
4080
    sizeof(CDataObject),                        /* tp_basicsize */
 
4081
    0,                                          /* tp_itemsize */
 
4082
    0,                                          /* tp_dealloc */
 
4083
    0,                                          /* tp_print */
 
4084
    0,                                          /* tp_getattr */
 
4085
    0,                                          /* tp_setattr */
 
4086
    0,                                          /* tp_reserved */
 
4087
    0,                                          /* tp_repr */
 
4088
    0,                                          /* tp_as_number */
 
4089
    0,                                          /* tp_as_sequence */
 
4090
    0,                                          /* tp_as_mapping */
 
4091
    0,                                          /* tp_hash */
 
4092
    0,                                          /* tp_call */
 
4093
    0,                                          /* tp_str */
 
4094
    0,                                          /* tp_getattro */
 
4095
    0,                                          /* tp_setattro */
 
4096
    &PyCData_as_buffer,                         /* tp_as_buffer */
 
4097
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
 
4098
    "Union base class",                         /* tp_doc */
 
4099
    (traverseproc)PyCData_traverse,             /* tp_traverse */
 
4100
    (inquiry)PyCData_clear,                     /* tp_clear */
 
4101
    0,                                          /* tp_richcompare */
 
4102
    0,                                          /* tp_weaklistoffset */
 
4103
    0,                                          /* tp_iter */
 
4104
    0,                                          /* tp_iternext */
 
4105
    0,                                          /* tp_methods */
 
4106
    0,                                          /* tp_members */
 
4107
    0,                                          /* tp_getset */
 
4108
    0,                                          /* tp_base */
 
4109
    0,                                          /* tp_dict */
 
4110
    0,                                          /* tp_descr_get */
 
4111
    0,                                          /* tp_descr_set */
 
4112
    0,                                          /* tp_dictoffset */
 
4113
    Struct_init,                                /* tp_init */
 
4114
    0,                                          /* tp_alloc */
 
4115
    GenericPyCData_new,                         /* tp_new */
 
4116
    0,                                          /* tp_free */
4117
4117
};
4118
4118
 
4119
 
 
 
4119
 
4120
4120
/******************************************************************/
4121
4121
/*
4122
4122
  PyCArray_Type
4124
4124
static int
4125
4125
Array_init(CDataObject *self, PyObject *args, PyObject *kw)
4126
4126
{
4127
 
        Py_ssize_t i;
4128
 
        Py_ssize_t n;
 
4127
    Py_ssize_t i;
 
4128
    Py_ssize_t n;
4129
4129
 
4130
 
        if (!PyTuple_Check(args)) {
4131
 
                PyErr_SetString(PyExc_TypeError,
4132
 
                                "args not a tuple?");
4133
 
                return -1;
4134
 
        }
4135
 
        n = PyTuple_GET_SIZE(args);
4136
 
        for (i = 0; i < n; ++i) {
4137
 
                PyObject *v;
4138
 
                v = PyTuple_GET_ITEM(args, i);
4139
 
                if (-1 == PySequence_SetItem((PyObject *)self, i, v))
4140
 
                        return -1;
4141
 
        }
4142
 
        return 0;
 
4130
    if (!PyTuple_Check(args)) {
 
4131
        PyErr_SetString(PyExc_TypeError,
 
4132
                        "args not a tuple?");
 
4133
        return -1;
 
4134
    }
 
4135
    n = PyTuple_GET_SIZE(args);
 
4136
    for (i = 0; i < n; ++i) {
 
4137
        PyObject *v;
 
4138
        v = PyTuple_GET_ITEM(args, i);
 
4139
        if (-1 == PySequence_SetItem((PyObject *)self, i, v))
 
4140
            return -1;
 
4141
    }
 
4142
    return 0;
4143
4143
}
4144
4144
 
4145
4145
static PyObject *
4146
4146
Array_item(PyObject *_self, Py_ssize_t index)
4147
4147
{
4148
 
        CDataObject *self = (CDataObject *)_self;
4149
 
        Py_ssize_t offset, size;
4150
 
        StgDictObject *stgdict;
4151
 
 
4152
 
 
4153
 
        if (index < 0 || index >= self->b_length) {
4154
 
                PyErr_SetString(PyExc_IndexError,
4155
 
                                "invalid index");
4156
 
                return NULL;
4157
 
        }
4158
 
 
4159
 
        stgdict = PyObject_stgdict((PyObject *)self);
4160
 
        assert(stgdict); /* Cannot be NULL for array instances */
4161
 
        /* Would it be clearer if we got the item size from
4162
 
           stgdict->proto's stgdict?
4163
 
        */
4164
 
        size = stgdict->size / stgdict->length;
4165
 
        offset = index * size;
4166
 
 
4167
 
        return PyCData_get(stgdict->proto, stgdict->getfunc, (PyObject *)self,
4168
 
                         index, size, self->b_ptr + offset);
 
4148
    CDataObject *self = (CDataObject *)_self;
 
4149
    Py_ssize_t offset, size;
 
4150
    StgDictObject *stgdict;
 
4151
 
 
4152
 
 
4153
    if (index < 0 || index >= self->b_length) {
 
4154
        PyErr_SetString(PyExc_IndexError,
 
4155
                        "invalid index");
 
4156
        return NULL;
 
4157
    }
 
4158
 
 
4159
    stgdict = PyObject_stgdict((PyObject *)self);
 
4160
    assert(stgdict); /* Cannot be NULL for array instances */
 
4161
    /* Would it be clearer if we got the item size from
 
4162
       stgdict->proto's stgdict?
 
4163
    */
 
4164
    size = stgdict->size / stgdict->length;
 
4165
    offset = index * size;
 
4166
 
 
4167
    return PyCData_get(stgdict->proto, stgdict->getfunc, (PyObject *)self,
 
4168
                     index, size, self->b_ptr + offset);
4169
4169
}
4170
4170
 
4171
4171
static PyObject *
4172
4172
Array_subscript(PyObject *_self, PyObject *item)
4173
4173
{
4174
 
        CDataObject *self = (CDataObject *)_self;
4175
 
 
4176
 
        if (PyIndex_Check(item)) {
4177
 
                Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
4178
 
                
4179
 
                if (i == -1 && PyErr_Occurred())
4180
 
                        return NULL;
4181
 
                if (i < 0)
4182
 
                        i += self->b_length;
4183
 
                return Array_item(_self, i);
4184
 
        }
4185
 
        else if PySlice_Check(item) {
4186
 
                StgDictObject *stgdict, *itemdict;
4187
 
                PyObject *proto;
4188
 
                PyObject *np;
4189
 
                Py_ssize_t start, stop, step, slicelen, cur, i;
4190
 
                
4191
 
                if (PySlice_GetIndicesEx((PySliceObject *)item,
4192
 
                                         self->b_length, &start, &stop,
4193
 
                                         &step, &slicelen) < 0) {
4194
 
                        return NULL;
4195
 
                }
4196
 
                
4197
 
                stgdict = PyObject_stgdict((PyObject *)self);
4198
 
                assert(stgdict); /* Cannot be NULL for array object instances */
4199
 
                proto = stgdict->proto;
4200
 
                itemdict = PyType_stgdict(proto);
4201
 
                assert(itemdict); /* proto is the item type of the array, a
4202
 
                                     ctypes type, so this cannot be NULL */
4203
 
 
4204
 
                if (itemdict->getfunc == _ctypes_get_fielddesc("c")->getfunc) {
4205
 
                        char *ptr = (char *)self->b_ptr;
4206
 
                        char *dest;
4207
 
 
4208
 
                        if (slicelen <= 0)
4209
 
                                return PyBytes_FromStringAndSize("", 0);
4210
 
                        if (step == 1) {
4211
 
                                return PyBytes_FromStringAndSize(ptr + start,
4212
 
                                                                 slicelen);
4213
 
                        }
4214
 
                        dest = (char *)PyMem_Malloc(slicelen);
4215
 
 
4216
 
                        if (dest == NULL)
4217
 
                                return PyErr_NoMemory();
4218
 
 
4219
 
                        for (cur = start, i = 0; i < slicelen;
4220
 
                             cur += step, i++) {
4221
 
                                dest[i] = ptr[cur];
4222
 
                        }
4223
 
 
4224
 
                        np = PyBytes_FromStringAndSize(dest, slicelen);
4225
 
                        PyMem_Free(dest);
4226
 
                        return np;
4227
 
                }
 
4174
    CDataObject *self = (CDataObject *)_self;
 
4175
 
 
4176
    if (PyIndex_Check(item)) {
 
4177
        Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
 
4178
 
 
4179
        if (i == -1 && PyErr_Occurred())
 
4180
            return NULL;
 
4181
        if (i < 0)
 
4182
            i += self->b_length;
 
4183
        return Array_item(_self, i);
 
4184
    }
 
4185
    else if PySlice_Check(item) {
 
4186
        StgDictObject *stgdict, *itemdict;
 
4187
        PyObject *proto;
 
4188
        PyObject *np;
 
4189
        Py_ssize_t start, stop, step, slicelen, cur, i;
 
4190
 
 
4191
        if (PySlice_GetIndicesEx((PySliceObject *)item,
 
4192
                                 self->b_length, &start, &stop,
 
4193
                                 &step, &slicelen) < 0) {
 
4194
            return NULL;
 
4195
        }
 
4196
 
 
4197
        stgdict = PyObject_stgdict((PyObject *)self);
 
4198
        assert(stgdict); /* Cannot be NULL for array object instances */
 
4199
        proto = stgdict->proto;
 
4200
        itemdict = PyType_stgdict(proto);
 
4201
        assert(itemdict); /* proto is the item type of the array, a
 
4202
                             ctypes type, so this cannot be NULL */
 
4203
 
 
4204
        if (itemdict->getfunc == _ctypes_get_fielddesc("c")->getfunc) {
 
4205
            char *ptr = (char *)self->b_ptr;
 
4206
            char *dest;
 
4207
 
 
4208
            if (slicelen <= 0)
 
4209
                return PyBytes_FromStringAndSize("", 0);
 
4210
            if (step == 1) {
 
4211
                return PyBytes_FromStringAndSize(ptr + start,
 
4212
                                                 slicelen);
 
4213
            }
 
4214
            dest = (char *)PyMem_Malloc(slicelen);
 
4215
 
 
4216
            if (dest == NULL)
 
4217
                return PyErr_NoMemory();
 
4218
 
 
4219
            for (cur = start, i = 0; i < slicelen;
 
4220
                 cur += step, i++) {
 
4221
                dest[i] = ptr[cur];
 
4222
            }
 
4223
 
 
4224
            np = PyBytes_FromStringAndSize(dest, slicelen);
 
4225
            PyMem_Free(dest);
 
4226
            return np;
 
4227
        }
4228
4228
#ifdef CTYPES_UNICODE
4229
 
                if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) {
4230
 
                        wchar_t *ptr = (wchar_t *)self->b_ptr;
4231
 
                        wchar_t *dest;
4232
 
                        
4233
 
                        if (slicelen <= 0)
4234
 
                                return PyUnicode_FromUnicode(NULL, 0);
4235
 
                        if (step == 1) {
4236
 
                                return PyUnicode_FromWideChar(ptr + start,
4237
 
                                                              slicelen);
4238
 
                        }
4239
 
 
4240
 
                        dest = (wchar_t *)PyMem_Malloc(
4241
 
                                                slicelen * sizeof(wchar_t));
4242
 
                        
4243
 
                        for (cur = start, i = 0; i < slicelen;
4244
 
                             cur += step, i++) {
4245
 
                                dest[i] = ptr[cur];
4246
 
                        }
4247
 
                        
4248
 
                        np = PyUnicode_FromWideChar(dest, slicelen);
4249
 
                        PyMem_Free(dest);
4250
 
                        return np;
4251
 
                }
 
4229
        if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) {
 
4230
            wchar_t *ptr = (wchar_t *)self->b_ptr;
 
4231
            wchar_t *dest;
 
4232
 
 
4233
            if (slicelen <= 0)
 
4234
                return PyUnicode_FromUnicode(NULL, 0);
 
4235
            if (step == 1) {
 
4236
                return PyUnicode_FromWideChar(ptr + start,
 
4237
                                              slicelen);
 
4238
            }
 
4239
 
 
4240
            dest = (wchar_t *)PyMem_Malloc(
 
4241
                                    slicelen * sizeof(wchar_t));
 
4242
 
 
4243
            for (cur = start, i = 0; i < slicelen;
 
4244
                 cur += step, i++) {
 
4245
                dest[i] = ptr[cur];
 
4246
            }
 
4247
 
 
4248
            np = PyUnicode_FromWideChar(dest, slicelen);
 
4249
            PyMem_Free(dest);
 
4250
            return np;
 
4251
        }
4252
4252
#endif
4253
4253
 
4254
 
                np = PyList_New(slicelen);
4255
 
                if (np == NULL)
4256
 
                        return NULL;
 
4254
        np = PyList_New(slicelen);
 
4255
        if (np == NULL)
 
4256
            return NULL;
4257
4257
 
4258
 
                for (cur = start, i = 0; i < slicelen;
4259
 
                     cur += step, i++) {
4260
 
                        PyObject *v = Array_item(_self, cur);
4261
 
                        PyList_SET_ITEM(np, i, v);
4262
 
                }
4263
 
                return np;
4264
 
        }
4265
 
        else {
4266
 
                PyErr_SetString(PyExc_TypeError, 
4267
 
                                "indices must be integers");
4268
 
                return NULL;
4269
 
        }
 
4258
        for (cur = start, i = 0; i < slicelen;
 
4259
             cur += step, i++) {
 
4260
            PyObject *v = Array_item(_self, cur);
 
4261
            PyList_SET_ITEM(np, i, v);
 
4262
        }
 
4263
        return np;
 
4264
    }
 
4265
    else {
 
4266
        PyErr_SetString(PyExc_TypeError,
 
4267
                        "indices must be integers");
 
4268
        return NULL;
 
4269
    }
4270
4270
 
4271
4271
}
4272
4272
 
4273
4273
static int
4274
4274
Array_ass_item(PyObject *_self, Py_ssize_t index, PyObject *value)
4275
4275
{
4276
 
        CDataObject *self = (CDataObject *)_self;
4277
 
        Py_ssize_t size, offset;
4278
 
        StgDictObject *stgdict;
4279
 
        char *ptr;
4280
 
 
4281
 
        if (value == NULL) {
4282
 
                PyErr_SetString(PyExc_TypeError,
4283
 
                                "Array does not support item deletion");
4284
 
                return -1;
4285
 
        }
4286
 
        
4287
 
        stgdict = PyObject_stgdict((PyObject *)self);
4288
 
        assert(stgdict); /* Cannot be NULL for array object instances */
4289
 
        if (index < 0 || index >= stgdict->length) {
4290
 
                PyErr_SetString(PyExc_IndexError,
4291
 
                                "invalid index");
4292
 
                return -1;
4293
 
        }
4294
 
        size = stgdict->size / stgdict->length;
4295
 
        offset = index * size;
4296
 
        ptr = self->b_ptr + offset;
4297
 
 
4298
 
        return PyCData_set((PyObject *)self, stgdict->proto, stgdict->setfunc, value,
4299
 
                         index, size, ptr);
 
4276
    CDataObject *self = (CDataObject *)_self;
 
4277
    Py_ssize_t size, offset;
 
4278
    StgDictObject *stgdict;
 
4279
    char *ptr;
 
4280
 
 
4281
    if (value == NULL) {
 
4282
        PyErr_SetString(PyExc_TypeError,
 
4283
                        "Array does not support item deletion");
 
4284
        return -1;
 
4285
    }
 
4286
 
 
4287
    stgdict = PyObject_stgdict((PyObject *)self);
 
4288
    assert(stgdict); /* Cannot be NULL for array object instances */
 
4289
    if (index < 0 || index >= stgdict->length) {
 
4290
        PyErr_SetString(PyExc_IndexError,
 
4291
                        "invalid index");
 
4292
        return -1;
 
4293
    }
 
4294
    size = stgdict->size / stgdict->length;
 
4295
    offset = index * size;
 
4296
    ptr = self->b_ptr + offset;
 
4297
 
 
4298
    return PyCData_set((PyObject *)self, stgdict->proto, stgdict->setfunc, value,
 
4299
                     index, size, ptr);
4300
4300
}
4301
4301
 
4302
4302
static int
4303
4303
Array_ass_subscript(PyObject *_self, PyObject *item, PyObject *value)
4304
4304
{
4305
 
        CDataObject *self = (CDataObject *)_self;
4306
 
        
4307
 
        if (value == NULL) {
4308
 
                PyErr_SetString(PyExc_TypeError,
4309
 
                                "Array does not support item deletion");
4310
 
                return -1;
4311
 
        }
4312
 
 
4313
 
        if (PyIndex_Check(item)) {
4314
 
                Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
4315
 
                
4316
 
                if (i == -1 && PyErr_Occurred())
4317
 
                        return -1;
4318
 
                if (i < 0)
4319
 
                        i += self->b_length;
4320
 
                return Array_ass_item(_self, i, value);
4321
 
        }
4322
 
        else if (PySlice_Check(item)) {
4323
 
                Py_ssize_t start, stop, step, slicelen, otherlen, i, cur;
4324
 
                
4325
 
                if (PySlice_GetIndicesEx((PySliceObject *)item,
4326
 
                                         self->b_length, &start, &stop,
4327
 
                                         &step, &slicelen) < 0) {
4328
 
                        return -1;
4329
 
                }
4330
 
                if ((step < 0 && start < stop) ||
4331
 
                    (step > 0 && start > stop))
4332
 
                        stop = start;
4333
 
 
4334
 
                otherlen = PySequence_Length(value);
4335
 
                if (otherlen != slicelen) {
4336
 
                        PyErr_SetString(PyExc_ValueError,
4337
 
                                "Can only assign sequence of same size");
4338
 
                        return -1;
4339
 
                }
4340
 
                for (cur = start, i = 0; i < otherlen; cur += step, i++) {
4341
 
                        PyObject *item = PySequence_GetItem(value, i);
4342
 
                        int result;
4343
 
                        if (item == NULL)
4344
 
                                return -1;
4345
 
                        result = Array_ass_item(_self, cur, item);
4346
 
                        Py_DECREF(item);
4347
 
                        if (result == -1)
4348
 
                                return -1;
4349
 
                }
4350
 
                return 0;
4351
 
        }
4352
 
        else {
4353
 
                PyErr_SetString(PyExc_TypeError,
4354
 
                                "indices must be integer");
4355
 
                return -1;
4356
 
        }
 
4305
    CDataObject *self = (CDataObject *)_self;
 
4306
 
 
4307
    if (value == NULL) {
 
4308
        PyErr_SetString(PyExc_TypeError,
 
4309
                        "Array does not support item deletion");
 
4310
        return -1;
 
4311
    }
 
4312
 
 
4313
    if (PyIndex_Check(item)) {
 
4314
        Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
 
4315
 
 
4316
        if (i == -1 && PyErr_Occurred())
 
4317
            return -1;
 
4318
        if (i < 0)
 
4319
            i += self->b_length;
 
4320
        return Array_ass_item(_self, i, value);
 
4321
    }
 
4322
    else if (PySlice_Check(item)) {
 
4323
        Py_ssize_t start, stop, step, slicelen, otherlen, i, cur;
 
4324
 
 
4325
        if (PySlice_GetIndicesEx((PySliceObject *)item,
 
4326
                                 self->b_length, &start, &stop,
 
4327
                                 &step, &slicelen) < 0) {
 
4328
            return -1;
 
4329
        }
 
4330
        if ((step < 0 && start < stop) ||
 
4331
            (step > 0 && start > stop))
 
4332
            stop = start;
 
4333
 
 
4334
        otherlen = PySequence_Length(value);
 
4335
        if (otherlen != slicelen) {
 
4336
            PyErr_SetString(PyExc_ValueError,
 
4337
                "Can only assign sequence of same size");
 
4338
            return -1;
 
4339
        }
 
4340
        for (cur = start, i = 0; i < otherlen; cur += step, i++) {
 
4341
            PyObject *item = PySequence_GetItem(value, i);
 
4342
            int result;
 
4343
            if (item == NULL)
 
4344
                return -1;
 
4345
            result = Array_ass_item(_self, cur, item);
 
4346
            Py_DECREF(item);
 
4347
            if (result == -1)
 
4348
                return -1;
 
4349
        }
 
4350
        return 0;
 
4351
    }
 
4352
    else {
 
4353
        PyErr_SetString(PyExc_TypeError,
 
4354
                        "indices must be integer");
 
4355
        return -1;
 
4356
    }
4357
4357
}
4358
4358
 
4359
4359
static Py_ssize_t
4360
4360
Array_length(PyObject *_self)
4361
4361
{
4362
 
        CDataObject *self = (CDataObject *)_self;
4363
 
        return self->b_length;
 
4362
    CDataObject *self = (CDataObject *)_self;
 
4363
    return self->b_length;
4364
4364
}
4365
4365
 
4366
4366
static PySequenceMethods Array_as_sequence = {
4367
 
        Array_length,                           /* sq_length; */
4368
 
        0,                                      /* sq_concat; */
4369
 
        0,                                      /* sq_repeat; */
4370
 
        Array_item,                             /* sq_item; */
4371
 
        0,                                      /* sq_slice; */
4372
 
        Array_ass_item,                         /* sq_ass_item; */
4373
 
        0,                                      /* sq_ass_slice; */
4374
 
        0,                                      /* sq_contains; */
4375
 
        
4376
 
        0,                                      /* sq_inplace_concat; */
4377
 
        0,                                      /* sq_inplace_repeat; */
 
4367
    Array_length,                               /* sq_length; */
 
4368
    0,                                          /* sq_concat; */
 
4369
    0,                                          /* sq_repeat; */
 
4370
    Array_item,                                 /* sq_item; */
 
4371
    0,                                          /* sq_slice; */
 
4372
    Array_ass_item,                             /* sq_ass_item; */
 
4373
    0,                                          /* sq_ass_slice; */
 
4374
    0,                                          /* sq_contains; */
 
4375
 
 
4376
    0,                                          /* sq_inplace_concat; */
 
4377
    0,                                          /* sq_inplace_repeat; */
4378
4378
};
4379
4379
 
4380
4380
static PyMappingMethods Array_as_mapping = {
4381
 
        Array_length,
4382
 
        Array_subscript,
4383
 
        Array_ass_subscript,
 
4381
    Array_length,
 
4382
    Array_subscript,
 
4383
    Array_ass_subscript,
4384
4384
};
4385
4385
 
4386
4386
PyTypeObject PyCArray_Type = {
4387
 
        PyVarObject_HEAD_INIT(NULL, 0)
4388
 
        "_ctypes.Array",
4389
 
        sizeof(CDataObject),                    /* tp_basicsize */
4390
 
        0,                                      /* tp_itemsize */
4391
 
        0,                                      /* tp_dealloc */
4392
 
        0,                                      /* tp_print */
4393
 
        0,                                      /* tp_getattr */
4394
 
        0,                                      /* tp_setattr */
4395
 
        0,                                      /* tp_reserved */
4396
 
        0,                                      /* tp_repr */
4397
 
        0,                                      /* tp_as_number */
4398
 
        &Array_as_sequence,                     /* tp_as_sequence */
4399
 
        &Array_as_mapping,                      /* tp_as_mapping */
4400
 
        0,                                      /* tp_hash */
4401
 
        0,                                      /* tp_call */
4402
 
        0,                                      /* tp_str */
4403
 
        0,                                      /* tp_getattro */
4404
 
        0,                                      /* tp_setattro */
4405
 
        &PyCData_as_buffer,                     /* tp_as_buffer */
4406
 
        Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4407
 
        "XXX to be provided",                   /* tp_doc */
4408
 
        (traverseproc)PyCData_traverse,         /* tp_traverse */
4409
 
        (inquiry)PyCData_clear,                 /* tp_clear */
4410
 
        0,                                      /* tp_richcompare */
4411
 
        0,                                      /* tp_weaklistoffset */
4412
 
        0,                                      /* tp_iter */
4413
 
        0,                                      /* tp_iternext */
4414
 
        0,                                      /* tp_methods */
4415
 
        0,                                      /* tp_members */
4416
 
        0,                                      /* tp_getset */
4417
 
        0,                                      /* tp_base */
4418
 
        0,                                      /* tp_dict */
4419
 
        0,                                      /* tp_descr_get */
4420
 
        0,                                      /* tp_descr_set */
4421
 
        0,                                      /* tp_dictoffset */
4422
 
        (initproc)Array_init,                   /* tp_init */
4423
 
        0,                                      /* tp_alloc */
4424
 
        GenericPyCData_new,                     /* tp_new */
4425
 
        0,                                      /* tp_free */
 
4387
    PyVarObject_HEAD_INIT(NULL, 0)
 
4388
    "_ctypes.Array",
 
4389
    sizeof(CDataObject),                        /* tp_basicsize */
 
4390
    0,                                          /* tp_itemsize */
 
4391
    0,                                          /* tp_dealloc */
 
4392
    0,                                          /* tp_print */
 
4393
    0,                                          /* tp_getattr */
 
4394
    0,                                          /* tp_setattr */
 
4395
    0,                                          /* tp_reserved */
 
4396
    0,                                          /* tp_repr */
 
4397
    0,                                          /* tp_as_number */
 
4398
    &Array_as_sequence,                         /* tp_as_sequence */
 
4399
    &Array_as_mapping,                          /* tp_as_mapping */
 
4400
    0,                                          /* tp_hash */
 
4401
    0,                                          /* tp_call */
 
4402
    0,                                          /* tp_str */
 
4403
    0,                                          /* tp_getattro */
 
4404
    0,                                          /* tp_setattro */
 
4405
    &PyCData_as_buffer,                         /* tp_as_buffer */
 
4406
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
 
4407
    "XXX to be provided",                       /* tp_doc */
 
4408
    (traverseproc)PyCData_traverse,             /* tp_traverse */
 
4409
    (inquiry)PyCData_clear,                     /* tp_clear */
 
4410
    0,                                          /* tp_richcompare */
 
4411
    0,                                          /* tp_weaklistoffset */
 
4412
    0,                                          /* tp_iter */
 
4413
    0,                                          /* tp_iternext */
 
4414
    0,                                          /* tp_methods */
 
4415
    0,                                          /* tp_members */
 
4416
    0,                                          /* tp_getset */
 
4417
    0,                                          /* tp_base */
 
4418
    0,                                          /* tp_dict */
 
4419
    0,                                          /* tp_descr_get */
 
4420
    0,                                          /* tp_descr_set */
 
4421
    0,                                          /* tp_dictoffset */
 
4422
    (initproc)Array_init,                       /* tp_init */
 
4423
    0,                                          /* tp_alloc */
 
4424
    GenericPyCData_new,                         /* tp_new */
 
4425
    0,                                          /* tp_free */
4426
4426
};
4427
4427
 
4428
4428
PyObject *
4429
4429
PyCArrayType_from_ctype(PyObject *itemtype, Py_ssize_t length)
4430
4430
{
4431
 
        static PyObject *cache;
4432
 
        PyObject *key;
4433
 
        PyObject *result;
4434
 
        char name[256];
4435
 
        PyObject *len;
4436
 
 
4437
 
        if (cache == NULL) {
4438
 
                cache = PyDict_New();
4439
 
                if (cache == NULL)
4440
 
                        return NULL;
4441
 
        }
4442
 
        len = PyLong_FromSsize_t(length);
4443
 
        if (len == NULL)
4444
 
                return NULL;
4445
 
        key = PyTuple_Pack(2, itemtype, len);
4446
 
        Py_DECREF(len);
4447
 
        if (!key)
4448
 
                return NULL;
4449
 
        result = PyDict_GetItemProxy(cache, key);
4450
 
        if (result) {
4451
 
                Py_INCREF(result);
4452
 
                Py_DECREF(key);
4453
 
                return result;
4454
 
        }
4455
 
 
4456
 
        if (!PyType_Check(itemtype)) {
4457
 
                PyErr_SetString(PyExc_TypeError,
4458
 
                                "Expected a type object");
4459
 
                return NULL;
4460
 
        }
 
4431
    static PyObject *cache;
 
4432
    PyObject *key;
 
4433
    PyObject *result;
 
4434
    char name[256];
 
4435
    PyObject *len;
 
4436
 
 
4437
    if (cache == NULL) {
 
4438
        cache = PyDict_New();
 
4439
        if (cache == NULL)
 
4440
            return NULL;
 
4441
    }
 
4442
    len = PyLong_FromSsize_t(length);
 
4443
    if (len == NULL)
 
4444
        return NULL;
 
4445
    key = PyTuple_Pack(2, itemtype, len);
 
4446
    Py_DECREF(len);
 
4447
    if (!key)
 
4448
        return NULL;
 
4449
    result = PyDict_GetItemProxy(cache, key);
 
4450
    if (result) {
 
4451
        Py_INCREF(result);
 
4452
        Py_DECREF(key);
 
4453
        return result;
 
4454
    }
 
4455
 
 
4456
    if (!PyType_Check(itemtype)) {
 
4457
        PyErr_SetString(PyExc_TypeError,
 
4458
                        "Expected a type object");
 
4459
        return NULL;
 
4460
    }
4461
4461
#ifdef MS_WIN64
4462
 
        sprintf(name, "%.200s_Array_%Id",
4463
 
                ((PyTypeObject *)itemtype)->tp_name, length);
 
4462
    sprintf(name, "%.200s_Array_%Id",
 
4463
        ((PyTypeObject *)itemtype)->tp_name, length);
4464
4464
#else
4465
 
        sprintf(name, "%.200s_Array_%ld",
4466
 
                ((PyTypeObject *)itemtype)->tp_name, (long)length);
 
4465
    sprintf(name, "%.200s_Array_%ld",
 
4466
        ((PyTypeObject *)itemtype)->tp_name, (long)length);
4467
4467
#endif
4468
4468
 
4469
 
        result = PyObject_CallFunction((PyObject *)&PyCArrayType_Type,
4470
 
                                       "U(O){s:n,s:O}",
4471
 
                                       name,
4472
 
                                       &PyCArray_Type,
4473
 
                                       "_length_",
4474
 
                                       length,
4475
 
                                       "_type_",
4476
 
                                       itemtype
4477
 
                );
4478
 
        if (result == NULL) {
4479
 
                Py_DECREF(key);
4480
 
                return NULL;
4481
 
        }
4482
 
        if (-1 == PyDict_SetItemProxy(cache, key, result)) {
4483
 
                Py_DECREF(key);
4484
 
                Py_DECREF(result);
4485
 
                return NULL;
4486
 
        }
4487
 
        Py_DECREF(key);
4488
 
        return result;
 
4469
    result = PyObject_CallFunction((PyObject *)&PyCArrayType_Type,
 
4470
                                   "U(O){s:n,s:O}",
 
4471
                                   name,
 
4472
                                   &PyCArray_Type,
 
4473
                                   "_length_",
 
4474
                                   length,
 
4475
                                   "_type_",
 
4476
                                   itemtype
 
4477
        );
 
4478
    if (result == NULL) {
 
4479
        Py_DECREF(key);
 
4480
        return NULL;
 
4481
    }
 
4482
    if (-1 == PyDict_SetItemProxy(cache, key, result)) {
 
4483
        Py_DECREF(key);
 
4484
        Py_DECREF(result);
 
4485
        return NULL;
 
4486
    }
 
4487
    Py_DECREF(key);
 
4488
    return result;
4489
4489
}
4490
4490
 
4491
 
 
 
4491
 
4492
4492
/******************************************************************/
4493
4493
/*
4494
4494
  Simple_Type
4497
4497
static int
4498
4498
Simple_set_value(CDataObject *self, PyObject *value)
4499
4499
{
4500
 
        PyObject *result;
4501
 
        StgDictObject *dict = PyObject_stgdict((PyObject *)self);
4502
 
 
4503
 
        if (value == NULL) {
4504
 
                PyErr_SetString(PyExc_TypeError,
4505
 
                                "can't delete attribute");
4506
 
                return -1;
4507
 
        }
4508
 
        assert(dict); /* Cannot be NULL for CDataObject instances */
4509
 
        assert(dict->setfunc);
4510
 
        result = dict->setfunc(self->b_ptr, value, dict->size);
4511
 
        if (!result)
4512
 
                return -1;
4513
 
 
4514
 
        /* consumes the refcount the setfunc returns */
4515
 
        return KeepRef(self, 0, result);
 
4500
    PyObject *result;
 
4501
    StgDictObject *dict = PyObject_stgdict((PyObject *)self);
 
4502
 
 
4503
    if (value == NULL) {
 
4504
        PyErr_SetString(PyExc_TypeError,
 
4505
                        "can't delete attribute");
 
4506
        return -1;
 
4507
    }
 
4508
    assert(dict); /* Cannot be NULL for CDataObject instances */
 
4509
    assert(dict->setfunc);
 
4510
    result = dict->setfunc(self->b_ptr, value, dict->size);
 
4511
    if (!result)
 
4512
        return -1;
 
4513
 
 
4514
    /* consumes the refcount the setfunc returns */
 
4515
    return KeepRef(self, 0, result);
4516
4516
}
4517
4517
 
4518
4518
static int
4519
4519
Simple_init(CDataObject *self, PyObject *args, PyObject *kw)
4520
4520
{
4521
 
        PyObject *value = NULL;
4522
 
        if (!PyArg_UnpackTuple(args, "__init__", 0, 1, &value))
4523
 
                return -1;
4524
 
        if (value)
4525
 
                return Simple_set_value(self, value);
4526
 
        return 0;
 
4521
    PyObject *value = NULL;
 
4522
    if (!PyArg_UnpackTuple(args, "__init__", 0, 1, &value))
 
4523
        return -1;
 
4524
    if (value)
 
4525
        return Simple_set_value(self, value);
 
4526
    return 0;
4527
4527
}
4528
4528
 
4529
4529
static PyObject *
4530
4530
Simple_get_value(CDataObject *self)
4531
4531
{
4532
 
        StgDictObject *dict;
4533
 
        dict = PyObject_stgdict((PyObject *)self);
4534
 
        assert(dict); /* Cannot be NULL for CDataObject instances */
4535
 
        assert(dict->getfunc);
4536
 
        return dict->getfunc(self->b_ptr, self->b_size);
 
4532
    StgDictObject *dict;
 
4533
    dict = PyObject_stgdict((PyObject *)self);
 
4534
    assert(dict); /* Cannot be NULL for CDataObject instances */
 
4535
    assert(dict->getfunc);
 
4536
    return dict->getfunc(self->b_ptr, self->b_size);
4537
4537
}
4538
4538
 
4539
4539
static PyGetSetDef Simple_getsets[] = {
4540
 
        { "value", (getter)Simple_get_value, (setter)Simple_set_value,
4541
 
          "current value", NULL },
4542
 
        { NULL, NULL }
 
4540
    { "value", (getter)Simple_get_value, (setter)Simple_set_value,
 
4541
      "current value", NULL },
 
4542
    { NULL, NULL }
4543
4543
};
4544
4544
 
4545
4545
static PyObject *
4546
4546
Simple_from_outparm(PyObject *self, PyObject *args)
4547
4547
{
4548
 
        if (_ctypes_simple_instance((PyObject *)Py_TYPE(self))) {
4549
 
                Py_INCREF(self);
4550
 
                return self;
4551
 
        }
4552
 
        /* call stgdict->getfunc */
4553
 
        return Simple_get_value((CDataObject *)self);
 
4548
    if (_ctypes_simple_instance((PyObject *)Py_TYPE(self))) {
 
4549
        Py_INCREF(self);
 
4550
        return self;
 
4551
    }
 
4552
    /* call stgdict->getfunc */
 
4553
    return Simple_get_value((CDataObject *)self);
4554
4554
}
4555
4555
 
4556
4556
static PyMethodDef Simple_methods[] = {
4557
 
        { "__ctypes_from_outparam__", Simple_from_outparm, METH_NOARGS, },
4558
 
        { NULL, NULL },
 
4557
    { "__ctypes_from_outparam__", Simple_from_outparm, METH_NOARGS, },
 
4558
    { NULL, NULL },
4559
4559
};
4560
4560
 
4561
4561
static int Simple_bool(CDataObject *self)
4562
4562
{
4563
 
        return memcmp(self->b_ptr, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", self->b_size);
 
4563
    return memcmp(self->b_ptr, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", self->b_size);
4564
4564
}
4565
4565
 
4566
4566
static PyNumberMethods Simple_as_number = {
4567
 
        0, /* nb_add */
4568
 
        0, /* nb_subtract */
4569
 
        0, /* nb_multiply */
4570
 
        0, /* nb_remainder */
4571
 
        0, /* nb_divmod */
4572
 
        0, /* nb_power */
4573
 
        0, /* nb_negative */
4574
 
        0, /* nb_positive */
4575
 
        0, /* nb_absolute */
4576
 
        (inquiry)Simple_bool, /* nb_bool */
 
4567
    0, /* nb_add */
 
4568
    0, /* nb_subtract */
 
4569
    0, /* nb_multiply */
 
4570
    0, /* nb_remainder */
 
4571
    0, /* nb_divmod */
 
4572
    0, /* nb_power */
 
4573
    0, /* nb_negative */
 
4574
    0, /* nb_positive */
 
4575
    0, /* nb_absolute */
 
4576
    (inquiry)Simple_bool, /* nb_bool */
4577
4577
};
4578
4578
 
4579
4579
/* "%s(%s)" % (self.__class__.__name__, self.value) */
4580
4580
static PyObject *
4581
4581
Simple_repr(CDataObject *self)
4582
4582
{
4583
 
        PyObject *val, *name, *args, *result;
4584
 
        static PyObject *format;
4585
 
 
4586
 
        if (Py_TYPE(self)->tp_base != &Simple_Type) {
4587
 
                return PyUnicode_FromFormat("<%s object at %p>",
4588
 
                                           Py_TYPE(self)->tp_name, self);
4589
 
        }
4590
 
 
4591
 
        if (format == NULL) {
4592
 
                format = PyUnicode_InternFromString("%s(%r)");
4593
 
                if (format == NULL)
4594
 
                        return NULL;
4595
 
        }
4596
 
 
4597
 
        val = Simple_get_value(self);
4598
 
        if (val == NULL)
4599
 
                return NULL;
4600
 
 
4601
 
        name = PyUnicode_FromString(Py_TYPE(self)->tp_name);
4602
 
        if (name == NULL) {
4603
 
                Py_DECREF(val);
4604
 
                return NULL;
4605
 
        }
4606
 
 
4607
 
        args = PyTuple_Pack(2, name, val);
4608
 
        Py_DECREF(name);
4609
 
        Py_DECREF(val);
4610
 
        if (args == NULL)
4611
 
                return NULL;
4612
 
 
4613
 
        result = PyUnicode_Format(format, args);
4614
 
        Py_DECREF(args);
4615
 
        return result;
 
4583
    PyObject *val, *name, *args, *result;
 
4584
    static PyObject *format;
 
4585
 
 
4586
    if (Py_TYPE(self)->tp_base != &Simple_Type) {
 
4587
        return PyUnicode_FromFormat("<%s object at %p>",
 
4588
                                   Py_TYPE(self)->tp_name, self);
 
4589
    }
 
4590
 
 
4591
    if (format == NULL) {
 
4592
        format = PyUnicode_InternFromString("%s(%r)");
 
4593
        if (format == NULL)
 
4594
            return NULL;
 
4595
    }
 
4596
 
 
4597
    val = Simple_get_value(self);
 
4598
    if (val == NULL)
 
4599
        return NULL;
 
4600
 
 
4601
    name = PyUnicode_FromString(Py_TYPE(self)->tp_name);
 
4602
    if (name == NULL) {
 
4603
        Py_DECREF(val);
 
4604
        return NULL;
 
4605
    }
 
4606
 
 
4607
    args = PyTuple_Pack(2, name, val);
 
4608
    Py_DECREF(name);
 
4609
    Py_DECREF(val);
 
4610
    if (args == NULL)
 
4611
        return NULL;
 
4612
 
 
4613
    result = PyUnicode_Format(format, args);
 
4614
    Py_DECREF(args);
 
4615
    return result;
4616
4616
}
4617
4617
 
4618
4618
static PyTypeObject Simple_Type = {
4619
 
        PyVarObject_HEAD_INIT(NULL, 0)
4620
 
        "_ctypes._SimpleCData",
4621
 
        sizeof(CDataObject),                    /* tp_basicsize */
4622
 
        0,                                      /* tp_itemsize */
4623
 
        0,                                      /* tp_dealloc */
4624
 
        0,                                      /* tp_print */
4625
 
        0,                                      /* tp_getattr */
4626
 
        0,                                      /* tp_setattr */
4627
 
        0,                                      /* tp_reserved */
4628
 
        (reprfunc)&Simple_repr,                 /* tp_repr */
4629
 
        &Simple_as_number,                      /* tp_as_number */
4630
 
        0,                                      /* tp_as_sequence */
4631
 
        0,                                      /* tp_as_mapping */
4632
 
        0,                                      /* tp_hash */
4633
 
        0,                                      /* tp_call */
4634
 
        0,                                      /* tp_str */
4635
 
        0,                                      /* tp_getattro */
4636
 
        0,                                      /* tp_setattro */
4637
 
        &PyCData_as_buffer,                     /* tp_as_buffer */
4638
 
        Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4639
 
        "XXX to be provided",                   /* tp_doc */
4640
 
        (traverseproc)PyCData_traverse,         /* tp_traverse */
4641
 
        (inquiry)PyCData_clear,                 /* tp_clear */
4642
 
        0,                                      /* tp_richcompare */
4643
 
        0,                                      /* tp_weaklistoffset */
4644
 
        0,                                      /* tp_iter */
4645
 
        0,                                      /* tp_iternext */
4646
 
        Simple_methods,                         /* tp_methods */
4647
 
        0,                                      /* tp_members */
4648
 
        Simple_getsets,                         /* tp_getset */
4649
 
        0,                                      /* tp_base */
4650
 
        0,                                      /* tp_dict */
4651
 
        0,                                      /* tp_descr_get */
4652
 
        0,                                      /* tp_descr_set */
4653
 
        0,                                      /* tp_dictoffset */
4654
 
        (initproc)Simple_init,                  /* tp_init */
4655
 
        0,                                      /* tp_alloc */
4656
 
        GenericPyCData_new,                     /* tp_new */
4657
 
        0,                                      /* tp_free */
 
4619
    PyVarObject_HEAD_INIT(NULL, 0)
 
4620
    "_ctypes._SimpleCData",
 
4621
    sizeof(CDataObject),                        /* tp_basicsize */
 
4622
    0,                                          /* tp_itemsize */
 
4623
    0,                                          /* tp_dealloc */
 
4624
    0,                                          /* tp_print */
 
4625
    0,                                          /* tp_getattr */
 
4626
    0,                                          /* tp_setattr */
 
4627
    0,                                          /* tp_reserved */
 
4628
    (reprfunc)&Simple_repr,                     /* tp_repr */
 
4629
    &Simple_as_number,                          /* tp_as_number */
 
4630
    0,                                          /* tp_as_sequence */
 
4631
    0,                                          /* tp_as_mapping */
 
4632
    0,                                          /* tp_hash */
 
4633
    0,                                          /* tp_call */
 
4634
    0,                                          /* tp_str */
 
4635
    0,                                          /* tp_getattro */
 
4636
    0,                                          /* tp_setattro */
 
4637
    &PyCData_as_buffer,                         /* tp_as_buffer */
 
4638
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
 
4639
    "XXX to be provided",                       /* tp_doc */
 
4640
    (traverseproc)PyCData_traverse,             /* tp_traverse */
 
4641
    (inquiry)PyCData_clear,                     /* tp_clear */
 
4642
    0,                                          /* tp_richcompare */
 
4643
    0,                                          /* tp_weaklistoffset */
 
4644
    0,                                          /* tp_iter */
 
4645
    0,                                          /* tp_iternext */
 
4646
    Simple_methods,                             /* tp_methods */
 
4647
    0,                                          /* tp_members */
 
4648
    Simple_getsets,                             /* tp_getset */
 
4649
    0,                                          /* tp_base */
 
4650
    0,                                          /* tp_dict */
 
4651
    0,                                          /* tp_descr_get */
 
4652
    0,                                          /* tp_descr_set */
 
4653
    0,                                          /* tp_dictoffset */
 
4654
    (initproc)Simple_init,                      /* tp_init */
 
4655
    0,                                          /* tp_alloc */
 
4656
    GenericPyCData_new,                         /* tp_new */
 
4657
    0,                                          /* tp_free */
4658
4658
};
4659
 
 
 
4659
 
4660
4660
/******************************************************************/
4661
4661
/*
4662
4662
  PyCPointer_Type
4664
4664
static PyObject *
4665
4665
Pointer_item(PyObject *_self, Py_ssize_t index)
4666
4666
{
4667
 
        CDataObject *self = (CDataObject *)_self;
4668
 
        Py_ssize_t size;
4669
 
        Py_ssize_t offset;
4670
 
        StgDictObject *stgdict, *itemdict;
4671
 
        PyObject *proto;
4672
 
 
4673
 
        if (*(void **)self->b_ptr == NULL) {
4674
 
                PyErr_SetString(PyExc_ValueError,
4675
 
                                "NULL pointer access");
4676
 
                return NULL;
4677
 
        }
4678
 
 
4679
 
        stgdict = PyObject_stgdict((PyObject *)self);
4680
 
        assert(stgdict); /* Cannot be NULL for pointer object instances */
4681
 
        
4682
 
        proto = stgdict->proto;
4683
 
        assert(proto);
4684
 
        itemdict = PyType_stgdict(proto);
4685
 
        assert(itemdict); /* proto is the item type of the pointer, a ctypes
4686
 
                             type, so this cannot be NULL */
4687
 
 
4688
 
        size = itemdict->size;
4689
 
        offset = index * itemdict->size;
4690
 
 
4691
 
        return PyCData_get(proto, stgdict->getfunc, (PyObject *)self,
4692
 
                         index, size, (*(char **)self->b_ptr) + offset);
 
4667
    CDataObject *self = (CDataObject *)_self;
 
4668
    Py_ssize_t size;
 
4669
    Py_ssize_t offset;
 
4670
    StgDictObject *stgdict, *itemdict;
 
4671
    PyObject *proto;
 
4672
 
 
4673
    if (*(void **)self->b_ptr == NULL) {
 
4674
        PyErr_SetString(PyExc_ValueError,
 
4675
                        "NULL pointer access");
 
4676
        return NULL;
 
4677
    }
 
4678
 
 
4679
    stgdict = PyObject_stgdict((PyObject *)self);
 
4680
    assert(stgdict); /* Cannot be NULL for pointer object instances */
 
4681
 
 
4682
    proto = stgdict->proto;
 
4683
    assert(proto);
 
4684
    itemdict = PyType_stgdict(proto);
 
4685
    assert(itemdict); /* proto is the item type of the pointer, a ctypes
 
4686
                         type, so this cannot be NULL */
 
4687
 
 
4688
    size = itemdict->size;
 
4689
    offset = index * itemdict->size;
 
4690
 
 
4691
    return PyCData_get(proto, stgdict->getfunc, (PyObject *)self,
 
4692
                     index, size, (*(char **)self->b_ptr) + offset);
4693
4693
}
4694
4694
 
4695
4695
static int
4696
4696
Pointer_ass_item(PyObject *_self, Py_ssize_t index, PyObject *value)
4697
4697
{
4698
 
        CDataObject *self = (CDataObject *)_self;
4699
 
        Py_ssize_t size;
4700
 
        Py_ssize_t offset;
4701
 
        StgDictObject *stgdict, *itemdict;
4702
 
        PyObject *proto;
4703
 
 
4704
 
        if (value == NULL) {
4705
 
                PyErr_SetString(PyExc_TypeError,
4706
 
                                "Pointer does not support item deletion");
4707
 
                return -1;
4708
 
        }
4709
 
 
4710
 
        if (*(void **)self->b_ptr == NULL) {
4711
 
                PyErr_SetString(PyExc_ValueError,
4712
 
                                "NULL pointer access");
4713
 
                return -1;
4714
 
        }
4715
 
        
4716
 
        stgdict = PyObject_stgdict((PyObject *)self);
4717
 
        assert(stgdict); /* Cannot be NULL fr pointer instances */
4718
 
 
4719
 
        proto = stgdict->proto;
4720
 
        assert(proto);
4721
 
 
4722
 
        itemdict = PyType_stgdict(proto);
4723
 
        assert(itemdict); /* Cannot be NULL because the itemtype of a pointer
4724
 
                             is always a ctypes type */
4725
 
 
4726
 
        size = itemdict->size;
4727
 
        offset = index * itemdict->size;
4728
 
 
4729
 
        return PyCData_set((PyObject *)self, proto, stgdict->setfunc, value,
4730
 
                         index, size, (*(char **)self->b_ptr) + offset);
 
4698
    CDataObject *self = (CDataObject *)_self;
 
4699
    Py_ssize_t size;
 
4700
    Py_ssize_t offset;
 
4701
    StgDictObject *stgdict, *itemdict;
 
4702
    PyObject *proto;
 
4703
 
 
4704
    if (value == NULL) {
 
4705
        PyErr_SetString(PyExc_TypeError,
 
4706
                        "Pointer does not support item deletion");
 
4707
        return -1;
 
4708
    }
 
4709
 
 
4710
    if (*(void **)self->b_ptr == NULL) {
 
4711
        PyErr_SetString(PyExc_ValueError,
 
4712
                        "NULL pointer access");
 
4713
        return -1;
 
4714
    }
 
4715
 
 
4716
    stgdict = PyObject_stgdict((PyObject *)self);
 
4717
    assert(stgdict); /* Cannot be NULL fr pointer instances */
 
4718
 
 
4719
    proto = stgdict->proto;
 
4720
    assert(proto);
 
4721
 
 
4722
    itemdict = PyType_stgdict(proto);
 
4723
    assert(itemdict); /* Cannot be NULL because the itemtype of a pointer
 
4724
                         is always a ctypes type */
 
4725
 
 
4726
    size = itemdict->size;
 
4727
    offset = index * itemdict->size;
 
4728
 
 
4729
    return PyCData_set((PyObject *)self, proto, stgdict->setfunc, value,
 
4730
                     index, size, (*(char **)self->b_ptr) + offset);
4731
4731
}
4732
4732
 
4733
4733
static PyObject *
4734
4734
Pointer_get_contents(CDataObject *self, void *closure)
4735
4735
{
4736
 
        StgDictObject *stgdict;
4737
 
 
4738
 
        if (*(void **)self->b_ptr == NULL) {
4739
 
                PyErr_SetString(PyExc_ValueError,
4740
 
                                "NULL pointer access");
4741
 
                return NULL;
4742
 
        }
4743
 
 
4744
 
        stgdict = PyObject_stgdict((PyObject *)self);
4745
 
        assert(stgdict); /* Cannot be NULL fr pointer instances */
4746
 
        return PyCData_FromBaseObj(stgdict->proto,
4747
 
                                 (PyObject *)self, 0,
4748
 
                                 *(void **)self->b_ptr);
 
4736
    StgDictObject *stgdict;
 
4737
 
 
4738
    if (*(void **)self->b_ptr == NULL) {
 
4739
        PyErr_SetString(PyExc_ValueError,
 
4740
                        "NULL pointer access");
 
4741
        return NULL;
 
4742
    }
 
4743
 
 
4744
    stgdict = PyObject_stgdict((PyObject *)self);
 
4745
    assert(stgdict); /* Cannot be NULL fr pointer instances */
 
4746
    return PyCData_FromBaseObj(stgdict->proto,
 
4747
                             (PyObject *)self, 0,
 
4748
                             *(void **)self->b_ptr);
4749
4749
}
4750
4750
 
4751
4751
static int
4752
4752
Pointer_set_contents(CDataObject *self, PyObject *value, void *closure)
4753
4753
{
4754
 
        StgDictObject *stgdict;
4755
 
        CDataObject *dst;
4756
 
        PyObject *keep;
4757
 
 
4758
 
        if (value == NULL) {
4759
 
                PyErr_SetString(PyExc_TypeError,
4760
 
                                "Pointer does not support item deletion");
4761
 
                return -1;
4762
 
        }
4763
 
        stgdict = PyObject_stgdict((PyObject *)self);
4764
 
        assert(stgdict); /* Cannot be NULL fr pointer instances */
4765
 
        assert(stgdict->proto);
4766
 
        if (!CDataObject_Check(value) 
4767
 
            || 0 == PyObject_IsInstance(value, stgdict->proto)) {
4768
 
                /* XXX PyObject_IsInstance could return -1! */
4769
 
                PyErr_Format(PyExc_TypeError,
4770
 
                             "expected %s instead of %s",
4771
 
                             ((PyTypeObject *)(stgdict->proto))->tp_name,
4772
 
                             Py_TYPE(value)->tp_name);
4773
 
                return -1;
4774
 
        }
4775
 
 
4776
 
        dst = (CDataObject *)value;
4777
 
        *(void **)self->b_ptr = dst->b_ptr;
4778
 
 
4779
 
        /* 
4780
 
           A Pointer instance must keep a the value it points to alive.  So, a
4781
 
           pointer instance has b_length set to 2 instead of 1, and we set
4782
 
           'value' itself as the second item of the b_objects list, additionally.
4783
 
        */
4784
 
        Py_INCREF(value);
4785
 
        if (-1 == KeepRef(self, 1, value))
4786
 
                return -1;
4787
 
 
4788
 
        keep = GetKeepedObjects(dst);
4789
 
        Py_INCREF(keep);
4790
 
        return KeepRef(self, 0, keep);
 
4754
    StgDictObject *stgdict;
 
4755
    CDataObject *dst;
 
4756
    PyObject *keep;
 
4757
 
 
4758
    if (value == NULL) {
 
4759
        PyErr_SetString(PyExc_TypeError,
 
4760
                        "Pointer does not support item deletion");
 
4761
        return -1;
 
4762
    }
 
4763
    stgdict = PyObject_stgdict((PyObject *)self);
 
4764
    assert(stgdict); /* Cannot be NULL fr pointer instances */
 
4765
    assert(stgdict->proto);
 
4766
    if (!CDataObject_Check(value)
 
4767
        || 0 == PyObject_IsInstance(value, stgdict->proto)) {
 
4768
        /* XXX PyObject_IsInstance could return -1! */
 
4769
        PyErr_Format(PyExc_TypeError,
 
4770
                     "expected %s instead of %s",
 
4771
                     ((PyTypeObject *)(stgdict->proto))->tp_name,
 
4772
                     Py_TYPE(value)->tp_name);
 
4773
        return -1;
 
4774
    }
 
4775
 
 
4776
    dst = (CDataObject *)value;
 
4777
    *(void **)self->b_ptr = dst->b_ptr;
 
4778
 
 
4779
    /*
 
4780
       A Pointer instance must keep a the value it points to alive.  So, a
 
4781
       pointer instance has b_length set to 2 instead of 1, and we set
 
4782
       'value' itself as the second item of the b_objects list, additionally.
 
4783
    */
 
4784
    Py_INCREF(value);
 
4785
    if (-1 == KeepRef(self, 1, value))
 
4786
        return -1;
 
4787
 
 
4788
    keep = GetKeepedObjects(dst);
 
4789
    Py_INCREF(keep);
 
4790
    return KeepRef(self, 0, keep);
4791
4791
}
4792
4792
 
4793
4793
static PyGetSetDef Pointer_getsets[] = {
4794
 
        { "contents", (getter)Pointer_get_contents,
4795
 
          (setter)Pointer_set_contents,
4796
 
          "the object this pointer points to (read-write)", NULL },
4797
 
        { NULL, NULL }
 
4794
    { "contents", (getter)Pointer_get_contents,
 
4795
      (setter)Pointer_set_contents,
 
4796
      "the object this pointer points to (read-write)", NULL },
 
4797
    { NULL, NULL }
4798
4798
};
4799
4799
 
4800
4800
static int
4801
4801
Pointer_init(CDataObject *self, PyObject *args, PyObject *kw)
4802
4802
{
4803
 
        PyObject *value = NULL;
 
4803
    PyObject *value = NULL;
4804
4804
 
4805
 
        if (!PyArg_UnpackTuple(args, "POINTER", 0, 1, &value))
4806
 
                return -1;
4807
 
        if (value == NULL)
4808
 
                return 0;
4809
 
        return Pointer_set_contents(self, value, NULL);
 
4805
    if (!PyArg_UnpackTuple(args, "POINTER", 0, 1, &value))
 
4806
        return -1;
 
4807
    if (value == NULL)
 
4808
        return 0;
 
4809
    return Pointer_set_contents(self, value, NULL);
4810
4810
}
4811
4811
 
4812
4812
static PyObject *
4813
4813
Pointer_new(PyTypeObject *type, PyObject *args, PyObject *kw)
4814
4814
{
4815
 
        StgDictObject *dict = PyType_stgdict((PyObject *)type);
4816
 
        if (!dict || !dict->proto) {
4817
 
                PyErr_SetString(PyExc_TypeError,
4818
 
                                "Cannot create instance: has no _type_");
4819
 
                return NULL;
4820
 
        }
4821
 
        return GenericPyCData_new(type, args, kw);
 
4815
    StgDictObject *dict = PyType_stgdict((PyObject *)type);
 
4816
    if (!dict || !dict->proto) {
 
4817
        PyErr_SetString(PyExc_TypeError,
 
4818
                        "Cannot create instance: has no _type_");
 
4819
        return NULL;
 
4820
    }
 
4821
    return GenericPyCData_new(type, args, kw);
4822
4822
}
4823
4823
 
4824
4824
static PyObject *
4825
4825
Pointer_subscript(PyObject *_self, PyObject *item)
4826
4826
{
4827
 
        CDataObject *self = (CDataObject *)_self;
4828
 
        if (PyIndex_Check(item)) {
4829
 
                Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
4830
 
                if (i == -1 && PyErr_Occurred())
4831
 
                        return NULL;
4832
 
                return Pointer_item(_self, i);
4833
 
        }
4834
 
        else if (PySlice_Check(item)) {
4835
 
                PySliceObject *slice = (PySliceObject *)item;
4836
 
                Py_ssize_t start, stop, step;
4837
 
                PyObject *np;
4838
 
                StgDictObject *stgdict, *itemdict;
4839
 
                PyObject *proto;
4840
 
                Py_ssize_t i, len, cur;
4841
 
 
4842
 
                /* Since pointers have no length, and we want to apply
4843
 
                   different semantics to negative indices than normal
4844
 
                   slicing, we have to dissect the slice object ourselves.*/
4845
 
                if (slice->step == Py_None) {
4846
 
                        step = 1;
4847
 
                }
4848
 
                else {
4849
 
                        step = PyNumber_AsSsize_t(slice->step,
4850
 
                                                  PyExc_ValueError);
4851
 
                        if (step == -1 && PyErr_Occurred())
4852
 
                                return NULL;
4853
 
                        if (step == 0) {
4854
 
                                PyErr_SetString(PyExc_ValueError,
4855
 
                                                "slice step cannot be zero");
4856
 
                                return NULL;
4857
 
                        }
4858
 
                }
4859
 
                if (slice->start == Py_None) {
4860
 
                        if (step < 0) {
4861
 
                                PyErr_SetString(PyExc_ValueError,
4862
 
                                                "slice start is required "
4863
 
                                                "for step < 0");
4864
 
                                return NULL;
4865
 
                        }
4866
 
                        start = 0;
4867
 
                }
4868
 
                else {
4869
 
                        start = PyNumber_AsSsize_t(slice->start,
4870
 
                                                   PyExc_ValueError);
4871
 
                        if (start == -1 && PyErr_Occurred())
4872
 
                                return NULL;
4873
 
                }
4874
 
                if (slice->stop == Py_None) {
4875
 
                        PyErr_SetString(PyExc_ValueError,
4876
 
                                        "slice stop is required");
4877
 
                        return NULL;
4878
 
                }
4879
 
                stop = PyNumber_AsSsize_t(slice->stop,
4880
 
                                          PyExc_ValueError);
4881
 
                if (stop == -1 && PyErr_Occurred())
4882
 
                        return NULL;
4883
 
                if ((step > 0 && start > stop) ||
4884
 
                    (step < 0 && start < stop))
4885
 
                        len = 0;
4886
 
                else if (step > 0)
4887
 
                        len = (stop - start - 1) / step + 1;
4888
 
                else
4889
 
                        len = (stop - start + 1) / step + 1;
4890
 
 
4891
 
                stgdict = PyObject_stgdict((PyObject *)self);
4892
 
                assert(stgdict); /* Cannot be NULL for pointer instances */
4893
 
                proto = stgdict->proto;
4894
 
                assert(proto);
4895
 
                itemdict = PyType_stgdict(proto);
4896
 
                assert(itemdict);
4897
 
                if (itemdict->getfunc == _ctypes_get_fielddesc("c")->getfunc) {
4898
 
                        char *ptr = *(char **)self->b_ptr;
4899
 
                        char *dest;
4900
 
                        
4901
 
                        if (len <= 0)
4902
 
                                return PyBytes_FromStringAndSize("", 0);
4903
 
                        if (step == 1) {
4904
 
                                return PyBytes_FromStringAndSize(ptr + start,
4905
 
                                                                 len);
4906
 
                        }
4907
 
                        dest = (char *)PyMem_Malloc(len);
4908
 
                        if (dest == NULL)
4909
 
                                return PyErr_NoMemory();
4910
 
                        for (cur = start, i = 0; i < len; cur += step, i++) {
4911
 
                                dest[i] = ptr[cur];
4912
 
                        }
4913
 
                        np = PyBytes_FromStringAndSize(dest, len);
4914
 
                        PyMem_Free(dest);
4915
 
                        return np;
4916
 
                }
 
4827
    CDataObject *self = (CDataObject *)_self;
 
4828
    if (PyIndex_Check(item)) {
 
4829
        Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
 
4830
        if (i == -1 && PyErr_Occurred())
 
4831
            return NULL;
 
4832
        return Pointer_item(_self, i);
 
4833
    }
 
4834
    else if (PySlice_Check(item)) {
 
4835
        PySliceObject *slice = (PySliceObject *)item;
 
4836
        Py_ssize_t start, stop, step;
 
4837
        PyObject *np;
 
4838
        StgDictObject *stgdict, *itemdict;
 
4839
        PyObject *proto;
 
4840
        Py_ssize_t i, len, cur;
 
4841
 
 
4842
        /* Since pointers have no length, and we want to apply
 
4843
           different semantics to negative indices than normal
 
4844
           slicing, we have to dissect the slice object ourselves.*/
 
4845
        if (slice->step == Py_None) {
 
4846
            step = 1;
 
4847
        }
 
4848
        else {
 
4849
            step = PyNumber_AsSsize_t(slice->step,
 
4850
                                      PyExc_ValueError);
 
4851
            if (step == -1 && PyErr_Occurred())
 
4852
                return NULL;
 
4853
            if (step == 0) {
 
4854
                PyErr_SetString(PyExc_ValueError,
 
4855
                                "slice step cannot be zero");
 
4856
                return NULL;
 
4857
            }
 
4858
        }
 
4859
        if (slice->start == Py_None) {
 
4860
            if (step < 0) {
 
4861
                PyErr_SetString(PyExc_ValueError,
 
4862
                                "slice start is required "
 
4863
                                "for step < 0");
 
4864
                return NULL;
 
4865
            }
 
4866
            start = 0;
 
4867
        }
 
4868
        else {
 
4869
            start = PyNumber_AsSsize_t(slice->start,
 
4870
                                       PyExc_ValueError);
 
4871
            if (start == -1 && PyErr_Occurred())
 
4872
                return NULL;
 
4873
        }
 
4874
        if (slice->stop == Py_None) {
 
4875
            PyErr_SetString(PyExc_ValueError,
 
4876
                            "slice stop is required");
 
4877
            return NULL;
 
4878
        }
 
4879
        stop = PyNumber_AsSsize_t(slice->stop,
 
4880
                                  PyExc_ValueError);
 
4881
        if (stop == -1 && PyErr_Occurred())
 
4882
            return NULL;
 
4883
        if ((step > 0 && start > stop) ||
 
4884
            (step < 0 && start < stop))
 
4885
            len = 0;
 
4886
        else if (step > 0)
 
4887
            len = (stop - start - 1) / step + 1;
 
4888
        else
 
4889
            len = (stop - start + 1) / step + 1;
 
4890
 
 
4891
        stgdict = PyObject_stgdict((PyObject *)self);
 
4892
        assert(stgdict); /* Cannot be NULL for pointer instances */
 
4893
        proto = stgdict->proto;
 
4894
        assert(proto);
 
4895
        itemdict = PyType_stgdict(proto);
 
4896
        assert(itemdict);
 
4897
        if (itemdict->getfunc == _ctypes_get_fielddesc("c")->getfunc) {
 
4898
            char *ptr = *(char **)self->b_ptr;
 
4899
            char *dest;
 
4900
 
 
4901
            if (len <= 0)
 
4902
                return PyBytes_FromStringAndSize("", 0);
 
4903
            if (step == 1) {
 
4904
                return PyBytes_FromStringAndSize(ptr + start,
 
4905
                                                 len);
 
4906
            }
 
4907
            dest = (char *)PyMem_Malloc(len);
 
4908
            if (dest == NULL)
 
4909
                return PyErr_NoMemory();
 
4910
            for (cur = start, i = 0; i < len; cur += step, i++) {
 
4911
                dest[i] = ptr[cur];
 
4912
            }
 
4913
            np = PyBytes_FromStringAndSize(dest, len);
 
4914
            PyMem_Free(dest);
 
4915
            return np;
 
4916
        }
4917
4917
#ifdef CTYPES_UNICODE
4918
 
                if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) {
4919
 
                        wchar_t *ptr = *(wchar_t **)self->b_ptr;
4920
 
                        wchar_t *dest;
4921
 
                        
4922
 
                        if (len <= 0)
4923
 
                                return PyUnicode_FromUnicode(NULL, 0);
4924
 
                        if (step == 1) {
4925
 
                                return PyUnicode_FromWideChar(ptr + start,
4926
 
                                                              len);
4927
 
                        }
4928
 
                        dest = (wchar_t *)PyMem_Malloc(len * sizeof(wchar_t));
4929
 
                        if (dest == NULL)
4930
 
                                return PyErr_NoMemory();
4931
 
                        for (cur = start, i = 0; i < len; cur += step, i++) {
4932
 
                                dest[i] = ptr[cur];
4933
 
                        }
4934
 
                        np = PyUnicode_FromWideChar(dest, len);
4935
 
                        PyMem_Free(dest);
4936
 
                        return np;
4937
 
                }
 
4918
        if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) {
 
4919
            wchar_t *ptr = *(wchar_t **)self->b_ptr;
 
4920
            wchar_t *dest;
 
4921
 
 
4922
            if (len <= 0)
 
4923
                return PyUnicode_FromUnicode(NULL, 0);
 
4924
            if (step == 1) {
 
4925
                return PyUnicode_FromWideChar(ptr + start,
 
4926
                                              len);
 
4927
            }
 
4928
            dest = (wchar_t *)PyMem_Malloc(len * sizeof(wchar_t));
 
4929
            if (dest == NULL)
 
4930
                return PyErr_NoMemory();
 
4931
            for (cur = start, i = 0; i < len; cur += step, i++) {
 
4932
                dest[i] = ptr[cur];
 
4933
            }
 
4934
            np = PyUnicode_FromWideChar(dest, len);
 
4935
            PyMem_Free(dest);
 
4936
            return np;
 
4937
        }
4938
4938
#endif
4939
4939
 
4940
 
                np = PyList_New(len);
4941
 
                if (np == NULL)
4942
 
                        return NULL;
 
4940
        np = PyList_New(len);
 
4941
        if (np == NULL)
 
4942
            return NULL;
4943
4943
 
4944
 
                for (cur = start, i = 0; i < len; cur += step, i++) {
4945
 
                        PyObject *v = Pointer_item(_self, cur);
4946
 
                        PyList_SET_ITEM(np, i, v);
4947
 
                }
4948
 
                return np;
4949
 
        }
4950
 
        else {
4951
 
                PyErr_SetString(PyExc_TypeError,
4952
 
                                "Pointer indices must be integer");
4953
 
                return NULL;
4954
 
        }
 
4944
        for (cur = start, i = 0; i < len; cur += step, i++) {
 
4945
            PyObject *v = Pointer_item(_self, cur);
 
4946
            PyList_SET_ITEM(np, i, v);
 
4947
        }
 
4948
        return np;
 
4949
    }
 
4950
    else {
 
4951
        PyErr_SetString(PyExc_TypeError,
 
4952
                        "Pointer indices must be integer");
 
4953
        return NULL;
 
4954
    }
4955
4955
}
4956
4956
 
4957
4957
static PySequenceMethods Pointer_as_sequence = {
4958
 
        0,                                      /* inquiry sq_length; */
4959
 
        0,                                      /* binaryfunc sq_concat; */
4960
 
        0,                                      /* intargfunc sq_repeat; */
4961
 
        Pointer_item,                           /* intargfunc sq_item; */
4962
 
        0,                                      /* intintargfunc sq_slice; */
4963
 
        Pointer_ass_item,                       /* intobjargproc sq_ass_item; */
4964
 
        0,                                      /* intintobjargproc sq_ass_slice; */
4965
 
        0,                                      /* objobjproc sq_contains; */
4966
 
        /* Added in release 2.0 */
4967
 
        0,                                      /* binaryfunc sq_inplace_concat; */
4968
 
        0,                                      /* intargfunc sq_inplace_repeat; */
 
4958
    0,                                          /* inquiry sq_length; */
 
4959
    0,                                          /* binaryfunc sq_concat; */
 
4960
    0,                                          /* intargfunc sq_repeat; */
 
4961
    Pointer_item,                               /* intargfunc sq_item; */
 
4962
    0,                                          /* intintargfunc sq_slice; */
 
4963
    Pointer_ass_item,                           /* intobjargproc sq_ass_item; */
 
4964
    0,                                          /* intintobjargproc sq_ass_slice; */
 
4965
    0,                                          /* objobjproc sq_contains; */
 
4966
    /* Added in release 2.0 */
 
4967
    0,                                          /* binaryfunc sq_inplace_concat; */
 
4968
    0,                                          /* intargfunc sq_inplace_repeat; */
4969
4969
};
4970
4970
 
4971
4971
static PyMappingMethods Pointer_as_mapping = {
4972
 
        0,
4973
 
        Pointer_subscript,
 
4972
    0,
 
4973
    Pointer_subscript,
4974
4974
};
4975
4975
 
4976
4976
static int
4977
4977
Pointer_bool(CDataObject *self)
4978
4978
{
4979
 
        return (*(void **)self->b_ptr != NULL);
 
4979
    return (*(void **)self->b_ptr != NULL);
4980
4980
}
4981
4981
 
4982
4982
static PyNumberMethods Pointer_as_number = {
4983
 
        0, /* nb_add */
4984
 
        0, /* nb_subtract */
4985
 
        0, /* nb_multiply */
4986
 
        0, /* nb_remainder */
4987
 
        0, /* nb_divmod */
4988
 
        0, /* nb_power */
4989
 
        0, /* nb_negative */
4990
 
        0, /* nb_positive */
4991
 
        0, /* nb_absolute */
4992
 
        (inquiry)Pointer_bool, /* nb_bool */
 
4983
    0, /* nb_add */
 
4984
    0, /* nb_subtract */
 
4985
    0, /* nb_multiply */
 
4986
    0, /* nb_remainder */
 
4987
    0, /* nb_divmod */
 
4988
    0, /* nb_power */
 
4989
    0, /* nb_negative */
 
4990
    0, /* nb_positive */
 
4991
    0, /* nb_absolute */
 
4992
    (inquiry)Pointer_bool, /* nb_bool */
4993
4993
};
4994
4994
 
4995
4995
PyTypeObject PyCPointer_Type = {
4996
 
        PyVarObject_HEAD_INIT(NULL, 0)
4997
 
        "_ctypes._Pointer",
4998
 
        sizeof(CDataObject),                    /* tp_basicsize */
4999
 
        0,                                      /* tp_itemsize */
5000
 
        0,                                      /* tp_dealloc */
5001
 
        0,                                      /* tp_print */
5002
 
        0,                                      /* tp_getattr */
5003
 
        0,                                      /* tp_setattr */
5004
 
        0,                                      /* tp_reserved */
5005
 
        0,                                      /* tp_repr */
5006
 
        &Pointer_as_number,                     /* tp_as_number */
5007
 
        &Pointer_as_sequence,                   /* tp_as_sequence */
5008
 
        &Pointer_as_mapping,                    /* tp_as_mapping */
5009
 
        0,                                      /* tp_hash */
5010
 
        0,                                      /* tp_call */
5011
 
        0,                                      /* tp_str */
5012
 
        0,                                      /* tp_getattro */
5013
 
        0,                                      /* tp_setattro */
5014
 
        &PyCData_as_buffer,                     /* tp_as_buffer */
5015
 
        Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
5016
 
        "XXX to be provided",                   /* tp_doc */
5017
 
        (traverseproc)PyCData_traverse,         /* tp_traverse */
5018
 
        (inquiry)PyCData_clear,                 /* tp_clear */
5019
 
        0,                                      /* tp_richcompare */
5020
 
        0,                                      /* tp_weaklistoffset */
5021
 
        0,                                      /* tp_iter */
5022
 
        0,                                      /* tp_iternext */
5023
 
        0,                                      /* tp_methods */
5024
 
        0,                                      /* tp_members */
5025
 
        Pointer_getsets,                        /* tp_getset */
5026
 
        0,                                      /* tp_base */
5027
 
        0,                                      /* tp_dict */
5028
 
        0,                                      /* tp_descr_get */
5029
 
        0,                                      /* tp_descr_set */
5030
 
        0,                                      /* tp_dictoffset */
5031
 
        (initproc)Pointer_init,                 /* tp_init */
5032
 
        0,                                      /* tp_alloc */
5033
 
        Pointer_new,                            /* tp_new */
5034
 
        0,                                      /* tp_free */
 
4996
    PyVarObject_HEAD_INIT(NULL, 0)
 
4997
    "_ctypes._Pointer",
 
4998
    sizeof(CDataObject),                        /* tp_basicsize */
 
4999
    0,                                          /* tp_itemsize */
 
5000
    0,                                          /* tp_dealloc */
 
5001
    0,                                          /* tp_print */
 
5002
    0,                                          /* tp_getattr */
 
5003
    0,                                          /* tp_setattr */
 
5004
    0,                                          /* tp_reserved */
 
5005
    0,                                          /* tp_repr */
 
5006
    &Pointer_as_number,                         /* tp_as_number */
 
5007
    &Pointer_as_sequence,                       /* tp_as_sequence */
 
5008
    &Pointer_as_mapping,                        /* tp_as_mapping */
 
5009
    0,                                          /* tp_hash */
 
5010
    0,                                          /* tp_call */
 
5011
    0,                                          /* tp_str */
 
5012
    0,                                          /* tp_getattro */
 
5013
    0,                                          /* tp_setattro */
 
5014
    &PyCData_as_buffer,                         /* tp_as_buffer */
 
5015
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
 
5016
    "XXX to be provided",                       /* tp_doc */
 
5017
    (traverseproc)PyCData_traverse,             /* tp_traverse */
 
5018
    (inquiry)PyCData_clear,                     /* tp_clear */
 
5019
    0,                                          /* tp_richcompare */
 
5020
    0,                                          /* tp_weaklistoffset */
 
5021
    0,                                          /* tp_iter */
 
5022
    0,                                          /* tp_iternext */
 
5023
    0,                                          /* tp_methods */
 
5024
    0,                                          /* tp_members */
 
5025
    Pointer_getsets,                            /* tp_getset */
 
5026
    0,                                          /* tp_base */
 
5027
    0,                                          /* tp_dict */
 
5028
    0,                                          /* tp_descr_get */
 
5029
    0,                                          /* tp_descr_set */
 
5030
    0,                                          /* tp_dictoffset */
 
5031
    (initproc)Pointer_init,                     /* tp_init */
 
5032
    0,                                          /* tp_alloc */
 
5033
    Pointer_new,                                /* tp_new */
 
5034
    0,                                          /* tp_free */
5035
5035
};
5036
5036
 
5037
 
 
 
5037
 
5038
5038
/******************************************************************/
5039
5039
/*
5040
5040
 *  Module initialization.
5056
5056
    int status;
5057
5057
 
5058
5058
    if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds))
5059
 
        return -1;
 
5059
    return -1;
5060
5060
 
5061
5061
    if (!PyArg_ParseTuple(args, "OOO:COMError", &hresult, &text, &details))
5062
 
            return -1;
 
5062
        return -1;
5063
5063
 
5064
5064
    a = PySequence_GetSlice(args, 1, PySequence_Size(args));
5065
5065
    if (!a)
5066
 
        return -1;
 
5066
    return -1;
5067
5067
    status = PyObject_SetAttrString(self, "args", a);
5068
5068
    Py_DECREF(a);
5069
5069
    if (status < 0)
5070
 
        return -1;
 
5070
    return -1;
5071
5071
 
5072
5072
    if (PyObject_SetAttrString(self, "hresult", hresult) < 0)
5073
 
            return -1;
 
5073
        return -1;
5074
5074
 
5075
5075
    if (PyObject_SetAttrString(self, "text", text) < 0)
5076
 
            return -1;
 
5076
        return -1;
5077
5077
 
5078
5078
    if (PyObject_SetAttrString(self, "details", details) < 0)
5079
 
            return -1;
 
5079
        return -1;
5080
5080
 
5081
5081
    bself = (PyBaseExceptionObject *)self;
5082
5082
    Py_DECREF(bself->args);
5131
5131
static int
5132
5132
create_comerror(void)
5133
5133
{
5134
 
        PyComError_Type.tp_base = (PyTypeObject*)PyExc_Exception;
5135
 
        if (PyType_Ready(&PyComError_Type) < 0)
5136
 
                return -1;
5137
 
        ComError = (PyObject*)&PyComError_Type;
5138
 
        return 0;
 
5134
    PyComError_Type.tp_base = (PyTypeObject*)PyExc_Exception;
 
5135
    if (PyType_Ready(&PyComError_Type) < 0)
 
5136
        return -1;
 
5137
    ComError = (PyObject*)&PyComError_Type;
 
5138
    return 0;
5139
5139
}
5140
5140
 
5141
5141
#endif
5143
5143
static PyObject *
5144
5144
string_at(const char *ptr, int size)
5145
5145
{
5146
 
        if (size == -1)
5147
 
                return PyBytes_FromStringAndSize(ptr, strlen(ptr));
5148
 
        return PyBytes_FromStringAndSize(ptr, size);
 
5146
    if (size == -1)
 
5147
        return PyBytes_FromStringAndSize(ptr, strlen(ptr));
 
5148
    return PyBytes_FromStringAndSize(ptr, size);
5149
5149
}
5150
5150
 
5151
5151
static int
5152
5152
cast_check_pointertype(PyObject *arg)
5153
5153
{
5154
 
        StgDictObject *dict;
 
5154
    StgDictObject *dict;
5155
5155
 
5156
 
        if (PyCPointerTypeObject_Check(arg))
5157
 
                return 1;
5158
 
        if (PyCFuncPtrTypeObject_Check(arg))
5159
 
                return 1;
5160
 
        dict = PyType_stgdict(arg);
5161
 
        if (dict) {
5162
 
                if (PyUnicode_Check(dict->proto)
5163
 
                    && (strchr("sPzUZXO", _PyUnicode_AsString(dict->proto)[0]))) {
5164
 
                        /* simple pointer types, c_void_p, c_wchar_p, BSTR, ... */
5165
 
                        return 1;
5166
 
                }
5167
 
        }
5168
 
        PyErr_Format(PyExc_TypeError,
5169
 
                     "cast() argument 2 must be a pointer type, not %s",
5170
 
                     PyType_Check(arg)
5171
 
                     ? ((PyTypeObject *)arg)->tp_name
5172
 
                     : Py_TYPE(arg)->tp_name);
5173
 
        return 0;
 
5156
    if (PyCPointerTypeObject_Check(arg))
 
5157
        return 1;
 
5158
    if (PyCFuncPtrTypeObject_Check(arg))
 
5159
        return 1;
 
5160
    dict = PyType_stgdict(arg);
 
5161
    if (dict) {
 
5162
        if (PyUnicode_Check(dict->proto)
 
5163
            && (strchr("sPzUZXO", _PyUnicode_AsString(dict->proto)[0]))) {
 
5164
            /* simple pointer types, c_void_p, c_wchar_p, BSTR, ... */
 
5165
            return 1;
 
5166
        }
 
5167
    }
 
5168
    PyErr_Format(PyExc_TypeError,
 
5169
                 "cast() argument 2 must be a pointer type, not %s",
 
5170
                 PyType_Check(arg)
 
5171
                 ? ((PyTypeObject *)arg)->tp_name
 
5172
                 : Py_TYPE(arg)->tp_name);
 
5173
    return 0;
5174
5174
}
5175
5175
 
5176
5176
static PyObject *
5177
5177
cast(void *ptr, PyObject *src, PyObject *ctype)
5178
5178
{
5179
 
        CDataObject *result;
5180
 
        if (0 == cast_check_pointertype(ctype))
5181
 
                return NULL;
5182
 
        result = (CDataObject *)PyObject_CallFunctionObjArgs(ctype, NULL);
5183
 
        if (result == NULL)
5184
 
                return NULL;
5185
 
 
5186
 
        /*
5187
 
          The casted objects '_objects' member:
5188
 
 
5189
 
          It must certainly contain the source objects one.
5190
 
          It must contain the source object itself.
5191
 
         */
5192
 
        if (CDataObject_Check(src)) {
5193
 
                CDataObject *obj = (CDataObject *)src;
5194
 
                /* PyCData_GetContainer will initialize src.b_objects, we need
5195
 
                   this so it can be shared */
5196
 
                PyCData_GetContainer(obj);
5197
 
                /* But we need a dictionary! */
5198
 
                if (obj->b_objects == Py_None) {
5199
 
                        Py_DECREF(Py_None);
5200
 
                        obj->b_objects = PyDict_New();
5201
 
                        if (obj->b_objects == NULL)
5202
 
                                goto failed;
5203
 
                }
5204
 
                Py_XINCREF(obj->b_objects);
5205
 
                result->b_objects = obj->b_objects;
5206
 
                if (result->b_objects && PyDict_CheckExact(result->b_objects)) {
5207
 
                        PyObject *index;
5208
 
                        int rc;
5209
 
                        index = PyLong_FromVoidPtr((void *)src);
5210
 
                        if (index == NULL)
5211
 
                                goto failed;
5212
 
                        rc = PyDict_SetItem(result->b_objects, index, src);
5213
 
                        Py_DECREF(index);
5214
 
                        if (rc == -1)
5215
 
                                goto failed;
5216
 
                }
5217
 
        }
5218
 
        /* Should we assert that result is a pointer type? */
5219
 
        memcpy(result->b_ptr, &ptr, sizeof(void *));
5220
 
        return (PyObject *)result;
 
5179
    CDataObject *result;
 
5180
    if (0 == cast_check_pointertype(ctype))
 
5181
        return NULL;
 
5182
    result = (CDataObject *)PyObject_CallFunctionObjArgs(ctype, NULL);
 
5183
    if (result == NULL)
 
5184
        return NULL;
 
5185
 
 
5186
    /*
 
5187
      The casted objects '_objects' member:
 
5188
 
 
5189
      It must certainly contain the source objects one.
 
5190
      It must contain the source object itself.
 
5191
     */
 
5192
    if (CDataObject_Check(src)) {
 
5193
        CDataObject *obj = (CDataObject *)src;
 
5194
        /* PyCData_GetContainer will initialize src.b_objects, we need
 
5195
           this so it can be shared */
 
5196
        PyCData_GetContainer(obj);
 
5197
        /* But we need a dictionary! */
 
5198
        if (obj->b_objects == Py_None) {
 
5199
            Py_DECREF(Py_None);
 
5200
            obj->b_objects = PyDict_New();
 
5201
            if (obj->b_objects == NULL)
 
5202
                goto failed;
 
5203
        }
 
5204
        Py_XINCREF(obj->b_objects);
 
5205
        result->b_objects = obj->b_objects;
 
5206
        if (result->b_objects && PyDict_CheckExact(result->b_objects)) {
 
5207
            PyObject *index;
 
5208
            int rc;
 
5209
            index = PyLong_FromVoidPtr((void *)src);
 
5210
            if (index == NULL)
 
5211
                goto failed;
 
5212
            rc = PyDict_SetItem(result->b_objects, index, src);
 
5213
            Py_DECREF(index);
 
5214
            if (rc == -1)
 
5215
                goto failed;
 
5216
        }
 
5217
    }
 
5218
    /* Should we assert that result is a pointer type? */
 
5219
    memcpy(result->b_ptr, &ptr, sizeof(void *));
 
5220
    return (PyObject *)result;
5221
5221
 
5222
5222
  failed:
5223
 
        Py_DECREF(result);
5224
 
        return NULL;
 
5223
    Py_DECREF(result);
 
5224
    return NULL;
5225
5225
}
5226
5226
 
5227
5227
#ifdef CTYPES_UNICODE
5228
5228
static PyObject *
5229
5229
wstring_at(const wchar_t *ptr, int size)
5230
5230
{
5231
 
        Py_ssize_t ssize = size;
5232
 
        if (ssize == -1)
5233
 
                ssize = wcslen(ptr);
5234
 
        return PyUnicode_FromWideChar(ptr, ssize);
 
5231
    Py_ssize_t ssize = size;
 
5232
    if (ssize == -1)
 
5233
        ssize = wcslen(ptr);
 
5234
    return PyUnicode_FromWideChar(ptr, ssize);
5235
5235
}
5236
5236
#endif
5237
5237
 
5238
5238
 
5239
5239
static struct PyModuleDef _ctypesmodule = {
5240
 
        PyModuleDef_HEAD_INIT,
5241
 
        "_ctypes",
5242
 
        module_docs,
5243
 
        -1,
5244
 
        _ctypes_module_methods,
5245
 
        NULL,
5246
 
        NULL,
5247
 
        NULL,
5248
 
        NULL
 
5240
    PyModuleDef_HEAD_INIT,
 
5241
    "_ctypes",
 
5242
    module_docs,
 
5243
    -1,
 
5244
    _ctypes_module_methods,
 
5245
    NULL,
 
5246
    NULL,
 
5247
    NULL,
 
5248
    NULL
5249
5249
};
5250
5250
 
5251
5251
PyMODINIT_FUNC
5252
5252
PyInit__ctypes(void)
5253
5253
{
5254
 
        PyObject *m;
 
5254
    PyObject *m;
5255
5255
 
5256
5256
/* Note:
5257
5257
   ob_type is the metatype (the 'type'), defaults to PyType_Type,
5258
5258
   tp_base is the base type, defaults to 'object' aka PyBaseObject_Type.
5259
5259
*/
5260
5260
#ifdef WITH_THREAD
5261
 
        PyEval_InitThreads();
 
5261
    PyEval_InitThreads();
5262
5262
#endif
5263
 
        m = PyModule_Create(&_ctypesmodule);
5264
 
        if (!m)
5265
 
                return NULL;
5266
 
 
5267
 
        _ctypes_ptrtype_cache = PyDict_New();
5268
 
        if (_ctypes_ptrtype_cache == NULL)
5269
 
                return NULL;
5270
 
 
5271
 
        PyModule_AddObject(m, "_pointer_type_cache", (PyObject *)_ctypes_ptrtype_cache);
5272
 
 
5273
 
        _unpickle = PyObject_GetAttrString(m, "_unpickle");
5274
 
        if (_unpickle == NULL)
5275
 
                return NULL;
5276
 
 
5277
 
        if (PyType_Ready(&PyCArg_Type) < 0)
5278
 
                return NULL;
5279
 
 
5280
 
        if (PyType_Ready(&PyCThunk_Type) < 0)
5281
 
                return NULL;
5282
 
 
5283
 
        /* StgDict is derived from PyDict_Type */
5284
 
        PyCStgDict_Type.tp_base = &PyDict_Type;
5285
 
        if (PyType_Ready(&PyCStgDict_Type) < 0)
5286
 
                return NULL;
5287
 
 
5288
 
        /*************************************************
5289
 
         *
5290
 
         * Metaclasses
5291
 
         */
5292
 
 
5293
 
        PyCStructType_Type.tp_base = &PyType_Type;
5294
 
        if (PyType_Ready(&PyCStructType_Type) < 0)
5295
 
                return NULL;
5296
 
 
5297
 
        UnionType_Type.tp_base = &PyType_Type;
5298
 
        if (PyType_Ready(&UnionType_Type) < 0)
5299
 
                return NULL;
5300
 
 
5301
 
        PyCPointerType_Type.tp_base = &PyType_Type;
5302
 
        if (PyType_Ready(&PyCPointerType_Type) < 0)
5303
 
                return NULL;
5304
 
 
5305
 
        PyCArrayType_Type.tp_base = &PyType_Type;
5306
 
        if (PyType_Ready(&PyCArrayType_Type) < 0)
5307
 
                return NULL;
5308
 
 
5309
 
        PyCSimpleType_Type.tp_base = &PyType_Type;
5310
 
        if (PyType_Ready(&PyCSimpleType_Type) < 0)
5311
 
                return NULL;
5312
 
 
5313
 
        PyCFuncPtrType_Type.tp_base = &PyType_Type;
5314
 
        if (PyType_Ready(&PyCFuncPtrType_Type) < 0)
5315
 
                return NULL;
5316
 
 
5317
 
        /*************************************************
5318
 
         *
5319
 
         * Classes using a custom metaclass
5320
 
         */
5321
 
 
5322
 
        if (PyType_Ready(&PyCData_Type) < 0)
5323
 
                return NULL;
5324
 
 
5325
 
        Py_TYPE(&Struct_Type) = &PyCStructType_Type;
5326
 
        Struct_Type.tp_base = &PyCData_Type;
5327
 
        if (PyType_Ready(&Struct_Type) < 0)
5328
 
                return NULL;
5329
 
        PyModule_AddObject(m, "Structure", (PyObject *)&Struct_Type);
5330
 
 
5331
 
        Py_TYPE(&Union_Type) = &UnionType_Type;
5332
 
        Union_Type.tp_base = &PyCData_Type;
5333
 
        if (PyType_Ready(&Union_Type) < 0)
5334
 
                return NULL;
5335
 
        PyModule_AddObject(m, "Union", (PyObject *)&Union_Type);
5336
 
 
5337
 
        Py_TYPE(&PyCPointer_Type) = &PyCPointerType_Type;
5338
 
        PyCPointer_Type.tp_base = &PyCData_Type;
5339
 
        if (PyType_Ready(&PyCPointer_Type) < 0)
5340
 
                return NULL;
5341
 
        PyModule_AddObject(m, "_Pointer", (PyObject *)&PyCPointer_Type);
5342
 
 
5343
 
        Py_TYPE(&PyCArray_Type) = &PyCArrayType_Type;
5344
 
        PyCArray_Type.tp_base = &PyCData_Type;
5345
 
        if (PyType_Ready(&PyCArray_Type) < 0)
5346
 
                return NULL;
5347
 
        PyModule_AddObject(m, "Array", (PyObject *)&PyCArray_Type);
5348
 
 
5349
 
        Py_TYPE(&Simple_Type) = &PyCSimpleType_Type;
5350
 
        Simple_Type.tp_base = &PyCData_Type;
5351
 
        if (PyType_Ready(&Simple_Type) < 0)
5352
 
                return NULL;
5353
 
        PyModule_AddObject(m, "_SimpleCData", (PyObject *)&Simple_Type);
5354
 
 
5355
 
        Py_TYPE(&PyCFuncPtr_Type) = &PyCFuncPtrType_Type;
5356
 
        PyCFuncPtr_Type.tp_base = &PyCData_Type;
5357
 
        if (PyType_Ready(&PyCFuncPtr_Type) < 0)
5358
 
                return NULL;
5359
 
        PyModule_AddObject(m, "CFuncPtr", (PyObject *)&PyCFuncPtr_Type);
5360
 
 
5361
 
        /*************************************************
5362
 
         *
5363
 
         * Simple classes
5364
 
         */
5365
 
 
5366
 
        /* PyCField_Type is derived from PyBaseObject_Type */
5367
 
        if (PyType_Ready(&PyCField_Type) < 0)
5368
 
                return NULL;
5369
 
 
5370
 
        /*************************************************
5371
 
         *
5372
 
         * Other stuff
5373
 
         */
5374
 
 
5375
 
        DictRemover_Type.tp_new = PyType_GenericNew;
5376
 
        if (PyType_Ready(&DictRemover_Type) < 0)
5377
 
                return NULL;
 
5263
    m = PyModule_Create(&_ctypesmodule);
 
5264
    if (!m)
 
5265
        return NULL;
 
5266
 
 
5267
    _ctypes_ptrtype_cache = PyDict_New();
 
5268
    if (_ctypes_ptrtype_cache == NULL)
 
5269
        return NULL;
 
5270
 
 
5271
    PyModule_AddObject(m, "_pointer_type_cache", (PyObject *)_ctypes_ptrtype_cache);
 
5272
 
 
5273
    _unpickle = PyObject_GetAttrString(m, "_unpickle");
 
5274
    if (_unpickle == NULL)
 
5275
        return NULL;
 
5276
 
 
5277
    if (PyType_Ready(&PyCArg_Type) < 0)
 
5278
        return NULL;
 
5279
 
 
5280
    if (PyType_Ready(&PyCThunk_Type) < 0)
 
5281
        return NULL;
 
5282
 
 
5283
    /* StgDict is derived from PyDict_Type */
 
5284
    PyCStgDict_Type.tp_base = &PyDict_Type;
 
5285
    if (PyType_Ready(&PyCStgDict_Type) < 0)
 
5286
        return NULL;
 
5287
 
 
5288
    /*************************************************
 
5289
     *
 
5290
     * Metaclasses
 
5291
     */
 
5292
 
 
5293
    PyCStructType_Type.tp_base = &PyType_Type;
 
5294
    if (PyType_Ready(&PyCStructType_Type) < 0)
 
5295
        return NULL;
 
5296
 
 
5297
    UnionType_Type.tp_base = &PyType_Type;
 
5298
    if (PyType_Ready(&UnionType_Type) < 0)
 
5299
        return NULL;
 
5300
 
 
5301
    PyCPointerType_Type.tp_base = &PyType_Type;
 
5302
    if (PyType_Ready(&PyCPointerType_Type) < 0)
 
5303
        return NULL;
 
5304
 
 
5305
    PyCArrayType_Type.tp_base = &PyType_Type;
 
5306
    if (PyType_Ready(&PyCArrayType_Type) < 0)
 
5307
        return NULL;
 
5308
 
 
5309
    PyCSimpleType_Type.tp_base = &PyType_Type;
 
5310
    if (PyType_Ready(&PyCSimpleType_Type) < 0)
 
5311
        return NULL;
 
5312
 
 
5313
    PyCFuncPtrType_Type.tp_base = &PyType_Type;
 
5314
    if (PyType_Ready(&PyCFuncPtrType_Type) < 0)
 
5315
        return NULL;
 
5316
 
 
5317
    /*************************************************
 
5318
     *
 
5319
     * Classes using a custom metaclass
 
5320
     */
 
5321
 
 
5322
    if (PyType_Ready(&PyCData_Type) < 0)
 
5323
        return NULL;
 
5324
 
 
5325
    Py_TYPE(&Struct_Type) = &PyCStructType_Type;
 
5326
    Struct_Type.tp_base = &PyCData_Type;
 
5327
    if (PyType_Ready(&Struct_Type) < 0)
 
5328
        return NULL;
 
5329
    PyModule_AddObject(m, "Structure", (PyObject *)&Struct_Type);
 
5330
 
 
5331
    Py_TYPE(&Union_Type) = &UnionType_Type;
 
5332
    Union_Type.tp_base = &PyCData_Type;
 
5333
    if (PyType_Ready(&Union_Type) < 0)
 
5334
        return NULL;
 
5335
    PyModule_AddObject(m, "Union", (PyObject *)&Union_Type);
 
5336
 
 
5337
    Py_TYPE(&PyCPointer_Type) = &PyCPointerType_Type;
 
5338
    PyCPointer_Type.tp_base = &PyCData_Type;
 
5339
    if (PyType_Ready(&PyCPointer_Type) < 0)
 
5340
        return NULL;
 
5341
    PyModule_AddObject(m, "_Pointer", (PyObject *)&PyCPointer_Type);
 
5342
 
 
5343
    Py_TYPE(&PyCArray_Type) = &PyCArrayType_Type;
 
5344
    PyCArray_Type.tp_base = &PyCData_Type;
 
5345
    if (PyType_Ready(&PyCArray_Type) < 0)
 
5346
        return NULL;
 
5347
    PyModule_AddObject(m, "Array", (PyObject *)&PyCArray_Type);
 
5348
 
 
5349
    Py_TYPE(&Simple_Type) = &PyCSimpleType_Type;
 
5350
    Simple_Type.tp_base = &PyCData_Type;
 
5351
    if (PyType_Ready(&Simple_Type) < 0)
 
5352
        return NULL;
 
5353
    PyModule_AddObject(m, "_SimpleCData", (PyObject *)&Simple_Type);
 
5354
 
 
5355
    Py_TYPE(&PyCFuncPtr_Type) = &PyCFuncPtrType_Type;
 
5356
    PyCFuncPtr_Type.tp_base = &PyCData_Type;
 
5357
    if (PyType_Ready(&PyCFuncPtr_Type) < 0)
 
5358
        return NULL;
 
5359
    PyModule_AddObject(m, "CFuncPtr", (PyObject *)&PyCFuncPtr_Type);
 
5360
 
 
5361
    /*************************************************
 
5362
     *
 
5363
     * Simple classes
 
5364
     */
 
5365
 
 
5366
    /* PyCField_Type is derived from PyBaseObject_Type */
 
5367
    if (PyType_Ready(&PyCField_Type) < 0)
 
5368
        return NULL;
 
5369
 
 
5370
    /*************************************************
 
5371
     *
 
5372
     * Other stuff
 
5373
     */
 
5374
 
 
5375
    DictRemover_Type.tp_new = PyType_GenericNew;
 
5376
    if (PyType_Ready(&DictRemover_Type) < 0)
 
5377
        return NULL;
5378
5378
 
5379
5379
#ifdef MS_WIN32
5380
 
        if (create_comerror() < 0)
5381
 
                return NULL;
5382
 
        PyModule_AddObject(m, "COMError", ComError);
 
5380
    if (create_comerror() < 0)
 
5381
        return NULL;
 
5382
    PyModule_AddObject(m, "COMError", ComError);
5383
5383
 
5384
 
        PyModule_AddObject(m, "FUNCFLAG_HRESULT", PyLong_FromLong(FUNCFLAG_HRESULT));
5385
 
        PyModule_AddObject(m, "FUNCFLAG_STDCALL", PyLong_FromLong(FUNCFLAG_STDCALL));
 
5384
    PyModule_AddObject(m, "FUNCFLAG_HRESULT", PyLong_FromLong(FUNCFLAG_HRESULT));
 
5385
    PyModule_AddObject(m, "FUNCFLAG_STDCALL", PyLong_FromLong(FUNCFLAG_STDCALL));
5386
5386
#endif
5387
 
        PyModule_AddObject(m, "FUNCFLAG_CDECL", PyLong_FromLong(FUNCFLAG_CDECL));
5388
 
        PyModule_AddObject(m, "FUNCFLAG_USE_ERRNO", PyLong_FromLong(FUNCFLAG_USE_ERRNO));
5389
 
        PyModule_AddObject(m, "FUNCFLAG_USE_LASTERROR", PyLong_FromLong(FUNCFLAG_USE_LASTERROR));
5390
 
        PyModule_AddObject(m, "FUNCFLAG_PYTHONAPI", PyLong_FromLong(FUNCFLAG_PYTHONAPI));
5391
 
        PyModule_AddStringConstant(m, "__version__", "1.1.0");
 
5387
    PyModule_AddObject(m, "FUNCFLAG_CDECL", PyLong_FromLong(FUNCFLAG_CDECL));
 
5388
    PyModule_AddObject(m, "FUNCFLAG_USE_ERRNO", PyLong_FromLong(FUNCFLAG_USE_ERRNO));
 
5389
    PyModule_AddObject(m, "FUNCFLAG_USE_LASTERROR", PyLong_FromLong(FUNCFLAG_USE_LASTERROR));
 
5390
    PyModule_AddObject(m, "FUNCFLAG_PYTHONAPI", PyLong_FromLong(FUNCFLAG_PYTHONAPI));
 
5391
    PyModule_AddStringConstant(m, "__version__", "1.1.0");
5392
5392
 
5393
 
        PyModule_AddObject(m, "_memmove_addr", PyLong_FromVoidPtr(memmove));
5394
 
        PyModule_AddObject(m, "_memset_addr", PyLong_FromVoidPtr(memset));
5395
 
        PyModule_AddObject(m, "_string_at_addr", PyLong_FromVoidPtr(string_at));
5396
 
        PyModule_AddObject(m, "_cast_addr", PyLong_FromVoidPtr(cast));
 
5393
    PyModule_AddObject(m, "_memmove_addr", PyLong_FromVoidPtr(memmove));
 
5394
    PyModule_AddObject(m, "_memset_addr", PyLong_FromVoidPtr(memset));
 
5395
    PyModule_AddObject(m, "_string_at_addr", PyLong_FromVoidPtr(string_at));
 
5396
    PyModule_AddObject(m, "_cast_addr", PyLong_FromVoidPtr(cast));
5397
5397
#ifdef CTYPES_UNICODE
5398
 
        PyModule_AddObject(m, "_wstring_at_addr", PyLong_FromVoidPtr(wstring_at));
 
5398
    PyModule_AddObject(m, "_wstring_at_addr", PyLong_FromVoidPtr(wstring_at));
5399
5399
#endif
5400
5400
 
5401
5401
/* If RTLD_LOCAL is not defined (Windows!), set it to zero. */
5410
5410
#define RTLD_GLOBAL RTLD_LOCAL
5411
5411
#endif
5412
5412
 
5413
 
        PyModule_AddObject(m, "RTLD_LOCAL", PyLong_FromLong(RTLD_LOCAL));
5414
 
        PyModule_AddObject(m, "RTLD_GLOBAL", PyLong_FromLong(RTLD_GLOBAL));
5415
 
        
5416
 
        PyExc_ArgError = PyErr_NewException("ctypes.ArgumentError", NULL, NULL);
5417
 
        if (PyExc_ArgError) {
5418
 
                Py_INCREF(PyExc_ArgError);
5419
 
                PyModule_AddObject(m, "ArgumentError", PyExc_ArgError);
5420
 
        }
5421
 
        return m;
 
5413
    PyModule_AddObject(m, "RTLD_LOCAL", PyLong_FromLong(RTLD_LOCAL));
 
5414
    PyModule_AddObject(m, "RTLD_GLOBAL", PyLong_FromLong(RTLD_GLOBAL));
 
5415
 
 
5416
    PyExc_ArgError = PyErr_NewException("ctypes.ArgumentError", NULL, NULL);
 
5417
    if (PyExc_ArgError) {
 
5418
        Py_INCREF(PyExc_ArgError);
 
5419
        PyModule_AddObject(m, "ArgumentError", PyExc_ArgError);
 
5420
    }
 
5421
    return m;
5422
5422
}
5423
5423
 
5424
5424
/*