summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAki <please@ignore.pl>2021-02-25 21:08:34 +0100
committerAki <please@ignore.pl>2021-02-25 21:08:34 +0100
commitd2d8e8733c68c75097bac120162742ba4b15736b (patch)
tree206819a9fbf24bd2909a418d7a98075b36abf918
parent27375d684bd5cdfa7f082855b79ab69175e3499f (diff)
downloadplop-d2d8e8733c68c75097bac120162742ba4b15736b.zip
plop-d2d8e8733c68c75097bac120162742ba4b15736b.tar.gz
plop-d2d8e8733c68c75097bac120162742ba4b15736b.tar.bz2
Implemented basic until reading
-rw-r--r--stream.c83
-rw-r--r--stream.h1
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 <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)
{
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