import 2.0 devl branch, suitable for PHP-trunk
[m6w6/ext-http] / php_http_querystring.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-2010, Michael Wallner <mike@php.net> |
10 +--------------------------------------------------------------------+
11 */
12
13 /* $Id$ */
14
15 #include "php_http.h"
16
17 /** API **/
18
19 static inline int php_http_querystring_modify_array_ex(zval *qarray, int key_type, char *key, int keylen, ulong idx, zval *params_entry TSRMLS_DC);
20 static inline int php_http_querystring_modify_array(zval *qarray, zval *params TSRMLS_DC);
21
22 #ifdef PHP_HTTP_HAVE_ICONV
23 PHP_HTTP_API int php_http_querystring_xlate(zval *array, zval *param, const char *ie, const char *oe TSRMLS_DC)
24 {
25 HashPosition pos;
26 zval **entry = NULL;
27 char *xlate_str = NULL, *xkey;
28 size_t xlate_len = 0, xlen;
29 php_http_array_hashkey_t key = php_http_array_hashkey_init(0);
30
31 FOREACH_KEYVAL(pos, param, key, entry) {
32 if (key.type == HASH_KEY_IS_STRING) {
33 if (PHP_ICONV_ERR_SUCCESS != php_iconv_string(key.str, key.len-1, &xkey, &xlen, oe, ie)) {
34 php_http_error(HE_WARNING, PHP_HTTP_E_QUERYSTRING, "Failed to convert '%.*s' from '%s' to '%s'", key.len-1, key.str, ie, oe);
35 return FAILURE;
36 }
37 }
38
39 if (Z_TYPE_PP(entry) == IS_STRING) {
40 if (PHP_ICONV_ERR_SUCCESS != php_iconv_string(Z_STRVAL_PP(entry), Z_STRLEN_PP(entry), &xlate_str, &xlate_len, oe, ie)) {
41 if (key.type == HASH_KEY_IS_STRING) {
42 efree(xkey);
43 }
44 php_http_error(HE_WARNING, PHP_HTTP_E_QUERYSTRING, "Failed to convert '%.*s' from '%s' to '%s'", Z_STRLEN_PP(entry), Z_STRVAL_PP(entry), ie, oe);
45 return FAILURE;
46 }
47 if (key.type == HASH_KEY_IS_STRING) {
48 add_assoc_stringl_ex(array, xkey, xlen+1, xlate_str, xlate_len, 0);
49 } else {
50 add_index_stringl(array, key.num, xlate_str, xlate_len, 0);
51 }
52 } else if (Z_TYPE_PP(entry) == IS_ARRAY) {
53 zval *subarray;
54
55 MAKE_STD_ZVAL(subarray);
56 array_init(subarray);
57 if (key.type == HASH_KEY_IS_STRING) {
58 add_assoc_zval_ex(array, xkey, xlen+1, subarray);
59 } else {
60 add_index_zval(array, key.num, subarray);
61 }
62 if (SUCCESS != php_http_querystring_xlate(subarray, *entry, ie, oe TSRMLS_CC)) {
63 if (key.type == HASH_KEY_IS_STRING) {
64 efree(xkey);
65 }
66 return FAILURE;
67 }
68 }
69
70 if (key.type == HASH_KEY_IS_STRING) {
71 efree(xkey);
72 }
73 }
74 return SUCCESS;
75 }
76 #endif /* HAVE_ICONV */
77
78 PHP_HTTP_API void php_http_querystring_update(zval *qarray, zval *qstring TSRMLS_DC)
79 {
80 char *s = NULL;
81 size_t l = 0;
82
83 if (Z_TYPE_P(qarray) != IS_ARRAY) {
84 convert_to_array(qarray);
85 }
86 if (SUCCESS == php_http_url_encode_hash(Z_ARRVAL_P(qarray), 0, NULL, 0, &s, &l TSRMLS_CC)) {
87 if (Z_TYPE_P(qstring) == IS_STRING)
88 zval_dtor(qstring);
89 ZVAL_STRINGL(qstring, s, l, 0);
90 } else {
91 php_http_error(HE_WARNING, PHP_HTTP_E_QUERYSTRING, "Failed to update query string");
92 }
93 }
94
95 PHP_HTTP_API int php_http_querystring_modify(zval *qarray, zval *params TSRMLS_DC)
96 {
97 if (Z_TYPE_P(params) == IS_ARRAY) {
98 return php_http_querystring_modify_array(qarray, params TSRMLS_CC);
99 } else if (Z_TYPE_P(params) == IS_OBJECT) {
100 if (instanceof_function(Z_OBJCE_P(params), php_http_querystring_class_entry TSRMLS_CC)) {
101 return php_http_querystring_modify_array(qarray, zend_read_property(php_http_querystring_class_entry, params, ZEND_STRL("queryArray"), 0 TSRMLS_CC) TSRMLS_CC);
102 } else {
103 return php_http_querystring_modify_array(qarray, params TSRMLS_CC);
104 }
105 } else {
106 int rv;
107 zval array;
108 zval *qstring = php_http_zsep(IS_STRING, params);
109
110 INIT_PZVAL(&array);
111 array_init(&array);
112
113 php_default_treat_data(PARSE_STRING, estrdup(Z_STRVAL_P(qstring)), &array TSRMLS_CC);
114 zval_ptr_dtor(&qstring);
115
116 rv = php_http_querystring_modify_array(qarray, &array TSRMLS_CC);
117 zval_dtor(&array);
118 return rv;
119 }
120 }
121
122 static inline int php_http_querystring_modify_array(zval *qarray, zval *params TSRMLS_DC)
123 {
124 int rv = 0;
125 php_http_array_hashkey_t key = php_http_array_hashkey_init(0);
126 HashPosition pos;
127 zval **params_entry = NULL;
128
129 FOREACH_HASH_KEYVAL(pos, HASH_OF(params), key, params_entry) {
130 /* only public properties */
131 if ((key.type != HASH_KEY_IS_STRING || *key.str) && php_http_querystring_modify_array_ex(qarray, key.type, key.str, key.len, key.num, *params_entry TSRMLS_CC)) {
132 rv = 1;
133 }
134 }
135
136 return rv;
137 }
138
139 static inline int php_http_querystring_modify_array_ex(zval *qarray, int key_type, char *key, int keylen, ulong idx, zval *params_entry TSRMLS_DC)
140 {
141 zval **qarray_entry;
142
143 /* ensure array type */
144 if (Z_TYPE_P(qarray) != IS_ARRAY) {
145 convert_to_array(qarray);
146 }
147
148 /* delete */
149 if (Z_TYPE_P(params_entry) == IS_NULL) {
150 if (key_type == HASH_KEY_IS_STRING) {
151 return (SUCCESS == zend_hash_del(Z_ARRVAL_P(qarray), key, keylen));
152 } else {
153 return (SUCCESS == zend_hash_index_del(Z_ARRVAL_P(qarray), idx));
154 }
155 }
156
157 /* update */
158 if ( ((key_type == HASH_KEY_IS_STRING) && (SUCCESS == zend_hash_find(Z_ARRVAL_P(qarray), key, keylen, (void *) &qarray_entry))) ||
159 ((key_type == HASH_KEY_IS_LONG) && (SUCCESS == zend_hash_index_find(Z_ARRVAL_P(qarray), idx, (void *) &qarray_entry)))) {
160 zval equal;
161
162 /* recursive */
163 if (Z_TYPE_P(params_entry) == IS_ARRAY || Z_TYPE_P(params_entry) == IS_OBJECT) {
164 return php_http_querystring_modify(*qarray_entry, params_entry TSRMLS_CC);
165 }
166 /* equal */
167 if ((SUCCESS == is_equal_function(&equal, *qarray_entry, params_entry TSRMLS_CC)) && Z_BVAL(equal)) {
168 return 0;
169 }
170 }
171
172 /* add */
173 if (Z_TYPE_P(params_entry) == IS_OBJECT) {
174 zval *new_array;
175
176 MAKE_STD_ZVAL(new_array);
177 array_init(new_array);
178 php_http_querystring_modify_array(new_array, params_entry TSRMLS_CC);
179 params_entry = new_array;
180 } else {
181 Z_ADDREF_P(params_entry);
182 }
183 if (key_type == HASH_KEY_IS_STRING) {
184 add_assoc_zval_ex(qarray, key, keylen, params_entry);
185 } else {
186 add_index_zval(qarray, idx, params_entry);
187 }
188 return 1;
189 }
190
191 /** PHP **/
192
193 #define PHP_HTTP_BEGIN_ARGS(method, req_args) PHP_HTTP_BEGIN_ARGS_EX(HttpQueryString, method, 0, req_args)
194 #define PHP_HTTP_EMPTY_ARGS(method) PHP_HTTP_EMPTY_ARGS_EX(HttpQueryString, method, 0)
195 #define PHP_HTTP_QUERYSTRING_ME(method, visibility) PHP_ME(HttpQueryString, method, PHP_HTTP_ARGS(HttpQueryString, method), visibility)
196 #define PHP_HTTP_QUERYSTRING_GME(method, visibility) PHP_ME(HttpQueryString, method, PHP_HTTP_ARGS(HttpQueryString, __getter), visibility)
197
198 PHP_HTTP_BEGIN_ARGS(__construct, 0)
199 PHP_HTTP_ARG_VAL(params, 0)
200 PHP_HTTP_END_ARGS;
201
202 PHP_HTTP_EMPTY_ARGS(getGlobalInstance);
203
204 PHP_HTTP_EMPTY_ARGS(toArray);
205 PHP_HTTP_EMPTY_ARGS(toString);
206
207 PHP_HTTP_BEGIN_ARGS(get, 0)
208 PHP_HTTP_ARG_VAL(name, 0)
209 PHP_HTTP_ARG_VAL(type, 0)
210 PHP_HTTP_ARG_VAL(defval, 0)
211 PHP_HTTP_ARG_VAL(delete, 0)
212 PHP_HTTP_END_ARGS;
213
214 PHP_HTTP_BEGIN_ARGS(set, 1)
215 PHP_HTTP_ARG_VAL(params, 0)
216 PHP_HTTP_END_ARGS;
217
218 PHP_HTTP_BEGIN_ARGS(mod, 0)
219 PHP_HTTP_ARG_VAL(params, 0)
220 PHP_HTTP_END_ARGS;
221
222 PHP_HTTP_BEGIN_ARGS(__getter, 1)
223 PHP_HTTP_ARG_VAL(name, 0)
224 PHP_HTTP_ARG_VAL(defval, 0)
225 PHP_HTTP_ARG_VAL(delete, 0)
226 PHP_HTTP_END_ARGS;
227
228 #ifdef PHP_HTTP_HAVE_ICONV
229 PHP_HTTP_BEGIN_ARGS(xlate, 2)
230 PHP_HTTP_ARG_VAL(from_encoding, 0)
231 PHP_HTTP_ARG_VAL(to_encoding, 0)
232 PHP_HTTP_END_ARGS;
233 #endif
234
235 PHP_HTTP_EMPTY_ARGS(serialize);
236 PHP_HTTP_BEGIN_ARGS(unserialize, 1)
237 PHP_HTTP_ARG_VAL(serialized, 0)
238 PHP_HTTP_END_ARGS;
239
240 PHP_HTTP_BEGIN_ARGS(offsetGet, 1)
241 PHP_HTTP_ARG_VAL(offset, 0)
242 PHP_HTTP_END_ARGS;
243
244 PHP_HTTP_BEGIN_ARGS(offsetSet, 2)
245 PHP_HTTP_ARG_VAL(offset, 0)
246 PHP_HTTP_ARG_VAL(value, 0)
247 PHP_HTTP_END_ARGS;
248
249 PHP_HTTP_BEGIN_ARGS(offsetExists, 1)
250 PHP_HTTP_ARG_VAL(offset, 0)
251 PHP_HTTP_END_ARGS;
252
253 PHP_HTTP_BEGIN_ARGS(offsetUnset, 1)
254 PHP_HTTP_ARG_VAL(offset, 0)
255 PHP_HTTP_END_ARGS;
256
257 PHP_HTTP_EMPTY_ARGS(getIterator);
258
259 zend_class_entry *php_http_querystring_class_entry;
260 zend_function_entry php_http_querystring_method_entry[] = {
261 PHP_HTTP_QUERYSTRING_ME(__construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR|ZEND_ACC_FINAL)
262
263 PHP_HTTP_QUERYSTRING_ME(toArray, ZEND_ACC_PUBLIC)
264 PHP_HTTP_QUERYSTRING_ME(toString, ZEND_ACC_PUBLIC)
265 ZEND_MALIAS(HttpQueryString, __toString, toString, PHP_HTTP_ARGS(HttpQueryString, toString), ZEND_ACC_PUBLIC)
266
267 PHP_HTTP_QUERYSTRING_ME(get, ZEND_ACC_PUBLIC)
268 PHP_HTTP_QUERYSTRING_ME(set, ZEND_ACC_PUBLIC)
269 PHP_HTTP_QUERYSTRING_ME(mod, ZEND_ACC_PUBLIC)
270
271 PHP_HTTP_QUERYSTRING_GME(getBool, ZEND_ACC_PUBLIC)
272 PHP_HTTP_QUERYSTRING_GME(getInt, ZEND_ACC_PUBLIC)
273 PHP_HTTP_QUERYSTRING_GME(getFloat, ZEND_ACC_PUBLIC)
274 PHP_HTTP_QUERYSTRING_GME(getString, ZEND_ACC_PUBLIC)
275 PHP_HTTP_QUERYSTRING_GME(getArray, ZEND_ACC_PUBLIC)
276 PHP_HTTP_QUERYSTRING_GME(getObject, ZEND_ACC_PUBLIC)
277
278 PHP_HTTP_QUERYSTRING_ME(getIterator, ZEND_ACC_PUBLIC)
279
280 PHP_HTTP_QUERYSTRING_ME(getGlobalInstance, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
281 #ifdef PHP_HTTP_HAVE_ICONV
282 PHP_HTTP_QUERYSTRING_ME(xlate, ZEND_ACC_PUBLIC)
283 #endif
284
285 /* Implements Serializable */
286 PHP_HTTP_QUERYSTRING_ME(serialize, ZEND_ACC_PUBLIC)
287 PHP_HTTP_QUERYSTRING_ME(unserialize, ZEND_ACC_PUBLIC)
288
289 /* Implements ArrayAccess */
290 PHP_HTTP_QUERYSTRING_ME(offsetGet, ZEND_ACC_PUBLIC)
291 PHP_HTTP_QUERYSTRING_ME(offsetSet, ZEND_ACC_PUBLIC)
292 PHP_HTTP_QUERYSTRING_ME(offsetExists, ZEND_ACC_PUBLIC)
293 PHP_HTTP_QUERYSTRING_ME(offsetUnset, ZEND_ACC_PUBLIC)
294
295 EMPTY_FUNCTION_ENTRY
296 };
297
298 PHP_MINIT_FUNCTION(http_querystring)
299 {
300 PHP_HTTP_REGISTER_CLASS(http, QueryString, http_querystring, php_http_object_class_entry, 0);
301
302 zend_class_implements(php_http_querystring_class_entry TSRMLS_CC, 3, zend_ce_serializable, zend_ce_arrayaccess, zend_ce_aggregate);
303
304 zend_declare_property_null(php_http_querystring_class_entry, ZEND_STRL("instance"), (ZEND_ACC_STATIC|ZEND_ACC_PRIVATE) TSRMLS_CC);
305 zend_declare_property_null(php_http_querystring_class_entry, ZEND_STRL("queryArray"), ZEND_ACC_PRIVATE TSRMLS_CC);
306 zend_declare_property_null(php_http_querystring_class_entry, ZEND_STRL("queryString"), ZEND_ACC_PRIVATE TSRMLS_CC);
307
308 zend_declare_class_constant_long(php_http_querystring_class_entry, ZEND_STRL("TYPE_BOOL"), PHP_HTTP_QUERYSTRING_TYPE_BOOL TSRMLS_CC);
309 zend_declare_class_constant_long(php_http_querystring_class_entry, ZEND_STRL("TYPE_INT"), PHP_HTTP_QUERYSTRING_TYPE_INT TSRMLS_CC);
310 zend_declare_class_constant_long(php_http_querystring_class_entry, ZEND_STRL("TYPE_FLOAT"), PHP_HTTP_QUERYSTRING_TYPE_FLOAT TSRMLS_CC);
311 zend_declare_class_constant_long(php_http_querystring_class_entry, ZEND_STRL("TYPE_STRING"), PHP_HTTP_QUERYSTRING_TYPE_STRING TSRMLS_CC);
312 zend_declare_class_constant_long(php_http_querystring_class_entry, ZEND_STRL("TYPE_ARRAY"), PHP_HTTP_QUERYSTRING_TYPE_ARRAY TSRMLS_CC);
313 zend_declare_class_constant_long(php_http_querystring_class_entry, ZEND_STRL("TYPE_OBJECT"), PHP_HTTP_QUERYSTRING_TYPE_OBJECT TSRMLS_CC);
314
315 return SUCCESS;
316 }
317
318 static inline void php_http_querystring_get(zval *this_ptr, int type, char *name, uint name_len, zval *defval, zend_bool del, zval *return_value TSRMLS_DC)
319 {
320 zval **arrval, *qarray = zend_read_property(php_http_querystring_class_entry, getThis(), ZEND_STRL("queryArray"), 0 TSRMLS_CC);
321
322 if ((Z_TYPE_P(qarray) == IS_ARRAY) && (SUCCESS == zend_hash_find(Z_ARRVAL_P(qarray), name, name_len + 1, (void *) &arrval))) {
323 if (type) {
324 zval *value = php_http_zsep(type, *arrval);
325 RETVAL_ZVAL(value, 1, 1);
326 } else {
327 RETVAL_ZVAL(*arrval, 1, 0);
328 }
329
330 if (del && (SUCCESS == zend_hash_del(Z_ARRVAL_P(qarray), name, name_len + 1))) {
331 php_http_querystring_update(qarray, zend_read_property(php_http_querystring_class_entry, getThis(), ZEND_STRL("queryString"), 0 TSRMLS_CC) TSRMLS_CC);
332 }
333 } else if(defval) {
334 RETURN_ZVAL(defval, 1, 0);
335 }
336 }
337
338 static inline void php_http_querystring_set(zval *instance, zval *params TSRMLS_DC)
339 {
340 zval *na = NULL, *qa = zend_read_property(php_http_querystring_class_entry, instance, ZEND_STRL("queryArray"), 0 TSRMLS_CC);
341
342 if (Z_TYPE_P(qa) != IS_ARRAY) {
343 MAKE_STD_ZVAL(qa);
344 array_init(qa);
345 zend_update_property(php_http_querystring_class_entry, instance, ZEND_STRL("queryArray"), qa TSRMLS_CC);
346 na = qa;
347 }
348
349 if (params && php_http_querystring_modify(qa, params TSRMLS_CC)) {
350 zval *ns = NULL, *qs = zend_read_property(php_http_querystring_class_entry, instance, ZEND_STRL("queryString"), 0 TSRMLS_CC);
351
352 if (Z_TYPE_P(qs) != IS_STRING) {
353 MAKE_STD_ZVAL(qs);
354 ZVAL_EMPTY_STRING(qs);
355 zend_update_property(php_http_querystring_class_entry, instance, ZEND_STRL("queryString"), qs TSRMLS_CC);
356 ns = qs;
357 }
358
359 php_http_querystring_update(qa, qs TSRMLS_CC);
360
361 if (ns) {
362 zval_ptr_dtor(&ns);
363 }
364 }
365
366 if (na) {
367 zval_ptr_dtor(&na);
368 }
369 }
370
371 PHP_METHOD(HttpQueryString, __construct)
372 {
373 zval *params = NULL;
374
375 with_error_handling(EH_THROW, PHP_HTTP_EX_CE(runtime)) {
376 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z", &params)) {
377 with_error_handling(EH_THROW, PHP_HTTP_EX_CE(querystring)) {
378 php_http_querystring_set(getThis(), params TSRMLS_CC);
379 } end_error_handling();
380 }
381 } end_error_handling();
382 }
383
384 PHP_METHOD(HttpQueryString, getGlobalInstance)
385 {
386 with_error_handling(EH_THROW, PHP_HTTP_EX_CE(runtime)) {
387 if (SUCCESS == zend_parse_parameters_none()) {
388 with_error_handling(EH_THROW, PHP_HTTP_EX_CE(querystring)) {
389 zval *instance = *zend_std_get_static_property(php_http_querystring_class_entry, ZEND_STRL("instance"), 0, NULL TSRMLS_CC);
390
391 if (Z_TYPE_P(instance) != IS_OBJECT) {
392 zval **_SERVER = NULL, **_GET = NULL, **QUERY_STRING = NULL;
393
394 zend_is_auto_global("_GET", lenof("_GET") TSRMLS_CC);
395 zend_is_auto_global("_SERVER", lenof("_SERVER") TSRMLS_CC);
396
397 if ((SUCCESS == zend_hash_find(&EG(symbol_table), "_SERVER", sizeof("_SERVER"), (void *) &_SERVER))
398 && (Z_TYPE_PP(_SERVER) == IS_ARRAY)
399 && (SUCCESS == zend_hash_find(Z_ARRVAL_PP(_SERVER), "QUERY_STRING", sizeof("QUERY_STRING"), (void *) &QUERY_STRING))
400 && (SUCCESS == zend_hash_find(&EG(symbol_table), "_GET", sizeof("_GET"), (void *) &_GET))
401 && (Z_TYPE_PP(_GET) == IS_ARRAY)
402 ) {
403 zval *qstring = *QUERY_STRING, *qarray = *_GET;
404
405 if (Z_TYPE_P(qstring) != IS_STRING) {
406 convert_to_string(qstring);
407 }
408
409 MAKE_STD_ZVAL(instance);
410 ZVAL_OBJVAL(instance, php_http_querystring_object_new(php_http_querystring_class_entry TSRMLS_CC), 0);
411
412 zend_update_property(php_http_querystring_class_entry, instance, ZEND_STRL("queryArray"), qarray TSRMLS_CC);
413 zend_update_property(php_http_querystring_class_entry, instance, ZEND_STRL("queryString"), qstring TSRMLS_CC);
414
415 Z_SET_ISREF_P(zend_read_property(php_http_querystring_class_entry, instance, ZEND_STRL("queryArray"), 0 TSRMLS_CC));
416 Z_SET_ISREF_P(zend_read_property(php_http_querystring_class_entry, instance, ZEND_STRL("queryString"), 0 TSRMLS_CC));
417
418 zend_update_static_property(php_http_querystring_class_entry, ZEND_STRL("instance"), instance TSRMLS_CC);
419 zval_ptr_dtor(&instance);
420 } else {
421 php_http_error(HE_WARNING, PHP_HTTP_E_QUERYSTRING, "Could not acquire reference to superglobal GET or QUERY_STRING");
422 }
423 }
424 RETVAL_ZVAL(instance, 1, 0);
425 } end_error_handling();
426 }
427 } end_error_handling();
428 }
429
430 PHP_METHOD(HttpQueryString, getIterator)
431 {
432 with_error_handling(EH_THROW, PHP_HTTP_EX_CE(runtime)) {
433 if (SUCCESS == zend_parse_parameters_none()) {
434 with_error_handling(EH_THROW, PHP_HTTP_EX_CE(querystring)) {
435 zval *retval = NULL, *qa = zend_read_property(php_http_querystring_class_entry, getThis(), ZEND_STRL("queryArray"), 0 TSRMLS_CC);
436
437 object_init_ex(return_value, spl_ce_RecursiveArrayIterator);
438 zend_call_method_with_1_params(&return_value, spl_ce_RecursiveArrayIterator, NULL, "__construct", &retval, qa);
439 if (retval) {
440 zval_ptr_dtor(&retval);
441 }
442 } end_error_handling();
443 }
444 } end_error_handling();
445 }
446
447 PHP_METHOD(HttpQueryString, toString)
448 {
449 if (SUCCESS == zend_parse_parameters_none()) {
450 RETURN_PROP(php_http_querystring_class_entry, "queryString");
451 }
452 RETURN_EMPTY_STRING();
453 }
454
455 PHP_METHOD(HttpQueryString, toArray)
456 {
457 if (SUCCESS == zend_parse_parameters_none()) {
458 RETURN_PROP(php_http_querystring_class_entry, "queryArray");
459 }
460 RETURN_FALSE;
461 }
462
463 PHP_METHOD(HttpQueryString, get)
464 {
465 char *name_str = NULL;
466 int name_len = 0;
467 long type = 0;
468 zend_bool del = 0;
469 zval *ztype = NULL, *defval = NULL;
470
471 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|szzb", &name_str, &name_len, &ztype, &defval, &del)) {
472 if (name_str && name_len) {
473 if (ztype) {
474 if (Z_TYPE_P(ztype) == IS_LONG) {
475 type = Z_LVAL_P(ztype);
476 } else if(Z_TYPE_P(ztype) == IS_STRING) {
477 switch (Z_STRVAL_P(ztype)[0]) {
478 case 'B':
479 case 'b': type = PHP_HTTP_QUERYSTRING_TYPE_BOOL; break;
480 case 'L':
481 case 'l':
482 case 'I':
483 case 'i': type = PHP_HTTP_QUERYSTRING_TYPE_INT; break;
484 case 'd':
485 case 'D':
486 case 'F':
487 case 'f': type = PHP_HTTP_QUERYSTRING_TYPE_FLOAT; break;
488 case 'S':
489 case 's': type = PHP_HTTP_QUERYSTRING_TYPE_STRING; break;
490 case 'A':
491 case 'a': type = PHP_HTTP_QUERYSTRING_TYPE_ARRAY; break;
492 case 'O':
493 case 'o': type = PHP_HTTP_QUERYSTRING_TYPE_OBJECT; break;
494 }
495 }
496 }
497 php_http_querystring_get(getThis(), type, name_str, name_len, defval, del, return_value TSRMLS_CC);
498 } else {
499 RETURN_PROP(php_http_querystring_class_entry, "queryString");
500 }
501 }
502 }
503
504 PHP_METHOD(HttpQueryString, set)
505 {
506 zval *params;
507
508 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &params)) {
509 php_http_querystring_set(getThis(), params TSRMLS_CC);
510 RETURN_PROP(php_http_querystring_class_entry, "queryString");
511 }
512
513 RETURN_FALSE;
514 }
515
516 PHP_METHOD(HttpQueryString, mod)
517 {
518 zval *params;
519
520 with_error_handling(EH_THROW, PHP_HTTP_EX_CE(runtime)) {
521 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &params)) {
522 with_error_handling(EH_THROW, PHP_HTTP_EX_CE(querystring)) {
523 ZVAL_OBJVAL(return_value, Z_OBJ_HT_P(getThis())->clone_obj(getThis() TSRMLS_CC), 0);
524 php_http_querystring_set(return_value, params TSRMLS_CC);
525 } end_error_handling();
526 }
527 } end_error_handling();
528 }
529
530 #define PHP_HTTP_QUERYSTRING_GETTER(method, TYPE) \
531 PHP_METHOD(HttpQueryString, method) \
532 { \
533 char *name; \
534 int name_len; \
535 zval *defval = NULL; \
536 zend_bool del = 0; \
537 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|zb", &name, &name_len, &defval, &del)) { \
538 php_http_querystring_get(getThis(), TYPE, name, name_len, defval, del, return_value TSRMLS_CC); \
539 } \
540 }
541 PHP_HTTP_QUERYSTRING_GETTER(getBool, IS_BOOL);
542 PHP_HTTP_QUERYSTRING_GETTER(getInt, IS_LONG);
543 PHP_HTTP_QUERYSTRING_GETTER(getFloat, IS_DOUBLE);
544 PHP_HTTP_QUERYSTRING_GETTER(getString, IS_STRING);
545 PHP_HTTP_QUERYSTRING_GETTER(getArray, IS_ARRAY);
546 PHP_HTTP_QUERYSTRING_GETTER(getObject, IS_OBJECT);
547
548 #ifdef PHP_HTTP_HAVE_ICONV
549 PHP_METHOD(HttpQueryString, xlate)
550 {
551 with_error_handling(EH_THROW, PHP_HTTP_EX_CE(runtime)) {
552 char *ie, *oe;
553 int ie_len, oe_len;
554
555 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &ie, &ie_len, &oe, &oe_len)) {
556 with_error_handling(EH_THROW, PHP_HTTP_EX_CE(querystring)) {
557 zval *qa = zend_read_property(php_http_querystring_class_entry, getThis(), ZEND_STRL("queryArray"), 0 TSRMLS_CC);
558
559 if (Z_TYPE_P(qa) != IS_ARRAY) {
560 MAKE_STD_ZVAL(qa);
561 array_init(qa);
562 zend_update_property(php_http_querystring_class_entry, getThis(), ZEND_STRL("queryArray"), qa TSRMLS_CC);
563 zval_ptr_dtor(&qa);
564 } else {
565 zval xa;
566
567 INIT_PZVAL(&xa);
568 array_init(&xa);
569 if (SUCCESS == php_http_querystring_xlate(&xa, qa, ie, oe TSRMLS_CC)) {
570 zval *ns = NULL, *qs = zend_read_property(php_http_querystring_class_entry, getThis(), ZEND_STRL("queryString"), 0 TSRMLS_CC);
571
572 /* shitty internal zvals */
573 if (Z_TYPE_P(qs) != IS_STRING) {
574 MAKE_STD_ZVAL(qs);
575 ZVAL_EMPTY_STRING(qs);
576 zend_update_property(php_http_querystring_class_entry, getThis(), ZEND_STRL("queryString"), qs TSRMLS_CC);
577 ns = qs;
578 }
579
580 zend_hash_clean(Z_ARRVAL_P(qa));
581 array_copy(Z_ARRVAL(xa), Z_ARRVAL_P(qa));
582 php_http_querystring_update(qa, qs TSRMLS_CC);
583
584 if (ns) {
585 zval_ptr_dtor(&ns);
586 }
587 }
588 zval_dtor(&xa);
589 }
590 RETVAL_ZVAL(getThis(), 1, 0);
591 } end_error_handling();
592 }
593 } end_error_handling();
594
595 }
596 #endif /* HAVE_ICONV */
597
598 PHP_METHOD(HttpQueryString, serialize)
599 {
600 if (SUCCESS == zend_parse_parameters_none()) {
601 RETURN_PROP(php_http_querystring_class_entry, "queryString");
602 }
603 RETURN_FALSE;
604 }
605
606 PHP_METHOD(HttpQueryString, unserialize)
607 {
608 zval *serialized;
609
610 with_error_handling(EH_THROW, PHP_HTTP_EX_CE(runtime)) {
611 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &serialized)) {
612 with_error_handling(EH_THROW, PHP_HTTP_EX_CE(querystring)) {
613 if (Z_TYPE_P(serialized) == IS_STRING) {
614 php_http_querystring_set(getThis(), serialized TSRMLS_CC);
615 } else {
616 php_http_error(HE_WARNING, PHP_HTTP_E_QUERYSTRING, "Expected a string as parameter");
617 }
618 } end_error_handling();
619 }
620 } end_error_handling();
621 }
622
623 PHP_METHOD(HttpQueryString, offsetGet)
624 {
625 char *offset_str;
626 int offset_len;
627 zval **value;
628
629 if ((SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &offset_str, &offset_len))
630 && (SUCCESS == zend_hash_find(Z_ARRVAL_P(zend_read_property(php_http_querystring_class_entry, getThis(), ZEND_STRL("queryArray"), 0 TSRMLS_CC)), offset_str, offset_len + 1, (void *) &value))
631 ) {
632 RETVAL_ZVAL(*value, 1, 0);
633 }
634 }
635
636 PHP_METHOD(HttpQueryString, offsetSet)
637 {
638 char *offset_str;
639 int offset_len;
640 zval *value;
641
642 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &offset_str, &offset_len, &value)) {
643 zval *qarr = zend_read_property(php_http_querystring_class_entry, getThis(), ZEND_STRL("queryArray"), 0 TSRMLS_CC), *qstr = zend_read_property(php_http_querystring_class_entry, getThis(), ZEND_STRL("queryString"), 0 TSRMLS_CC);
644
645 Z_ADDREF_P(value);
646 add_assoc_zval_ex(qarr, offset_str, offset_len + 1, value);
647 php_http_querystring_update(qarr, qstr TSRMLS_CC);
648 }
649 }
650
651 PHP_METHOD(HttpQueryString, offsetExists)
652 {
653 char *offset_str;
654 int offset_len;
655 zval **value;
656
657 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &offset_str, &offset_len)) {
658 RETURN_BOOL((SUCCESS == zend_hash_find(Z_ARRVAL_P(zend_read_property(php_http_querystring_class_entry, getThis(), ZEND_STRL("queryArray"), 0 TSRMLS_CC)), offset_str, offset_len + 1, (void *) &value)) && (Z_TYPE_PP(value) != IS_NULL));
659 }
660 }
661
662 PHP_METHOD(HttpQueryString, offsetUnset)
663 {
664 char *offset_str;
665 int offset_len;
666
667 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &offset_str, &offset_len)) {
668 zval *qarr = zend_read_property(php_http_querystring_class_entry, getThis(), ZEND_STRL("queryArray"), 0 TSRMLS_CC);
669
670 if (SUCCESS == zend_hash_del(Z_ARRVAL_P(qarr), offset_str, offset_len + 1)) {
671 php_http_querystring_update(qarr, zend_read_property(php_http_querystring_class_entry, getThis(), ZEND_STRL("queryString"), 0 TSRMLS_CC) TSRMLS_CC);
672 }
673 }
674 }
675
676
677 /*
678 * Local variables:
679 * tab-width: 4
680 * c-basic-offset: 4
681 * End:
682 * vim600: noet sw=4 ts=4 fdm=marker
683 * vim<600: noet sw=4 ts=4
684 */