tests
[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 #ifdef PHP_HTTP_HAVE_ICONV
24 PHP_HTTP_API STATUS php_http_querystring_xlate(zval *dst, zval *src, const char *ie, const char *oe TSRMLS_DC)
25 {
26 HashPosition pos;
27 zval **entry = NULL;
28 char *xlate_str = NULL, *xkey;
29 size_t xlate_len = 0, xlen;
30 php_http_array_hashkey_t key = php_http_array_hashkey_init(0);
31
32 FOREACH_KEYVAL(pos, src, key, entry) {
33 if (key.type == HASH_KEY_IS_STRING) {
34 if (PHP_ICONV_ERR_SUCCESS != php_iconv_string(key.str, key.len-1, &xkey, &xlen, oe, ie)) {
35 php_http_error(HE_WARNING, PHP_HTTP_E_QUERYSTRING, "Failed to convert '%.*s' from '%s' to '%s'", key.len-1, key.str, ie, oe);
36 return FAILURE;
37 }
38 }
39
40 if (Z_TYPE_PP(entry) == IS_STRING) {
41 if (PHP_ICONV_ERR_SUCCESS != php_iconv_string(Z_STRVAL_PP(entry), Z_STRLEN_PP(entry), &xlate_str, &xlate_len, oe, ie)) {
42 if (key.type == HASH_KEY_IS_STRING) {
43 efree(xkey);
44 }
45 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);
46 return FAILURE;
47 }
48 if (key.type == HASH_KEY_IS_STRING) {
49 add_assoc_stringl_ex(dst, xkey, xlen+1, xlate_str, xlate_len, 0);
50 } else {
51 add_index_stringl(dst, key.num, xlate_str, xlate_len, 0);
52 }
53 } else if (Z_TYPE_PP(entry) == IS_ARRAY) {
54 zval *subarray;
55
56 MAKE_STD_ZVAL(subarray);
57 array_init(subarray);
58 if (key.type == HASH_KEY_IS_STRING) {
59 add_assoc_zval_ex(dst, xkey, xlen+1, subarray);
60 } else {
61 add_index_zval(dst, key.num, subarray);
62 }
63 if (SUCCESS != php_http_querystring_xlate(subarray, *entry, ie, oe TSRMLS_CC)) {
64 if (key.type == HASH_KEY_IS_STRING) {
65 efree(xkey);
66 }
67 return FAILURE;
68 }
69 }
70
71 if (key.type == HASH_KEY_IS_STRING) {
72 efree(xkey);
73 }
74 }
75 return SUCCESS;
76 }
77 #endif /* HAVE_ICONV */
78
79 PHP_HTTP_API STATUS php_http_querystring_update(zval *qarray, zval *params, zval *outstring TSRMLS_DC)
80 {
81 /* enforce proper type */
82 if (Z_TYPE_P(qarray) != IS_ARRAY) {
83 convert_to_array(qarray);
84 }
85
86 /* modify qarray */
87 if (params) {
88 HashPosition pos;
89 HashTable *ptr;
90 php_http_array_hashkey_t key = php_http_array_hashkey_init(0);
91 zval **params_entry, **qarray_entry;
92 zval zv, *zv_ptr = NULL;
93
94 INIT_PZVAL(&zv);
95 ZVAL_NULL(&zv);
96
97 /* squeeze the hash out of the zval */
98 if (Z_TYPE_P(params) == IS_OBJECT && instanceof_function(Z_OBJCE_P(params), php_http_querystring_class_entry TSRMLS_CC)) {
99 zv_ptr = php_http_ztyp(IS_ARRAY, zend_read_property(php_http_querystring_class_entry, params, ZEND_STRL("queryArray"), 0 TSRMLS_CC));
100 ptr = Z_ARRVAL_P(zv_ptr);
101 } else if (Z_TYPE_P(params) == IS_OBJECT || Z_TYPE_P(params) == IS_ARRAY) {
102 ptr = HASH_OF(params);
103 } else {
104 zv_ptr = php_http_ztyp(IS_STRING, params);
105 array_init(&zv);
106 php_default_treat_data(PARSE_STRING, estrdup(Z_STRVAL_P(zv_ptr)), &zv TSRMLS_CC);
107 zval_ptr_dtor(&zv_ptr);
108 zv_ptr = NULL;
109 ptr = Z_ARRVAL(zv);
110 }
111
112 FOREACH_HASH_KEYVAL(pos, ptr, key, params_entry) {
113 /* only public properties */
114 if (key.type != HASH_KEY_IS_STRING || *key.str) {
115 if (Z_TYPE_PP(params_entry) == IS_NULL) {
116 /*
117 * delete
118 */
119 if (key.type == HASH_KEY_IS_STRING) {
120 zend_hash_del(Z_ARRVAL_P(qarray), key.str, key.len);
121 } else {
122 zend_hash_index_del(Z_ARRVAL_P(qarray), key.num);
123 }
124 } else if ( ((key.type == HASH_KEY_IS_STRING) && (SUCCESS == zend_hash_find(Z_ARRVAL_P(qarray), key.str, key.len, (void *) &qarray_entry)))
125 || ((key.type == HASH_KEY_IS_LONG) && (SUCCESS == zend_hash_index_find(Z_ARRVAL_P(qarray), key.num, (void *) &qarray_entry)))) {
126 /*
127 * update
128 */
129 zval equal, *entry = NULL;
130
131 /* recursive */
132 if (Z_TYPE_PP(params_entry) == IS_ARRAY || Z_TYPE_PP(params_entry) == IS_OBJECT) {
133 entry = php_http_zsep(1, IS_ARRAY, *qarray_entry);
134 php_http_querystring_update(entry, *params_entry, NULL TSRMLS_CC);
135 } else if ((FAILURE == is_equal_function(&equal, *qarray_entry, *params_entry TSRMLS_CC)) || !Z_BVAL(equal)) {
136 Z_ADDREF_PP(params_entry);
137 entry = *params_entry;
138 }
139
140 if (entry) {
141 if (key.type == HASH_KEY_IS_STRING) {
142 zend_hash_update(Z_ARRVAL_P(qarray), key.str, key.len, (void *) &entry, sizeof(zval *), NULL);
143 } else {
144 zend_hash_index_update(Z_ARRVAL_P(qarray), key.num, (void *) &entry, sizeof(zval *), NULL);
145 }
146 }
147 } else {
148 /*
149 * add
150 */
151 if (Z_TYPE_PP(params_entry) == IS_OBJECT) {
152 zval *new_array;
153
154 MAKE_STD_ZVAL(new_array);
155 array_init(new_array);
156 php_http_querystring_update(new_array, *params_entry, NULL TSRMLS_CC);
157 *params_entry = new_array;
158 } else {
159 Z_ADDREF_PP(params_entry);
160 }
161 if (key.type == HASH_KEY_IS_STRING) {
162 add_assoc_zval_ex(qarray, key.str, key.len, *params_entry);
163 } else {
164 add_index_zval(qarray, key.num, *params_entry);
165 }
166 }
167 }
168 }
169 /* clean up */
170 if (zv_ptr) {
171 zval_ptr_dtor(&zv_ptr);
172 }
173 zval_dtor(&zv);
174 }
175
176 /* serialize to string */
177 if (outstring) {
178 char *s;
179 size_t l;
180
181 if (SUCCESS == php_http_url_encode_hash(Z_ARRVAL_P(qarray), NULL, 0, &s, &l TSRMLS_CC)) {
182 zval_dtor(outstring);
183 ZVAL_STRINGL(outstring, s, l, 0);
184 } else {
185 php_http_error(HE_WARNING, PHP_HTTP_E_QUERYSTRING, "Failed to encode query string");
186 return FAILURE;
187 }
188 }
189
190 return SUCCESS;
191 }
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
307 zend_declare_class_constant_long(php_http_querystring_class_entry, ZEND_STRL("TYPE_BOOL"), PHP_HTTP_QUERYSTRING_TYPE_BOOL TSRMLS_CC);
308 zend_declare_class_constant_long(php_http_querystring_class_entry, ZEND_STRL("TYPE_INT"), PHP_HTTP_QUERYSTRING_TYPE_INT TSRMLS_CC);
309 zend_declare_class_constant_long(php_http_querystring_class_entry, ZEND_STRL("TYPE_FLOAT"), PHP_HTTP_QUERYSTRING_TYPE_FLOAT TSRMLS_CC);
310 zend_declare_class_constant_long(php_http_querystring_class_entry, ZEND_STRL("TYPE_STRING"), PHP_HTTP_QUERYSTRING_TYPE_STRING TSRMLS_CC);
311 zend_declare_class_constant_long(php_http_querystring_class_entry, ZEND_STRL("TYPE_ARRAY"), PHP_HTTP_QUERYSTRING_TYPE_ARRAY TSRMLS_CC);
312 zend_declare_class_constant_long(php_http_querystring_class_entry, ZEND_STRL("TYPE_OBJECT"), PHP_HTTP_QUERYSTRING_TYPE_OBJECT TSRMLS_CC);
313
314 return SUCCESS;
315 }
316
317 #define QS_MERGE 1
318
319 static inline void php_http_querystring_set(zval *instance, zval *params, int flags TSRMLS_DC)
320 {
321 zval *qa;
322
323 if (flags & QS_MERGE) {
324 qa = php_http_zsep(1, IS_ARRAY, zend_read_property(php_http_querystring_class_entry, instance, ZEND_STRL("queryArray"), 0 TSRMLS_CC));
325 } else {
326 MAKE_STD_ZVAL(qa);
327 array_init(qa);
328 }
329
330 php_http_querystring_update(qa, params, NULL TSRMLS_CC);
331 zend_update_property(php_http_querystring_class_entry, instance, ZEND_STRL("queryArray"), qa TSRMLS_CC);
332 zval_ptr_dtor(&qa);
333 }
334
335 static inline void php_http_querystring_str(zval *instance, zval *return_value TSRMLS_DC)
336 {
337 zval *qa = zend_read_property(php_http_querystring_class_entry, instance, ZEND_STRL("queryArray"), 0 TSRMLS_CC);
338
339 if (Z_TYPE_P(qa) == IS_ARRAY) {
340 php_http_querystring_update(qa, NULL, return_value TSRMLS_CC);
341 } else {
342 RETURN_EMPTY_STRING();
343 }
344 }
345
346 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)
347 {
348 zval **arrval, *qarray = zend_read_property(php_http_querystring_class_entry, getThis(), ZEND_STRL("queryArray"), 0 TSRMLS_CC);
349
350 if ((Z_TYPE_P(qarray) == IS_ARRAY) && (SUCCESS == zend_symtable_find(Z_ARRVAL_P(qarray), name, name_len + 1, (void *) &arrval))) {
351 if (type) {
352 zval *value = php_http_ztyp(type, *arrval);
353 RETVAL_ZVAL(value, 1, 1);
354 } else {
355 RETVAL_ZVAL(*arrval, 1, 0);
356 }
357
358 if (del) {
359 zval *delarr;
360
361 MAKE_STD_ZVAL(delarr);
362 array_init(delarr);
363 add_assoc_null_ex(delarr, name, name_len + 1);
364 php_http_querystring_set(this_ptr, delarr, QS_MERGE TSRMLS_CC);
365 zval_ptr_dtor(&delarr);
366 }
367 } else if(defval) {
368 RETURN_ZVAL(defval, 1, 0);
369 }
370 }
371 PHP_METHOD(HttpQueryString, __construct)
372 {
373 zval *params = NULL;
374
375 with_error_handling(EH_THROW, php_http_exception_class_entry) {
376 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z", &params)) {
377 with_error_handling(EH_THROW, php_http_exception_class_entry) {
378 php_http_querystring_set(getThis(), params, 0 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_exception_class_entry) {
387 if (SUCCESS == zend_parse_parameters_none()) {
388 with_error_handling(EH_THROW, php_http_exception_class_entry) {
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 **_GET = NULL;
393
394 zend_is_auto_global("_GET", lenof("_GET") TSRMLS_CC);
395
396 if ((SUCCESS == zend_hash_find(&EG(symbol_table), "_GET", sizeof("_GET"), (void *) &_GET))
397 && (Z_TYPE_PP(_GET) == IS_ARRAY)
398 ) {
399 MAKE_STD_ZVAL(instance);
400 ZVAL_OBJVAL(instance, php_http_querystring_object_new(php_http_querystring_class_entry TSRMLS_CC), 0);
401
402 SEPARATE_ZVAL_TO_MAKE_IS_REF(_GET);
403 convert_to_array(*_GET);
404 zend_update_property(php_http_querystring_class_entry, instance, ZEND_STRL("queryArray"), *_GET TSRMLS_CC);
405
406 zend_update_static_property(php_http_querystring_class_entry, ZEND_STRL("instance"), instance TSRMLS_CC);
407 zval_ptr_dtor(&instance);
408 } else {
409 php_http_error(HE_WARNING, PHP_HTTP_E_QUERYSTRING, "Could not acquire reference to superglobal GET array");
410 }
411 }
412 RETVAL_ZVAL(instance, 1, 0);
413 } end_error_handling();
414 }
415 } end_error_handling();
416 }
417
418 PHP_METHOD(HttpQueryString, getIterator)
419 {
420 with_error_handling(EH_THROW, php_http_exception_class_entry) {
421 if (SUCCESS == zend_parse_parameters_none()) {
422 with_error_handling(EH_THROW, php_http_exception_class_entry) {
423 zval *retval = NULL, *qa = zend_read_property(php_http_querystring_class_entry, getThis(), ZEND_STRL("queryArray"), 0 TSRMLS_CC);
424
425 object_init_ex(return_value, spl_ce_RecursiveArrayIterator);
426 zend_call_method_with_1_params(&return_value, spl_ce_RecursiveArrayIterator, NULL, "__construct", &retval, qa);
427 if (retval) {
428 zval_ptr_dtor(&retval);
429 }
430 } end_error_handling();
431 }
432 } end_error_handling();
433 }
434
435 PHP_METHOD(HttpQueryString, toString)
436 {
437 if (SUCCESS != zend_parse_parameters_none()) {
438 RETURN_FALSE;
439 }
440 php_http_querystring_str(getThis(), return_value TSRMLS_CC);
441 }
442
443 PHP_METHOD(HttpQueryString, toArray)
444 {
445 if (SUCCESS == zend_parse_parameters_none()) {
446 RETURN_PROP(php_http_querystring_class_entry, "queryArray");
447 }
448 RETURN_FALSE;
449 }
450
451 PHP_METHOD(HttpQueryString, get)
452 {
453 char *name_str = NULL;
454 int name_len = 0;
455 long type = 0;
456 zend_bool del = 0;
457 zval *ztype = NULL, *defval = NULL;
458
459 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|szzb", &name_str, &name_len, &ztype, &defval, &del)) {
460 if (name_str && name_len) {
461 if (ztype) {
462 if (Z_TYPE_P(ztype) == IS_LONG) {
463 type = Z_LVAL_P(ztype);
464 } else if(Z_TYPE_P(ztype) == IS_STRING) {
465 switch (Z_STRVAL_P(ztype)[0]) {
466 case 'B':
467 case 'b': type = PHP_HTTP_QUERYSTRING_TYPE_BOOL; break;
468 case 'L':
469 case 'l':
470 case 'I':
471 case 'i': type = PHP_HTTP_QUERYSTRING_TYPE_INT; break;
472 case 'd':
473 case 'D':
474 case 'F':
475 case 'f': type = PHP_HTTP_QUERYSTRING_TYPE_FLOAT; break;
476 case 'S':
477 case 's': type = PHP_HTTP_QUERYSTRING_TYPE_STRING; break;
478 case 'A':
479 case 'a': type = PHP_HTTP_QUERYSTRING_TYPE_ARRAY; break;
480 case 'O':
481 case 'o': type = PHP_HTTP_QUERYSTRING_TYPE_OBJECT; break;
482 }
483 }
484 }
485 php_http_querystring_get(getThis(), type, name_str, name_len, defval, del, return_value TSRMLS_CC);
486 } else {
487 php_http_querystring_str(getThis(), return_value TSRMLS_CC);
488 }
489 }
490 }
491
492 PHP_METHOD(HttpQueryString, set)
493 {
494 zval *params;
495
496 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &params)) {
497 RETURN_FALSE;
498 }
499
500 php_http_querystring_set(getThis(), params, QS_MERGE TSRMLS_CC);
501 RETVAL_ZVAL(getThis(), 1, 0);
502 }
503
504 PHP_METHOD(HttpQueryString, mod)
505 {
506 zval *params;
507
508 with_error_handling(EH_THROW, php_http_exception_class_entry) {
509 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &params)) {
510 with_error_handling(EH_THROW, php_http_exception_class_entry) {
511 ZVAL_OBJVAL(return_value, Z_OBJ_HT_P(getThis())->clone_obj(getThis() TSRMLS_CC), 0);
512 php_http_querystring_set(return_value, params, QS_MERGE TSRMLS_CC);
513 } end_error_handling();
514 }
515 } end_error_handling();
516 }
517
518 #define PHP_HTTP_QUERYSTRING_GETTER(method, TYPE) \
519 PHP_METHOD(HttpQueryString, method) \
520 { \
521 char *name; \
522 int name_len; \
523 zval *defval = NULL; \
524 zend_bool del = 0; \
525 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|zb", &name, &name_len, &defval, &del)) { \
526 php_http_querystring_get(getThis(), TYPE, name, name_len, defval, del, return_value TSRMLS_CC); \
527 } \
528 }
529 PHP_HTTP_QUERYSTRING_GETTER(getBool, IS_BOOL);
530 PHP_HTTP_QUERYSTRING_GETTER(getInt, IS_LONG);
531 PHP_HTTP_QUERYSTRING_GETTER(getFloat, IS_DOUBLE);
532 PHP_HTTP_QUERYSTRING_GETTER(getString, IS_STRING);
533 PHP_HTTP_QUERYSTRING_GETTER(getArray, IS_ARRAY);
534 PHP_HTTP_QUERYSTRING_GETTER(getObject, IS_OBJECT);
535
536 #ifdef PHP_HTTP_HAVE_ICONV
537 PHP_METHOD(HttpQueryString, xlate)
538 {
539 with_error_handling(EH_THROW, php_http_exception_class_entry) {
540 char *ie, *oe;
541 int ie_len, oe_len;
542
543 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &ie, &ie_len, &oe, &oe_len)) {
544 with_error_handling(EH_THROW, php_http_exception_class_entry) {
545 zval *na, *qa = php_http_ztyp(IS_ARRAY, zend_read_property(php_http_querystring_class_entry, getThis(), ZEND_STRL("queryArray"), 0 TSRMLS_CC));
546
547 MAKE_STD_ZVAL(na);
548 array_init(na);
549 if (SUCCESS == php_http_querystring_xlate(na, qa, ie, oe TSRMLS_CC)) {
550 php_http_querystring_set(getThis(), na, 0 TSRMLS_CC);
551 }
552
553 zval_ptr_dtor(&na);
554 zval_ptr_dtor(&qa);
555
556 RETVAL_ZVAL(getThis(), 1, 0);
557 } end_error_handling();
558 }
559 } end_error_handling();
560
561 }
562 #endif /* HAVE_ICONV */
563
564 PHP_METHOD(HttpQueryString, serialize)
565 {
566 if (SUCCESS != zend_parse_parameters_none()) {
567 RETURN_FALSE;
568 }
569 php_http_querystring_str(getThis(), return_value TSRMLS_CC);
570 }
571
572 PHP_METHOD(HttpQueryString, unserialize)
573 {
574 zval *serialized;
575
576 with_error_handling(EH_THROW, php_http_exception_class_entry) {
577 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &serialized)) {
578 with_error_handling(EH_THROW, php_http_exception_class_entry) {
579 if (Z_TYPE_P(serialized) == IS_STRING) {
580 php_http_querystring_set(getThis(), serialized, 0 TSRMLS_CC);
581 } else {
582 php_http_error(HE_WARNING, PHP_HTTP_E_QUERYSTRING, "Expected a string as parameter");
583 }
584 } end_error_handling();
585 }
586 } end_error_handling();
587 }
588
589 PHP_METHOD(HttpQueryString, offsetGet)
590 {
591 char *offset_str;
592 int offset_len;
593 zval **value;
594
595 if ((SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &offset_str, &offset_len))) {
596 zval *qa = zend_read_property(php_http_querystring_class_entry, getThis(), ZEND_STRL("queryArray"), 0 TSRMLS_CC);
597
598 if (Z_TYPE_P(qa) == IS_ARRAY
599 && SUCCESS == zend_symtable_find(Z_ARRVAL_P(qa), offset_str, offset_len + 1, (void *) &value)
600 ) {
601 RETVAL_ZVAL(*value, 1, 0);
602 }
603 }
604 }
605
606 PHP_METHOD(HttpQueryString, offsetSet)
607 {
608 char *offset_str;
609 int offset_len;
610 zval *value;
611
612 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &offset_str, &offset_len, &value)) {
613 zval *param;
614
615 MAKE_STD_ZVAL(param);
616 array_init(param);
617 Z_ADDREF_P(value);
618 add_assoc_zval_ex(param, offset_str, offset_len + 1, value);
619 php_http_querystring_set(getThis(), param, 0 TSRMLS_CC);
620 zval_ptr_dtor(&param);
621 }
622 }
623
624 PHP_METHOD(HttpQueryString, offsetExists)
625 {
626 char *offset_str;
627 int offset_len;
628 zval **value;
629
630 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &offset_str, &offset_len)) {
631 zval *qa = zend_read_property(php_http_querystring_class_entry, getThis(), ZEND_STRL("queryArray"), 0 TSRMLS_CC);
632
633 if (Z_TYPE_P(qa) == IS_ARRAY
634 && SUCCESS == zend_symtable_find(Z_ARRVAL_P(qa), offset_str, offset_len + 1, (void *) &value)
635 && Z_TYPE_PP(value) != IS_NULL
636 ) {
637 RETURN_TRUE;
638 }
639 RETURN_FALSE;
640 }
641 }
642
643 PHP_METHOD(HttpQueryString, offsetUnset)
644 {
645 char *offset_str;
646 int offset_len;
647
648 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &offset_str, &offset_len)) {
649 zval *param;
650
651 MAKE_STD_ZVAL(param);
652 array_init(param);
653 add_assoc_null_ex(param, offset_str, offset_len + 1);
654 php_http_querystring_set(getThis(), param, QS_MERGE TSRMLS_CC);
655 zval_ptr_dtor(&param);
656 }
657 }
658
659
660 /*
661 * Local variables:
662 * tab-width: 4
663 * c-basic-offset: 4
664 * End:
665 * vim600: noet sw=4 ts=4 fdm=marker
666 * vim<600: noet sw=4 ts=4
667 */