Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
Changes | 1 +
Virt.xs | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++
lib/Sys/Virt/Stream.pm | 14 ++++++++++
t/030-api-coverage.t | 1 +
4 files changed, 86 insertions(+)
diff --git a/Changes b/Changes
index c92c271..4c1e071 100644
--- a/Changes
+++ b/Changes
@@ -7,6 +7,7 @@ Revision history for perl module Sys::Virt
- Introduce flags to Stream::recv() and
register RECV_STOP_AT_HOLE constant
- Introduce Stream::recvHole() and Stream::sendHole()
+ - Introduce Stream::sparse_recv_all()
3.3.0 2017-05-08
diff --git a/Virt.xs b/Virt.xs
index d112708..002bd6a 100644
--- a/Virt.xs
+++ b/Virt.xs
@@ -2008,6 +2008,48 @@ _stream_recv_all_sink(virStreamPtr st,
}
+static int
+_stream_sparse_recv_holeHandler(virStreamPtr st,
+ long long offset,
+ void *opaque)
+{
+ AV *av = opaque;
+ SV **self;
+ SV **holeHandler;
+ int rv;
+ int ret;
+ dSP;
+
+ self = av_fetch(av, 0, 0);
+ holeHandler = av_fetch(av, 2, 0);
+
+ SvREFCNT_inc(*self);
+
+ ENTER;
+ SAVETMPS;
+
+ PUSHMARK(SP);
+ XPUSHs(*self);
+ XPUSHs(sv_2mortal(virt_newSVll(offset)));
+ PUTBACK;
+
+ rv = call_sv((SV*)*holeHandler, G_SCALAR);
+
+ SPAGAIN;
+
+ if (rv == 1) {
+ ret = POPi;
+ } else {
+ ret = -1;
+ }
+
+ FREETMPS;
+ LEAVE;
+
+ return ret;
+}
+
+
MODULE = Sys::Virt PACKAGE = Sys::Virt
PROTOTYPES: ENABLE
@@ -7972,6 +8014,34 @@ recv_all(stref, handler)
SvREFCNT_dec(opaque);
+void
+sparse_recv_all(stref, handler, holeHandler)
+ SV *stref;
+ SV *handler;
+ SV *holeHandler;
+ PREINIT:
+ AV *opaque;
+ virStreamPtr st;
+ CODE:
+ st = (virStreamPtr)SvIV((SV*)SvRV(stref));
+
+ opaque = newAV();
+ SvREFCNT_inc(stref);
+ SvREFCNT_inc(handler);
+ SvREFCNT_inc(holeHandler);
+ av_push(opaque, stref);
+ av_push(opaque, handler);
+ av_push(opaque, holeHandler);
+
+ if (virStreamSparseRecvAll(st,
+ _stream_recv_all_sink,
+ _stream_sparse_recv_holeHandler,
+ opaque) < 0)
+ _croak_error();
+
+ SvREFCNT_dec(opaque);
+
+
void
add_callback(stref, events, cb)
SV* stref;
diff --git a/lib/Sys/Virt/Stream.pm b/lib/Sys/Virt/Stream.pm
index 5984fb6..c32b957 100644
--- a/lib/Sys/Virt/Stream.pm
+++ b/lib/Sys/Virt/Stream.pm
@@ -130,6 +130,20 @@ data byte count desired. The function should return
the number of bytes filled, 0 on end of file, or
-1 upon error
+=item $st->sparse_recv_all($handler, $holeHandler)
+
+Receive all data available from the sparse stream, invoking
+C<$handler> to process the data. The C<$handler> parameter must
+be a function which expects three arguments, the C<$st> stream
+object, a scalar containing the data received and a data byte
+count. The function should return the number of bytes processed,
+or -1 upon error. The second argument C<$holeHandler> is a
+function which expects two arguments: the C<$st> stream and a
+scalar, number describing the size of the hole in the stream (in
+bytes). The C<$holeHandler> is expected to return a non-negative
+number on success (usually 0) and a negative number (usually -1)
+otherwise.
+
=item $st->add_callback($events, $coderef)
Register a callback to be invoked whenever the stream has
diff --git a/t/030-api-coverage.t b/t/030-api-coverage.t
index 3049713..6a281ba 100644
--- a/t/030-api-coverage.t
+++ b/t/030-api-coverage.t
@@ -114,6 +114,7 @@ virEventUpdateTimeoutFunc
virStreamEventCallback
virStreamSinkFunc
+virStreamSinkHoleFunc
virStreamSourceFunc
virConnectCloseFunc
--
2.13.0