aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMattias Andrée <maandree@operamail.com>2014-05-19 04:10:02 +0200
committerMattias Andrée <maandree@operamail.com>2014-05-19 04:10:02 +0200
commit3c6a4056aa9b4a65e8066092f823202d587d9bfd (patch)
tree263eaadc972785b19b8a7d7fa173533d2564f820 /src
parentm doc (diff)
downloadmds-3c6a4056aa9b4a65e8066092f823202d587d9bfd.tar.gz
mds-3c6a4056aa9b4a65e8066092f823202d587d9bfd.tar.bz2
mds-3c6a4056aa9b4a65e8066092f823202d587d9bfd.tar.xz
reduce code complexity
Signed-off-by: Mattias Andrée <maandree@operamail.com>
Diffstat (limited to 'src')
-rw-r--r--src/libmdsserver/mds-message.c122
1 files changed, 69 insertions, 53 deletions
diff --git a/src/libmdsserver/mds-message.c b/src/libmdsserver/mds-message.c
index ea4e458..c70bb15 100644
--- a/src/libmdsserver/mds-message.c
+++ b/src/libmdsserver/mds-message.c
@@ -26,6 +26,9 @@
#include <sys/socket.h>
+#define try(INSTRUCTION) if ((r = INSTRUCTION) < 0) return r
+
+
/**
* Initialise a message slot so that it can
* be used by `mds_message_read`
@@ -272,10 +275,52 @@ static int store_header(mds_message_t* restrict this, size_t length)
/**
- * Read the next message from a file descriptor
+ * Continue reading from the socket into the buffer
+ *
+ * @param this The message
+ * @param fd The file descriptor of the socekt
+ * @return The return value follows the rules of `mds_message_read`
+ */
+static int continue_read(mds_message_t* restrict this, int fd)
+{
+ size_t n;
+ ssize_t got;
+ int r;
+
+ /* Figure out how much space we have left in the read buffer. */
+ n = this->buffer_size - this->buffer_ptr;
+
+ /* If we do not have too much left, */
+ if (n < 128)
+ {
+ /* grow the buffer, */
+ try (mds_message_extend_buffer(this));
+
+ /* and recalculate how much space we have left. */
+ n = this->buffer_size - this->buffer_ptr;
+ }
+
+ /* Then read from the socket. */
+ errno = 0;
+ got = recv(fd, this->buffer + this->buffer_ptr, n, 0);
+ this->buffer_ptr += (size_t)(got < 0 ? 0 : got);
+ if (errno)
+ return -1;
+ if (got == 0)
+ {
+ errno = ECONNRESET;
+ return -1;
+ }
+
+ return 0;
+}
+
+
+/**
+ * Read the next message from a file descriptor of the socekt
*
* @param this Memory slot in which to store the new message
- * @param fd The file descriptor
+ * @param fd The file descriptor of the socekt
* @return Non-zero on error or interruption, errno will be
* set accordingly. Destroy the message on error,
* be aware that the reading could have been
@@ -289,8 +334,6 @@ int mds_message_read(mds_message_t* restrict this, int fd)
size_t header_commit_buffer = 0;
int r;
-#define try(INSTRUCTION) if ((r = INSTRUCTION) < 0) return r
-
/* If we are at stage 2, we are done and it is time to start over.
This is important because the function could have been interrupted. */
if (this->stage == 2)
@@ -302,8 +345,6 @@ int mds_message_read(mds_message_t* restrict this, int fd)
/* Read from file descriptor until we have a full message. */
for (;;)
{
- size_t n;
- ssize_t got;
char* p;
size_t length;
@@ -337,12 +378,8 @@ int mds_message_read(mds_message_t* restrict this, int fd)
this->stage = 1;
}
+
/* Stage 1: payload. */
- if ((this->stage == 1) && (this->payload_size == 0))
- {
- this->stage = 2;
- return 0;
- }
if ((this->stage == 1) && (this->payload_size > 0))
{
/* How much of the payload that has not yet been filled. */
@@ -356,45 +393,22 @@ int mds_message_read(mds_message_t* restrict this, int fd)
/* Keep track of how much we have read. */
this->payload_ptr += move;
-
- /* If we have filled the payload, make the end of this stage,
- i.e. that the message is complete, and return with success. */
- if (this->payload_ptr == this->payload_size)
- {
- this->stage = 2;
- return 0;
- }
}
-
- /* If stage 1 was not completed. */
-
- /* Figure out how much space we have left in the read buffer. */
- n = this->buffer_size - this->buffer_ptr;
-
- /* If we do not have too much left, */
- if (n < 128)
+ if ((this->stage == 1) && (this->payload_ptr == this->payload_size))
{
- /* grow the buffer, */
- try (mds_message_extend_buffer(this));
-
- /* and recalculate how much space we have left. */
- n = this->buffer_size - this->buffer_ptr;
+ /* If we have filled the payload (or there was no payload),
+ mark the end of this stage, i.e. that the message is
+ complete, and return with success. */
+ this->stage = 2;
+ return 0;
}
- /* Then read from the socket. */
- errno = 0;
- got = recv(fd, this->buffer + this->buffer_ptr, n, 0);
- this->buffer_ptr += (size_t)(got < 0 ? 0 : got);
- if (errno)
- return -1;
- if (got == 0)
- {
- errno = ECONNRESET;
- return -1;
- }
+
+ /* If stage 1 was not completed. */
+
+ /* Continue reading from the socket into the buffer. */
+ try (continue_read(this, fd));
}
-
-#undef try
}
@@ -501,23 +515,19 @@ int mds_message_unmarshal(mds_message_t* restrict this, char* restrict data)
/* Allocate header list, payload and read buffer. */
if (header_count > 0)
- if (xmalloc(this->headers, header_count, char*))
- return -1;
+ fail_if (xmalloc(this->headers, header_count, char*));
if (this->payload_size > 0)
- if (xmalloc(this->payload, this->payload_size, char))
- return -1;
+ fail_if (xmalloc(this->payload, this->payload_size, char));
- if (xmalloc(this->buffer, this->buffer_size, char))
- return -1;
+ fail_if (xmalloc(this->buffer, this->buffer_size, char));
/* Fill the header list, payload and read buffer. */
for (i = 0; i < this->header_count; i++)
{
n = strlen(data) + 1;
- if (xmalloc(this->headers[i], n, char))
- return -1;
+ fail_if (xmalloc(this->headers[i], n, char));
memcpy(this->headers[i], data, n * sizeof(char));
buf_next(data, char, n);
this->header_count++;
@@ -529,6 +539,9 @@ int mds_message_unmarshal(mds_message_t* restrict this, char* restrict data)
memcpy(this->buffer, data, this->buffer_ptr * sizeof(char));
return 0;
+
+ pfail:
+ return -1;
}
@@ -572,3 +585,6 @@ void mds_message_compose(const mds_message_t* restrict this, char* restrict data
memcpy(data, this->payload, this->payload_size * sizeof(char));
}
+
+#undef try
+