From 19f47cd105c997d2f916967f6fcb062be757f767 Mon Sep 17 00:00:00 2001 From: Pierrick Charron Date: Tue, 20 Nov 2012 19:54:00 -0500 Subject: [PATCH] read buffer implementation on top of stomp_recv --- stomp.c | 41 +++++++++++++++++++++++++++++++++++++++-- stomp.h | 5 +++++ 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/stomp.c b/stomp.c index 357020e..d52303f 100644 --- a/stomp.c +++ b/stomp.c @@ -60,6 +60,7 @@ stomp_t *stomp_init() #endif stomp->frame_stack = NULL; + stomp->read_buffer.size = 0; return stomp; } /* }}} */ @@ -336,10 +337,12 @@ int stomp_send(stomp_t *stomp, stomp_frame_t *frame TSRMLS_DC) /* {{{ stomp_recv */ -int stomp_recv(stomp_t *stomp, char *msg, size_t length) +static int stomp_recv_no_buffer(stomp_t *stomp, char *msg, const size_t length) { int len; + stomp_select(stomp); + #if HAVE_STOMP_SSL if(stomp->options.use_ssl) { len = SSL_read(stomp->ssl_handle, msg, length); @@ -357,6 +360,40 @@ int stomp_recv(stomp_t *stomp, char *msg, size_t length) } return len; } + +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); + } else { + int recv_size = stomp_recv_no_buffer(stomp, stomp->read_buffer.buf, STOMP_BUFSIZE); + if (recv_size <= length) { + memcpy(msg, stomp->read_buffer.buf, recv_size); + return recv_size; + } else { + memcpy(msg, stomp->read_buffer.buf, length); + stomp->read_buffer.pos = stomp->read_buffer.buf + length; + stomp->read_buffer.size = recv_size - length; + return length; + } + } + } else if (stomp->read_buffer.size >= length) { + memcpy(msg, stomp->read_buffer.pos, length); + stomp->read_buffer.pos += length; + stomp->read_buffer.size -= length; + return length; + } else { + int len = stomp->read_buffer.size; + memcpy(msg, stomp->read_buffer.pos, stomp->read_buffer.size); + stomp->read_buffer.size = 0; + if (stomp_select_ex(stomp, 0, 0)) { + return len + stomp_recv(stomp, msg + len, length - len); + } else { + return len; + } + } +} /* }}} */ /* {{{ stomp_read_buffer @@ -639,7 +676,7 @@ int stomp_select_ex(stomp_t *stomp, const long int sec, const long int usec) int n; struct timeval tv; - if (stomp->frame_stack) { + if (stomp->read_buffer.size || stomp->frame_stack) { return 1; } tv.tv_sec = sec; diff --git a/stomp.h b/stomp.h index 8f31a4f..a973160 100755 --- a/stomp.h +++ b/stomp.h @@ -73,6 +73,11 @@ typedef struct _stomp { SSL *ssl_handle; #endif stomp_frame_stack_t *frame_stack; + struct { + size_t size; + char buf[STOMP_BUFSIZE]; + char *pos; + } read_buffer; } stomp_t; stomp_t *stomp_init();