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