2 +--------------------------------------------------------------------+
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-2007, Michael Wallner <mike@php.net> |
10 +--------------------------------------------------------------------+
15 #define HTTP_WANT_SAPI
18 #include "php_variables.h"
19 #ifdef HTTP_HAVE_ICONV
21 # include "ext/iconv/php_iconv.h"
22 # include "ext/standard/url.h"
25 #include "php_http_api.h"
26 #include "php_http_url_api.h"
27 #include "php_http_querystring_api.h"
30 #define THIS_CE http_querystring_object_ce
31 extern zend_class_entry
*http_querystring_object_ce
;
35 #define http_querystring_modify_array_ex(q, t, k, kl, i, pe) _http_querystring_modify_array_ex((q), (t), (k), (kl), (i), (pe) TSRMLS_CC)
36 static inline int _http_querystring_modify_array_ex(zval
*qarray
, int key_type
, char *key
, int keylen
, ulong idx
, zval
*params_entry TSRMLS_DC
);
37 #define http_querystring_modify_array(q, p) _http_querystring_modify_array((q), (p) TSRMLS_CC)
38 static inline int _http_querystring_modify_array(zval
*qarray
, zval
*params TSRMLS_DC
);
41 #ifdef HTTP_HAVE_ICONV
42 PHP_HTTP_API
int _http_querystring_xlate(zval
*array
, zval
*param
, const char *ie
, const char *oe TSRMLS_DC
)
46 char *xlate_str
= NULL
, *xkey
;
47 size_t xlate_len
= 0, xlen
;
48 HashKey key
= initHashKey(0);
50 FOREACH_KEYVAL(pos
, param
, key
, entry
) {
51 if (key
.type
== HASH_KEY_IS_STRING
) {
52 if (PHP_ICONV_ERR_SUCCESS
!= php_iconv_string(key
.str
, key
.len
-1, &xkey
, &xlen
, oe
, ie
)) {
53 http_error_ex(HE_WARNING
, HTTP_E_QUERYSTRING
, "Failed to convert '%.*s' from '%s' to '%s'", key
.len
-1, key
.str
, ie
, oe
);
58 if (Z_TYPE_PP(entry
) == IS_STRING
) {
59 if (PHP_ICONV_ERR_SUCCESS
!= php_iconv_string(Z_STRVAL_PP(entry
), Z_STRLEN_PP(entry
), &xlate_str
, &xlate_len
, oe
, ie
)) {
60 if (key
.type
== HASH_KEY_IS_STRING
) {
63 http_error_ex(HE_WARNING
, HTTP_E_QUERYSTRING
, "Failed to convert '%.*s' from '%s' to '%s'", Z_STRLEN_PP(entry
), Z_STRVAL_PP(entry
), ie
, oe
);
66 if (key
.type
== HASH_KEY_IS_STRING
) {
67 add_assoc_stringl_ex(array
, xkey
, xlen
+1, xlate_str
, xlate_len
, 0);
69 add_index_stringl(array
, key
.num
, xlate_str
, xlate_len
, 0);
71 } else if (Z_TYPE_PP(entry
) == IS_ARRAY
) {
74 MAKE_STD_ZVAL(subarray
);
76 if (key
.type
== HASH_KEY_IS_STRING
) {
77 add_assoc_zval_ex(array
, xkey
, xlen
+1, subarray
);
79 add_index_zval(array
, key
.num
, subarray
);
81 if (SUCCESS
!= http_querystring_xlate(subarray
, *entry
, ie
, oe
)) {
82 if (key
.type
== HASH_KEY_IS_STRING
) {
89 if (key
.type
== HASH_KEY_IS_STRING
) {
95 #endif /* HAVE_ICONV */
97 PHP_HTTP_API
void _http_querystring_update(zval
*qarray
, zval
*qstring TSRMLS_DC
)
102 if (Z_TYPE_P(qarray
) != IS_ARRAY
) {
103 convert_to_array(qarray
);
105 if (SUCCESS
== http_urlencode_hash_ex(Z_ARRVAL_P(qarray
), 0, NULL
, 0, &s
, &l
)) {
107 ZVAL_STRINGL(qstring
, s
, l
, 0);
109 http_error(HE_WARNING
, HTTP_E_QUERYSTRING
, "Failed to update query string");
113 PHP_HTTP_API
int _http_querystring_modify(zval
*qarray
, zval
*params TSRMLS_DC
)
115 if (Z_TYPE_P(params
) == IS_ARRAY
) {
116 return http_querystring_modify_array(qarray
, params
);
117 } else if (Z_TYPE_P(params
) == IS_OBJECT
) {
119 if (instanceof_function(Z_OBJCE_P(params
), http_querystring_object_ce TSRMLS_CC
)) {
120 return http_querystring_modify_array(qarray
, zend_read_property(THIS_CE
, params
, ZEND_STRS("queryArray")-1, 0 TSRMLS_CC
));
123 return http_querystring_modify_array(qarray
, params
);
130 zval
*qstring
= http_zsep(IS_STRING
, params
);
135 sapi_module
.treat_data(PARSE_STRING
, estrdup(Z_STRVAL_P(qstring
)), &array TSRMLS_CC
);
136 zval_ptr_dtor(&qstring
);
138 rv
= http_querystring_modify_array(qarray
, &array
);
144 static inline int _http_querystring_modify_array(zval
*qarray
, zval
*params TSRMLS_DC
)
147 HashKey key
= initHashKey(0);
149 zval
**params_entry
= NULL
;
151 FOREACH_HASH_KEYVAL(pos
, HASH_OF(params
), key
, params_entry
) {
152 /* only public properties */
153 if ((key
.type
!= HASH_KEY_IS_STRING
|| *key
.str
) && http_querystring_modify_array_ex(qarray
, key
.type
, key
.str
, key
.len
, key
.num
, *params_entry
)) {
161 static inline int _http_querystring_modify_array_ex(zval
*qarray
, int key_type
, char *key
, int keylen
, ulong idx
, zval
*params_entry TSRMLS_DC
)
165 /* ensure array type */
166 if (Z_TYPE_P(qarray
) != IS_ARRAY
) {
167 convert_to_array(qarray
);
171 if (Z_TYPE_P(params_entry
) == IS_NULL
) {
172 if (key_type
== HASH_KEY_IS_STRING
) {
173 return (SUCCESS
== zend_hash_del(Z_ARRVAL_P(qarray
), key
, keylen
));
175 return (SUCCESS
== zend_hash_index_del(Z_ARRVAL_P(qarray
), idx
));
180 if ( ((key_type
== HASH_KEY_IS_STRING
) && (SUCCESS
== zend_hash_find(Z_ARRVAL_P(qarray
), key
, keylen
, (void *) &qarray_entry
))) ||
181 ((key_type
== HASH_KEY_IS_LONG
) && (SUCCESS
== zend_hash_index_find(Z_ARRVAL_P(qarray
), idx
, (void *) &qarray_entry
)))) {
185 if (Z_TYPE_P(params_entry
) == IS_ARRAY
|| Z_TYPE_P(params_entry
) == IS_OBJECT
) {
186 return http_querystring_modify(*qarray_entry
, params_entry
);
189 if ((SUCCESS
== is_equal_function(&equal
, *qarray_entry
, params_entry TSRMLS_CC
)) && Z_BVAL(equal
)) {
195 if (Z_TYPE_P(params_entry
) == IS_OBJECT
) {
198 MAKE_STD_ZVAL(new_array
);
199 array_init(new_array
);
200 http_querystring_modify_array(new_array
, params_entry
);
201 params_entry
= new_array
;
203 ZVAL_ADDREF(params_entry
);
205 if (key_type
== HASH_KEY_IS_STRING
) {
206 add_assoc_zval_ex(qarray
, key
, keylen
, params_entry
);
208 add_index_zval(qarray
, idx
, params_entry
);
218 * vim600: noet sw=4 ts=4 fdm=marker
219 * vim<600: noet sw=4 ts=4