- add flush() to HttpDeflateStream and HttpInflateStream
authorMichael Wallner <mike@php.net>
Tue, 27 Dec 2005 10:57:58 +0000 (10:57 +0000)
committerMichael Wallner <mike@php.net>
Tue, 27 Dec 2005 10:57:58 +0000 (10:57 +0000)
http_deflatestream_object.c
http_encoding_api.c
http_inflatestream_object.c
php_http_deflatestream_object.h
php_http_inflatestream_object.h
tests/encoding_objects_001.phpt

index 4060ba4cf98158b5fa44ac401e954ed2eb34e30b..f4e55325ef637053207c446f15b9fb0573002751 100644 (file)
@@ -39,7 +39,13 @@ HTTP_BEGIN_ARGS(update, 0, 1)
        HTTP_ARG_VAL(data, 0)
 HTTP_END_ARGS;
 
-HTTP_EMPTY_ARGS(finish, 0);
+HTTP_BEGIN_ARGS(flush, 0, 0)
+       HTTP_ARG_VAL(data, 0)
+HTTP_END_ARGS;
+
+HTTP_BEGIN_ARGS(finish, 0, 0)
+       HTTP_ARG_VAL(data, 0)
+HTTP_END_ARGS;
 
 #define http_deflatestream_object_declare_default_properties() _http_deflatestream_object_declare_default_properties(TSRMLS_C)
 static inline void _http_deflatestream_object_declare_default_properties(TSRMLS_D);
@@ -48,6 +54,7 @@ zend_class_entry *http_deflatestream_object_ce;
 zend_function_entry http_deflatestream_object_fe[] = {
        HTTP_DEFLATE_ME(__construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
        HTTP_DEFLATE_ME(update, ZEND_ACC_PUBLIC)
+       HTTP_DEFLATE_ME(flush, ZEND_ACC_PUBLIC)
        HTTP_DEFLATE_ME(finish, ZEND_ACC_PUBLIC)
        
        EMPTY_FUNCTION_ENTRY
@@ -175,10 +182,8 @@ PHP_METHOD(HttpDeflateStream, update)
                RETURN_FALSE;
        }
        
-       if (!obj->stream) {
-               if (!(obj->stream = http_encoding_deflate_stream_init(NULL, 0))) {
-                       RETURN_FALSE;
-               }
+       if (!obj->stream && !(obj->stream = http_encoding_deflate_stream_init(NULL, 0))) {
+               RETURN_FALSE;
        }
        
        if (SUCCESS == http_encoding_deflate_stream_update(obj->stream, data, data_len, &encoded, &encoded_len)) {
@@ -189,7 +194,52 @@ PHP_METHOD(HttpDeflateStream, update)
 }
 /* }}} */
 
-/* {{{ proto string HttpDeflateStream::finish()
+/* {{{ proto string HttpDeflateStream::flush([string data])
+ *
+ * Flushes the deflate stream.
+ * 
+ * Returns some deflated data as string on success or FALSE on failure.
+ */ 
+PHP_METHOD(HttpDeflateStream, flush)
+{
+       int data_len = 0;
+       size_t updated_len = 0, encoded_len = 0;
+       char *updated = NULL, *encoded = NULL, *data = NULL;
+       getObject(http_deflatestream_object, obj);
+       
+       if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &data, &data_len)) {
+               RETURN_FALSE;
+       }
+       
+       if (!obj->stream && !(obj->stream = http_encoding_deflate_stream_init(NULL, 0))) {
+               RETURN_FALSE;
+       }
+       
+       if (data_len) {
+               if (SUCCESS != http_encoding_deflate_stream_update(obj->stream, data, data_len, &updated, &updated_len)) {
+                       RETURN_FALSE;
+               }
+       }
+       
+       if (SUCCESS == http_encoding_deflate_stream_flush(obj->stream, &encoded, &encoded_len)) {
+               if (updated_len) {
+                       updated = erealloc(updated, updated_len + encoded_len + 1);
+                       updated[updated_len + encoded_len] = '\0';
+                       memcpy(updated + updated_len, encoded, encoded_len);
+                       STR_FREE(encoded);
+                       updated_len += encoded_len;
+                       RETURN_STRINGL(updated, updated_len, 0);
+               } else {
+                       RETVAL_STRINGL(encoded, encoded_len, 0);
+               }
+       } else {
+               RETVAL_FALSE;
+       }
+       STR_FREE(updated);
+}
+/* }}} */
+
+/* {{{ proto string HttpDeflateStream::finish([string data])
  *
  * Finalizes the deflate stream.  The deflate stream can be reused after finalizing.
  * 
@@ -197,19 +247,39 @@ PHP_METHOD(HttpDeflateStream, update)
  */ 
 PHP_METHOD(HttpDeflateStream, finish)
 {
-       size_t encoded_len = 0;
-       char *encoded = NULL;
+       int data_len = 0;
+       size_t updated_len = 0, encoded_len = 0;
+       char *updated = NULL, *encoded = NULL, *data = NULL;
        getObject(http_deflatestream_object, obj);
        
-       NO_ARGS;
+       if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &data, &data_len)) {
+               RETURN_FALSE;
+       }
        
