diff options
author | Emeric Brun <ebrun@haproxy.com> | 2020-10-05 14:35:21 +0200 |
---|---|---|
committer | Willy Tarreau <w@1wt.eu> | 2020-10-07 17:17:27 +0200 |
commit | 6d75616951b260456f96f370210432b3108891b0 (patch) | |
tree | f39ec6efa97d198e331c443ceac0bf34fe9d17b6 | |
parent | 2897644ae5cdfde7a91271b3c4c7d879ed336be3 (diff) | |
download | haproxy-6d75616951b260456f96f370210432b3108891b0.tar.gz |
MINOR: channel: new getword and getchar functions on channel.
This patch adds two new functions to get a char
or a word from a channel.
-rw-r--r-- | include/haproxy/channel.h | 2 | ||||
-rw-r--r-- | src/channel.c | 74 |
2 files changed, 76 insertions, 0 deletions
diff --git a/include/haproxy/channel.h b/include/haproxy/channel.h index 3cd3bb3b1..de51d0467 100644 --- a/include/haproxy/channel.h +++ b/include/haproxy/channel.h @@ -47,7 +47,9 @@ int ci_getline_nc(const struct channel *chn, char **blk1, size_t *len1, char **b int ci_getblk_nc(const struct channel *chn, char **blk1, size_t *len1, char **blk2, size_t *len2); int ci_insert_line2(struct channel *c, int pos, const char *str, int len); int co_inject(struct channel *chn, const char *msg, int len); +int co_getchar(const struct channel *chn, char *c); int co_getline(const struct channel *chn, char *str, int len); +int co_getword(const struct channel *chn, char *str, int len, char sep); int co_getblk(const struct channel *chn, char *blk, int len, int offset); int co_getline_nc(const struct channel *chn, const char **blk1, size_t *len1, const char **blk2, size_t *len2); int co_getblk_nc(const struct channel *chn, const char **blk1, size_t *len1, const char **blk2, size_t *len2); diff --git a/src/channel.c b/src/channel.c index a139eada1..ba8ab638a 100644 --- a/src/channel.c +++ b/src/channel.c @@ -175,6 +175,57 @@ int ci_putblk(struct channel *chn, const char *blk, int len) return len; } +/* Gets one text word out of a channel's buffer from a stream interface. + * Return values : + * >0 : number of bytes read. Includes the sep if present before len or end. + * =0 : no sep before end found. <str> is left undefined. + * <0 : no more bytes readable because output is shut. + * The channel status is not changed. The caller must call co_skip() to + * update it. The line separator is waited for as long as neither the buffer + * nor the output are full. If either of them is full, the string may be + * returned as is, without the line separator. + */ +int co_getword(const struct channel *chn, char *str, int len, char sep) +{ + int ret, max; + char *p; + + ret = 0; + max = len; + + /* closed or empty + imminent close = -1; empty = 0 */ + if (unlikely((chn->flags & CF_SHUTW) || channel_is_empty(chn))) { + if (chn->flags & (CF_SHUTW|CF_SHUTW_NOW)) + ret = -1; + goto out; + } + + p = co_head(chn); + + if (max > co_data(chn)) { + max = co_data(chn); + str[max-1] = 0; + } + while (max) { + *str++ = *p; + ret++; + max--; + + if (*p == sep) + break; + p = b_next(&chn->buf, p); + } + if (ret > 0 && ret < len && + (ret < co_data(chn) || channel_may_recv(chn)) && + *(str-1) != sep && + !(chn->flags & (CF_SHUTW|CF_SHUTW_NOW))) + ret = 0; + out: + if (max) + *str = 0; + return ret; +} + /* Gets one text line out of a channel's buffer from a stream interface. * Return values : * >0 : number of bytes read. Includes the \n if present before len or end. @@ -226,6 +277,29 @@ int co_getline(const struct channel *chn, char *str, int len) return ret; } +/* Gets one char of data from a channel's buffer, + * Return values : + * 1 : number of bytes read, equal to requested size. + * =0 : not enough data available. <c> is left undefined. + * <0 : no more bytes readable because output is shut. + * The channel status is not changed. The caller must call co_skip() to + * update it. + */ +int co_getchar(const struct channel *chn, char *c) +{ + if (chn->flags & CF_SHUTW) + return -1; + + if (unlikely(co_data(chn) == 0)) { + if (chn->flags & (CF_SHUTW|CF_SHUTW_NOW)) + return -1; + return 0; + } + + *c = *(co_head(chn)); + return 1; +} + /* Gets one full block of data at once from a channel's buffer, optionally from * a specific offset. Return values : * >0 : number of bytes read, equal to requested size. |