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]

Reply via email to