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