blob: 4ce6c0f0ca0c4711ee56604263e76dd051a4e897 [file] [log] [blame]
rjw1f884582022-01-06 17:20:42 +08001/*
2 * Copyright (c) 2014 Travis Geiselbrecht
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files
6 * (the "Software"), to deal in the Software without restriction,
7 * including without limitation the rights to use, copy, modify, merge,
8 * publish, distribute, sublicense, and/or sell copies of the Software,
9 * and to permit persons to whom the Software is furnished to do so,
10 * subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23#include <err.h>
24#include <debug.h>
25#include <assert.h>
26#include <string.h>
27#include <sys/types.h>
28
29#include <iovec.h>
30
31#define LOCAL_TRACE 0
32
33/*
34 * Calc total size of iovec buffers
35 */
36ssize_t iovec_size (const iovec_t *iov, uint iov_cnt)
37{
38 if (!iov)
39 return (ssize_t) ERR_INVALID_ARGS;
40
41 size_t c = 0;
42 for (uint i = 0; i < iov_cnt; i++, iov++) {
43 c += iov->iov_len;
44 }
45 return (ssize_t) c;
46}
47
48/*
49 * Copy out portion of iovec started from given position
50 * into single buffer
51 */
52ssize_t iovec_to_membuf (uint8_t *buf, uint buf_len, const iovec_t *iov, uint iov_cnt, uint iov_pos)
53{
54 uint buf_pos = 0;
55
56 if (!buf || !iov)
57 return (ssize_t) ERR_INVALID_ARGS;
58
59 /* for all iovec */
60 for (uint i = 0; i < iov_cnt; i++, iov++) {
61
62 if (iov_pos >= iov->iov_len) {
63 iov_pos -= iov->iov_len; /* skip whole chunks */
64 continue;
65 }
66
67 /* calc number of bytes left in current iov */
68 size_t to_copy = (size_t) (iov->iov_len - iov_pos);
69
70 /* limit it to number of bytes left in buffer */
71 if (to_copy > buf_len)
72 to_copy = buf_len;
73
74 /* copy data out */
75 memcpy (buf + buf_pos, (uint8_t *)iov->iov_base + iov_pos, to_copy);
76
77 /* advance in buffer position */
78 buf_pos += to_copy;
79 buf_len -= to_copy;
80
81 /* check if we need to copy more data */
82 if (buf_len == 0)
83 break;
84
85 iov_pos = 0; /* it is only possible to have fully copied iovec here */
86 }
87
88 return (ssize_t) buf_pos;
89}
90
91
92// vim: set ts=4 sw=4 noexpandtab: