#ifndef _PY_NAMESPACE_OBJ_H #define _PY_NAMESPACE_OBJ_H #define PY_SSIZE_T_CLEAN #include #include #include "namespace.h" typedef struct { PyObject_HEAD LSUP_NSMap *ob_struct; } NSMapObject; static int NSMap_init (NSMapObject *self, PyObject *args) { self->ob_struct = LSUP_nsmap_new(); if (!self->ob_struct) { PyErr_SetString (PyExc_SystemError, "Could not create namespace."); return -1; } return 0; } static void NSMap_dealloc (NSMapObject *self) { LSUP_nsmap_free (self->ob_struct); Py_TYPE (self)->tp_free ((PyObject *) self); } static PyObject * NSMap_add (PyObject *self, PyObject *args) { const char *pfx, *ns; if (! PyArg_ParseTuple (args, "ss", &pfx, &ns)) return NULL; if (LSUP_nsmap_add (((NSMapObject *)self)->ob_struct, pfx, ns) < 0) { PyErr_SetString (PyExc_ValueError, "Error adding namespace."); return NULL; } Py_RETURN_NONE; } static PyObject * NSMap_remove (PyObject *self, PyObject *pfx_obj) { if (PyUnicode_READY (pfx_obj) < 0) return NULL; const char *pfx = PyUnicode_AsUTF8 (pfx_obj); if (LSUP_nsmap_remove (((NSMapObject *)self)->ob_struct, pfx) < 0) { PyErr_SetString (PyExc_ValueError, "Error removing namespace."); return NULL; } Py_RETURN_NONE; } static PyObject * NSMap_get (PyObject *self, PyObject *pfx_obj) { if (PyUnicode_READY (pfx_obj) < 0) return NULL; const char *pfx = PyUnicode_AsUTF8 (pfx_obj); const char *ns = LSUP_nsmap_get_ns (((NSMapObject *)self)->ob_struct, pfx); if (!ns) Py_RETURN_NONE; PyObject *ns_obj = PyUnicode_FromString (ns); Py_INCREF (ns_obj); return (ns_obj); } static PyObject * NSMap_denormalize_uri (PyObject *self, PyObject *fq_uri_obj) { if (PyUnicode_READY (fq_uri_obj) < 0) return NULL; const char *fq_uri = PyUnicode_AsUTF8 (fq_uri_obj); char *pfx_uri; LSUP_rc rc = LSUP_nsmap_denormalize_uri ( ((NSMapObject *)self)->ob_struct, fq_uri, &pfx_uri); if (rc < 0) { PyErr_SetString (PyExc_ValueError, "Error normalizing URI."); return NULL; } else if (rc == LSUP_NORESULT) Py_RETURN_NONE; PyObject *uri_obj = PyUnicode_FromString (pfx_uri); Py_INCREF (uri_obj); return (uri_obj); } static PyObject * NSMap_normalize_uri (PyObject *self, PyObject *pfx_uri_obj) { if (PyUnicode_READY (pfx_uri_obj) < 0) return NULL; const char *pfx_uri = PyUnicode_AsUTF8 (pfx_uri_obj); char *fq_uri; LSUP_rc rc = LSUP_nsmap_normalize_uri ( ((NSMapObject *)self)->ob_struct, pfx_uri, &fq_uri); if (rc < 0) { PyErr_SetString (PyExc_ValueError, "Error denormalizing URI."); return NULL; } PyObject *uri_obj = PyUnicode_FromString (fq_uri); Py_INCREF (uri_obj); return (uri_obj); } static PyObject * NSMap_as_dict (PyObject *self) { const char ***data = LSUP_nsmap_dump (((NSMapObject *)self)->ob_struct); PyObject *data_obj = PyDict_New(); // TODO PyDictProxy_New(PyObject *mapping) for (size_t i = 0; data[i] != NULL; i++) { PyObject *val_obj = PyUnicode_FromString(data[i][1]); if (PyDict_SetItemString (data_obj, data[i][0], val_obj) < 0) return NULL; } Py_INCREF (data_obj); return data_obj; } static PyMethodDef NSMap_methods[] = { { "add", (PyCFunction) NSMap_add, METH_VARARGS, "Add a namespace prefix." }, { "remove", (PyCFunction) NSMap_remove, METH_O, "Remove a namespace prefix." }, { "get", (PyCFunction) NSMap_get, METH_O, "Get the fully qualified namespace for a prefix." }, { "normalize_uri", (PyCFunction) NSMap_normalize_uri, METH_O, "Normalize a URI (i.e. convert from prefixed to fully qualified)." }, { "denormalize_uri", (PyCFunction) NSMap_denormalize_uri, METH_O, "Denormalize a URI (i.e. convert from fully qualified to prefixed)." }, { "as_dict", (PyCFunction) NSMap_as_dict, METH_NOARGS, "Namespace map as a dictionary of prefixes and namespaces.", }, {NULL}, }; PyTypeObject NSMapType = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "namespace.NSMap", .tp_doc = "Namespace prefix map.", .tp_basicsize = sizeof(NSMapObject), .tp_itemsize = 0, .tp_flags = Py_TPFLAGS_DEFAULT, .tp_new = PyType_GenericNew, .tp_init = (initproc) NSMap_init, .tp_dealloc = (destructor) NSMap_dealloc, .tp_methods = NSMap_methods, }; #endif /* _PY_NAMESPACE_OBJ */