1
2
3
4
5
6
7
8
9
10
11
12
13
14#ifndef IOV_H
15#define IOV_H
16
17
18
19
20
21size_t iov_size(const struct iovec *iov, const unsigned int iov_cnt);
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40size_t iov_from_buf_full(const struct iovec *iov, unsigned int iov_cnt,
41 size_t offset, const void *buf, size_t bytes);
42size_t iov_to_buf_full(const struct iovec *iov, const unsigned int iov_cnt,
43 size_t offset, void *buf, size_t bytes);
44
45static inline size_t
46iov_from_buf(const struct iovec *iov, unsigned int iov_cnt,
47 size_t offset, const void *buf, size_t bytes)
48{
49 if (__builtin_constant_p(bytes) && iov_cnt &&
50 offset <= iov[0].iov_len && bytes <= iov[0].iov_len - offset) {
51 memcpy(iov[0].iov_base + offset, buf, bytes);
52 return bytes;
53 } else {
54 return iov_from_buf_full(iov, iov_cnt, offset, buf, bytes);
55 }
56}
57
58static inline size_t
59iov_to_buf(const struct iovec *iov, const unsigned int iov_cnt,
60 size_t offset, void *buf, size_t bytes)
61{
62 if (__builtin_constant_p(bytes) && iov_cnt &&
63 offset <= iov[0].iov_len && bytes <= iov[0].iov_len - offset) {
64 memcpy(buf, iov[0].iov_base + offset, bytes);
65 return bytes;
66 } else {
67 return iov_to_buf_full(iov, iov_cnt, offset, buf, bytes);
68 }
69}
70
71
72
73
74
75
76
77
78
79
80
81size_t iov_memset(const struct iovec *iov, const unsigned int iov_cnt,
82 size_t offset, int fillc, size_t bytes);
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102ssize_t iov_send_recv(int sockfd, const struct iovec *iov, unsigned iov_cnt,
103 size_t offset, size_t bytes, bool do_send);
104#define iov_recv(sockfd, iov, iov_cnt, offset, bytes) \
105 iov_send_recv(sockfd, iov, iov_cnt, offset, bytes, false)
106#define iov_send(sockfd, iov, iov_cnt, offset, bytes) \
107 iov_send_recv(sockfd, iov, iov_cnt, offset, bytes, true)
108
109
110
111
112
113
114void iov_hexdump(const struct iovec *iov, const unsigned int iov_cnt,
115 FILE *fp, const char *prefix, size_t limit);
116
117
118
119
120
121
122unsigned iov_copy(struct iovec *dst_iov, unsigned int dst_iov_cnt,
123 const struct iovec *iov, unsigned int iov_cnt,
124 size_t offset, size_t bytes);
125
126
127
128
129
130
131
132
133
134size_t iov_discard_front(struct iovec **iov, unsigned int *iov_cnt,
135 size_t bytes);
136size_t iov_discard_back(struct iovec *iov, unsigned int *iov_cnt,
137 size_t bytes);
138
139typedef struct QEMUIOVector {
140 struct iovec *iov;
141 int niov;
142 int nalloc;
143 size_t size;
144} QEMUIOVector;
145
146void qemu_iovec_init(QEMUIOVector *qiov, int alloc_hint);
147void qemu_iovec_init_external(QEMUIOVector *qiov, struct iovec *iov, int niov);
148void qemu_iovec_add(QEMUIOVector *qiov, void *base, size_t len);
149void qemu_iovec_concat(QEMUIOVector *dst,
150 QEMUIOVector *src, size_t soffset, size_t sbytes);
151size_t qemu_iovec_concat_iov(QEMUIOVector *dst,
152 struct iovec *src_iov, unsigned int src_cnt,
153 size_t soffset, size_t sbytes);
154bool qemu_iovec_is_zero(QEMUIOVector *qiov);
155void qemu_iovec_destroy(QEMUIOVector *qiov);
156void qemu_iovec_reset(QEMUIOVector *qiov);
157size_t qemu_iovec_to_buf(QEMUIOVector *qiov, size_t offset,
158 void *buf, size_t bytes);
159size_t qemu_iovec_from_buf(QEMUIOVector *qiov, size_t offset,
160 const void *buf, size_t bytes);
161size_t qemu_iovec_memset(QEMUIOVector *qiov, size_t offset,
162 int fillc, size_t bytes);
163ssize_t qemu_iovec_compare(QEMUIOVector *a, QEMUIOVector *b);
164void qemu_iovec_clone(QEMUIOVector *dest, const QEMUIOVector *src, void *buf);
165void qemu_iovec_discard_back(QEMUIOVector *qiov, size_t bytes);
166
167#endif
168