1 /*- 2 * BSD LICENSE 3 * 4 * Copyright (c) Intel Corporation. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Intel Corporation nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include "spdk/util.h" 35 36 size_t 37 spdk_iovcpy(struct iovec *siov, size_t siovcnt, struct iovec *diov, size_t diovcnt) 38 { 39 size_t total_sz; 40 size_t sidx; 41 size_t didx; 42 int siov_len; 43 uint8_t *siov_base; 44 int diov_len; 45 uint8_t *diov_base; 46 47 /* d prefix = destination. s prefix = source. */ 48 49 assert(diovcnt > 0); 50 assert(siovcnt > 0); 51 52 total_sz = 0; 53 sidx = 0; 54 didx = 0; 55 siov_len = siov[0].iov_len; 56 siov_base = siov[0].iov_base; 57 diov_len = diov[0].iov_len; 58 diov_base = diov[0].iov_base; 59 while (siov_len > 0 && diov_len > 0) { 60 if (siov_len == diov_len) { 61 memcpy(diov_base, siov_base, siov_len); 62 total_sz += siov_len; 63 64 /* Advance both iovs to the next element */ 65 sidx++; 66 if (sidx == siovcnt) { 67 break; 68 } 69 70 didx++; 71 if (didx == diovcnt) { 72 break; 73 } 74 75 siov_len = siov[sidx].iov_len; 76 siov_base = siov[sidx].iov_base; 77 diov_len = diov[didx].iov_len; 78 diov_base = diov[didx].iov_base; 79 } else if (siov_len < diov_len) { 80 memcpy(diov_base, siov_base, siov_len); 81 total_sz += siov_len; 82 83 /* Advance only the source to the next element */ 84 sidx++; 85 if (sidx == siovcnt) { 86 break; 87 } 88 89 diov_base += siov_len; 90 diov_len -= siov_len; 91 siov_len = siov[sidx].iov_len; 92 siov_base = siov[sidx].iov_base; 93 } else { 94 memcpy(diov_base, siov_base, diov_len); 95 total_sz += diov_len; 96 97 /* Advance only the destination to the next element */ 98 didx++; 99 if (didx == diovcnt) { 100 break; 101 } 102 103 siov_base += diov_len; 104 siov_len -= diov_len; 105 diov_len = diov[didx].iov_len; 106 diov_base = diov[didx].iov_base; 107 } 108 } 109 110 return total_sz; 111 } 112