2 * Helpers for using (partial) iovecs.
4 * Copyright (C) 2010 Red Hat, Inc.
7 * Amit Shah <amit.shah@redhat.com>
8 * Michael Tokarev <mjt@tls.msk.ru>
10 * This work is licensed under the terms of the GNU GPL, version 2. See
11 * the COPYING file in the top-level directory.
18 * count and return data size, in bytes, of an iovec
19 * starting at `iov' of `iov_cnt' number of elements.
21 size_t iov_size(const struct iovec
*iov
, const unsigned int iov_cnt
);
24 * Copy from single continuous buffer to scatter-gather vector of buffers
25 * (iovec) and back like memcpy() between two continuous memory regions.
26 * Data in single continuous buffer starting at address `buf' and
27 * `bytes' bytes long will be copied to/from an iovec `iov' with
28 * `iov_cnt' number of elements, starting at byte position `offset'
29 * within the iovec. If the iovec does not contain enough space,
30 * only part of data will be copied, up to the end of the iovec.
31 * Number of bytes actually copied will be returned, which is
32 * min(bytes, iov_size(iov)-offset)
33 * `Offset' must point to the inside of iovec.
35 size_t iov_from_buf_full(const struct iovec
*iov
, unsigned int iov_cnt
,
36 size_t offset
, const void *buf
, size_t bytes
);
37 size_t iov_to_buf_full(const struct iovec
*iov
, const unsigned int iov_cnt
,
38 size_t offset
, void *buf
, size_t bytes
);
41 iov_from_buf(const struct iovec
*iov
, unsigned int iov_cnt
,
42 size_t offset
, const void *buf
, size_t bytes
)
44 if (__builtin_constant_p(bytes
) && iov_cnt
&&
45 offset
<= iov
[0].iov_len
&& bytes
<= iov
[0].iov_len
- offset
) {
46 memcpy(iov
[0].iov_base
+ offset
, buf
, bytes
);
49 return iov_from_buf_full(iov
, iov_cnt
, offset
, buf
, bytes
);
54 iov_to_buf(const struct iovec
*iov
, const unsigned int iov_cnt
,
55 size_t offset
, void *buf
, size_t bytes
)
57 if (__builtin_constant_p(bytes
) && iov_cnt
&&
58 offset
<= iov
[0].iov_len
&& bytes
<= iov
[0].iov_len
- offset
) {
59 memcpy(buf
, iov
[0].iov_base
+ offset
, bytes
);
62 return iov_to_buf_full(iov
, iov_cnt
, offset
, buf
, bytes
);
67 * Set data bytes pointed out by iovec `iov' of size `iov_cnt' elements,
68 * starting at byte offset `start', to value `fillc', repeating it
69 * `bytes' number of times. `Offset' must point to the inside of iovec.
70 * If `bytes' is large enough, only last bytes portion of iovec,
71 * up to the end of it, will be filled with the specified value.
72 * Function return actual number of bytes processed, which is
73 * min(size, iov_size(iov) - offset).
75 size_t iov_memset(const struct iovec
*iov
, const unsigned int iov_cnt
,
76 size_t offset
, int fillc
, size_t bytes
);
79 * Send/recv data from/to iovec buffers directly
81 * `offset' bytes in the beginning of iovec buffer are skipped and
82 * next `bytes' bytes are used, which must be within data of iovec.
84 * r = iov_send_recv(sockfd, iov, iovcnt, offset, bytes, true);
86 * is logically equivalent to
88 * char *buf = malloc(bytes);
89 * iov_to_buf(iov, iovcnt, offset, buf, bytes);
90 * r = send(sockfd, buf, bytes, 0);
93 * For iov_send_recv() _whole_ area being sent or received
94 * should be within the iovec, not only beginning of it.
96 ssize_t
iov_send_recv(int sockfd
, const struct iovec
*iov
, unsigned iov_cnt
,
97 size_t offset
, size_t bytes
, bool do_send
);
98 #define iov_recv(sockfd, iov, iov_cnt, offset, bytes) \
99 iov_send_recv(sockfd, iov, iov_cnt, offset, bytes, false)
100 #define iov_send(sockfd, iov, iov_cnt, offset, bytes) \
101 iov_send_recv(sockfd, iov, iov_cnt, offset, bytes, true)
104 * Produce a text hexdump of iovec `iov' with `iov_cnt' number of elements
105 * in file `fp', prefixing each line with `prefix' and processing not more
106 * than `limit' data bytes.
108 void iov_hexdump(const struct iovec
*iov
, const unsigned int iov_cnt
,
109 FILE *fp
, const char *prefix
, size_t limit
);
112 * Partial copy of vector from iov to dst_iov (data is not copied).
113 * dst_iov overlaps iov at a specified offset.
114 * size of dst_iov is at most bytes. dst vector count is returned.
116 unsigned iov_copy(struct iovec
*dst_iov
, unsigned int dst_iov_cnt
,
117 const struct iovec
*iov
, unsigned int iov_cnt
,
118 size_t offset
, size_t bytes
);
121 * Remove a given number of bytes from the front or back of a vector.
122 * This may update iov and/or iov_cnt to exclude iovec elements that are
123 * no longer required.
125 * The number of bytes actually discarded is returned. This number may be
126 * smaller than requested if the vector is too small.
128 size_t iov_discard_front(struct iovec
**iov
, unsigned int *iov_cnt
,
130 size_t iov_discard_back(struct iovec
*iov
, unsigned int *iov_cnt
,
133 typedef struct QEMUIOVector
{
140 void qemu_iovec_init(QEMUIOVector
*qiov
, int alloc_hint
);
141 void qemu_iovec_init_external(QEMUIOVector
*qiov
, struct iovec
*iov
, int niov
);
142 void qemu_iovec_add(QEMUIOVector
*qiov
, void *base
, size_t len
);
143 void qemu_iovec_concat(QEMUIOVector
*dst
,
144 QEMUIOVector
*src
, size_t soffset
, size_t sbytes
);
145 size_t qemu_iovec_concat_iov(QEMUIOVector
*dst
,
146 struct iovec
*src_iov
, unsigned int src_cnt
,
147 size_t soffset
, size_t sbytes
);
148 bool qemu_iovec_is_zero(QEMUIOVector
*qiov
);
149 void qemu_iovec_destroy(QEMUIOVector
*qiov
);
150 void qemu_iovec_reset(QEMUIOVector
*qiov
);
151 size_t qemu_iovec_to_buf(QEMUIOVector
*qiov
, size_t offset
,
152 void *buf
, size_t bytes
);
153 size_t qemu_iovec_from_buf(QEMUIOVector
*qiov
, size_t offset
,
154 const void *buf
, size_t bytes
);
155 size_t qemu_iovec_memset(QEMUIOVector
*qiov
, size_t offset
,
156 int fillc
, size_t bytes
);
157 ssize_t
qemu_iovec_compare(QEMUIOVector
*a
, QEMUIOVector
*b
);
158 void qemu_iovec_clone(QEMUIOVector
*dest
, const QEMUIOVector
*src
, void *buf
);
159 void qemu_iovec_discard_back(QEMUIOVector
*qiov
, size_t bytes
);