mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-02-16 10:36:55 +00:00
BUILD: buffers: keep b_getblk_nc() and b_peek_varint() in buf.h
Some large functions were moved to buf.c by commit ac66df4e2
("REORG:
buffers: move some of the heavy functions from buf.h to buf.c"). However,
as found by Amaury, haring doesn't build anymore. Upon close inspection,
b_getblk_nc() isn't that big since it's very much inlinable, and a part
of its apparently large size comes from the BUG_ON_HOT() that were
implemented. Regarding b_peek_varint(), it doesn't have any dependency
and is used only at 4 places in the DNS code, so its loop will not have
big impacts, and the rest around can be optimised away by the compiler
so it remains relevant to keep it inlined. Also it can serve as a base
to deduplicate the code in b_get_varint().
No backport needed.
This commit is contained in:
parent
f33e9079a9
commit
8b5a1fd1fc
@ -35,8 +35,6 @@
|
||||
|
||||
size_t b_getblk_ofs(const struct buffer *buf, char *blk, size_t len, size_t offset);
|
||||
size_t b_getblk(const struct buffer *buf, char *blk, size_t len, size_t offset);
|
||||
size_t b_getblk_nc(const struct buffer *buf, const char **blk1, size_t *len1,
|
||||
const char **blk2, size_t *len2, size_t ofs, size_t max);
|
||||
size_t b_getdelim(const struct buffer *buf, size_t offset, size_t count,
|
||||
char *str, size_t len, const char *delim, char escape);
|
||||
size_t b_getline(const struct buffer *buf, size_t offset, size_t count,
|
||||
@ -53,7 +51,6 @@ int b_insert_blk(struct buffer *b, size_t off, const char *blk, size_t len);
|
||||
void __b_put_varint(struct buffer *b, uint64_t v);
|
||||
int b_put_varint(struct buffer *b, uint64_t v);
|
||||
int b_get_varint(struct buffer *b, uint64_t *vptr);
|
||||
int b_peek_varint(struct buffer *b, size_t ofs, uint64_t *vptr);
|
||||
|
||||
void bl_deinit(struct bl_elem *head);
|
||||
uint32_t bl_get(struct bl_elem *head, uint32_t idx);
|
||||
@ -463,6 +460,80 @@ static inline size_t b_force_xfer(struct buffer *dst, struct buffer *src, size_t
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* b_getblk_nc() : gets one or two blocks of data at once from a buffer,
|
||||
* starting from offset <ofs> after the beginning of its output, and limited to
|
||||
* no more than <max> bytes. The caller is responsible for ensuring that
|
||||
* neither <ofs> nor <ofs>+<max> exceed the total number of bytes available in
|
||||
* the buffer. Return values :
|
||||
* >0 : number of blocks filled (1 or 2). blk1 is always filled before blk2.
|
||||
* =0 : not enough data available. <blk*> are left undefined.
|
||||
* The buffer is left unaffected. Unused buffers are left in an undefined state.
|
||||
*/
|
||||
static inline size_t b_getblk_nc(const struct buffer *buf, const char **blk1, size_t *len1, const char **blk2, size_t *len2, size_t ofs, size_t max)
|
||||
{
|
||||
size_t l1;
|
||||
|
||||
BUG_ON_HOT(buf->data > buf->size);
|
||||
BUG_ON_HOT(ofs > buf->data);
|
||||
BUG_ON_HOT(ofs + max > buf->data);
|
||||
|
||||
if (!max)
|
||||
return 0;
|
||||
|
||||
*blk1 = b_peek(buf, ofs);
|
||||
l1 = b_wrap(buf) - *blk1;
|
||||
if (l1 < max) {
|
||||
*len1 = l1;
|
||||
*len2 = max - l1;
|
||||
*blk2 = b_orig(buf);
|
||||
return 2;
|
||||
}
|
||||
*len1 = max;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* b_peek_varint(): try to decode a varint from buffer <b> at offset <ofs>
|
||||
* relative to head, into value <vptr>. Returns the number of bytes parsed in
|
||||
* case of success, or 0 if there were not enough bytes, in which case the
|
||||
* contents of <vptr> are not updated. Wrapping is supported. The buffer's head
|
||||
* will NOT be updated. It is illegal to call this function with <ofs> greater
|
||||
* than b->data.
|
||||
*/
|
||||
static inline int b_peek_varint(struct buffer *b, size_t ofs, uint64_t *vptr)
|
||||
{
|
||||
const uint8_t *head = (const uint8_t *)b_peek(b, ofs);
|
||||
const uint8_t *wrap = (const uint8_t *)b_wrap(b);
|
||||
size_t data = b_data(b) - ofs;
|
||||
size_t size = b_size(b);
|
||||
uint64_t v = 0;
|
||||
int bits = 0;
|
||||
|
||||
BUG_ON_HOT(ofs > b_data(b));
|
||||
|
||||
if (data != 0 && (*head >= 0xF0)) {
|
||||
v = *head;
|
||||
bits += 4;
|
||||
while (1) {
|
||||
if (++head == wrap)
|
||||
head -= size;
|
||||
data--;
|
||||
if (!data || !(*head & 0x80))
|
||||
break;
|
||||
v += (uint64_t)*head << bits;
|
||||
bits += 7;
|
||||
}
|
||||
}
|
||||
|
||||
/* last byte */
|
||||
if (!data)
|
||||
return 0;
|
||||
|
||||
v += (uint64_t)*head << bits;
|
||||
*vptr = v;
|
||||
data--;
|
||||
size = b->data - ofs - data;
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
74
src/buf.c
74
src/buf.c
@ -81,38 +81,6 @@ size_t b_getblk(const struct buffer *buf, char *blk, size_t len, size_t offset)
|
||||
return len;
|
||||
}
|
||||
|
||||
/* b_getblk_nc() : gets one or two blocks of data at once from a buffer,
|
||||
* starting from offset <ofs> after the beginning of its output, and limited to
|
||||
* no more than <max> bytes. The caller is responsible for ensuring that
|
||||
* neither <ofs> nor <ofs>+<max> exceed the total number of bytes available in
|
||||
* the buffer. Return values :
|
||||
* >0 : number of blocks filled (1 or 2). blk1 is always filled before blk2.
|
||||
* =0 : not enough data available. <blk*> are left undefined.
|
||||
* The buffer is left unaffected. Unused buffers are left in an undefined state.
|
||||
*/
|
||||
size_t b_getblk_nc(const struct buffer *buf, const char **blk1, size_t *len1, const char **blk2, size_t *len2, size_t ofs, size_t max)
|
||||
{
|
||||
size_t l1;
|
||||
|
||||
BUG_ON_HOT(buf->data > buf->size);
|
||||
BUG_ON_HOT(ofs > buf->data);
|
||||
BUG_ON_HOT(ofs + max > buf->data);
|
||||
|
||||
if (!max)
|
||||
return 0;
|
||||
|
||||
*blk1 = b_peek(buf, ofs);
|
||||
l1 = b_wrap(buf) - *blk1;
|
||||
if (l1 < max) {
|
||||
*len1 = l1;
|
||||
*len2 = max - l1;
|
||||
*blk2 = b_orig(buf);
|
||||
return 2;
|
||||
}
|
||||
*len1 = max;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Locates the longest part of the buffer that is composed exclusively of
|
||||
* characters not in the <delim> set, and delimited by one of these characters,
|
||||
* and returns the initial part and the first of such delimiters. A single
|
||||
@ -688,48 +656,6 @@ int b_get_varint(struct buffer *b, uint64_t *vptr)
|
||||
return size;
|
||||
}
|
||||
|
||||
/* b_peek_varint(): try to decode a varint from buffer <b> at offset <ofs>
|
||||
* relative to head, into value <vptr>. Returns the number of bytes parsed in
|
||||
* case of success, or 0 if there were not enough bytes, in which case the
|
||||
* contents of <vptr> are not updated. Wrapping is supported. The buffer's head
|
||||
* will NOT be updated. It is illegal to call this function with <ofs> greater
|
||||
* than b->data.
|
||||
*/
|
||||
int b_peek_varint(struct buffer *b, size_t ofs, uint64_t *vptr)
|
||||
{
|
||||
const uint8_t *head = (const uint8_t *)b_peek(b, ofs);
|
||||
const uint8_t *wrap = (const uint8_t *)b_wrap(b);
|
||||
size_t data = b_data(b) - ofs;
|
||||
size_t size = b_size(b);
|
||||
uint64_t v = 0;
|
||||
int bits = 0;
|
||||
|
||||
BUG_ON_HOT(ofs > b_data(b));
|
||||
|
||||
if (data != 0 && (*head >= 0xF0)) {
|
||||
v = *head;
|
||||
bits += 4;
|
||||
while (1) {
|
||||
if (++head == wrap)
|
||||
head -= size;
|
||||
data--;
|
||||
if (!data || !(*head & 0x80))
|
||||
break;
|
||||
v += (uint64_t)*head << bits;
|
||||
bits += 7;
|
||||
}
|
||||
}
|
||||
|
||||
/* last byte */
|
||||
if (!data)
|
||||
return 0;
|
||||
|
||||
v += (uint64_t)*head << bits;
|
||||
*vptr = v;
|
||||
data--;
|
||||
size = b->data - ofs - data;
|
||||
return size;
|
||||
}
|
||||
|
||||
/*
|
||||
* Buffer List management.
|
||||
|
Loading…
Reference in New Issue
Block a user