⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 apr_brigade.c

📁 apache的软件linux版本
💻 C
📖 第 1 页 / 共 2 页
字号:
            return rv;        vec->iov_len = iov_len; /* set indirectly in case size differs */        ++vec;    }    *nvec = vec - orig;    return APR_SUCCESS;}APU_DECLARE(apr_status_t) apr_brigade_vputstrs(apr_bucket_brigade *b,                                                apr_brigade_flush flush,                                               void *ctx,                                               va_list va){    for (;;) {        const char *str = va_arg(va, const char *);        apr_status_t rv;        if (str == NULL)            break;        rv = apr_brigade_write(b, flush, ctx, str, strlen(str));        if (rv != APR_SUCCESS)            return rv;    }    return APR_SUCCESS;}APU_DECLARE(apr_status_t) apr_brigade_putc(apr_bucket_brigade *b,                                           apr_brigade_flush flush, void *ctx,                                           const char c){    return apr_brigade_write(b, flush, ctx, &c, 1);}APU_DECLARE(apr_status_t) apr_brigade_write(apr_bucket_brigade *b,                                            apr_brigade_flush flush,                                            void *ctx,                                             const char *str, apr_size_t nbyte){    apr_bucket *e = APR_BRIGADE_LAST(b);    apr_size_t remaining = APR_BUCKET_BUFF_SIZE;    char *buf = NULL;    if (!APR_BRIGADE_EMPTY(b) && APR_BUCKET_IS_HEAP(e)) {        apr_bucket_heap *h = e->data;        /* HEAP bucket start offsets are always in-memory, safe to cast */        remaining = h->alloc_len - (e->length + (apr_size_t)e->start);        buf = h->base + e->start + e->length;    }    if (nbyte > remaining) {        /* either a buffer bucket exists but is full,          * or no buffer bucket exists and the data is too big         * to buffer.  In either case, we should flush.  */        if (flush) {            e = apr_bucket_transient_create(str, nbyte, b->bucket_alloc);            APR_BRIGADE_INSERT_TAIL(b, e);            return flush(b, ctx);        }        else {            e = apr_bucket_heap_create(str, nbyte, NULL, b->bucket_alloc);            APR_BRIGADE_INSERT_TAIL(b, e);            return APR_SUCCESS;        }    }    else if (!buf) {        /* we don't have a buffer, but the data is small enough         * that we don't mind making a new buffer */        buf = apr_bucket_alloc(APR_BUCKET_BUFF_SIZE, b->bucket_alloc);        e = apr_bucket_heap_create(buf, APR_BUCKET_BUFF_SIZE,                                   apr_bucket_free, b->bucket_alloc);        APR_BRIGADE_INSERT_TAIL(b, e);        e->length = 0;   /* We are writing into the brigade, and                          * allocating more memory than we need.  This                          * ensures that the bucket thinks it is empty just                          * after we create it.  We'll fix the length                          * once we put data in it below.                          */    }    /* there is a sufficiently big buffer bucket available now */    memcpy(buf, str, nbyte);    e->length += nbyte;    return APR_SUCCESS;}APU_DECLARE(apr_status_t) apr_brigade_writev(apr_bucket_brigade *b,                                             apr_brigade_flush flush,                                             void *ctx,                                             const struct iovec *vec,                                             apr_size_t nvec){    apr_bucket *e;    apr_size_t total_len;    apr_size_t i;    char *buf;    /* Compute the total length of the data to be written.     */    total_len = 0;    for (i = 0; i < nvec; i++) {       total_len += vec[i].iov_len;    }    /* If the data to be written is very large, try to convert     * the iovec to transient buckets rather than copying.     */    if (total_len > APR_BUCKET_BUFF_SIZE) {        if (flush) {            for (i = 0; i < nvec; i++) {                e = apr_bucket_transient_create(vec[i].iov_base,                                                vec[i].iov_len,                                                b->bucket_alloc);                APR_BRIGADE_INSERT_TAIL(b, e);            }            return flush(b, ctx);        }        else {            for (i = 0; i < nvec; i++) {                e = apr_bucket_heap_create((const char *) vec[i].iov_base,                                           vec[i].iov_len, NULL,                                           b->bucket_alloc);                APR_BRIGADE_INSERT_TAIL(b, e);            }            return APR_SUCCESS;        }    }    i = 0;    /* If there is a heap bucket at the end of the brigade     * already, copy into the existing bucket.     */    e = APR_BRIGADE_LAST(b);    if (!APR_BRIGADE_EMPTY(b) && APR_BUCKET_IS_HEAP(e)) {        apr_bucket_heap *h = e->data;        apr_size_t remaining = h->alloc_len -            (e->length + (apr_size_t)e->start);        buf = h->base + e->start + e->length;        if (remaining >= total_len) {            /* Simple case: all the data will fit in the             * existing heap bucket             */            for (; i < nvec; i++) {                apr_size_t len = vec[i].iov_len;                memcpy(buf, (const void *) vec[i].iov_base, len);                buf += len;            }            e->length += total_len;            return APR_SUCCESS;        }        else {            /* More complicated case: not all of the data             * will fit in the existing heap bucket.  The             * total data size is <= APR_BUCKET_BUFF_SIZE,             * so we'll need only one additional bucket.             */            const char *start_buf = buf;            for (; i < nvec; i++) {                apr_size_t len = vec[i].iov_len;                if (len > remaining) {                    break;                }                memcpy(buf, (const void *) vec[i].iov_base, len);                buf += len;                remaining -= len;            }            e->length += (buf - start_buf);            total_len -= (buf - start_buf);            if (flush) {                apr_status_t rv = flush(b, ctx);                if (rv != APR_SUCCESS) {                    return rv;                }            }            /* Now fall through into the case below to             * allocate another heap bucket and copy the             * rest of the array.  (Note that i is not             * reset to zero here; it holds the index             * of the first vector element to be             * written to the new bucket.)             */        }    }    /* Allocate a new heap bucket, and copy the data into it.     * The checks above ensure that the amount of data to be     * written here is no larger than APR_BUCKET_BUFF_SIZE.     */    buf = apr_bucket_alloc(APR_BUCKET_BUFF_SIZE, b->bucket_alloc);    e = apr_bucket_heap_create(buf, APR_BUCKET_BUFF_SIZE,                               apr_bucket_free, b->bucket_alloc);    for (; i < nvec; i++) {        apr_size_t len = vec[i].iov_len;        memcpy(buf, (const void *) vec[i].iov_base, len);        buf += len;    }    e->length = total_len;    APR_BRIGADE_INSERT_TAIL(b, e);    return APR_SUCCESS;}APU_DECLARE(apr_status_t) apr_brigade_puts(apr_bucket_brigade *bb,                                           apr_brigade_flush flush, void *ctx,                                           const char *str){    apr_size_t len = strlen(str);    apr_bucket *bkt = APR_BRIGADE_LAST(bb);    if (!APR_BRIGADE_EMPTY(bb) && APR_BUCKET_IS_HEAP(bkt)) {        /* If there is enough space available in a heap bucket         * at the end of the brigade, copy the string directly         * into the heap bucket         */        apr_bucket_heap *h = bkt->data;        apr_size_t bytes_avail = h->alloc_len - bkt->length;        if (bytes_avail >= len) {            char *buf = h->base + bkt->start + bkt->length;            memcpy(buf, str, len);            bkt->length += len;            return APR_SUCCESS;        }    }    /* If the string could not be copied into an existing heap     * bucket, delegate the work to apr_brigade_write(), which     * knows how to grow the brigade     */    return apr_brigade_write(bb, flush, ctx, str, len);}APU_DECLARE_NONSTD(apr_status_t) apr_brigade_putstrs(apr_bucket_brigade *b,                                                      apr_brigade_flush flush,                                                     void *ctx, ...){    va_list va;    apr_status_t rv;    va_start(va, ctx);    rv = apr_brigade_vputstrs(b, flush, ctx, va);    va_end(va);    return rv;}APU_DECLARE_NONSTD(apr_status_t) apr_brigade_printf(apr_bucket_brigade *b,                                                     apr_brigade_flush flush,                                                    void *ctx,                                                     const char *fmt, ...){    va_list ap;    apr_status_t rv;    va_start(ap, fmt);    rv = apr_brigade_vprintf(b, flush, ctx, fmt, ap);    va_end(ap);    return rv;}struct brigade_vprintf_data_t {    apr_vformatter_buff_t vbuff;    apr_bucket_brigade *b;  /* associated brigade */    apr_brigade_flush *flusher; /* flushing function */    void *ctx;    char *cbuff; /* buffer to flush from */};static apr_status_t brigade_flush(apr_vformatter_buff_t *buff){    /* callback function passed to ap_vformatter to be     * called when vformatter needs to buff and     * buff.curpos > buff.endpos     */    /* "downcast," have really passed a brigade_vprintf_data_t* */    struct brigade_vprintf_data_t *vd = (struct brigade_vprintf_data_t*)buff;    apr_status_t res = APR_SUCCESS;    res = apr_brigade_write(vd->b, *vd->flusher, vd->ctx, vd->cbuff,                          APR_BUCKET_BUFF_SIZE);    if(res != APR_SUCCESS) {      return -1;    }    vd->vbuff.curpos = vd->cbuff;    vd->vbuff.endpos = vd->cbuff + APR_BUCKET_BUFF_SIZE;    return res;}APU_DECLARE(apr_status_t) apr_brigade_vprintf(apr_bucket_brigade *b,                                              apr_brigade_flush flush,                                              void *ctx,                                              const char *fmt, va_list va){    /* the cast, in order of appearance */    struct brigade_vprintf_data_t vd;    char buf[APR_BUCKET_BUFF_SIZE];    apr_size_t written;    vd.vbuff.curpos = buf;    vd.vbuff.endpos = buf + APR_BUCKET_BUFF_SIZE;    vd.b = b;    vd.flusher = &flush;    vd.ctx = ctx;    vd.cbuff = buf;    written = apr_vformatter(brigade_flush, &vd.vbuff, fmt, va);    if (written == -1) {      return -1;    }    /* tack on null terminator to remaining string */    *(vd.vbuff.curpos) = '\0';    /* write out what remains in the buffer */    return apr_brigade_write(b, flush, ctx, buf, vd.vbuff.curpos - buf);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -