iovec-util: introduce IOVEC_SHIFT() macro and friends

This commit is contained in:
Yu Watanabe
2026-04-19 03:27:35 +09:00
parent 366e1d264a
commit 043358d852
2 changed files with 53 additions and 0 deletions
+19
View File
@@ -23,6 +23,25 @@ struct iovec {
.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);
+34
View File
@@ -4,6 +4,40 @@
#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 = {};