allow qemu_iovec_from_buffer() to specify offset from which to start copying
[qemu/ar7.git] / iov.c
blob9657d286b852396348bde1cfd35375dc20f2e4bd
1 /*
2 * Helpers for getting linearized buffers from iov / filling buffers into iovs
4 * Copyright IBM, Corp. 2007, 2008
5 * Copyright (C) 2010 Red Hat, Inc.
7 * Author(s):
8 * Anthony Liguori <aliguori@us.ibm.com>
9 * Amit Shah <amit.shah@redhat.com>
10 * Michael Tokarev <mjt@tls.msk.ru>
12 * This work is licensed under the terms of the GNU GPL, version 2. See
13 * the COPYING file in the top-level directory.
15 * Contributions after 2012-01-13 are licensed under the terms of the
16 * GNU GPL, version 2 or (at your option) any later version.
19 #include "iov.h"
21 size_t iov_from_buf(struct iovec *iov, unsigned int iov_cnt,
22 size_t offset, const void *buf, size_t bytes)
24 size_t done;
25 unsigned int i;
26 for (i = 0, done = 0; (offset || done < bytes) && i < iov_cnt; i++) {
27 if (offset < iov[i].iov_len) {
28 size_t len = MIN(iov[i].iov_len - offset, bytes - done);
29 memcpy(iov[i].iov_base + offset, buf + done, len);
30 done += len;
31 offset = 0;
32 } else {
33 offset -= iov[i].iov_len;
36 assert(offset == 0);
37 return done;
40 size_t iov_to_buf(const struct iovec *iov, const unsigned int iov_cnt,
41 size_t offset, void *buf, size_t bytes)
43 size_t done;
44 unsigned int i;
45 for (i = 0, done = 0; (offset || done < bytes) && i < iov_cnt; i++) {
46 if (offset < iov[i].iov_len) {
47 size_t len = MIN(iov[i].iov_len - offset, bytes - done);
48 memcpy(buf + done, iov[i].iov_base + offset, len);
49 done += len;
50 offset = 0;
51 } else {
52 offset -= iov[i].iov_len;
55 assert(offset == 0);
56 return done;
59 size_t iov_memset(const struct iovec *iov, const unsigned int iov_cnt,
60 size_t offset, int fillc, size_t bytes)
62 size_t done;
63 unsigned int i;
64 for (i = 0, done = 0; (offset || done < bytes) && i < iov_cnt; i++) {
65 if (offset < iov[i].iov_len) {
66 size_t len = MIN(iov[i].iov_len - offset, bytes - done);
67 memset(iov[i].iov_base + offset, fillc, len);
68 done += len;
69 offset = 0;
70 } else {
71 offset -= iov[i].iov_len;
74 assert(offset == 0);
75 return done;
78 size_t iov_size(const struct iovec *iov, const unsigned int iov_cnt)
80 size_t len;
81 unsigned int i;
83 len = 0;
84 for (i = 0; i < iov_cnt; i++) {
85 len += iov[i].iov_len;
87 return len;
90 void iov_hexdump(const struct iovec *iov, const unsigned int iov_cnt,
91 FILE *fp, const char *prefix, size_t limit)
93 unsigned int i, v, b;
94 uint8_t *c;
96 c = iov[0].iov_base;
97 for (i = 0, v = 0, b = 0; b < limit; i++, b++) {
98 if (i == iov[v].iov_len) {
99 i = 0; v++;
100 if (v == iov_cnt) {
101 break;
103 c = iov[v].iov_base;
105 if ((b % 16) == 0) {
106 fprintf(fp, "%s: %04x:", prefix, b);
108 if ((b % 4) == 0) {
109 fprintf(fp, " ");
111 fprintf(fp, " %02x", c[i]);
112 if ((b % 16) == 15) {
113 fprintf(fp, "\n");
116 if ((b % 16) != 0) {
117 fprintf(fp, "\n");