summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEmil Renner Berthing <esmil@mailme.dk>2013-08-17 02:15:22 +0200
committerEmil Renner Berthing <esmil@mailme.dk>2013-08-27 22:03:04 +0200
commitdeb634636068fc191d807606437cd63f5dc0d150 (patch)
treef44afda7f560cf924500fd53a48b208f8ee26a10
parent6634321cb9c490b05ce807fce5027e60b374e069 (diff)
downloadlem-deb634636068fc191d807606437cd63f5dc0d150.tar.gz
lem-deb634636068fc191d807606437cd63f5dc0d150.tar.xz
lem-deb634636068fc191d807606437cd63f5dc0d150.zip
parsers: give parsers a set amount of space for state
..and don't try to cram all parser states into the same struct.
-rw-r--r--include/lem-parsers.h11
-rw-r--r--lem/http/core.c30
-rw-r--r--lem/parsers/core.c97
3 files changed, 82 insertions, 56 deletions
diff --git a/include/lem-parsers.h b/include/lem-parsers.h
index b65becd..52ab696 100644
--- a/include/lem-parsers.h
+++ b/include/lem-parsers.h
@@ -21,23 +21,16 @@
#include <lem.h>
+#define LEM_INPUTBUF_PSIZE (4*sizeof(size_t))
#define LEM_INPUTBUF_SIZE 4096
struct lem_inputbuf {
unsigned int start;
unsigned int end;
- union {
- void *p;
- unsigned long u;
- };
- int parts;
+ char pstate[LEM_INPUTBUF_PSIZE];
char buf[LEM_INPUTBUF_SIZE];
};
-enum lem_presult {
- LEM_PMORE = 0,
-};
-
enum lem_preason {
LEM_PCLOSED,
LEM_PERROR,
diff --git a/lem/http/core.c b/lem/http/core.c
index 9fdd954..2186294 100644
--- a/lem/http/core.c
+++ b/lem/http/core.c
@@ -153,6 +153,11 @@ static const unsigned char state_table[SMAX][C_MAX] = {
/* SEND*/ { X___,XEND,X___,X___,X___,X___,X___,X___,X___,X___,X___,X___,X___ },
};
+struct parse_http_state {
+ unsigned int w;
+ unsigned char state;
+};
+
static void
parse_http_init(lua_State *T)
{
@@ -164,26 +169,32 @@ parse_http_init(lua_State *T)
static void
parse_http_req_init(lua_State *T, struct lem_inputbuf *b)
{
- b->u = S_GO;
+ struct parse_http_state *s = (struct parse_http_state *)&b->pstate;
+
+ s->w = 0;
+ s->state = S_GO;
parse_http_init(T);
}
static void
parse_http_res_init(lua_State *T, struct lem_inputbuf *b)
{
- b->u = C_GO;
+ struct parse_http_state *s = (struct parse_http_state *)&b->pstate;
+
+ s->w = 0;
+ s->state = C_GO;
parse_http_init(T);
}
static int
parse_http_process(lua_State *T, struct lem_inputbuf *b)
{
- unsigned char state = b->u & 0xFF;
- unsigned int w = b->u >> 8;
+ struct parse_http_state *s = (struct parse_http_state *)&b->pstate;
+ unsigned int w = s->w;
unsigned int r = b->start;
- unsigned int end = b->end;
+ unsigned char state = s->state;
- while (r < end) {
+ while (r < b->end) {
unsigned char ch = b->buf[r++];
state = state_table[state][ch > 127 ? C_ETC : ascii_class[ch]];
@@ -296,7 +307,7 @@ parse_http_process(lua_State *T, struct lem_inputbuf *b)
}
lua_setfield(T, -2, "headers");
- if (r == end)
+ if (r == b->end)
b->start = b->end = 0;
else
b->start = r;
@@ -313,8 +324,9 @@ parse_http_process(lua_State *T, struct lem_inputbuf *b)
}
b->start = b->end = w + 1;
- b->u = (w << 8) | state;
- return LEM_PMORE;
+ s->w = w;
+ s->state = state;
+ return 0;
}
static const struct lem_parser http_req_parser = {
diff --git a/lem/parsers/core.c b/lem/parsers/core.c
index 0b0bb10..affde27 100644
--- a/lem/parsers/core.c
+++ b/lem/parsers/core.c
@@ -24,10 +24,10 @@
static int
parse_available_process(lua_State *T, struct lem_inputbuf *b)
{
- size_t size = b->end - b->start;
+ unsigned int size = b->end - b->start;
if (size == 0)
- return LEM_PMORE;
+ return 0;
lua_pushlstring(T, b->buf + b->start, size);
b->start = b->end = 0;
@@ -41,24 +41,31 @@ static const struct lem_parser parser_available = {
/*
* read a specified number of bytes
*/
+struct parse_target_state {
+ size_t target;
+ int parts;
+};
+
static void
parse_target_init(lua_State *T, struct lem_inputbuf *b)
{
- b->u = luaL_checknumber(T, 3);
- b->parts = 0;
+ struct parse_target_state *s = (struct parse_target_state *)&b->pstate;
+
+ s->target = luaL_checknumber(T, 3);
+ s->parts = 0;
lua_settop(T, 2);
}
static int
parse_target_process(lua_State *T, struct lem_inputbuf *b)
{
- unsigned long target = b->u;
- unsigned int size = b->end - b->start;
+ struct parse_target_state *s = (struct parse_target_state *)&b->pstate;
+ size_t size = b->end - b->start;
- if ((unsigned long)size >= target) {
- lua_pushlstring(T, b->buf + b->start, target);
- lua_concat(T, b->parts + 1);
- b->start += target;
+ if (size >= s->target) {
+ lua_pushlstring(T, b->buf + b->start, s->target);
+ lua_concat(T, s->parts + 1);
+ b->start += s->target;
if (b->start == b->end)
b->start = b->end = 0;
@@ -67,16 +74,16 @@ parse_target_process(lua_State *T, struct lem_inputbuf *b)
if (b->end == LEM_INPUTBUF_SIZE) {
lua_pushlstring(T, b->buf + b->start, size);
- b->parts++;
- if (b->parts == LUA_MINSTACK-2) {
+ s->parts++;
+ if (s->parts == LUA_MINSTACK-2) {
lua_concat(T, LUA_MINSTACK-2);
- b->parts = 1;
+ s->parts = 1;
}
b->start = b->end = 0;
- b->u = target - size;
+ s->target -= size;
}
- return LEM_PMORE;
+ return 0;
}
static const struct lem_parser parser_target = {
@@ -87,46 +94,55 @@ static const struct lem_parser parser_target = {
/*
* read all data until stream closes
*/
+struct parse_all_state {
+ int parts;
+};
+
static void
parse_all_init(lua_State *T, struct lem_inputbuf *b)
{
- b->parts = 0;
+ struct parse_all_state *s = (struct parse_all_state *)&b->pstate;
+
+ s->parts = 0;
lua_settop(T, 2);
}
static int
parse_all_process(lua_State *T, struct lem_inputbuf *b)
{
+ struct parse_all_state *s = (struct parse_all_state *)&b->pstate;
+
if (b->end == LEM_INPUTBUF_SIZE) {
lua_pushlstring(T, b->buf + b->start,
LEM_INPUTBUF_SIZE - b->start);
- b->parts++;
- if (b->parts == LUA_MINSTACK-2) {
+ s->parts++;
+ if (s->parts == LUA_MINSTACK-2) {
lua_concat(T, LUA_MINSTACK-2);
- b->parts = 1;
+ s->parts = 1;
}
b->start = b->end = 0;
}
- return LEM_PMORE;
+ return 0;
}
static int
parse_all_destroy(lua_State *T, struct lem_inputbuf *b, enum lem_preason reason)
{
+ struct parse_all_state *s = (struct parse_all_state *)&b->pstate;
unsigned int size;
if (reason != LEM_PCLOSED)
- return LEM_PMORE;
+ return 0;
size = b->end - b->start;
if (size > 0) {
lua_pushlstring(T, b->buf + b->start, size);
- b->parts++;
- b->start = b->end = 0;
+ s->parts++;
}
+ b->start = b->end = 0;
- lua_concat(T, b->parts);
+ lua_concat(T, s->parts);
return 1;
}
@@ -139,26 +155,32 @@ static const struct lem_parser parser_all = {
/*
* read a line
*/
+struct parse_line_state {
+ int parts;
+ char stopbyte;
+};
+
static void
parse_line_init(lua_State *T, struct lem_inputbuf *b)
{
+ struct parse_line_state *s = (struct parse_line_state *)&b->pstate;
const char *stopbyte = luaL_optstring(T, 3, "\n");
- b->u = (b->start << 8) | stopbyte[0];
- b->parts = 0;
+ s->parts = 0;
+ s->stopbyte = stopbyte[0];
lua_settop(T, 2);
}
static int
parse_line_process(lua_State *T, struct lem_inputbuf *b)
{
+ struct parse_line_state *s = (struct parse_line_state *)&b->pstate;
unsigned int i;
- unsigned char stopbyte = b->u & 0xFF;
- for (i = b->u >> 8; i < b->end; i++) {
- if (b->buf[i] == stopbyte) {
+ for (i = b->start; i < b->end; i++) {
+ if (b->buf[i] == s->stopbyte) {
lua_pushlstring(T, b->buf + b->start, i - b->start);
- lua_concat(T, b->parts + 1);
+ lua_concat(T, s->parts + 1);
i++;
if (i == b->end)
b->start = b->end = 0;
@@ -169,18 +191,17 @@ parse_line_process(lua_State *T, struct lem_inputbuf *b)
}
if (b->end == LEM_INPUTBUF_SIZE) {
- lua_pushlstring(T, b->buf + b->start, b->end - b->start);
- b->parts++;
- if (b->parts == LUA_MINSTACK-2) {
+ lua_pushlstring(T, b->buf + b->start,
+ LEM_INPUTBUF_SIZE - b->start);
+ s->parts++;
+ if (s->parts == LUA_MINSTACK-2) {
lua_concat(T, LUA_MINSTACK-2);
- b->parts = 1;
+ s->parts = 1;
}
b->start = b->end = 0;
- b->u = stopbyte;
- } else
- b->u = (i << 8) | stopbyte;
+ }
- return LEM_PMORE;
+ return 0;
}
static const struct lem_parser parser_line = {