You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by jo...@apache.org on 2004/11/17 15:29:48 UTC

svn commit: rev 76134 - in apr/apr-util/trunk: . buckets include test

Author: jorton
Date: Wed Nov 17 06:29:46 2004
New Revision: 76134

Modified:
   apr/apr-util/trunk/CHANGES
   apr/apr-util/trunk/buckets/apr_brigade.c
   apr/apr-util/trunk/include/apr_buckets.h
   apr/apr-util/trunk/test/   (props changed)
   apr/apr-util/trunk/test/testbuckets.c
Log:
* buckets/apr_brigade.c (apr_brigade_insert_file): New function.

* test/testbucket.c (test_insertfile): New test.


Modified: apr/apr-util/trunk/CHANGES
==============================================================================
--- apr/apr-util/trunk/CHANGES	(original)
+++ apr/apr-util/trunk/CHANGES	Wed Nov 17 06:29:46 2004
@@ -1,5 +1,8 @@
 Changes with APR-util 1.1.0
 
+  *) Add apr_brigade_insert_file() function, to safely insert a file
+     into a brigade, regardless of size.  [Joe Orton]
+
 Changes with APR-util 1.0.1
 
   *) Add support for Berkeley DB 4.3.  [Jani Averbach <jaa jaa.iki.fi>]

Modified: apr/apr-util/trunk/buckets/apr_brigade.c
==============================================================================
--- apr/apr-util/trunk/buckets/apr_brigade.c	(original)
+++ apr/apr-util/trunk/buckets/apr_brigade.c	Wed Nov 17 06:29:46 2004
@@ -666,3 +666,36 @@
     return apr_brigade_write(b, flush, ctx, buf, vd.vbuff.curpos - buf);
 }
 
+/* A "safe" maximum bucket size, 1Gb */
+#define MAX_BUCKET_SIZE (0x40000000)
+
+APU_DECLARE(apr_bucket *) apr_brigade_insert_file(apr_bucket_brigade *bb,
+                                                  apr_file_t *f,
+                                                  apr_off_t start,
+                                                  apr_off_t length,
+                                                  apr_pool_t *p)
+{
+    apr_bucket *e;
+
+    if (sizeof(apr_off_t) == sizeof(apr_size_t) || length < MAX_BUCKET_SIZE) {
+        e = apr_bucket_file_create(f, start, (apr_size_t)length, p, 
+                                   bb->bucket_alloc);
+    }
+    else {
+        /* Several buckets are needed. */        
+        e = apr_bucket_file_create(f, start, MAX_BUCKET_SIZE, p, 
+                                   bb->bucket_alloc);
+
+        while (length > MAX_BUCKET_SIZE) {
+            apr_bucket *ce;
+            apr_bucket_copy(e, &ce);
+            APR_BRIGADE_INSERT_TAIL(bb, ce);
+            e->start += MAX_BUCKET_SIZE;
+            length -= MAX_BUCKET_SIZE;
+        }
+        e->length = (apr_size_t)length; /* Resize just the last bucket */
+    }
+    
+    APR_BRIGADE_INSERT_TAIL(bb, e);
+    return e;
+}

Modified: apr/apr-util/trunk/include/apr_buckets.h
==============================================================================
--- apr/apr-util/trunk/include/apr_buckets.h	(original)
+++ apr/apr-util/trunk/include/apr_buckets.h	Wed Nov 17 06:29:46 2004
@@ -868,6 +868,25 @@
                                               void *ctx,
                                               const char *fmt, va_list va);
 
+/**
+ * Utility function to insert a file of given length onto the end of
+ * the brigade.  The file is split into multiple buckets if it is
+ * larger than the maximum size which can be represented by a single bucket.
+ * @param bb the brigade to insert into
+ * @param f the file to insert
+ * @param start the offset into the file
+ * @param len the length of the file to insert
+ * @param p pool from which file buckets are allocated
+ * @return the last bucket inserted
+ */
+APU_DECLARE(apr_bucket *) apr_brigade_insert_file(apr_bucket_brigade *bb,
+                                                  apr_file_t *f,
+                                                  apr_off_t start,
+                                                  apr_off_t len,
+                                                  apr_pool_t *p);
+
+
+
 /*  *****  Bucket freelist functions *****  */
 /**
  * Create a bucket allocator.

Modified: apr/apr-util/trunk/test/testbuckets.c
==============================================================================
--- apr/apr-util/trunk/test/testbuckets.c	(original)
+++ apr/apr-util/trunk/test/testbuckets.c	Wed Nov 17 06:29:46 2004
@@ -285,6 +285,54 @@
     apr_bucket_alloc_destroy(ba);
 }
 
+#define TIF_FNAME "testfile.txt"
+
+static void test_insertfile(abts_case *tc, void *ctx)
+{
+    apr_bucket_alloc_t *ba = apr_bucket_alloc_create(p);
+    apr_bucket_brigade *bb;
+    const apr_off_t bignum = (APR_INT64_C(2) << 32) + 424242;
+    apr_off_t count;
+    apr_file_t *f;
+    apr_bucket *e;
+
+    ABTS_ASSERT(tc, "open test file",
+                apr_file_open(&f, TIF_FNAME,
+                              APR_WRITE|APR_TRUNCATE|APR_CREATE,
+                              APR_OS_DEFAULT, p) == APR_SUCCESS);
+
+    if (apr_file_trunc(f, bignum)) {
+        apr_file_close(f);
+        apr_file_remove(TIF_FNAME, p);
+        ABTS_NOT_IMPL(tc, "Skipped: could not create large file");
+    }
+    
+    bb = apr_brigade_create(p, ba);
+
+    e = apr_brigade_insert_file(bb, f, 0, bignum, p);
+    
+    ABTS_ASSERT(tc, "inserted file was not at end of brigade",
+                e == APR_BRIGADE_LAST(bb));
+
+    /* check that the total size of inserted buckets is equal to the
+     * total size of the file. */
+    count = 0;
+
+    for (e = APR_BRIGADE_FIRST(bb);
+         e != APR_BRIGADE_SENTINEL(bb);
+         e = APR_BUCKET_NEXT(e)) {
+        ABTS_ASSERT(tc, "bucket size sane", e->length != (apr_size_t)-1);
+        count += e->length;
+    }
+
+    ABTS_ASSERT(tc, "total size of buckets incorrect", count == bignum);
+    
+    apr_brigade_destroy(bb);
+    apr_file_close(f);
+    apr_bucket_alloc_destroy(ba);
+    apr_file_remove(TIF_FNAME, p);
+}
+
 abts_suite *testbuckets(abts_suite *suite)
 {
     suite = ADD_SUITE(suite);
@@ -296,6 +344,7 @@
     abts_run_test(suite, test_bwrite, NULL);
     abts_run_test(suite, test_splitline, NULL);
     abts_run_test(suite, test_splits, NULL);
+    abts_run_test(suite, test_insertfile, NULL);
 
     return suite;
 }