director.swg 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /* -----------------------------------------------------------------------------
  2. * director.swg
  3. *
  4. * This file contains support for director classes so that PHP proxy
  5. * methods can be called from C++.
  6. * ----------------------------------------------------------------------------- */
  7. #ifndef SWIG_DIRECTOR_PHP_HEADER_
  8. #define SWIG_DIRECTOR_PHP_HEADER_
  9. #include <string>
  10. #include <exception>
  11. #include <map>
  12. namespace Swig {
  13. /* memory handler */
  14. struct GCItem {
  15. virtual ~GCItem() {
  16. }
  17. virtual int get_own() const {
  18. return 0;
  19. }
  20. };
  21. struct GCItem_var {
  22. GCItem_var(GCItem *item = 0) : _item(item) {
  23. }
  24. GCItem_var& operator=(GCItem *item) {
  25. GCItem *tmp = _item;
  26. _item = item;
  27. delete tmp;
  28. return *this;
  29. }
  30. ~GCItem_var() {
  31. delete _item;
  32. }
  33. GCItem * operator->() const {
  34. return _item;
  35. }
  36. private:
  37. GCItem *_item;
  38. };
  39. struct GCItem_Object : GCItem {
  40. GCItem_Object(int own) : _own(own) {
  41. }
  42. virtual ~GCItem_Object() {
  43. }
  44. int get_own() const {
  45. return _own;
  46. }
  47. private:
  48. int _own;
  49. };
  50. template <typename Type>
  51. struct GCItem_T : GCItem {
  52. GCItem_T(Type *ptr) : _ptr(ptr) {
  53. }
  54. virtual ~GCItem_T() {
  55. delete _ptr;
  56. }
  57. private:
  58. Type *_ptr;
  59. };
  60. class Director {
  61. protected:
  62. zval *swig_self;
  63. typedef std::map<void *, GCItem_var> swig_ownership_map;
  64. mutable swig_ownership_map swig_owner;
  65. #ifdef ZTS
  66. // Store the ZTS context so it's available when C++ calls back to PHP.
  67. void *** swig_zts_ctx;
  68. #endif
  69. public:
  70. Director(zval *self TSRMLS_DC) : swig_self(self) {
  71. TSRMLS_SET_CTX(swig_zts_ctx);
  72. }
  73. static bool swig_is_overridden_method(char *cname, char *lc_fname TSRMLS_DC) {
  74. zend_class_entry **ce;
  75. zend_function *mptr;
  76. if (zend_lookup_class(cname, strlen(cname), &ce TSRMLS_CC) != SUCCESS) {
  77. return false;
  78. }
  79. if (zend_hash_find(&(*ce)->function_table, lc_fname, strlen(lc_fname) + 1, (void **) &mptr) != SUCCESS) {
  80. return false;
  81. }
  82. // common.scope points to the declaring class
  83. return strcmp(mptr->common.scope->name, cname);
  84. }
  85. template <typename Type>
  86. void swig_acquire_ownership(Type *vptr) const {
  87. if (vptr) {
  88. swig_owner[vptr] = new GCItem_T<Type>(vptr);
  89. }
  90. }
  91. };
  92. /* base class for director exceptions */
  93. class DirectorException : public std::exception {
  94. protected:
  95. std::string swig_msg;
  96. public:
  97. DirectorException(int code, const char *hdr, const char *msg TSRMLS_DC) : swig_msg(hdr) {
  98. if (msg[0]) {
  99. swig_msg += " ";
  100. swig_msg += msg;
  101. }
  102. SWIG_ErrorCode() = code;
  103. SWIG_ErrorMsg() = swig_msg.c_str();
  104. }
  105. virtual ~DirectorException() throw() {
  106. }
  107. const char *what() const throw() {
  108. return swig_msg.c_str();
  109. }
  110. static void raise(int code, const char *hdr, const char *msg TSRMLS_DC) {
  111. throw DirectorException(code, hdr, msg TSRMLS_CC);
  112. }
  113. };
  114. /* attempt to call a pure virtual method via a director method */
  115. class DirectorPureVirtualException : public DirectorException {
  116. public:
  117. DirectorPureVirtualException(const char *msg TSRMLS_DC)
  118. : DirectorException(E_ERROR, "SWIG director pure virtual method called", msg TSRMLS_CC) {
  119. }
  120. static void raise(const char *msg TSRMLS_DC) {
  121. throw DirectorPureVirtualException(msg TSRMLS_CC);
  122. }
  123. };
  124. /* any php exception that occurs during a director method call */
  125. class DirectorMethodException : public DirectorException
  126. {
  127. public:
  128. DirectorMethodException(const char *msg TSRMLS_DC)
  129. : DirectorException(E_ERROR, "SWIG director method error", msg TSRMLS_CC) {
  130. }
  131. static void raise(const char *msg TSRMLS_DC) {
  132. throw DirectorMethodException(msg TSRMLS_CC);
  133. }
  134. };
  135. }
  136. // DirectorMethodException() is documented to be callable with no parameters
  137. // so use a macro to insert TSRMLS_CC so any ZTS context gets passed.
  138. #define DirectorMethodException() DirectorMethodException("" TSRMLS_CC)
  139. #endif