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