ParseTuple routines for Obj, String.
Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/514827b7 Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/514827b7 Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/514827b7 Branch: refs/heads/master Commit: 514827b7293471645b0d6a5d450ef7ad1177e79d Parents: 9bbb13f Author: Marvin Humphrey <[email protected]> Authored: Wed Jan 27 17:13:51 2016 -0800 Committer: Marvin Humphrey <[email protected]> Committed: Tue Feb 23 18:22:04 2016 -0800 ---------------------------------------------------------------------- runtime/python/cfext/CFBind.c | 100 +++++++++++++++++++++++++++++++++++++ runtime/python/cfext/CFBind.h | 13 +++++ 2 files changed, 113 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/514827b7/runtime/python/cfext/CFBind.c ---------------------------------------------------------------------- diff --git a/runtime/python/cfext/CFBind.c b/runtime/python/cfext/CFBind.c index 9ecd11e..7e7f617 100644 --- a/runtime/python/cfext/CFBind.c +++ b/runtime/python/cfext/CFBind.c @@ -285,6 +285,106 @@ CFBind_py_to_cfish_noinc(PyObject *py_obj, cfish_Class *klass, } static int +S_convert_obj(PyObject *py_obj, CFBindArg *arg, bool nullable) { + if (py_obj == Py_None) { + if (nullable) { + return 1; + } + else { + PyErr_SetString(PyExc_TypeError, "Required argument cannot be None"); + return 0; + } + } + PyTypeObject *py_type = S_get_cached_py_type(arg->klass); + if (!PyObject_TypeCheck(py_obj, py_type)) { + PyErr_SetString(PyExc_TypeError, "Invalid argument type"); + return 0; + } + *((PyObject**)arg->ptr) = py_obj; + return 1; +} + +int +CFBind_convert_obj(PyObject *py_obj, CFBindArg *arg) { + return S_convert_obj(py_obj, arg, false); +} + +int +CFBind_maybe_convert_obj(PyObject *py_obj, CFBindArg *arg) { + return S_convert_obj(py_obj, arg, true); +} + +static int +S_convert_string(PyObject *py_obj, cfish_String **ptr, bool nullable) { + if (py_obj == NULL) { // Py_CLEANUP_SUPPORTED cleanup + if (*ptr != NULL) { + if (!CFISH_Str_Is_Copy_On_IncRef(*ptr)) { + CFISH_DECREF(*ptr); + } + *ptr = NULL; + } + return 1; + } + + if (py_obj == Py_None) { + if (*ptr != NULL) { + // Default value passed as stack string. + *ptr = CFISH_Str_Clone(*ptr); + return Py_CLEANUP_SUPPORTED; + } + else if (nullable) { + return 1; + } + else { + PyErr_SetString(PyExc_TypeError, "Required argument cannot be None"); + return 0; + } + } + else if (PyUnicode_CheckExact(py_obj)) { + Py_ssize_t size; + char *utf8 = PyUnicode_AsUTF8AndSize(py_obj, &size); + if (!utf8) { + return 0; + } + *ptr = cfish_Str_new_from_trusted_utf8(utf8, size); + return Py_CLEANUP_SUPPORTED; + } + else if (S_py_obj_is_a(py_obj, CFISH_STRING)) { + *ptr = (cfish_String*)CFISH_INCREF(py_obj); + return Py_CLEANUP_SUPPORTED; + } + else if (S_py_obj_is_a(py_obj, CFISH_OBJ)) { + *ptr = CFISH_Obj_To_String((cfish_Obj*)py_obj); + return Py_CLEANUP_SUPPORTED; + } + else { + PyObject *stringified = PyObject_Str(py_obj); + if (stringified == NULL) { + return 0; + } + Py_ssize_t size; + char *utf8 = PyUnicode_AsUTF8AndSize(stringified, &size); + if (!utf8) { + Py_DECREF(stringified); + return 0; + } + *ptr = cfish_Str_new_from_trusted_utf8(utf8, size); + Py_DECREF(stringified); + return Py_CLEANUP_SUPPORTED; + } +} + +int +CFBind_convert_string(PyObject *py_obj, cfish_String **ptr) { + return S_convert_string(py_obj, ptr, false); +} + +int +CFBind_maybe_convert_string(PyObject *py_obj, cfish_String **ptr) { + return S_convert_string(py_obj, ptr, true); +} + +static int S_convert_hash(PyObject *py_obj, cfish_Hash **hash_ptr, bool nullable) { if (py_obj == NULL) { // Py_CLEANUP_SUPPORTED cleanup CFISH_DECREF(*hash_ptr); http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/514827b7/runtime/python/cfext/CFBind.h ---------------------------------------------------------------------- diff --git a/runtime/python/cfext/CFBind.h b/runtime/python/cfext/CFBind.h index d7eb0ba..b6e57fd 100644 --- a/runtime/python/cfext/CFBind.h +++ b/runtime/python/cfext/CFBind.h @@ -100,16 +100,29 @@ cfish_Obj* CFBind_py_to_cfish_noinc(PyObject *py_obj, cfish_Class *klass, void *allocation); +typedef struct CFBindArg { + cfish_Class *klass; + void *ptr; +} CFBindArg; + /* ParseTuple conversion routines for reference types. * * If `input` is `None`, the "maybe_convert" variants will leave `ptr` * untouched, while the "convert" routines will raise a TypeError. */ int +CFBind_convert_obj(PyObject *input, CFBindArg *arg); +int +CFBind_convert_string(PyObject *input, cfish_String **ptr); +int CFBind_convert_hash(PyObject *input, cfish_Hash **ptr); int CFBind_convert_vec(PyObject *input, cfish_Vector **ptr); int +CFBind_maybe_convert_obj(PyObject *input, CFBindArg *arg); +int +CFBind_maybe_convert_string(PyObject *input, cfish_String **ptr); +int CFBind_maybe_convert_hash(PyObject *input, cfish_Hash **ptr); int CFBind_maybe_convert_vec(PyObject *input, cfish_Vector **ptr);
