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