-       if (!obj->stream) {
+       if (!obj->stream && !(obj->stream = http_encoding_deflate_stream_init(NULL, 0))) {
                RETURN_FALSE;
        }
        
+       if (data_len) {
+               if (SUCCESS != http_encoding_deflate_stream_update(obj->stream, data, data_len, &updated, &updated_len)) {
+                       RETURN_FALSE;
+               }
+       }
+       
        if (SUCCESS == http_encoding_deflate_stream_finish(obj->stream, &encoded, &encoded_len)) {
-               RETVAL_STRINGL(encoded, encoded_len, 0);
+               if (updated_len) {
+                       updated = erealloc(updated, updated_len + encoded_len + 1);
+                       updated[updated_len + encoded_len] = '\0';
+                       memcpy(updated + updated_len, encoded, encoded_len);
+                       STR_FREE(encoded);
+                       updated_len += encoded_len;
+                       RETVAL_STRINGL(updated, updated_len, 0);
+               } else {
+                       STR_FREE(updated);
+                       RETVAL_STRINGL(encoded, encoded_len, 0);
+               }
        } else {
+               STR_FREE(updated);
                RETVAL_FALSE;
        }
        
index f57add91cff00ce9c5a1ae6895db82961078e5d9..a31b5b79772cc0533c2af23274674cdb158db89d 100644 (file)
@@ -392,7 +392,7 @@ PHP_HTTP_API STATUS _http_encoding_deflate_stream_update(http_encoding_stream *s
                case Z_OK:
                case Z_STREAM_END:
                        /* cut processed chunk off the buffer */
-                       phpstr_cut(PHPSTR(s->stream.opaque), 0, data_len - s->stream.avail_in);
+                       phpstr_cut(PHPSTR(s->stream.opaque), 0, PHPSTR_LEN(s->stream.opaque) - s->stream.avail_in);
                        
                        /* size buffer down to actual size */
                        *encoded_len -= s->stream.avail_out;
@@ -436,7 +436,7 @@ retry_raw_inflate:
                        case Z_OK:
                        case Z_STREAM_END:
                                /* cut off */
-                               phpstr_cut(PHPSTR(s->stream.opaque), 0, data_len - s->stream.avail_in);
+                               phpstr_cut(PHPSTR(s->stream.opaque), 0, PHPSTR_LEN(s->stream.opaque) - s->stream.avail_in);
                                
                                /* size down */
                                *decoded_len -= s->stream.avail_out;
@@ -494,31 +494,9 @@ PHP_HTTP_API STATUS _http_encoding_deflate_stream_flush(http_encoding_stream *s,
 
 PHP_HTTP_API STATUS _http_encoding_inflate_stream_flush(http_encoding_stream *s, char **decoded, size_t *decoded_len ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC TSRMLS_DC)
 {
-       int status;
-       
-       *decoded_len = 0x800;
-       *decoded = emalloc_rel(*decoded_len);
-       
-       s->stream.avail_in = 0;
-       s->stream.next_in = NULL;
-       s->stream.avail_out = *decoded_len;
-       s->stream.next_out = (Bytef *) *decoded;
-       
-       switch (status = inflate(&s->stream, Z_SYNC_FLUSH))
-       {
-               case Z_OK:
-               case Z_STREAM_END:
-                       *decoded_len = 0x800 - s->stream.avail_out;
-                       *decoded = erealloc_rel(*decoded, *decoded_len + 1);
-                       (*decoded)[*decoded_len] = '\0';
-                       return SUCCESS;
-               break;
-       }
-       
-       STR_SET(*decoded, NULL);
-       *decoded_len = 0;
-       http_error_ex(HE_WARNING, HTTP_E_ENCODING, "Failed to flush inflate stream: %s", zError(status));
-       return FAILURE;
+       /* noop */
+       *decoded = estrndup("", *decoded_len = 0);
+       return SUCCESS;
 }
 
 PHP_HTTP_API STATUS _http_encoding_deflate_stream_finish(http_encoding_stream *s, char **encoded, size_t *encoded_len ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC TSRMLS_DC)
index b89a77b7398deeaa5a5fc8062ebe870b4e281bee..c54d094f86c4ab0aef69a9da6c920c19b431caa0 100644 (file)
@@ -39,11 +39,18 @@ HTTP_BEGIN_ARGS(update, 0, 1)
        HTTP_ARG_VAL(data, 0)
 HTTP_END_ARGS;
 
-HTTP_EMPTY_ARGS(finish, 0);
+HTTP_BEGIN_ARGS(flush, 0, 0)
+       HTTP_ARG_VAL(data, 0)
+HTTP_END_ARGS;
+
+HTTP_BEGIN_ARGS(finish, 0, 0)
+       HTTP_ARG_VAL(data, 0)
+HTTP_END_ARGS;
 
 zend_class_entry *http_inflatestream_object_ce;
 zend_function_entry http_inflatestream_object_fe[] = {
        HTTP_INFLATE_ME(update, ZEND_ACC_PUBLIC)
+       HTTP_INFLATE_ME(flush, ZEND_ACC_PUBLIC)
        HTTP_INFLATE_ME(finish, ZEND_ACC_PUBLIC)
        
        EMPTY_FUNCTION_ENTRY
@@ -139,11 +146,10 @@ PHP_METHOD(HttpInflateStream, update)
                RETURN_STRING("", 1);
        }
        
-       if (!obj->stream) {
-               if (!(obj->stream = http_encoding_inflate_stream_init(NULL, 0))) {
-                       RETURN_FALSE;
-               }
+       if (!obj->stream && !(obj->stream = http_encoding_inflate_stream_init(NULL, 0))) {
+               RETURN_FALSE;
        }
+       
        if (SUCCESS == http_encoding_inflate_stream_update(obj->stream, data, data_len, &decoded, &decoded_len)) {
                RETURN_STRINGL(decoded, decoded_len, 0);
        } else {
@@ -152,7 +158,37 @@ PHP_METHOD(HttpInflateStream, update)
 }
 /* }}} */
 
-/* {{{ proto string HttpInflateStream::finish()
+/* {{{ proto string HttpInflateStream::flush([string data])
+ *
+ * Flush the inflate stream.
+ * 
+ * Returns some inflated data as string on success or FALSE on failure.
+ */
+PHP_METHOD(HttpInflateStream, flush)
+{
+       int data_len = 0;
+       size_t decoded_len = 0;
+       char *decoded = NULL, *data = NULL;
+       getObject(http_inflatestream_object, obj);
+       
+       if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &data, &data_len));
+       
+       if (!obj->stream && !(obj->stream = http_encoding_inflate_stream_init(NULL, 0))) {
+               RETURN_FALSE;
+       }
+       
+       /* flushing the inflate stream is a no-op */
+       if (!data_len) {
+               RETURN_STRINGL("", 0, 1);
+       } else if (SUCCESS == http_encoding_inflate_stream_update(obj->stream, data, data_len, &decoded, &decoded_len)) {
+               RETURN_STRINGL(decoded, decoded_len, 0);
+       } else {
+               RETURN_FALSE;
+       }
+}
+/* }}} */
+
+/* {{{ proto string HttpInflateStream::finish([string data])
  *
  * Finalizes the inflate stream.  The inflate stream can be reused after finalizing.
  * 
@@ -160,18 +196,37 @@ PHP_METHOD(HttpInflateStream, update)
  */ 
 PHP_METHOD(HttpInflateStream, finish)
 {
-       size_t decoded_len = 0;
-       char *decoded = NULL;
+       int data_len = 0;
+       size_t updated_len = 0, decoded_len = 0;
+       char *updated = NULL, *decoded = NULL, *data = NULL;
        getObject(http_inflatestream_object, obj);
        
-       NO_ARGS;
+       if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &data, &data_len)) {
+               RETURN_FALSE;
+       }
        
-       if (!obj->stream) {
+       if (!obj->stream && !(obj->stream = http_encoding_inflate_stream_init(NULL, 0))) {
                RETURN_FALSE;
        }
        
+       if (data_len) {
+               if (SUCCESS != http_encoding_inflate_stream_update(obj->stream, data, data_len, &updated, &updated_len)) {
+                       RETURN_FALSE;
+               }
+       }
+       
        if (SUCCESS == http_encoding_inflate_stream_finish(obj->stream, &decoded, &decoded_len)) {
-               RETVAL_STRINGL(decoded, decoded_len, 0);
+               if (updated_len) {
+                       updated = erealloc(updated, updated_len + decoded_len + 1);
+                       updated[updated_len + decoded_len] = '\0';
+                       memcpy(updated + updated_len, decoded, decoded_len);
+                       updated_len += decoded_len;
+                       RETVAL_STRINGL(updated, updated_len, 0);
+                       STR_FREE(decoded);
+               } else {
+                       RETVAL_STRINGL(decoded, decoded_len, 0);
+                       STR_FREE(updated);
+               }
        } else {
                RETVAL_FALSE;
        }
index 5a274a8da38a131d45aeff1a2b182f70cd62f0ab..cd5df9736ae7138466dcbbff15aeb38c55b15f17 100644 (file)
@@ -37,6 +37,7 @@ extern void _http_deflatestream_object_free(zend_object *object TSRMLS_DC);
 
 PHP_METHOD(HttpDeflateStream, __construct);
 PHP_METHOD(HttpDeflateStream, update);
+PHP_METHOD(HttpDeflateStream, flush);
 PHP_METHOD(HttpDeflateStream, finish);
 
 #endif
index 91da740a3af67eceb9c53e755dc7731666f49a9e..64c10e4d4caddd798a4a3b0b4882097778528bad 100644 (file)
@@ -36,6 +36,7 @@ extern zend_object_value _http_inflatestream_object_clone_obj(zval *object TSRML
 extern void _http_inflatestream_object_free(zend_object *object TSRMLS_DC);
 
 PHP_METHOD(HttpInflateStream, update);
+PHP_METHOD(HttpInflateStream, flush);
 PHP_METHOD(HttpInflateStream, finish);
 
 #endif
index d9cf992b54b3c28835a01fb3baf507ffbacbf6a0..f2fc6e29588e7b792919111808346fd5078b35a4 100644 (file)
@@ -11,14 +11,14 @@ skipif(!http_support(HTTP_SUPPORT_ENCODINGS), "need zlib");
 echo "-TEST\n";
 $d = new HttpDeflateStream;
 $i = new HttpInflateStream;
-echo $i->update($d->update("Hi "));
-echo $i->update($d->update("there!\n"));
-echo $i->update($d->finish());
-echo $i->finish();
+echo $i->flush($d->flush("Hi "));
+echo $i->finish($d->finish("there!\n"));
+echo $i->finish($d->finish("Yo...\n"));
 echo "Done\n";
 ?>
 --EXPECTF--
 %sTEST
 Hi there!
+Yo...
 Done