1 : /*
2 : +--------------------------------------------------------------------+
3 : | PECL :: http |
4 : +--------------------------------------------------------------------+
5 : | Redistribution and use in source and binary forms, with or without |
6 : | modification, are permitted provided that the conditions mentioned |
7 : | in the accompanying LICENSE file are met. |
8 : +--------------------------------------------------------------------+
9 : | Copyright (c) 2004-2007, Michael Wallner <mike@php.net> |
10 : +--------------------------------------------------------------------+
11 : */
12 :
13 : /* $Id: http_requestdatashare_object.c,v 1.8 2007/02/22 11:04:37 mike Exp $ */
14 :
15 : #define HTTP_WANT_CURL
16 : #include "php_http.h"
17 :
18 : #if defined(ZEND_ENGINE_2) && defined(HTTP_HAVE_CURL)
19 :
20 : #include "zend_interfaces.h"
21 :
22 : #include "php_http_api.h"
23 : #include "php_http_exception_object.h"
24 : #include "php_http_request_api.h"
25 : #include "php_http_request_object.h"
26 : #include "php_http_request_datashare_api.h"
27 : #include "php_http_requestdatashare_object.h"
28 :
29 : #define HTTP_BEGIN_ARGS(method, req_args) HTTP_BEGIN_ARGS_EX(HttpRequestDataShare, method, 0, req_args)
30 : #define HTTP_EMPTY_ARGS(method) HTTP_EMPTY_ARGS_EX(HttpRequestDataShare, method, 0)
31 : #define HTTP_RSHARE_ME(method, visibility) PHP_ME(HttpRequestDataShare, method, HTTP_ARGS(HttpRequestDataShare, method), visibility)
32 :
33 : #if defined(HAVE_SPL) && !defined(WONKY)
34 : /* SPL doesn't install its headers */
35 : extern PHPAPI zend_class_entry *spl_ce_Countable;
36 : #endif
37 :
38 : HTTP_EMPTY_ARGS(__destruct);
39 : HTTP_EMPTY_ARGS(count);
40 :
41 : HTTP_BEGIN_ARGS(attach, 1)
42 : HTTP_ARG_OBJ(HttpRequest, request, 0)
43 : HTTP_END_ARGS;
44 : HTTP_BEGIN_ARGS(detach, 1)
45 : HTTP_ARG_OBJ(HttpRequest, request, 0)
46 : HTTP_END_ARGS;
47 :
48 : HTTP_EMPTY_ARGS(reset);
49 :
50 : HTTP_BEGIN_ARGS(factory, 0)
51 : HTTP_ARG_VAL(global, 0)
52 : HTTP_ARG_VAL(class_name, 0)
53 : HTTP_END_ARGS;
54 :
55 : #ifndef WONKY
56 : HTTP_BEGIN_ARGS(singleton, 0)
57 : HTTP_ARG_VAL(global, 0)
58 : HTTP_END_ARGS;
59 : #endif
60 :
61 :
62 : #define http_requestdatashare_object_read_prop _http_requestdatashare_object_read_prop
63 : static zval *_http_requestdatashare_object_read_prop(zval *object, zval *member, int type TSRMLS_DC);
64 : #define http_requestdatashare_object_write_prop _http_requestdatashare_object_write_prop
65 : static void _http_requestdatashare_object_write_prop(zval *object, zval *member, zval *value TSRMLS_DC);
66 : #define http_requestdatashare_instantiate(t, g) _http_requestdatashare_instantiate((t), (g) TSRMLS_CC)
67 : static inline zval *_http_requestdatashare_instantiate(zval *this_ptr, zend_bool global TSRMLS_DC);
68 :
69 : #define THIS_CE http_requestdatashare_object_ce
70 : zend_class_entry *http_requestdatashare_object_ce;
71 : zend_function_entry http_requestdatashare_object_fe[] = {
72 : HTTP_RSHARE_ME(__destruct, ZEND_ACC_PUBLIC|ZEND_ACC_DTOR)
73 : HTTP_RSHARE_ME(count, ZEND_ACC_PUBLIC)
74 : HTTP_RSHARE_ME(attach, ZEND_ACC_PUBLIC)
75 : HTTP_RSHARE_ME(detach, ZEND_ACC_PUBLIC)
76 : HTTP_RSHARE_ME(reset, ZEND_ACC_PUBLIC)
77 : HTTP_RSHARE_ME(factory, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
78 : #ifndef WONKY
79 : HTTP_RSHARE_ME(singleton, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
80 : #endif
81 : EMPTY_FUNCTION_ENTRY
82 : };
83 : static zend_object_handlers http_requestdatashare_object_handlers;
84 :
85 : PHP_MINIT_FUNCTION(http_requestdatashare_object)
86 220 : {
87 220 : HTTP_REGISTER_CLASS_EX(HttpRequestDataShare, http_requestdatashare_object, NULL, 0);
88 220 : http_requestdatashare_object_handlers.clone_obj = NULL;
89 220 : http_requestdatashare_object_handlers.read_property = http_requestdatashare_object_read_prop;
90 220 : http_requestdatashare_object_handlers.write_property = http_requestdatashare_object_write_prop;
91 :
92 : #if defined(HAVE_SPL) && !defined(WONKY)
93 220 : zend_class_implements(http_requestdatashare_object_ce TSRMLS_CC, 1, spl_ce_Countable);
94 : #endif
95 :
96 220 : zend_declare_property_null(THIS_CE, ZEND_STRS("instance")-1, (ZEND_ACC_STATIC|ZEND_ACC_PRIVATE) TSRMLS_CC);
97 220 : zend_declare_property_bool(THIS_CE, ZEND_STRS("cookie")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC);
98 220 : zend_declare_property_bool(THIS_CE, ZEND_STRS("dns")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC);
99 220 : zend_declare_property_bool(THIS_CE, ZEND_STRS("ssl")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC);
100 220 : zend_declare_property_bool(THIS_CE, ZEND_STRS("connect")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC);
101 :
102 220 : return SUCCESS;
103 : }
104 :
105 : zend_object_value _http_requestdatashare_object_new(zend_class_entry *ce TSRMLS_DC)
106 1 : {
107 1 : return http_requestdatashare_object_new_ex(ce, NULL, NULL);
108 : }
109 :
110 : zend_object_value _http_requestdatashare_object_new_ex(zend_class_entry *ce, http_request_datashare *share, http_requestdatashare_object **ptr TSRMLS_DC)
111 2 : {
112 : zend_object_value ov;
113 : http_requestdatashare_object *o;
114 :
115 2 : o = ecalloc(1, sizeof(http_requestdatashare_object));
116 2 : o->zo.ce = ce;
117 :
118 2 : if (share) {
119 1 : o->share = share;
120 : } else {
121 1 : o->share = http_request_datashare_new();
122 : }
123 :
124 2 : if (ptr) {
125 0 : *ptr = o;
126 : }
127 :
128 2 : ALLOC_HASHTABLE(OBJ_PROP(o));
129 2 : zend_hash_init(OBJ_PROP(o), zend_hash_num_elements(&ce->default_properties), NULL, ZVAL_PTR_DTOR, 0);
130 2 : zend_hash_copy(OBJ_PROP(o), &ce->default_properties, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
131 :
132 2 : ov.handle = putObject(http_requestdatashare_object, o);
133 2 : ov.handlers = &http_requestdatashare_object_handlers;
134 :
135 2 : return ov;
136 : }
137 :
138 : void _http_requestdatashare_object_free(zend_object *object TSRMLS_DC)
139 2 : {
140 2 : http_requestdatashare_object *o = (http_requestdatashare_object *) object;
141 :
142 2 : if (!o->share->persistent) {
143 1 : http_request_datashare_free(&o->share);
144 : }
145 2 : freeObject(o);
146 2 : }
147 :
148 : static zval *_http_requestdatashare_object_read_prop(zval *object, zval *member, int type TSRMLS_DC)
149 0 : {
150 0 : if (type == BP_VAR_W && zend_hash_exists(&THIS_CE->default_properties, Z_STRVAL_P(member), Z_STRLEN_P(member)+1)) {
151 0 : zend_error(E_ERROR, "Cannot access HttpRequestDataShare default properties by reference or array key/index");
152 0 : return NULL;
153 : }
154 :
155 0 : return zend_get_std_object_handlers()->read_property(object, member, type TSRMLS_CC);
156 : }
157 :
158 : static void _http_requestdatashare_object_write_prop(zval *object, zval *member, zval *value TSRMLS_DC)
159 4 : {
160 4 : if (zend_hash_exists(&THIS_CE->default_properties, Z_STRVAL_P(member), Z_STRLEN_P(member)+1)) {
161 : int status;
162 4 : zval *orig = value;
163 4 : getObjectEx(http_requestdatashare_object, obj, object);
164 :
165 4 : SEPARATE_ZVAL_IF_NOT_REF(&value);
166 4 : status = http_request_datashare_set(obj->share, Z_STRVAL_P(member), Z_STRLEN_P(member), (zend_bool) zval_is_true(value));
167 4 : if (orig != value) {
168 0 : zval_ptr_dtor(&value);
169 0 : value = orig;
170 : }
171 4 : if (SUCCESS != status) {
172 0 : return;
173 : }
174 : }
175 :
176 4 : zend_get_std_object_handlers()->write_property(object, member, value TSRMLS_CC);
177 : }
178 :
179 : /* {{{ proto void HttpRequestDataShare::__destruct()
180 : Clean up HttpRequestDataShare object. */
181 : PHP_METHOD(HttpRequestDataShare, __destruct)
182 2 : {
183 2 : NO_ARGS {
184 2 : getObject(http_requestdatashare_object, obj);
185 2 : http_request_datashare_detach_all(obj->share);
186 : }
187 2 : }
188 : /* }}} */
189 :
190 : /* {{{ proto int HttpRequestDataShare::count()
191 : Implements Countable::count(). */
192 : PHP_METHOD(HttpRequestDataShare, count)
193 0 : {
194 0 : getObject(http_requestdatashare_object, obj);
195 :
196 0 : NO_ARGS;
197 :
198 0 : RETURN_LONG(zend_llist_count(HTTP_RSHARE_HANDLES(obj->share)));
199 : }
200 : /* }}} */
201 :
202 : PHP_METHOD(HttpRequestDataShare, attach)
203 4 : {
204 : zval *request;
205 4 : getObject(http_requestdatashare_object, obj);
206 :
207 4 : if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &request, http_request_object_ce)) {
208 0 : RETURN_FALSE;
209 : }
210 :
211 4 : RETURN_SUCCESS(http_request_datashare_attach(obj->share, request));
212 : }
213 :
214 : PHP_METHOD(HttpRequestDataShare, detach)
215 0 : {
216 : zval *request;
217 0 : getObject(http_requestdatashare_object, obj);
218 :
219 0 : if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &request, http_request_object_ce)) {
220 0 : RETURN_FALSE;
221 : }
222 :
223 0 : RETURN_SUCCESS(http_request_datashare_detach(obj->share, request));
224 : }
225 :
226 : PHP_METHOD(HttpRequestDataShare, reset)
227 2 : {
228 2 : NO_ARGS {
229 2 : getObject(http_requestdatashare_object, obj);
230 2 : http_request_datashare_detach_all(obj->share);
231 : }
232 2 : }
233 :
234 : PHP_METHOD(HttpRequestDataShare, factory)
235 0 : {
236 0 : zend_bool global = 0;
237 0 : char *cn = NULL;
238 0 : int cl = 0;
239 : zend_object_value ov;
240 :
241 0 : SET_EH_THROW_HTTP();
242 0 : if ( SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|bs", &global, &cn, &cl) &&
243 : SUCCESS == http_object_new(&ov, cn, cl, _http_requestdatashare_object_new_ex, http_requestdatashare_object_ce, NULL, NULL)) {
244 0 : RETVAL_OBJVAL(ov, 0);
245 0 : http_requestdatashare_instantiate(return_value, global);
246 : }
247 0 : SET_EH_NORMAL();
248 0 : }
249 :
250 : #ifndef WONKY
251 : /* {{{ proto static HttpRequestDataShare HttpRequestDataShare::singleton([bool global = false])
252 : Get a single instance (differentiates between the global setting). */
253 : PHP_METHOD(HttpRequestDataShare, singleton)
254 1 : {
255 1 : zend_bool global = 0;
256 1 : zval *instance = *zend_std_get_static_property(THIS_CE, ZEND_STRS("instance")-1, 0 TSRMLS_CC);
257 :
258 1 : SET_EH_THROW_HTTP();
259 1 : if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &global)) {
260 1 : zval **zobj_ptr = NULL, *zobj = NULL;
261 :
262 1 : if (Z_TYPE_P(instance) == IS_ARRAY) {
263 0 : if (SUCCESS == zend_hash_index_find(Z_ARRVAL_P(instance), global, (void *) &zobj_ptr)) {
264 0 : RETVAL_ZVAL(*zobj_ptr, 1, 0);
265 : } else {
266 0 : zobj = http_requestdatashare_instantiate(NULL, global);
267 0 : add_index_zval(instance, global, zobj);
268 0 : RETVAL_OBJECT(zobj, 1);
269 : }
270 : } else {
271 1 : MAKE_STD_ZVAL(instance);
272 1 : array_init(instance);
273 :
274 1 : zobj = http_requestdatashare_instantiate(NULL, global);
275 1 : add_index_zval(instance, global, zobj);
276 1 : RETVAL_OBJECT(zobj, 1);
277 :
278 1 : zend_update_static_property(THIS_CE, ZEND_STRS("instance")-1, instance TSRMLS_CC);
279 1 : zval_ptr_dtor(&instance);
280 : }
281 : }
282 1 : SET_EH_NORMAL();
283 1 : }
284 : /* }}} */
285 : #endif /* !WONKY */
286 :
287 : static inline zval *_http_requestdatashare_instantiate(zval *this_ptr, zend_bool global TSRMLS_DC)
288 1 : {
289 1 : if (!this_ptr) {
290 1 : MAKE_STD_ZVAL(this_ptr);
291 1 : Z_TYPE_P(this_ptr) = IS_OBJECT;
292 1 : this_ptr->value.obj = http_requestdatashare_object_new_ex(http_requestdatashare_object_ce, global ? http_request_datashare_global_get() : NULL, NULL);
293 : }
294 1 : if (global) {
295 1 : if (HTTP_G->request.datashare.cookie) {
296 0 : zend_update_property_bool(THIS_CE, getThis(), ZEND_STRS("cookie")-1, HTTP_G->request.datashare.cookie TSRMLS_CC);
297 : }
298 1 : if (HTTP_G->request.datashare.dns) {
299 1 : zend_update_property_bool(THIS_CE, getThis(), ZEND_STRS("dns")-1, HTTP_G->request.datashare.dns TSRMLS_CC);
300 : }
301 1 : if (HTTP_G->request.datashare.ssl) {
302 0 : zend_update_property_bool(THIS_CE, getThis(), ZEND_STRS("ssl")-1, HTTP_G->request.datashare.ssl TSRMLS_CC);
303 : }
304 1 : if (HTTP_G->request.datashare.connect) {
305 0 : zend_update_property_bool(THIS_CE, getThis(), ZEND_STRS("connect")-1, HTTP_G->request.datashare.connect TSRMLS_CC);
306 : }
307 : }
308 1 : return this_ptr;
309 : }
310 :
311 : #endif /* ZEND_ENGINE_2 && HTTP_HAVE_CURL */
312 :
313 : /*
314 : * Local variables:
315 : * tab-width: 4
316 : * c-basic-offset: 4
317 : * End:
318 : * vim600: noet sw=4 ts=4 fdm=marker
319 : * vim<600: noet sw=4 ts=4
320 : */
321 :
|