From d2d8e8733c68c75097bac120162742ba4b15736b Mon Sep 17 00:00:00 2001 From: Aki Date: Thu, 25 Feb 2021 21:08:34 +0100 Subject: Implemented basic until reading --- stream.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---------- stream.h | 1 + 2 files changed, 71 insertions(+), 13 deletions(-) diff --git a/stream.c b/stream.c index 781c821..cf92ad3 100644 --- a/stream.c +++ b/stream.c @@ -1,6 +1,7 @@ #include "stream.h" #include +#include #include #include #include @@ -101,9 +102,31 @@ int stream_read(lua_State * L) } s->in.data = buffer; + s->in.allocated = 1024; + s->in.length = 0; + s->in.offset = 0; } - return stream_readk(L, LUA_OK, (lua_KContext) s); // Intentionally do not pop Stream that's on top of the stack. + return stream_readk(L, LUA_OK, (lua_KContext) s); // Intentionally do not remove arguments from the stack. +} + +static int until(struct buffer * b, const char * pattern, const int pattern_length) +{ + int offset = b->offset; + + while (offset + pattern_length < b->length) + { + if (0 == strncmp(&b->data[offset], pattern, pattern_length)) + { + return offset; + } + else + { + offset++; + } + } + + return -1; } /// Continuation function and core implementation of the reading operation from a stream. @@ -115,27 +138,61 @@ int stream_readk(lua_State * L, int status, lua_KContext ctx) { struct stream * s = (struct stream *) ctx; - int length = read(s->fd, s->in.data, 1023); // TODO: Allow user to control amount of bytes being read. + int remaining_bytes = s->in.length - s->in.offset; + int offset = -1; + + size_t len; + const char * pattern = lua_tolstring(L, 2, &len); + const int pattern_length = (int) len; + + // TODO: NULL check - if (-1 == length) + if (pattern_length <= remaining_bytes) { - if (EWOULDBLOCK == errno || EAGAIN == errno) + offset = until(&s->in, pattern, pattern_length); + } + + if (-1 == offset || 0 == remaining_bytes) + { + if (0 < s->in.length && 0 <= s->in.allocated - s->in.offset - 1) { - lua_yieldk(L, 0, ctx, stream_readk); + // TODO: Allow buffer to grow some before raising an error. + lua_pushliteral(L, "Read buffer growing not implemented"); + return lua_error(L); } - else + + // TODO: Allow user to control amount of bytes being read. + int length = read(s->fd, s->in.data + s->in.offset, s->in.allocated - s->in.offset - 1); + + if (-1 == length) { - lua_pop(L, 1); - lua_pushstring(L, strerror(errno)); + if (EWOULDBLOCK == errno || EAGAIN == errno) + { + return lua_yieldk(L, 0, ctx, stream_readk); + } + else + { + lua_pop(L, 1); + lua_pushstring(L, strerror(errno)); + return lua_error(L); + } + } + + s->in.data[length] = 0; + s->in.length = s->in.offset + length; + + offset = until(&s->in, pattern, pattern_length); + + if (-1 == offset) + { + // TODO: Reiterate at this point, grow buffer until some error is reached or pattern is found. + lua_pushliteral(L, "Could not find pattern"); return lua_error(L); } } - s->in.data[length] = 0; - s->in.length = length; - s->in.offset = 0; - - lua_pushstring(L, s->in.data); + lua_pushlstring(L, &s->in.data[s->in.offset], offset - s->in.offset); + s->in.offset = offset + 1; for (int n = -lua_gettop(L); n < -1; ++n) { diff --git a/stream.h b/stream.h index c4bb3ef..a164981 100644 --- a/stream.h +++ b/stream.h @@ -7,6 +7,7 @@ struct buffer char * data; int length; int offset; + int allocated; }; struct stream -- cgit v1.1