#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, int fd, struct buffer * in, int minimum_length, lua_KContext ctx) { const int free_space = in->allocated + in->offset - in->length - 1; while (free_space < minimum_length) { grow(L, in); } if (0 < in->offset) { memmove(in->data, in->data + in->offset, in->length - in->offset); in->offset = 0; in->length -= in->offset; } int length = read(fd, in->data + 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); } } in->length += length; return length; } int prepare_at_least(lua_State * L, int fd, struct buffer * in, int minimum_length, lua_KContext ctx) { const int remaining_bytes = in->length - in->next; if (remaining_bytes < minimum_length) { return read_more(L, fd, in, 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; }