From f148888d198e15f8d01ce5e2a1c811358227cdd4 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Fri, 20 Jul 2018 16:24:39 +0200 Subject: [PATCH] MINOR: buffers: add b_xfer() to transfer data between buffers 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 | 7 +++++++ include/common/buf.h | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/doc/internals/buffer-api.txt b/doc/internals/buffer-api.txt index c318da463..7938f4c9a 100644 --- a/doc/internals/buffer-api.txt +++ b/doc/internals/buffer-api.txt @@ -459,6 +459,13 @@ b_rep_blk() | buffer *buf | writes the block at position | | done. If is null, the | | pointer is allowed to be null, in | | order to erase a block +--------------------+------------------+--------------------------------------- +b_xfer() | buffer *src | transfers at most bytes from + | buffer *dst | buffer to buffer and + | size_t cout | returns the number of bytes copied. + | ret: size_t | The bytes are removed from and + | | added to . The caller guarantees + | | that is <= b_room(dst) ====================+==================+======================================= diff --git a/include/common/buf.h b/include/common/buf.h index b93ef9946..e72de911a 100644 --- a/include/common/buf.h +++ b/include/common/buf.h @@ -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 bytes from buffer to buffer + * and returns the number of bytes copied. The bytes are removed from and + * added to . The caller is responsible for ensuring that 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 at position which must be in * buffer , and moves the part between and the buffer's tail just * after the end of the copy of . This effectively replaces the part