Tom Schindl wrote:
More perlish would be:

insert_head => unshift
insert_tail => push

Although these method-names are perfect.

I should have mentioned that we want to stay as close as possible to the C API and change things only when things aren't quite perlish (like when C passes its arguments by reference, in order to return more than one argument). Otherwise we try to mostly stick to the C API. That's in order to make the life of those who have to write modules in Perl and C Apache API.


So, in this case, the glue code is this:

static MP_INLINE
void mpxs_APR__Brigade_insert_tail(apr_bucket_brigade *brigade,
                                   apr_bucket *bucket)
{
    APR_BRIGADE_INSERT_TAIL(brigade, bucket);
}

static MP_INLINE
void mpxs_APR__Brigade_insert_head(apr_bucket_brigade *brigade,
                                   apr_bucket *bucket)
{
    APR_BRIGADE_INSERT_HEAD(brigade, bucket);
}

where APR_... are C macros privided by APR.

> next($b) => next()
> prev($b) => prev()
>
> I don't know whether my conception is right but $bb is something like an
> iterator. Why does one have to pass $bb->next($b) $b, wouldn't
> $bb->next() that's how iterator work, at least i'd expect that.

bucket brigade is not an iterator, it's a container for buckets, which internally is just a linked list. So when you say next($b), it does something like $b->next, but it has no way to tell whether it hits the wall or not. In C it looks like:

#define get_bucket(brigade, bucket, fetch) \
(fetch(bucket) == APR_BRIGADE_SENTINEL(brigade) ? \
 NULL : fetch(bucket))

static MP_INLINE
apr_bucket *mpxs_APR__Brigade_next(apr_bucket_brigade *brigade,
                                    apr_bucket *bucket)
{
    return get_bucket(brigade, bucket, APR_BUCKET_NEXT);
}

which can be translated as:

 APR_BUCKET_NEXT(bucket) == APR_BRIGADE_SENTINEL(brigade)
   ? NULL : APR_BUCKET_NEXT(bucket);

gimme the next bucket, unless it's a sentinel bucket.

That wall is artificial and needed because internally it's implemented using a ring:

/**
 * The magic pointer value that indicates the head of the brigade
 * @remark This is used to find the beginning and end of the brigade, eg:
 * <pre>
 *      while (e != APR_BRIGADE_SENTINEL(b)) {
 *          ...
 *          e = APR_BUCKET_NEXT(e);
 *      }
 * </pre>
 * @param  b The brigade
 * @return The magic pointer value
 */
#define APR_BRIGADE_SENTINEL(b) APR_RING_SENTINEL(&(b)->list, apr_bucket, link)

I agree with you that ideally, you should be able to just say:

  $b_next = $b->next;

and it should work. The problem is that the bucket has no idea which brigade it belongs to. There is not much we can do about it. We just provide the perl glue to the existing C code.

If you are after confusing functions, I find much more confusing the following APR::Bucket APIs:
# insert_after
# insert_before


--
__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com

--
Report problems: http://perl.apache.org/bugs/
Mail list info: http://perl.apache.org/maillist/modperl.html
List etiquette: http://perl.apache.org/maillist/email-etiquette.html



Reply via email to