| 1 | /* |
| 2 | * php4.swg |
| 3 | * |
| 4 | * PHP4 runtime library |
| 5 | * |
| 6 | */ |
| 7 | |
| 8 | #ifdef __cplusplus |
| 9 | extern "C" { |
| 10 | #endif |
| 11 | #include "zend.h" |
| 12 | #include "zend_API.h" |
| 13 | #include "php.h" |
| 14 | |
| 15 | /* These TSRMLS_ stuff should already be defined now, but with older php under |
| 16 | redhat are not... */ |
| 17 | #ifndef TSRMLS_D |
| 18 | #define TSRMLS_D |
| 19 | #endif |
| 20 | #ifndef TSRMLS_DC |
| 21 | #define TSRMLS_DC |
| 22 | #endif |
| 23 | #ifndef TSRMLS_C |
| 24 | #define TSRMLS_C |
| 25 | #endif |
| 26 | #ifndef TSRMLS_CC |
| 27 | #define TSRMLS_CC |
| 28 | #endif |
| 29 | |
| 30 | #ifdef __cplusplus |
| 31 | } |
| 32 | #endif |
| 33 | |
| 34 | /* But in fact SWIG_ConvertPtr is the native interface for getting typed |
| 35 | pointer values out of zvals. We need the TSRMLS_ macros for when we |
| 36 | make PHP type calls later as we handle php resources */ |
| 37 | #define SWIG_ConvertPtr(obj,pp,type,flags) SWIG_ZTS_ConvertPtr(obj,pp,type,flags TSRMLS_CC) |
| 38 | |
| 39 | /* Flags for SWIG_ConvertPtr */ |
| 40 | #define SWIG_POINTER_DISOWN 0x1 |
| 41 | |
| 42 | #define SWIG_fail goto fail |
| 43 | |
| 44 | static char *default_error_msg = "Unknown error occurred"; |
| 45 | static int default_error_code = E_ERROR; |
| 46 | |
| 47 | #define SWIG_PHP_Arg_Error_Msg(argnum,extramsg) "Error in argument " #argnum " "#extramsg |
| 48 | |
| 49 | #define SWIG_PHP_Error(code,msg) ErrorCode() = code; ErrorMsg() = msg; SWIG_fail; |
| 50 | |
| 51 | #define SWIG_contract_assert(expr,msg) \ |
| 52 | if (!(expr) ) { zend_printf("Contract Assert Failed %s\n",msg ); } else |
| 53 | |
| 54 | /* Standard SWIG API */ |
| 55 | #define SWIG_GetModule(clientdata) SWIG_Php4_GetModule() |
| 56 | #define SWIG_SetModule(clientdata, pointer) SWIG_Php4_SetModule(pointer) |
| 57 | |
| 58 | /* used to wrap returned objects in so we know whether they are newobject |
| 59 | and need freeing, or not */ |
| 60 | typedef struct _swig_object_wrapper { |
| 61 | void * ptr; |
| 62 | int newobject; |
| 63 | } swig_object_wrapper; |
| 64 | |
| 65 | /* empty zend destructor for types without one */ |
| 66 | static ZEND_RSRC_DTOR_FUNC(SWIG_landfill) {}; |
| 67 | |
| 68 | #define SWIG_SetPointerZval(a,b,c,d) SWIG_ZTS_SetPointerZval(a,b,c,d, SWIG_module_entry TSRMLS_CC) |
| 69 | |
| 70 | static void |
| 71 | SWIG_ZTS_SetPointerZval(zval *z, void *ptr, swig_type_info *type, int newobject, zend_module_entry* module_entry TSRMLS_DC) { |
| 72 | swig_object_wrapper *value=NULL; |
| 73 | /* |
| 74 | * First test for Null pointers. Return those as PHP native NULL |
| 75 | */ |
| 76 | if (!ptr ) { |
| 77 | ZVAL_NULL(z); |
| 78 | return; |
| 79 | } |
| 80 | if (type->clientdata) { |
| 81 | if (! (*(int *)(type->clientdata))) |
| 82 | zend_error(E_ERROR, "Type: %s failed to register with zend",type->name); |
| 83 | value=(swig_object_wrapper *)emalloc(sizeof(swig_object_wrapper)); |
| 84 | value->ptr=ptr; |
| 85 | value->newobject=newobject; |
| 86 | ZEND_REGISTER_RESOURCE(z, value, *(int *)(type->clientdata)); |
| 87 | return; |
| 88 | } else { /* have to deal with old fashioned string pointer? |
| 89 | but this should not get this far */ |
| 90 | zend_error(E_ERROR, "Type: %s not registered with zend",type->name); |
| 91 | } |
| 92 | } |
| 93 | |
| 94 | /* This is a new pointer conversion routine |
| 95 | Taking the native pointer p (which would have been converted from the old |
| 96 | string pointer) and it's php type id, and it's type name (which also would |
| 97 | have come from the old string pointer) it converts it to ptr calling |
| 98 | appropriate casting functions according to ty |
| 99 | Sadly PHP has no API to find a type name from a type id, only from an instance |
| 100 | of a resource of the type id, so we have to pass type_name as well. |
| 101 | The two functions which might call this are: |
| 102 | SWIG_ZTS_ConvertResourcePtr which gets the type name from the resource |
| 103 | and the registered zend destructors for which we have one per type each |
| 104 | with the type name hard wired in. */ |
| 105 | static int |
| 106 | SWIG_ZTS_ConvertResourceData(void * p, int type, const char *type_name, void **ptr, swig_type_info *ty TSRMLS_DC) { |
| 107 | swig_cast_info *tc; |
| 108 | |
| 109 | if (ty) { |
| 110 | if (! type_name) { |
| 111 | /* can't convert p to ptr type ty if we don't know what type p is */ |
| 112 | return -1; |
| 113 | } else { |
| 114 | /* convert and cast p from type_name to ptr as ty |
| 115 | Need to sort out const-ness, can SWIG_TypeCast really not take a const? */ |
| 116 | tc = SWIG_TypeCheck((char *)type_name,ty); |
| 117 | if (!tc) return -1; |
| 118 | *ptr = SWIG_TypeCast(tc, (void*)p); |
| 119 | } |
| 120 | } else { |
| 121 | /* They don't care about the target type, so just pass on the pointer! */ |
| 122 | *ptr = (void *) p; |
| 123 | } |
| 124 | return 0; |
| 125 | } |
| 126 | |
| 127 | /* This function fills ptr with a pointer of type ty by extracting the pointer |
| 128 | and type info from the resource in z. z must be a resource |
| 129 | It uses SWIG_ZTS_ConvertResourceData to do the real work. */ |
| 130 | static int |
| 131 | SWIG_ZTS_ConvertResourcePtr(zval *z, void **ptr, swig_type_info *ty, int flags TSRMLS_DC) { |
| 132 | swig_object_wrapper *value; |
| 133 | void *p; |
| 134 | int type; |
| 135 | char *type_name; |
| 136 | |
| 137 | value = (swig_object_wrapper *) zend_list_find(z->value.lval,&type); |
| 138 | if ( flags && SWIG_POINTER_DISOWN ) { |
| 139 | value->newobject = 0; |
| 140 | } |
| 141 | p = value->ptr; |
| 142 | if (type==-1) return -1; |
| 143 | |
| 144 | type_name=zend_rsrc_list_get_rsrc_type(z->value.lval TSRMLS_CC); |
| 145 | |
| 146 | return SWIG_ZTS_ConvertResourceData(p,type,type_name,ptr,ty TSRMLS_CC); |
| 147 | } |
| 148 | |
| 149 | /* We allow passing of a STRING or RESOURCE pointing to the object |
| 150 | or an OBJECT whose _cPtr is a string or resource pointing to the object |
| 151 | STRING pointers are very depracated */ |
| 152 | static int |
| 153 | SWIG_ZTS_ConvertPtr(zval *z, void **ptr, swig_type_info *ty, int flags TSRMLS_DC) { |
| 154 | char *c; |
| 155 | zval *val; |
| 156 | |
| 157 | if(z == NULL) { |
| 158 | *ptr = 0; |
| 159 | return 0; |
| 160 | } |
| 161 | |
| 162 | if (z->type==IS_OBJECT) { |
| 163 | zval ** _cPtr; |
| 164 | if (zend_hash_find(HASH_OF(z),"_cPtr",sizeof("_cPtr"),(void**)&_cPtr)==SUCCESS) { |
| 165 | /* Don't co-erce to string if it isn't */ |
| 166 | if ((*_cPtr)->type==IS_STRING) c = Z_STRVAL_PP(_cPtr); |
| 167 | else if ((*_cPtr)->type==IS_RESOURCE) { |
| 168 | return SWIG_ZTS_ConvertResourcePtr(*_cPtr,ptr,ty, flags TSRMLS_CC); |
| 169 | } else goto type_error; /* _cPtr was not string or resource property */ |
| 170 | } else goto type_error; /* can't find property _cPtr */ |
| 171 | } else if (z->type==IS_RESOURCE) { |
| 172 | return SWIG_ZTS_ConvertResourcePtr(z,ptr,ty, flags TSRMLS_CC); |
| 173 | } if (z->type==IS_NULL ) { |
| 174 | *ptr = 0; |
| 175 | return 0; |
| 176 | } else goto type_error; |
| 177 | |
| 178 | type_error: |
| 179 | |
| 180 | return -1; |
| 181 | } |
| 182 | |
| 183 | static char const_name[] = "swig_runtime_data_type_pointer"; |
| 184 | static swig_module_info *SWIG_Php4_GetModule() { |
| 185 | zval *pointer; |
| 186 | swig_module_info *ret = 0; |
| 187 | |
| 188 | MAKE_STD_ZVAL(pointer); |
| 189 | |
| 190 | if (zend_get_constant(const_name, sizeof(const_name), pointer)) { |
| 191 | if (pointer->type == IS_LONG) { |
| 192 | ret = (swig_module_info *) pointer->value.lval; |
| 193 | } |
| 194 | } |
| 195 | return 0; |
| 196 | } |
| 197 | |
| 198 | static void SWIG_Php4_SetModule(swig_module_info *pointer) { |
| 199 | REGISTER_MAIN_LONG_CONSTANT(const_name, (long) pointer, 0); |
| 200 | } |