- class HttpRequestPool implements Countable
authorMichael Wallner <mike@php.net>
Mon, 7 Nov 2005 15:50:06 +0000 (15:50 +0000)
committerMichael Wallner <mike@php.net>
Mon, 7 Nov 2005 15:50:06 +0000 (15:50 +0000)
- class HttpMessage implements Countable, Serializable
- add test

http_message_object.c
http_requestpool_object.c
php_http_message_object.h
php_http_requestpool_object.h
tests/HttpMessage_003.phpt [new file with mode: 0644]

index 921ba0ba459b6c8746e0b213110d2a33d71e8627..c9505f6cb0f5a348bbc094eec378e09ad24f85b2 100644 (file)
 #include "phpstr/phpstr.h"
 #include "missing.h"
 
+#ifndef WONKY
+#      include "zend_interfaces.h"
+#endif
+#ifdef HAVE_SPL
+#      include "ext/spl/spl_array.h"
+#endif
+
 ZEND_EXTERN_MODULE_GLOBALS(http);
 
 #define HTTP_BEGIN_ARGS(method, ret_ref, req_args)     HTTP_BEGIN_ARGS_EX(HttpMessage, method, ret_ref, req_args)
@@ -89,6 +96,13 @@ HTTP_BEGIN_ARGS(toString, 0, 0)
        HTTP_ARG_VAL(include_parent, 0)
 HTTP_END_ARGS;
 
