1// Copyright 2016 The Fuchsia Authors 2// Copyright (c) 2014 Travis Geiselbrecht 3// 4// Use of this source code is governed by a MIT-style 5// license that can be found in the LICENSE file or at 6// https://opensource.org/licenses/MIT 7 8#include <err.h> 9#include <debug.h> 10#include <assert.h> 11#include <string.h> 12#include <sys/types.h> 13 14#include <iovec.h> 15 16#define LOCAL_TRACE 0 17 18/* 19 * Calc total size of iovec buffers 20 */ 21ssize_t iovec_size (const iovec_t *iov, uint iov_cnt) 22{ 23 if (!iov) 24 return (ssize_t) ZX_ERR_INVALID_ARGS; 25 26 size_t c = 0; 27 for (uint i = 0; i < iov_cnt; i++, iov++) { 28 c += iov->iov_len; 29 } 30 return (ssize_t) c; 31} 32 33/* 34 * Copy out portion of iovec started from given position 35 * into single buffer 36 */ 37ssize_t iovec_to_membuf (uint8_t *buf, uint buf_len, const iovec_t *iov, uint iov_cnt, uint iov_pos) 38{ 39 uint buf_pos = 0; 40 41 if (!buf || !iov) 42 return (ssize_t) ZX_ERR_INVALID_ARGS; 43 44 /* for all iovec */ 45 for (uint i = 0; i < iov_cnt; i++, iov++) { 46 47 if (iov_pos >= iov->iov_len) { 48 iov_pos -= iov->iov_len; /* skip whole chunks */ 49 continue; 50 } 51 52 /* calc number of bytes left in current iov */ 53 size_t to_copy = (size_t) (iov->iov_len - iov_pos); 54 55 /* limit it to number of bytes left in buffer */ 56 if (to_copy > buf_len) 57 to_copy = buf_len; 58 59 /* copy data out */ 60 memcpy (buf + buf_pos, (uint8_t *)iov->iov_base + iov_pos, to_copy); 61 62 /* advance in buffer position */ 63 buf_pos += to_copy; 64 buf_len -= to_copy; 65 66 /* check if we need to copy more data */ 67 if (buf_len == 0) 68 break; 69 70 iov_pos = 0; /* it is only possible to have fully copied iovec here */ 71 } 72 73 return (ssize_t) buf_pos; 74} 75