From: Yu Watanabe Date: Fri, 17 Apr 2026 13:53:56 +0000 (+0900) Subject: iovec-wrapper: introduce iovw_compare() and iovw_equal() X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a4e0f041570f5f4fb6b486ab1fff99c839a9d73f;p=thirdparty%2Fsystemd.git iovec-wrapper: introduce iovw_compare() and iovw_equal() --- diff --git a/src/basic/iovec-wrapper.c b/src/basic/iovec-wrapper.c index 2b302b96ab0..a76087b859e 100644 --- a/src/basic/iovec-wrapper.c +++ b/src/basic/iovec-wrapper.c @@ -23,6 +23,28 @@ void iovw_done_free(struct iovec_wrapper *iovw) { iovw_done(iovw); } +int iovw_compare(const struct iovec_wrapper *a, const struct iovec_wrapper *b) { + int r; + + if (a == b) + return 0; + + if (!a || !b) + return CMP(!!a, !!b); + + /* Note, this performs structural (element-by-element) comparison, not content-based comparison. + * Two wrappers with identical concatenated content but different element boundaries + * (e.g., ["fo","o"] vs ["f","oo"]) will not compare as equal. */ + + for (size_t i = 0, n = MIN(a->count, b->count); i < n; i++) { + r = iovec_memcmp(a->iovec + i, b->iovec + i); + if (r != 0) + return r; + } + + return CMP(a->count, b->count); +} + int iovw_put(struct iovec_wrapper *iovw, void *data, size_t len) { assert(iovw); diff --git a/src/basic/iovec-wrapper.h b/src/basic/iovec-wrapper.h index eaa859af06d..d2437b60f19 100644 --- a/src/basic/iovec-wrapper.h +++ b/src/basic/iovec-wrapper.h @@ -11,6 +11,11 @@ struct iovec_wrapper { void iovw_done_free(struct iovec_wrapper *iovw); void iovw_done(struct iovec_wrapper *iovw); +int iovw_compare(const struct iovec_wrapper *a, const struct iovec_wrapper *b) _pure_; +static inline bool iovw_equal(const struct iovec_wrapper *a, const struct iovec_wrapper *b) { + return iovw_compare(a, b) == 0; +} + int iovw_put(struct iovec_wrapper *iovw, void *data, size_t len); int iovw_consume(struct iovec_wrapper *iovw, void *data, size_t len); int iovw_append(struct iovec_wrapper *iovw, const void *data, size_t len); diff --git a/src/test/test-iovec-wrapper.c b/src/test/test-iovec-wrapper.c index 1f4585a129f..168217f16c2 100644 --- a/src/test/test-iovec-wrapper.c +++ b/src/test/test-iovec-wrapper.c @@ -3,9 +3,66 @@ #include #include "alloc-util.h" +#include "iovec-util.h" #include "iovec-wrapper.h" #include "tests.h" +TEST(iovw_compare) { + _cleanup_(iovw_done) struct iovec_wrapper a1 = {}, a2 = {}, b = {}, c = {}, d = {}, e = {}; + + ASSERT_OK(iovw_put(&a1, (char*) "foo", 3)); + ASSERT_OK(iovw_put(&a1, (char*) "aaaaa", 5)); + + ASSERT_OK(iovw_put(&a2, (char*) "foo", 3)); + ASSERT_OK(iovw_put(&a2, (char*) "aaaaa", 5)); + + ASSERT_OK(iovw_put(&b, (char*) "foo", 3)); + ASSERT_OK(iovw_put(&b, (char*) "bbbbb", 5)); + + ASSERT_OK(iovw_put(&c, (char*) "foo", 3)); + + ASSERT_OK(iovw_put(&d, (char*) "fooaa", 5)); + ASSERT_OK(iovw_put(&d, (char*) "aaa", 3)); + + ASSERT_EQ(iovw_compare(&a1, &a1), 0); + ASSERT_EQ(iovw_compare(&a1, &a2), 0); + ASSERT_EQ(iovw_compare(&a2, &a1), 0); + ASSERT_LT(iovw_compare(&a1, &b), 0); + ASSERT_GT(iovw_compare(&b, &a1), 0); + ASSERT_EQ(iovw_compare(&b, &b), 0); + ASSERT_GT(iovw_compare(&a1, &c), 0); + ASSERT_LT(iovw_compare(&c, &a1), 0); + ASSERT_EQ(iovw_compare(&c, &c), 0); + ASSERT_LT(iovw_compare(&a1, &d), 0); + ASSERT_GT(iovw_compare(&d, &a1), 0); + ASSERT_EQ(iovw_compare(&d, &d), 0); + ASSERT_GT(iovw_compare(&a1, &e), 0); + ASSERT_LT(iovw_compare(&e, &a1), 0); + ASSERT_EQ(iovw_compare(&e, &e), 0); + ASSERT_GT(iovw_compare(&a1, NULL), 0); + ASSERT_LT(iovw_compare(NULL, &a1), 0); + ASSERT_EQ(iovw_compare(NULL, NULL), 0); + + ASSERT_TRUE(iovw_equal(&a1, &a1)); + ASSERT_TRUE(iovw_equal(&a1, &a2)); + ASSERT_TRUE(iovw_equal(&a2, &a1)); + ASSERT_FALSE(iovw_equal(&a1, &b)); + ASSERT_FALSE(iovw_equal(&b, &a1)); + ASSERT_TRUE(iovw_equal(&b, &b)); + ASSERT_FALSE(iovw_equal(&a1, &c)); + ASSERT_FALSE(iovw_equal(&c, &a1)); + ASSERT_TRUE(iovw_equal(&c, &c)); + ASSERT_FALSE(iovw_equal(&a1, &d)); + ASSERT_FALSE(iovw_equal(&d, &a1)); + ASSERT_TRUE(iovw_equal(&d, &d)); + ASSERT_FALSE(iovw_equal(&a1, &e)); + ASSERT_FALSE(iovw_equal(&e, &a1)); + ASSERT_TRUE(iovw_equal(&e, &e)); + ASSERT_FALSE(iovw_equal(&a1, NULL)); + ASSERT_FALSE(iovw_equal(NULL, &a1)); + ASSERT_TRUE(iovw_equal(NULL, NULL)); +} + TEST(iovw_put) { _cleanup_(iovw_done) struct iovec_wrapper iovw = {};