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