]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: channel: new getword and getchar functions on channel.
authorEmeric Brun <ebrun@haproxy.com>
Mon, 5 Oct 2020 12:35:21 +0000 (14:35 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 7 Oct 2020 15:17:27 +0000 (17:17 +0200)
This patch adds two new functions to get a char
or a word from a channel.

include/haproxy/channel.h
src/channel.c

index 3cd3bb3b1f277ab3b0da65b485c21bacdd340178..de51d046789e2e24d5923d606799d056588ef0ba 100644 (file)
@@ -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);
index a139eada124ba907b9897bbb0af9d1f37630eea3..ba8ab638a1552ed488613615e46faab3a4972e8d 100644 (file)
@@ -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.