summaryrefslogtreecommitdiff
path: root/python/generic.h
diff options
context:
space:
mode:
authorJulian Andres Klode <jak@debian.org>2013-10-08 17:36:16 +0200
committerJulian Andres Klode <jak@debian.org>2013-10-08 17:39:59 +0200
commit7c03e56db77a3ae69f3710f588342a6e1fde2250 (patch)
tree019dbc2d5a84bc378b77ec68bc1dadaca9905364 /python/generic.h
parentaf280830c12f4e29862733a8155e87985d57c574 (diff)
downloadpython-apt-7c03e56db77a3ae69f3710f588342a6e1fde2250.tar.gz
python/generic.h: Introduce a PyApt_Filename class
On Python 3, we need to encode filenames. We could use PyUnicode_FSConverter but this introduces unneeded complexity in all callees, and is only available in Python 3.1 anyway.
Diffstat (limited to 'python/generic.h')
-rw-r--r--python/generic.h60
1 files changed, 60 insertions, 0 deletions
diff --git a/python/generic.h b/python/generic.h
index e4679c6c..97806e17 100644
--- a/python/generic.h
+++ b/python/generic.h
@@ -251,4 +251,64 @@ inline PyObject *MkPyNumber(double o) { return PyFloat_FromDouble(o); }
# define _PyAptObject_getattro 0
+
+/**
+ * Magic class for file name handling
+ *
+ * This manages decoding file names from Python objects; bytes and unicode
+ * objects. On Python 2, this does the same conversion as PyObject_AsString,
+ * on Python3, it uses PyUnicode_EncodeFSDefault for unicode objects.
+ */
+class PyApt_Filename {
+public:
+ PyObject *object;
+ const char *path;
+
+ PyApt_Filename() {
+ object = NULL;
+ path = NULL;
+ }
+
+ int init(PyObject *object) {
+ this->object = NULL;
+ this->path = NULL;
+
+#if PY_MAJOR_VERSION < 3 || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 2)
+ this->path = PyObject_AsString(object);
+ return this->path ? 1 : 0;
+#else
+ if (PyUnicode_Check(object)) {
+ object = PyUnicode_EncodeFSDefault(object);
+ } else if (PyBytes_Check(object)) {
+ Py_INCREF(object);
+ } else {
+ return 0;
+ }
+
+ this->object = object;
+ this->path = PyBytes_AS_STRING(this->object);
+ return 1;
+#endif
+ }
+
+ ~PyApt_Filename() {
+ Py_XDECREF(object);
+ }
+
+ static int Converter(PyObject *object, void *out) {
+ return static_cast<PyApt_Filename *>(out)->init(object);
+ }
+
+ operator const char *() {
+ return path;
+ }
+ operator const std::string() {
+ return path;
+ }
+
+ void operator=(const char *path) {
+ this->path = path;
+ }
+};
+
#endif