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 | ||