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