From fbe2ea3c0dcfbfc30c3e3072e29deea67f688211 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Tue, 22 Apr 2014 06:03:39 +0200 Subject: add marshaling for linked-list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- src/libmdsserver/linked-list.c | 86 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 85 insertions(+), 1 deletion(-) (limited to 'src/libmdsserver/linked-list.c') diff --git a/src/libmdsserver/linked-list.c b/src/libmdsserver/linked-list.c index bc7faee..a6c44cd 100644 --- a/src/libmdsserver/linked-list.c +++ b/src/libmdsserver/linked-list.c @@ -117,7 +117,7 @@ void linked_list_destroy(linked_list_t* this) * @param out Memory slot in which to store the new linked list * @return Non-zero on error, `errno` will have been set accordingly */ -int linked_list_clone(linked_list_t* this, linked_list_t* out) +int linked_list_clone(const linked_list_t* restrict this, linked_list_t* restrict out) { size_t n = this->capacity * sizeof(ssize_t); size_t* new_values; @@ -406,3 +406,87 @@ void linked_list_remove(linked_list_t* this, ssize_t node) linked_list_unuse(this, node); } + +/** + * Calculate the buffer size need to marshal a linked list + * + * @param this The list + * @return The number of bytes to allocate to the output buffer + */ +size_t linked_list_marshal_size(const linked_list_t* this) +{ + return sizeof(size_t) * (4 + this->reuse_head + 3 * this->end); +} + + +/** + * Marshals a linked list + * + * @param this The list + * @param data Output buffer for the marshalled data + */ +void linked_list_marshal(const linked_list_t* restrict this, char* restrict data) +{ + ((size_t*)data)[0] = this->capacity; + ((size_t*)data)[1] = this->end; + ((size_t*)data)[2] = this->reuse_head; + ((ssize_t*)data)[3] = this->edge; + data += 4 * sizeof(size_t) / sizeof(char); + + memcpy(data, this->reusable, this->reuse_head * sizeof(ssize_t)); + data += this->reuse_head * sizeof(ssize_t) / sizeof(char); + + memcpy(data, this->values, this->end * sizeof(size_t)); + data += this->end * sizeof(size_t) / sizeof(char); + + memcpy(data, this->next, this->end * sizeof(ssize_t)); + data += this->end * sizeof(ssize_t) / sizeof(char); + + memcpy(data, this->previous, this->end * sizeof(ssize_t)); +} + + +/** + * Unmarshals a linked list + * + * @param this Memory slot in which to store the new linked list + * @param data In buffer with the marshalled data + * @return Non-zero one error, errno will be set accordingly. + * Destroy the list on error. + */ +int linked_list_unmarshal(linked_list_t* restrict this, char* restrict data) +{ + size_t n; + + this->reusable = NULL; + this->values = NULL; + this->next = NULL; + this->previous = NULL; + + this->capacity = ((size_t*)data)[0]; + this->end = ((size_t*)data)[1]; + this->reuse_head = ((size_t*)data)[2]; + this->edge = ((ssize_t*)data)[3]; + data += 4 * sizeof(size_t) / sizeof(char); + + n = this->capacity * sizeof(size_t); + + if ((this->reusable = malloc(n)) == NULL) return -1; + if ((this->values = malloc(n)) == NULL) return -1; + if ((this->next = malloc(n)) == NULL) return -1; + if ((this->previous = malloc(n)) == NULL) return -1; + + memcpy(this->reusable, data, this->reuse_head * sizeof(ssize_t)); + data += this->reuse_head * sizeof(ssize_t) / sizeof(char); + + memcpy(this->values, data, this->end * sizeof(size_t)); + data += this->end * sizeof(size_t) / sizeof(char); + + memcpy(this->next, data, this->end * sizeof(ssize_t)); + data += this->end * sizeof(ssize_t) / sizeof(char); + + memcpy(this->previous, data, this->end * sizeof(ssize_t)); + + return 0; +} + -- cgit v1.2.3-70-g09d2