- adjust ini entry names to those of the globals struct
[m6w6/ext-http] / http_querystring_api.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-2006, Michael Wallner <mike@php.net> |
10 +--------------------------------------------------------------------+
11 */
12
13 /* $Id$ */
14
15 #define HTTP_WANT_SAPI
16 #include "php_http.h"
17
18 #include "php_variables.h"
19 #ifdef HAVE_ICONV
20 # undef PHP_ATOM_INC
21 # include "ext/iconv/php_iconv.h"
22 # include "ext/standard/url.h"
23 #endif
24
25 #include "php_http_api.h"
26 #include "php_http_url_api.h"
27 #include "php_http_querystring_api.h"
28
29 #ifdef ZEND_ENGINE_2
30 #define OBJ_PROP_CE http_querystring_object_ce
31 extern zend_class_entry *http_querystring_object_ce;
32 #endif
33
34
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);
39
40
41 #ifdef HAVE_ICONV
42 PHP_HTTP_API int _http_querystring_xlate(zval *array, zval *param, const char *ie, const char *oe TSRMLS_DC)
43 {
44 HashPosition pos;
45 zval **entry = NULL;
46 char *xlate_str = NULL, *xkey, *kstr = NULL;
47 size_t xlate_len = 0, xlen;
48 uint klen = 0;
49 ulong kidx = 0;
50
51 FOREACH_KEYLENVAL(pos, param, kstr, klen, kidx, entry) {
52 if (kstr) {
53 if (PHP_ICONV_ERR_SUCCESS != php_iconv_string(kstr, klen-1, &xkey, &xlen, oe, ie)) {
54 http_error_ex(HE_WARNING, HTTP_E_QUERYSTRING, "Failed to convert '%.*s' from '%s' to '%s'", klen-1, kstr, ie, oe);
55 return FAILURE;
56 }
57 }
58
59 if (Z_TYPE_PP(entry) == IS_STRING) {
60 if (PHP_ICONV_ERR_SUCCESS != php_iconv_string(Z_STRVAL_PP(entry), Z_STRLEN_PP(entry), &xlate_str, &xlate_len, oe, ie)) {
61 if (kstr) {
62 efree(xkey);
63 }
64 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);
65 return FAILURE;
66 }
67 if (kstr) {
68 add_assoc_stringl_ex(array, xkey, xlen+1, xlate_str, xlate_len, 0);
69 } else {
70 add_index_stringl(array, kidx, xlate_str, xlate_len, 0);
71 }
72 } else if (Z_TYPE_PP(entry) == IS_ARRAY) {
73 zval *subarray;
74
75 MAKE_STD_ZVAL(subarray);
76 array_init(subarray);
77 if (kstr) {
78 add_assoc_zval_ex(array, xkey, xlen+1, subarray);
79 } else {
80 add_index_zval(array, kidx, subarray);
81 }
82 if (SUCCESS != http_querystring_xlate(subarray, *entry, ie, oe)) {
83 if (kstr) {
84 efree(xkey);
85 }
86 return FAILURE;
87 }
88 }
89
90 if (kstr) {
91 kstr = NULL;
92 efree(xkey);
93 }
94 }
95 return SUCCESS;
96 }
97 #endif /* HAVE_ICONV */
98
99 PHP_HTTP_API void _http_querystring_update(zval *qarray, zval *qstring TSRMLS_DC)
100 {
101 char *s = NULL;
102 size_t l = 0;
103
104 if (Z_TYPE_P(qarray) != IS_ARRAY) {
105 convert_to_array(qarray);
106 }
107 if (SUCCESS == http_urlencode_hash_ex(Z_ARRVAL_P(qarray), 0, NULL, 0, &s, &l)) {
108 zval_dtor(qstring);
109 ZVAL_STRINGL(qstring, s, l, 0);
110 } else {
111 http_error(HE_WARNING, HTTP_E_QUERYSTRING, "Failed to update query string");
112 }
113 }
114
115 PHP_HTTP_API int _http_querystring_modify(zval *qarray, zval *params TSRMLS_DC)
116 {
117 if (Z_TYPE_P(params) == IS_ARRAY) {
118 return http_querystring_modify_array(qarray, params);
119 } else if (Z_TYPE_P(params) == IS_OBJECT) {
120 #ifdef ZEND_ENGINE_2
121 if (!instanceof_function(Z_OBJCE_P(params), http_querystring_object_ce TSRMLS_CC)) {
122 #endif
123 zval temp_array;
124 INIT_ZARR(temp_array, HASH_OF(params));
125 return http_querystring_modify_array(qarray, &temp_array);
126 #ifdef ZEND_ENGINE_2
127 }
128 return http_querystring_modify_array(qarray, GET_PROP_EX(params, queryArray));
129 #endif
130 } else {
131 int rv;
132 zval array;
133
134 INIT_PZVAL(&array);
135 array_init(&array);
136
137 ZVAL_ADDREF(params);
138 convert_to_string_ex(&params);
139 sapi_module.treat_data(PARSE_STRING, estrdup(Z_STRVAL_P(params)), &array TSRMLS_CC);
140 zval_ptr_dtor(&params);
141 rv = http_querystring_modify_array(qarray, &array);
142 zval_dtor(&array);
143 return rv;
144 }
145 }
146
147 static inline int _http_querystring_modify_array(zval *qarray, zval *params TSRMLS_DC)
148 {
149 int rv = 0;
150 char *key = NULL;
151 uint keylen = 0;
152 ulong idx = 0;
153 HashPosition pos;
154 zval **params_entry = NULL;
155
156 FOREACH_KEYLENVAL(pos, params, key, keylen, idx, params_entry) {
157 if (http_querystring_modify_array_ex(qarray, key ? HASH_KEY_IS_STRING : HASH_KEY_IS_LONG, key, keylen, idx, *params_entry)) {
158 rv = 1;
159 }
160 key = NULL;
161 }
162
163 return rv;
164 }
165
166 static inline int _http_querystring_modify_array_ex(zval *qarray, int key_type, char *key, int keylen, ulong idx, zval *params_entry TSRMLS_DC)
167 {
168 zval **qarray_entry;
169
170 /* delete */
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));
174 } else {
175 return (SUCCESS == zend_hash_index_del(Z_ARRVAL_P(qarray), idx));
176 }
177 }
178
179 /* update */
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)))) {
182 zval equal;
183
184 /* recursive */
185 if (Z_TYPE_P(params_entry) == IS_ARRAY) {
186 return http_querystring_modify_array(*qarray_entry, params_entry);
187 }
188 /* equal */
189 if ((SUCCESS == is_equal_function(&equal, *qarray_entry, params_entry TSRMLS_CC)) && Z_BVAL(equal)) {
190 return 0;
191 }
192 }
193
194 /* add */
195 ZVAL_ADDREF(params_entry);
196 if (key_type == HASH_KEY_IS_STRING) {
197 add_assoc_zval_ex(qarray, key, keylen, params_entry);
198 } else {
199 add_index_zval(qarray, idx, params_entry);
200 }
201 return 1;
202 }
203
204 /*
205 * Local variables:
206 * tab-width: 4
207 * c-basic-offset: 4
208 * End:
209 * vim600: noet sw=4 ts=4 fdm=marker
210 * vim<600: noet sw=4 ts=4
211 */