gio/auto/
input_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::{ffi, AsyncResult, Cancellable};
6use glib::{prelude::*, translate::*};
7use std::{boxed::Box as Box_, pin::Pin};
8
9glib::wrapper! {
10    /// `GInputStream` is a base class for implementing streaming input.
11    ///
12    /// It has functions to read from a stream ([`InputStreamExtManual::read()`][crate::prelude::InputStreamExtManual::read()]),
13    /// to close a stream ([`InputStreamExt::close()`][crate::prelude::InputStreamExt::close()]) and to skip some content
14    /// ([`InputStreamExt::skip()`][crate::prelude::InputStreamExt::skip()]).
15    ///
16    /// To copy the content of an input stream to an output stream without
17    /// manually handling the reads and writes, use [`OutputStreamExt::splice()`][crate::prelude::OutputStreamExt::splice()].
18    ///
19    /// See the documentation for [`IOStream`][crate::IOStream] for details of thread safety
20    /// of streaming APIs.
21    ///
22    /// All of these functions have async variants too.
23    ///
24    /// This is an Abstract Base Class, you cannot instantiate it.
25    ///
26    /// # Implements
27    ///
28    /// [`InputStreamExt`][trait@crate::prelude::InputStreamExt], [`trait@glib::ObjectExt`], [`InputStreamExtManual`][trait@crate::prelude::InputStreamExtManual]
29    #[doc(alias = "GInputStream")]
30    pub struct InputStream(Object<ffi::GInputStream, ffi::GInputStreamClass>);
31
32    match fn {
33        type_ => || ffi::g_input_stream_get_type(),
34    }
35}
36
37impl InputStream {
38    pub const NONE: Option<&'static InputStream> = None;
39}
40
41/// Trait containing all [`struct@InputStream`] methods.
42///
43/// # Implementors
44///
45/// [`FileInputStream`][struct@crate::FileInputStream], [`FilterInputStream`][struct@crate::FilterInputStream], [`InputStream`][struct@crate::InputStream], [`MemoryInputStream`][struct@crate::MemoryInputStream], [`PollableInputStream`][struct@crate::PollableInputStream], [`UnixInputStream`][struct@crate::UnixInputStream]
46pub trait InputStreamExt: IsA<InputStream> + 'static {
47    /// Clears the pending flag on @self.
48    #[doc(alias = "g_input_stream_clear_pending")]
49    fn clear_pending(&self) {
50        unsafe {
51            ffi::g_input_stream_clear_pending(self.as_ref().to_glib_none().0);
52        }
53    }
54
55    /// Closes the stream, releasing resources related to it.
56    ///
57    /// Once the stream is closed, all other operations will return [`IOErrorEnum::Closed`][crate::IOErrorEnum::Closed].
58    /// Closing a stream multiple times will not return an error.
59    ///
60    /// Streams will be automatically closed when the last reference
61    /// is dropped, but you might want to call this function to make sure
62    /// resources are released as early as possible.
63    ///
64    /// Some streams might keep the backing store of the stream (e.g. a file descriptor)
65    /// open after the stream is closed. See the documentation for the individual
66    /// stream for details.
67    ///
68    /// On failure the first error that happened will be reported, but the close
69    /// operation will finish as much as possible. A stream that failed to
70    /// close will still return [`IOErrorEnum::Closed`][crate::IOErrorEnum::Closed] for all operations. Still, it
71    /// is important to check and report the error to the user.
72    ///
73    /// If @cancellable is not [`None`], then the operation can be cancelled by
74    /// triggering the cancellable object from another thread. If the operation
75    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
76    /// Cancelling a close will still leave the stream closed, but some streams
77    /// can use a faster close that doesn't block to e.g. check errors.
78    /// ## `cancellable`
79    /// optional #GCancellable object, [`None`] to ignore.
80    ///
81    /// # Returns
82    ///
83    /// [`true`] on success, [`false`] on failure
84    #[doc(alias = "g_input_stream_close")]
85    fn close(&self, cancellable: Option<&impl IsA<Cancellable>>) -> Result<(), glib::Error> {
86        unsafe {
87            let mut error = std::ptr::null_mut();
88            let is_ok = ffi::g_input_stream_close(
89                self.as_ref().to_glib_none().0,
90                cancellable.map(|p| p.as_ref()).to_glib_none().0,
91                &mut error,
92            );
93            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
94            if error.is_null() {
95                Ok(())
96            } else {
97                Err(from_glib_full(error))
98            }
99        }
100    }
101
102    /// Requests an asynchronous closes of the stream, releasing resources related to it.
103    /// When the operation is finished @callback will be called.
104    /// You can then call g_input_stream_close_finish() to get the result of the
105    /// operation.
106    ///
107    /// For behaviour details see g_input_stream_close().
108    ///
109    /// The asynchronous methods have a default fallback that uses threads to implement
110    /// asynchronicity, so they are optional for inheriting classes. However, if you
111    /// override one you must override all.
112    /// ## `io_priority`
113    /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
114    /// ## `cancellable`
115    /// optional cancellable object
116    /// ## `callback`
117    /// a #GAsyncReadyCallback
118    ///   to call when the request is satisfied
119    #[doc(alias = "g_input_stream_close_async")]
120    fn close_async<P: FnOnce(Result<(), glib::Error>) + 'static>(
121        &self,
122        io_priority: glib::Priority,
123        cancellable: Option<&impl IsA<Cancellable>>,
124        callback: P,
125    ) {
126        let main_context = glib::MainContext::ref_thread_default();
127        let is_main_context_owner = main_context.is_owner();
128        let has_acquired_main_context = (!is_main_context_owner)
129            .then(|| main_context.acquire().ok())
130            .flatten();
131        assert!(
132            is_main_context_owner || has_acquired_main_context.is_some(),
133            "Async operations only allowed if the thread is owning the MainContext"
134        );
135
136        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
137            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
138        unsafe extern "C" fn close_async_trampoline<
139            P: FnOnce(Result<(), glib::Error>) + 'static,
140        >(
141            _source_object: *mut glib::gobject_ffi::GObject,
142            res: *mut crate::ffi::GAsyncResult,
143            user_data: glib::ffi::gpointer,
144        ) {
145            let mut error = std::ptr::null_mut();
146            ffi::g_input_stream_close_finish(_source_object as *mut _, res, &mut error);
147            let result = if error.is_null() {
148                Ok(())
149            } else {
150                Err(from_glib_full(error))
151            };
152            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
153                Box_::from_raw(user_data as *mut _);
154            let callback: P = callback.into_inner();
155            callback(result);
156        }
157        let callback = close_async_trampoline::<P>;
158        unsafe {
159            ffi::g_input_stream_close_async(
160                self.as_ref().to_glib_none().0,
161                io_priority.into_glib(),
162                cancellable.map(|p| p.as_ref()).to_glib_none().0,
163                Some(callback),
164                Box_::into_raw(user_data) as *mut _,
165            );
166        }
167    }
168
169    fn close_future(
170        &self,
171        io_priority: glib::Priority,
172    ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
173        Box_::pin(crate::GioFuture::new(
174            self,
175            move |obj, cancellable, send| {
176                obj.close_async(io_priority, Some(cancellable), move |res| {
177                    send.resolve(res);
178                });
179            },
180        ))
181    }
182
183    /// Checks if an input stream has pending actions.
184    ///
185    /// # Returns
186    ///
187    /// [`true`] if @self has pending actions.
188    #[doc(alias = "g_input_stream_has_pending")]
189    fn has_pending(&self) -> bool {
190        unsafe {
191            from_glib(ffi::g_input_stream_has_pending(
192                self.as_ref().to_glib_none().0,
193            ))
194        }
195    }
196
197    /// Checks if an input stream is closed.
198    ///
199    /// # Returns
200    ///
201    /// [`true`] if the stream is closed.
202    #[doc(alias = "g_input_stream_is_closed")]
203    fn is_closed(&self) -> bool {
204        unsafe {
205            from_glib(ffi::g_input_stream_is_closed(
206                self.as_ref().to_glib_none().0,
207            ))
208        }
209    }
210
211    /// Like g_input_stream_read(), this tries to read @count bytes from
212    /// the stream in a blocking fashion. However, rather than reading into
213    /// a user-supplied buffer, this will create a new #GBytes containing
214    /// the data that was read. This may be easier to use from language
215    /// bindings.
216    ///
217    /// If count is zero, returns a zero-length #GBytes and does nothing. A
218    /// value of @count larger than `G_MAXSSIZE` will cause a
219    /// [`IOErrorEnum::InvalidArgument`][crate::IOErrorEnum::InvalidArgument] error.
220    ///
221    /// On success, a new #GBytes is returned. It is not an error if the
222    /// size of this object is not the same as the requested size, as it
223    /// can happen e.g. near the end of a file. A zero-length #GBytes is
224    /// returned on end of file (or if @count is zero), but never
225    /// otherwise.
226    ///
227    /// If @cancellable is not [`None`], then the operation can be cancelled by
228    /// triggering the cancellable object from another thread. If the operation
229    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned. If an
230    /// operation was partially finished when the operation was cancelled the
231    /// partial result will be returned, without an error.
232    ///
233    /// On error [`None`] is returned and @error is set accordingly.
234    /// ## `count`
235    /// maximum number of bytes that will be read from the stream. Common
236    /// values include 4096 and 8192.
237    /// ## `cancellable`
238    /// optional #GCancellable object, [`None`] to ignore.
239    ///
240    /// # Returns
241    ///
242    /// a new #GBytes, or [`None`] on error
243    #[doc(alias = "g_input_stream_read_bytes")]
244    fn read_bytes(
245        &self,
246        count: usize,
247        cancellable: Option<&impl IsA<Cancellable>>,
248    ) -> Result<glib::Bytes, glib::Error> {
249        unsafe {
250            let mut error = std::ptr::null_mut();
251            let ret = ffi::g_input_stream_read_bytes(
252                self.as_ref().to_glib_none().0,
253                count,
254                cancellable.map(|p| p.as_ref()).to_glib_none().0,
255                &mut error,
256            );
257            if error.is_null() {
258                Ok(from_glib_full(ret))
259            } else {
260                Err(from_glib_full(error))
261            }
262        }
263    }
264
265    /// Request an asynchronous read of @count bytes from the stream into a
266    /// new #GBytes. When the operation is finished @callback will be
267    /// called. You can then call g_input_stream_read_bytes_finish() to get the
268    /// result of the operation.
269    ///
270    /// During an async request no other sync and async calls are allowed
271    /// on @self, and will result in [`IOErrorEnum::Pending`][crate::IOErrorEnum::Pending] errors.
272    ///
273    /// A value of @count larger than `G_MAXSSIZE` will cause a
274    /// [`IOErrorEnum::InvalidArgument`][crate::IOErrorEnum::InvalidArgument] error.
275    ///
276    /// On success, the new #GBytes will be passed to the callback. It is
277    /// not an error if this is smaller than the requested size, as it can
278    /// happen e.g. near the end of a file, but generally we try to read as
279    /// many bytes as requested. Zero is returned on end of file (or if
280    /// @count is zero), but never otherwise.
281    ///
282    /// Any outstanding I/O request with higher priority (lower numerical
283    /// value) will be executed before an outstanding request with lower
284    /// priority. Default priority is `G_PRIORITY_DEFAULT`.
285    /// ## `count`
286    /// the number of bytes that will be read from the stream
287    /// ## `io_priority`
288    /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
289    /// ## `cancellable`
290    /// optional #GCancellable object, [`None`] to ignore.
291    /// ## `callback`
292    /// a #GAsyncReadyCallback
293    ///   to call when the request is satisfied
294    #[doc(alias = "g_input_stream_read_bytes_async")]
295    fn read_bytes_async<P: FnOnce(Result<glib::Bytes, glib::Error>) + 'static>(
296        &self,
297        count: usize,
298        io_priority: glib::Priority,
299        cancellable: Option<&impl IsA<Cancellable>>,
300        callback: P,
301    ) {
302        let main_context = glib::MainContext::ref_thread_default();
303        let is_main_context_owner = main_context.is_owner();
304        let has_acquired_main_context = (!is_main_context_owner)
305            .then(|| main_context.acquire().ok())
306            .flatten();
307        assert!(
308            is_main_context_owner || has_acquired_main_context.is_some(),
309            "Async operations only allowed if the thread is owning the MainContext"
310        );
311
312        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
313            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
314        unsafe extern "C" fn read_bytes_async_trampoline<
315            P: FnOnce(Result<glib::Bytes, glib::Error>) + 'static,
316        >(
317            _source_object: *mut glib::gobject_ffi::GObject,
318            res: *mut crate::ffi::GAsyncResult,
319            user_data: glib::ffi::gpointer,
320        ) {
321            let mut error = std::ptr::null_mut();
322            let ret =
323                ffi::g_input_stream_read_bytes_finish(_source_object as *mut _, res, &mut error);
324            let result = if error.is_null() {
325                Ok(from_glib_full(ret))
326            } else {
327                Err(from_glib_full(error))
328            };
329            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
330                Box_::from_raw(user_data as *mut _);
331            let callback: P = callback.into_inner();
332            callback(result);
333        }
334        let callback = read_bytes_async_trampoline::<P>;
335        unsafe {
336            ffi::g_input_stream_read_bytes_async(
337                self.as_ref().to_glib_none().0,
338                count,
339                io_priority.into_glib(),
340                cancellable.map(|p| p.as_ref()).to_glib_none().0,
341                Some(callback),
342                Box_::into_raw(user_data) as *mut _,
343            );
344        }
345    }
346
347    fn read_bytes_future(
348        &self,
349        count: usize,
350        io_priority: glib::Priority,
351    ) -> Pin<Box_<dyn std::future::Future<Output = Result<glib::Bytes, glib::Error>> + 'static>>
352    {
353        Box_::pin(crate::GioFuture::new(
354            self,
355            move |obj, cancellable, send| {
356                obj.read_bytes_async(count, io_priority, Some(cancellable), move |res| {
357                    send.resolve(res);
358                });
359            },
360        ))
361    }
362
363    /// Sets @self to have actions pending. If the pending flag is
364    /// already set or @self is closed, it will return [`false`] and set
365    /// @error.
366    ///
367    /// # Returns
368    ///
369    /// [`true`] if pending was previously unset and is now set.
370    #[doc(alias = "g_input_stream_set_pending")]
371    fn set_pending(&self) -> Result<(), glib::Error> {
372        unsafe {
373            let mut error = std::ptr::null_mut();
374            let is_ok = ffi::g_input_stream_set_pending(self.as_ref().to_glib_none().0, &mut error);
375            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
376            if error.is_null() {
377                Ok(())
378            } else {
379                Err(from_glib_full(error))
380            }
381        }
382    }
383
384    /// Tries to skip @count bytes from the stream. Will block during the operation.
385    ///
386    /// This is identical to g_input_stream_read(), from a behaviour standpoint,
387    /// but the bytes that are skipped are not returned to the user. Some
388    /// streams have an implementation that is more efficient than reading the data.
389    ///
390    /// This function is optional for inherited classes, as the default implementation
391    /// emulates it using read.
392    ///
393    /// If @cancellable is not [`None`], then the operation can be cancelled by
394    /// triggering the cancellable object from another thread. If the operation
395    /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned. If an
396    /// operation was partially finished when the operation was cancelled the
397    /// partial result will be returned, without an error.
398    /// ## `count`
399    /// the number of bytes that will be skipped from the stream
400    /// ## `cancellable`
401    /// optional #GCancellable object, [`None`] to ignore.
402    ///
403    /// # Returns
404    ///
405    /// Number of bytes skipped, or -1 on error
406    #[doc(alias = "g_input_stream_skip")]
407    fn skip(
408        &self,
409        count: usize,
410        cancellable: Option<&impl IsA<Cancellable>>,
411    ) -> Result<isize, glib::Error> {
412        unsafe {
413            let mut error = std::ptr::null_mut();
414            let ret = ffi::g_input_stream_skip(
415                self.as_ref().to_glib_none().0,
416                count,
417                cancellable.map(|p| p.as_ref()).to_glib_none().0,
418                &mut error,
419            );
420            if error.is_null() {
421                Ok(ret)
422            } else {
423                Err(from_glib_full(error))
424            }
425        }
426    }
427
428    /// Request an asynchronous skip of @count bytes from the stream.
429    /// When the operation is finished @callback will be called.
430    /// You can then call g_input_stream_skip_finish() to get the result
431    /// of the operation.
432    ///
433    /// During an async request no other sync and async calls are allowed,
434    /// and will result in [`IOErrorEnum::Pending`][crate::IOErrorEnum::Pending] errors.
435    ///
436    /// A value of @count larger than `G_MAXSSIZE` will cause a [`IOErrorEnum::InvalidArgument`][crate::IOErrorEnum::InvalidArgument] error.
437    ///
438    /// On success, the number of bytes skipped will be passed to the callback.
439    /// It is not an error if this is not the same as the requested size, as it
440    /// can happen e.g. near the end of a file, but generally we try to skip
441    /// as many bytes as requested. Zero is returned on end of file
442    /// (or if @count is zero), but never otherwise.
443    ///
444    /// Any outstanding i/o request with higher priority (lower numerical value)
445    /// will be executed before an outstanding request with lower priority.
446    /// Default priority is `G_PRIORITY_DEFAULT`.
447    ///
448    /// The asynchronous methods have a default fallback that uses threads to
449    /// implement asynchronicity, so they are optional for inheriting classes.
450    /// However, if you override one, you must override all.
451    /// ## `count`
452    /// the number of bytes that will be skipped from the stream
453    /// ## `io_priority`
454    /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
455    /// ## `cancellable`
456    /// optional #GCancellable object, [`None`] to ignore.
457    /// ## `callback`
458    /// a #GAsyncReadyCallback
459    ///   to call when the request is satisfied
460    #[doc(alias = "g_input_stream_skip_async")]
461    fn skip_async<P: FnOnce(Result<isize, glib::Error>) + 'static>(
462        &self,
463        count: usize,
464        io_priority: glib::Priority,
465        cancellable: Option<&impl IsA<Cancellable>>,
466        callback: P,
467    ) {
468        let main_context = glib::MainContext::ref_thread_default();
469        let is_main_context_owner = main_context.is_owner();
470        let has_acquired_main_context = (!is_main_context_owner)
471            .then(|| main_context.acquire().ok())
472            .flatten();
473        assert!(
474            is_main_context_owner || has_acquired_main_context.is_some(),
475            "Async operations only allowed if the thread is owning the MainContext"
476        );
477
478        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
479            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
480        unsafe extern "C" fn skip_async_trampoline<
481            P: FnOnce(Result<isize, glib::Error>) + 'static,
482        >(
483            _source_object: *mut glib::gobject_ffi::GObject,
484            res: *mut crate::ffi::GAsyncResult,
485            user_data: glib::ffi::gpointer,
486        ) {
487            let mut error = std::ptr::null_mut();
488            let ret = ffi::g_input_stream_skip_finish(_source_object as *mut _, res, &mut error);
489            let result = if error.is_null() {
490                Ok(ret)
491            } else {
492                Err(from_glib_full(error))
493            };
494            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
495                Box_::from_raw(user_data as *mut _);
496            let callback: P = callback.into_inner();
497            callback(result);
498        }
499        let callback = skip_async_trampoline::<P>;
500        unsafe {
501            ffi::g_input_stream_skip_async(
502                self.as_ref().to_glib_none().0,
503                count,
504                io_priority.into_glib(),
505                cancellable.map(|p| p.as_ref()).to_glib_none().0,
506                Some(callback),
507                Box_::into_raw(user_data) as *mut _,
508            );
509        }
510    }
511
512    fn skip_future(
513        &self,
514        count: usize,
515        io_priority: glib::Priority,
516    ) -> Pin<Box_<dyn std::future::Future<Output = Result<isize, glib::Error>> + 'static>> {
517        Box_::pin(crate::GioFuture::new(
518            self,
519            move |obj, cancellable, send| {
520                obj.skip_async(count, io_priority, Some(cancellable), move |res| {
521                    send.resolve(res);
522                });
523            },
524        ))
525    }
526}
527
528impl<O: IsA<InputStream>> InputStreamExt for O {}