-1
You cannot use a global variable for the buffer. That prevents multiple
threads from executing ap_vrprintf() at the same time.
Also, use a #define rather than the "const int" thing. This isn't C++, and
we don't need to use storage for a constant. Also note that the variable
wasn't labeled as static, so it would be exposed to external users anyway.
Otherwise, it looks good.
Cheers,
-g
On Wed, Aug 15, 2001 at 02:11:20PM -0700, Cody Sherr wrote:
>
> The purpose of this patch is to allow vrprintf to work for larger than 4k
> sized fmt strings by providing a flushing function for vformatter to use
> when the buffer fills up.
>
> regards,
>
> --
> Cody Sherr
>
> Engineer
> Covalent Technologies
>
> phone: (415)536-5292
> email: [EMAIL PROTECTED]
>
> Index: protocol.c
> ===================================================================
> RCS file: /home/cvspublic/httpd-2.0/server/protocol.c,v
> retrieving revision 1.38
> diff -u -r1.38 protocol.c
> --- protocol.c 2001/08/07 16:40:25 1.38
> +++ protocol.c 2001/08/15 20:59:39
> @@ -1133,19 +1133,63 @@
> return nbyte;
> }
>
> +const int BUFSIZE = 4096;
> +static char vrprintf_buf[4096];
> +
> +struct ap_vrprintf_data {
> + apr_vformatter_buff_t vbuff;
> + request_rec *r;
> +};
> +
> +static apr_status_t r_flush(apr_vformatter_buff_t *buff)
> +{
> + /* callback function passed to ap_vformatter to be called when
> + * vformatter needs to write into buff and buff.curpos > buff.endpos */
> +
> + /* ap_vrprintf_data passed as a apr_vformatter_buff_t, which is then
> + * "downcast" to an ap_vrprintf_data */
> + struct ap_vrprintf_data *vd = (struct ap_vrprintf_data*)buff;
> +
> + if (vd->r->connection->aborted)
> + return -1;
> +
> + /* r_flush is called when vbuff is completely full */
> + if (buffer_output(vd->r, vrprintf_buf, BUFSIZE)) {
> + return -1;
> + }
> +
> + /* reset the buffer position */
> + vd->vbuff.curpos = vrprintf_buf;
> + vd->vbuff.endpos = vrprintf_buf + BUFSIZE;
> +
> + return APR_SUCCESS;
> +}
> +
> AP_DECLARE(int) ap_vrprintf(request_rec *r, const char *fmt, va_list va)
> {
> - char buf[4096];
> apr_size_t written;
> + struct ap_vrprintf_data vd;
> +
> + vd.vbuff.curpos = vrprintf_buf;
> + vd.vbuff.endpos = vrprintf_buf + BUFSIZE;
> + vd.r = r;
>
> if (r->connection->aborted)
> return -1;
>
> - /* ### fix this mechanism to allow more than 4K of output */
> - written = apr_vsnprintf(buf, sizeof(buf), fmt, va);
> + written = apr_vformatter(r_flush, &vd.vbuff, fmt, va);
> + /* tack on null terminator on remaining string */
> + *(vd.vbuff.curpos) = '\0';
>
> - if (buffer_output(r, buf, written) != APR_SUCCESS)
> - return -1;
> + if (written != -1) {
> + int n = vd.vbuff.curpos - vrprintf_buf;
> +
> + /* last call to buffer_output, to finish clearing the buffer */
> + if (buffer_output(r, vrprintf_buf,n) != APR_SUCCESS)
> + return -1;
> +
> + written += n;
> + }
>
> return written;
> }
--
Greg Stein, http://www.lyra.org/