fix build with old curl version
[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 static int apply_querystring(void *pData TSRMLS_DC)
142 {
143 zval **val = pData;
144
145 if (Z_TYPE_PP(val) == IS_ARRAY) {
146 zval **zvalue;
147
148 if (SUCCESS == zend_hash_find(Z_ARRVAL_PP(val), ZEND_STRS("value"), (void *) &zvalue)) {
149 zval *tmp = *val;
150
151 Z_ADDREF_PP(zvalue);
152 *val = *zvalue;
153 zval_dtor(tmp);
154 Z_TYPE_P(tmp) = IS_NULL;
155 zval_ptr_dtor(&tmp);
156 }
157 }
158
159 return ZEND_HASH_APPLY_KEEP;
160 }
161
162 PHP_HTTP_API STATUS php_http_querystring_parse(HashTable *ht, const char *str, size_t len TSRMLS_DC)
163 {
164 STATUS rv = FAILURE;
165 php_http_params_opts_t opts;
166 php_http_params_token_t psep = { ZEND_STRL("&") }, *psepp[] = { &psep, NULL };
167 php_http_params_token_t vsep = { ZEND_STRL("=") }, *vsepp[] = { &vsep, NULL };
168 const char *asi_str = NULL;
169 size_t asi_len = 0;
170
171 opts.input.str = estrndup(str, len);
172 opts.input.len = len;
173 opts.param = psepp;
174 opts.arg = NULL;
175 opts.val = vsepp;
176 opts.flags = PHP_HTTP_PARAMS_QUERY;
177
178 if (SUCCESS == php_http_ini_entry(ZEND_STRL("arg_separator.input"), &asi_str, &asi_len, 0 TSRMLS_CC) && asi_len) {
179 zval *arr;
180
181 MAKE_STD_ZVAL(arr);
182 array_init_size(arr, asi_len);
183
184 do {
185 add_next_index_stringl(arr, asi_str++, 1, 1);
186 } while (*asi_str);
187
188 opts.param = php_http_params_separator_init(arr TSRMLS_CC);
189
190 zval_ptr_dtor(&arr);
191 }
192
193 MAKE_STD_ZVAL(opts.defval);
194 ZVAL_NULL(opts.defval);
195
196 if (php_http_params_parse(ht, &opts TSRMLS_CC)) {
197 zend_hash_apply(ht, apply_querystring TSRMLS_CC);
198 rv = SUCCESS;
199 }
200
201 if (asi_len) {
202 php_http_params_separator_free(opts.param);
203 }
204
205 zval_ptr_dtor(&opts.defval);
206 efree(opts.input.str);
207 return rv;
208 }
209
210 PHP_HTTP_API STATUS php_http_querystring_update(zval *qarray, zval *params, zval *outstring TSRMLS_DC)
211 {
212 /* enforce proper type */
213 if (Z_TYPE_P(qarray) != IS_ARRAY) {
214 convert_to_array(qarray);
215 }
216
217 /* modify qarray */
218 if (params) {
219 HashPosition pos;
220 HashTable *ptr;
221 php_http_array_hashkey_t key = php_http_array_hashkey_init(0);
222 zval **params_entry, **qarray_entry;
223 zval zv, *zv_ptr = NULL;
224
225 INIT_PZVAL(&zv);
226 ZVAL_NULL(&zv);
227
228 /* squeeze the hash out of the zval */
229 if (Z_TYPE_P(params) == IS_OBJECT && instanceof_function(Z_OBJCE_P(params), php_http_querystring_get_class_entry() TSRMLS_CC)) {
230 zv_ptr = php_http_ztyp(IS_ARRAY, zend_read_property(php_http_querystring_get_class_entry(), params, ZEND_STRL("queryArray"), 0 TSRMLS_CC));
231 ptr = Z_ARRVAL_P(zv_ptr);
232 } else if (Z_TYPE_P(params) == IS_OBJECT || Z_TYPE_P(params) == IS_ARRAY) {
233 ptr = HASH_OF(params);
234 } else {
235 zv_ptr = php_http_ztyp(IS_STRING, params);
236 array_init(&zv);
237 php_http_querystring_parse(Z_ARRVAL(zv), Z_STRVAL_P(zv_ptr), Z_STRLEN_P(zv_ptr) TSRMLS_CC);
238 zval_ptr_dtor(&zv_ptr);
239 zv_ptr = NULL;
240 ptr = Z_ARRVAL(zv);
241 }
242
243 FOREACH_HASH_KEYVAL(pos, ptr, key, params_entry) {
244 /* only public properties */
245 if (key.type != HASH_KEY_IS_STRING || *key.str) {
246 if (Z_TYPE_PP(params_entry) == IS_NULL) {
247 /*
248 * delete
249 */
250 if (key.type == HASH_KEY_IS_STRING) {
251 zend_hash_del(Z_ARRVAL_P(qarray), key.str, key.len);
252 } else {
253 zend_hash_index_del(Z_ARRVAL_P(qarray), key.num);
254 }
255 } else if ( ((key.type == HASH_KEY_IS_STRING) && (SUCCESS == zend_hash_find(Z_ARRVAL_P(qarray), key.str, key.len, (void *) &qarray_entry)))
256 || ((key.type == HASH_KEY_IS_LONG) && (SUCCESS == zend_hash_index_find(Z_ARRVAL_P(qarray), key.num, (void *) &qarray_entry)))) {
257 /*
258 * update
259 */
260 zval equal, *entry = NULL;
261
262 /* recursive */
263 if (Z_TYPE_PP(params_entry) == IS_ARRAY || Z_TYPE_PP(params_entry) == IS_OBJECT) {
264 entry = php_http_zsep(1, IS_ARRAY, *qarray_entry);
265 php_http_querystring_update(entry, *params_entry, NULL TSRMLS_CC);
266 } else if ((FAILURE == is_equal_function(&equal, *qarray_entry, *params_entry TSRMLS_CC)) || !Z_BVAL(equal)) {
267 Z_ADDREF_PP(params_entry);
268 entry = *params_entry;
269 }
270
271 if (entry) {
272 if (key.type == HASH_KEY_IS_STRING) {
273 zend_hash_update(Z_ARRVAL_P(qarray), key.str, key.len, (void *) &entry, sizeof(zval *), NULL);
274 } else {
275 zend_hash_index_update(Z_ARRVAL_P(qarray), key.num, (void *) &entry, sizeof(zval *), NULL);
276 }
277 }
278 } else {
279 zval *entry;
280 /*
281 * add
282 */
283 if (Z_TYPE_PP(params_entry) == IS_OBJECT) {
284 MAKE_STD_ZVAL(entry);
285 array_init(entry);
286 php_http_querystring_update(entry, *params_entry, NULL TSRMLS_CC);
287 } else {
288 Z_ADDREF_PP(params_entry);
289 entry = *params_entry;
290 }
291 if (key.type == HASH_KEY_IS_STRING) {
292 add_assoc_zval_ex(qarray, key.str, key.len, entry);
293 } else {
294 add_index_zval(qarray, key.num, entry);
295 }
296 }
297 }
298 }
299 /* clean up */
300 if (zv_ptr) {
301 zval_ptr_dtor(&zv_ptr);
302 }
303 zval_dtor(&zv);
304 }
305
306 /* serialize to string */
307 if (outstring) {
308 char *s;
309 size_t l;
310
311 if (SUCCESS == php_http_url_encode_hash(Z_ARRVAL_P(qarray), NULL, 0, &s, &l TSRMLS_CC)) {
312 zval_dtor(outstring);
313 ZVAL_STRINGL(outstring, s, l, 0);
314 } else {
315 php_http_error(HE_WARNING, PHP_HTTP_E_QUERYSTRING, "Failed to encode query string");
316 return FAILURE;
317 }
318 }
319
320 return SUCCESS;
321 }
322
323 #define PHP_HTTP_BEGIN_ARGS(method, req_args) PHP_HTTP_BEGIN_ARGS_EX(HttpQueryString, method, 0, req_args)
324 #define PHP_HTTP_EMPTY_ARGS(method) PHP_HTTP_EMPTY_ARGS_EX(HttpQueryString, method, 0)
325 #define PHP_HTTP_QUERYSTRING_ME(method, visibility) PHP_ME(HttpQueryString, method, PHP_HTTP_ARGS(HttpQueryString, method), visibility)
326 #define PHP_HTTP_QUERYSTRING_GME(method, visibility) PHP_ME(HttpQueryString, method, PHP_HTTP_ARGS(HttpQueryString, __getter), visibility)
327
328 PHP_HTTP_BEGIN_ARGS(__construct, 0)
329 PHP_HTTP_ARG_VAL(params, 0)
330 PHP_HTTP_END_ARGS;
331
332 PHP_HTTP_EMPTY_ARGS(getGlobalInstance);
333
334 PHP_HTTP_EMPTY_ARGS(toArray);
335 PHP_HTTP_EMPTY_ARGS(toString);
336
337 PHP_HTTP_BEGIN_ARGS(get, 0)
338 PHP_HTTP_ARG_VAL(name, 0)
339 PHP_HTTP_ARG_VAL(type, 0)
340 PHP_HTTP_ARG_VAL(defval, 0)
341 PHP_HTTP_ARG_VAL(delete, 0)
342 PHP_HTTP_END_ARGS;
343
344 PHP_HTTP_BEGIN_ARGS(set, 1)
345 PHP_HTTP_ARG_VAL(params, 0)
346 PHP_HTTP_END_ARGS;
347
348 PHP_HTTP_BEGIN_ARGS(mod, 0)
349 PHP_HTTP_ARG_VAL(params, 0)
350 PHP_HTTP_END_ARGS;
351
352 PHP_HTTP_BEGIN_ARGS(__getter, 1)
353 PHP_HTTP_ARG_VAL(name, 0)
354 PHP_HTTP_ARG_VAL(defval, 0)
355 PHP_HTTP_ARG_VAL(delete, 0)
356 PHP_HTTP_END_ARGS;
357
358 #ifdef PHP_HTTP_HAVE_ICONV
359 PHP_HTTP_BEGIN_ARGS(xlate, 2)
360 PHP_HTTP_ARG_VAL(from_encoding, 0)
361 PHP_HTTP_ARG_VAL(to_encoding, 0)
362 PHP_HTTP_END_ARGS;
363 #endif
364
365 PHP_HTTP_EMPTY_ARGS(serialize);
366 PHP_HTTP_BEGIN_ARGS(unserialize, 1)
367 PHP_HTTP_ARG_VAL(serialized, 0)
368 PHP_HTTP_END_ARGS;
369
370 PHP_HTTP_BEGIN_ARGS(offsetGet, 1)
371 PHP_HTTP_ARG_VAL(offset, 0)
372 PHP_HTTP_END_ARGS;
373
374 PHP_HTTP_BEGIN_ARGS(offsetSet, 2)
375 PHP_HTTP_ARG_VAL(offset, 0)
376 PHP_HTTP_ARG_VAL(value, 0)
377 PHP_HTTP_END_ARGS;
378
379 PHP_HTTP_BEGIN_ARGS(offsetExists, 1)
380 PHP_HTTP_ARG_VAL(offset, 0)
381 PHP_HTTP_END_ARGS;
382
383 PHP_HTTP_BEGIN_ARGS(offsetUnset, 1)
384 PHP_HTTP_ARG_VAL(offset, 0)
385 PHP_HTTP_END_ARGS;
386
387 PHP_HTTP_EMPTY_ARGS(getIterator);
388
389 static zend_class_entry *php_http_querystring_class_entry;
390
391 zend_class_entry *php_http_querystring_get_class_entry(void)
392 {
393 return php_http_querystring_class_entry;
394 }
395
396 static zend_function_entry php_http_querystring_method_entry[] = {
397 PHP_HTTP_QUERYSTRING_ME(__construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR|ZEND_ACC_FINAL)
398
399 PHP_HTTP_QUERYSTRING_ME(toArray, ZEND_ACC_PUBLIC)
400 PHP_HTTP_QUERYSTRING_ME(toString, ZEND_ACC_PUBLIC)
401 ZEND_MALIAS(HttpQueryString, __toString, toString, PHP_HTTP_ARGS(HttpQueryString, toString), ZEND_ACC_PUBLIC)
402
403 PHP_HTTP_QUERYSTRING_ME(get, ZEND_ACC_PUBLIC)
404 PHP_HTTP_QUERYSTRING_ME(set, ZEND_ACC_PUBLIC)
405 PHP_HTTP_QUERYSTRING_ME(mod, ZEND_ACC_PUBLIC)
406
407 PHP_HTTP_QUERYSTRING_GME(getBool, ZEND_ACC_PUBLIC)
408 PHP_HTTP_QUERYSTRING_GME(getInt, ZEND_ACC_PUBLIC)
409 PHP_HTTP_QUERYSTRING_GME(getFloat, ZEND_ACC_PUBLIC)
410 PHP_HTTP_QUERYSTRING_GME(getString, ZEND_ACC_PUBLIC)
411 PHP_HTTP_QUERYSTRING_GME(getArray, ZEND_ACC_PUBLIC)
412 PHP_HTTP_QUERYSTRING_GME(getObject, ZEND_ACC_PUBLIC)
413
414 PHP_HTTP_QUERYSTRING_ME(getIterator, ZEND_ACC_PUBLIC)
415
416 PHP_HTTP_QUERYSTRING_ME(getGlobalInstance, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
417 #ifdef PHP_HTTP_HAVE_ICONV
418 PHP_HTTP_QUERYSTRING_ME(xlate, ZEND_ACC_PUBLIC)
419 #endif
420
421 /* Implements Serializable */
422 PHP_HTTP_QUERYSTRING_ME(serialize, ZEND_ACC_PUBLIC)
423 PHP_HTTP_QUERYSTRING_ME(unserialize, ZEND_ACC_PUBLIC)
424
425 /* Implements ArrayAccess */
426 PHP_HTTP_QUERYSTRING_ME(offsetGet, ZEND_ACC_PUBLIC)
427 PHP_HTTP_QUERYSTRING_ME(offsetSet, ZEND_ACC_PUBLIC)
428 PHP_HTTP_QUERYSTRING_ME(offsetExists, ZEND_ACC_PUBLIC)
429 PHP_HTTP_QUERYSTRING_ME(offsetUnset, ZEND_ACC_PUBLIC)
430
431 EMPTY_FUNCTION_ENTRY
432 };
433
434 PHP_MINIT_FUNCTION(http_querystring)
435 {
436 PHP_HTTP_REGISTER_CLASS(http, QueryString, http_querystring, php_http_object_get_class_entry(), 0);
437
438 zend_class_implements(php_http_querystring_class_entry TSRMLS_CC, 3, zend_ce_serializable, zend_ce_arrayaccess, zend_ce_aggregate);
439
440 zend_declare_property_null(php_http_querystring_class_entry, ZEND_STRL("instance"), (ZEND_ACC_STATIC|ZEND_ACC_PRIVATE) TSRMLS_CC);
441 zend_declare_property_null(php_http_querystring_class_entry, ZEND_STRL("queryArray"), ZEND_ACC_PRIVATE TSRMLS_CC);
442
443 zend_declare_class_constant_long(php_http_querystring_class_entry, ZEND_STRL("TYPE_BOOL"), PHP_HTTP_QUERYSTRING_TYPE_BOOL TSRMLS_CC);
444 zend_declare_class_constant_long(php_http_querystring_class_entry, ZEND_STRL("TYPE_INT"), PHP_HTTP_QUERYSTRING_TYPE_INT TSRMLS_CC);
445 zend_declare_class_constant_long(php_http_querystring_class_entry, ZEND_STRL("TYPE_FLOAT"), PHP_HTTP_QUERYSTRING_TYPE_FLOAT TSRMLS_CC);
446 zend_declare_class_constant_long(php_http_querystring_class_entry, ZEND_STRL("TYPE_STRING"), PHP_HTTP_QUERYSTRING_TYPE_STRING TSRMLS_CC);
447 zend_declare_class_constant_long(php_http_querystring_class_entry, ZEND_STRL("TYPE_ARRAY"), PHP_HTTP_QUERYSTRING_TYPE_ARRAY TSRMLS_CC);
448 zend_declare_class_constant_long(php_http_querystring_class_entry, ZEND_STRL("TYPE_OBJECT"), PHP_HTTP_QUERYSTRING_TYPE_OBJECT TSRMLS_CC);
449
450 return SUCCESS;
451 }
452
453 PHP_METHOD(HttpQueryString, __construct)
454 {
455 zval *params = NULL;
456
457 with_error_handling(EH_THROW, php_http_exception_get_class_entry()) {
458 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z", &params)) {
459 with_error_handling(EH_THROW, php_http_exception_get_class_entry()) {
460 php_http_querystring_set(getThis(), params, 0 TSRMLS_CC);
461 } end_error_handling();
462 }
463 } end_error_handling();
464 }
465
466 PHP_METHOD(HttpQueryString, getGlobalInstance)
467 {
468 with_error_handling(EH_THROW, php_http_exception_get_class_entry()) {
469 if (SUCCESS == zend_parse_parameters_none()) {
470 with_error_handling(EH_THROW, php_http_exception_get_class_entry()) {
471 zval *instance = *zend_std_get_static_property(php_http_querystring_class_entry, ZEND_STRL("instance"), 0 PHP_HTTP_ZEND_LITERAL_CCN TSRMLS_CC);
472
473 if (Z_TYPE_P(instance) != IS_OBJECT) {
474 zval **_GET = NULL;
475
476 zend_is_auto_global("_GET", lenof("_GET") TSRMLS_CC);
477
478 if ((SUCCESS == zend_hash_find(&EG(symbol_table), "_GET", sizeof("_GET"), (void *) &_GET))
479 && (Z_TYPE_PP(_GET) == IS_ARRAY)
480 ) {
481 MAKE_STD_ZVAL(instance);
482 ZVAL_OBJVAL(instance, php_http_querystring_object_new(php_http_querystring_class_entry TSRMLS_CC), 0);
483
484 SEPARATE_ZVAL_TO_MAKE_IS_REF(_GET);
485 convert_to_array(*_GET);
486 zend_update_property(php_http_querystring_class_entry, instance, ZEND_STRL("queryArray"), *_GET TSRMLS_CC);
487
488 zend_update_static_property(php_http_querystring_class_entry, ZEND_STRL("instance"), instance TSRMLS_CC);
489 zval_ptr_dtor(&instance);
490 } else {
491 php_http_error(HE_WARNING, PHP_HTTP_E_QUERYSTRING, "Could not acquire reference to superglobal GET array");
492 }
493 }
494 RETVAL_ZVAL(instance, 1, 0);
495 } end_error_handling();
496 }
497 } end_error_handling();
498 }
499
500 PHP_METHOD(HttpQueryString, getIterator)
501 {
502 with_error_handling(EH_THROW, php_http_exception_get_class_entry()) {
503 if (SUCCESS == zend_parse_parameters_none()) {
504 with_error_handling(EH_THROW, php_http_exception_get_class_entry()) {
505 zval *retval = NULL, *qa = zend_read_property(php_http_querystring_class_entry, getThis(), ZEND_STRL("queryArray"), 0 TSRMLS_CC);
506
507 object_init_ex(return_value, spl_ce_RecursiveArrayIterator);
508 zend_call_method_with_1_params(&return_value, spl_ce_RecursiveArrayIterator, NULL, "__construct", &retval, qa);
509 if (retval) {
510 zval_ptr_dtor(&retval);
511 }
512 } end_error_handling();
513 }
514 } end_error_handling();
515 }
516
517 PHP_METHOD(HttpQueryString, toString)
518 {
519 if (SUCCESS != zend_parse_parameters_none()) {
520 RETURN_FALSE;
521 }
522 php_http_querystring_str(getThis(), return_value TSRMLS_CC);
523 }
524
525 PHP_METHOD(HttpQueryString, toArray)
526 {
527 if (SUCCESS == zend_parse_parameters_none()) {
528 RETURN_PROP(php_http_querystring_class_entry, "queryArray");
529 }
530 RETURN_FALSE;
531 }
532
533 PHP_METHOD(HttpQueryString, get)
534 {
535 char *name_str = NULL;
536 int name_len = 0;
537 long type = 0;
538 zend_bool del = 0;
539 zval *ztype = NULL, *defval = NULL;
540
541 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|szzb", &name_str, &name_len, &ztype, &defval, &del)) {
542 if (name_str && name_len) {
543 if (ztype) {
544 if (Z_TYPE_P(ztype) == IS_LONG) {
545 type = Z_LVAL_P(ztype);
546 } else if(Z_TYPE_P(ztype) == IS_STRING) {
547 switch (Z_STRVAL_P(ztype)[0]) {
548 case 'B':
549 case 'b': type = PHP_HTTP_QUERYSTRING_TYPE_BOOL; break;
550 case 'L':
551 case 'l':
552 case 'I':
553 case 'i': type = PHP_HTTP_QUERYSTRING_TYPE_INT; break;
554 case 'd':
555 case 'D':
556 case 'F':
557 case 'f': type = PHP_HTTP_QUERYSTRING_TYPE_FLOAT; break;
558 case 'S':
559 case 's': type = PHP_HTTP_QUERYSTRING_TYPE_STRING; break;
560 case 'A':
561 case 'a': type = PHP_HTTP_QUERYSTRING_TYPE_ARRAY; break;
562 case 'O':
563 case 'o': type = PHP_HTTP_QUERYSTRING_TYPE_OBJECT; break;
564 }
565 }
566 }
567 php_http_querystring_get(getThis(), type, name_str, name_len, defval, del, return_value TSRMLS_CC);
568 } else {
569 php_http_querystring_str(getThis(), return_value TSRMLS_CC);
570 }
571 }
572 }
573
574 PHP_METHOD(HttpQueryString, set)
575 {
576 zval *params;
577
578 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &params)) {
579 RETURN_FALSE;
580 }
581
582 php_http_querystring_set(getThis(), params, QS_MERGE TSRMLS_CC);
583 RETVAL_ZVAL(getThis(), 1, 0);
584 }
585
586 PHP_METHOD(HttpQueryString, mod)
587 {
588 zval *params;
589
590 with_error_handling(EH_THROW, php_http_exception_get_class_entry()) {
591 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &params)) {
592 with_error_handling(EH_THROW, php_http_exception_get_class_entry()) {
593 ZVAL_OBJVAL(return_value, Z_OBJ_HT_P(getThis())->clone_obj(getThis() TSRMLS_CC), 0);
594 php_http_querystring_set(return_value, params, QS_MERGE TSRMLS_CC);
595 } end_error_handling();
596 }
597 } end_error_handling();
598 }
599
600 #define PHP_HTTP_QUERYSTRING_GETTER(method, TYPE) \
601 PHP_METHOD(HttpQueryString, method) \
602 { \
603 char *name; \
604 int name_len; \
605 zval *defval = NULL; \
606 zend_bool del = 0; \
607 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|zb", &name, &name_len, &defval, &del)) { \
608 php_http_querystring_get(getThis(), TYPE, name, name_len, defval, del, return_value TSRMLS_CC); \
609 } \
610 }
611 PHP_HTTP_QUERYSTRING_GETTER(getBool, IS_BOOL);
612 PHP_HTTP_QUERYSTRING_GETTER(getInt, IS_LONG);
613 PHP_HTTP_QUERYSTRING_GETTER(getFloat, IS_DOUBLE);
614 PHP_HTTP_QUERYSTRING_GETTER(getString, IS_STRING);
615 PHP_HTTP_QUERYSTRING_GETTER(getArray, IS_ARRAY);
616 PHP_HTTP_QUERYSTRING_GETTER(getObject, IS_OBJECT);
617
618 #ifdef PHP_HTTP_HAVE_ICONV
619 PHP_METHOD(HttpQueryString, xlate)
620 {
621 with_error_handling(EH_THROW, php_http_exception_get_class_entry()) {
622 char *ie, *oe;
623 int ie_len, oe_len;
624
625 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &ie, &ie_len, &oe, &oe_len)) {
626 with_error_handling(EH_THROW, php_http_exception_get_class_entry()) {
627 zval *na, *qa = php_http_ztyp(IS_ARRAY, zend_read_property(php_http_querystring_class_entry, getThis(), ZEND_STRL("queryArray"), 0 TSRMLS_CC));
628
629 MAKE_STD_ZVAL(na);
630 array_init(na);
631 if (SUCCESS == php_http_querystring_xlate(na, qa, ie, oe TSRMLS_CC)) {
632 php_http_querystring_set(getThis(), na, 0 TSRMLS_CC);
633 }
634
635 zval_ptr_dtor(&na);
636 zval_ptr_dtor(&qa);
637
638 RETVAL_ZVAL(getThis(), 1, 0);
639 } end_error_handling();
640 }
641 } end_error_handling();
642
643 }
644 #endif /* HAVE_ICONV */
645
646 PHP_METHOD(HttpQueryString, serialize)
647 {
648 if (SUCCESS != zend_parse_parameters_none()) {
649 RETURN_FALSE;
650 }
651 php_http_querystring_str(getThis(), return_value TSRMLS_CC);
652 }
653
654 PHP_METHOD(HttpQueryString, unserialize)
655 {
656 zval *serialized;
657
658 with_error_handling(EH_THROW, php_http_exception_get_class_entry()) {
659 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &serialized)) {
660 with_error_handling(EH_THROW, php_http_exception_get_class_entry()) {
661 if (Z_TYPE_P(serialized) == IS_STRING) {
662 php_http_querystring_set(getThis(), serialized, 0 TSRMLS_CC);
663 } else {
664 php_http_error(HE_WARNING, PHP_HTTP_E_QUERYSTRING, "Expected a string as parameter");
665 }
666 } end_error_handling();
667 }
668 } end_error_handling();
669 }
670
671 PHP_METHOD(HttpQueryString, offsetGet)
672 {
673 char *offset_str;
674 int offset_len;
675 zval **value;
676
677 if ((SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &offset_str, &offset_len))) {
678 zval *qa = zend_read_property(php_http_querystring_class_entry, getThis(), ZEND_STRL("queryArray"), 0 TSRMLS_CC);
679
680 if (Z_TYPE_P(qa) == IS_ARRAY
681 && SUCCESS == zend_symtable_find(Z_ARRVAL_P(qa), offset_str, offset_len + 1, (void *) &value)
682 ) {
683 RETVAL_ZVAL(*value, 1, 0);
684 }
685 }
686 }
687
688 PHP_METHOD(HttpQueryString, offsetSet)
689 {
690 char *offset_str;
691 int offset_len;
692 zval *value;
693
694 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &offset_str, &offset_len, &value)) {
695 zval *param;
696
697 MAKE_STD_ZVAL(param);
698 array_init(param);
699 Z_ADDREF_P(value);
700 add_assoc_zval_ex(param, offset_str, offset_len + 1, value);
701 php_http_querystring_set(getThis(), param, 0 TSRMLS_CC);
702 zval_ptr_dtor(&param);
703 }
704 }
705
706 PHP_METHOD(HttpQueryString, offsetExists)
707 {
708 char *offset_str;
709 int offset_len;
710 zval **value;
711
712 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &offset_str, &offset_len)) {
713 zval *qa = zend_read_property(php_http_querystring_class_entry, getThis(), ZEND_STRL("queryArray"), 0 TSRMLS_CC);
714
715 if (Z_TYPE_P(qa) == IS_ARRAY
716 && SUCCESS == zend_symtable_find(Z_ARRVAL_P(qa), offset_str, offset_len + 1, (void *) &value)
717 && Z_TYPE_PP(value) != IS_NULL
718 ) {
719 RETURN_TRUE;
720 }
721 RETURN_FALSE;
722 }
723 }
724
725 PHP_METHOD(HttpQueryString, offsetUnset)
726 {
727 char *offset_str;
728 int offset_len;
729
730 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &offset_str, &offset_len)) {
731 zval *param;
732
733 MAKE_STD_ZVAL(param);
734 array_init(param);
735 add_assoc_null_ex(param, offset_str, offset_len + 1);
736 php_http_querystring_set(getThis(), param, QS_MERGE TSRMLS_CC);
737 zval_ptr_dtor(&param);
738 }
739 }
740
741
742 /*
743 * Local variables:
744 * tab-width: 4
745 * c-basic-offset: 4
746 * End:
747 * vim600: noet sw=4 ts=4 fdm=marker
748 * vim<600: noet sw=4 ts=4
749 */