Backport v4 updates
[m6w6/ext-http] / src / php_http_message.c
index d09b0b46f4cd874ccc485b0e00b533521f1acde3..2014aac8f4087a4cb587127fdba5e42f30a2cb38 100644 (file)
@@ -509,8 +509,9 @@ zend_class_entry *php_http_message_get_class_entry(void)
        return php_http_message_class_entry;
 }
 
-static zval *php_http_message_object_read_prop(zend_object *object, zend_string *member, int type, void **cache_slot, zval *rv);
-static zval *php_http_message_object_write_prop(zend_object *object, zend_string *member, zval *value, void **cache_slot);
+static zval *php_http_message_object_read_prop(zval *object, zval *member, int type, void **cache_slot, zval *rv);
+
+static PHP_WRITE_PROP_HANDLER_TYPE php_http_message_object_write_prop(zval *object, zval *member, zval *value, void **cache_slot);
 
 static zend_object_handlers php_http_message_object_handlers;
 static HashTable php_http_message_object_prophandlers;
@@ -688,6 +689,8 @@ static void php_http_message_object_prophandler_set_parent_message(php_http_mess
        do { \
                if (!obj->message) { \
                        obj->message = php_http_message_init(NULL, 0, NULL); \
+               } else if (!obj->body && php_http_message_body_size(obj->message->body)) { \
+                       php_http_message_object_init_body_object(obj); \
                } \
        } while(0)
 
@@ -856,10 +859,10 @@ php_http_message_object_t *php_http_message_object_new_ex(zend_class_entry *ce,
        return o;
 }
 
-zend_object *php_http_message_object_clone(zend_object *this_ptr)
+zend_object *php_http_message_object_clone(zval *this_ptr)
 {
        php_http_message_object_t *new_obj;
-       php_http_message_object_t *old_obj = PHP_HTTP_OBJ(this_ptr, NULL);
+       php_http_message_object_t *old_obj = PHP_HTTP_OBJ(NULL, this_ptr);
 
        new_obj = php_http_message_object_new_ex(old_obj->zo.ce, php_http_message_copy(old_obj->message, NULL));
        zend_objects_clone_members(&new_obj->zo, &old_obj->zo);
@@ -894,48 +897,67 @@ void php_http_message_object_free(zend_object *object)
        zend_object_std_dtor(object);
 }
 
-static zval *php_http_message_object_get_prop_ptr(zend_object *object, zend_string *member, int type, void **cache_slot)
+#if PHP_VERSION_ID >= 70400
+static zval *php_http_message_object_get_prop_ptr(zval *object, zval *member, int type, void **cache_slot)
 {
        return NULL;
 }
+#endif
 
-static zval *php_http_message_object_read_prop(zend_object *object, zend_string *member, int type, void **cache_slot, zval *tmp)
+static zval *php_http_message_object_read_prop(zval *object, zval *member, int type, void **cache_slot, zval *tmp)
 {
        zval *return_value;
-       php_http_message_object_prophandler_t *handler = php_http_message_object_get_prophandler(member);
+       zend_string *member_name = zval_get_string(member);
+       php_http_message_object_prophandler_t *handler = php_http_message_object_get_prophandler(member_name);
 
        return_value = zend_get_std_object_handlers()->read_property(object, member, type, cache_slot, tmp);
 
        if (handler && handler->read) {
-               php_http_message_object_t *obj = PHP_HTTP_OBJ(object, NULL);
+               if (type == BP_VAR_R || type == BP_VAR_IS) {
+                       php_http_message_object_t *obj = PHP_HTTP_OBJ(NULL, object);
+
+                       handler->read(obj, return_value);
+               } else {
+                       php_property_proxy_t *proxy;
+                       php_property_proxy_object_t *proxy_obj;
+
+                       proxy = php_property_proxy_init(object, member_name);
+                       proxy_obj = php_property_proxy_object_new_ex(NULL, proxy);
 
-               handler->read(obj, return_value);
+                       ZVAL_OBJ(tmp, &proxy_obj->zo);
+                       return_value = tmp;
+               }
        }
+
+       zend_string_release(member_name);
        return return_value;
 }
 
-static zval *php_http_message_object_write_prop(zend_object *object, zend_string *member, zval *value, void **cache_slot)
+static PHP_WRITE_PROP_HANDLER_TYPE php_http_message_object_write_prop(zval *object, zval *member, zval *value, void **cache_slot)
 {
-       php_http_message_object_t *obj = PHP_HTTP_OBJ(object, NULL);
+       php_http_message_object_t *obj = PHP_HTTP_OBJ(NULL, object);
        php_http_message_object_prophandler_t *handler;
+       zend_string *member_name = zval_get_string(member);
 
        PHP_HTTP_MESSAGE_OBJECT_INIT(obj);
 
-       if ((handler = php_http_message_object_get_prophandler(member))) {
+       if ((handler = php_http_message_object_get_prophandler(member_name))) {
                handler->write(obj, value);
        } else {
                zend_get_std_object_handlers()->write_property(object, member, value, cache_slot);
        }
-       return value;
+
+       zend_string_release(member_name);
+       PHP_WRITE_PROP_HANDLER_RETURN(value);
 }
 
-static HashTable *php_http_message_object_get_debug_info(zend_object *object, int *is_temp)
+static HashTable *php_http_message_object_get_debug_info(zval *object, int *is_temp)
 {
-       php_http_message_object_t *obj = PHP_HTTP_OBJ(object, NULL);
+       zval tmp;
+       php_http_message_object_t *obj = PHP_HTTP_OBJ(NULL, object);
        HashTable *props = zend_get_std_object_handlers()->get_properties(object);
        char *ver_str, *url_str = NULL;
        size_t ver_len, url_len = 0;
-       zval tmp;
 
        PHP_HTTP_MESSAGE_OBJECT_INIT(obj);
        if (is_temp) {
@@ -1010,10 +1032,10 @@ static HashTable *php_http_message_object_get_debug_info(zend_object *object, in
        return props;
 }
 
-static HashTable *php_http_message_object_get_gc(zend_object *object, zval **table, int *n)
+static HashTable *php_http_message_object_get_gc(zval *object, zval **table, int *n)
 {
-       php_http_message_object_t *obj = PHP_HTTP_OBJ(object, NULL);
-       HashTable *props = object->handlers->get_properties(object);
+       php_http_message_object_t *obj = PHP_HTTP_OBJ(NULL, object);
+       HashTable *props = Z_OBJPROP_P(object);
        uint32_t count = 2 + zend_hash_num_elements(props);
        zval *val;
 
@@ -1036,30 +1058,6 @@ static HashTable *php_http_message_object_get_gc(zend_object *object, zval **tab
        return NULL;
 }
 
-static int php_http_message_object_cast(zend_object *object, zval *return_value, int type)
-{
-       php_http_message_object_t *obj = PHP_HTTP_OBJ(object, NULL);
-       char *string;
-       size_t length;
-
-       switch (type) {
-       case IS_STRING:
-               PHP_HTTP_MESSAGE_OBJECT_INIT(obj);
-               php_http_message_to_string(obj->message, &string, &length);
-               if (string) {
-                       RETVAL_STR(php_http_cs2zs(string, length));
-               } else {
-                       RETVAL_EMPTY_STRING();
-               }
-               return SUCCESS;
-       case _IS_BOOL:
-               RETVAL_TRUE;
-               return SUCCESS;
-       default:
-               return FAILURE;
-       }
-}
-
 ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage___construct, 0, 0, 0)
        ZEND_ARG_INFO(0, message)
        ZEND_ARG_INFO(0, greedy)
@@ -1764,57 +1762,6 @@ static PHP_METHOD(HttpMessage, toCallback)
        }
 }
 
-ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(ai_HttpMessage___serialize, 0, 0, IS_ARRAY, 0)
-ZEND_END_ARG_INFO();
-static PHP_METHOD(HttpMessage, __serialize)
-{
-       zend_ulong num_index;
-       zend_string *str_index;
-       zend_property_info *pi;
-       php_http_message_object_t *obj = PHP_HTTP_OBJ(NULL, getThis());
-       HashTable *props = php_http_message_object_get_debug_info(&obj->zo, NULL);
-
-       zend_parse_parameters_none();
-
-       array_init(return_value);
-
-       ZEND_HASH_FOREACH_KEY_PTR(&obj->zo.ce->properties_info, num_index, str_index, pi)
-       {
-               zval *val;
-               if (str_index && (val = zend_hash_find_ind(props, pi->name))) {
-                       Z_TRY_ADDREF_P(val);
-                       zend_hash_update(Z_ARRVAL_P(return_value), str_index, val);
-               }
-       }
-       ZEND_HASH_FOREACH_END();
-}
-
-ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(ai_HttpMessage___unserialize, 0, 1, IS_VOID, 0)
-       ZEND_ARG_TYPE_INFO(0, data, IS_ARRAY, 0)
-ZEND_END_ARG_INFO();
-static PHP_METHOD(HttpMessage, __unserialize)
-{
-       HashTable *arr;
-       zend_string *key;
-       zval *val;
-       php_http_message_object_t *obj = PHP_HTTP_OBJ(NULL, getThis());
-
-       php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "h", &arr), invalid_arg, return);
-
-       PHP_HTTP_MESSAGE_OBJECT_INIT(obj);
-
-       ZEND_HASH_FOREACH_STR_KEY_VAL(arr, key, val)
-       {
-               php_http_message_object_prophandler_t *ph = php_http_message_object_get_prophandler(key);
-               if (ph) {
-                       ph->write(obj, val);
-               } else {
-                       zend_update_property_ex(php_http_message_class_entry, &obj->zo, key, val);
-               }
-       }
-       ZEND_HASH_FOREACH_END();
-}
-
 ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_serialize, 0, 0, 0)
 ZEND_END_ARG_INFO();
 static PHP_METHOD(HttpMessage, serialize)
