• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * this code is taken from Michael - the qemu code is GPLv2 so I don't want
3  * to reuse it.
4  * I've adapted it to handle offsets and callback
5  */
6 
7 //
8 // iovec.c
9 //
10 // Scatter/gather utility routines
11 //
12 // Copyright (C) 2002 Michael Ringgaard. All rights reserved.
13 //
14 // Redistribution and use in source and binary forms, with or without
15 // modification, are permitted provided that the following conditions
16 // are met:
17 //
18 // 1. Redistributions of source code must retain the above copyright
19 //    notice, this list of conditions and the following disclaimer.
20 // 2. Redistributions in binary form must reproduce the above copyright
21 //    notice, this list of conditions and the following disclaimer in the
22 //    documentation and/or other materials provided with the distribution.
23 // 3. Neither the name of the project nor the names of its contributors
24 //    may be used to endorse or promote products derived from this software
25 //    without specific prior written permission.
26 //
27 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
28 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 // ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
31 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 // SUCH DAMAGE.
38 //
39 
40 #include <assert.h>
41 #include <string.h>
42 #include "vrend_iov.h"
43 
vrend_get_iovec_size(const struct iovec * iov,int iovlen)44 size_t vrend_get_iovec_size(const struct iovec *iov, int iovlen) {
45   size_t size = 0;
46 
47   while (iovlen > 0) {
48     size += iov->iov_len;
49     iov++;
50     iovlen--;
51   }
52 
53   return size;
54 }
55 
vrend_read_from_iovec(const struct iovec * iov,int iovlen,size_t offset,char * buf,size_t count)56 size_t vrend_read_from_iovec(const struct iovec *iov, int iovlen,
57 			     size_t offset,
58 			     char *buf, size_t count)
59 {
60   size_t read = 0;
61   size_t len;
62 
63   while (count > 0 && iovlen > 0) {
64     if (iov->iov_len > offset) {
65       len = iov->iov_len - offset;
66 
67       if (count < len) len = count;
68 
69       memcpy(buf, (char*)iov->iov_base + offset, len);
70       read += len;
71 
72       buf += len;
73       count -= len;
74       offset = 0;
75     } else {
76       offset -= iov->iov_len;
77     }
78 
79     iov++;
80     iovlen--;
81   }
82     assert(offset == 0);
83   return read;
84 }
85 
vrend_write_to_iovec(const struct iovec * iov,int iovlen,size_t offset,const char * buf,size_t count)86 size_t vrend_write_to_iovec(const struct iovec *iov, int iovlen,
87 			 size_t offset, const char *buf, size_t count)
88 {
89   size_t written = 0;
90   size_t len;
91 
92   while (count > 0 && iovlen > 0) {
93     if (iov->iov_len > offset) {
94       len = iov->iov_len - offset;
95 
96       if (count < len) len = count;
97 
98       memcpy((char*)iov->iov_base + offset, buf, len);
99       written += len;
100 
101       offset = 0;
102       buf += len;
103       count -= len;
104     } else {
105       offset -= iov->iov_len;
106     }
107     iov++;
108     iovlen--;
109   }
110     assert(offset == 0);
111   return written;
112 }
113 
vrend_read_from_iovec_cb(const struct iovec * iov,int iovlen,size_t offset,size_t count,iov_cb iocb,void * cookie)114 size_t vrend_read_from_iovec_cb(const struct iovec *iov, int iovlen,
115 				size_t offset, size_t count,
116 				iov_cb iocb, void *cookie)
117 {
118   size_t read = 0;
119   size_t len;
120 
121   while (count > 0 && iovlen > 0) {
122     if (iov->iov_len > offset) {
123       len = iov->iov_len - offset;
124 
125       if (count < len) len = count;
126 
127       (*iocb)(cookie, read, (char*)iov->iov_base + offset, len);
128       read += len;
129 
130       count -= len;
131       offset = 0;
132     } else {
133       offset -= iov->iov_len;
134     }
135     iov++;
136     iovlen--;
137   }
138     assert(offset == 0);
139   return read;
140 
141 
142 }
143