- add internal http_message_set_info()
authorMichael Wallner <mike@php.net>
Thu, 19 Jan 2006 18:07:29 +0000 (18:07 +0000)
committerMichael Wallner <mike@php.net>
Thu, 19 Jan 2006 18:07:29 +0000 (18:07 +0000)
- add HttpMessage::detach(), HttpMessage::prepend() and tests

http_functions.c
http_message_api.c
http_message_object.c
php_http_message_api.h
php_http_message_object.h

index d9acab978d3e21568fac7179f2fe5a48282436c2..cdddb81143d9ba91bb68227da1ac58674a510f2d 100644 (file)
@@ -41,8 +41,8 @@
  * Compose a valid HTTP date regarding RFC 822/1123
  * looking like: "Wed, 22 Dec 2004 11:34:47 GMT"
  *
- * Takes an optional unix timestamp as parameter.
- *  
+ * Accepts an optional unix timestamp as parameter.
+ *
  * Returns the HTTP date as string.
  */
 PHP_FUNCTION(http_date)
index 93c4bf1d5cbb1ba027511b45d3f2db12d769b59e..27f3d78228273ec502f2297387f60513e464043e 100644 (file)
@@ -37,22 +37,7 @@ static void _http_message_info_callback(http_message **message, HashTable **head
                (*headers) = &((*message)->hdrs);
        }
        
-       (*message)->http.version = info->http.version;
-       
-       switch (info->type)
-       {
-               case IS_HTTP_REQUEST:
-                       (*message)->type = HTTP_MSG_REQUEST;
-                       HTTP_INFO(*message).request.url = estrdup(HTTP_INFO(info).request.url);
-                       HTTP_INFO(*message).request.method = estrdup(HTTP_INFO(info).request.method);
-               break;
-               
-               case IS_HTTP_RESPONSE:
-                       (*message)->type = HTTP_MSG_RESPONSE;
-                       HTTP_INFO(*message).response.code = HTTP_INFO(info).response.code;
-                       HTTP_INFO(*message).response.status = estrdup(HTTP_INFO(info).response.status);
-               break;
-       }
+       http_message_set_info(*message, info);
 }
 
 #define http_message_init_type _http_message_init_type
@@ -119,6 +104,26 @@ PHP_HTTP_API void _http_message_set_type(http_message *message, http_message_typ
        }
 }
 
+PHP_HTTP_API void _http_message_set_info(http_message *message, http_info *info)
+{
+       message->http.version = info->http.version;
+       
+       switch (info->type)
+       {
+               case IS_HTTP_REQUEST:
+                       message->type = HTTP_MSG_REQUEST;
+                       HTTP_INFO(message).request.url = estrdup(HTTP_INFO(info).request.url);
+                       STR_SET(HTTP_INFO(message).request.method, estrdup(HTTP_INFO(info).request.method));
+                       break;
+               
+               case IS_HTTP_RESPONSE:
+                       message->type = HTTP_MSG_RESPONSE;
+                       HTTP_INFO(message).response.code = HTTP_INFO(info).response.code;
+                       STR_SET(HTTP_INFO(message).response.status, estrdup(HTTP_INFO(info).response.status));
+                       break;
+       }
+}
+
 PHP_HTTP_API http_message *_http_message_parse_ex(http_message *msg, const char *message, size_t message_length ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC TSRMLS_DC)
 {
        const char *body = NULL;
index 4634cabb143e7d2783b867d5ab548e46a0372680..8a4b4c626c5757c43675ae7487a3f5566ef457d2 100644 (file)
@@ -94,6 +94,12 @@ HTTP_BEGIN_ARGS(unserialize, 0, 1)
        HTTP_ARG_VAL(serialized, 0)
 HTTP_END_ARGS;
 
+HTTP_EMPTY_ARGS(detach, 0);
+
+HTTP_BEGIN_ARGS(prepend, 0, 1)
+       HTTP_ARG_OBJ(HttpMessage, message, 0)
+HTTP_END_ARGS;
+
 #define http_message_object_declare_default_properties() _http_message_object_declare_default_properties(TSRMLS_C)
 static inline void _http_message_object_declare_default_properties(TSRMLS_D);
 #define http_message_object_read_prop _http_message_object_read_prop
@@ -136,6 +142,10 @@ zend_function_entry http_message_object_fe[] = {
 
        HTTP_MESSAGE_ME(fromString, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
        
+       HTTP_MESSAGE_ME(detach, ZEND_ACC_PUBLIC)
+       
+       HTTP_MESSAGE_ME(prepend, ZEND_ACC_PUBLIC)
+       
        EMPTY_FUNCTION_ENTRY
 };
 static zend_object_handlers http_message_object_handlers;
@@ -235,6 +245,14 @@ void _http_message_object_free(zend_object *object TSRMLS_DC)
                http_message_dtor(o->message);
                efree(o->message);
        }
+       if (o->parent.handle) {
+               zval p;
+               
+               INIT_PZVAL(&p);
+               p.type = IS_OBJECT;
+               p.value.obj = o->parent;
+               zend_objects_store_del_ref(&p TSRMLS_CC);
+       }
        efree(o);
 }
 
