geoff 2004/01/27 08:34:37
Modified: t/response/TestAPR flatten.pm
xs/APR/Brigade APR__Brigade.h
xs/maps apr_functions.map
xs/tables/current/ModPerl FunctionTable.pm
Log:
rework apr_brigade_flatten and apr_brigade_pflatten into a single
APR::Brigade::flatten()
Revision Changes Path
1.2 +62 -38 modperl-2.0/t/response/TestAPR/flatten.pm
Index: flatten.pm
===================================================================
RCS file: /home/cvs/modperl-2.0/t/response/TestAPR/flatten.pm,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- flatten.pm 23 Jan 2004 15:26:55 -0000 1.1
+++ flatten.pm 27 Jan 2004 16:34:36 -0000 1.2
@@ -16,11 +16,13 @@
my $r = shift;
- plan $r, tests => 9;
+ plan $r, tests => 14;
# first, create a brigade
- my $bb = APR::Brigade->new($r->pool,
- $r->connection->bucket_alloc);
+ my $pool = $r->pool;
+ my $ba = $r->connection->bucket_alloc;
+
+ my $bb = APR::Brigade->new($pool, $ba);
# now, let's put several buckets in it
for (1 .. 10) {
@@ -34,19 +36,17 @@
$bb->length,
'APR::Brigade::length()');
- # slurp up the entire brigade
- # this is somewhat wasteful, since we're simulating a user
- # 'guessing' at how much data there is to slurp
- {
- my $rc = $bb->flatten(my $data, my $length = 300000);
-
- ok t_cmp(APR::SUCCESS,
- $rc,
- 'APR::Brigade::flatten() return value');
+ # syntax: always require a pool
+ eval { $bb->flatten() };
- ok t_cmp(200000,
- $length,
- 'APR::Brigade::flatten() length population');
+ ok t_cmp(qr/Usage: APR::Brigade::flatten/,
+ $@,
+ 'APR::Brigade::flatten() requires a pool');
+
+ # flatten($pool) will slurp up the entire brigade
+ # equivalent to calling apr_brigade_pflatten
+ {
+ my $data = $bb->flatten($pool);
ok t_cmp(200000,
length($data),
@@ -58,44 +58,68 @@
ok ($data !~ m/[^x]/);
}
- # test that other length variants - such as constants and
- # subroutine returns - don't segfault
+ # syntax: flatten($p, 0) is equivalent to flatten($p)
{
- my $rc = $bb->flatten(my $data, 300000);
+ my $data = $bb->flatten($pool, 0);
+
+ ok t_cmp(200000,
+ length($data),
+ 'APR::Brigade::flatten() returned all the data');
- ok t_cmp(APR::SUCCESS,
- $rc,
- 'APR::Brigade::flatten() return value');
+ t_debug("APR::Brigade::flatten() data all 'x' characters");
+ ok ($data !~ m/[^x]/);
}
- # this is probably the best example of using flatten() to
- # get the entire brigade - using $bb->length to determine
- # the full size of the brigade.
- # probably still inefficient, though...
+
+ # flatten($pool, $length) will return the first $length bytes
+ # equivalent to calling apr_brigade_flatten
{
- my $rc = $bb->flatten(my $data, $bb->length);
+ # small
+ my $data = $bb->flatten($pool, 30);
+
+ ok t_cmp(30,
+ length($data),
+ 'APR::Brigade::flatten() returned all the data');
- ok t_cmp(APR::SUCCESS,
- $rc,
- 'APR::Brigade::flatten() return value');
+ t_debug("APR::Brigade::flatten() data all 'x' characters");
+ ok ($data !~ m/[^x]/);
}
- # this is the most proper use of flatten() - retrieving
- # only a chunk of a brigade. most examples in httpd core
- # use flatten() to grab the first 30 bytes or so
{
- my $rc = $bb->flatten(my $data, 100000);
+ # large
+ my $data = $bb->flatten($pool, 190000);
- ok t_cmp(APR::SUCCESS,
- $rc,
- 'APR::Brigade::flatten() return value');
+ ok t_cmp(190000,
+ length($data),
+ 'APR::Brigade::flatten() returned all the data');
+
+ t_debug("APR::Brigade::flatten() data all 'x' characters");
+ ok ($data !~ m/[^x]/);
+ }
+
+ {
+ # more than enough
+ my $data = $bb->flatten($pool, 300000);
- ok t_cmp(100000,
+ ok t_cmp(200000,
length($data),
'APR::Brigade::flatten() returned all the data');
+
+ t_debug("APR::Brigade::flatten() data all 'x' characters");
+ ok ($data !~ m/[^x]/);
}
- # pflatten() examples to come...
+ # fetch from a brigade with no data in it
+ {
+ my $data = APR::Brigade->new($pool, $ba)->flatten($pool);
+
+ t_debug('an empty brigade returns a defined value');
+ ok (defined $data);
+
+ ok t_cmp(0,
+ length($data),
+ 'an empty brigade returns data of 0 length');
+ }
Apache::OK;
}
1.6 +43 -9 modperl-2.0/xs/APR/Brigade/APR__Brigade.h
Index: APR__Brigade.h
===================================================================
RCS file: /home/cvs/modperl-2.0/xs/APR/Brigade/APR__Brigade.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- APR__Brigade.h 23 Jan 2004 15:26:55 -0000 1.5
+++ APR__Brigade.h 27 Jan 2004 16:34:36 -0000 1.6
@@ -87,19 +87,53 @@
}
static MP_INLINE
-apr_status_t mpxs_apr_brigade_flatten(pTHX_ apr_bucket_brigade *bb,
- SV *sv_buf, SV *sv_len)
+SV *mpxs_APR__Brigade_flatten(pTHX_ apr_bucket_brigade *bb,
+ apr_pool_t *pool, SV *sv_len)
{
+
+ /* XXX we're deviating from the API here to try and make
+ * the API more Perlish - nobody likes the idea of two
+ * "in/out" arguments. and we generally don't ever need
+ * the length anyway...
+ */
+
apr_status_t status;
- apr_size_t len = mp_xs_sv2_apr_size_t(sv_len);
+ char *buffer;
+ apr_size_t length;
+
+ if (SvTRUE(sv_len)) {
+ /* APR::Brigade->flatten($p, $length);
+ * use apr_brigade_flatten to get the first $length bytes
+ *
+ * note that $length must be non-zero to get here
+ */
+
+ length = mp_xs_sv2_apr_size_t(sv_len);
+
+ /* since we always require a pool, we can allocate from it */
+ buffer = apr_pcalloc(pool, length);
- mpxs_sv_grow(sv_buf, len);
- status = apr_brigade_flatten(bb, SvPVX(sv_buf), &len);
- mpxs_sv_cur_set(sv_buf, len);
+ status = apr_brigade_flatten(bb, buffer, &length);
+
+ }
+ else {
+ /* APR::Brigade->flatten($p);
+ * use apr_brigade_pflatten to slurp the entire brigade
+ *
+ * note that it doesn't matter what we pass in for length
+ */
+
+ status = apr_brigade_pflatten(bb, &buffer, &length, pool);
+
+ }
- if (!SvREADONLY(sv_len)) {
- sv_setiv(sv_len, len);
+ if (status != APR_SUCCESS) {
+ /* XXX croak?
+ * note that reading from an empty brigade will return
+ * an empty string, not undef, so there is a difference
+ */
+ return &PL_sv_undef;
}
- return status;
+ return newSVpvn(buffer, length);
}
1.67 +3 -2 modperl-2.0/xs/maps/apr_functions.map
Index: apr_functions.map
===================================================================
RCS file: /home/cvs/modperl-2.0/xs/maps/apr_functions.map,v
retrieving revision 1.66
retrieving revision 1.67
diff -u -r1.66 -r1.67
--- apr_functions.map 23 Jan 2004 15:26:55 -0000 1.66
+++ apr_functions.map 27 Jan 2004 16:34:36 -0000 1.67
@@ -86,8 +86,8 @@
!apr_brigade_puts
-apr_brigade_putc
!apr_brigade_cleanup
- apr_brigade_flatten | mpxs_ | bb, SV *:sv_buf, SV *:sv_len
-?apr_brigade_pflatten
+~apr_brigade_flatten
+~apr_brigade_pflatten
?apr_brigade_split_line
mpxs_APR__Brigade_first #APR_BRIGADE_FIRST
mpxs_APR__Brigade_last #APR_BRIGADE_LAST
@@ -98,6 +98,7 @@
mpxs_APR__Brigade_concat #APR_BRIGADE_CONCAT
mpxs_APR__Brigade_empty #APR_BRIGADE_EMPTY
mpxs_APR__Brigade_length | | bb, read_all=1
+ mpxs_APR__Brigade_flatten | | bb, pool, sv_len=0
MODULE=APR::Bucket
mpxs_APR__Bucket_is_flush #APR_BUCKET_IS_FLUSH
1.140 +4 -4 modperl-2.0/xs/tables/current/ModPerl/FunctionTable.pm
Index: FunctionTable.pm
===================================================================
RCS file: /home/cvs/modperl-2.0/xs/tables/current/ModPerl/FunctionTable.pm,v
retrieving revision 1.139
retrieving revision 1.140
diff -u -r1.139 -r1.140
--- FunctionTable.pm 23 Jan 2004 15:26:56 -0000 1.139
+++ FunctionTable.pm 27 Jan 2004 16:34:36 -0000 1.140
@@ -6462,8 +6462,8 @@
]
},
{
- 'return_type' => 'apr_status_t',
- 'name' => 'mpxs_apr_brigade_flatten',
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_APR__Brigade_flatten',
'args' => [
{
'type' => 'PerlInterpreter *',
@@ -6474,8 +6474,8 @@
'name' => 'bb'
},
{
- 'type' => 'SV *',
- 'name' => 'sv_buf'
+ 'type' => 'apr_pool_t *',
+ 'name' => 'pool'
},
{
'type' => 'SV *',