/* 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, 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"); }