diff options
Diffstat (limited to 'src/buffer.c')
| -rw-r--r-- | src/buffer.c | 84 |
1 files changed, 34 insertions, 50 deletions
diff --git a/src/buffer.c b/src/buffer.c index d9ba779..4bcfa1a 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
| @@ -13,9 +13,9 @@ | |||
| 13 | /*=========================================================================*\ | 13 | /*=========================================================================*\ |
| 14 | * Internal function prototypes | 14 | * Internal function prototypes |
| 15 | \*=========================================================================*/ | 15 | \*=========================================================================*/ |
| 16 | static int recvraw(lua_State *L, p_buf buf, size_t wanted); | 16 | static int recvraw(p_buf buf, size_t wanted, luaL_Buffer *b); |
| 17 | static int recvline(lua_State *L, p_buf buf); | 17 | static int recvline(p_buf buf, luaL_Buffer *b); |
| 18 | static int recvall(lua_State *L, p_buf buf); | 18 | static int recvall(p_buf buf, luaL_Buffer *b); |
| 19 | static int buf_get(p_buf buf, const char **data, size_t *count); | 19 | static int buf_get(p_buf buf, const char **data, size_t *count); |
| 20 | static void buf_skip(p_buf buf, size_t count); | 20 | static void buf_skip(p_buf buf, size_t count); |
| 21 | static int sendraw(p_buf buf, const char *data, size_t count, size_t *sent); | 21 | static int sendraw(p_buf buf, const char *data, size_t count, size_t *sent); |
| @@ -73,42 +73,34 @@ int buf_meth_send(lua_State *L, p_buf buf) | |||
| 73 | \*-------------------------------------------------------------------------*/ | 73 | \*-------------------------------------------------------------------------*/ |
| 74 | int buf_meth_receive(lua_State *L, p_buf buf) | 74 | int buf_meth_receive(lua_State *L, p_buf buf) |
| 75 | { | 75 | { |
| 76 | int top = lua_gettop(L); | 76 | int err = IO_DONE, top = lua_gettop(L); |
| 77 | int arg, err = IO_DONE; | ||
| 78 | p_tm tm = buf->tm; | 77 | p_tm tm = buf->tm; |
| 78 | luaL_Buffer b; | ||
| 79 | luaL_buffinit(L, &b); | ||
| 79 | tm_markstart(tm); | 80 | tm_markstart(tm); |
| 80 | /* push default pattern if need be */ | ||
| 81 | if (top < 2) { | ||
| 82 | lua_pushstring(L, "*l"); | ||
| 83 | top++; | ||
| 84 | } | ||
| 85 | /* make sure we have enough stack space for all returns */ | ||
| 86 | luaL_checkstack(L, top+LUA_MINSTACK, "too many arguments"); | ||
| 87 | /* receive all patterns */ | 81 | /* receive all patterns */ |
| 88 | for (arg = 2; arg <= top && err == IO_DONE; arg++) { | 82 | if (!lua_isnumber(L, 2)) { |
| 89 | if (!lua_isnumber(L, arg)) { | 83 | static const char *patternnames[] = {"*l", "*a", NULL}; |
| 90 | static const char *patternnames[] = {"*l", "*a", NULL}; | 84 | const char *pattern = luaL_optstring(L, 2, "*l"); |
| 91 | const char *pattern = lua_isnil(L, arg) ? | 85 | /* get next pattern */ |
| 92 | "*l" : luaL_checkstring(L, arg); | 86 | int p = luaL_findstring(pattern, patternnames); |
| 93 | /* get next pattern */ | 87 | if (p == 0) err = recvline(buf, &b); |
| 94 | switch (luaL_findstring(pattern, patternnames)) { | 88 | else if (p == 1) err = recvall(buf, &b); |
| 95 | case 0: /* line pattern */ | 89 | else luaL_argcheck(L, 0, 2, "invalid receive pattern"); |
| 96 | err = recvline(L, buf); break; | ||
| 97 | case 1: /* until closed pattern */ | ||
| 98 | err = recvall(L, buf); | ||
| 99 | if (err == IO_CLOSED) err = IO_DONE; | ||
| 100 | break; | ||
| 101 | default: /* else it is an error */ | ||
| 102 | luaL_argcheck(L, 0, arg, "invalid receive pattern"); | ||
| 103 | break; | ||
| 104 | } | ||
| 105 | /* get a fixed number of bytes */ | 90 | /* get a fixed number of bytes */ |
| 106 | } else err = recvraw(L, buf, (size_t) lua_tonumber(L, arg)); | 91 | } else err = recvraw(buf, (size_t) lua_tonumber(L, 2), &b); |
| 92 | /* check if there was an error */ | ||
| 93 | if (err != IO_DONE) { | ||
| 94 | luaL_pushresult(&b); | ||
| 95 | io_pusherror(L, err); | ||
| 96 | lua_pushvalue(L, -2); | ||
| 97 | lua_pushnil(L); | ||
| 98 | lua_replace(L, -4); | ||
| 99 | } else { | ||
| 100 | luaL_pushresult(&b); | ||
| 101 | lua_pushnil(L); | ||
| 102 | lua_pushnil(L); | ||
| 107 | } | 103 | } |
| 108 | /* push nil for each pattern after an error */ | ||
| 109 | for ( ; arg <= top; arg++) lua_pushnil(L); | ||
| 110 | /* last return is an error code */ | ||
| 111 | io_pusherror(L, err); | ||
| 112 | #ifdef LUASOCKET_DEBUG | 104 | #ifdef LUASOCKET_DEBUG |
| 113 | /* push time elapsed during operation as the last return value */ | 105 | /* push time elapsed during operation as the last return value */ |
| 114 | lua_pushnumber(L, (tm_gettime() - tm_getstart(tm))/1000.0); | 106 | lua_pushnumber(L, (tm_gettime() - tm_getstart(tm))/1000.0); |
| @@ -150,21 +142,18 @@ int sendraw(p_buf buf, const char *data, size_t count, size_t *sent) | |||
| 150 | * Reads a fixed number of bytes (buffered) | 142 | * Reads a fixed number of bytes (buffered) |
| 151 | \*-------------------------------------------------------------------------*/ | 143 | \*-------------------------------------------------------------------------*/ |
| 152 | static | 144 | static |
| 153 | int recvraw(lua_State *L, p_buf buf, size_t wanted) | 145 | int recvraw(p_buf buf, size_t wanted, luaL_Buffer *b) |
| 154 | { | 146 | { |
| 155 | int err = IO_DONE; | 147 | int err = IO_DONE; |
| 156 | size_t total = 0; | 148 | size_t total = 0; |
| 157 | luaL_Buffer b; | ||
| 158 | luaL_buffinit(L, &b); | ||
| 159 | while (total < wanted && (err == IO_DONE || err == IO_RETRY)) { | 149 | while (total < wanted && (err == IO_DONE || err == IO_RETRY)) { |
| 160 | size_t count; const char *data; | 150 | size_t count; const char *data; |
| 161 | err = buf_get(buf, &data, &count); | 151 | err = buf_get(buf, &data, &count); |
| 162 | count = MIN(count, wanted - total); | 152 | count = MIN(count, wanted - total); |
| 163 | luaL_addlstring(&b, data, count); | 153 | luaL_addlstring(b, data, count); |
| 164 | buf_skip(buf, count); | 154 | buf_skip(buf, count); |
| 165 | total += count; | 155 | total += count; |
| 166 | } | 156 | } |
| 167 | luaL_pushresult(&b); | ||
| 168 | return err; | 157 | return err; |
| 169 | } | 158 | } |
| 170 | 159 | ||
| @@ -172,19 +161,17 @@ int recvraw(lua_State *L, p_buf buf, size_t wanted) | |||
| 172 | * Reads everything until the connection is closed (buffered) | 161 | * Reads everything until the connection is closed (buffered) |
| 173 | \*-------------------------------------------------------------------------*/ | 162 | \*-------------------------------------------------------------------------*/ |
| 174 | static | 163 | static |
| 175 | int recvall(lua_State *L, p_buf buf) | 164 | int recvall(p_buf buf, luaL_Buffer *b) |
| 176 | { | 165 | { |
| 177 | int err = IO_DONE; | 166 | int err = IO_DONE; |
| 178 | luaL_Buffer b; | ||
| 179 | luaL_buffinit(L, &b); | ||
| 180 | while (err == IO_DONE || err == IO_RETRY) { | 167 | while (err == IO_DONE || err == IO_RETRY) { |
| 181 | const char *data; size_t count; | 168 | const char *data; size_t count; |
| 182 | err = buf_get(buf, &data, &count); | 169 | err = buf_get(buf, &data, &count); |
| 183 | luaL_addlstring(&b, data, count); | 170 | luaL_addlstring(b, data, count); |
| 184 | buf_skip(buf, count); | 171 | buf_skip(buf, count); |
| 185 | } | 172 | } |
| 186 | luaL_pushresult(&b); | 173 | if (err == IO_CLOSED) return IO_DONE; |
| 187 | return err; | 174 | else return err; |
| 188 | } | 175 | } |
| 189 | 176 | ||
| 190 | /*-------------------------------------------------------------------------*\ | 177 | /*-------------------------------------------------------------------------*\ |
| @@ -192,18 +179,16 @@ int recvall(lua_State *L, p_buf buf) | |||
| 192 | * are not returned by the function and are discarded from the buffer | 179 | * are not returned by the function and are discarded from the buffer |
| 193 | \*-------------------------------------------------------------------------*/ | 180 | \*-------------------------------------------------------------------------*/ |
| 194 | static | 181 | static |
| 195 | int recvline(lua_State *L, p_buf buf) | 182 | int recvline(p_buf buf, luaL_Buffer *b) |
| 196 | { | 183 | { |
| 197 | int err = IO_DONE; | 184 | int err = IO_DONE; |
| 198 | luaL_Buffer b; | ||
| 199 | luaL_buffinit(L, &b); | ||
| 200 | while (err == IO_DONE || err == IO_RETRY) { | 185 | while (err == IO_DONE || err == IO_RETRY) { |
| 201 | size_t count, pos; const char *data; | 186 | size_t count, pos; const char *data; |
| 202 | err = buf_get(buf, &data, &count); | 187 | err = buf_get(buf, &data, &count); |
| 203 | pos = 0; | 188 | pos = 0; |
| 204 | while (pos < count && data[pos] != '\n') { | 189 | while (pos < count && data[pos] != '\n') { |
| 205 | /* we ignore all \r's */ | 190 | /* we ignore all \r's */ |
| 206 | if (data[pos] != '\r') luaL_putchar(&b, data[pos]); | 191 | if (data[pos] != '\r') luaL_putchar(b, data[pos]); |
| 207 | pos++; | 192 | pos++; |
| 208 | } | 193 | } |
| 209 | if (pos < count) { /* found '\n' */ | 194 | if (pos < count) { /* found '\n' */ |
| @@ -212,7 +197,6 @@ int recvline(lua_State *L, p_buf buf) | |||
| 212 | } else /* reached the end of the buffer */ | 197 | } else /* reached the end of the buffer */ |
| 213 | buf_skip(buf, pos); | 198 | buf_skip(buf, pos); |
| 214 | } | 199 | } |
| 215 | luaL_pushresult(&b); | ||
| 216 | return err; | 200 | return err; |
| 217 | } | 201 | } |
| 218 | 202 | ||
