From: Amaury Denoyelle Date: Thu, 16 Oct 2025 15:34:10 +0000 (+0200) Subject: MINOR: ncbuf2: implement iterator bitmap utilities functions X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=99e54fa962647154357dd287a368401dac7cbfeb;p=thirdparty%2Fhaproxy.git MINOR: ncbuf2: implement iterator bitmap utilities functions --- diff --git a/src/ncbuf2.c b/src/ncbuf2.c index ba83ce8b2..0cea43d01 100644 --- a/src/ncbuf2.c +++ b/src/ncbuf2.c @@ -2,6 +2,87 @@ #include +/* ******** internal API ******** */ + +struct itbmap { + char *b; + ncb2_sz_t off; + unsigned char mask; + unsigned char bitcount; +}; + +static int itbmap_is_full(const struct itbmap *it) +{ + if (!it->b) + return 0; + + return (*it->b & it->mask) == it->mask; +} + +static void itbmap_load(struct itbmap *it, ncb2_sz_t off, + const struct ncbuf2 *buf) +{ + const ncb2_sz_t sz = ncb2_size(buf); + ncb2_sz_t off_abs; + ncb2_sz_t off_bmap; + + off_abs = buf->head + off; + if (off_abs >= sz) + off_abs -= sz; + off_bmap = off_abs / 8; + BUG_ON_HOT(off_bmap >= buf->bitmap_sz); + + it->b = buf->bitmap + off_bmap; + it->off = off; + it->mask = 0xff; + it->bitcount = 8; + + if (off_bmap == buf->bitmap_sz - 1 && (sz % 8)) { + it->mask <<= 8 - (sz % 8); + it->bitcount -= 8 - (sz % 8); + } + + if (off_abs % 8) { + it->mask &= (0xff >> (off_abs % 8)); + it->bitcount -= off_abs % 8; + } + + if (it->off + it->bitcount > sz) { + it->mask &= (0xff << (it->off + it->bitcount - sz)); + it->bitcount -= it->off + it->bitcount - sz; + } +} + +static struct itbmap itbmap_get(const struct ncbuf2 *buf, ncb2_sz_t off) +{ + struct itbmap it; + + BUG_ON(off >= ncb2_size(buf)); + + itbmap_load(&it, off, buf); + return it; +} + +static struct itbmap itbmap_next(const struct ncbuf2 *buf, const struct itbmap *prev) +{ + const ncb2_sz_t off_next = prev->off + prev->bitcount; + struct itbmap next; + + BUG_ON_HOT(off_next > ncb2_size(buf)); + + if (off_next == ncb2_size(buf)) { + next.b = NULL; + next.off = off_next; + } + else { + itbmap_load(&next, prev->off + prev->bitcount, buf); + } + + return next; +} + +/* ******** public API ******** */ + struct ncbuf2 ncb2_make(char *area, ncb2_sz_t size, ncb2_sz_t head) { struct ncbuf2 buf;