1 /* ----------------------------------------------------------------------------- 2 * director.swg 3 * 4 * This file contains support for director classes that proxy 5 * method calls from C++ to PHP extensions. 6 * ----------------------------------------------------------------------------- */ 7 8 #ifndef SWIG_DIRECTOR_PHP_HEADER_ 9 #define SWIG_DIRECTOR_PHP_HEADER_ 10 11 #ifdef __cplusplus 12 13 #include <string> 14 #include <map> 15 16 /* 17 Use -DSWIG_DIRECTOR_STATIC if you prefer to avoid the use of the 18 'Swig' namespace. This could be useful for multi-modules projects. 19 */ 20 #ifdef SWIG_DIRECTOR_STATIC 21 /* Force anonymous (static) namespace */ 22 #define Swig 23 #endif 24 25 namespace Swig { 26 /* memory handler */ 27 struct GCItem 28 { 29 virtual ~GCItem() {} 30 31 virtual int get_own() const 32 { 33 return 0; 34 } 35 }; 36 37 struct GCItem_var 38 { 39 GCItem_var(GCItem *item = 0) : _item(item) 40 { 41 } 42 43 GCItem_var& operator=(GCItem *item) 44 { 45 GCItem *tmp = _item; 46 _item = item; 47 delete tmp; 48 return *this; 49 } 50 51 ~GCItem_var() 52 { 53 delete _item; 54 } 55 56 GCItem * operator->() const 57 { 58 return _item; 59 } 60 61 private: 62 GCItem *_item; 63 }; 64 65 struct GCItem_Object : GCItem 66 { 67 GCItem_Object(int own) : _own(own) 68 { 69 } 70 71 virtual ~GCItem_Object() 72 { 73 } 74 75 int get_own() const 76 { 77 return _own; 78 } 79 80 private: 81 int _own; 82 }; 83 84 template <typename Type> 85 struct GCItem_T : GCItem 86 { 87 GCItem_T(Type *ptr) : _ptr(ptr) 88 { 89 } 90 91 virtual ~GCItem_T() 92 { 93 delete _ptr; 94 } 95 96 private: 97 Type *_ptr; 98 }; 99 100 class Director { 101 protected: 102 zval *swig_self; 103 typedef std::map<void*, GCItem_var> swig_ownership_map; 104 mutable swig_ownership_map swig_owner; 105 #ifdef ZTS 106 // Store the ZTS context so it's available when C++ calls back to PHP. 107 void *** swig_zts_ctx; 108 #endif 109 public: 110 Director(zval* self TSRMLS_DC) : swig_self(self) { 111 TSRMLS_SET_CTX(swig_zts_ctx); 112 } 113 114 bool swig_is_overridden_method(char *cname, char *lc_fname) { 115 TSRMLS_FETCH_FROM_CTX(swig_zts_ctx); 116 zend_class_entry **ce; 117 zend_function *mptr; 118 int name_len = strlen(lc_fname); 119 120 if (zend_lookup_class(cname, strlen(cname), &ce TSRMLS_CC) != SUCCESS) { 121 return false; 122 } 123 if (zend_hash_find(&(*ce)->function_table, lc_fname, name_len + 1, (void**) &mptr) != SUCCESS) { 124 return false; 125 } 126 // common.scope points to the declaring class 127 return strcmp(mptr->common.scope->name, cname); 128 } 129 130 template <typename Type> 131 void swig_acquire_ownership(Type *vptr) const 132 { 133 if (vptr) { 134 swig_owner[vptr] = new GCItem_T<Type>(vptr); 135 } 136 } 137 }; 138 139 /* base class for director exceptions */ 140 class DirectorException { 141 protected: 142 std::string swig_msg; 143 public: 144 DirectorException(int code, const char *hdr, const char* msg TSRMLS_DC) 145 : swig_msg(hdr) 146 { 147 if (strlen(msg)) { 148 swig_msg += " "; 149 swig_msg += msg; 150 } 151 SWIG_ErrorCode() = code; 152 SWIG_ErrorMsg() = swig_msg.c_str(); 153 } 154 155 static void raise(int code, const char *hdr, const char* msg TSRMLS_DC) 156 { 157 throw DirectorException(code, hdr, msg TSRMLS_CC); 158 } 159 }; 160 161 /* attempt to call a pure virtual method via a director method */ 162 class DirectorPureVirtualException : public Swig::DirectorException 163 { 164 public: 165 DirectorPureVirtualException(const char* msg TSRMLS_DC) 166 : DirectorException(E_ERROR, "SWIG director pure virtual method called", msg TSRMLS_CC) 167 { 168 } 169 170 static void raise(const char *msg TSRMLS_DC) 171 { 172 throw DirectorPureVirtualException(msg TSRMLS_CC); 173 } 174 }; 175 /* any php exception that occurs during a director method call */ 176 class DirectorMethodException : public Swig::DirectorException 177 { 178 public: 179 DirectorMethodException(const char* msg TSRMLS_DC) 180 : DirectorException(E_ERROR, "SWIG director method error", msg TSRMLS_CC) 181 { 182 } 183 184 static void raise(const char *msg TSRMLS_DC) 185 { 186 throw DirectorMethodException(msg TSRMLS_CC); 187 } 188 }; 189 } 190 191 // DirectorMethodException() is documented to be callable with no parameters 192 // so use a macro to insert TSRMLS_CC so any ZTS context gets passed. 193 #define DirectorMethodException() DirectorMethodException("" TSRMLS_CC) 194 195 #endif /* __cplusplus */ 196 197 #endif 198