kodi
swig.h
1 /*
2  * Copyright (C) 2005-2018 Team Kodi
3  * This file is part of Kodi - https://kodi.tv
4  *
5  * SPDX-License-Identifier: GPL-2.0-or-later
6  * See LICENSES/README.md for more information.
7  */
8 
9 #pragma once
10 
11 #include "interfaces/legacy/AddonClass.h"
12 #include "interfaces/legacy/Exception.h"
13 #include "interfaces/legacy/Window.h"
14 
15 #include <stdint.h>
16 #include <string>
17 #include <typeindex>
18 
19 #include <Python.h>
20 
21 namespace PythonBindings
22 {
33  void PyXBMCGetUnicodeString(std::string& buf, PyObject* pObject, bool coerceToString = false,
34  const char* pos = "unknown",
35  const char* methodname = "unknown");
36 
37  struct TypeInfo
38  {
39  const char* swigType;
40  TypeInfo* parentType;
41  PyTypeObject pythonType;
42  const std::type_index typeIndex;
43 
44  explicit TypeInfo(const std::type_info& ti);
45  };
46 
47  // This will hold the pointer to the api type, whether known or unknown
48  struct PyHolder
49  {
50  PyObject_HEAD
51  int32_t magicNumber;
52  const TypeInfo* typeInfo;
53  XBMCAddon::AddonClass* pSelf;
54  };
55 
56 #define XBMC_PYTHON_TYPE_MAGIC_NUMBER 0x58626D63
57 
64  inline XBMCAddon::AddonClass* retrieveApiInstance(PyObject* pythonObj, const TypeInfo* typeToCheck,
65  const char* methodNameForErrorString,
66  const char* typenameForErrorString)
67  {
68  if (pythonObj == NULL || pythonObj == Py_None)
69  return NULL;
70  if (reinterpret_cast<PyHolder*>(pythonObj)->magicNumber != XBMC_PYTHON_TYPE_MAGIC_NUMBER || !PyObject_TypeCheck(pythonObj, const_cast<PyTypeObject*>((&(typeToCheck->pythonType)))))
71  throw XBMCAddon::WrongTypeException("Incorrect type passed to \"%s\", was expecting a \"%s\".",methodNameForErrorString,typenameForErrorString);
72  return reinterpret_cast<PyHolder*>(pythonObj)->pSelf;
73  }
74 
75  bool isParameterRightType(const char* passedType, const char* expectedType, const char* methodNamespacePrefix, bool tryReverse = true);
76 
77  XBMCAddon::AddonClass* doretrieveApiInstance(const PyHolder* pythonObj, const TypeInfo* typeInfo, const char* expectedType,
78  const char* methodNamespacePrefix, const char* methodNameForErrorString);
79 
89  inline XBMCAddon::AddonClass* retrieveApiInstance(const PyObject* pythonObj, const char* expectedType, const char* methodNamespacePrefix,
90  const char* methodNameForErrorString)
91  {
92  return (pythonObj == NULL || pythonObj == Py_None) ? NULL :
93  doretrieveApiInstance(reinterpret_cast<const PyHolder*>(pythonObj),reinterpret_cast<const PyHolder*>(pythonObj)->typeInfo, expectedType, methodNamespacePrefix, methodNameForErrorString);
94  }
95 
100  void prepareForReturn(XBMCAddon::AddonClass* c);
101 
106  void cleanForDealloc(XBMCAddon::AddonClass* c);
107 
116  void cleanForDealloc(XBMCAddon::xbmcgui::Window* c);
117 
130  PyObject* makePythonInstance(XBMCAddon::AddonClass* api, PyTypeObject* pythonType, bool incrementRefCount);
131 
141  inline PyObject* makePythonInstance(XBMCAddon::AddonClass* api, bool incrementRefCount)
142  {
143  return makePythonInstance(api,NULL,incrementRefCount);
144  }
145 
146  void registerAddonClassTypeInformation(const TypeInfo* classInfo);
147  const TypeInfo* getTypeInfoForInstance(XBMCAddon::AddonClass* obj);
148 
149  int dummy_tp_init(PyObject* self, PyObject* args, PyObject* kwds);
150 
151  class Director
152  {
153  protected:
154  PyObject* self;
155  public:
156  inline Director() : self(NULL) {}
157  inline void setPyObjectForDirector(PyObject* pyargself) { self = pyargself; }
158  };
159 
164  class PythonToCppException : public XbmcCommons::UncheckedException
165  {
166  public:
173  PythonToCppException(const std::string &exceptionType, const std::string &exceptionValue, const std::string &exceptionTraceback);
174 
175  static bool ParsePythonException(std::string &exceptionType, std::string &exceptionValue, std::string &exceptionTraceback);
176 
177  protected:
178  void SetMessage(const std::string &exceptionType, const std::string &exceptionValue, const std::string &exceptionTraceback);
179  };
180 
181  template<class T> struct PythonCompare
182  {
183  static inline int compare(PyObject* obj1, PyObject* obj2, const char* swigType, const char* methodNamespacePrefix, const char* methodNameForErrorString)
184  {
185  XBMC_TRACE;
186  try
187  {
188  T* o1 = (T*)retrieveApiInstance(obj1, swigType, methodNamespacePrefix, methodNameForErrorString);
189  T* o2 = (T*)retrieveApiInstance(obj2, swigType, methodNamespacePrefix, methodNameForErrorString);
190 
191  return ((*o1) < (*o2) ? -1 :
192  ((*o1) > (*o2) ? 1 : 0));
193  }
194  catch (const XBMCAddon::WrongTypeException& e)
195  {
196  CLog::Log(LOGERROR, "EXCEPTION: {}", e.GetExMessage());
197  PyErr_SetString(PyExc_RuntimeError, e.GetExMessage());
198  }
199  return -1;
200  }
201  };
202 }
Definition: swig.h:37
Definition: swig.h:181
Definition: AddonPythonInvoker.cpp:76
Definition: swig.h:151
Definition: swig.h:48
Definition: LibInputPointer.h:13
Definition: Window.h:186
This exception is thrown from Director calls that call into python when the Python error is...
Definition: swig.h:164
This class is the superclass for all reference counted classes in the api.
Definition: AddonClass.h:57