@@ -1969,7 +1916,7 @@ static PHP_METHOD(HttpMessage, splitMultipartBody)
        RETURN_OBJ(&php_http_message_object_new_ex(obj->zo.ce, msg)->zo);
 }
 
-ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(ai_HttpMessage_count, 0, 0, IS_LONG, 0)
+ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_count, 0, 0, 0)
 ZEND_END_ARG_INFO();
 static PHP_METHOD(HttpMessage, count)
 {
@@ -1984,7 +1931,7 @@ static PHP_METHOD(HttpMessage, count)
        }
 }
 
-ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(ai_HttpMessage_rewind, 0, 0, IS_VOID, 0)
+ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_rewind, 0, 0, 0)
 ZEND_END_ARG_INFO();
 static PHP_METHOD(HttpMessage, rewind)
 {
@@ -1999,7 +1946,7 @@ static PHP_METHOD(HttpMessage, rewind)
        }
 }
 
-ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(ai_HttpMessage_valid, 0, 0, _IS_BOOL, 0)
+ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_valid, 0, 0, 0)
 ZEND_END_ARG_INFO();
 static PHP_METHOD(HttpMessage, valid)
 {
@@ -2010,7 +1957,7 @@ static PHP_METHOD(HttpMessage, valid)
        }
 }
 
-ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(ai_HttpMessage_next, 0, 0, IS_VOID, 0)
+ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_next, 0, 0, 0)
 ZEND_END_ARG_INFO();
 static PHP_METHOD(HttpMessage, next)
 {
@@ -2034,7 +1981,7 @@ static PHP_METHOD(HttpMessage, next)
        }
 }
 
-ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(ai_HttpMessage_key, 0, 0, IS_LONG, 0)
+ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_key, 0, 0, 0)
 ZEND_END_ARG_INFO();
 static PHP_METHOD(HttpMessage, key)
 {
@@ -2045,7 +1992,7 @@ static PHP_METHOD(HttpMessage, key)
        }
 }
 
-ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(ai_HttpMessage_current, 0, 0, http\\Message, 0)
+ZEND_BEGIN_ARG_INFO_EX(ai_HttpMessage_current, 0, 0, 0)
 ZEND_END_ARG_INFO();
 static PHP_METHOD(HttpMessage, current)
 {
@@ -2094,8 +2041,6 @@ static zend_function_entry php_http_message_methods[] = {
        /* implements Serializable */
        PHP_ME(HttpMessage, serialize,          ai_HttpMessage_serialize,          ZEND_ACC_PUBLIC)
        PHP_ME(HttpMessage, unserialize,        ai_HttpMessage_unserialize,        ZEND_ACC_PUBLIC)
-       PHP_ME(HttpMessage, __serialize,        ai_HttpMessage___serialize,        ZEND_ACC_PUBLIC)
-       PHP_ME(HttpMessage, __unserialize,      ai_HttpMessage___unserialize,      ZEND_ACC_PUBLIC)
 
        /* implements Iterator */
        PHP_ME(HttpMessage, rewind,             ai_HttpMessage_rewind,             ZEND_ACC_PUBLIC)
@@ -2130,11 +2075,14 @@ PHP_MINIT_FUNCTION(http_message)
        php_http_message_object_handlers.read_property = php_http_message_object_read_prop;
        php_http_message_object_handlers.write_property = php_http_message_object_write_prop;
        php_http_message_object_handlers.get_debug_info = php_http_message_object_get_debug_info;
+#if PHP_VERSION_ID >= 70400
        php_http_message_object_handlers.get_property_ptr_ptr = php_http_message_object_get_prop_ptr;
+#else
+       php_http_message_object_handlers.get_property_ptr_ptr = NULL;
+#endif
        php_http_message_object_handlers.get_gc = php_http_message_object_get_gc;
-       php_http_message_object_handlers.cast_object = php_http_message_object_cast;
 
-       zend_class_implements(php_http_message_class_entry, 3, zend_ce_countable, zend_ce_serializable, zend_ce_iterator);
+       zend_class_implements(php_http_message_class_entry, 3, spl_ce_Countable, zend_ce_serializable, zend_ce_iterator);
 
        zend_hash_init(&php_http_message_object_prophandlers, 9, NULL, php_http_message_object_prophandler_hash_dtor, 1);
        zend_declare_property_long(php_http_message_class_entry, ZEND_STRL("type"), PHP_HTTP_NONE, ZEND_ACC_PROTECTED);