+static inline void shift_rfc5988(php_http_buffer_t *buf, char *key_str, size_t key_len, const char *ass, size_t asl, unsigned flags)
+{
+ char *str;
+ size_t len;
+
+ if (buf->used) {
+ php_http_buffer_append(buf, ass, asl);
+ }
+
+ prepare_key(flags, key_str, key_len, &str, &len);
+ php_http_buffer_appends(buf, "<");
+ php_http_buffer_append(buf, str, len);
+ php_http_buffer_appends(buf, ">");
+ efree(str);
+}
+
+static inline void shift_rfc5988_val(php_http_buffer_t *buf, zval *zv, const char *vss, size_t vsl, unsigned flags)
+{
+ zend_string *zs = zval_get_string(zv);
+
+ quote_string(&zs, 1);
+ php_http_buffer_append(buf, vss, vsl);
+ php_http_buffer_append(buf, zs->val, zs->len);
+
+ zend_string_release(zs);
+}
+
+static inline void shift_val(php_http_buffer_t *buf, zval *zvalue, const char *vss, size_t vsl, unsigned flags)
+{
+ zval tmp;
+ zend_string *zs;
+
+ switch (Z_TYPE_P(zvalue)) {
+ case IS_TRUE:
+ break;
+
+ case IS_FALSE:
+ php_http_buffer_append(buf, vss, vsl);
+ php_http_buffer_appends(buf, "0");
+ break;
+
+ default:
+ zs = zval_get_string(zvalue);
+
+ ZVAL_STR(&tmp, zs);
+ prepare_value(flags, &tmp);
+ php_http_buffer_append(buf, vss, vsl);
+ php_http_buffer_append(buf, Z_STRVAL(tmp), Z_STRLEN(tmp));
+
+ zval_ptr_dtor(&tmp);
+ break;
+ }
+}
+
+static void shift_arg(php_http_buffer_t *buf, char *key_str, size_t key_len, zval *zvalue, const char *ass, size_t asl, const char *vss, size_t vsl, unsigned flags)
+{
+ if (Z_TYPE_P(zvalue) == IS_ARRAY || Z_TYPE_P(zvalue) == IS_OBJECT) {
+ php_http_arrkey_t key;
+ HashTable *ht = HASH_OF(zvalue);
+ zval *val;
+ zend_bool rfc5987 = !strcmp(key_str, "*rfc5987*");
+
+ if (!rfc5987) {
+ shift_key(buf, key_str, key_len, ass, asl, flags);
+ }
+ ZEND_HASH_FOREACH_KEY_VAL_IND(ht, key.h, key.key, val)
+ {
+ /* did you mean recursion? */
+ php_http_arrkey_stringify(&key, NULL);
+ if (rfc5987 && (Z_TYPE_P(val) == IS_ARRAY || Z_TYPE_P(val) == IS_OBJECT)) {
+ shift_key(buf, key.key->val, key.key->len, ass, asl, flags);
+ shift_rfc5987(buf, val, vss, vsl, flags);
+ } else {
+ shift_arg(buf, key.key->val, key.key->len, val, ass, asl, vss, vsl, flags);
+ }
+ php_http_arrkey_dtor(&key);
+ }
+ ZEND_HASH_FOREACH_END();
+ } else {
+ shift_key(buf, key_str, key_len, ass, asl, flags);
+
+ if (flags & PHP_HTTP_PARAMS_RFC5988) {
+ switch (key_len) {
+ case lenof("rel"):
+ case lenof("title"):
+ case lenof("anchor"):
+ /* some args must be quoted */
+ if (0 <= php_http_select_str(key_str, 3, "rel", "title", "anchor")) {
+ shift_rfc5988_val(buf, zvalue, vss, vsl, flags);
+ return;