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