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