Stas Bekman wrote:
> Geoffrey Young wrote:
>
>> hi all
>>
>> joe schaefer suggested on modperl@ that having access to
>> apr_brigade_flatten
>> might be of use.
> I certainly have no objections to opening up the entire APR API if
> someone needs it. And most of the APR::(Brigade|Bucket) API is needed in
> filters.
ok, here's a first pass. I opened up apr_brigade_length as well, since
apr_brigade_flatten takes a length parameter.
oh, and joe had asked:
> (hmm, does APR::Brigade have a DESTROY method?).
yes, apr_brigade_destroy is currently mapped as $bb->destroy, and is called
in a few of the filter tests.
--Geoff
Index: xs/APR/Brigade/APR__Brigade.h
===================================================================
RCS file: /home/cvspublic/modperl-2.0/xs/APR/Brigade/APR__Brigade.h,v
retrieving revision 1.4
diff -u -r1.4 APR__Brigade.h
--- xs/APR/Brigade/APR__Brigade.h 29 Mar 2002 16:16:43 -0000 1.4
+++ xs/APR/Brigade/APR__Brigade.h 20 Jan 2004 18:54:10 -0000
@@ -67,3 +67,35 @@
return APR_BRIGADE_EMPTY(brigade);
}
+static MP_INLINE
+SV *mpxs_APR__Brigade_length(pTHX_ apr_bucket_brigade *bb,
+ int read_all)
+{
+ apr_off_t length;
+
+ apr_status_t rv = apr_brigade_length(bb, read_all, &length);
+
+ if (rv == APR_SUCCESS) {
+ return newSViv((int)length);
+ }
+
+ return &PL_sv_undef;
+}
+
+static MP_INLINE
+apr_status_t mpxs_apr_brigade_flatten(pTHX_ apr_bucket_brigade *bb,
+ SV *sv_buf, SV *sv_len)
+{
+ apr_status_t status;
+ apr_size_t len = mp_xs_sv2_apr_size_t(sv_len);
+
+ mpxs_sv_grow(sv_buf, len);
+ status = apr_brigade_flatten(bb, SvPVX(sv_buf), &len);
+ mpxs_sv_cur_set(sv_buf, len);
+
+ if (!SvREADONLY(sv_len)) {
+ sv_setiv(sv_len, len);
+ }
+
+ return status;
+}
Index: xs/maps/apr_functions.map
===================================================================
RCS file: /home/cvspublic/modperl-2.0/xs/maps/apr_functions.map,v
retrieving revision 1.65
diff -u -r1.65 apr_functions.map
--- xs/maps/apr_functions.map 18 Dec 2003 18:53:50 -0000 1.65
+++ xs/maps/apr_functions.map 20 Jan 2004 18:54:11 -0000
@@ -81,12 +81,12 @@
-apr_brigade_to_iovec
-apr_brigade_vprintf
-apr_brigade_vputstrs
-!apr_brigade_length
+~apr_brigade_length
!apr_brigade_write
!apr_brigade_puts
-apr_brigade_putc
!apr_brigade_cleanup
-?apr_brigade_flatten
+ apr_brigade_flatten | mpxs_ | bb, SV *:sv_buf, SV *:sv_len
?apr_brigade_pflatten
?apr_brigade_split_line
mpxs_APR__Brigade_first #APR_BRIGADE_FIRST
@@ -97,6 +97,7 @@
mpxs_APR__Brigade_insert_head #APR_BRIGADE_INSERT_HEAD
mpxs_APR__Brigade_concat #APR_BRIGADE_CONCAT
mpxs_APR__Brigade_empty #APR_BRIGADE_EMPTY
+ mpxs_APR__Brigade_length | | bb, read_all=1
MODULE=APR::Bucket
mpxs_APR__Bucket_is_flush #APR_BUCKET_IS_FLUSH
Index: xs/tables/current/ModPerl/FunctionTable.pm
===================================================================
RCS file: /home/cvspublic/modperl-2.0/xs/tables/current/ModPerl/FunctionTable.pm,v
retrieving revision 1.136
diff -u -r1.136 FunctionTable.pm
--- xs/tables/current/ModPerl/FunctionTable.pm 14 Jan 2004 21:27:41 -0000 1.136
+++ xs/tables/current/ModPerl/FunctionTable.pm 20 Jan 2004 18:54:16 -0000
@@ -6440,6 +6440,46 @@
]
},
{
+ 'return_type' => 'SV *',
+ 'name' => 'mpxs_APR__Brigade_length',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bb'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'read_all'
+ },
+ ]
+ },
+ {
+ 'return_type' => 'apr_status_t',
+ 'name' => 'mpxs_apr_brigade_flatten',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'my_perl'
+ },
+ {
+ 'type' => 'apr_bucket_brigade *',
+ 'name' => 'bb'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv_buf'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'sv_len'
+ },
+ ]
+ },
+ {
'return_type' => 'apr_ipsubnet_t *',
'name' => 'mpxs_apr_ipsubnet_create',
'args' => [
--- /dev/null 2003-01-30 05:24:37.000000000 -0500
+++ t/response/TestAPR/brigade.pm 2004-01-20 13:53:14.000000000 -0500
@@ -0,0 +1,93 @@
+package TestAPR::brigade;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+
+use Apache::RequestRec ();
+use APR::Bucket ();
+use APR::Brigade ();
+
+use Apache::Const -compile => 'OK';
+
+sub handler {
+
+ my $r = shift;
+
+ plan $r, tests => 9;
+
+ # first, create a brigade
+ my $bb = APR::Brigade->new($r->pool,
+ $r->connection->bucket_alloc);
+
+ # now, let's put several buckets in it
+ for (1 .. 10) {
+ my $data = 'x' x 20000;
+ my $bucket = APR::Bucket->new($data);
+ $bb->insert_tail($bucket);
+ }
+
+ # ok, that's 10 buckets of 20,000 = 200,000 characters
+ ok t_cmp(200000,
+ $bb->length,
+ 'APR::Brigade::length()');
+
+ # slurp up the entire brigade
+ {
+ my $rc = $bb->flatten(my $data, my $length = 300000);
+
+ ok t_cmp(APR::SUCCESS,
+ $rc,
+ 'APR::Brigade::flatten() return value');
+
+ ok t_cmp(200000,
+ $length,
+ 'APR::Brigade::flatten() length population');
+
+ ok t_cmp(200000,
+ length($data),
+ 'APR::Brigade::flatten() 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");
+ ok ($data !~ m/[^x]/);
+ }
+
+ # test that other length variants - such as constants and
+ # subroutine returns - don't segfault
+ {
+ my $rc = $bb->flatten(my $data, 300000);
+
+ ok t_cmp(APR::SUCCESS,
+ $rc,
+ 'APR::Brigade::flatten() return value');
+ }
+
+ {
+ my $rc = $bb->flatten(my $data, $bb->length);
+
+ ok t_cmp(APR::SUCCESS,
+ $rc,
+ 'APR::Brigade::flatten() return value');
+ }
+
+ # read less than the whole brigade
+ {
+ my $rc = $bb->flatten(my $data, 100000);
+
+ ok t_cmp(APR::SUCCESS,
+ $rc,
+ 'APR::Brigade::flatten() return value');
+
+ ok t_cmp(100000,
+ length($data),
+ 'APR::Brigade::flatten() returned all the data');
+ }
+
+ Apache::OK;
+}
+
+1;
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]