aboutsummaryrefslogtreecommitdiff
path: root/src/buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/buffer.c')
-rw-r--r--src/buffer.c84
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\*=========================================================================*/
16static int recvraw(lua_State *L, p_buf buf, size_t wanted); 16static int recvraw(p_buf buf, size_t wanted, luaL_Buffer *b);
17static int recvline(lua_State *L, p_buf buf); 17static int recvline(p_buf buf, luaL_Buffer *b);
18static int recvall(lua_State *L, p_buf buf); 18static int recvall(p_buf buf, luaL_Buffer *b);
19static int buf_get(p_buf buf, const char **data, size_t *count); 19static int buf_get(p_buf buf, const char **data, size_t *count);
20static void buf_skip(p_buf buf, size_t count); 20static void buf_skip(p_buf buf, size_t count);
21static int sendraw(p_buf buf, const char *data, size_t count, size_t *sent); 21static 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\*-------------------------------------------------------------------------*/
74int buf_meth_receive(lua_State *L, p_buf buf) 74int 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\*-------------------------------------------------------------------------*/
152static 144static
153int recvraw(lua_State *L, p_buf buf, size_t wanted) 145int 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\*-------------------------------------------------------------------------*/
174static 163static
175int recvall(lua_State *L, p_buf buf) 164int 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\*-------------------------------------------------------------------------*/
194static 181static
195int recvline(lua_State *L, p_buf buf) 182int 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