From e7feab2950c89902739fc38eaf3abe3209f727ef Mon Sep 17 00:00:00 2001 From: Pierrick Charron Date: Tue, 20 Nov 2012 21:25:46 -0500 Subject: [PATCH] Reimplement read_line and read_buffer --- stomp.c | 161 +++++++++++++++++++++++++++----------------------------- 1 file changed, 77 insertions(+), 84 deletions(-) diff --git a/stomp.c b/stomp.c index d52303f..b7fec1c 100644 --- a/stomp.c +++ b/stomp.c @@ -337,7 +337,7 @@ int stomp_send(stomp_t *stomp, stomp_frame_t *frame TSRMLS_DC) /* {{{ stomp_recv */ -static int stomp_recv_no_buffer(stomp_t *stomp, char *msg, const size_t length) +static int _stomp_recv(stomp_t *stomp, char *msg, const size_t length) { int len; @@ -365,9 +365,9 @@ int stomp_recv(stomp_t *stomp, char *msg, const size_t length) { if (stomp->read_buffer.size == 0) { if (length >= STOMP_BUFSIZE) { - return stomp_recv_no_buffer(stomp, msg, length); + return _stomp_recv(stomp, msg, length); } else { - int recv_size = stomp_recv_no_buffer(stomp, stomp->read_buffer.buf, STOMP_BUFSIZE); + int recv_size = _stomp_recv(stomp, stomp->read_buffer.buf, STOMP_BUFSIZE); if (recv_size <= length) { memcpy(msg, stomp->read_buffer.buf, recv_size); return recv_size; @@ -396,59 +396,88 @@ int stomp_recv(stomp_t *stomp, char *msg, const size_t length) } /* }}} */ -/* {{{ stomp_read_buffer +/* {{{ _stomp_read_until */ -static int stomp_read_buffer(stomp_t *stomp, char **data) +static size_t _stomp_read_until(stomp_t *stomp, char **data, const char delimiter) { - int rc = 0; - size_t i = 0; - size_t bufsize = STOMP_BUFSIZE + 1; - char *buffer = (char *) emalloc(STOMP_BUFSIZE + 1); + size_t length = 0; + size_t bufsize = STOMP_BUFSIZE; + char *buffer = (char *) emalloc(STOMP_BUFSIZE); while (1) { + int i, found; + found = 0; + char *c; - size_t length = 1; - rc = stomp_recv(stomp, buffer + i, length); - if (rc < 1) { - efree(buffer); - return -1; + // First populate the buffer + if (stomp->read_buffer.size == 0) { + stomp->read_buffer.size = _stomp_recv(stomp, stomp->read_buffer.buf, STOMP_BUFSIZE); + stomp->read_buffer.pos = stomp->read_buffer.buf; } - if (1 == length) { - i++; - - if (buffer[i-1] == 0) { - if (stomp_select_ex(stomp, 0, 0)) { - char endline[1]; - if (1 != stomp_recv(stomp, endline, 1) && '\n' != endline[0]) { - efree(buffer); - return 0; - } - } + // Then search the delimiter + c = stomp->read_buffer.pos; + for (i = 1; i <= stomp->read_buffer.size ; i++) { + if (*c == delimiter) { + found = 1; break; + } else { + c++; } + } + if (!found) i--; - if (i >= bufsize) { - buffer = (char *) erealloc(buffer, bufsize + STOMP_BUFSIZE); - bufsize += STOMP_BUFSIZE; - } + // Make sure we have enough place in the buffer + if ((i+length) >= bufsize) { + buffer = (char *) erealloc(buffer, bufsize + STOMP_BUFSIZE); + bufsize += STOMP_BUFSIZE; + } + // Copy and update the buffer + memcpy(buffer + length, stomp->read_buffer.pos, i); + length += i; + stomp->read_buffer.pos += i; + stomp->read_buffer.size -= i; + + if (found) { + break; } } - if (i > 1) { - *data = (char *) emalloc(i); - if (NULL == *data) { - efree(buffer); - return -1; - } - - memcpy(*data, buffer, i); + if (length) { + *data = buffer; + } else { + efree(buffer); + *data = NULL; } - efree(buffer); + return length; +} +/* }}} */ - return i-1; +/* {{{ stomp_read_buffer + */ +static size_t stomp_read_buffer(stomp_t *stomp, char **data) +{ + size_t length = _stomp_read_until(stomp, data, 0); + if (stomp_select_ex(stomp, 0, 0)) { + char endline[1]; + if (1 != stomp_recv(stomp, endline, 1) && '\n' != endline[0]) { + if (*data) { + efree(*data); + *data = NULL; + } + return 0; + } + } + if (length > 1) { + length --; + } else if (length) { + efree(*data); + *data = NULL; + length = 0; + } + return length; } /* }}} */ @@ -456,52 +485,16 @@ static int stomp_read_buffer(stomp_t *stomp, char **data) */ static int stomp_read_line(stomp_t *stomp, char **data) { - int rc = 0; - size_t i = 0; - size_t bufsize = STOMP_BUFSIZE + 1; - char *buffer = (char *) emalloc(STOMP_BUFSIZE + 1); - - while (1) { - - size_t length = 1; - rc = stomp_recv(stomp, buffer + i, length); - if (rc < 1) { - efree(buffer); - return -1; - } - - if (1 == length) { - i++; - - if (buffer[i-1] == '\n') { - buffer[i-1] = 0; - break; - } else if (buffer[i-1] == 0) { - efree(buffer); - return 0; - } - - if (i >= bufsize) { - buffer = (char *) erealloc(buffer, bufsize + STOMP_BUFSIZE); - bufsize += STOMP_BUFSIZE; - } - } - + size_t length = _stomp_read_until(stomp, data, '\n'); + if (length > 1) { + (*data)[length - 1] = 0; + length--; + } else if (length) { + efree(*data); + *data = NULL; + length = 0; } - - if (i > 1) { - *data = (char *) emalloc(i); - if (NULL == *data) { - efree(buffer); - return -1; - } - - memcpy(*data, buffer, i); - } - - efree(buffer); - - return i-1; + return length; } /* }}} */