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 {}