Reimplement read_line and read_buffer

v1.1
Pierrick Charron 2012-11-20 21:25:46 -05:00
parent 19f47cd105
commit e7feab2950
1 changed files with 77 additions and 84 deletions

161
stomp.c
View File

@ -337,7 +337,7 @@ int stomp_send(stomp_t *stomp, stomp_frame_t *frame TSRMLS_DC)
/* {{{ stomp_recv /* {{{ 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; 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 (stomp->read_buffer.size == 0) {
if (length >= STOMP_BUFSIZE) { if (length >= STOMP_BUFSIZE) {
return stomp_recv_no_buffer(stomp, msg, length); return _stomp_recv(stomp, msg, length);
} else { } 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) { if (recv_size <= length) {
memcpy(msg, stomp->read_buffer.buf, recv_size); memcpy(msg, stomp->read_buffer.buf, recv_size);
return 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 length = 0;
size_t i = 0; size_t bufsize = STOMP_BUFSIZE;
size_t bufsize = STOMP_BUFSIZE + 1; char *buffer = (char *) emalloc(STOMP_BUFSIZE);
char *buffer = (char *) emalloc(STOMP_BUFSIZE + 1);
while (1) { while (1) {
int i, found;
found = 0;
char *c;
size_t length = 1; // First populate the buffer
rc = stomp_recv(stomp, buffer + i, length); if (stomp->read_buffer.size == 0) {
if (rc < 1) { stomp->read_buffer.size = _stomp_recv(stomp, stomp->read_buffer.buf, STOMP_BUFSIZE);
efree(buffer); stomp->read_buffer.pos = stomp->read_buffer.buf;
return -1;
} }
if (1 == length) { // Then search the delimiter
i++; c = stomp->read_buffer.pos;
for (i = 1; i <= stomp->read_buffer.size ; i++) {
if (buffer[i-1] == 0) { if (*c == delimiter) {
if (stomp_select_ex(stomp, 0, 0)) { found = 1;
char endline[1];
if (1 != stomp_recv(stomp, endline, 1) && '\n' != endline[0]) {
efree(buffer);
return 0;
}
}
break; break;
} else {
c++;
} }
}
if (!found) i--;
if (i >= bufsize) { // Make sure we have enough place in the buffer
buffer = (char *) erealloc(buffer, bufsize + STOMP_BUFSIZE); if ((i+length) >= bufsize) {
bufsize += STOMP_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) { if (length) {
*data = (char *) emalloc(i); *data = buffer;
if (NULL == *data) { } else {
efree(buffer); efree(buffer);
return -1; *data = NULL;
}
memcpy(*data, buffer, i);
} }
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) static int stomp_read_line(stomp_t *stomp, char **data)
{ {
int rc = 0; size_t length = _stomp_read_until(stomp, data, '\n');
size_t i = 0; if (length > 1) {
size_t bufsize = STOMP_BUFSIZE + 1; (*data)[length - 1] = 0;
char *buffer = (char *) emalloc(STOMP_BUFSIZE + 1); length--;
} else if (length) {
while (1) { efree(*data);
*data = NULL;
size_t length = 1; length = 0;
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;
}
}
} }
return length;
if (i > 1) {
*data = (char *) emalloc(i);
if (NULL == *data) {
efree(buffer);
return -1;
}
memcpy(*data, buffer, i);
}
efree(buffer);
return i-1;
} }
/* }}} */ /* }}} */