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