basic/iovec-wrapper: add iovw_append and iovw_to_cstring

Existing iovw_append is renamed to iovw_append_iovw.
iovw_consume is made noninline.
This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2026-04-16 20:37:18 +02:00
parent 267b16f33c
commit f32af5c69a
3 changed files with 57 additions and 13 deletions
+52 -1
View File
@@ -41,6 +41,28 @@ int iovw_put(struct iovec_wrapper *iovw, void *data, size_t len) {
return 0;
}
int iovw_append(struct iovec_wrapper *iovw, const void *data, size_t len) {
if (len == 0)
return 0;
void *c = memdup(data, len);
if (!c)
return -ENOMEM;
return iovw_put(iovw, c, len);
}
int iovw_consume(struct iovec_wrapper *iovw, void *data, size_t len) {
/* Move data into iovw or free on error */
int r;
r = iovw_put(iovw, data, len);
if (r < 0)
free(data);
return r;
}
int iovw_put_string_field_full(struct iovec_wrapper *iovw, bool replace, const char *field, const char *value) {
_cleanup_free_ char *x = NULL;
int r;
@@ -103,7 +125,7 @@ size_t iovw_size(const struct iovec_wrapper *iovw) {
return iovec_total_size(iovw->iovec, iovw->count);
}
int iovw_append(struct iovec_wrapper *target, const struct iovec_wrapper *source) {
int iovw_append_iovw(struct iovec_wrapper *target, const struct iovec_wrapper *source) {
size_t original_count;
int r;
@@ -139,3 +161,32 @@ rollback:
target->count = original_count;
return r;
}
char* iovw_to_cstring(const struct iovec_wrapper *iovw) {
size_t size;
char *p, *ans;
assert(iovw);
/* Squish a series of iovecs into a C string. Embedded NULs are not allowed.
* The caller is expected to filter them out when populating the data. */
size = iovw_size(iovw);
if (size == SIZE_MAX)
return NULL; /* Prevent theoretical overflow */
size ++;
p = ans = new(char, size);
if (!ans)
return NULL;
FOREACH_ARRAY(iovec, iovw->iovec, iovw->count) {
assert(!memchr(iovec->iov_base, 0, iovec->iov_len));
p = mempcpy(p, iovec->iov_base, iovec->iov_len);
}
*p = '\0';
return ans;
}
+4 -11
View File
@@ -12,16 +12,8 @@ void iovw_done_free(struct iovec_wrapper *iovw);
void iovw_done(struct iovec_wrapper *iovw);
int iovw_put(struct iovec_wrapper *iovw, void *data, size_t len);
static inline int iovw_consume(struct iovec_wrapper *iovw, void *data, size_t len) {
/* Move data into iovw or free on error */
int r;
r = iovw_put(iovw, data, len);
if (r < 0)
free(data);
return r;
}
int iovw_append(struct iovec_wrapper *iovw, const void *data, size_t len);
int iovw_consume(struct iovec_wrapper *iovw, void *data, size_t len);
static inline bool iovw_isempty(const struct iovec_wrapper *iovw) {
return !iovw || iovw->count == 0;
@@ -40,4 +32,5 @@ int iovw_put_string_fieldf_full(struct iovec_wrapper *iovw, bool replace, const
int iovw_put_string_field_free(struct iovec_wrapper *iovw, const char *field, char *value);
void iovw_rebase(struct iovec_wrapper *iovw, void *old, void *new);
size_t iovw_size(const struct iovec_wrapper *iovw);
int iovw_append(struct iovec_wrapper *target, const struct iovec_wrapper *source);
int iovw_append_iovw(struct iovec_wrapper *target, const struct iovec_wrapper *source);
char* iovw_to_cstring(const struct iovec_wrapper *iovw);