summaryrefslogtreecommitdiff
path: root/iov.c
diff options
context:
space:
mode:
authorStefan Hajnoczi <stefanha@redhat.com>2012-11-21 17:41:10 +0100
committerStefan Hajnoczi <stefanha@redhat.com>2013-01-02 15:58:05 +0100
commitd02776350d9c76348988fc9e58a64a4f6b1a9f61 (patch)
tree16aca1151bf5e3658b60181c68dd07e7f537a49b /iov.c
parent3e9ec521711ed033476098cfc7f23c992cc606a2 (diff)
downloadqemu-d02776350d9c76348988fc9e58a64a4f6b1a9f61.tar.gz
iov: add iov_discard_front/back() to remove data
The iov_discard_front/back() functions remove data from the front or back of the vector. This is useful when peeling off header/footer structs. Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'iov.c')
-rw-r--r--iov.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/iov.c b/iov.c
index 419e419969..92ad77b162 100644
--- a/iov.c
+++ b/iov.c
@@ -354,3 +354,54 @@ size_t qemu_iovec_memset(QEMUIOVector *qiov, size_t offset,
{
return iov_memset(qiov->iov, qiov->niov, offset, fillc, bytes);
}
+
+size_t iov_discard_front(struct iovec **iov, unsigned int *iov_cnt,
+ size_t bytes)
+{
+ size_t total = 0;
+ struct iovec *cur;
+
+ for (cur = *iov; *iov_cnt > 0; cur++) {
+ if (cur->iov_len > bytes) {
+ cur->iov_base += bytes;
+ cur->iov_len -= bytes;
+ total += bytes;
+ break;
+ }
+
+ bytes -= cur->iov_len;
+ total += cur->iov_len;
+ *iov_cnt -= 1;
+ }
+
+ *iov = cur;
+ return total;
+}
+
+size_t iov_discard_back(struct iovec *iov, unsigned int *iov_cnt,
+ size_t bytes)
+{
+ size_t total = 0;
+ struct iovec *cur;
+
+ if (*iov_cnt == 0) {
+ return 0;
+ }
+
+ cur = iov + (*iov_cnt - 1);
+
+ while (*iov_cnt > 0) {
+ if (cur->iov_len > bytes) {
+ cur->iov_len -= bytes;
+ total += bytes;
+ break;
+ }
+
+ bytes -= cur->iov_len;
+ total += cur->iov_len;
+ cur--;
+ *iov_cnt -= 1;
+ }
+
+ return total;
+}