ew yuck.
please consult 1.3's src/main/buff.c ap_vbprintf() and see how you can do
this without exponential memory allocation. you need to use
ap_vformatter() and a callback... but it's really worth it.
there's probably even a 2.0 way that just uses multiple 4K buffers
allocated one after the other and tacked onto the bucket to avoid the
extra copy... which still has the disadvantage that it could consume lots
of memory (1 byte per byte output) but at least it doesn't consume 2 bytes
per byte output memory.
also -- if you really want to do it the way you've done it below you might
as well use ap_psprintf() ... which does almost what you're doing, but it
can at least optimise its use of the free space in a pool. but really the
bprintf() stuff from 1.3 is the best for an output buffer, 'cause you can
get rid of each 4K chunk as soon as you've finished writing to it, and
save memory. psprintf() style stuff is only useful if you absolutely need
the entire output as a single string.
-dean
On Wed, 1 Aug 2001, Cody Sherr wrote:
>
> This allows ap_vrprintf to handle > 4k length writes, as listed in STATUS.
>
> 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.35
> diff -u -r1.35 protocol.c
> --- protocol.c 2001/07/30 04:38:02 1.35
> +++ protocol.c 2001/08/01 21:08:02
> @@ -1135,14 +1135,31 @@
>
> AP_DECLARE(int) ap_vrprintf(request_rec *r, const char *fmt, va_list va)
> {
> - char buf[4096];
> + char *buf;
> + int buf_size = 4096; /* start with a 4k buffer */
> apr_size_t written;
>
> if (r->connection->aborted)
> return -1;
>
> - /* ### fix this mechanism to allow more than 4K of output */
> - written = apr_vsnprintf(buf, sizeof(buf), fmt, va);
> + buf = apr_palloc(r->pool, buf_size);
> + while (1) {
> + written = apr_vsnprintf(buf, buf_size, fmt, va);
> +
> + /*
> + * Per the apr_vsnprintf comments, in no event does apr_snprintf return a
>negative number.
> + * Therefore, it's not possible to distinguish between an output which was
>truncated,
> + * and an output which exactly filled the buffer.
> + */
> + if (written == buf_size) {
> + buf_size *= 2;
> + buf = apr_palloc(r->pool, buf_size); /* want realloc */
> + }
> + else {
> + break;
> + }
> + }
> +
> if (buffer_output(r, buf, written) != APR_SUCCESS)
> return -1;
>
>
>