diff options
author | Aki <please@ignore.pl> | 2021-02-25 21:08:34 +0100 |
---|---|---|
committer | Aki <please@ignore.pl> | 2021-02-25 21:08:34 +0100 |
commit | d2d8e8733c68c75097bac120162742ba4b15736b (patch) | |
tree | 206819a9fbf24bd2909a418d7a98075b36abf918 | |
parent | 27375d684bd5cdfa7f082855b79ab69175e3499f (diff) | |
download | plop-d2d8e8733c68c75097bac120162742ba4b15736b.zip plop-d2d8e8733c68c75097bac120162742ba4b15736b.tar.gz plop-d2d8e8733c68c75097bac120162742ba4b15736b.tar.bz2 |
Implemented basic until reading
-rw-r--r-- | stream.c | 83 | ||||
-rw-r--r-- | stream.h | 1 |
2 files changed, 71 insertions, 13 deletions
@@ -1,6 +1,7 @@ #include "stream.h" #include <errno.h> +#include <stdint.h> #include <stdlib.h> #include <string.h> #include <unistd.h> @@ -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) { @@ -7,6 +7,7 @@ struct buffer char * data; int length; int offset; + int allocated; }; struct stream |