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