add current state of refactoring
[m6w6/ext-http] / php_http_client_datashare.c
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-2011, Michael Wallner <mike@php.net> |
10 +--------------------------------------------------------------------+
11 */
12
13 #include "php_http_api.h"
14 #include "php_http_client_datashare.h"
15
16 static int php_http_client_datashare_compare_handles(void *h1, void *h2);
17
18 PHP_HTTP_API php_http_client_datashare_t *php_http_client_datashare_init(php_http_client_datashare_t *h, php_http_client_datashare_ops_t *ops, php_http_resource_factory_t *rf, void *init_arg TSRMLS_DC)
19 {
20 php_http_client_datashare_t *free_h = NULL;
21
22 if (!h) {
23 free_h = h = emalloc(sizeof(*h));
24 }
25 memset(h, sizeof(*h), 0);
26
27 zend_llist_init(&h->clients, sizeof(zval *), ZVAL_PTR_DTOR, 0);
28 h->ops = ops;
29 h->rf = rf ? rf : php_http_resource_factory_init(NULL, h->ops->rsrc, NULL, NULL);
30 TSRMLS_SET_CTX(h->ts);
31
32 if (h->ops->init) {
33 if (!(h = h->ops->init(h, init_arg))) {
34 if (free_h) {
35 efree(free_h);
36 }
37 }
38 }
39
40 return h;
41 }
42
43 PHP_HTTP_API php_http_client_datashare_t *php_http_client_datashare_copy(php_http_client_datashare_t *from, php_http_client_datashare_t *to)
44 {
45 if (from->ops->copy) {
46 return from->ops->copy(from, to);
47 }
48
49 return NULL;
50 }
51
52 PHP_HTTP_API void php_http_client_datashare_dtor(php_http_client_datashare_t *h)
53 {
54 if (h->ops->dtor) {
55 h->ops->dtor(h);
56 }
57 zend_llist_destroy(&h->clients);
58 php_http_resource_factory_free(&h->rf);
59 }
60
61 PHP_HTTP_API void php_http_client_datashare_free(php_http_client_datashare_t **h)
62 {
63 php_http_client_datashare_dtor(*h);
64 efree(*h);
65 *h = NULL;
66 }
67
68 PHP_HTTP_API STATUS php_http_client_datashare_attach(php_http_client_datashare_t *h, zval *client)
69 {
70 TSRMLS_FETCH_FROM_CTX(h->ts);
71
72 if (h->ops->attach) {
73 php_http_client_object_t *obj = zend_object_store_get_object(client TSRMLS_CC);
74
75 if (SUCCESS == h->ops->attach(h, obj->client)) {
76 Z_ADDREF_P(client);
77 zend_llist_add_element(&h->clients, &client);
78 return SUCCESS;
79 }
80 }
81
82 return FAILURE;
83 }
84
85 static int php_http_client_datashare_compare_handles(void *h1, void *h2)
86 {
87 return (Z_OBJ_HANDLE_PP((zval **) h1) == Z_OBJ_HANDLE_P((zval *) h2));
88 }
89
90 PHP_HTTP_API STATUS php_http_client_datashare_detach(php_http_client_datashare_t *h, zval *client)
91 {
92 TSRMLS_FETCH_FROM_CTX(h->ts);
93
94 if (h->ops->detach) {
95 php_http_client_object_t *obj = zend_object_store_get_object(client TSRMLS_CC);
96
97 if (SUCCESS == h->ops->detach(h, obj->client)) {
98 zend_llist_del_element(&h->clients, client, php_http_client_datashare_compare_handles);
99 return SUCCESS;
100 }
101 }
102 return FAILURE;
103 }
104
105 PHP_HTTP_API STATUS php_http_client_datashare_setopt(php_http_client_datashare_t *h, php_http_client_datashare_setopt_opt_t opt, void *arg)
106 {
107 if (h->ops->setopt) {
108 return h->ops->setopt(h, opt, arg);
109 }
110 return FAILURE;
111 }
112
113 static void detach(void *r, void *h TSRMLS_DC)
114 {
115 ((php_http_client_datashare_t *) h)->ops->detach(h, ((php_http_client_object_t *) zend_object_store_get_object(*((zval **) r) TSRMLS_CC))->client);
116 }
117
118 PHP_HTTP_API void php_http_client_datashare_reset(php_http_client_datashare_t *h)
119 {
120 TSRMLS_FETCH_FROM_CTX(h->ts);
121
122 if (h->ops->reset) {
123 h->ops->reset(h);
124 } else if (h->ops->detach) {
125 zend_llist_apply_with_argument(&h->clients, detach, h TSRMLS_CC);
126 }
127
128 zend_llist_clean(&h->clients);
129 }
130
131 #define PHP_HTTP_BEGIN_ARGS(method, req_args) PHP_HTTP_BEGIN_ARGS_EX(HttpClientDataShare, method, 0, req_args)
132 #define PHP_HTTP_EMPTY_ARGS(method) PHP_HTTP_EMPTY_ARGS_EX(HttpClientDataShare, method, 0)
133 #define PHP_HTTP_RSHARE_ME(method, visibility) PHP_ME(HttpClientDataShare, method, PHP_HTTP_ARGS(HttpClientDataShare, method), visibility)
134
135 PHP_HTTP_EMPTY_ARGS(__destruct);
136 PHP_HTTP_EMPTY_ARGS(reset);
137 PHP_HTTP_EMPTY_ARGS(count);
138
139 PHP_HTTP_BEGIN_ARGS(attach, 1)
140 PHP_HTTP_ARG_OBJ(http\\Client, client, 0)
141 PHP_HTTP_END_ARGS;
142 PHP_HTTP_BEGIN_ARGS(detach, 1)
143 PHP_HTTP_ARG_OBJ(http\\Client, client, 0)
144 PHP_HTTP_END_ARGS;
145
146 static void php_http_client_datashare_object_write_prop(zval *object, zval *member, zval *value, const zend_literal *literal_key TSRMLS_DC);
147
148 zend_class_entry *php_http_client_datashare_class_entry;
149 zend_function_entry php_http_client_datashare_method_entry[] = {
150 PHP_HTTP_RSHARE_ME(__destruct, ZEND_ACC_PUBLIC|ZEND_ACC_DTOR)
151 PHP_HTTP_RSHARE_ME(count, ZEND_ACC_PUBLIC)
152 PHP_HTTP_RSHARE_ME(attach, ZEND_ACC_PUBLIC)
153 PHP_HTTP_RSHARE_ME(detach, ZEND_ACC_PUBLIC)
154 PHP_HTTP_RSHARE_ME(reset, ZEND_ACC_PUBLIC)
155 EMPTY_FUNCTION_ENTRY
156 };
157
158 static zend_object_handlers php_http_client_datashare_object_handlers;
159
160 zend_object_handlers *php_http_client_datashare_get_object_handlers(void)
161 {
162 return &php_http_client_datashare_object_handlers;
163 }
164
165 zend_object_value php_http_client_datashare_object_new(zend_class_entry *ce TSRMLS_DC)
166 {
167 return php_http_client_datashare_object_new_ex(ce, NULL, NULL TSRMLS_CC);
168 }
169
170 zend_object_value php_http_client_datashare_object_new_ex(zend_class_entry *ce, php_http_client_datashare_t *share, php_http_client_datashare_object_t **ptr TSRMLS_DC)
171 {
172 zend_object_value ov;
173 php_http_client_datashare_object_t *o;
174
175 o = ecalloc(1, sizeof(*o));
176 zend_object_std_init((zend_object *) o, ce TSRMLS_CC);
177 object_properties_init((zend_object *) o, ce);
178
179 if (share) {
180 o->share = share;
181 } else {
182 o->share = php_http_client_datashare_init(NULL, NULL, NULL, NULL TSRMLS_CC);
183 }
184
185 if (ptr) {
186 *ptr = o;
187 }
188
189 ov.handle = zend_objects_store_put(o, NULL, php_http_client_datashare_object_free, NULL TSRMLS_CC);
190 ov.handlers = &php_http_client_datashare_object_handlers;
191
192 return ov;
193 }
194
195 void php_http_client_datashare_object_free(void *object TSRMLS_DC)
196 {
197 php_http_client_datashare_object_t *o = (php_http_client_datashare_object_t *) object;
198
199 php_http_client_datashare_free(&o->share);
200 zend_object_std_dtor((zend_object *) o TSRMLS_CC);
201 efree(o);
202 }
203
204 static void php_http_client_datashare_object_write_prop(zval *object, zval *member, zval *value, const zend_literal *literal_key TSRMLS_DC)
205 {
206 zend_property_info *pi;
207
208 if ((pi = zend_get_property_info(php_http_client_datashare_class_entry, member, 1 TSRMLS_CC))) {
209 zend_bool enable = i_zend_is_true(value);
210 php_http_client_datashare_setopt_opt_t opt;
211 php_http_client_datashare_object_t *obj = zend_object_store_get_object(object TSRMLS_CC);
212
213 if (!strcmp(pi->name, "cookie")) {
214 opt = PHP_HTTP_CLIENT_DATASHARE_OPT_COOKIES;
215 } else if (!strcmp(pi->name, "dns")) {
216 opt = PHP_HTTP_CLIENT_DATASHARE_OPT_RESOLVER;
217 } else if (!strcmp(pi->name, "ssl")) {
218 opt = PHP_HTTP_CLIENT_DATASHARE_OPT_SSLSESSIONS;
219 } else {
220 return;
221 }
222
223 if (SUCCESS != php_http_client_datashare_setopt(obj->share, opt, &enable)) {
224 return;
225 }
226 }
227
228 zend_get_std_object_handlers()->write_property(object, member, value, literal_key TSRMLS_CC);
229 }
230
231 static zval **php_http_client_datashare_object_get_prop_ptr(zval *object, zval *member, const zend_literal *literal_key TSRMLS_DC)
232 {
233 zend_property_info *pi;
234
235 if ((pi = zend_get_property_info(php_http_client_datashare_class_entry, member, 1 TSRMLS_CC))) {
236 return &php_http_property_proxy_init(NULL, object, member, NULL TSRMLS_CC)->myself;
237 }
238
239 return zend_get_std_object_handlers()->get_property_ptr_ptr(object, member, literal_key TSRMLS_CC);
240 }
241
242
243 PHP_METHOD(HttpClientDataShare, __destruct)
244 {
245 php_http_client_datashare_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
246 /* FIXME: move to php_http_client_datashare_dtor */
247 if (SUCCESS == zend_parse_parameters_none()) {
248 ; /* we always want to clean up */
249 }
250
251 php_http_client_datashare_reset(obj->share);
252 }
253
254 PHP_METHOD(HttpClientDataShare, count)
255 {
256 if (SUCCESS == zend_parse_parameters_none()) {
257 php_http_client_datashare_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
258
259 RETURN_LONG(zend_llist_count(&obj->share->clients));
260 }
261 RETURN_FALSE;
262 }
263
264
265 PHP_METHOD(HttpClientDataShare, attach)
266 {
267 zval *client;
268
269 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &client, php_http_client_class_entry)) {
270 php_http_client_datashare_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
271
272 RETURN_SUCCESS(php_http_client_datashare_attach(obj->share, client));
273 }
274 RETURN_FALSE;
275
276 }
277
278 PHP_METHOD(HttpClientDataShare, detach)
279 {
280 zval *client;
281
282 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &client, php_http_client_class_entry)) {
283 php_http_client_datashare_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
284
285 RETURN_SUCCESS(php_http_client_datashare_detach(obj->share, client));
286 }
287 RETURN_FALSE;
288 }
289
290 PHP_METHOD(HttpClientDataShare, reset)
291 {
292 if (SUCCESS == zend_parse_parameters_none()) {
293 php_http_client_datashare_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
294
295 php_http_client_datashare_reset(obj->share);
296 RETURN_TRUE;
297 }
298 RETURN_FALSE;
299 }
300
301 PHP_MINIT_FUNCTION(http_client_datashare)
302 {
303 PHP_HTTP_REGISTER_CLASS(http\\Client\\DataShare, AbstractDataShare, http_client_datashare, php_http_object_class_entry, 0);
304 php_http_client_datashare_class_entry->create_object = php_http_object_new;//php_http_client_datashare_object_new;
305 memcpy(&php_http_client_datashare_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
306 php_http_client_datashare_object_handlers.clone_obj = NULL;
307 php_http_client_datashare_object_handlers.write_property = php_http_client_datashare_object_write_prop;
308 php_http_client_datashare_object_handlers.get_property_ptr_ptr = php_http_client_datashare_object_get_prop_ptr;
309
310 zend_class_implements(php_http_client_datashare_class_entry TSRMLS_CC, 1, spl_ce_Countable);
311
312 zend_declare_property_bool(php_http_client_datashare_class_entry, ZEND_STRL("cookie"), 0, ZEND_ACC_PUBLIC TSRMLS_CC);
313 zend_declare_property_bool(php_http_client_datashare_class_entry, ZEND_STRL("dns"), 0, ZEND_ACC_PUBLIC TSRMLS_CC);
314 zend_declare_property_bool(php_http_client_datashare_class_entry, ZEND_STRL("ssl"), 0, ZEND_ACC_PUBLIC TSRMLS_CC);
315
316 return SUCCESS;
317 }
318
319 /*
320 * Local variables:
321 * tab-width: 4
322 * c-basic-offset: 4
323 * End:
324 * vim600: noet sw=4 ts=4 fdm=marker
325 * vim<600: noet sw=4 ts=4
326 */
327