diff --git a/core/admin.c b/core/admin.c index 3e5ddfe721ea3df6c0cde37f5b931c317d3dfd74..5f4e196e0600a8920120f962c0cc7f897d9f62b7 100644 --- a/core/admin.c +++ b/core/admin.c @@ -1452,8 +1452,7 @@ case 107: #line 199 "core/admin.rl" - fiber->rbuf->len -= (void *)pe - (void *)fiber->rbuf->data; - fiber->rbuf->data = pe; + tbuf_ltrim(fiber->rbuf, (void *)pe - (void *)fiber->rbuf->data); if (p != pe) { start(out); diff --git a/core/admin.rl b/core/admin.rl index bed4f22a8df8fc99bdb130506c07c2bca68547d3..5352e2b5b26d4715405595a9631e7da413a1dcbe 100644 --- a/core/admin.rl +++ b/core/admin.rl @@ -198,8 +198,7 @@ admin_dispatch(void) write exec; }%% - fiber->rbuf->len -= (void *)pe - (void *)fiber->rbuf->data; - fiber->rbuf->data = pe; + tbuf_ltrim(fiber->rbuf, (void *)pe - (void *)fiber->rbuf->data); if (p != pe) { start(out); diff --git a/core/tbuf.c b/core/tbuf.c index 52a2dc48da1b59617995feb3e6f41ec2d16618bb..bb9fb1369641ce0a1c182e186f0cb07faf9ad600 100644 --- a/core/tbuf.c +++ b/core/tbuf.c @@ -124,6 +124,19 @@ tbuf_peek(struct tbuf *b, size_t count) return NULL; } +void * +tbuf_ltrim(struct tbuf *b, size_t count) +{ + void *p = NULL; + + tbuf_assert(b); + if (count <= b->len) { + p = memmove(b->data, b->data + count, b->len - count); + b->len -= count; + } + return p; +} + size_t tbuf_reserve(struct tbuf *b, size_t count) { diff --git a/include/tbuf.h b/include/tbuf.h index 49c72f301e46ba6eccd7e50fdd92af89efd87ccc..e45d44fc094c24c685825d5085f4015c80fdca94 100644 --- a/include/tbuf.h +++ b/include/tbuf.h @@ -63,6 +63,7 @@ struct tbuf *tbuf_split(struct tbuf *e, size_t at); size_t tbuf_reserve(struct tbuf *b, size_t count); void tbuf_reset(struct tbuf *b); void *tbuf_peek(struct tbuf *b, size_t count); +void *tbuf_ltrim(struct tbuf *b, size_t count); void tbuf_append_field(struct tbuf *b, void *f); void tbuf_vprintf(struct tbuf *b, const char *format, va_list ap)