00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef _lib_iovec_h_
00027 #define _lib_iovec_h_
00028
00029 #include "common.h"
00030
00035 static inline struct iovec *
00036 iov_alloc_n(size_t n)
00037 {
00038 struct iovec *iov;
00039
00040 if (n > (size_t) -1 / sizeof *iov) {
00041 g_assert_not_reached();
00042 return NULL;
00043 }
00044 iov = g_malloc(n * sizeof *iov);
00045 return iov;
00046 }
00047
00048 static inline struct iovec
00049 iov_get(gpointer base, size_t size)
00050 {
00051 static const struct iovec zero_iov;
00052 struct iovec iov;
00053
00054 iov = zero_iov;
00055 iov.iov_base = base;
00056 iov.iov_len = size;
00057 return iov;
00058 }
00059
00067 static inline void
00068 iov_reset_n(struct iovec *iov, size_t n)
00069 {
00070 size_t i;
00071
00072 g_assert(iov);
00073 for (i = 0; i < n; i++) {
00074 static const struct iovec zero_iov;
00075 iov[i] = zero_iov;
00076 }
00077 }
00078
00089 static inline size_t
00090 iov_init_from_string_vector(struct iovec *iov, size_t iov_cnt,
00091 gchar *argv[], size_t argc)
00092 {
00093 size_t i, n;
00094
00095 g_assert(iov);
00096 g_assert(iov_cnt >= argc);
00097 g_assert(argv);
00098
00099 n = MIN(iov_cnt, argc);
00100 for (i = 0; i < n; i++) {
00101 iov[i].iov_base = argv[i];
00102 iov[i].iov_len = argv[i] ? (1 + strlen(argv[i])) : 0;
00103 }
00104 return n;
00105 }
00106
00112 static inline gboolean
00113 iov_is_contiguous(const struct iovec * const a, const struct iovec * const b)
00114 {
00115 g_assert(a);
00116 g_assert(b);
00117
00118 return (size_t) a->iov_base + a->iov_len == (size_t) b->iov_base;
00119 }
00120
00128 static inline size_t
00129 iov_contiguous_size(const struct iovec *iov, size_t iov_cnt)
00130 {
00131 struct iovec iov0;
00132 size_t i;
00133
00134 g_assert(iov);
00135
00136 iov0 = iov[0];
00137
00138 for (i = 1; i < iov_cnt && iov_is_contiguous(&iov0, &iov[i]); i++) {
00139 size_t n = iov[i].iov_len;
00140
00141 if (n >= (size_t) -1 - iov0.iov_len) {
00142
00143 iov0.iov_len = (size_t) -1;
00144 break;
00145 }
00146 iov0.iov_len += n;
00147 }
00148 return iov0.iov_len;
00149 }
00150
00158 static inline void
00159 iov_clear(struct iovec *iov, size_t byte_offset)
00160 {
00161 g_assert(iov);
00162
00163 if (byte_offset < iov->iov_len) {
00164 gchar *p = iov->iov_base;
00165 memset(&p[byte_offset], 0, iov->iov_len - byte_offset);
00166 }
00167 }
00168
00177 static inline size_t
00178 iov_calculate_size(struct iovec *iov, size_t iov_cnt)
00179 {
00180 size_t size = 0;
00181 size_t i;
00182
00183 g_assert(iov);
00184
00185 for (i = 0; i < iov_cnt; i++) {
00186 size_t n = iov[i].iov_len;
00187
00188 if (n >= (size_t) -1 - size) {
00189
00190 size = (size_t) -1;
00191 break;
00192 }
00193 size += n;
00194 }
00195 return size;
00196 }
00197
00208 static inline size_t
00209 iov_scatter_string(struct iovec *iov, size_t iov_cnt, const gchar *s)
00210 {
00211 size_t i, len, avail, size;
00212
00213 g_assert(iov);
00214 g_assert(s);
00215
00216
00217 size = iov_calculate_size(iov, iov_cnt);
00218 len = strlen(s);
00219 if (len >= size) {
00220 len = size > 0 ? (size - 1) : 0;
00221 }
00222 avail = len;
00223
00224 for (i = 0; i < iov_cnt; i++) {
00225 size_t n;
00226
00227 n = MIN(iov[i].iov_len, avail);
00228 memmove(iov[i].iov_base, s, n);
00229 avail -= n;
00230 s += n;
00231 if (0 == avail) {
00232 iov_clear(&iov[i], n);
00233 i++;
00234 break;
00235 }
00236 }
00237 while (i < iov_cnt) {
00238 iov_clear(&iov[i], 0);
00239 i++;
00240 }
00241 return len;
00242 }
00243
00244 #endif
00245