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