xref: /spdk/lib/util/iov.c (revision 94a84ae98590bea46939eb1dcd7a9876bd393b54)
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