Skip to main content

gio/auto/
io_stream.rs

1// This file was generated by gir (https://github.com/gtk-rs/gir)
2// from gir-files (https://github.com/gtk-rs/gir-files)
3// DO NOT EDIT
4
5use crate::{AsyncResult, Cancellable, InputStream, OutputStream, ffi};
6use glib::{
7    prelude::*,
8    signal::{SignalHandlerId, connect_raw},
9    translate::*,
10};
11use std::{boxed::Box as Box_, pin::Pin};
12
13glib::wrapper! {
14    /// t start any
15    /// `GInputStream` or `GOutputStream` operation while there is a `GIOStream`
16    /// operation in progress.
17    ///
18    /// This is a product of individual stream operations being associated with a
19    /// given [type@GLib.MainContext] (the thread-default context at the time the
20    /// operation was started), rather than entire streams being associated with a
21    /// single `GMainContext`.
22    ///
23    /// GIO may run operations on `GIOStream`s from other (worker) threads, and this
24    /// may be exposed to application code in the behaviour of wrapper streams, such
25    /// as [`BufferedInputStream`][crate::BufferedInputStream] or [`TlsConnection`][crate::TlsConnection]. With such
26    /// wrapper APIs, application code may only run operations on the base (wrapped)
27    /// stream when the wrapper stream is idle. Note that the semantics of such
28    /// operations may not be well-defined due to the state the wrapper stream leaves
29    /// the base stream in (though they are guaranteed not to crash).
30    ///
31    /// This is an Abstract Base Class, you cannot instantiate it.
32    ///
33    /// ## Properties
34    ///
35    ///
36    /// #### `closed`
37    ///  Whether the stream is closed.
38    ///
39    /// Readable
40    ///
41    ///
42    /// #### `input-stream`
43    ///  The [`InputStream`][crate::InputStream] to read from.
44    ///
45    /// Readable
46    ///
47    ///
48    /// #### `output-stream`
49    ///  The [`OutputStream`][crate::OutputStream] to write to.
50    ///
51    /// Readable
52    ///
53    /// # Implements
54    ///
55    /// [`IOStreamExt`][trait@crate::prelude::IOStreamExt], [`trait@glib::ObjectExt`], [`IOStreamExtManual`][trait@crate::prelude::IOStreamExtManual]
56    #[doc(alias = "GIOStream")]
57    pub struct IOStream(Object<ffi::GIOStream, ffi::GIOStreamClass>);
58
59    match fn {
60        type_ => || ffi::g_io_stream_get_type(),
61    }
62}
63
64impl IOStream {
65    pub const NONE: Option<&'static IOStream> = None;
66}
67
68/// Trait containing all [`struct@IOStream`] methods.
69///
70/// # Implementors
71///
72/// [`FileIOStream`][struct@crate::FileIOStream], [`IOStream`][struct@crate::IOStream], [`SimpleIOStream`][struct@crate::SimpleIOStream], [`SocketConnection`][struct@crate::SocketConnection], [`TlsConnection`][struct@crate::TlsConnection]
73pub trait IOStreamExt: IsA<IOStream> + 'static {
74    /// Clears the pending flag on @self.
75    #[doc(alias = "g_io_stream_clear_pending")]
76    fn clear_pending(&self) {
77        unsafe {
78            ffi::g_io_stream_clear_pending(self.as_ref().to_glib_none().0);
79        }
80    }
81
82    /// Closes the stream, releasing resources related to it. This will also
83    /// close the individual input and output streams, if they are not already
84    /// closed.
85    ///
86    /// Once the stream is closed, all other operations will return
87    /// [`IOErrorEnum::Closed`][crate::IOErrorEnum::Closed]. Closing a stream multiple times will not
88    /// return an error.
89    ///
90    /// Closing a stream will automatically flush any outstanding buffers
91    /// in the stream.
92    ///
93    /// Streams will be automatically closed when the last reference
94    /// is dropped, but you might want to call this function to make sure
95    /// resources are released as early as possible.
96    ///
97    /// Some streams might keep the backing store of the stream (e.g. a file
98    /// descriptor) open after the stream is closed. See the documentation for
99    /// the individual stream for details.
100    ///
101    /// On failure the first error that happened will be reported, but the
102    /// close operation will finish as much as possible. A stream that failed
103    /// to close will still return [`IOErrorEnum::Closed`][crate::IOErrorEnum::Closed] for all operations.
104    /// Still, it is important to check and report the error to the user,
105    /// otherwise there might be a loss of data as all data might not be written.
106    ///
107    /// If @cancellable is not NULL, then the operation can be cancelled by
108    /// triggering the cancellable object from another thread. If the operation
109    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
110    /// Cancelling a close will still leave the stream closed, but some streams
111    /// can use a faster close that doesn't block to e.g. check errors.
112    ///
113    /// The default implementation of this method just calls close on the
114    /// individual input/output streams.
115    /// ## `cancellable`
116    /// optional #GCancellable object, [`None`] to ignore
117    ///
118    /// # Returns
119    ///
120    /// [`true`] on success, [`false`] on failure
121    #[doc(alias = "g_io_stream_close")]
122    fn close(&self, cancellable: Option<&impl IsA<Cancellable>>) -> Result<(), glib::Error> {
123        unsafe {
124            let mut error = std::ptr::null_mut();
125            let is_ok = ffi::g_io_stream_close(
126                self.as_ref().to_glib_none().0,
127                cancellable.map(|p| p.as_ref()).to_glib_none().0,
128                &mut error,
129            );
130            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
131            if error.is_null() {
132                Ok(())
133            } else {
134                Err(from_glib_full(error))
135            }
136        }
137    }
138
139    /// Requests an asynchronous close of the stream, releasing resources
140    /// related to it. When the operation is finished @callback will be
141    /// called. You can then call g_io_stream_close_finish() to get
142    /// the result of the operation.
143    ///
144    /// For behaviour details see g_io_stream_close().
145    ///
146    /// The asynchronous methods have a default fallback that uses threads
147    /// to implement asynchronicity, so they are optional for inheriting
148    /// classes. However, if you override one you must override all.
149    /// ## `io_priority`
150    /// the io priority of the request
151    /// ## `cancellable`
152    /// optional cancellable object
153    /// ## `callback`
154    /// a #GAsyncReadyCallback
155    ///   to call when the request is satisfied
156    #[doc(alias = "g_io_stream_close_async")]
157    fn close_async<P: FnOnce(Result<(), glib::Error>) + 'static>(
158        &self,
159        io_priority: glib::Priority,
160        cancellable: Option<&impl IsA<Cancellable>>,
161        callback: P,
162    ) {
163        let main_context = glib::MainContext::ref_thread_default();
164        let is_main_context_owner = main_context.is_owner();
165        let has_acquired_main_context = (!is_main_context_owner)
166            .then(|| main_context.acquire().ok())
167            .flatten();
168        assert!(
169            is_main_context_owner || has_acquired_main_context.is_some(),
170            "Async operations only allowed if the thread is owning the MainContext"
171        );
172
173        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
174            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
175        unsafe extern "C" fn close_async_trampoline<
176            P: FnOnce(Result<(), glib::Error>) + 'static,
177        >(
178            _source_object: *mut glib::gobject_ffi::GObject,
179            res: *mut crate::ffi::GAsyncResult,
180            user_data: glib::ffi::gpointer,
181        ) {
182            unsafe {
183                let mut error = std::ptr::null_mut();
184                ffi::g_io_stream_close_finish(_source_object as *mut _, res, &mut error);
185                let result = if error.is_null() {
186                    Ok(())
187                } else {
188                    Err(from_glib_full(error))
189                };
190                let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
191                    Box_::from_raw(user_data as *mut _);
192                let callback: P = callback.into_inner();
193                callback(result);
194            }
195        }
196        let callback = close_async_trampoline::<P>;
197        unsafe {
198            ffi::g_io_stream_close_async(
199                self.as_ref().to_glib_none().0,
200                io_priority.into_glib(),
201                cancellable.map(|p| p.as_ref()).to_glib_none().0,
202                Some(callback),
203                Box_::into_raw(user_data) as *mut _,
204            );
205        }
206    }
207
208    fn close_future(
209        &self,
210        io_priority: glib::Priority,
211    ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
212        Box_::pin(crate::GioFuture::new(
213            self,
214            move |obj, cancellable, send| {
215                obj.close_async(io_priority, Some(cancellable), move |res| {
216                    send.resolve(res);
217                });
218            },
219        ))
220    }
221
222    /// Gets the input stream for this object. This is used
223    /// for reading.
224    ///
225    /// # Returns
226    ///
227    /// a #GInputStream, owned by the #GIOStream.
228    /// Do not free.
229    #[doc(alias = "g_io_stream_get_input_stream")]
230    #[doc(alias = "get_input_stream")]
231    #[doc(alias = "input-stream")]
232    fn input_stream(&self) -> InputStream {
233        unsafe {
234            from_glib_none(ffi::g_io_stream_get_input_stream(
235                self.as_ref().to_glib_none().0,
236            ))
237        }
238    }
239
240    /// Gets the output stream for this object. This is used for
241    /// writing.
242    ///
243    /// # Returns
244    ///
245    /// a #GOutputStream, owned by the #GIOStream.
246    /// Do not free.
247    #[doc(alias = "g_io_stream_get_output_stream")]
248    #[doc(alias = "get_output_stream")]
249    #[doc(alias = "output-stream")]
250    fn output_stream(&self) -> OutputStream {
251        unsafe {
252            from_glib_none(ffi::g_io_stream_get_output_stream(
253                self.as_ref().to_glib_none().0,
254            ))
255        }
256    }
257
258    /// Checks if a stream has pending actions.
259    ///
260    /// # Returns
261    ///
262    /// [`true`] if @self has pending actions.
263    #[doc(alias = "g_io_stream_has_pending")]
264    fn has_pending(&self) -> bool {
265        unsafe { from_glib(ffi::g_io_stream_has_pending(self.as_ref().to_glib_none().0)) }
266    }
267
268    /// Checks if a stream is closed.
269    ///
270    /// # Returns
271    ///
272    /// [`true`] if the stream is closed.
273    #[doc(alias = "g_io_stream_is_closed")]
274    #[doc(alias = "closed")]
275    fn is_closed(&self) -> bool {
276        unsafe { from_glib(ffi::g_io_stream_is_closed(self.as_ref().to_glib_none().0)) }
277    }
278
279    /// Sets @self to have actions pending. If the pending flag is
280    /// already set or @self is closed, it will return [`false`] and set
281    /// @error.
282    ///
283    /// # Returns
284    ///
285    /// [`true`] if pending was previously unset and is now set.
286    #[doc(alias = "g_io_stream_set_pending")]
287    fn set_pending(&self) -> Result<(), glib::Error> {
288        unsafe {
289            let mut error = std::ptr::null_mut();
290            let is_ok = ffi::g_io_stream_set_pending(self.as_ref().to_glib_none().0, &mut error);
291            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
292            if error.is_null() {
293                Ok(())
294            } else {
295                Err(from_glib_full(error))
296            }
297        }
298    }
299
300    #[doc(alias = "closed")]
301    fn connect_closed_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
302        unsafe extern "C" fn notify_closed_trampoline<P: IsA<IOStream>, F: Fn(&P) + 'static>(
303            this: *mut ffi::GIOStream,
304            _param_spec: glib::ffi::gpointer,
305            f: glib::ffi::gpointer,
306        ) {
307            unsafe {
308                let f: &F = &*(f as *const F);
309                f(IOStream::from_glib_borrow(this).unsafe_cast_ref())
310            }
311        }
312        unsafe {
313            let f: Box_<F> = Box_::new(f);
314            connect_raw(
315                self.as_ptr() as *mut _,
316                c"notify::closed".as_ptr(),
317                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
318                    notify_closed_trampoline::<Self, F> as *const (),
319                )),
320                Box_::into_raw(f),
321            )
322        }
323    }
324}
325
326impl<O: IsA<IOStream>> IOStreamExt for O {}