1/* ----------------------------------------------------------------------------- 2 * See the LICENSE file for information on copyright, usage and redistribution 3 * of SWIG, and the README file for authors - http://www.swig.org/release.html. 4 * 5 * director.swg 6 * 7 * This file contains support for director classes that proxy 8 * method calls from C++ to Python extensions. 9 * ----------------------------------------------------------------------------- */ 10 11#ifndef SWIG_DIRECTOR_PYTHON_HEADER_ 12#define SWIG_DIRECTOR_PYTHON_HEADER_ 13 14#ifdef __cplusplus 15 16#include <string> 17#include <iostream> 18#include <exception> 19#include <vector> 20#include <map> 21 22 23/* 24 Use -DSWIG_PYTHON_DIRECTOR_NO_VTABLE if you don't want to generate a 'virtual 25 table', and avoid multiple GetAttr calls to retrieve the python 26 methods. 27*/ 28 29#ifndef SWIG_PYTHON_DIRECTOR_NO_VTABLE 30#ifndef SWIG_PYTHON_DIRECTOR_VTABLE 31#define SWIG_PYTHON_DIRECTOR_VTABLE 32#endif 33#endif 34 35 36 37/* 38 Use -DSWIG_DIRECTOR_NO_UEH if you prefer to avoid the use of the 39 Undefined Exception Handler provided by swift 40*/ 41#ifndef SWIG_DIRECTOR_NO_UEH 42#ifndef SWIG_DIRECTOR_UEH 43#define SWIG_DIRECTOR_UEH 44#endif 45#endif 46 47 48/* 49 Use -DSWIG_DIRECTOR_STATIC if you prefer to avoid the use of the 50 'Swig' namespace. This could be useful for multi-modules projects. 51*/ 52#ifdef SWIG_DIRECTOR_STATIC 53/* Force anonymous (static) namespace */ 54#define Swig 55#endif 56 57 58/* 59 Use -DSWIG_DIRECTOR_NORTTI if you prefer to avoid the use of the 60 native C++ RTTI and dynamic_cast<>. But be aware that directors 61 could stop working when using this option. 62*/ 63#ifdef SWIG_DIRECTOR_NORTTI 64/* 65 When we don't use the native C++ RTTI, we implement a minimal one 66 only for Directors. 67*/ 68# ifndef SWIG_DIRECTOR_RTDIR 69# define SWIG_DIRECTOR_RTDIR 70#include <map> 71 72namespace Swig { 73 class Director; 74 SWIGINTERN std::map<void*,Director*>& get_rtdir_map() { 75 static std::map<void*,Director*> rtdir_map; 76 return rtdir_map; 77 } 78 79 SWIGINTERNINLINE void set_rtdir(void *vptr, Director *rtdir) { 80 get_rtdir_map()[vptr] = rtdir; 81 } 82 83 SWIGINTERNINLINE Director *get_rtdir(void *vptr) { 84 std::map<void*,Director*>::const_iterator pos = get_rtdir_map().find(vptr); 85 Director *rtdir = (pos != get_rtdir_map().end()) ? pos->second : 0; 86 return rtdir; 87 } 88} 89# endif /* SWIG_DIRECTOR_RTDIR */ 90 91# define SWIG_DIRECTOR_CAST(Arg) Swig::get_rtdir(static_cast<void*>(Arg)) 92# define SWIG_DIRECTOR_RGTR(Arg1, Arg2) Swig::set_rtdir(static_cast<void*>(Arg1), Arg2) 93 94#else 95 96# define SWIG_DIRECTOR_CAST(Arg) dynamic_cast<Swig::Director*>(Arg) 97# define SWIG_DIRECTOR_RGTR(Arg1, Arg2) 98 99#endif /* SWIG_DIRECTOR_NORTTI */ 100 101extern "C" { 102 struct swig_type_info; 103} 104 105namespace Swig { 106 107 /* memory handler */ 108 struct GCItem 109 { 110 virtual ~GCItem() {} 111 112 virtual int get_own() const 113 { 114 return 0; 115 } 116 }; 117 118 struct GCItem_var 119 { 120 GCItem_var(GCItem *item = 0) : _item(item) 121 { 122 } 123 124 GCItem_var& operator=(GCItem *item) 125 { 126 GCItem *tmp = _item; 127 _item = item; 128 delete tmp; 129 return *this; 130 } 131 132 ~GCItem_var() 133 { 134 delete _item; 135 } 136 137 GCItem * operator->() const 138 { 139 return _item; 140 } 141 142 private: 143 GCItem *_item; 144 }; 145 146 struct GCItem_Object : GCItem 147 { 148 GCItem_Object(int own) : _own(own) 149 { 150 } 151 152 virtual ~GCItem_Object() 153 { 154 } 155 156 int get_own() const 157 { 158 return _own; 159 } 160 161 private: 162 int _own; 163 }; 164 165 template <typename Type> 166 struct GCItem_T : GCItem 167 { 168 GCItem_T(Type *ptr) : _ptr(ptr) 169 { 170 } 171 172 virtual ~GCItem_T() 173 { 174 delete _ptr; 175 } 176 177 private: 178 Type *_ptr; 179 }; 180 181 template <typename Type> 182 struct GCArray_T : GCItem 183 { 184 GCArray_T(Type *ptr) : _ptr(ptr) 185 { 186 } 187 188 virtual ~GCArray_T() 189 { 190 delete[] _ptr; 191 } 192 193 private: 194 Type *_ptr; 195 }; 196 197 /* base class for director exceptions */ 198 class DirectorException { 199 protected: 200 std::string swig_msg; 201 public: 202 DirectorException(PyObject *error, const char* hdr ="", const char* msg ="") 203 : swig_msg(hdr) 204 { 205 SWIG_PYTHON_THREAD_BEGIN_BLOCK; 206 if (strlen(msg)) { 207 swig_msg += " "; 208 swig_msg += msg; 209 } 210 if (!PyErr_Occurred()) { 211 PyErr_SetString(error, getMessage()); 212 } 213 SWIG_PYTHON_THREAD_END_BLOCK; 214 } 215 216 const char *getMessage() const 217 { 218 return swig_msg.c_str(); 219 } 220 221 static void raise(PyObject *error, const char *msg) 222 { 223 throw DirectorException(error, msg); 224 } 225 226 static void raise(const char *msg) 227 { 228 raise(PyExc_RuntimeError, msg); 229 } 230 }; 231 232 /* unknown exception handler */ 233 class UnknownExceptionHandler 234 { 235#ifdef SWIG_DIRECTOR_UEH 236 static void handler() { 237 try { 238 throw; 239 } catch (DirectorException& e) { 240 std::cerr << "Swig Director exception caught:" << std::endl 241 << e.getMessage() << std::endl; 242 } catch (std::exception& e) { 243 std::cerr << "std::exception caught: "<< e.what() << std::endl; 244 } catch (...) { 245 std::cerr << "Unknown exception caught." << std::endl; 246 } 247 248 std::cerr << std::endl 249 << "Python interpreter traceback:" << std::endl; 250 PyErr_Print(); 251 std::cerr << std::endl; 252 253 std::cerr << "This exception was caught by the SWIG unexpected exception handler." << std::endl 254 << "Try using %feature(\"director:except\") to avoid reaching this point." << std::endl 255 << std::endl 256 << "Exception is being re-thrown, program will like abort/terminate." << std::endl; 257 throw; 258 } 259 260 public: 261 262 std::unexpected_handler old; 263 UnknownExceptionHandler(std::unexpected_handler nh = handler) 264 { 265 old = std::set_unexpected(nh); 266 } 267 268 ~UnknownExceptionHandler() 269 { 270 std::set_unexpected(old); 271 } 272#endif 273 }; 274 275 /* type mismatch in the return value from a python method call */ 276 class DirectorTypeMismatchException : public Swig::DirectorException { 277 public: 278 DirectorTypeMismatchException(PyObject *error, const char* msg="") 279 : Swig::DirectorException(error, "Swig director type mismatch", msg) 280 { 281 } 282 283 DirectorTypeMismatchException(const char* msg="") 284 : Swig::DirectorException(PyExc_TypeError, "Swig director type mismatch", msg) 285 { 286 } 287 288 static void raise(PyObject *error, const char *msg) 289 { 290 throw DirectorTypeMismatchException(error, msg); 291 } 292 293 static void raise(const char *msg) 294 { 295 throw DirectorTypeMismatchException(msg); 296 } 297 }; 298 299 /* any python exception that occurs during a director method call */ 300 class DirectorMethodException : public Swig::DirectorException { 301 public: 302 DirectorMethodException(const char* msg = "") 303 : DirectorException(PyExc_RuntimeError, "Swig director method error.", msg) 304 { 305 } 306 307 static void raise(const char *msg) 308 { 309 throw DirectorMethodException(msg); 310 } 311 }; 312 313 /* attempt to call a pure virtual method via a director method */ 314 class DirectorPureVirtualException : public Swig::DirectorException 315 { 316 public: 317 DirectorPureVirtualException(const char* msg = "") 318 : DirectorException(PyExc_RuntimeError, "Swig director pure virtual method called", msg) 319 { 320 } 321 322 static void raise(const char *msg) 323 { 324 throw DirectorPureVirtualException(msg); 325 } 326 }; 327 328 329#if defined(SWIG_PYTHON_THREADS) 330/* __THREAD__ is the old macro to activate some thread support */ 331# if !defined(__THREAD__) 332# define __THREAD__ 1 333# endif 334#endif 335 336#ifdef __THREAD__ 337# include "pythread.h" 338 class Guard 339 { 340 PyThread_type_lock & mutex_; 341 342 public: 343 Guard(PyThread_type_lock & mutex) : mutex_(mutex) 344 { 345 PyThread_acquire_lock(mutex_, WAIT_LOCK); 346 } 347 348 ~Guard() 349 { 350 PyThread_release_lock(mutex_); 351 } 352 }; 353# define SWIG_GUARD(mutex) Guard _guard(mutex) 354#else 355# define SWIG_GUARD(mutex) 356#endif 357 358 /* director base class */ 359 class Director { 360 private: 361 /* pointer to the wrapped python object */ 362 PyObject* swig_self; 363 /* flag indicating whether the object is owned by python or c++ */ 364 mutable bool swig_disown_flag; 365 366 /* decrement the reference count of the wrapped python object */ 367 void swig_decref() const { 368 if (swig_disown_flag) { 369 SWIG_PYTHON_THREAD_BEGIN_BLOCK; 370 Py_DECREF(swig_self); 371 SWIG_PYTHON_THREAD_END_BLOCK; 372 } 373 } 374 375 public: 376 /* wrap a python object, optionally taking ownership */ 377 Director(PyObject* self) : swig_self(self), swig_disown_flag(false) { 378 swig_incref(); 379 } 380 381 382 /* discard our reference at destruction */ 383 virtual ~Director() { 384 swig_decref(); 385 } 386 387 388 /* return a pointer to the wrapped python object */ 389 PyObject *swig_get_self() const { 390 return swig_self; 391 } 392 393 /* acquire ownership of the wrapped python object (the sense of "disown" 394 * is from python) */ 395 void swig_disown() const { 396 if (!swig_disown_flag) { 397 swig_disown_flag=true; 398 swig_incref(); 399 } 400 } 401 402 /* increase the reference count of the wrapped python object */ 403 void swig_incref() const { 404 if (swig_disown_flag) { 405 Py_INCREF(swig_self); 406 } 407 } 408 409 /* methods to implement pseudo protected director members */ 410 virtual bool swig_get_inner(const char* /* name */) const { 411 return true; 412 } 413 414 virtual void swig_set_inner(const char* /* name */, bool /* val */) const { 415 } 416 417 /* ownership management */ 418 private: 419 typedef std::map<void*, GCItem_var> ownership_map; 420 mutable ownership_map owner; 421#ifdef __THREAD__ 422 static PyThread_type_lock swig_mutex_own; 423#endif 424 425 public: 426 template <typename Type> 427 void swig_acquire_ownership_array(Type *vptr) const 428 { 429 if (vptr) { 430 SWIG_GUARD(swig_mutex_own); 431 owner[vptr] = new GCArray_T<Type>(vptr); 432 } 433 } 434 435 template <typename Type> 436 void swig_acquire_ownership(Type *vptr) const 437 { 438 if (vptr) { 439 SWIG_GUARD(swig_mutex_own); 440 owner[vptr] = new GCItem_T<Type>(vptr); 441 } 442 } 443 444 void swig_acquire_ownership_obj(void *vptr, int own) const 445 { 446 if (vptr && own) { 447 SWIG_GUARD(swig_mutex_own); 448 owner[vptr] = new GCItem_Object(own); 449 } 450 } 451 452 int swig_release_ownership(void *vptr) const 453 { 454 int own = 0; 455 if (vptr) { 456 SWIG_GUARD(swig_mutex_own); 457 ownership_map::iterator iter = owner.find(vptr); 458 if (iter != owner.end()) { 459 own = iter->second->get_own(); 460 owner.erase(iter); 461 } 462 } 463 return own; 464 } 465 }; 466 467#ifdef __THREAD__ 468 PyThread_type_lock Director::swig_mutex_own = PyThread_allocate_lock(); 469#endif 470} 471 472#endif /* __cplusplus */ 473 474 475#endif 476