1 /* Copyright (c) 2016 Google Inc
2 * Barret Rhoden <brho@cs.berkeley.edu>
3 * See LICENSE for details.
5 * Various utility functions. */
7 #include <parlib/iovec.h>
11 /* Strips bytes from the front of the iovec. This modifies the base and
12 * length of the iovecs in the array. */
13 void iov_strip_bytes(struct iovec *iov, int iovcnt, size_t amt)
15 for (int i = 0; i < iovcnt; i++) {
16 if (iov[i].iov_len <= amt) {
17 amt -= iov[i].iov_len;
21 iov[i].iov_len -= amt;
22 iov[i].iov_base += amt;
27 /* Drops bytes from the end of the iovec. This modified the length of the
28 * iovecs in the array. */
29 void iov_drop_trailing_bytes(struct iovec *iov, int iovcnt, size_t amt)
31 for (int i = iovcnt - 1; i >= 0; i--) {
32 if (iov[i].iov_len <= amt) {
33 amt -= iov[i].iov_len;
37 iov[i].iov_len -= amt;
42 /* Trims the iov's length to new_len, modifying the iov_lens. If the iov is
43 * shorter than new_len, it will not grow. */
44 void iov_trim_len_to(struct iovec *iov, int iovcnt, size_t new_len)
46 for (int i = 0; i < iovcnt; i++) {
47 if (iov[i].iov_len <= new_len) {
48 new_len -= iov[i].iov_len;
51 iov[i].iov_len = new_len;
56 /* Checks if iov has amt bytes in it. */
57 bool iov_has_bytes(struct iovec *iov, int iovcnt, size_t amt)
59 for (int i = 0; i < iovcnt; i++) {
60 if (iov[i].iov_len >= amt)
62 amt -= iov[i].iov_len;
67 size_t iov_get_len(struct iovec *iov, int iovcnt)
71 for (int i = 0; i < iovcnt; i++)
72 ret += iov[i].iov_len;
76 /* Copies up to len bytes of the contents of IOV into buf. */
77 void iov_linearize(struct iovec *iov, int iovcnt, uint8_t *buf, size_t len)
82 for (int i = 0; i < iovcnt; i++) {
85 copy_amt = MIN(iov[i].iov_len, len);
86 memcpy(buf + sofar, iov[i].iov_base, copy_amt);
92 /* Sets a byte in an iov, essentially iov_mem[idx] = val. */
93 void iov_set_byte(struct iovec *iov, int iovcnt, size_t idx, uint8_t val)
97 for (int i = 0; i < iovcnt; i++) {
98 if (iov[i].iov_len <= idx) {
99 idx -= iov[i].iov_len;
102 p = iov[i].iov_base + idx;
109 /* Sets a byte in an iov, essentially *val = iov_mem[idx]. */
110 uint8_t iov_get_byte(struct iovec *iov, int iovcnt, size_t idx)
114 for (int i = 0; i < iovcnt; i++) {
115 if (iov[i].iov_len <= idx) {
116 idx -= iov[i].iov_len;
119 p = iov[i].iov_base + idx;
126 void iov_memcpy_from(struct iovec *iov, int iovcnt, size_t from,
127 void *to, size_t amt)
133 for (int i = 0; i < iovcnt; i++) {
136 if (iov[i].iov_len <= from) {
137 from -= iov[i].iov_len;
140 copy_start = iov[i].iov_base + from;
141 copy_amt = iov[i].iov_len - from;
143 copy_amt = MIN(copy_amt, amt);
144 memcpy(to + sofar, copy_start, copy_amt);
151 void iov_memcpy_to(struct iovec *iov, int iovcnt, size_t to,
152 void *from, size_t amt)
158 for (int i = 0; i < iovcnt; i++) {
161 if (iov[i].iov_len <= to) {
162 to -= iov[i].iov_len;
165 copy_start = iov[i].iov_base + to;
166 copy_amt = iov[i].iov_len - to;
168 copy_amt = MIN(copy_amt, amt);
169 memcpy(copy_start, from + sofar, copy_amt);
176 uint16_t iov_get_be16(struct iovec *iov, int iovcnt, size_t idx)
178 return ((uint16_t)iov_get_byte(iov, iovcnt, idx + 0) << 8)
179 | ((uint16_t)iov_get_byte(iov, iovcnt, idx + 1) << 0);
182 uint16_t iov_get_be32(struct iovec *iov, int iovcnt, size_t idx)
184 return ((uint32_t)iov_get_byte(iov, iovcnt, idx + 0) << 24)
185 | ((uint32_t)iov_get_byte(iov, iovcnt, idx + 1) << 16)
186 | ((uint32_t)iov_get_byte(iov, iovcnt, idx + 2) << 8)
187 | ((uint32_t)iov_get_byte(iov, iovcnt, idx + 3) << 0);
190 void iov_put_be16(struct iovec *iov, int iovcnt, size_t idx, uint16_t val)
192 iov_set_byte(iov, iovcnt, idx + 0, (val >> 8) & 0xff);
193 iov_set_byte(iov, iovcnt, idx + 1, (val >> 0) & 0xff);
196 void iov_put_be32(struct iovec *iov, int iovcnt, size_t idx, uint32_t val)
198 iov_set_byte(iov, iovcnt, idx + 0, (val >> 24) & 0xff);
199 iov_set_byte(iov, iovcnt, idx + 1, (val >> 16) & 0xff);
200 iov_set_byte(iov, iovcnt, idx + 2, (val >> 8) & 0xff);
201 iov_set_byte(iov, iovcnt, idx + 3, (val >> 0) & 0xff);