/* 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:
 */
