+
+ if (Z_TYPE_P(zvalue) == IS_ARRAY) {
+ ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(zvalue), key.h, key.key, zargs)
+ {
+ if (zvalue == zparam && key.key && zend_string_equals_literal(key.key, "value")) {
+ continue;
+ }
+
+ php_http_arrkey_stringify(&key, NULL);
+ shift_arg(buf, key.key->val, key.key->len, zargs, ass, asl, vss, vsl, flags);
+ php_http_arrkey_dtor(&key);
+ }
+ ZEND_HASH_FOREACH_END();
+ }
+ }
+ ZEND_HASH_FOREACH_END();
+
+ php_http_buffer_shrink(buf);
+ php_http_buffer_fix(buf);
+
+ return buf;
+}
+
+php_http_params_token_t **php_http_params_separator_init(zval *zv)
+{
+ zval *sep, ztmp;
+ php_http_params_token_t **ret, **tmp;
+
+ if (!zv) {
+ return NULL;
+ }
+
+ ZVAL_DUP(&ztmp, zv);
+ zv = &ztmp;
+ convert_to_array(zv);
+
+ ret = ecalloc(zend_hash_num_elements(Z_ARRVAL_P(zv)) + 1, sizeof(*ret));
+
+ tmp = ret;
+ ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(zv), sep)
+ {
+ zend_string *zs = zval_get_string(sep);
+
+ if (zs->len) {
+ *tmp = emalloc(sizeof(**tmp));
+ (*tmp)->str = estrndup(zs->val, (*tmp)->len = zs->len);
+ ++tmp;
+ }
+ zend_string_release(zs);
+ }
+ ZEND_HASH_FOREACH_END();
+
+ zval_ptr_dtor(&ztmp);
+
+ *tmp = NULL;
+ return ret;
+}
+
+void php_http_params_separator_free(php_http_params_token_t **separator)
+{
+ php_http_params_token_t **sep = separator;
+ if (sep) {
+ while (*sep) {
+ PTR_FREE((*sep)->str);
+ efree(*sep);
+ ++sep;
+ }
+ efree(separator);
+ }
+}
+
+ZEND_BEGIN_ARG_INFO_EX(ai_HttpParams___construct, 0, 0, 0)
+ ZEND_ARG_INFO(0, params)
+ ZEND_ARG_INFO(0, param_sep)
+ ZEND_ARG_INFO(0, arg_sep)
+ ZEND_ARG_INFO(0, val_sep)
+ ZEND_ARG_INFO(0, flags)
+ZEND_END_ARG_INFO();
+PHP_METHOD(HttpParams, __construct)
+{
+ zval *zparams = NULL, *param_sep = NULL, *arg_sep = NULL, *val_sep = NULL;
+ zend_long flags = PHP_HTTP_PARAMS_DEFAULT;
+ zend_error_handling zeh;
+ zend_string *zs;
+
+ php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "|z!/z/z/z/l", &zparams, ¶m_sep, &arg_sep, &val_sep, &flags), invalid_arg, return);
+
+ zend_replace_error_handling(EH_THROW, php_http_exception_runtime_class_entry, &zeh);
+ {
+ switch (ZEND_NUM_ARGS()) {
+ case 5:
+ zend_update_property_long(php_http_params_class_entry, getThis(), ZEND_STRL("flags"), flags);
+ /* no break */
+ case 4:
+ zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("val_sep"), val_sep);
+ /* no break */
+ case 3:
+ zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("arg_sep"), arg_sep);
+ /* no break */
+ case 2:
+ zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("param_sep"), param_sep);
+ /* no break */
+ }
+
+ if (zparams) {
+ switch (Z_TYPE_P(zparams)) {
+ case IS_OBJECT:
+ case IS_ARRAY:
+ convert_to_array(zparams);
+ zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), zparams);
+ break;
+ default:
+ zs = zval_get_string(zparams);
+ if (zs->len) {
+ zval tmp;
+
+ php_http_params_opts_t opts = {
+ {zs->val, zs->len},
+ php_http_params_separator_init(zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("param_sep"), 0, &tmp)),
+ php_http_params_separator_init(zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("arg_sep"), 0, &tmp)),
+ php_http_params_separator_init(zend_read_property(php_http_params_class_entry, getThis(), ZEND_STRL("val_sep"), 0, &tmp)),
+ {{0}}, flags
+ };
+
+ array_init(&tmp);
+ php_http_params_parse(Z_ARRVAL(tmp), &opts);
+ zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("params"), &tmp);
+ zval_ptr_dtor(&tmp);
+
+ php_http_params_separator_free(opts.param);
+ php_http_params_separator_free(opts.arg);
+ php_http_params_separator_free(opts.val);
+ }
+ zend_string_release(zs);
+ break;
+ }