src/line_proto.c
changeset 28 9c1050bc8709
parent 27 e6639132bead
child 32 ae66e9ae4afb
equal deleted inserted replaced
27:e6639132bead 28:9c1050bc8709
   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