]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: buffers: add b_xfer() to transfer data between buffers
authorWilly Tarreau <w@1wt.eu>
Fri, 20 Jul 2018 14:24:39 +0000 (16:24 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 20 Jul 2018 17:21:43 +0000 (19:21 +0200)
Instead of open-coding buffer-to-buffer transfers using blocks, let's
have a dedicated function for this. It also adjusts the buffer counts.

doc/internals/buffer-api.txt
include/common/buf.h

index c318da4638294702b16eaf7f0cc0ec7da61f50a2..7938f4c9a3c4c199c05a38fe2690d8c4dc1a2ae8 100644 (file)
@@ -459,6 +459,13 @@ b_rep_blk()         | buffer *buf      | writes the block <blk> at position
                     |                  | done. If <len> is null, the <blk>
                     |                  | pointer is allowed to be null, in
                     |                  | order to erase a block
+--------------------+------------------+---------------------------------------
+b_xfer()            | buffer *src      | transfers at most <count> bytes from
+                    | buffer *dst      | buffer <src> to buffer <dst> and
+                    | size_t cout      | returns the number of bytes copied.
+                    | ret: size_t      | The bytes are removed from <src> and
+                    |                  | added to <dst>. The caller guarantees
+                    |                  | that <count> is <= b_room(dst)
 ====================+==================+=======================================
 
 
index b93ef9946d5b56a964b7fb79221aec1c3003dbea..e72de911aba79eca936ceac663c30dbc92acffc2 100644 (file)
@@ -514,6 +514,42 @@ static inline size_t b_putblk(struct buffer *b, const char *blk, size_t len)
        return len;
 }
 
+/* b_xfer() : transfers at most <count> bytes from buffer <src> to buffer <dst>
+ * and returns the number of bytes copied. The bytes are removed from <src> and
+ * added to <dst>. The caller is responsible for ensuring that <count> is not
+ * larger than b_room(dst).
+ */
+static inline size_t b_xfer(struct buffer *dst, struct buffer *src, size_t count)
+{
+       size_t ret, block1, block2;
+
+       ret = 0;
+       if (!count)
+               goto leave;
+
+       ret = b_data(src);
+       if (!ret)
+               goto leave;
+
+       if (ret > count)
+               ret = count;
+
+       block1 = b_contig_data(src, 0);
+       if (block1 > ret)
+               block1 = ret;
+       block2 = ret - block1;
+
+       if (block1)
+               __b_putblk(dst, b_head(src), block1);
+
+       if (block2)
+               __b_putblk(dst, b_peek(src, block1), block2);
+
+       b_del(src, ret);
+ leave:
+       return ret;
+}
+
 /* b_rep_blk() : writes the block <blk> at position <pos> which must be in
  * buffer <b>, and moves the part between <end> and the buffer's tail just
  * after the end of the copy of <blk>. This effectively replaces the part