+#ifdef HAVE_ICONV
+#define http_querystring_xlate(a, p, ie, oe) _http_querystring_xlate((a), (p), (ie), (oe) TSRMLS_CC)
+static inline int _http_querystring_xlate(zval *array, zval *param, const char *ie, const char *oe TSRMLS_DC)
+{
+ HashPosition pos;
+ zval **entry = NULL;
+ char *xlate_str = NULL, *xkey, *kstr = NULL;
+ size_t xlate_len = 0, xlen;
+ uint klen = 0;
+ ulong kidx = 0;
+
+ FOREACH_KEYLENVAL(pos, param, kstr, klen, kidx, entry) {
+ if (kstr) {
+ if (PHP_ICONV_ERR_SUCCESS != php_iconv_string(kstr, klen-1, &xkey, &xlen, oe, ie)) {
+ http_error_ex(HE_WARNING, HTTP_E_QUERYSTRING, "Failed to convert '%.*s' from '%s' to '%s'", klen-1, kstr, ie, oe);
+ return FAILURE;
+ }
+ }
+
+ if (Z_TYPE_PP(entry) == IS_STRING) {
+ if (PHP_ICONV_ERR_SUCCESS != php_iconv_string(Z_STRVAL_PP(entry), Z_STRLEN_PP(entry), &xlate_str, &xlate_len, oe, ie)) {
+ if (kstr) {
+ efree(xkey);
+ }
+ 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);
+ return FAILURE;
+ }
+ if (kstr) {
+ add_assoc_stringl_ex(array, xkey, xlen+1, xlate_str, xlate_len, 0);
+ } else {
+ add_index_stringl(array, kidx, xlate_str, xlate_len, 0);
+ }
+ } else if (Z_TYPE_PP(entry) == IS_ARRAY) {
+ zval *subarray;
+
+ MAKE_STD_ZVAL(subarray);
+ array_init(subarray);
+ if (kstr) {
+ add_assoc_zval_ex(array, xkey, xlen+1, subarray);
+ } else {
+ add_index_zval(array, kidx, subarray);
+ }
+ if (SUCCESS != http_querystring_xlate(subarray, *entry, ie, oe)) {
+ if (kstr) {
+ efree(xkey);
+ }
+ return FAILURE;
+ }
+ }
+
+ if (kstr) {
+ kstr = NULL;
+ efree(xkey);
+ }
+ }
+ return SUCCESS;
+}
+#endif /* HAVE_ICONV */