+HTTP_EMPTY_ARGS(count, 0);
+
+HTTP_EMPTY_ARGS(serialize, 0);
+HTTP_BEGIN_ARGS(unserialize, 0, 1)
+       HTTP_ARG_VAL(serialized, 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
@@ -120,6 +134,13 @@ zend_function_entry http_message_object_fe[] = {
        HTTP_MESSAGE_ME(send, ZEND_ACC_PUBLIC)
        HTTP_MESSAGE_ME(toString, ZEND_ACC_PUBLIC)
 
+       /* implements Countable */
+       HTTP_MESSAGE_ME(count, ZEND_ACC_PUBLIC)
+       
+       /* implements Serializable */
+       HTTP_MESSAGE_ME(serialize, ZEND_ACC_PUBLIC)
+       HTTP_MESSAGE_ME(unserialize, ZEND_ACC_PUBLIC)
+       
        ZEND_MALIAS(HttpMessage, __toString, toString, HTTP_ARGS(HttpMessage, toString), ZEND_ACC_PUBLIC)
 
        HTTP_MESSAGE_ME(fromString, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
@@ -131,6 +152,17 @@ static zend_object_handlers http_message_object_handlers;
 PHP_MINIT_FUNCTION(http_message_object)
 {
        HTTP_REGISTER_CLASS_EX(HttpMessage, http_message_object, NULL, 0);
+#ifndef WONKY
+#      ifdef HAVE_SPL
+       zend_class_implements(http_message_object_ce TSRMLS_CC, 2, spl_ce_Countable, zend_ce_serializable);
+#      else
+       zend_class_implements(http_message_object_ce TSRMLS_CC, 1, zend_ce_serializable);
+#      endif
+#else
+#      ifdef HAVE_SPL
+       zend_class_implements(http_message_object_ce TSRMLS_CC, 1, spl_ce_Countable);
+#      endif
+#endif
 
        HTTP_LONG_CONSTANT("HTTP_MSG_NONE", HTTP_MSG_NONE);
        HTTP_LONG_CONSTANT("HTTP_MSG_REQUEST", HTTP_MSG_REQUEST);
@@ -508,18 +540,25 @@ static HashTable *_http_message_object_get_props(zval *object TSRMLS_DC)
  */
 PHP_METHOD(HttpMessage, __construct)
 {
-       char *message = NULL;
        int length = 0;
+       char *message = NULL;
+       
        getObject(http_message_object, obj);
-
+       
        SET_EH_THROW_HTTP();
        if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &message, &length) && message && length) {
-               if (obj->message = http_message_parse(message, length)) {
+               http_message *msg = obj->message;
+               
+               http_message_dtor(msg);
+               if (obj->message = http_message_parse_ex(msg, message, length)) {
                        if (obj->message->parent) {
                                obj->parent = http_message_object_new_ex(Z_OBJCE_P(getThis()), obj->message->parent, NULL);
                        }
+               } else {
+                       obj->message = http_message_init(msg);
                }
-       } else if (!obj->message) {
+       }
+       if (!obj->message) {
                obj->message = http_message_new();
        }
        SET_EH_NORMAL();
@@ -548,8 +587,7 @@ PHP_METHOD(HttpMessage, fromString)
        SET_EH_THROW_HTTP();
        if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &string, &length)) {
                if (msg = http_message_parse(string, length)) {
-                       Z_TYPE_P(return_value) = IS_OBJECT;
-                       return_value->value.obj = http_message_object_new_ex(http_message_object_ce, msg, NULL);
+                       ZVAL_OBJVAL(return_value, http_message_object_new_ex(http_message_object_ce, msg, NULL));
                }
        }
        SET_EH_NORMAL();
@@ -969,6 +1007,66 @@ PHP_METHOD(HttpMessage, toString)
 }
 /* }}} */
 
+/* {{{ proto int HttpMessage::count()
+ *
+ * Implements Countable.
+ * 
+ * Returns the number of parent messages + 1.
+ */
+PHP_METHOD(HttpMessage, count)
+{
+       NO_ARGS {
+               long i;
+               http_message *msg;
+               getObject(http_message_object, obj);
+               
+               for (i = 0, msg = obj->message; msg; msg = msg->parent, ++i);
+               RETURN_LONG(i);
+       }
+}
+/* }}} */
+
+/* {{{ proto string HttpMessage::serialize()
+ *
+ * Implements Serializable.
+ * 
+ * Returns the serialized representation of the HttpMessage.
+ */
+PHP_METHOD(HttpMessage, serialize)
+{
+       NO_ARGS {
+               char *string;
+               size_t length;
+               getObject(http_message_object, obj);
+               
+               http_message_serialize(obj->message, &string, &length);
+               RETURN_STRINGL(string, length, 0);
+       }
+}
+/* }}} */
+
+/* {{{ proto void HttpMessage::unserialize(string serialized)
+ *
+ * Implements Serializable.
+ * 
+ * Re-constructs the HttpMessage based upon the serialized string.
+ */
+PHP_METHOD(HttpMessage, unserialize)
+{
+       int length;
+       char *serialized;
+       getObject(http_message_object, obj);
+       
+       if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &serialized, &length)) {
+               http_message_dtor(obj->message);
+               if (!http_message_parse_ex(obj->message, serialized, (size_t) length)) {
+                       http_error(HE_ERROR, HTTP_E_RUNTIME, "Could not unserialize HttpMessage");
+                       http_message_init(obj->message);
+               }
+       }
+}
+/* }}} */
+
 #endif /* ZEND_ENGINE_2 */
 
 /*
index 9c008a6c406bd3e1ccf56dd84c3567c8a3f4329d..0bb585974c64e8ba0e5f462659f49e2fa9859bb5 100644 (file)
 #include "php_http_exception_object.h"
 
 #include "zend_interfaces.h"
+#ifdef HAVE_SPL
+#      include "ext/spl/spl_array.h"
+#      include "ext/spl/spl_iterators.h"
+#endif
 
 #ifdef PHP_WIN32
 #      include <winsock2.h>
@@ -65,6 +69,8 @@ HTTP_EMPTY_ARGS(key, 0);
 HTTP_EMPTY_ARGS(next, 0);
 HTTP_EMPTY_ARGS(rewind, 0);
 
+HTTP_EMPTY_ARGS(count, 0);
+
 HTTP_EMPTY_ARGS(getAttachedRequests, 0);
 HTTP_EMPTY_ARGS(getFinishedRequests, 0);
 
@@ -90,6 +96,9 @@ zend_function_entry http_requestpool_object_fe[] = {
        HTTP_REQPOOL_ME(next, ZEND_ACC_PUBLIC)
        HTTP_REQPOOL_ME(rewind, ZEND_ACC_PUBLIC)
        
+       /* implmenents Countable */
+       HTTP_REQPOOL_ME(count, ZEND_ACC_PUBLIC)
+       
        HTTP_REQPOOL_ME(getAttachedRequests, ZEND_ACC_PUBLIC)
        HTTP_REQPOOL_ME(getFinishedRequests, ZEND_ACC_PUBLIC)
 
