From: Willy Tarreau Date: Thu, 3 Sep 2009 05:13:50 +0000 (+0200) Subject: [MINOR] buffers: provide buffer_si_putchar() to send a char from a stream interface X-Git-Tag: v1.4-dev3~24 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=36a5c5389d2073126813ed834a7aca4810389bc0;p=thirdparty%2Fhaproxy.git [MINOR] buffers: provide buffer_si_putchar() to send a char from a stream interface This function works like a traditional putchar() except that it can return 0 if the output buffer is full. Now a basic character-based echo function would look like this, from a stream interface : while (1) { c = buffer_si_peekchar(req); if (c < 0) break; if (!buffer_si_putchar(res, c)) { si->flags |= SI_FL_WAIT_ROOM; break; } buffer_skip(req, 1); req->flags |= BF_WRITE_PARTIAL; res->flags |= BF_READ_PARTIAL; } --- diff --git a/include/proto/buffers.h b/include/proto/buffers.h index 544db654f5..724d14800a 100644 --- a/include/proto/buffers.h +++ b/include/proto/buffers.h @@ -366,6 +366,7 @@ static inline int buffer_si_peekchar(struct buffer *buf) int buffer_write(struct buffer *buf, const char *msg, int len); int buffer_feed(struct buffer *buf, const char *str, int len); +int buffer_si_putchar(struct buffer *buf, char c); int buffer_si_peekline(struct buffer *buf, char *str, int len); int buffer_replace(struct buffer *b, char *pos, char *end, const char *str); int buffer_replace2(struct buffer *b, char *pos, char *end, const char *str, int len); diff --git a/src/buffers.c b/src/buffers.c index edda45954f..ee7a5dce75 100644 --- a/src/buffers.c +++ b/src/buffers.c @@ -119,6 +119,38 @@ int buffer_feed(struct buffer *buf, const char *str, int len) return -1; } +/* Try to write character into buffer after length controls. This + * work like buffer_feed(buf, &c, 1). + * Returns non-zero in case of success, 0 if the buffer was full. + * The send limit is automatically adjusted with the amount of data written. + */ +int buffer_si_putchar(struct buffer *buf, char c) +{ + if (buf->flags & BF_FULL) + return 0; + + if (!buf->l) + buf->r = buf->w = buf->lr = buf->data; + + *buf->r++ = c; + buf->l++; + buf->total++; + + if (buf->to_forward) { + buf->send_max++; + buf->to_forward--; + } + + if (buf->r == buf->data + buf->size) + buf->r = buf->data; + + buf->flags &= ~(BF_EMPTY|BF_FULL); + if (buf->l >= buf->max_len) + buf->flags |= BF_FULL; + + return 1; +} + /* Get one text line out of a buffer from a stream interface. * Return values : * >0 : number of bytes read. Includes the \n if present before len or end.