diff --git a/include/common/buf.h b/include/common/buf.h index fccad45b2..0ee9c5474 100644 --- a/include/common/buf.h +++ b/include/common/buf.h @@ -278,6 +278,21 @@ static inline int b_space_wraps(const struct buffer *b) return 1; } +/* b_contig_data() : returns the amount of data that can contiguously be read + * at once starting from a relative offset (which allows to easily + * pre-compute blocks for memcpy). The start point will typically contain the + * amount of past data already returned by a previous call to this function. + */ +static inline size_t b_contig_data(const struct buffer *b, size_t start) +{ + size_t data = b_wrap(b) - b_peek(b, start); + size_t limit = b_data(b) - start; + + if (data > limit) + data = limit; + return data; +} + /*********************************************/ /* Functions used to modify the buffer state */ diff --git a/include/common/buffer.h b/include/common/buffer.h index b34c38922..da65e89c5 100644 --- a/include/common/buffer.h +++ b/include/common/buffer.h @@ -123,16 +123,6 @@ static inline char *bi_end(const struct buffer *b) return ret; } -/* Returns the amount of input data that can contiguously be read at once */ -static inline int bi_contig_data(const struct buffer *b) -{ - int data = b->data + b->size - b->p; - - if (data > b->i) - data = b->i; - return data; -} - /* Returns the start of the output data in a buffer */ static inline char *bo_ptr(const struct buffer *b) { diff --git a/include/proto/channel.h b/include/proto/channel.h index 9429689ab..956805057 100644 --- a/include/proto/channel.h +++ b/include/proto/channel.h @@ -309,6 +309,12 @@ static inline const char *ci_stop(const struct channel *c) } +/* Returns the amount of input data that can contiguously be read at once */ +static inline size_t ci_contig_data(const struct channel *c) +{ + return b_contig_data(c->buf, co_data(c)); +} + /* Initialize all fields in the channel. */ static inline void channel_init(struct channel *chn) { diff --git a/src/cache.c b/src/cache.c index aec9ba670..c1e6bcc85 100644 --- a/src/cache.c +++ b/src/cache.c @@ -225,7 +225,7 @@ cache_store_http_forward_data(struct stream *s, struct filter *filter, ret = shctx_row_data_append(shctx, st->first_block, (unsigned char *)bi_ptr(msg->chn->buf), - MIN(bi_contig_data(msg->chn->buf), len - st->hdrs_len)); + MIN(ci_contig_data(msg->chn), len - st->hdrs_len)); /* Rewind the buffer to forward all data */ c_rew(msg->chn, st->hdrs_len); st->hdrs_len = 0; diff --git a/src/flt_http_comp.c b/src/flt_http_comp.c index df59d7d55..f26b28b67 100644 --- a/src/flt_http_comp.c +++ b/src/flt_http_comp.c @@ -206,7 +206,7 @@ comp_http_data(struct stream *s, struct filter *filter, struct http_msg *msg) len = MIN(tmpbuf->size - buffer_len(tmpbuf), len); c_adv(chn, *nxt); - block = bi_contig_data(buf); + block = ci_contig_data(chn); memcpy(bi_end(tmpbuf), bi_ptr(buf), block); if (len > block) memcpy(bi_end(tmpbuf)+block, buf->data, len-block); @@ -644,8 +644,8 @@ http_compression_buffer_add_data(struct comp_state *st, struct buffer *in, data_process_len = MIN(out->size - buffer_len(out), sz); block1 = data_process_len; - if (block1 > bi_contig_data(in)) - block1 = bi_contig_data(in); + if (block1 > b_contig_data(in, in->o)) + block1 = b_contig_data(in, in->o); block2 = data_process_len - block1; /* compressors return < 0 upon error or the amount of bytes read */ @@ -765,7 +765,7 @@ http_compression_buffer_end(struct comp_state *st, struct stream *s, /* copy the remaining data in the tmp buffer. */ c_adv(chn, st->consumed); if (ib->i > 0) { - left = bi_contig_data(ib); + left = ci_contig_data(chn); memcpy(ob->p + ob->i, bi_ptr(ib), left); ob->i += left; if (ib->i - left) { diff --git a/src/flt_trace.c b/src/flt_trace.c index f088340b7..b1d208fdb 100644 --- a/src/flt_trace.c +++ b/src/flt_trace.c @@ -84,9 +84,9 @@ trace_hexdump(struct buffer *buf, int len) int block1, block2, i, j, padding; block1 = len; - if (block1 > bi_contig_data(buf)) - block1 = bi_contig_data(buf); - block2 = len - block1; + if (block1 > b_contig_data(buf, buf->o)) + block1 = b_contig_data(buf, buf->o); + block2 = len - block1; memcpy(p, buf->p, block1); memcpy(p+block1, buf->data, block2); diff --git a/src/mux_h2.c b/src/mux_h2.c index 8aab234e5..2f41c6fe8 100644 --- a/src/mux_h2.c +++ b/src/mux_h2.c @@ -2838,7 +2838,7 @@ static int h2_frt_transfer_data(struct h2s *h2s, struct buffer *buf, int count) /* Block1 is the length of the first block before the buffer wraps, * block2 is the optional second block to reach the end of the frame. */ - block1 = bi_contig_data(h2c->dbuf); + block1 = b_contig_data(h2c->dbuf, 0); if (block1 > flen) block1 = flen; block2 = flen - block1;