]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: ncbmbuf: implement ncbmb_data()
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Wed, 15 Oct 2025 09:56:16 +0000 (11:56 +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 fd228128ce744f9938287c64af3d2eab68612aad..f06807264f28e1c57f7a6b9c966b698199c0422d 100644 (file)
@@ -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);
 
index f713d4c543c37ebb77f1700503133d2c22ab5e61..cc586b5827e09231c97e36d44951796685f21b53 100644 (file)
@@ -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 <off> offset
  * relative to <buf> 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 <prev> 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 <buf> starting at offset
+ * <off> 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 <data> of size <len> in <buf> at offset <off>. Note that