aboutsummaryrefslogtreecommitdiffstats
path: root/types-filter.c
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2019-10-22 15:04:45 +0200
committerMattias Andrée <maandree@kth.se>2019-10-22 15:04:45 +0200
commitb13efce73e506b0feb4bb7c275c273a54ae6e716 (patch)
tree79f93e69b01d236e96037aa60332d214696e048b /types-filter.c
parentFix NULL-pointer bug in get_pathname when running with -mdrm (diff)
downloadcoopgammad-091c8e5182775626fca8d429ad996d198c6ef081.tar.gz
coopgammad-091c8e5182775626fca8d429ad996d198c6ef081.tar.bz2
coopgammad-091c8e5182775626fca8d429ad996d198c6ef081.tar.xz
Change license and style, reorganise file, make makefile portable, and fix bugs1.3
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to 'types-filter.c')
-rw-r--r--types-filter.c125
1 files changed, 125 insertions, 0 deletions
diff --git a/types-filter.c b/types-filter.c
new file mode 100644
index 0000000..7fbebbd
--- /dev/null
+++ b/types-filter.c
@@ -0,0 +1,125 @@
+/* See LICENSE file for copyright and license details. */
+#include "types-filter.h"
+#include "util.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+
+/**
+ * Free all resources allocated to a filter.
+ * The allocation of `filter` itself is not freed.
+ *
+ * @param this The filter
+ */
+void
+filter_destroy(struct filter *restrict this)
+{
+ free(this->class);
+ free(this->ramps);
+}
+
+
+#if defined(__clang__)
+# pragma GCC diagnostic ignored "-Wcast-align"
+#endif
+
+
+/**
+ * Marshal a filter
+ *
+ * @param this The filter
+ * @param buf Output buffer for the marshalled filter,
+ * `NULL` just measure how large the buffers
+ * needs to be
+ * @param ramps_size The byte-size of `this->ramps`
+ * @return The number of marshalled byte
+ */
+size_t
+filter_marshal(const struct filter *restrict this, void *restrict buf, size_t ramps_size)
+{
+ size_t off = 0, n;
+ char nonnulls = 0;
+ char *restrict bs = buf;
+
+ if (bs) {
+ if (this->class)
+ nonnulls |= 1;
+ if (this->ramps)
+ nonnulls |= 2;
+ bs[off] = nonnulls;
+ }
+ off += 1;
+
+ if (bs)
+ *(int64_t *)&bs[off] = this->priority;
+ off += sizeof(int64_t);
+
+ if (bs)
+ *(enum lifespan *)&bs[off] = this->lifespan;
+ off += sizeof(enum lifespan);
+
+ if (this->class) {
+ n = strlen(this->class) + 1;
+ if (bs)
+ memcpy(&bs[off], this->class, n);
+ off += n;
+ }
+
+ if (this->ramps) {
+ if (bs)
+ memcpy(&bs[off], this->ramps, ramps_size);
+ off += ramps_size;
+ }
+
+ return off;
+}
+
+
+/**
+ * Unmarshal a filter
+ *
+ * @param this Output for the filter
+ * @param buf Buffer with the marshalled filter
+ * @param ramps_size The byte-size of `this->ramps`
+ * @return The number of unmarshalled bytes, 0 on error
+ */
+size_t
+filter_unmarshal(struct filter *restrict this, const void *restrict buf, size_t ramps_size)
+{
+ size_t off = 0, n;
+ char nonnulls = 0;
+ const char *restrict bs = buf;
+
+ nonnulls = bs[off];
+ off += 1;
+
+ this->class = NULL;
+ this->ramps = NULL;
+
+ this->priority = *(const int64_t *)&bs[off];
+ off += sizeof(int64_t);
+
+ this->lifespan = *(const enum lifespan *)&bs[off];
+ off += sizeof(enum lifespan);
+
+ if (nonnulls & 1) {
+ n = strlen(&bs[off]) + 1;
+ if (!(this->class = memdup(&bs[off], n)))
+ goto fail;
+ off += n;
+ }
+
+ if (nonnulls & 2) {
+ if (!(this->ramps = memdup(&bs[off], ramps_size)))
+ goto fail;
+ off += ramps_size;
+ }
+
+ return off;
+
+fail:
+ free(this->class);
+ free(this->ramps);
+ return 0;
+}