From 818b53a4d442271f61edbdc08f7f47ee651821b3 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Thu, 8 May 2014 03:08:14 +0200 Subject: split up mds-server structs into their own .h-files and add marshal functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- src/mds-server/client.c | 124 +++++++++++++++++++++++++++++++ src/mds-server/client.h | 126 ++++++++++++++++++++++++++++++++ src/mds-server/interception_condition.c | 76 +++++++++++++++++++ src/mds-server/interception_condition.h | 86 ++++++++++++++++++++++ src/mds-server/mds-server.c | 3 + src/mds-server/mds-server.h | 125 +------------------------------ src/mds-server/queued_interception.h | 51 +++++++++++++ 7 files changed, 468 insertions(+), 123 deletions(-) create mode 100644 src/mds-server/client.c create mode 100644 src/mds-server/client.h create mode 100644 src/mds-server/interception_condition.c create mode 100644 src/mds-server/interception_condition.h create mode 100644 src/mds-server/queued_interception.h (limited to 'src/mds-server') diff --git a/src/mds-server/client.c b/src/mds-server/client.c new file mode 100644 index 0000000..13b291c --- /dev/null +++ b/src/mds-server/client.c @@ -0,0 +1,124 @@ +/** + * mds — A micro-display server + * Copyright © 2014 Mattias Andrée (maandree@member.fsf.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include "client.h" + +#include + +#include +#include + + + +/** + * Calculate the buffer size need to marshal client information + * + * @param this The client information + * @return The number of bytes to allocate to the output buffer + */ +size_t client_marshal_size(const client_t* restrict this) +{ + size_t n = sizeof(ssize_t) + 2 * sizeof(int) + sizeof(uint64_t) + 3 * sizeof(size_t); + size_t i; + + n += mds_message_marshal_size(&(this->message), 1); + for (i = 0; i < this->interception_conditions_count; i++) + n += interception_condition_marshal_size(this->interception_conditions + i); + n += this->send_pending_size * sizeof(char); + + return n; +} + + +/** + * Marshals an client information + * + * @param this The client information + * @param data Output buffer for the marshalled data + * @return The number of bytes that have been written (everything will be written) + */ +size_t client_marshal(const client_t* restrict this, char* restrict data) +{ + size_t i, n; + buf_set_next(data, ssize_t, this->list_entry); + buf_set_next(data, int, this->socket_fd); + buf_set_next(data, int, this->open); + buf_set_next(data, uint64_t, this->id); + n = mds_message_marshal_size(&(this->message), 1);; + buf_set_next(data, size_t, n); + mds_message_marshal(&(this->message), data, 1); + data += n / sizeof(char); + buf_set_next(data, size_t, this->interception_conditions_count); + for (i = 0; i < this->interception_conditions_count; i++) + data += interception_condition_marshal(this->interception_conditions + i, data) / sizeof(char); + buf_set_next(data, size_t, this->send_pending_size); + if (this->send_pending_size > 0) + memcpy(data, this->send_pending, this->send_pending_size * sizeof(char)); + return client_marshal_size(this); +} + + +/** + * Unmarshals an client information + * + * @param this Memory slot in which to store the new client information + * @param data In buffer with the marshalled data + * @return Zero on error, errno will be set accordingly, otherwise the number of read bytes + */ +size_t client_unmarshal(client_t* restrict this, char* restrict data) +{ + size_t i, n, rc = sizeof(ssize_t) + 2 * sizeof(int) + sizeof(uint64_t) + 3 * sizeof(size_t); + this->interception_conditions = NULL; + this->send_pending = NULL; + buf_get_next(data, ssize_t, this->list_entry); + buf_get_next(data, int, this->socket_fd); + buf_get_next(data, int, this->open); + buf_get_next(data, uint64_t, this->id); + buf_get_next(data, size_t, n); + if (mds_message_unmarshal(&(this->message), data)) + return 0; + data += n / sizeof(char); + rc += n; + buf_get_next(data, size_t, this->interception_conditions_count); + for (i = 0; i < this->interception_conditions_count; i++) + { + n = interception_condition_unmarshal(this->interception_conditions + i, data); + if (n == 0) + { + this->interception_conditions_count = i - 1; + goto fail; + } + data += n / sizeof(char); + rc += n; + } + buf_get_next(data, size_t, this->send_pending_size); + if (this->send_pending_size > 0) + { + if (xmalloc(this->send_pending, this->send_pending_size, char)) + goto fail; + memcpy(this->send_pending, data, this->send_pending_size * sizeof(char)); + } + return rc; + + fail: + for (i = 0; i < this->interception_conditions_count; i++) + free(this->interception_conditions[i].condition); + free(this->interception_conditions); + free(this->send_pending); + return 0; +} + diff --git a/src/mds-server/client.h b/src/mds-server/client.h new file mode 100644 index 0000000..a63f2b6 --- /dev/null +++ b/src/mds-server/client.h @@ -0,0 +1,126 @@ +/** + * mds — A micro-display server + * Copyright © 2014 Mattias Andrée (maandree@member.fsf.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef MDS_MDS_SERVER_CLIENT_H +#define MDS_MDS_SERVER_CLIENT_H + + +#include "interception_condition.h" + +#include + +#include +#include +#include + + + +/** + * Client information structure + */ +typedef struct client +{ + /** + * The client's entry in the list of clients + */ + ssize_t list_entry; + + /** + * The socket file descriptor for the socket connected to the client + */ + int socket_fd; + + /** + * Whether the socket is open + */ + int open; + + /** + * Message read buffer for the client + */ + mds_message_t message; + + /** + * The read thread for the client + */ + pthread_t thread; + + /** + * The client's ID + */ + uint64_t id; + + /** + * Mutex for sending data and other + * actions that only affacts this client + */ + pthread_mutex_t mutex; + + /** + * The messages interception conditions conditions + * for the client + */ + interception_condition_t* interception_conditions; + + /** + * The number of interception conditions + */ + size_t interception_conditions_count; + + /** + * Messages pending to be sent (concatenated) + */ + char* send_pending; + + /** + * The character length of the messages pending to be sent + */ + size_t send_pending_size; + +} client_t; + + +/** + * Calculate the buffer size need to marshal client information + * + * @param this The client information + * @return The number of bytes to allocate to the output buffer + */ +size_t client_marshal_size(const client_t* restrict this) __attribute__((pure)); + +/** + * Marshals an client information + * + * @param this The client information + * @param data Output buffer for the marshalled data + * @return The number of bytes that have been written (everything will be written) + */ +size_t client_marshal(const client_t* restrict this, char* restrict data); + +/** + * Unmarshals an client information + * + * @param this Memory slot in which to store the new client information + * @param data In buffer with the marshalled data + * @return Zero on error, errno will be set accordingly, otherwise the number of read bytes. + * Destroy the client information on error. + */ +size_t client_unmarshal(client_t* restrict this, char* restrict data); + + +#endif + diff --git a/src/mds-server/interception_condition.c b/src/mds-server/interception_condition.c new file mode 100644 index 0000000..076bc19 --- /dev/null +++ b/src/mds-server/interception_condition.c @@ -0,0 +1,76 @@ +/** + * mds — A micro-display server + * Copyright © 2014 Mattias Andrée (maandree@member.fsf.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include "interception_condition.h" + +#include + +#include +#include + + + +/** + * Calculate the buffer size need to marshal an interception condition + * + * @param this The interception condition + * @return The number of bytes to allocate to the output buffer + */ +size_t interception_condition_marshal_size(const interception_condition_t* restrict this) +{ + return sizeof(size_t) + sizeof(int64_t) + sizeof(int) + (strlen(this->condition) + 1) * sizeof(char); +} + +/** + * Marshals an interception condition + * + * @param this The interception condition + * @param data Output buffer for the marshalled data + * @return The number of bytes that have been written (everything will be written) + */ +size_t interception_condition_marshal(const interception_condition_t* restrict this, char* restrict data) +{ + size_t n = (strlen(this->condition) + 1) * sizeof(char);; + buf_set_next(data, size_t, this->header_hash); + buf_set_next(data, int64_t, this->priority); + buf_set_next(data, int, this->modifying); + memcpy(data, this->condition, n); + return sizeof(size_t) + sizeof(int64_t) + sizeof(int) + n; +} + + +/** + * Unmarshals an interception condition + * + * @param this Memory slot in which to store the new interception condition + * @param data In buffer with the marshalled data + * @return Zero on error, errno will be set accordingly, otherwise the number of read bytes + */ +size_t interception_condition_unmarshal(interception_condition_t* restrict this, char* restrict data) +{ + size_t n; + this->condition = NULL; + buf_get_next(data, size_t, this->header_hash); + buf_get_next(data, int64_t, this->priority); + buf_get_next(data, int, this->modifying); + n = (strlen(data) + 1) * sizeof(char); + if ((this->condition = malloc(n)) == NULL) + return 0; + memcpy(this->condition, data, n); + return sizeof(size_t) + sizeof(int64_t) + sizeof(int) + n; +} + diff --git a/src/mds-server/interception_condition.h b/src/mds-server/interception_condition.h new file mode 100644 index 0000000..c80fab0 --- /dev/null +++ b/src/mds-server/interception_condition.h @@ -0,0 +1,86 @@ +/** + * mds — A micro-display server + * Copyright © 2014 Mattias Andrée (maandree@member.fsf.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef MDS_MDS_SERVER_INTERCEPTION_CONDITION_H +#define MDS_MDS_SERVER_INTERCEPTION_CONDITION_H + + +#include +#include + + +/** + * A condition for a message being intercepted by a client + */ +typedef struct interception_condition +{ + /** + * The header of messages to intercept, optionally with a value, + * empty (most not be NULL) for all messages. + */ + char* condition; + + /** + * The hash of the header of messages to intercept + */ + size_t header_hash; + + /** + * The interception priority. The client should be + * consistent with the priority for conditions that + * are not mutually exclusive. + */ + int64_t priority; + + /** + * Whether the messages may get modified by the client + */ + int modifying; + +} interception_condition_t; + + +/** + * Calculate the buffer size need to marshal an interception condition + * + * @param this The interception condition + * @return The number of bytes to allocate to the output buffer + */ +size_t interception_condition_marshal_size(const interception_condition_t* restrict this) __attribute__((pure)); + +/** + * Marshals an interception condition + * + * @param this The interception condition + * @param data Output buffer for the marshalled data + * @return The number of bytes that have been written (everything will be written) + */ +size_t interception_condition_marshal(const interception_condition_t* restrict this, char* restrict data); + +/** + * Unmarshals an interception condition + * + * @param this Memory slot in which to store the new interception condition + * @param data In buffer with the marshalled data + * @return Zero on error, errno will be set accordingly, otherwise the number of read bytes. + * Destroy the interception condition on error. + */ +size_t interception_condition_unmarshal(interception_condition_t* restrict this, char* restrict data); + + +#endif + diff --git a/src/mds-server/mds-server.c b/src/mds-server/mds-server.c index d707eab..f0fa701 100644 --- a/src/mds-server/mds-server.c +++ b/src/mds-server/mds-server.c @@ -16,6 +16,9 @@ * along with this program. If not, see . */ #include "mds-server.h" +#include "interception_condition.h" +#include "client.h" +#include "queued_interception.h" #include #include diff --git a/src/mds-server/mds-server.h b/src/mds-server/mds-server.h index 1e3869f..b2dafd4 100644 --- a/src/mds-server/mds-server.h +++ b/src/mds-server/mds-server.h @@ -19,130 +19,9 @@ #define MDS_MDS_SERVER_H -#include +#include "client.h" -#include -#include -#include - - - -/** - * A condition for a message being intercepted by a client - */ -typedef struct interception_condition -{ - /** - * The header of messages to intercept, optionally with a value, - * empty (most not be NULL) for all messages. - */ - char* condition; - - /** - * The hash of the header of messages to intercept - */ - size_t header_hash; - - /** - * The interception priority. The client should be - * consistent with the priority for conditions that - * are not mutually exclusive. - */ - int64_t priority; - - /** - * Whether the messages may get modified by the client - */ - int modifying; - -} interception_condition_t; - - -/** - * Client information structure - */ -typedef struct client -{ - /** - * The client's entry in the list of clients - */ - ssize_t list_entry; - - /** - * The socket file descriptor for the socket connected to the client - */ - int socket_fd; - - /** - * Whether the socket is open - */ - int open; - - /** - * Message read buffer for the client - */ - mds_message_t message; - - /** - * The read thread for the client - */ - pthread_t thread; - - /** - * The client's ID - */ - uint64_t id; - - /** - * Mutex for sending data and other - * actions that only affacts this client - */ - pthread_mutex_t mutex; - - /** - * The messages interception conditions conditions - * for the client - */ - interception_condition_t* interception_conditions; - - /** - * The number of interception conditions - */ - size_t interception_conditions_count; - - /** - * Messages pending to be sent (concatenated) - */ - char* send_pending; - - /** - * The character length of the messages pending to be sent - */ - size_t send_pending_size; - -} client_t; - -/** - * A queued interception - */ -typedef struct queued_interception -{ - /** - * The intercepting client - */ - client_t* client; - - /** - * The interception priority - */ - int64_t priority; - - /** - * Whether the messages may get modified by the client - */ - int modifying; - -} queued_interception_t; +#include diff --git a/src/mds-server/queued_interception.h b/src/mds-server/queued_interception.h new file mode 100644 index 0000000..6f08a8a --- /dev/null +++ b/src/mds-server/queued_interception.h @@ -0,0 +1,51 @@ +/** + * mds — A micro-display server + * Copyright © 2014 Mattias Andrée (maandree@member.fsf.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef MDS_MDS_SERVER_QUEUED_INTERCEPTION_H +#define MDS_MDS_SERVER_QUEUED_INTERCEPTION_H + + +#include "client.h" + +#include + + +/** + * A queued interception + */ +typedef struct queued_interception +{ + /** + * The intercepting client + */ + client_t* client; + + /** + * The interception priority + */ + int64_t priority; + + /** + * Whether the messages may get modified by the client + */ + int modifying; + +} queued_interception_t; + + +#endif + -- cgit v1.2.3-70-g09d2