From f0e1c1b1bc9709be729f911f9f650b82b5e2e30b Mon Sep 17 00:00:00 2001 From: Amaury Denoyelle Date: Thu, 16 Oct 2025 15:05:50 +0200 Subject: [PATCH] MINOR: ncbmbuf: implement advance operation --- include/haproxy/ncbmbuf.h | 3 ++- src/ncbmbuf.c | 46 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/include/haproxy/ncbmbuf.h b/include/haproxy/ncbmbuf.h index f06807264..4ca5ea728 100644 --- a/include/haproxy/ncbmbuf.h +++ b/include/haproxy/ncbmbuf.h @@ -42,6 +42,7 @@ static inline ncb_sz_t ncbmb_size(const struct ncbmbuf *buf) ncb_sz_t ncbmb_data(const struct ncbmbuf *buf, ncb_sz_t offset); enum ncb_ret ncbmb_add(struct ncbmbuf *buf, ncb_sz_t off, - const char *data, ncb_sz_t len, enum ncb_add_mode mode); + const char *data, ncb_sz_t len, enum ncb_add_mode mode); +enum ncb_ret ncbmb_advance(struct ncbmbuf *buf, ncb_sz_t adv); #endif /* _HAPROXY_NCBMBUF_H */ diff --git a/src/ncbmbuf.c b/src/ncbmbuf.c index cc586b582..9ca28b84b 100644 --- a/src/ncbmbuf.c +++ b/src/ncbmbuf.c @@ -142,6 +142,13 @@ static struct itbmap itbmap_next(const struct ncbmbuf *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 ******** */ /* Construct a ncbmbuf with all its parameters. */ @@ -250,8 +257,45 @@ enum ncb_ret ncbmb_add(struct ncbmbuf *buf, ncb_sz_t off, return NCB_RET_OK; } +/* Advance the head of to the offset . Data at the start of buffer + * will be lost while some space will be formed at the end to be able to insert + * new data. + * + * Always returns NCB_RET_OK as this operation cannot fail. + */ enum ncb_ret ncbmb_advance(struct ncbmbuf *buf, ncb_sz_t adv) { - /* TODO */ + struct itbmap it; + + BUG_ON_HOT(adv > ncbmb_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; } -- 2.47.3