MP_TRACE_f(MP_FUNC, "eating/returning %d of remaining %d leftover bytes\n",
MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT "eating and returning %d of " "remaining %d leftover bytes\n", MP_FILTER_NAME(filter->f),
MP_INLINE static apr_size_t modperl_filter_read(pTHX_                                                modperl_filter_t *filter,                                                SV *buffer,                                                apr_size_t wanted){    int num_buckets = 0;    apr_size_t len = 0;        (void)SvUPGRADE(buffer, SVt_PV);    SvPOK_only(buffer);    SvCUR(buffer) = 0;    /* sometimes the EOS bucket arrives in the same brigade with other     * buckets, so that particular read() will not return 0 and will     * be called again if called in the while ($filter->read(...))     * loop. In that case we return 0.     */    if (filter->seen_eos) {        return 0;    }        /*modperl_brigade_dump(filter->bb_in, stderr);*/    MP_TRACE_f(MP_FUNC, "%s filter wants %d bytes\n",               (filter->mode == MP_INPUT_FILTER_MODE ? "input" : "output"),               wanted);    if (filter->remaining) {        if (filter->remaining >= wanted) {            MP_TRACE_f(MP_FUNC,                       "eating/returning %d of remaining %d leftover bytes\n",                       wanted, filter->remaining);            sv_catpvn(buffer, filter->leftover, wanted);            filter->leftover += wanted;            filter->remaining -= wanted;            return wanted;        }        else {            MP_TRACE_f(MP_FUNC, "eating remaining %d leftover bytes\n",                       filter->remaining);            sv_catpvn(buffer, filter->leftover, filter->remaining);            len = filter->remaining;            filter->remaining = 0;            filter->leftover = NULL;        }    }    while (1) {        const char *buf;        apr_size_t buf_len;        if (!get_bucket(filter)) {            break;        }        num_buckets++;        filter->rc = apr_bucket_read(filter->bucket, &buf, &buf_len, 0);        if (filter->rc == APR_SUCCESS) {            MP_TRACE_f(MP_FUNC,                       "bucket=%s(0x%lx) read returned %d bytes\n",                       filter->bucket->type->name,                       (unsigned long)filter->bucket,                       buf_len);        }        else {            MP_TRACE_f(MP_FUNC,                       "apr_bucket_read error: %s\n",                       modperl_apr_strerror(filter->rc));            return len;        }        if (buf_len) {            if ((SvCUR(buffer) + buf_len) >= wanted) {                int nibble = wanted - SvCUR(buffer);                sv_catpvn(buffer, buf, nibble);                filter->leftover = (char *)buf+nibble;                filter->remaining = buf_len - nibble;                len += nibble;                break;            }            else {                len += buf_len;                sv_catpvn(buffer, buf, buf_len);            }        }    }    MP_TRACE_f(MP_FUNC,               "returning %d bytes from %d bucket%s "               "(%d bytes leftover)\n",               len, num_buckets, ((num_buckets == 1) ? "" : "s"),               filter->remaining);    return len;}