]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: ncbuf2: implement advance operation
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Thu, 16 Oct 2025 13:05:50 +0000 (15:05 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Fri, 17 Oct 2025 09:06:07 +0000 (11:06 +0200)
include/haproxy/ncbuf2.h
src/ncbuf2.c

index 0170b2a946ca5a1930f8e6764a7bae0dc80d94c1..7220b4e78c17e1aa53cd53a9c2b150876aef59a7 100644 (file)
@@ -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 */
index 9370efba2f946970562d4e81f0cd57d7b83c5988..ba1a6ab6147dab3adf70072da3f4aa4c80485bdd 100644 (file)
@@ -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;
 }