diff options
Diffstat (limited to '')
-rw-r--r-- | src/basic/iovec-util.h | 69 |
1 files changed, 62 insertions, 7 deletions
diff --git a/src/basic/iovec-util.h b/src/basic/iovec-util.h index 39feabd..8cfa571 100644 --- a/src/basic/iovec-util.h +++ b/src/basic/iovec-util.h @@ -8,16 +8,38 @@ #include "alloc-util.h" #include "macro.h" +/* An iovec pointing to a single NUL byte */ +#define IOVEC_NUL_BYTE (const struct iovec) { \ + .iov_base = (void*) (const uint8_t[1]) { 0 }, \ + .iov_len = 1, \ + } + size_t iovec_total_size(const struct iovec *iovec, size_t n); bool iovec_increment(struct iovec *iovec, size_t n, size_t k); -#define IOVEC_MAKE(base, len) (struct iovec) { .iov_base = (base), .iov_len = (len) } -#define IOVEC_MAKE_STRING(string) \ - ({ \ - const char *_s = (string); \ - IOVEC_MAKE((char*) _s, strlen(_s)); \ - }) +/* This accepts both const and non-const pointers */ +#define IOVEC_MAKE(base, len) \ + (struct iovec) { \ + .iov_base = (void*) (base), \ + .iov_len = (len), \ + } + +static inline struct iovec* iovec_make_string(struct iovec *iovec, const char *s) { + assert(iovec); + /* We don't use strlen_ptr() here, because we don't want to include string-util.h for now */ + *iovec = IOVEC_MAKE(s, s ? strlen(s) : 0); + return iovec; +} + +#define IOVEC_MAKE_STRING(s) \ + *iovec_make_string(&(struct iovec) {}, s) + +#define CONST_IOVEC_MAKE_STRING(s) \ + (const struct iovec) { \ + .iov_base = (char*) s, \ + .iov_len = STRLEN(s), \ + } static inline void iovec_done(struct iovec *iovec) { /* A _cleanup_() helper that frees the iov_base in the iovec */ @@ -35,10 +57,43 @@ static inline void iovec_done_erase(struct iovec *iovec) { } static inline bool iovec_is_set(const struct iovec *iovec) { + /* Checks if the iovec points to a non-empty chunk of memory */ return iovec && iovec->iov_len > 0 && iovec->iov_base; } +static inline bool iovec_is_valid(const struct iovec *iovec) { + /* Checks if the iovec is either NULL, empty or points to a valid bit of memory */ + return !iovec || (iovec->iov_base || iovec->iov_len == 0); +} + char* set_iovec_string_field(struct iovec *iovec, size_t *n_iovec, const char *field, const char *value); char* set_iovec_string_field_free(struct iovec *iovec, size_t *n_iovec, const char *field, char *value); -void iovec_array_free(struct iovec *iovec, size_t n); +void iovec_array_free(struct iovec *iovec, size_t n_iovec); + +static inline int iovec_memcmp(const struct iovec *a, const struct iovec *b) { + + if (a == b) + return 0; + + return memcmp_nn(a ? a->iov_base : NULL, + a ? a->iov_len : 0, + b ? b->iov_base : NULL, + b ? b->iov_len : 0); +} + +static inline struct iovec *iovec_memdup(const struct iovec *source, struct iovec *ret) { + assert(ret); + + if (!iovec_is_set(source)) + *ret = (struct iovec) {}; + else { + void *p = memdup(source->iov_base, source->iov_len); + if (!p) + return NULL; + + *ret = IOVEC_MAKE(p, source->iov_len); + } + + return ret; +} |