From: Amaury Denoyelle Date: Wed, 15 Oct 2025 09:56:16 +0000 (+0200) Subject: MINOR: ncbmbuf: implement ncbmb_data() X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b2b735c855058d6f2c9f79ba6600620e160c2d88;p=thirdparty%2Fhaproxy.git MINOR: ncbmbuf: implement ncbmb_data() --- diff --git a/include/haproxy/ncbmbuf.h b/include/haproxy/ncbmbuf.h index fd228128c..f06807264 100644 --- a/include/haproxy/ncbmbuf.h +++ b/include/haproxy/ncbmbuf.h @@ -39,6 +39,8 @@ static inline ncb_sz_t ncbmb_size(const struct ncbmbuf *buf) return buf->size; } +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); diff --git a/src/ncbmbuf.c b/src/ncbmbuf.c index f713d4c54..cc586b582 100644 --- a/src/ncbmbuf.c +++ b/src/ncbmbuf.c @@ -68,7 +68,7 @@ struct itbmap { unsigned char bitcount; }; -static __attribute__((unused)) int itbmap_is_full(const struct itbmap *it) +static int itbmap_is_full(const struct itbmap *it) { if (!it->b) return 0; @@ -76,8 +76,8 @@ static __attribute__((unused)) int itbmap_is_full(const struct itbmap *it) return (*it->b & it->mask) == it->mask; } -static __attribute__((unused)) void itbmap_load(struct itbmap *it, ncb_sz_t off, - const struct ncbmbuf *buf) +static void itbmap_load(struct itbmap *it, ncb_sz_t off, + const struct ncbmbuf *buf) { const ncb_sz_t sz = ncbmb_size(buf); ncb_sz_t off_abs; @@ -113,7 +113,7 @@ static __attribute__((unused)) void itbmap_load(struct itbmap *it, ncb_sz_t off, /* Returns an iterator on the bitmap byte corresponding to offset * relative to head. */ -static __attribute__((unused)) struct itbmap itbmap_get(const struct ncbmbuf *buf, ncb_sz_t off) +static struct itbmap itbmap_get(const struct ncbmbuf *buf, ncb_sz_t off) { struct itbmap it; @@ -124,7 +124,7 @@ static __attribute__((unused)) struct itbmap itbmap_get(const struct ncbmbuf *bu } /* Returns the next bitmap byte relative to iterator. */ -static __attribute__((unused)) struct itbmap itbmap_next(const struct ncbmbuf *buf, const struct itbmap *prev) +static struct itbmap itbmap_next(const struct ncbmbuf *buf, const struct itbmap *prev) { const ncb_sz_t off_next = prev->off + prev->bitcount; struct itbmap next; @@ -187,10 +187,36 @@ int ncbmb_is_fragmented(const struct ncbmbuf *buf) return 0; } +/* Returns the number of bytes of data available in starting at offset + * until the next gap or the buffer end. The counted data may wrapped if + * the buffer storage is not aligned. + */ ncb_sz_t ncbmb_data(const struct ncbmbuf *buf, ncb_sz_t off) { - /* TODO */ - return 0; + struct itbmap it = itbmap_get(buf, off); + unsigned char value; + ncb_sz_t count = 0; + + while (itbmap_is_full(&it)) { + count += it.bitcount; + it = itbmap_next(buf, &it); + } + + if (it.b) { + value = *it.b & it.mask; + while (it.mask && !(it.mask & 0x80)) { + it.mask <<= 1; + value <<= 1; + } + + while (it.mask && (it.mask & 0x80) && (value & 0x80)) { + it.mask <<= 1; + value <<= 1; + ++count; + } + } + + return count; } /* Add a new block at of size in at offset . Note that