Author: rhuijben
Date: Wed Nov 11 14:36:21 2015
New Revision: 1713852

URL: http://svn.apache.org/viewvc?rev=1713852&view=rev
Log:
In preparation for improving the capabilities of the deflate stream,
split the serf_deflate_read() function in 3 functions that now call
each other. No functional changes yet.

* buckets/deflate_buckets.c
  (deflate_read3,
   deflate_read2): New functions, extracted from...
  (serf_deflate_read): ... here. Call deflate_read2.

Modified:
    serf/trunk/buckets/deflate_buckets.c

Modified: serf/trunk/buckets/deflate_buckets.c
URL: 
http://svn.apache.org/viewvc/serf/trunk/buckets/deflate_buckets.c?rev=1713852&r1=1713851&r2=1713852&view=diff
==============================================================================
--- serf/trunk/buckets/deflate_buckets.c (original)
+++ serf/trunk/buckets/deflate_buckets.c Wed Nov 11 14:36:21 2015
@@ -146,7 +146,195 @@ static void serf_deflate_destroy_and_dat
     serf_default_destroy_and_data(bucket);
 }
 
-static apr_status_t serf_deflate_read(serf_bucket_t *bucket,
+static apr_status_t deflate_read3(serf_bucket_t *bucket,
+                                  apr_size_t requested,
+                                  const char **data,
+                                  apr_size_t *len)
+{
+    deflate_context_t *ctx = bucket->data;
+    apr_status_t status;
+    int zRC;
+
+    /* Do we have anything already uncompressed to read? */
+    status = serf_bucket_read(ctx->inflate_stream, requested, data,
+                              len);
+    if (SERF_BUCKET_READ_ERROR(status)) {
+        return status;
+    }
+    /* Hide EOF. */
+    if (APR_STATUS_IS_EOF(status)) {
+        status = ctx->stream_status;
+        if (APR_STATUS_IS_EOF(status)) {
+            /* We've read all of the data from our stream, but we
+              * need to continue to iterate until we flush
+              * out the zlib buffer.
+              */
+            status = APR_SUCCESS;
+        }
+    }
+    if (*len != 0) {
+        return status;
+    }
+
+    /* We tried; but we have nothing buffered. Fetch more. */
+
+    /* It is possible that we maxed out avail_out before
+      * exhausting avail_in; therefore, continue using the
+      * previous buffer.  Otherwise, fetch more data from
+      * our stream bucket.
+      */
+    if (ctx->zstream.avail_in == 0) {
+        const char *private_data;
+        apr_size_t private_len;
+
+        /* When we empty our inflated stream, we'll return this
+          * status - this allow us to eventually pass up EAGAINs.
+          */
+        ctx->stream_status = serf_bucket_read(ctx->stream,
+                                              ctx->bufferSize,
+                                              &private_data,
+                                              &private_len);
+
+        if (SERF_BUCKET_READ_ERROR(ctx->stream_status)) {
+            return ctx->stream_status;
+        }
+
+        if (!private_len && APR_STATUS_IS_EAGAIN(ctx->stream_status)) {
+            *len = 0;
+            status = ctx->stream_status;
+            ctx->stream_status = APR_SUCCESS;
+            return status;
+        }
+
+        /* Make valgrind happy and explictly initialize next_in to specific
+          * value for empty buffer. */
+        if (private_len) {
+            ctx->zstream.next_in = (unsigned char*)private_data;
+            ctx->zstream.avail_in = private_len;
+        } else {
+            ctx->zstream.next_in = Z_NULL;
+            ctx->zstream.avail_in = 0;
+        }
+    }
+
+    while (1) {
+
+        zRC = inflate(&ctx->zstream, Z_NO_FLUSH);
+
+        /* We're full or zlib requires more space. Either case, clear
+            out our buffer, reset, and return. */
+        if (zRC == Z_BUF_ERROR || ctx->zstream.avail_out == 0) {
+            apr_size_t private_len;
+            serf_bucket_t *tmp;
+
+            ctx->zstream.next_out = ctx->buffer;
+            private_len = ctx->bufferSize - ctx->zstream.avail_out;
+
+            ctx->crc = crc32(ctx->crc, (const Bytef *)ctx->buffer,
+                              private_len);
+
+            /* FIXME: There probably needs to be a free func. */
+            tmp = SERF_BUCKET_SIMPLE_STRING_LEN((char *)ctx->buffer,
+                                                private_len,
+                                                bucket->allocator);
+            serf_bucket_aggregate_append(ctx->inflate_stream, tmp);
+            ctx->zstream.avail_out = ctx->bufferSize;
+            break;
+        }
+
+        if (zRC == Z_STREAM_END) {
+            apr_size_t private_len;
+            serf_bucket_t *tmp;
+
+            private_len = ctx->bufferSize - ctx->zstream.avail_out;
+            ctx->crc = crc32(ctx->crc, (const Bytef *)ctx->buffer,
+                              private_len);
+            /* FIXME: There probably needs to be a free func. */
+            tmp = SERF_BUCKET_SIMPLE_STRING_LEN((char *)ctx->buffer,
+                                                private_len,
+                                                bucket->allocator);
+            serf_bucket_aggregate_append(ctx->inflate_stream, tmp);
+
+            ctx->zstream.avail_out = ctx->bufferSize;
+
+            /* Push back the remaining data to be read. */
+            tmp = serf_bucket_aggregate_create(bucket->allocator);
+            serf_bucket_set_config(tmp, ctx->config);
+            serf_bucket_aggregate_prepend(tmp, ctx->stream);
+            ctx->stream = tmp;
+
+            /* We now need to take the remaining avail_in and
+              * throw it in ctx->stream so our next read picks it up.
+              */
+            tmp = SERF_BUCKET_SIMPLE_STRING_LEN(
+                                (const char*)ctx->zstream.next_in,
+                                              ctx->zstream.avail_in,
+                                              bucket->allocator);
+            serf_bucket_aggregate_prepend(ctx->stream, tmp);
+
+            switch (ctx->format) {
+            case SERF_DEFLATE_GZIP:
+                ctx->stream_left = ctx->stream_size =
+                    DEFLATE_VERIFY_SIZE;
+                ctx->state++;
+                break;
+            case SERF_DEFLATE_DEFLATE:
+                /* Deflate does not have a verify footer. */
+                ctx->state = STATE_FINISH;
+                break;
+            default:
+                /* Not reachable */
+                return APR_EGENERAL;
+            }
+
+            break;
+        }
+
+        /* Any other error? */
+        if (zRC != Z_OK) {
+            serf__log(LOGLVL_ERROR, LOGCOMP_COMPR, __FILE__,
+                      ctx->config, "inflate error %d - %s\n",
+                      zRC, ctx->zstream.msg);
+            return SERF_ERROR_DECOMPRESSION_FAILED;
+        }
+
+        /* As long as zRC == Z_OK, just keep looping. */
+    }
+    /* Okay, we've inflated.  Try to read. */
+    status = serf_bucket_read(ctx->inflate_stream, requested, data,
+                              len);
+    /* Hide EOF. */
+    if (APR_STATUS_IS_EOF(status)) {
+        status = ctx->stream_status;
+
+        /* If the inflation wasn't finished, return APR_SUCCESS. */
+        if (zRC != Z_STREAM_END)
+            return APR_SUCCESS;
+
+        /* If our stream is finished too and all data was inflated,
+          * return SUCCESS so we'll iterate one more time.
+          */
+        if (APR_STATUS_IS_EOF(status)) {
+            /* No more data to read from the stream, and everything
+                inflated. If all data was received correctly, state
+                should have been advanced to STATE_READING_VERIFY or
+                STATE_FINISH. If not, then the data was incomplete
+                and we have an error. */
+            if (ctx->state != STATE_INFLATE)
+                return APR_SUCCESS;
+            else {
+                serf__log(LOGLVL_ERROR, LOGCOMP_COMPR, __FILE__,
+                          ctx->config,
+                          "Unexpected EOF on input stream\n");
+                return SERF_ERROR_DECOMPRESSION_FAILED;
+            }
+        }
+    }
+
+    return status;
+}
+
+static apr_status_t deflate_read2(serf_bucket_t *bucket,
                                       apr_size_t requested,
                                       const char **data, apr_size_t *len)
 {
@@ -252,176 +440,7 @@ static apr_status_t serf_deflate_read(se
             ctx->state++;
             break;
         case STATE_INFLATE:
-            /* Do we have anything already uncompressed to read? */
-            status = serf_bucket_read(ctx->inflate_stream, requested, data,
-                                      len);
-            if (SERF_BUCKET_READ_ERROR(status)) {
-                return status;
-            }
-            /* Hide EOF. */
-            if (APR_STATUS_IS_EOF(status)) {
-                status = ctx->stream_status;
-                if (APR_STATUS_IS_EOF(status)) {
-                    /* We've read all of the data from our stream, but we
-                     * need to continue to iterate until we flush
-                     * out the zlib buffer.
-                     */
-                    status = APR_SUCCESS;
-                }
-            }
-            if (*len != 0) {
-                return status;
-            }
-
-            /* We tried; but we have nothing buffered. Fetch more. */
-
-            /* It is possible that we maxed out avail_out before
-             * exhausting avail_in; therefore, continue using the
-             * previous buffer.  Otherwise, fetch more data from
-             * our stream bucket.
-             */
-            if (ctx->zstream.avail_in == 0) {
-                /* When we empty our inflated stream, we'll return this
-                 * status - this allow us to eventually pass up EAGAINs.
-                 */
-                ctx->stream_status = serf_bucket_read(ctx->stream,
-                                                      ctx->bufferSize,
-                                                      &private_data,
-                                                      &private_len);
-
-                if (SERF_BUCKET_READ_ERROR(ctx->stream_status)) {
-                    return ctx->stream_status;
-                }
-
-                if (!private_len && APR_STATUS_IS_EAGAIN(ctx->stream_status)) {
-                    *len = 0;
-                    status = ctx->stream_status;
-                    ctx->stream_status = APR_SUCCESS;
-                    return status;
-                }
-
-                /* Make valgrind happy and explictly initialize next_in to 
specific
-                 * value for empty buffer. */
-                if (private_len) {
-                    ctx->zstream.next_in = (unsigned char*)private_data;
-                    ctx->zstream.avail_in = private_len;
-                } else {
-                    ctx->zstream.next_in = Z_NULL;
-                    ctx->zstream.avail_in = 0;
-                }
-            }
-
-            while (1) {
-
-                zRC = inflate(&ctx->zstream, Z_NO_FLUSH);
-
-                /* We're full or zlib requires more space. Either case, clear
-                   out our buffer, reset, and return. */
-                if (zRC == Z_BUF_ERROR || ctx->zstream.avail_out == 0) {
-                    serf_bucket_t *tmp;
-                    ctx->zstream.next_out = ctx->buffer;
-                    private_len = ctx->bufferSize - ctx->zstream.avail_out;
-
-                    ctx->crc = crc32(ctx->crc, (const Bytef *)ctx->buffer,
-                                     private_len);
-
-                    /* FIXME: There probably needs to be a free func. */
-                    tmp = SERF_BUCKET_SIMPLE_STRING_LEN((char *)ctx->buffer,
-                                                        private_len,
-                                                        bucket->allocator);
-                    serf_bucket_aggregate_append(ctx->inflate_stream, tmp);
-                    ctx->zstream.avail_out = ctx->bufferSize;
-                    break;
-                }
-
-                if (zRC == Z_STREAM_END) {
-                    serf_bucket_t *tmp;
-
-                    private_len = ctx->bufferSize - ctx->zstream.avail_out;
-                    ctx->crc = crc32(ctx->crc, (const Bytef *)ctx->buffer,
-                                     private_len);
-                    /* FIXME: There probably needs to be a free func. */
-                    tmp = SERF_BUCKET_SIMPLE_STRING_LEN((char *)ctx->buffer,
-                                                        private_len,
-                                                        bucket->allocator);
-                    serf_bucket_aggregate_append(ctx->inflate_stream, tmp);
-
-                    ctx->zstream.avail_out = ctx->bufferSize;
-
-                    /* Push back the remaining data to be read. */
-                    tmp = serf_bucket_aggregate_create(bucket->allocator);
-                    serf_bucket_set_config(tmp, ctx->config);
-                    serf_bucket_aggregate_prepend(tmp, ctx->stream);
-                    ctx->stream = tmp;
-
-                    /* We now need to take the remaining avail_in and
-                     * throw it in ctx->stream so our next read picks it up.
-                     */
-                    tmp = SERF_BUCKET_SIMPLE_STRING_LEN(
-                                        (const char*)ctx->zstream.next_in,
-                                                     ctx->zstream.avail_in,
-                                                     bucket->allocator);
-                    serf_bucket_aggregate_prepend(ctx->stream, tmp);
-
-                    switch (ctx->format) {
-                    case SERF_DEFLATE_GZIP:
-                        ctx->stream_left = ctx->stream_size =
-                            DEFLATE_VERIFY_SIZE;
-                        ctx->state++;
-                        break;
-                    case SERF_DEFLATE_DEFLATE:
-                        /* Deflate does not have a verify footer. */
-                        ctx->state = STATE_FINISH;
-                        break;
-                    default:
-                        /* Not reachable */
-                        return APR_EGENERAL;
-                    }
-
-                    break;
-                }
-
-                /* Any other error? */
-                if (zRC != Z_OK) {
-                    serf__log(LOGLVL_ERROR, LOGCOMP_COMPR, __FILE__,
-                              ctx->config, "inflate error %d - %s\n",
-                              zRC, ctx->zstream.msg);
-                    return SERF_ERROR_DECOMPRESSION_FAILED;
-                }
-
-                /* As long as zRC == Z_OK, just keep looping. */
-            }
-            /* Okay, we've inflated.  Try to read. */
-            status = serf_bucket_read(ctx->inflate_stream, requested, data,
-                                      len);
-            /* Hide EOF. */
-            if (APR_STATUS_IS_EOF(status)) {
-                status = ctx->stream_status;
-
-                /* If the inflation wasn't finished, return APR_SUCCESS. */
-                if (zRC != Z_STREAM_END)
-                    return APR_SUCCESS;
-
-                /* If our stream is finished too and all data was inflated,
-                 * return SUCCESS so we'll iterate one more time.
-                 */
-                if (APR_STATUS_IS_EOF(status)) {
-                    /* No more data to read from the stream, and everything
-                       inflated. If all data was received correctly, state
-                       should have been advanced to STATE_READING_VERIFY or
-                       STATE_FINISH. If not, then the data was incomplete
-                       and we have an error. */
-                    if (ctx->state != STATE_INFLATE)
-                        return APR_SUCCESS;
-                    else {
-                        serf__log(LOGLVL_ERROR, LOGCOMP_COMPR, __FILE__,
-                                  ctx->config,
-                                  "Unexpected EOF on input stream\n");
-                        return SERF_ERROR_DECOMPRESSION_FAILED;
-                    }
-                }
-            }
-            return status;
+            return deflate_read3(bucket, requested, data, len);
         case STATE_DONE:
             /* We're done inflating.  Use our finished buffer. */
             return serf_bucket_read(ctx->stream, requested, data, len);
@@ -434,6 +453,13 @@ static apr_status_t serf_deflate_read(se
     /* NOTREACHED */
 }
 
+static apr_status_t serf_deflate_read(serf_bucket_t *bucket,
+                                      apr_size_t requested,
+                                      const char **data, apr_size_t *len)
+{
+  return deflate_read2(bucket, requested, data, len);
+}
+
 static apr_status_t serf_deflate_set_config(serf_bucket_t *bucket,
                                             serf_config_t *config)
 {


Reply via email to