.iov_len = (len), \
}
+static inline struct iovec* iovec_shift(const struct iovec *iovec, size_t shift, struct iovec *ret) {
+ assert(iovec);
+ assert(ret);
+
+ /* This returns an empty iovec when 'shift' is larger or equals to the input iovec length.
+ * The 'iovec' and 'ret' can point to the same object. */
+
+ *ret = IOVEC_MAKE(iovec->iov_len > shift ? (uint8_t*) iovec->iov_base + shift : NULL,
+ LESS_BY(iovec->iov_len, shift));
+ return ret;
+}
+
+#define IOVEC_SHIFT(iov, shift) \
+ *iovec_shift(iov, shift, &(struct iovec){})
+
+static inline struct iovec* iovec_inc(struct iovec *iovec, size_t shift) {
+ return iovec_shift(iovec, shift, iovec);
+}
+
static inline void iovec_done(struct iovec *iovec) {
/* A _cleanup_() helper that frees the iov_base in the iovec */
assert(iovec);
#include "memory-util.h"
#include "tests.h"
+TEST(iovec_shift) {
+ const struct iovec iov = CONST_IOVEC_MAKE_STRING("54321");
+
+ ASSERT_EQ(iovec_memcmp(&IOVEC_SHIFT(&iov, 0), &CONST_IOVEC_MAKE_STRING("54321")), 0);
+ ASSERT_EQ(iovec_memcmp(&IOVEC_SHIFT(&iov, 1), &CONST_IOVEC_MAKE_STRING("4321")), 0);
+ ASSERT_EQ(iovec_memcmp(&IOVEC_SHIFT(&iov, 2), &CONST_IOVEC_MAKE_STRING("321")), 0);
+ ASSERT_EQ(iovec_memcmp(&IOVEC_SHIFT(&iov, 3), &CONST_IOVEC_MAKE_STRING("21")), 0);
+ ASSERT_EQ(iovec_memcmp(&IOVEC_SHIFT(&iov, 4), &CONST_IOVEC_MAKE_STRING("1")), 0);
+ ASSERT_FALSE(iovec_is_set(&IOVEC_SHIFT(&iov, 5)));
+ ASSERT_FALSE(iovec_is_set(&IOVEC_SHIFT(&iov, 6)));
+ ASSERT_FALSE(iovec_is_set(&IOVEC_SHIFT(&iov, 7)));
+
+ const struct iovec empty = {};
+ ASSERT_FALSE(iovec_is_set(&IOVEC_SHIFT(&empty, 0)));
+ ASSERT_FALSE(iovec_is_set(&IOVEC_SHIFT(&empty, 1)));
+}
+
+TEST(iovec_inc) {
+ struct iovec iov = IOVEC_MAKE_STRING("54321");
+
+ ASSERT_EQ(iovec_memcmp(iovec_inc(&iov, 0), &CONST_IOVEC_MAKE_STRING("54321")), 0);
+ ASSERT_EQ(iovec_memcmp(iovec_inc(&iov, 1), &CONST_IOVEC_MAKE_STRING("4321")), 0);
+ ASSERT_EQ(iovec_memcmp(iovec_inc(&iov, 1), &CONST_IOVEC_MAKE_STRING("321")), 0);
+ ASSERT_EQ(iovec_memcmp(iovec_inc(&iov, 1), &CONST_IOVEC_MAKE_STRING("21")), 0);
+ ASSERT_EQ(iovec_memcmp(iovec_inc(&iov, 1), &CONST_IOVEC_MAKE_STRING("1")), 0);
+ ASSERT_FALSE(iovec_is_set(iovec_inc(&iov, 1)));
+ ASSERT_FALSE(iovec_is_set(iovec_inc(&iov, 1)));
+ ASSERT_FALSE(iovec_is_set(iovec_inc(&iov, 1)));
+
+ struct iovec empty = {};
+ ASSERT_FALSE(iovec_is_set(iovec_inc(&empty, 0)));
+ ASSERT_FALSE(iovec_is_set(iovec_inc(&empty, 1)));
+}
+
TEST(iovec_memcmp) {
struct iovec iov1 = CONST_IOVEC_MAKE_STRING("abcdef"), iov2 = IOVEC_MAKE_STRING("bcdefg"), empty = {};