Exemple #1
0
static PyObject *_ffi_new(FFIObject *self, PyObject *args, PyObject *kwds,
                          const cffi_allocator_t *allocator)
{
    CTypeDescrObject *ct;
    PyObject *arg, *init = Py_None;
    static char *keywords[] = {"cdecl", "init", NULL};
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:new", keywords,
                                     &arg, &init))
        return NULL;

    ct = _ffi_type(self, arg, ACCEPT_STRING|ACCEPT_CTYPE);
    if (ct == NULL)
        return NULL;

    return direct_newp(ct, init, allocator);
}
Exemple #2
0
static PyObject *ffi_sizeof(FFIObject *self, PyObject *arg)
{
    Py_ssize_t size;
    CTypeDescrObject *ct = _ffi_type(self, arg, ACCEPT_ALL);
    if (ct == NULL)
        return NULL;

    size = ct->ct_size;

    if (CData_Check(arg)) {
        CDataObject *cd = (CDataObject *)arg;
        if (cd->c_type->ct_flags & CT_ARRAY)
            size = get_array_length(cd) * cd->c_type->ct_itemdescr->ct_size;
    }

    if (size < 0) {
        PyErr_Format(FFIError, "don't know the size of ctype '%s'",
                     ct->ct_name);
        return NULL;
    }
    return PyInt_FromSsize_t(size);
}
Exemple #3
0
static CTypeDescrObject *_ffi_type(FFIObject *ffi, PyObject *arg,
                                   int accept)
{
    /* Returns the CTypeDescrObject from the user-supplied 'arg'.
       Does not return a new reference!
    */
    if ((accept & ACCEPT_STRING) && PyText_Check(arg)) {
        PyObject *types_dict = ffi->types_builder.types_dict;
        PyObject *x = PyDict_GetItem(types_dict, arg);

        if (x == NULL) {
            char *input_text = PyText_AS_UTF8(arg);
            int err, index = parse_c_type(&ffi->info, input_text);
            if (index < 0)
                return _ffi_bad_type(ffi, input_text);

            x = realize_c_type_or_func(&ffi->types_builder,
                                       ffi->info.output, index);
            if (x == NULL)
                return NULL;

            /* Cache under the name given by 'arg', in addition to the
               fact that the same ct is probably already cached under
               its standardized name.  In a few cases, it is not, e.g.
               if it is a primitive; for the purpose of this function,
               the important point is the following line, which makes
               sure that in any case the next _ffi_type() with the same
               'arg' will succeed early, in PyDict_GetItem() above.
            */
            err = PyDict_SetItem(types_dict, arg, x);
            Py_DECREF(x); /* we know it was written in types_dict (unless out
                             of mem), so there is at least that ref left */
            if (err < 0)
                return NULL;
        }

        if (CTypeDescr_Check(x))
            return (CTypeDescrObject *)x;
        else if (accept & CONSIDER_FN_AS_FNPTR)
            return unwrap_fn_as_fnptr(x);
        else
            return unexpected_fn_type(x);
    }
    else if ((accept & ACCEPT_CTYPE) && CTypeDescr_Check(arg)) {
        return (CTypeDescrObject *)arg;
    }
    else if ((accept & ACCEPT_CDATA) && CData_Check(arg)) {
        return ((CDataObject *)arg)->c_type;
    }
#if PY_MAJOR_VERSION < 3
    else if (PyUnicode_Check(arg)) {
        CTypeDescrObject *result;
        arg = PyUnicode_AsASCIIString(arg);
        if (arg == NULL)
            return NULL;
        result = _ffi_type(ffi, arg, accept);
        Py_DECREF(arg);
        return result;
    }
#endif
    else {
        const char *m1 = (accept & ACCEPT_STRING) ? "string" : "";
        const char *m2 = (accept & ACCEPT_CTYPE) ? "ctype object" : "";
        const char *m3 = (accept & ACCEPT_CDATA) ? "cdata object" : "";
        const char *s12 = (*m1 && (*m2 || *m3)) ? " or " : "";
        const char *s23 = (*m2 && *m3) ? " or " : "";
        PyErr_Format(PyExc_TypeError, "expected a %s%s%s%s%s, got '%.200s'",
                     m1, s12, m2, s23, m3,
                     Py_TYPE(arg)->tp_name);
        return NULL;
    }
}