The purpose of this patch is allow apr_brigade_vprintf and consequently
apr_brigade_printf to handle arbitrary length strings. This is similar to
the ap_vrprintf patch that I submitted previously. The buffer is allocated
off the stack, so it should be thread safe (thanks Greg).
regards,
--
Cody Sherr
Engineer
Covalent Technologies
phone: (415)536-5292
email: [EMAIL PROTECTED]
Index: apr_brigade.c
===================================================================
RCS file: /home/cvspublic/apr-util/buckets/apr_brigade.c,v
retrieving revision 1.22
diff -u -r1.22 apr_brigade.c
--- apr_brigade.c 2001/08/08 22:24:04 1.22
+++ apr_brigade.c 2001/08/17 21:05:08
@@ -53,6 +53,7 @@
*/
#include "apr.h"
+#include "apr_lib.h"
#include "apr_strings.h"
#include "apr_pools.h"
#include "apr_tables.h"
@@ -382,18 +383,67 @@
return rv;
}
+struct bridgade_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 bridgade_vprintf_data_t* */
+ struct bridgade_vprintf_data_t *vd = (struct bridgade_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)
{
- /* XXX: This needs to be replaced with a function to printf
- * directly into a bucket. I'm being lazy right now. RBB
- */
- char buf[4096];
-
- apr_vsnprintf(buf, sizeof(buf), fmt, va);
-
- return apr_brigade_puts(b, flush, ctx, buf);
+ /* the cast, in order of appearance */
+ struct bridgade_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);
}