+#ifdef HAVE_ICONV
+/* {{{ proto bool HttpQueryString::iconv(string ie, string oe)
+ *
+ * Converts the query string from the source encoding ie to the target encoding oe.
+ * WARNING: Don't use any character set that can contain NUL bytes like UTF-16.
+ *
+ * Returns TRUE on success or FALSE on failure.
+ */
+PHP_METHOD(HttpQueryString, iconv)
+{
+ char *ie, *oe, *er = NULL;
+ int ie_len, oe_len;
+ size_t er_len = 0;
+ zval *qa, *qs;
+
+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &ie, &ie_len, &oe, &oe_len)) {
+ RETURN_FALSE;
+ }
+
+ qa = GET_PROP(queryArray);
+ qs = GET_PROP(queryString);
+ Z_STRLEN_P(qs) = php_url_decode(Z_STRVAL_P(qs), Z_STRLEN_P(qs));
+ if (PHP_ICONV_ERR_SUCCESS == php_iconv_string(Z_STRVAL_P(qs), (size_t) Z_STRLEN_P(qs), &er, &er_len, oe, ie)) {
+ efree(Z_STRVAL_P(qs));
+ ZVAL_STRINGL(qs, er, er_len, 0);
+ http_querystring_modify(qa, qs);
+ RETVAL_TRUE;
+ } else {
+ http_error_ex(HE_WARNING, HTTP_E_QUERYSTRING, "Failed to convert '%.*s' from '%s' to '%s'", Z_STRLEN_P(qs), Z_STRVAL_P(qs), ie, oe);
+ RETVAL_FALSE;
+ }
+ http_querystring_update(qa, qs);
+}
+/* }}} */
+#endif /* HAVE_ICONV */
+
+/* {{{ proto string HttpQueryString::serialize()
+ *
+ * Implements Serializable.
+ */
+PHP_METHOD(HttpQueryString, serialize)
+{
+ NO_ARGS;
+ RETURN_PROP(queryString);
+}
+/* }}} */
+
+/* {{{ proto void HttpQueryString::unserialize(string serialized)
+ *
+ * Implements Serializable.
+ */
+PHP_METHOD(HttpQueryString, unserialize)
+{
+ zval *serialized;
+
+ SET_EH_THROW_HTTP();
+ if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &serialized)) {
+ if (Z_TYPE_P(serialized) == IS_STRING) {
+ zval *qa = GET_PROP(queryArray);
+
+ zend_hash_clean(Z_ARRVAL_P(qa));
+ http_querystring_modify(qa, serialized);
+ http_querystring_update(qa, GET_PROP(queryString));
+ } else {
+ http_error(HE_WARNING, HTTP_E_QUERYSTRING, "Expected a string as parameter");
+ }
+ }
+ SET_EH_NORMAL();
+}
+/* }}} */
+