1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// This file was generated by gir (https://github.com/gtk-rs/gir)
// from gir-files (https://github.com/gtk-rs/gir-files)
// DO NOT EDIT

use crate::{Cancellable, OutputStream};
use glib::{prelude::*, translate::*};
use std::{fmt, ptr};

glib::wrapper! {
    /// [`PollableOutputStream`][crate::PollableOutputStream] is implemented by `GOutputStreams` that
    /// can be polled for readiness to write. This can be used when
    /// interfacing with a non-GIO API that expects
    /// UNIX-file-descriptor-style asynchronous I/O rather than GIO-style.
    ///
    /// # Implements
    ///
    /// [`PollableOutputStreamExt`][trait@crate::prelude::PollableOutputStreamExt], [`OutputStreamExt`][trait@crate::prelude::OutputStreamExt], [`trait@glib::ObjectExt`], [`PollableOutputStreamExtManual`][trait@crate::prelude::PollableOutputStreamExtManual], [`OutputStreamExtManual`][trait@crate::prelude::OutputStreamExtManual]
    #[doc(alias = "GPollableOutputStream")]
    pub struct PollableOutputStream(Interface<ffi::GPollableOutputStream, ffi::GPollableOutputStreamInterface>) @requires OutputStream;

    match fn {
        type_ => || ffi::g_pollable_output_stream_get_type(),
    }
}

impl PollableOutputStream {
    pub const NONE: Option<&'static PollableOutputStream> = None;
}

/// Trait containing all [`struct@PollableOutputStream`] methods.
///
/// # Implementors
///
/// [`ConverterOutputStream`][struct@crate::ConverterOutputStream], [`MemoryOutputStream`][struct@crate::MemoryOutputStream], [`PollableOutputStream`][struct@crate::PollableOutputStream], [`UnixOutputStream`][struct@crate::UnixOutputStream]
pub trait PollableOutputStreamExt: 'static {
    /// Checks if `self` is actually pollable. Some classes may implement
    /// [`PollableOutputStream`][crate::PollableOutputStream] but have only certain instances of that
    /// class be pollable. If this method returns [`false`], then the behavior
    /// of other [`PollableOutputStream`][crate::PollableOutputStream] methods is undefined.
    ///
    /// For any given stream, the value returned by this method is constant;
    /// a stream cannot switch from pollable to non-pollable or vice versa.
    ///
    /// # Returns
    ///
    /// [`true`] if `self` is pollable, [`false`] if not.
    #[doc(alias = "g_pollable_output_stream_can_poll")]
    fn can_poll(&self) -> bool;

    /// Checks if `self` can be written.
    ///
    /// Note that some stream types may not be able to implement this 100%
    /// reliably, and it is possible that a call to [`OutputStreamExt::write()`][crate::prelude::OutputStreamExt::write()]
    /// after this returns [`true`] would still block. To guarantee
    /// non-blocking behavior, you should always use
    /// [`write_nonblocking()`][Self::write_nonblocking()], which will return a
    /// [`IOErrorEnum::WouldBlock`][crate::IOErrorEnum::WouldBlock] error rather than blocking.
    ///
    /// # Returns
    ///
    /// [`true`] if `self` is writable, [`false`] if not. If an error
    ///  has occurred on `self`, this will result in
    ///  [`is_writable()`][Self::is_writable()] returning [`true`], and the
    ///  next attempt to write will return the error.
    #[doc(alias = "g_pollable_output_stream_is_writable")]
    fn is_writable(&self) -> bool;

    /// Attempts to write up to `count` bytes from `buffer` to `self`, as
    /// with [`OutputStreamExt::write()`][crate::prelude::OutputStreamExt::write()]. If `self` is not currently writable,
    /// this will immediately return [`IOErrorEnum::WouldBlock`][crate::IOErrorEnum::WouldBlock], and you can
    /// use [`PollableOutputStreamExtManual::create_source()`][crate::prelude::PollableOutputStreamExtManual::create_source()] to create a [`glib::Source`][crate::glib::Source]
    /// that will be triggered when `self` is writable.
    ///
    /// Note that since this method never blocks, you cannot actually
    /// use `cancellable` to cancel it. However, it will return an error
    /// if `cancellable` has already been cancelled when you call, which
    /// may happen if you call this method after a source triggers due
    /// to having been cancelled.
    ///
    /// Also note that if [`IOErrorEnum::WouldBlock`][crate::IOErrorEnum::WouldBlock] is returned some underlying
    /// transports like D/TLS require that you re-send the same `buffer` and
    /// `count` in the next write call.
    /// ## `buffer`
    /// a buffer to write
    ///  data from
    /// ## `cancellable`
    /// a [`Cancellable`][crate::Cancellable], or [`None`]
    ///
    /// # Returns
    ///
    /// the number of bytes written, or -1 on error (including
    ///  [`IOErrorEnum::WouldBlock`][crate::IOErrorEnum::WouldBlock]).
    #[doc(alias = "g_pollable_output_stream_write_nonblocking")]
    fn write_nonblocking(
        &self,
        buffer: &[u8],
        cancellable: Option<&impl IsA<Cancellable>>,
    ) -> Result<isize, glib::Error>;
}

impl<O: IsA<PollableOutputStream>> PollableOutputStreamExt for O {
    fn can_poll(&self) -> bool {
        unsafe {
            from_glib(ffi::g_pollable_output_stream_can_poll(
                self.as_ref().to_glib_none().0,
            ))
        }
    }

    fn is_writable(&self) -> bool {
        unsafe {
            from_glib(ffi::g_pollable_output_stream_is_writable(
                self.as_ref().to_glib_none().0,
            ))
        }
    }

    fn write_nonblocking(
        &self,
        buffer: &[u8],
        cancellable: Option<&impl IsA<Cancellable>>,
    ) -> Result<isize, glib::Error> {
        let count = buffer.len() as _;
        unsafe {
            let mut error = ptr::null_mut();
            let ret = ffi::g_pollable_output_stream_write_nonblocking(
                self.as_ref().to_glib_none().0,
                buffer.to_glib_none().0,
                count,
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                &mut error,
            );
            if error.is_null() {
                Ok(ret)
            } else {
                Err(from_glib_full(error))
            }
        }
    }
}

impl fmt::Display for PollableOutputStream {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str("PollableOutputStream")
    }
}