#include "buffer.h" #include #include #include #include #include #include "stream.h" void grow(lua_State * L, struct buffer * b) { int allocated = b->allocated + 1024; if (8192 < allocated) { lua_pushliteral(L, "Too large buffer"); lua_error(L); } void * buffer = realloc(b->data, allocated); if (NULL == buffer) { lua_pushliteral(L, "Could not grow buffer"); lua_error(L); } b->data = buffer; b->allocated = allocated; } int read_more(lua_State * L, struct stream * s, int minimum_length, lua_KContext ctx) { const int free_space = s->in.allocated + s->in.offset - s->in.length - 1; while (free_space < minimum_length) { grow(L, &s->in); } if (0 < s->in.offset) { memmove(s->in.data, s->in.data + s->in.offset, s->in.length - s->in.offset); s->in.offset = 0; s->in.length -= s->in.offset; } int length = read(s->fd, s->in.data + s->in.length, free_space); if (-1 == length) { if (EWOULDBLOCK == errno || EAGAIN == errno) { return lua_yieldk(L, 0, ctx, stream_readk); } else { lua_pushstring(L, strerror(errno)); return lua_error(L); } } s->in.length += length; return length; } int prepare_at_least(lua_State * L, struct stream * s, int minimum_length, lua_KContext ctx) { const int remaining_bytes = s->in.length - s->in.next; if (remaining_bytes < minimum_length) { return read_more(L, s, minimum_length, ctx); } return remaining_bytes; } int until(struct buffer * b, const char * pattern, int pattern_length) { while (b->next + pattern_length <= b->length) { if (0 == strncmp(&b->data[b->next], pattern, pattern_length)) { return b->next; } else { b->next++; } } return -1; }