aboutsummaryrefslogtreecommitdiffstats
path: root/types-ring.h
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-ring.h
parentFix NULL-pointer bug in get_pathname when running with -mdrm (diff)
downloadcoopgammad-b13efce73e506b0feb4bb7c275c273a54ae6e716.tar.gz
coopgammad-b13efce73e506b0feb4bb7c275c273a54ae6e716.tar.bz2
coopgammad-b13efce73e506b0feb4bb7c275c273a54ae6e716.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-ring.h')
-rw-r--r--types-ring.h131
1 files changed, 131 insertions, 0 deletions
diff --git a/types-ring.h b/types-ring.h
new file mode 100644
index 0000000..c8b5f77
--- /dev/null
+++ b/types-ring.h
@@ -0,0 +1,131 @@
+/* See LICENSE file for copyright and license details. */
+#ifndef TYPES_RING_H
+#define TYPES_RING_H
+
+#include <stdlib.h>
+
+#ifndef GCC_ONLY
+# if defined(__GNUC__) && !defined(__clang__)
+# define GCC_ONLY(...) __VA_ARGS__
+# else
+# define GCC_ONLY(...) /* nothing */
+# endif
+#endif
+
+/**
+ * Ring buffer
+ */
+struct ring {
+ /**
+ * Buffer for the data
+ */
+ char *restrict buffer;
+
+ /**
+ * The first set byte in `.buffer`
+ */
+ size_t start;
+
+ /**
+ * The last set byte in `.buffer`, plus 1
+ */
+ size_t end;
+
+ /**
+ * The size of `.buffer`
+ */
+ size_t size;
+};
+
+/**
+ * Initialise a ring buffer
+ *
+ * @param this The ring buffer
+ */
+GCC_ONLY(__attribute__((__nonnull__)))
+void ring_initialise(struct ring *restrict this);
+
+/**
+ * Marshal a ring buffer
+ *
+ * @param this The ring buffer
+ * @param buf Output buffer for the marshalled data,
+ * `NULL` to only measure how large buffer
+ * is needed
+ * @return The number of marshalled bytes
+ */
+GCC_ONLY(__attribute__((__nonnull__(1))))
+size_t ring_marshal(const struct ring *restrict this, void *restrict buf);
+
+/**
+ * Unmarshal a ring buffer
+ *
+ * @param this Output parameter for the ring buffer
+ * @param buf Buffer with the marshalled data
+ * @return The number of unmarshalled bytes, 0 on error
+ */
+GCC_ONLY(__attribute__((__nonnull__)))
+size_t ring_unmarshal(struct ring *restrict this, const void *restrict buf);
+
+/**
+ * Append data to a ring buffer
+ *
+ * @param this The ring buffer
+ * @param data The new data
+ * @param n The number of bytes in `data`
+ * @return Zero on success, -1 on error
+ */
+GCC_ONLY(__attribute__((__nonnull__(1))))
+int ring_push(struct ring *restrict this, void *restrict data, size_t n);
+
+/**
+ * Get queued data from a ring buffer
+ *
+ * It can take up to two calls (with `ring_pop` between)
+ * to get all queued data
+ *
+ * @param this The ring buffer
+ * @param n Output parameter for the length
+ * of the returned segment
+ * @return The beginning of the queued data,
+ * `NULL` if there is nothing more
+ */
+GCC_ONLY(__attribute__((__nonnull__)))
+void *ring_peek(struct ring *restrict this, size_t *restrict n);
+
+/**
+ * Dequeue data from a ring bubber
+ *
+ * @param this The ring buffer
+ * @param n The number of bytes to dequeue
+ */
+GCC_ONLY(__attribute__((__nonnull__)))
+void ring_pop(struct ring *restrict this, size_t n);
+
+/**
+ * Release resource allocated to a ring buffer
+ *
+ * @param this The ring buffer
+ */
+GCC_ONLY(__attribute__((__nonnull__)))
+static inline void
+ring_destroy(struct ring *restrict this)
+{
+ free(this->buffer);
+}
+
+/**
+ * Check whether there is more data waiting
+ * in a ring buffer
+ *
+ * @param this The ring buffer
+ * @return 1 if there is more data, 0 otherwise
+ */
+GCC_ONLY(__attribute__((__nonnull__)))
+static inline int
+ring_have_more(struct ring *restrict this)
+{
+ return !!this->buffer;
+}
+
+#endif