equal
deleted
inserted
replaced
131 *lp_ptr = lp; |
131 *lp_ptr = lp; |
132 |
132 |
133 return SUCCESS; |
133 return SUCCESS; |
134 |
134 |
135 error: |
135 error: |
136 if (lp) { |
136 // cleanup the lp |
137 free(lp->in_buf); |
137 if (lp) |
138 free(lp->out_buf); |
138 line_proto_release(lp); |
139 |
|
140 // XXX: handle sock init errors |
|
141 } |
|
142 |
|
143 free(lp); |
|
144 |
139 |
145 return ERROR_CODE(err); |
140 return ERROR_CODE(err); |
146 } |
141 } |
147 |
142 |
148 /* |
143 /* |
248 } |
243 } |
249 |
244 |
250 int line_proto_send (struct line_proto *lp, const char *line) |
245 int line_proto_send (struct line_proto *lp, const char *line) |
251 { |
246 { |
252 int ret; |
247 int ret; |
253 size_t len = strlen(line); |
248 size_t len = strlen(line), ret_len; |
254 |
249 |
255 // drop line if we already have output buffered |
250 // drop line if we already have output buffered |
256 if (lp->out_offset) |
251 if (lp->out_offset) |
257 return -ERR_LINE_TOO_LONG; |
252 return -ERR_LINE_TOO_LONG; |
258 |
253 |
261 SET_ERROR_INFO(&lp->err, sock_stream_error(lp->sock)); |
256 SET_ERROR_INFO(&lp->err, sock_stream_error(lp->sock)); |
262 |
257 |
263 return -ERROR_CODE(&lp->err); |
258 return -ERROR_CODE(&lp->err); |
264 } |
259 } |
265 |
260 |
|
261 // length of the sent data |
|
262 ret_len = ret; |
|
263 |
266 // EAGAIN or partial? |
264 // EAGAIN or partial? |
267 if (ret < len) { |
265 if (ret_len < len) { |
268 size_t trailing = len - ret; |
266 size_t trailing = len - ret_len; |
269 |
267 |
270 // ensure it's not waaaay too long |
268 // ensure it's not waaaay too long |
271 if (trailing > lp->buf_len) |
269 if (trailing > lp->buf_len) |
272 return -ERR_LINE_TOO_LONG; |
270 return -ERR_LINE_TOO_LONG; |
273 |
271 |
274 // copy remaining portion to buffer |
272 // copy remaining portion to buffer |
275 memcpy(lp->out_buf, line + ret, trailing); |
273 memcpy(lp->out_buf, line + ret_len, trailing); |
276 |
274 |
277 // update offset |
275 // update offset |
278 lp->out_offset = trailing; |
276 lp->out_offset = trailing; |
279 |
277 |
280 // register for EV_WRITE |
278 // register for EV_WRITE |
292 } |
290 } |
293 |
291 |
294 int line_proto_flush (struct line_proto *lp) |
292 int line_proto_flush (struct line_proto *lp) |
295 { |
293 { |
296 int ret; |
294 int ret; |
|
295 size_t ret_len; |
297 |
296 |
298 // try and write the line |
297 // try and write the line |
299 if ((ret = sock_stream_write(lp->sock, lp->out_buf, lp->out_offset)) < 0) { |
298 if ((ret = sock_stream_write(lp->sock, lp->out_buf, lp->out_offset)) < 0) { |
300 SET_ERROR_INFO(&lp->err, sock_stream_error(lp->sock)); |
299 SET_ERROR_INFO(&lp->err, sock_stream_error(lp->sock)); |
301 |
300 |
302 return -ERROR_CODE(&lp->err); |
301 return -ERROR_CODE(&lp->err); |
303 } |
302 } |
304 |
303 |
|
304 ret_len = ret; |
|
305 |
305 // empty now? |
306 // empty now? |
306 if (ret == lp->out_offset) { |
307 if (ret_len == lp->out_offset) { |
307 lp->out_offset = 0; |
308 lp->out_offset = 0; |
308 |
309 |
309 return SUCCESS; |
310 return SUCCESS; |
310 } |
311 } |
311 |
312 |
312 // partial? |
313 // partial? |
313 if (ret > 0) { |
314 if (ret_len > 0) { |
314 size_t remaining = lp->out_offset - ret; |
315 size_t remaining = lp->out_offset - ret_len; |
315 |
316 |
316 // move the rest up |
317 // move the rest up |
317 memmove(lp->out_buf, lp->out_buf + ret, remaining); |
318 memmove(lp->out_buf, lp->out_buf + ret_len, remaining); |
318 |
319 |
319 // update offset |
320 // update offset |
320 lp->out_offset = remaining; |
321 lp->out_offset = remaining; |
321 } |
322 } |
322 |
323 |
332 { |
333 { |
333 // return pointer |
334 // return pointer |
334 return &lp->err; |
335 return &lp->err; |
335 } |
336 } |
336 |
337 |
|
338 void line_proto_release (struct line_proto *lp) |
|
339 { |
|
340 // free buffers |
|
341 free(lp->in_buf); |
|
342 free(lp->out_buf); |
|
343 |
|
344 // socket? |
|
345 if (lp->sock) |
|
346 sock_stream_release(lp->sock); |
|
347 |
|
348 // free the state itself |
|
349 free(lp); |
|
350 } |
|
351 |