From 145746c2d55f6524fdb47191479d84bcd6e3d5d1 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Thu, 26 Oct 2017 15:26:17 +0200 Subject: [PATCH] MINOR: buffer: add the buffer input manipulation functions We used to have bo_{get,put}_{chr,blk,str} to retrieve/send data to the output area of a buffer, but not the equivalent ones for the input area. This will be needed to copy uploaded data frames in HTTP/2. --- include/common/buffer.h | 99 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/include/common/buffer.h b/include/common/buffer.h index 9006c0095..c34e3ac8c 100644 --- a/include/common/buffer.h +++ b/include/common/buffer.h @@ -545,6 +545,105 @@ static inline int bo_getblk_nc(struct buffer *buf, char **blk1, int *len1, char return 1; } +/* Tries to write char into input data at buffer . Supports wrapping. + * Data are truncated if buffer is full. + */ +static inline void bi_putchr(struct buffer *b, char c) +{ + if (buffer_len(b) == b->size) + return; + *bi_end(b) = c; + b->i++; +} + +/* Tries to copy block into input data at buffer . Supports wrapping. + * Data are truncated if buffer is too short. It returns the number of bytes + * copied. + */ +static inline int bi_putblk(struct buffer *b, const char *blk, int len) +{ + int cur_len = buffer_len(b); + int half; + + if (len > b->size - cur_len) + len = (b->size - cur_len); + if (!len) + return 0; + + half = bi_contig_space(b); + if (half > len) + half = len; + + memcpy(bi_end(b), blk, half); + if (len > half) + memcpy(b_ptr(b, b->i + half), blk, len - half); + b->i += len; + return len; +} + +/* Tries to copy string into input data at buffer . Supports wrapping. + * Data are truncated if buffer is too short. It returns the number of bytes + * copied. + */ +static inline int bi_putstr(struct buffer *b, const char *str) +{ + return bi_putblk(b, str, strlen(str)); +} + +/* Tries to copy chunk into input data at buffer . Supports wrapping. + * Data are truncated if buffer is too short. It returns the number of bytes + * copied. + */ +static inline int bi_putchk(struct buffer *b, const struct chunk *chk) +{ + return bi_putblk(b, chk->str, chk->len); +} + +/* Gets one full block of data at once from a buffer's input. Return values : + * >0 : number of bytes read, equal to requested size. + * =0 : not enough data available. is left undefined. + * The buffer is left unaffected. + */ +static inline int bi_getblk(const struct buffer *buf, char *blk, int len) +{ + int firstblock; + + if (len > buf->i) + return 0; + + firstblock = bi_contig_data(buf); + if (firstblock > len) + firstblock = len; + + memcpy(blk, bi_ptr(buf), firstblock); + if (len > firstblock) + memcpy(blk + firstblock, buf->data, len - firstblock); + return len; +} + +/* Gets one or two blocks of data at once from a buffer's input. + * Return values : + * >0 : number of blocks filled (1 or 2). blk1 is always filled before blk2. + * =0 : not enough data available. are left undefined. + * The buffer is left unaffected. Unused buffers are left in an undefined state. + */ +static inline int bi_getblk_nc(struct buffer *buf, char **blk1, int *len1, char **blk2, int *len2) +{ + if (unlikely(buf->i == 0)) + return 0; + + if (unlikely(buf->p + buf->i > buf->data + buf->size)) { + *blk1 = buf->p; + *len1 = buf->data + buf->size - buf->p; + *blk2 = buf->data; + *len2 = buf->i - *len1; + return 2; + } + + *blk1 = buf->p; + *len1 = buf->i; + return 1; +} /* Resets a buffer. The size is not touched. */ static inline void b_reset(struct buffer *buf)