PageRenderTime 17ms CodeModel.GetById 11ms app.highlight 2ms RepoModel.GetById 1ms app.codeStats 0ms

/trunk/Lib/php/director.swg

#
Unknown | 197 lines | 167 code | 30 blank | 0 comment | 0 complexity | 1d39f6df069a0f71b527a07f116d5ca8 MD5 | raw file
  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
 25namespace 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