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]