]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: ncbmbuf: implement advance operation
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Thu, 16 Oct 2025 13:05:50 +0000 (15:05 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Mon, 20 Oct 2025 12:30:37 +0000 (14:30 +0200)
include/haproxy/ncbmbuf.h
src/ncbmbuf.c

index f06807264f28e1c57f7a6b9c966b698199c0422d..4ca5ea728b1a8f3a142fc40077eb806c7abea7df 100644 (file)
@@ -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 */
index cc586b5827e09231c97e36d44951796685f21b53..9ca28b84beb749b5c6a68121d03de0119cf4439a 100644 (file)
@@ -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 <buf> to the offset <adv>. 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;
 }