@@ -1058,6 +1076,83 @@ PHP_METHOD(HttpMessage, unserialize)
 }
 /* }}} */
 
+/* {{{ proto HttpMessage HttpMessage::detach(void)
+ *
+ * Returns a clone of an HttpMessage object detached from any parent messages.
+ */
+PHP_METHOD(HttpMessage, detach)
+{
+       http_info info;
+       http_message *msg;
+       getObject(http_message_object, obj);
+       
+       NO_ARGS;
+       
+       info.type = obj->message->type;
+       memcpy(&HTTP_INFO(&info), &HTTP_INFO(obj->message), sizeof(struct http_info));
+       
+       msg = http_message_new();
+       http_message_set_info(msg, &info);
+       
+       zend_hash_copy(&msg->hdrs, &obj->message->hdrs, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
+       phpstr_append(&msg->body, PHPSTR_VAL(obj->message), PHPSTR_LEN(obj->message));
+       
+       RETURN_OBJVAL(http_message_object_new_ex(http_message_object_ce, msg, NULL));
+}
+/* }}} */
+
+/* {{{ proto void HttpMessage::prepend(HttpMessage message)
+ *
+ * Prepends message(s) to the HTTP message.
+ *
+ * Expects an HttpMessage object as parameter.
+ */
+PHP_METHOD(HttpMessage, prepend)
+{
+       zval *prepend;
+       zend_bool top = 1;
+       
+       if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|b", &prepend, http_message_object_ce, &top)) {
+               zval m;
+               http_message *save_parent_msg;
+               zend_object_value save_parent_obj;
+               getObject(http_message_object, obj);
+               getObjectEx(http_message_object, prepend_obj, prepend);
+               
+               INIT_PZVAL(&m);
+               m.type = IS_OBJECT;
+               
+               if (!top) {
+                       save_parent_obj = obj->parent;
+                       save_parent_msg = obj->message->parent;
+               } else {
+                       /* iterate to the most parent object */
+                       while (obj->parent.handle) {
+                               m.value.obj = obj->parent;
+                               obj = zend_object_store_get_object(&m TSRMLS_CC);
+                       }
+               }
+               
+               /* prepend */
+               obj->parent = prepend->value.obj;
+               obj->message->parent = prepend_obj->message;
+               
+               /* add ref */
+               zend_objects_store_add_ref(prepend TSRMLS_CC);
+               while (prepend_obj->parent.handle) {
+                       m.value.obj = prepend_obj->parent;
+                       zend_objects_store_add_ref(&m TSRMLS_CC);
+                       prepend_obj = zend_object_store_get_object(&m TSRMLS_CC);
+               }
+               
+               if (!top) {
+                       prepend_obj->parent = save_parent_obj;
+                       prepend_obj->message->parent = save_parent_msg;
+               }
+       }
+}
+/* }}} */
+
 #endif /* ZEND_ENGINE_2 */
 
 /*
index 37ccb2ce89475fe30152795839ed97e81100dd3e..cf942567d371411cabcb44aef8781ae4611ccdd1 100644 (file)
@@ -48,6 +48,9 @@ PHP_HTTP_API http_message *_http_message_init_ex(http_message *m, http_message_t
 #define http_message_set_type(m, t) _http_message_set_type((m), (t))
 PHP_HTTP_API void _http_message_set_type(http_message *m, http_message_type t);
 
+#define http_message_set_info(m, i) _http_message_set_info((m), (i))
+PHP_HTTP_API void _http_message_set_info(http_message *message, http_info *info);
+
 #define http_message_header(m, h) _http_message_header_ex((m), (h), sizeof(h))
 #define http_message_header_ex _http_message_header_ex
 static inline zval *_http_message_header_ex(http_message *msg, char *key_str, size_t key_len)
index 6bc06f27ebdb6647193e90359d3a276466760238..8b28b15ea6a64cf3783bb17fa4eca2fb944a0c14 100644 (file)
@@ -95,6 +95,9 @@ PHP_METHOD(HttpMessage, unserialize);
 
 PHP_METHOD(HttpMessage, fromString);
 
+PHP_METHOD(HttpMessage, detach);
+PHP_METHOD(HttpMessage, prepend);
+
 #endif
 #endif