blob: 15181fd35029fd63f615336cb49674e44de55c30 [file] [log] [blame]
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
static MP_INLINE
void mpxs_APR__Brigade_cleanup(apr_bucket_brigade *brigade)
{
/* apr has a broken prototype (passing 'void *' instead of
* 'apr_bucket_brigade *', so use a wrapper here */
apr_brigade_cleanup(brigade);
}
static MP_INLINE
SV *mpxs_apr_brigade_create(pTHX_ SV *CLASS, SV *p_sv,
apr_bucket_alloc_t *ba)
{
apr_pool_t *p = mp_xs_sv2_APR__Pool(p_sv);
apr_bucket_brigade *bb = apr_brigade_create(p, ba);
SV *bb_sv = sv_setref_pv(newSV(0), "APR::Brigade", (void*)bb);
mpxs_add_pool_magic(bb_sv, p_sv);
return bb_sv;
}
#define get_brigade(brigade, fetch) \
(fetch(brigade) == APR_BRIGADE_SENTINEL(brigade) ? \
NULL : fetch(brigade))
static MP_INLINE
apr_bucket *mpxs_APR__Brigade_first(apr_bucket_brigade *brigade)
{
return get_brigade(brigade, APR_BRIGADE_FIRST);
}
static MP_INLINE
apr_bucket *mpxs_APR__Brigade_last(apr_bucket_brigade *brigade)
{
return get_brigade(brigade, APR_BRIGADE_LAST);
}
#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);
}
static MP_INLINE
apr_bucket *mpxs_APR__Brigade_prev(apr_bucket_brigade *brigade,
apr_bucket *bucket)
{
return get_bucket(brigade, bucket, APR_BUCKET_PREV);
}
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);
}
static MP_INLINE
void mpxs_APR__Brigade_concat(apr_bucket_brigade *a,
apr_bucket_brigade *b)
{
APR_BRIGADE_CONCAT(a, b);
}
static MP_INLINE
int mpxs_APR__Brigade_is_empty(apr_bucket_brigade *brigade)
{
return APR_BRIGADE_EMPTY(brigade);
}
static MP_INLINE
apr_pool_t *mpxs_APR__Brigade_pool(apr_bucket_brigade *brigade)
{
/* eesh, it's r->pool, and c->pool, but bb->p
* let's make Perl consistent, otherwise this could be autogenerated
*/
return brigade->p;
}
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);
/* XXX - we're deviating from the API here a bit in order to
* make it more perlish - returning the length instead of
* the return code. maybe that's not such a good idea, though...
*/
if (rv == APR_SUCCESS) {
return newSViv((int)length);
}
return &PL_sv_undef;
}
#define mp_xs_sv2_bb mp_xs_sv2_APR__Brigade
static MP_INLINE
apr_size_t mpxs_APR__Brigade_flatten(pTHX_ I32 items,
SV **MARK, SV **SP)
{
apr_bucket_brigade *bb;
apr_size_t wanted;
apr_status_t rc;
SV *buffer;
mpxs_usage_va_2(bb, buffer, "$bb->flatten($buf, [$wanted])");
if (items > 2) {
/* APR::Brigade->flatten($wanted); */
wanted = SvIV(*MARK);
}
else {
/* APR::Brigade->flatten(); */
/* can't use pflatten, because we can't realloc() memory
* allocated by pflatten. and we need to append '\0' to it in
* SvPVX. so we copy pflatten's guts here.
*/
apr_off_t actual;
apr_brigade_length(bb, 1, &actual);
wanted = (apr_size_t)actual;
}
(void)SvUPGRADE(buffer, SVt_PV);
mpxs_sv_grow(buffer, wanted);
rc = apr_brigade_flatten(bb, SvPVX(buffer), &wanted);
if (!(rc == APR_SUCCESS || rc == APR_EOF)) {
modperl_croak(aTHX_ rc, "APR::Brigade::flatten");
}
mpxs_sv_cur_set(buffer, wanted);
SvTAINTED_on(buffer);
return wanted;
}
static MP_INLINE
void mpxs_APR__Brigade_destroy(pTHX_ apr_bucket_brigade *bb)
{
MP_RUN_CROAK(apr_brigade_destroy(bb), "APR::Brigade::destroy");
}
/*
* Local Variables:
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*/