MINOR: buffer: add a function to match against string patterns

In order to match known patterns in wrapping buffer, we'll introduce new
string manipulation functions for buffers. The new function b_isteq()
relies on an ist string for the pattern and compares it against any
location in the buffer relative to <p>. The second function bi_eat()
is specially designed to match input contents.
This commit is contained in:
Willy Tarreau 2017-09-22 15:02:54 +02:00
parent 7f564d2b60
commit 6634b63c78
1 changed files with 51 additions and 0 deletions

View File

@ -28,6 +28,7 @@
#include <common/chunk.h>
#include <common/config.h>
#include <common/ist.h>
#include <common/memory.h>
@ -567,6 +568,56 @@ static inline void offer_buffers(void *from, unsigned int threshold)
__offer_buffer(from, threshold);
}
/*************************************************************************/
/* functions used to manipulate strings and blocks with wrapping buffers */
/*************************************************************************/
/* returns > 0 if the first <n> characters of buffer <b> starting at
* offset <o> relative to b->p match <ist>. (empty strings do match). It is
* designed to be use with reasonably small strings (ie matches a single byte
* per iteration). This function is usable both with input and output data. To
* be used like this depending on what to match :
* - input contents : b_isteq(b, 0, b->i, ist);
* - output contents : b_isteq(b, -b->o, b->o, ist);
* Return value :
* >0 : the number of matching bytes
* =0 : not enough bytes (or matching of empty string)
* <0 : non-matching byte found
*/
static inline int b_isteq(const struct buffer *b, unsigned int o, size_t n, const struct ist ist)
{
struct ist r = ist;
const char *p;
const char *end = b->data + b->size;
if (n < r.len)
return 0;
p = b_ptr(b, o);
while (r.len--) {
if (*p++ != *r.ptr++)
return -1;
if (unlikely(p == end))
p = b->data;
}
return ist.len;
}
/* "eats" string <ist> from the input region of buffer <b>. Wrapping data is
* explicitly supported. It matches a single byte per iteration so strings
* should remain reasonably small. Returns :
* > 0 : number of bytes matched and eaten
* = 0 : not enough bytes (or matching an empty string)
* < 0 : non-matching byte found
*/
static inline int bi_eat(struct buffer *b, const struct ist ist)
{
int ret = b_isteq(b, 0, b->i, ist);
if (ret > 0)
bi_del(b, ret);
return ret;
}
#endif /* _COMMON_BUFFER_H */
/*