+
+ return buf.data;
+}
+
+char *php_http_url_authority_to_string(const php_http_url_t *url, char **url_str, size_t *url_len)
+{
+ php_http_buffer_t buf;
+
+ php_http_buffer_init(&buf);
+
+ if (url->user && *url->user) {
+ php_http_buffer_appendl(&buf, url->user);
+ if (url->pass && *url->pass) {
+ php_http_buffer_appends(&buf, ":");
+ php_http_buffer_appendl(&buf, url->pass);
+ }
+ php_http_buffer_appends(&buf, "@");
+ }
+
+ if (url->host && *url->host) {
+ php_http_buffer_appendl(&buf, url->host);
+ if (url->port) {
+ php_http_buffer_appendf(&buf, ":%hu", url->port);
+ }
+ }
+
+ php_http_buffer_shrink(&buf);
+ php_http_buffer_fix(&buf);
+
+ if (url_len) {
+ *url_len = buf.used;
+ }
+
+ if (url_str) {
+ *url_str = buf.data;
+ }
+
+ return buf.data;
+}
+
+php_http_url_t *php_http_url_from_zval(zval *value, unsigned flags)
+{
+ zend_string *zs;
+ php_http_url_t *purl;
+
+ switch (Z_TYPE_P(value)) {
+ case IS_ARRAY:
+ case IS_OBJECT:
+ purl = php_http_url_from_struct(HASH_OF(value));
+ break;
+
+ default:
+ zs = zval_get_string(value);
+ purl = php_http_url_parse(zs->val, zs->len, flags);
+ zend_string_release(zs);
+ }
+
+ return purl;
+}
+
+php_http_url_t *php_http_url_from_struct(HashTable *ht)
+{
+ zval *e;
+ php_http_buffer_t buf;
+
+ php_http_buffer_init_ex(&buf, MAX(PHP_HTTP_BUFFER_DEFAULT_SIZE, sizeof(php_http_url_t)<<2), PHP_HTTP_BUFFER_INIT_PREALLOC);
+ php_http_buffer_account(&buf, sizeof(php_http_url_t));
+ memset(buf.data, 0, buf.used);
+
+ if ((e = zend_hash_str_find_ind(ht, ZEND_STRL("scheme")))) {
+ zend_string *zs = zval_get_string(e);
+ url(buf)->scheme = &buf.data[buf.used];
+ url_append(&buf, php_http_buffer_append(&buf, zs->val, zs->len + 1));
+ zend_string_release(zs);
+ }
+ if ((e = zend_hash_str_find_ind(ht, ZEND_STRL("user")))) {
+ zend_string *zs = zval_get_string(e);
+ url(buf)->user = &buf.data[buf.used];
+ url_append(&buf, php_http_buffer_append(&buf, zs->val, zs->len + 1));
+ zend_string_release(zs);
+ }
+ if ((e = zend_hash_str_find_ind(ht, ZEND_STRL("pass")))) {
+ zend_string *zs = zval_get_string(e);
+ url(buf)->pass = &buf.data[buf.used];
+ url_append(&buf, php_http_buffer_append(&buf, zs->val, zs->len + 1));
+ zend_string_release(zs);
+ }
+ if ((e = zend_hash_str_find_ind(ht, ZEND_STRL("host")))) {
+ zend_string *zs = zval_get_string(e);
+ url(buf)->host = &buf.data[buf.used];
+ url_append(&buf, php_http_buffer_append(&buf, zs->val, zs->len + 1));
+ zend_string_release(zs);
+ }
+ if ((e = zend_hash_str_find_ind(ht, ZEND_STRL("port")))) {
+ url(buf)->port = (unsigned short) zval_get_long(e);
+ }
+ if ((e = zend_hash_str_find_ind(ht, ZEND_STRL("path")))) {
+ zend_string *zs = zval_get_string(e);
+ url(buf)->path = &buf.data[buf.used];
+ url_append(&buf, php_http_buffer_append(&buf, zs->val, zs->len + 1));
+ zend_string_release(zs);
+ }
+ if ((e = zend_hash_str_find_ind(ht, ZEND_STRL("query")))) {
+ zend_string *zs = zval_get_string(e);
+ url(buf)->query = &buf.data[buf.used];
+ url_append(&buf, php_http_buffer_append(&buf, zs->val, zs->len + 1));
+ zend_string_release(zs);
+ }
+ if ((e = zend_hash_str_find_ind(ht, ZEND_STRL("fragment")))) {
+ zend_string *zs = zval_get_string(e);
+ url(buf)->fragment = &buf.data[buf.used];
+ url_append(&buf, php_http_buffer_append(&buf, zs->val, zs->len + 1));
+ zend_string_release(zs);
+ }
+
+ return url(buf);
+}
+
+HashTable *php_http_url_to_struct(const php_http_url_t *url, zval *strct)
+{
+ HashTable *ht;
+ zval tmp;
+
+ if (strct) {
+ switch (Z_TYPE_P(strct)) {
+ default:
+ zval_dtor(strct);
+ array_init(strct);
+ /* no break */
+ case IS_ARRAY:
+ case IS_OBJECT:
+ ht = HASH_OF(strct);
+ break;
+ }