|
@@ -0,0 +1,189 @@
|
|
|
|
+#ifndef _PY_NAMESPACE_OBJ_H
|
|
|
|
+#define _PY_NAMESPACE_OBJ_H
|
|
|
|
+
|
|
|
|
+#define PY_SSIZE_T_CLEAN
|
|
|
|
+
|
|
|
|
+#include <Python.h>
|
|
|
|
+#include <structmember.h>
|
|
|
|
+
|
|
|
|
+#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 (((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_normalize_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_normalize_uri (
|
|
|
|
+ ((NSMapObject *)self)->ob_struct, fq_uri, &pfx_uri);
|
|
|
|
+ if (rc < 0) {
|
|
|
|
+ PyErr_SetString (PyExc_ValueError, "Error normalizing URI.");
|
|
|
|
+ return NULL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ PyObject *uri_obj = PyUnicode_FromString (pfx_uri);
|
|
|
|
+
|
|
|
|
+ Py_INCREF (uri_obj);
|
|
|
|
+ return (uri_obj);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+static PyObject *
|
|
|
|
+NSMap_denormalize_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_denormalize_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 fully qualified to prefixed)."
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ "denormalize_uri", (PyCFunction) NSMap_denormalize_uri, METH_O,
|
|
|
|
+ "Denormalize a URI (i.e. convert from prefixed to fully qualified)."
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ "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 */
|