Skip to content

Commit c63f07c

Browse files
committed
gio: support writev in stream impls for io::Write, AsyncWrite
1 parent 47bb097 commit c63f07c

File tree

2 files changed

+69
-0
lines changed

2 files changed

+69
-0
lines changed

gio/src/output_stream.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,30 @@ impl<T: IsA<OutputStream>> io::Write for OutputStreamWrite<T> {
668668
to_std_io_result(result)
669669
}
670670

671+
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
672+
let result = self
673+
.0
674+
.as_ref()
675+
.write_all(buf, crate::Cancellable::NONE)
676+
.and_then(|(_, e)| e.map(Err).unwrap_or(Ok(())));
677+
to_std_io_result(result)
678+
}
679+
680+
#[cfg(any(feature = "v2_60", feature = "dox"))]
681+
#[cfg_attr(feature = "dox", doc(cfg(feature = "v2_60")))]
682+
fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> {
683+
let vectors = bufs
684+
.iter()
685+
.map(|v| OutputVector::new(&**v))
686+
.collect::<smallvec::SmallVec<[_; 2]>>();
687+
let result = self
688+
.0
689+
.as_ref()
690+
.writev(&vectors, crate::Cancellable::NONE)
691+
.map(|size| size as usize);
692+
to_std_io_result(result)
693+
}
694+
671695
fn flush(&mut self) -> io::Result<()> {
672696
let gio_result = self.0.as_ref().flush(crate::Cancellable::NONE);
673697
to_std_io_result(gio_result)

gio/src/pollable_output_stream.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,51 @@ impl<T: IsA<PollableOutputStream>> AsyncWrite for OutputStreamAsyncWrite<T> {
236236
}
237237
}
238238

239+
#[cfg(any(feature = "v2_60", feature = "dox"))]
240+
#[cfg_attr(feature = "dox", doc(cfg(feature = "v2_60")))]
241+
fn poll_write_vectored(
242+
self: Pin<&mut Self>,
243+
cx: &mut Context<'_>,
244+
bufs: &[io::IoSlice<'_>],
245+
) -> Poll<io::Result<usize>> {
246+
let stream = Pin::get_ref(self.as_ref());
247+
let vectors = bufs
248+
.iter()
249+
.map(|v| OutputVector::new(&**v))
250+
.collect::<smallvec::SmallVec<[_; 2]>>();
251+
let gio_result = stream
252+
.0
253+
.as_ref()
254+
.writev_nonblocking(&vectors, crate::Cancellable::NONE);
255+
256+
match gio_result {
257+
Ok((PollableReturn::Ok, size)) => Poll::Ready(Ok(size as usize)),
258+
Ok((PollableReturn::WouldBlock, _)) => {
259+
let mut waker = Some(cx.waker().clone());
260+
let source = stream.0.as_ref().create_source(
261+
crate::Cancellable::NONE,
262+
None,
263+
glib::PRIORITY_DEFAULT,
264+
move |_| {
265+
if let Some(waker) = waker.take() {
266+
waker.wake();
267+
}
268+
glib::Continue(false)
269+
},
270+
);
271+
let main_context = glib::MainContext::ref_thread_default();
272+
source.attach(Some(&main_context));
273+
274+
Poll::Pending
275+
}
276+
Ok((_, _)) => unreachable!(),
277+
Err(err) => Poll::Ready(Err(io::Error::new(
278+
io::ErrorKind::from(err.kind::<crate::IOErrorEnum>().unwrap()),
279+
err,
280+
))),
281+
}
282+
}
283+
239284
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context) -> Poll<io::Result<()>> {
240285
let stream = unsafe { Pin::get_unchecked_mut(self) };
241286

0 commit comments

Comments
 (0)