>
> Not only not intuitive, but wrong. Consider this case: some function
> returns the wanted amount of chars to slurp, let's say it decides that
> it doesn't want any more chars and sets $wanted to 0 and you passed it
> to $bb->flatten($pool, $wanted); now instead of getting an empty string,
> you get the whole brigade. You could check that $wanted is 0 and not
> call flatten, but hey why making it more error-prone to users.
yes, you're right
>> + return newSVpvn(buffer, length);
>
>
> this is a bad idea. You should install the buffer into the SV not copy it.
ok, both of these issues are addressed in the attached patch.
--Geoff
Index: t/response/TestAPR/flatten.pm
===================================================================
RCS file: /home/cvspublic/modperl-2.0/t/response/TestAPR/flatten.pm,v
retrieving revision 1.2
diff -u -r1.2 flatten.pm
--- t/response/TestAPR/flatten.pm 27 Jan 2004 16:34:36 -0000 1.2
+++ t/response/TestAPR/flatten.pm 28 Jan 2004 19:07:00 -0000
@@ -16,7 +16,7 @@
my $r = shift;
- plan $r, tests => 14;
+ plan $r, tests => 16;
# first, create a brigade
my $pool = $r->pool;
@@ -36,10 +36,24 @@
$bb->length,
'APR::Brigade::length()');
+ # syntax: require a $bb
+ eval { APR::Brigade::flatten("", "") };
+
+ ok t_cmp(qr!expecting an APR::Brigade derived object!,
+ $@,
+ 'APR::Brigade::flatten() requires a brigade');
+
+ # syntax: always require a pool
+ eval { $bb->flatten("") };
+
+ ok t_cmp(qr!expecting an APR::Pool derived object!,
+ $@,
+ 'APR::Brigade::flatten() requires a pool');
+
# syntax: always require a pool
eval { $bb->flatten() };
- ok t_cmp(qr/Usage: APR::Brigade::flatten/,
+ ok t_cmp(qr!usage: \$bb->flatten!,
$@,
'APR::Brigade::flatten() requires a pool');
@@ -50,24 +64,24 @@
ok t_cmp(200000,
length($data),
- 'APR::Brigade::flatten() returned all the data');
+ '$bb->flatten($pool) returned all the data');
# don't use t_cmp() here, else we get 200,000 characters
# to look at in verbose mode
- t_debug("APR::Brigade::flatten() data all 'x' characters");
+ t_debug("data all 'x' characters");
ok ($data !~ m/[^x]/);
}
- # syntax: flatten($p, 0) is equivalent to flatten($p)
+ # flatten($p, 0) returns 0 bytes
{
my $data = $bb->flatten($pool, 0);
- ok t_cmp(200000,
+ t_debug('$bb->flatten($pool, 0) returns a defined value');
+ ok (defined $data);
+
+ ok t_cmp(0,
length($data),
- 'APR::Brigade::flatten() returned all the data');
-
- t_debug("APR::Brigade::flatten() data all 'x' characters");
- ok ($data !~ m/[^x]/);
+ '$bb->flatten($pool, 0) returned no data');
}
@@ -79,7 +93,7 @@
ok t_cmp(30,
length($data),
- 'APR::Brigade::flatten() returned all the data');
+ '$bb->flatten($pool, 30) returned 30 characters');
t_debug("APR::Brigade::flatten() data all 'x' characters");
ok ($data !~ m/[^x]/);
@@ -91,9 +105,9 @@
ok t_cmp(190000,
length($data),
- 'APR::Brigade::flatten() returned all the data');
+ '$bb->flatten($pool, 190000) returned 19000 characters');
- t_debug("APR::Brigade::flatten() data all 'x' characters");
+ t_debug("data all 'x' characters");
ok ($data !~ m/[^x]/);
}
@@ -103,9 +117,9 @@
ok t_cmp(200000,
length($data),
- 'APR::Brigade::flatten() returned all the data');
+ '$bb->flatten($pool, 300000) returned all 200000 characters');
- t_debug("APR::Brigade::flatten() data all 'x' characters");
+ t_debug("data all 'x' characters");
ok ($data !~ m/[^x]/);
}
@@ -113,12 +127,12 @@
{
my $data = APR::Brigade->new($pool, $ba)->flatten($pool);
- t_debug('an empty brigade returns a defined value');
+ t_debug('empty brigade returns a defined value');
ok (defined $data);
ok t_cmp(0,
length($data),
- 'an empty brigade returns data of 0 length');
+ 'empty brigade returns data of 0 length');
}
Apache::OK;
Index: xs/APR/Brigade/APR__Brigade.h
===================================================================
RCS file: /home/cvspublic/modperl-2.0/xs/APR/Brigade/APR__Brigade.h,v
retrieving revision 1.7
diff -u -r1.7 APR__Brigade.h
--- xs/APR/Brigade/APR__Brigade.h 28 Jan 2004 13:54:27 -0000 1.7
+++ xs/APR/Brigade/APR__Brigade.h 28 Jan 2004 19:07:00 -0000
@@ -97,28 +97,36 @@
}
static MP_INLINE
-SV *mpxs_APR__Brigade_flatten(pTHX_ apr_bucket_brigade *bb,
- apr_pool_t *pool, SV *sv_len)
+SV *mpxs_APR__Brigade_flatten(pTHX_ I32 items,
+ SV **MARK, SV **SP)
{
+ apr_bucket_brigade *bb;
+ apr_pool_t *pool;
+ apr_size_t length;
+ apr_status_t status;
+ char *buffer;
+ SV *data = newSV(0);
+
/* 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;
- char *buffer;
- apr_size_t length;
+ if (items < 2) {
+ Perl_croak(aTHX_ "usage: $bb->flatten($pool, [$length])");
+ }
+
+ bb = mp_xs_sv2_APR__Brigade(*MARK);
+ pool = mp_xs_sv2_APR__Pool(*(MARK+1));
- if (SvTRUE(sv_len)) {
+ if (items > 2) {
/* 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);
+ length = SvIV(*(MARK+2));
/* since we always require a pool, we can allocate from it */
buffer = apr_pcalloc(pool, length);
@@ -130,7 +138,7 @@
/* 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
+ * note that length is output only
*/
status = apr_brigade_pflatten(bb, &buffer, &length, pool);
@@ -145,5 +153,12 @@
return &PL_sv_undef;
}
- return newSVpvn(buffer, length);
+ mpxs_sv_grow(data, length);
+ SvPVX(data) = buffer;
+ mpxs_sv_cur_set(data, length);
+
+ /* the brigade could be anything, so taint it */
+ SvTAINTED_on(data);
+
+ return data;
}
Index: xs/maps/apr_functions.map
===================================================================
RCS file: /home/cvspublic/modperl-2.0/xs/maps/apr_functions.map,v
retrieving revision 1.68
diff -u -r1.68 apr_functions.map
--- xs/maps/apr_functions.map 28 Jan 2004 13:54:35 -0000 1.68
+++ xs/maps/apr_functions.map 28 Jan 2004 19:07:00 -0000
@@ -98,7 +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
+ mpxs_APR__Brigade_flatten | | ...
mpxs_APR__Brigade_pool
MODULE=APR::Bucket
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]