iovec-wrapper: introduce iovw_compare() and iovw_equal()

This commit is contained in:
Yu Watanabe
2026-04-19 05:51:01 +09:00
parent ce81c7dd74
commit a4e0f04157
3 changed files with 84 additions and 0 deletions
+22
View File
@@ -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);
+5
View File
@@ -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);
+57
View File
@@ -3,9 +3,66 @@
#include <sys/uio.h>
#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 = {};