diff options
author | Diego Nehab <diego@tecgraf.puc-rio.br> | 2003-05-25 01:54:13 +0000 |
---|---|---|
committer | Diego Nehab <diego@tecgraf.puc-rio.br> | 2003-05-25 01:54:13 +0000 |
commit | 0f6c8d50a99997ac7829864b1c93362b50f1bbf3 (patch) | |
tree | d0cefe3a05484e65b7b7e79d8cae4a1d2e6d19fb /src/buffer.c | |
parent | c1ef3e7103cc652d2004ef1ddc9409b946207f33 (diff) | |
download | luasocket-0f6c8d50a99997ac7829864b1c93362b50f1bbf3.tar.gz luasocket-0f6c8d50a99997ac7829864b1c93362b50f1bbf3.tar.bz2 luasocket-0f6c8d50a99997ac7829864b1c93362b50f1bbf3.zip |
Porting to LUA 5.0 final
Diffstat (limited to 'src/buffer.c')
-rw-r--r-- | src/buffer.c | 275 |
1 files changed, 91 insertions, 184 deletions
diff --git a/src/buffer.c b/src/buffer.c index 73df8b3..c5ef66c 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
@@ -1,28 +1,24 @@ | |||
1 | /*=========================================================================*\ | 1 | /*=========================================================================*\ |
2 | * Buffered input/output routines | 2 | * Buffered input/output routines |
3 | * Lua methods: | ||
4 | * send: unbuffered send using C base_send | ||
5 | * receive: buffered read using C base_receive | ||
6 | * | 3 | * |
7 | * RCS ID: $Id$ | 4 | * RCS ID: $Id$ |
8 | \*=========================================================================*/ | 5 | \*=========================================================================*/ |
9 | #include <lua.h> | 6 | #include <lua.h> |
10 | #include <lauxlib.h> | 7 | #include <lauxlib.h> |
11 | 8 | ||
12 | #include "lsbuf.h" | 9 | #include "error.h" |
10 | #include "aux.h" | ||
11 | #include "buf.h" | ||
13 | 12 | ||
14 | /*=========================================================================*\ | 13 | /*=========================================================================*\ |
15 | * Internal function prototypes. | 14 | * Internal function prototypes |
16 | \*=========================================================================*/ | 15 | \*=========================================================================*/ |
17 | static int sendraw(lua_State *L, p_buf buf, cchar *data, size_t len, | ||
18 | size_t *done); | ||
19 | static int recvraw(lua_State *L, p_buf buf, size_t wanted); | 16 | static int recvraw(lua_State *L, p_buf buf, size_t wanted); |
20 | static int recvdosline(lua_State *L, p_buf buf); | 17 | static int recvline(lua_State *L, p_buf buf); |
21 | static int recvunixline(lua_State *L, p_buf buf); | ||
22 | static int recvall(lua_State *L, p_buf buf); | 18 | static int recvall(lua_State *L, p_buf buf); |
23 | 19 | static int buf_get(p_buf buf, const char **data, size_t *count); | |
24 | static int buf_contents(lua_State *L, p_buf buf, cchar **data, size_t *len); | 20 | static void buf_skip(p_buf buf, size_t count); |
25 | static void buf_skip(lua_State *L, p_buf buf, size_t len); | 21 | static int sendraw(p_buf buf, const char *data, size_t count, size_t *sent); |
26 | 22 | ||
27 | /*=========================================================================*\ | 23 | /*=========================================================================*\ |
28 | * Exported functions | 24 | * Exported functions |
@@ -37,98 +33,69 @@ void buf_open(lua_State *L) | |||
37 | 33 | ||
38 | /*-------------------------------------------------------------------------*\ | 34 | /*-------------------------------------------------------------------------*\ |
39 | * Initializes C structure | 35 | * Initializes C structure |
40 | * Input | ||
41 | * buf: buffer structure to initialize | ||
42 | * base: socket object to associate with buffer structure | ||
43 | \*-------------------------------------------------------------------------*/ | 36 | \*-------------------------------------------------------------------------*/ |
44 | void buf_init(lua_State *L, p_buf buf, p_base base) | 37 | void buf_init(p_buf buf, p_io io, p_tm tm) |
45 | { | 38 | { |
46 | (void) L; | 39 | buf->first = buf->last = 0; |
47 | buf->buf_first = buf->buf_last = 0; | 40 | buf->io = io; |
48 | buf->buf_base = base; | 41 | buf->tm = tm; |
49 | } | 42 | } |
50 | 43 | ||
51 | /*-------------------------------------------------------------------------*\ | 44 | /*-------------------------------------------------------------------------*\ |
52 | * Send data through buffered object | 45 | * Send data through buffered object |
53 | * Input | ||
54 | * buf: buffer structure to be used | ||
55 | * Lua Input: self, a_1 [, a_2, a_3 ... a_n] | ||
56 | * self: socket object | ||
57 | * a_i: strings to be sent. | ||
58 | * Lua Returns | ||
59 | * On success: nil, followed by the total number of bytes sent | ||
60 | * On error: error message | ||
61 | \*-------------------------------------------------------------------------*/ | 46 | \*-------------------------------------------------------------------------*/ |
62 | int buf_send(lua_State *L, p_buf buf) | 47 | int buf_meth_send(lua_State *L, p_buf buf) |
63 | { | 48 | { |
64 | int top = lua_gettop(L); | 49 | int top = lua_gettop(L); |
65 | size_t total = 0; | 50 | size_t total = 0; |
66 | int err = PRIV_DONE; | 51 | int arg, err = IO_DONE; |
67 | int arg; | 52 | p_tm tm = buf->tm; |
68 | p_base base = buf->buf_base; | 53 | tm_markstart(tm); |
69 | tm_markstart(&base->base_tm); | ||
70 | for (arg = 2; arg <= top; arg++) { /* first arg is socket object */ | 54 | for (arg = 2; arg <= top; arg++) { /* first arg is socket object */ |
71 | size_t done, len; | 55 | size_t sent, count; |
72 | cchar *data = luaL_optlstring(L, arg, NULL, &len); | 56 | const char *data = luaL_optlstring(L, arg, NULL, &count); |
73 | if (!data || err != PRIV_DONE) break; | 57 | if (!data || err != IO_DONE) break; |
74 | err = sendraw(L, buf, data, len, &done); | 58 | err = sendraw(buf, data, count, &sent); |
75 | total += done; | 59 | total += sent; |
76 | } | 60 | } |
77 | priv_pusherror(L, err); | ||
78 | lua_pushnumber(L, total); | 61 | lua_pushnumber(L, total); |
62 | error_push(L, err); | ||
79 | #ifdef LUASOCKET_DEBUG | 63 | #ifdef LUASOCKET_DEBUG |
80 | /* push time elapsed during operation as the last return value */ | 64 | /* push time elapsed during operation as the last return value */ |
81 | lua_pushnumber(L, tm_getelapsed(&base->base_tm)/1000.0); | 65 | lua_pushnumber(L, (tm_gettime() - tm_getstart(tm))/1000.0); |
82 | #endif | 66 | #endif |
83 | return lua_gettop(L) - top; | 67 | return lua_gettop(L) - top; |
84 | } | 68 | } |
85 | 69 | ||
86 | /*-------------------------------------------------------------------------*\ | 70 | /*-------------------------------------------------------------------------*\ |
87 | * Receive data from a buffered object | 71 | * Receive data from a buffered object |
88 | * Input | ||
89 | * buf: buffer structure to be used | ||
90 | * Lua Input: self [pat_1, pat_2 ... pat_n] | ||
91 | * self: socket object | ||
92 | * pat_i: may be one of the following | ||
93 | * "*l": reads a text line, defined as a string of caracters terminates | ||
94 | * by a LF character, preceded or not by a CR character. This is | ||
95 | * the default pattern | ||
96 | * "*lu": reads a text line, terminanted by a CR character only. (Unix mode) | ||
97 | * "*a": reads until connection closed | ||
98 | * number: reads 'number' characters from the socket object | ||
99 | * Lua Returns | ||
100 | * On success: one string for each pattern | ||
101 | * On error: all strings for which there was no error, followed by one | ||
102 | * nil value for the remaining strings, followed by an error code | ||
103 | \*-------------------------------------------------------------------------*/ | 72 | \*-------------------------------------------------------------------------*/ |
104 | int buf_receive(lua_State *L, p_buf buf) | 73 | int buf_meth_receive(lua_State *L, p_buf buf) |
105 | { | 74 | { |
106 | int top = lua_gettop(L); | 75 | int top = lua_gettop(L); |
107 | int arg, err = PRIV_DONE; | 76 | int arg, err = IO_DONE; |
108 | p_base base = buf->buf_base; | 77 | p_tm tm = buf->tm; |
109 | tm_markstart(&base->base_tm); | 78 | tm_markstart(tm); |
110 | /* push default pattern if need be */ | 79 | /* push default pattern if need be */ |
111 | if (top < 2) { | 80 | if (top < 2) { |
112 | lua_pushstring(L, "*l"); | 81 | lua_pushstring(L, "*l"); |
113 | top++; | 82 | top++; |
114 | } | 83 | } |
115 | /* make sure we have enough stack space */ | 84 | /* make sure we have enough stack space for all returns */ |
116 | luaL_checkstack(L, top+LUA_MINSTACK, "too many arguments"); | 85 | luaL_checkstack(L, top+LUA_MINSTACK, "too many arguments"); |
117 | /* receive all patterns */ | 86 | /* receive all patterns */ |
118 | for (arg = 2; arg <= top && err == PRIV_DONE; arg++) { | 87 | for (arg = 2; arg <= top && err == IO_DONE; arg++) { |
119 | if (!lua_isnumber(L, arg)) { | 88 | if (!lua_isnumber(L, arg)) { |
120 | static cchar *patternnames[] = {"*l", "*lu", "*a", "*w", NULL}; | 89 | static const char *patternnames[] = {"*l", "*a", NULL}; |
121 | cchar *pattern = luaL_optstring(L, arg, NULL); | 90 | const char *pattern = lua_isnil(L, arg) ? |
91 | "*l" : luaL_checkstring(L, arg); | ||
122 | /* get next pattern */ | 92 | /* get next pattern */ |
123 | switch (luaL_findstring(pattern, patternnames)) { | 93 | switch (luaL_findstring(pattern, patternnames)) { |
124 | case 0: /* DOS line pattern */ | 94 | case 0: /* line pattern */ |
125 | err = recvdosline(L, buf); break; | 95 | err = recvline(L, buf); break; |
126 | case 1: /* Unix line pattern */ | 96 | case 1: /* until closed pattern */ |
127 | err = recvunixline(L, buf); break; | 97 | err = recvall(L, buf); |
128 | case 2: /* Until closed pattern */ | 98 | if (err == IO_CLOSED) err = IO_DONE; |
129 | err = recvall(L, buf); break; | ||
130 | case 3: /* Word pattern */ | ||
131 | luaL_argcheck(L, 0, arg, "word patterns are deprecated"); | ||
132 | break; | 99 | break; |
133 | default: /* else it is an error */ | 100 | default: /* else it is an error */ |
134 | luaL_argcheck(L, 0, arg, "invalid receive pattern"); | 101 | luaL_argcheck(L, 0, arg, "invalid receive pattern"); |
@@ -140,25 +107,20 @@ int buf_receive(lua_State *L, p_buf buf) | |||
140 | /* push nil for each pattern after an error */ | 107 | /* push nil for each pattern after an error */ |
141 | for ( ; arg <= top; arg++) lua_pushnil(L); | 108 | for ( ; arg <= top; arg++) lua_pushnil(L); |
142 | /* last return is an error code */ | 109 | /* last return is an error code */ |
143 | priv_pusherror(L, err); | 110 | error_push(L, err); |
144 | #ifdef LUASOCKET_DEBUG | 111 | #ifdef LUASOCKET_DEBUG |
145 | /* push time elapsed during operation as the last return value */ | 112 | /* push time elapsed during operation as the last return value */ |
146 | lua_pushnumber(L, tm_getelapsed(&base->base_tm)/1000.0); | 113 | lua_pushnumber(L, (tm_gettime() - tm_getstart(tm))/1000.0); |
147 | #endif | 114 | #endif |
148 | return lua_gettop(L) - top; | 115 | return lua_gettop(L) - top; |
149 | } | 116 | } |
150 | 117 | ||
151 | /*-------------------------------------------------------------------------*\ | 118 | /*-------------------------------------------------------------------------*\ |
152 | * Determines if there is any data in the read buffer | 119 | * Determines if there is any data in the read buffer |
153 | * Input | ||
154 | * buf: buffer structure to be used | ||
155 | * Returns | ||
156 | * 1 if empty, 0 if there is data | ||
157 | \*-------------------------------------------------------------------------*/ | 120 | \*-------------------------------------------------------------------------*/ |
158 | int buf_isempty(lua_State *L, p_buf buf) | 121 | int buf_isempty(p_buf buf) |
159 | { | 122 | { |
160 | (void) L; | 123 | return buf->first >= buf->last; |
161 | return buf->buf_first >= buf->buf_last; | ||
162 | } | 124 | } |
163 | 125 | ||
164 | /*=========================================================================*\ | 126 | /*=========================================================================*\ |
@@ -166,24 +128,16 @@ int buf_isempty(lua_State *L, p_buf buf) | |||
166 | \*=========================================================================*/ | 128 | \*=========================================================================*/ |
167 | /*-------------------------------------------------------------------------*\ | 129 | /*-------------------------------------------------------------------------*\ |
168 | * Sends a raw block of data through a buffered object. | 130 | * Sends a raw block of data through a buffered object. |
169 | * Input | ||
170 | * buf: buffer structure to be used | ||
171 | * data: data to be sent | ||
172 | * len: number of bytes to send | ||
173 | * Output | ||
174 | * sent: number of bytes sent | ||
175 | * Returns | ||
176 | * operation error code. | ||
177 | \*-------------------------------------------------------------------------*/ | 131 | \*-------------------------------------------------------------------------*/ |
178 | static int sendraw(lua_State *L, p_buf buf, cchar *data, size_t len, | 132 | static int sendraw(p_buf buf, const char *data, size_t count, size_t *sent) |
179 | size_t *sent) | ||
180 | { | 133 | { |
181 | p_base base = buf->buf_base; | 134 | p_io io = buf->io; |
135 | p_tm tm = buf->tm; | ||
182 | size_t total = 0; | 136 | size_t total = 0; |
183 | int err = PRIV_DONE; | 137 | int err = IO_DONE; |
184 | while (total < len && err == PRIV_DONE) { | 138 | while (total < count && err == IO_DONE) { |
185 | size_t done; | 139 | size_t done; |
186 | err = base->base_send(L, base, data + total, len - total, &done); | 140 | err = io->send(io->ctx, data+total, count-total, &done, tm_get(tm)); |
187 | total += done; | 141 | total += done; |
188 | } | 142 | } |
189 | *sent = total; | 143 | *sent = total; |
@@ -192,25 +146,21 @@ static int sendraw(lua_State *L, p_buf buf, cchar *data, size_t len, | |||
192 | 146 | ||
193 | /*-------------------------------------------------------------------------*\ | 147 | /*-------------------------------------------------------------------------*\ |
194 | * Reads a raw block of data from a buffered object. | 148 | * Reads a raw block of data from a buffered object. |
195 | * Input | ||
196 | * buf: buffer structure | ||
197 | * wanted: number of bytes to be read | ||
198 | * Returns | ||
199 | * operation error code. | ||
200 | \*-------------------------------------------------------------------------*/ | 149 | \*-------------------------------------------------------------------------*/ |
201 | static int recvraw(lua_State *L, p_buf buf, size_t wanted) | 150 | static |
151 | int recvraw(lua_State *L, p_buf buf, size_t wanted) | ||
202 | { | 152 | { |
203 | int err = PRIV_DONE; | 153 | int err = IO_DONE; |
204 | size_t total = 0; | 154 | size_t total = 0; |
205 | luaL_Buffer b; | 155 | luaL_Buffer b; |
206 | luaL_buffinit(L, &b); | 156 | luaL_buffinit(L, &b); |
207 | while (total < wanted && err == PRIV_DONE) { | 157 | while (total < wanted && err == IO_DONE) { |
208 | size_t len; cchar *data; | 158 | size_t count; const char *data; |
209 | err = buf_contents(L, buf, &data, &len); | 159 | err = buf_get(buf, &data, &count); |
210 | len = MIN(len, wanted - total); | 160 | count = MIN(count, wanted - total); |
211 | luaL_addlstring(&b, data, len); | 161 | luaL_addlstring(&b, data, count); |
212 | buf_skip(L, buf, len); | 162 | buf_skip(buf, count); |
213 | total += len; | 163 | total += count; |
214 | } | 164 | } |
215 | luaL_pushresult(&b); | 165 | luaL_pushresult(&b); |
216 | return err; | 166 | return err; |
@@ -218,21 +168,18 @@ static int recvraw(lua_State *L, p_buf buf, size_t wanted) | |||
218 | 168 | ||
219 | /*-------------------------------------------------------------------------*\ | 169 | /*-------------------------------------------------------------------------*\ |
220 | * Reads everything until the connection is closed | 170 | * Reads everything until the connection is closed |
221 | * Input | ||
222 | * buf: buffer structure | ||
223 | * Result | ||
224 | * operation error code. | ||
225 | \*-------------------------------------------------------------------------*/ | 171 | \*-------------------------------------------------------------------------*/ |
226 | static int recvall(lua_State *L, p_buf buf) | 172 | static |
173 | int recvall(lua_State *L, p_buf buf) | ||
227 | { | 174 | { |
228 | int err = PRIV_DONE; | 175 | int err = IO_DONE; |
229 | luaL_Buffer b; | 176 | luaL_Buffer b; |
230 | luaL_buffinit(L, &b); | 177 | luaL_buffinit(L, &b); |
231 | while (err == PRIV_DONE) { | 178 | while (err == IO_DONE) { |
232 | cchar *data; size_t len; | 179 | const char *data; size_t count; |
233 | err = buf_contents(L, buf, &data, &len); | 180 | err = buf_get(buf, &data, &count); |
234 | luaL_addlstring(&b, data, len); | 181 | luaL_addlstring(&b, data, count); |
235 | buf_skip(L, buf, len); | 182 | buf_skip(buf, count); |
236 | } | 183 | } |
237 | luaL_pushresult(&b); | 184 | luaL_pushresult(&b); |
238 | return err; | 185 | return err; |
@@ -241,61 +188,27 @@ static int recvall(lua_State *L, p_buf buf) | |||
241 | /*-------------------------------------------------------------------------*\ | 188 | /*-------------------------------------------------------------------------*\ |
242 | * Reads a line terminated by a CR LF pair or just by a LF. The CR and LF | 189 | * Reads a line terminated by a CR LF pair or just by a LF. The CR and LF |
243 | * are not returned by the function and are discarded from the buffer. | 190 | * are not returned by the function and are discarded from the buffer. |
244 | * Input | ||
245 | * buf: buffer structure | ||
246 | * Result | ||
247 | * operation error code. PRIV_DONE, PRIV_TIMEOUT or PRIV_CLOSED | ||
248 | \*-------------------------------------------------------------------------*/ | 191 | \*-------------------------------------------------------------------------*/ |
249 | static int recvdosline(lua_State *L, p_buf buf) | 192 | static |
193 | int recvline(lua_State *L, p_buf buf) | ||
250 | { | 194 | { |
251 | int err = 0; | 195 | int err = 0; |
252 | luaL_Buffer b; | 196 | luaL_Buffer b; |
253 | luaL_buffinit(L, &b); | 197 | luaL_buffinit(L, &b); |
254 | while (err == PRIV_DONE) { | 198 | while (err == IO_DONE) { |
255 | size_t len, pos; cchar *data; | 199 | size_t count, pos; const char *data; |
256 | err = buf_contents(L, buf, &data, &len); | 200 | err = buf_get(buf, &data, &count); |
257 | pos = 0; | 201 | pos = 0; |
258 | while (pos < len && data[pos] != '\n') { | 202 | while (pos < count && data[pos] != '\n') { |
259 | /* we ignore all \r's */ | 203 | /* we ignore all \r's */ |
260 | if (data[pos] != '\r') luaL_putchar(&b, data[pos]); | 204 | if (data[pos] != '\r') luaL_putchar(&b, data[pos]); |
261 | pos++; | 205 | pos++; |
262 | } | 206 | } |
263 | if (pos < len) { /* found '\n' */ | 207 | if (pos < count) { /* found '\n' */ |
264 | buf_skip(L, buf, pos+1); /* skip '\n' too */ | 208 | buf_skip(buf, pos+1); /* skip '\n' too */ |
265 | break; /* we are done */ | ||
266 | } else /* reached the end of the buffer */ | ||
267 | buf_skip(L, buf, pos); | ||
268 | } | ||
269 | luaL_pushresult(&b); | ||
270 | return err; | ||
271 | } | ||
272 | |||
273 | /*-------------------------------------------------------------------------*\ | ||
274 | * Reads a line terminated by a LF character, which is not returned by | ||
275 | * the function, and is skipped in the buffer. | ||
276 | * Input | ||
277 | * buf: buffer structure | ||
278 | * Returns | ||
279 | * operation error code. PRIV_DONE, PRIV_TIMEOUT or PRIV_CLOSED | ||
280 | \*-------------------------------------------------------------------------*/ | ||
281 | static int recvunixline(lua_State *L, p_buf buf) | ||
282 | { | ||
283 | int err = PRIV_DONE; | ||
284 | luaL_Buffer b; | ||
285 | luaL_buffinit(L, &b); | ||
286 | while (err == 0) { | ||
287 | size_t pos, len; cchar *data; | ||
288 | err = buf_contents(L, buf, &data, &len); | ||
289 | pos = 0; | ||
290 | while (pos < len && data[pos] != '\n') { | ||
291 | luaL_putchar(&b, data[pos]); | ||
292 | pos++; | ||
293 | } | ||
294 | if (pos < len) { /* found '\n' */ | ||
295 | buf_skip(L, buf, pos+1); /* skip '\n' too */ | ||
296 | break; /* we are done */ | 209 | break; /* we are done */ |
297 | } else /* reached the end of the buffer */ | 210 | } else /* reached the end of the buffer */ |
298 | buf_skip(L, buf, pos); | 211 | buf_skip(buf, pos); |
299 | } | 212 | } |
300 | luaL_pushresult(&b); | 213 | luaL_pushresult(&b); |
301 | return err; | 214 | return err; |
@@ -303,38 +216,32 @@ static int recvunixline(lua_State *L, p_buf buf) | |||
303 | 216 | ||
304 | /*-------------------------------------------------------------------------*\ | 217 | /*-------------------------------------------------------------------------*\ |
305 | * Skips a given number of bytes in read buffer | 218 | * Skips a given number of bytes in read buffer |
306 | * Input | ||
307 | * buf: buffer structure | ||
308 | * len: number of bytes to skip | ||
309 | \*-------------------------------------------------------------------------*/ | 219 | \*-------------------------------------------------------------------------*/ |
310 | static void buf_skip(lua_State *L, p_buf buf, size_t len) | 220 | static |
221 | void buf_skip(p_buf buf, size_t count) | ||
311 | { | 222 | { |
312 | buf->buf_first += len; | 223 | buf->first += count; |
313 | if (buf_isempty(L, buf)) buf->buf_first = buf->buf_last = 0; | 224 | if (buf_isempty(buf)) |
225 | buf->first = buf->last = 0; | ||
314 | } | 226 | } |
315 | 227 | ||
316 | /*-------------------------------------------------------------------------*\ | 228 | /*-------------------------------------------------------------------------*\ |
317 | * Return any data available in buffer, or get more data from transport layer | 229 | * Return any data available in buffer, or get more data from transport layer |
318 | * if buffer is empty. | 230 | * if buffer is empty. |
319 | * Input | ||
320 | * buf: buffer structure | ||
321 | * Output | ||
322 | * data: pointer to buffer start | ||
323 | * len: buffer buffer length | ||
324 | * Returns | ||
325 | * PRIV_DONE, PRIV_CLOSED, PRIV_TIMEOUT ... | ||
326 | \*-------------------------------------------------------------------------*/ | 231 | \*-------------------------------------------------------------------------*/ |
327 | static int buf_contents(lua_State *L, p_buf buf, cchar **data, size_t *len) | 232 | static |
233 | int buf_get(p_buf buf, const char **data, size_t *count) | ||
328 | { | 234 | { |
329 | int err = PRIV_DONE; | 235 | int err = IO_DONE; |
330 | p_base base = buf->buf_base; | 236 | p_io io = buf->io; |
331 | if (buf_isempty(L, buf)) { | 237 | p_tm tm = buf->tm; |
332 | size_t done; | 238 | if (buf_isempty(buf)) { |
333 | err = base->base_receive(L, base, buf->buf_data, BUF_SIZE, &done); | 239 | size_t got; |
334 | buf->buf_first = 0; | 240 | err = io->recv(io->ctx, buf->data, BUF_SIZE, &got, tm_get(tm)); |
335 | buf->buf_last = done; | 241 | buf->first = 0; |
242 | buf->last = got; | ||
336 | } | 243 | } |
337 | *len = buf->buf_last - buf->buf_first; | 244 | *count = buf->last - buf->first; |
338 | *data = buf->buf_data + buf->buf_first; | 245 | *data = buf->data + buf->first; |
339 | return err; | 246 | return err; |
340 | } | 247 | } |