@@ -100,7 +109,12 @@ static zend_object_handlers http_requestpool_object_handlers;
 PHP_MINIT_FUNCTION(http_requestpool_object)
 {
        HTTP_REGISTER_CLASS_EX(HttpRequestPool, http_requestpool_object, NULL, 0);
+#ifdef HAVE_SPL
+       zend_class_implements(http_requestpool_object_ce TSRMLS_CC, 2, spl_ce_Countable, spl_ce_Iterator);
+#else
        zend_class_implements(http_requestpool_object_ce TSRMLS_CC, 1, zend_ce_iterator);
+#endif
+
        http_requestpool_object_handlers.clone_obj = NULL;
        return SUCCESS;
 }
@@ -464,6 +478,21 @@ PHP_METHOD(HttpRequestPool, rewind)
 }
 /* }}} */
 
+/* {{{ proto int HttpRequestPool::count()
+ *
+ * Implements Countable.
+ * 
+ * Returns the number of attached HttpRequest objects.
+ */
+PHP_METHOD(HttpRequestPool, count)
+{
+       NO_ARGS {
+               getObject(http_requestpool_object, obj);
+               RETURN_LONG((long) zend_llist_count(&obj->pool.handles));
+       }
+}
+/* }}} */
+
 /* {{{ proto array HttpRequestPool::getAttachedRequests()
  *
  * Get attached HttpRequest objects.
index 153cc81203fd09414506429046c1db566811a67a..e9c849474752d0915d46641a8d5d48dd770c4ef3 100644 (file)
@@ -91,6 +91,10 @@ PHP_METHOD(HttpMessage, getParentMessage);
 PHP_METHOD(HttpMessage, send);
 PHP_METHOD(HttpMessage, toString);
 
+PHP_METHOD(HttpMessage, count);
+PHP_METHOD(HttpMessage, serialize);
+PHP_METHOD(HttpMessage, unserialize);
+
 PHP_METHOD(HttpMessage, fromString);
 
 #endif
index 2c70a0102229bd6ed05c75ba5bf254a375a01b33..3d71e64571d9da67909c4dbbf99124f2f7a10197 100644 (file)
@@ -56,6 +56,7 @@ PHP_METHOD(HttpRequestPool, current);
 PHP_METHOD(HttpRequestPool, key);
 PHP_METHOD(HttpRequestPool, next);
 PHP_METHOD(HttpRequestPool, rewind);
+PHP_METHOD(HttpRequestPool, count);
 PHP_METHOD(HttpRequestPool, getAttachedRequests);
 PHP_METHOD(HttpRequestPool, getFinishedRequests);
 
diff --git a/tests/HttpMessage_003.phpt b/tests/HttpMessage_003.phpt
new file mode 100644 (file)
index 0000000..79d0dc6
--- /dev/null
@@ -0,0 +1,67 @@
+--TEST--
+HttpMessage implmenets Serializable, Countable
+--SKIPIF--
+<?php
+include 'skip.inc';
+checkmin(5);
+?>
+--FILE--
+<?php
+echo "-TEST\n";
+
+$m = new HttpMessage(
+       "HTTP/1.1 301\r\n".
+       "Location: /anywhere\r\n".
+       "HTTP/1.1 302\r\n".
+       "Location: /somewhere\r\n".
+       "HTTP/1.1 200\r\n".
+       "Transfer-Encoding: chunked\r\n".
+       "\r\n".
+       "01\r\n".
+       "X\r\n".
+       "00"
+);
+
+var_dump($m->count());
+var_dump($m->serialize());
+$m->unserialize("HTTP/1.1 200 Ok\r\nServer: Funky/1.0");
+var_dump($m);
+var_dump($m->count());
+
+echo "Done\n";
+?>
+--EXPECTF--
+%sTEST
+int(3)
+string(109) "HTTP/1.1 301
+Location: /anywhere
+HTTP/1.1 302
+Location: /somewhere
+HTTP/1.1 200
+Content-Length: 1
+
+X
+"
+object(HttpMessage)#%d (%d) {
+  ["type:protected"]=>
+  int(2)
+  ["httpVersion:protected"]=>
+  float(1.1)
+  ["responseCode:protected"]=>
+  int(200)
+  ["responseStatus:protected"]=>
+  string(2) "Ok"
+  ["requestMethod:protected"]=>
+  string(0) ""
+  ["requestUri:protected"]=>
+  string(0) ""
+  ["headers:protected"]=>
+  array(1) {
+    ["Server"]=>
+    string(9) "Funky/1.0"
+  }
+  ["body:protected"]=>
+  string(0) ""
+}
+int(1)
+Done