From: Amaury Denoyelle Date: Thu, 16 Oct 2025 13:05:50 +0000 (+0200) Subject: MINOR: ncbuf2: implement advance operation X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=37f086a14c36f9615431e989a70279a423f85813;p=thirdparty%2Fhaproxy.git MINOR: ncbuf2: implement advance operation --- diff --git a/include/haproxy/ncbuf2.h b/include/haproxy/ncbuf2.h index 0170b2a94..7220b4e78 100644 --- a/include/haproxy/ncbuf2.h +++ b/include/haproxy/ncbuf2.h @@ -38,5 +38,6 @@ ncb2_sz_t ncb2_data(const struct ncbuf2 *buf, ncb2_sz_t offset); enum ncb_ret ncb2_add(struct ncbuf2 *buf, ncb2_sz_t off, const char *data, ncb2_sz_t len, enum ncb_add_mode mode); +enum ncb_ret ncb2_advance(struct ncbuf2 *buf, ncb2_sz_t adv); #endif /* _HAPROXY_NCBUF2_H */ diff --git a/src/ncbuf2.c b/src/ncbuf2.c index 9370efba2..ba1a6ab61 100644 --- a/src/ncbuf2.c +++ b/src/ncbuf2.c @@ -123,6 +123,13 @@ static struct itbmap itbmap_next(const struct ncbuf2 *buf, const struct itbmap * return next; } +/* ******** bit set/unset utilities ******** */ + +static void bit_unset(unsigned char *value, char i) +{ + *value &= ~(1 << (8 - i)); +} + /* ******** public API ******** */ struct ncbuf2 ncb2_make(char *area, ncb2_sz_t size, ncb2_sz_t head) @@ -221,6 +228,37 @@ enum ncb_ret ncb2_add(struct ncbuf2 *buf, ncb2_sz_t off, enum ncb_ret ncb2_advance(struct ncbuf2 *buf, ncb2_sz_t adv) { - /* TODO */ + struct itbmap it; + + BUG_ON_HOT(adv > ncb2_size(buf)); + + while (adv) { + it = itbmap_get(buf, 0); + if (it.bitcount <= adv) { + adv -= it.bitcount; + *it.b &= ~it.mask; + buf->head += it.bitcount; + } + else { + unsigned char mask = 0xff; + int i = 1; + + while (!(it.mask & 0x80)) { + it.mask <<= 1; + ++i; + } + + while (adv && (it.mask & 0x80)) { + bit_unset(&mask, i); + --adv; + ++i; + ++buf->head; + } + + BUG_ON(adv); + *it.b &= mask; + } + } + return NCB_RET_OK; }