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