|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef GENERIC_H |
|
#define GENERIC_H |
|
|
|
#include <Python.h> |
|
#include <string> |
|
#include <iostream> |
|
#include <new> |
|
#include <langinfo.h> |
|
|
|
|
|
|
|
|
|
extern PyObject *PyAptError; |
|
|
|
|
|
|
|
extern PyObject *PyAptCacheMismatchError; |
|
|
|
#if PYTHON_API_VERSION < 1013 |
|
typedef int Py_ssize_t; |
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if PY_MAJOR_VERSION >= 3 |
|
#define PyString_Check PyUnicode_Check |
|
#define PyString_FromString PyUnicode_FromString |
|
#define PyString_FromStringAndSize PyUnicode_FromStringAndSize |
|
#define PyString_AsString PyUnicode_AsString |
|
#define PyString_FromFormat PyUnicode_FromFormat |
|
#define PyString_Type PyUnicode_Type |
|
#define PyInt_Check PyLong_Check |
|
#define PyInt_AsLong PyLong_AsLong |
|
#define PyInt_FromLong PyLong_FromLong |
|
#endif |
|
|
|
static inline const char *PyUnicode_AsString(PyObject *op) { |
|
|
|
#if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3 |
|
return PyUnicode_AsUTF8(op); |
|
#else |
|
|
|
|
|
PyObject *bytes = _PyUnicode_AsDefaultEncodedString(op, 0); |
|
return bytes ? PyBytes_AS_STRING(bytes) : 0; |
|
#endif |
|
} |
|
|
|
|
|
#if PY_MAJOR_VERSION < 3 |
|
static inline const char *PyObject_AsString(PyObject *object) { |
|
if (PyBytes_Check(object)) |
|
return PyBytes_AsString(object); |
|
else if (PyUnicode_Check(object)) |
|
return PyUnicode_AsString(object); |
|
else |
|
PyErr_SetString(PyExc_TypeError, "Argument must be str."); |
|
return 0; |
|
} |
|
#else |
|
static inline const char *PyObject_AsString(PyObject *object) { |
|
if (PyUnicode_Check(object) == 0) { |
|
PyErr_SetString(PyExc_TypeError, "Argument must be str."); |
|
return 0; |
|
} |
|
return PyUnicode_AsString(object); |
|
} |
|
#endif |
|
|
|
template <class T> struct CppPyObject : public PyObject |
|
{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CppPyObject() { }; |
|
|
|
|
|
|
|
PyObject *Owner; |
|
|
|
|
|
bool NoDelete; |
|
|
|
|
|
T Object; |
|
}; |
|
|
|
template <class T> |
|
inline T &GetCpp(PyObject *Obj) |
|
{ |
|
return ((CppPyObject<T> *)Obj)->Object; |
|
} |
|
|
|
template <class T> |
|
inline PyObject *GetOwner(PyObject *Obj) |
|
{ |
|
return ((CppPyObject<T> *)Obj)->Owner; |
|
} |
|
|
|
|
|
template <class T> |
|
inline CppPyObject<T> *CppPyObject_NEW(PyObject *Owner,PyTypeObject *Type) |
|
{ |
|
#ifdef ALLOC_DEBUG |
|
std::cerr << "=== ALLOCATING " << Type->tp_name << "+ ===\n"; |
|
#endif |
|
CppPyObject<T> *New = (CppPyObject<T>*)Type->tp_alloc(Type, 0); |
|
new (&New->Object) T; |
|
New->Owner = Owner; |
|
Py_XINCREF(Owner); |
|
return New; |
|
} |
|
|
|
template <class T,class A> |
|
inline CppPyObject<T> *CppPyObject_NEW(PyObject *Owner, PyTypeObject *Type,A const &Arg) |
|
{ |
|
#ifdef ALLOC_DEBUG |
|
std::cerr << "=== ALLOCATING " << Type->tp_name << "+ ===\n"; |
|
#endif |
|
CppPyObject<T> *New = (CppPyObject<T>*)Type->tp_alloc(Type, 0); |
|
new (&New->Object) T(Arg); |
|
New->Owner = Owner; |
|
Py_XINCREF(Owner); |
|
return New; |
|
} |
|
|
|
|
|
template <class T> |
|
int CppTraverse(PyObject *self, visitproc visit, void* arg) { |
|
Py_VISIT(((CppPyObject<T> *)self)->Owner); |
|
return 0; |
|
} |
|
|
|
template <class T> |
|
int CppClear(PyObject *self) { |
|
Py_CLEAR(((CppPyObject<T> *)self)->Owner); |
|
return 0; |
|
} |
|
|
|
template <class T> |
|
void CppDealloc(PyObject *iObj) |
|
{ |
|
#ifdef ALLOC_DEBUG |
|
std::cerr << "=== DEALLOCATING " << iObj->ob_type->tp_name << "+ ===\n"; |
|
#endif |
|
CppPyObject<T> *Obj = (CppPyObject<T> *)iObj; |
|
if (!((CppPyObject<T>*)Obj)->NoDelete) |
|
Obj->Object.~T(); |
|
CppClear<T>(iObj); |
|
iObj->ob_type->tp_free(iObj); |
|
} |
|
|
|
|
|
template <class T> |
|
void CppDeallocPtr(PyObject *iObj) |
|
{ |
|
#ifdef ALLOC_DEBUG |
|
std::cerr << "=== DEALLOCATING " << iObj->ob_type->tp_name << "*+ ===\n"; |
|
#endif |
|
CppPyObject<T> *Obj = (CppPyObject<T> *)iObj; |
|
if (!((CppPyObject<T>*)Obj)->NoDelete) { |
|
delete Obj->Object; |
|
Obj->Object = NULL; |
|
} |
|
CppClear<T>(iObj); |
|
iObj->ob_type->tp_free(iObj); |
|
} |
|
|
|
inline PyObject *CppPyString(const std::string &Str) |
|
{ |
|
return PyString_FromStringAndSize(Str.c_str(),Str.length()); |
|
} |
|
|
|
inline PyObject *CppPyString(const char *Str) |
|
{ |
|
if (Str == 0) |
|
return PyString_FromString(""); |
|
return PyString_FromString(Str); |
|
} |
|
|
|
inline PyObject *CppPyLocaleString(const std::string &Str) |
|
{ |
|
char const * const codeset = nl_langinfo(CODESET); |
|
return PyUnicode_Decode(Str.c_str(), Str.length(), codeset, "replace"); |
|
} |
|
|
|
#if PY_MAJOR_VERSION >= 3 |
|
static inline PyObject *CppPyPath(const std::string &path) |
|
{ |
|
return PyUnicode_DecodeFSDefaultAndSize(path.c_str(), path.length()); |
|
} |
|
|
|
static inline PyObject *CppPyPath(const char *path) |
|
{ |
|
if (path == nullptr) |
|
path = ""; |
|
return PyUnicode_DecodeFSDefault(path); |
|
} |
|
#else |
|
template<typename T> static inline PyObject *CppPyPath(T path) { |
|
return CppPyString(path); |
|
} |
|
#endif |
|
|
|
|
|
PyObject *HandleErrors(PyObject *Res = 0); |
|
|
|
|
|
const char **ListToCharChar(PyObject *List,bool NullTerm = false); |
|
PyObject *CharCharToList(const char **List,unsigned long Size = 0); |
|
|
|
|
|
inline PyObject *MkPyNumber(unsigned long long o) { return PyLong_FromUnsignedLongLong(o); } |
|
inline PyObject *MkPyNumber(unsigned long o) { return PyLong_FromUnsignedLong(o); } |
|
inline PyObject *MkPyNumber(unsigned int o) { return PyLong_FromUnsignedLong(o); } |
|
inline PyObject *MkPyNumber(unsigned short o) { return PyInt_FromLong(o); } |
|
inline PyObject *MkPyNumber(unsigned char o) { return PyInt_FromLong(o); } |
|
|
|
inline PyObject *MkPyNumber(long long o) { return PyLong_FromLongLong(o); } |
|
inline PyObject *MkPyNumber(long o) { return PyInt_FromLong(o); } |
|
inline PyObject *MkPyNumber(int o) { return PyInt_FromLong(o); } |
|
inline PyObject *MkPyNumber(short o) { return PyInt_FromLong(o); } |
|
inline PyObject *MkPyNumber(signed char o) { return PyInt_FromLong(o); } |
|
|
|
inline PyObject *MkPyNumber(double o) { return PyFloat_FromDouble(o); } |
|
|
|
# define _PyAptObject_getattro 0 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class PyApt_Filename { |
|
public: |
|
PyObject *object; |
|
const char *path; |
|
|
|
PyApt_Filename() { |
|
object = NULL; |
|
path = NULL; |
|
} |
|
|
|
int init(PyObject *object); |
|
|
|
~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; |
|
} |
|
|
|
const char *operator=(const char *path) { |
|
return this->path = path; |
|
} |
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template <class T, bool clear=true> struct PyApt_UniqueObject { |
|
T *self; |
|
explicit PyApt_UniqueObject(T *self) : self(self) { } |
|
~PyApt_UniqueObject() { reset(NULL); } |
|
void reset(T *newself) { if (clear && self && Py_TYPE(self)->tp_clear) Py_TYPE(self)->tp_clear(self); Py_XDECREF(self); self = newself; } |
|
PyApt_UniqueObject<T> operator =(PyApt_UniqueObject<T>) = delete; |
|
bool operator ==(void *other) { return self == other; } |
|
T *operator ->() { return self; } |
|
T *get() { return self; } |
|
T *release() { T *ret = self; self = NULL; return ret; } |
|
}; |
|
#endif |
|
|