gio/auto/output_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, InputStream, OutputStreamSpliceFlags, ffi};
6use glib::{prelude::*, translate::*};
7use std::{boxed::Box as Box_, pin::Pin};
8
9glib::wrapper! {
10 /// `GOutputStream` is a base class for implementing streaming output.
11 ///
12 /// It has functions to write to a stream ([`OutputStreamExt::write()`][crate::prelude::OutputStreamExt::write()]),
13 /// to close a stream ([`OutputStreamExt::close()`][crate::prelude::OutputStreamExt::close()]) and to flush pending
14 /// writes ([`OutputStreamExt::flush()`][crate::prelude::OutputStreamExt::flush()]).
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 /// All classes derived from `GOutputStream` *should* implement synchronous
25 /// writing, splicing, flushing and closing streams, but *may* implement
26 /// asynchronous versions.
27 ///
28 /// This is an Abstract Base Class, you cannot instantiate it.
29 ///
30 /// # Implements
31 ///
32 /// [`OutputStreamExt`][trait@crate::prelude::OutputStreamExt], [`trait@glib::ObjectExt`], [`OutputStreamExtManual`][trait@crate::prelude::OutputStreamExtManual]
33 #[doc(alias = "GOutputStream")]
34 pub struct OutputStream(Object<ffi::GOutputStream, ffi::GOutputStreamClass>);
35
36 match fn {
37 type_ => || ffi::g_output_stream_get_type(),
38 }
39}
40
41impl OutputStream {
42 pub const NONE: Option<&'static OutputStream> = None;
43}
44
45/// Trait containing all [`struct@OutputStream`] methods.
46///
47/// # Implementors
48///
49/// [`FileOutputStream`][struct@crate::FileOutputStream], [`FilterOutputStream`][struct@crate::FilterOutputStream], [`MemoryOutputStream`][struct@crate::MemoryOutputStream], [`OutputStream`][struct@crate::OutputStream], [`PollableOutputStream`][struct@crate::PollableOutputStream]
50pub trait OutputStreamExt: IsA<OutputStream> + 'static {
51 /// Clears the pending flag on @self.
52 #[doc(alias = "g_output_stream_clear_pending")]
53 fn clear_pending(&self) {
54 unsafe {
55 ffi::g_output_stream_clear_pending(self.as_ref().to_glib_none().0);
56 }
57 }
58
59 /// Closes the stream, releasing resources related to it.
60 ///
61 /// Once the stream is closed, all other operations will return [`IOErrorEnum::Closed`][crate::IOErrorEnum::Closed].
62 /// Closing a stream multiple times will not return an error.
63 ///
64 /// Closing a stream will automatically flush any outstanding buffers in the
65 /// stream.
66 ///
67 /// Streams will be automatically closed when the last reference
68 /// is dropped, but you might want to call this function to make sure
69 /// resources are released as early as possible.
70 ///
71 /// Some streams might keep the backing store of the stream (e.g. a file descriptor)
72 /// open after the stream is closed. See the documentation for the individual
73 /// stream for details.
74 ///
75 /// On failure the first error that happened will be reported, but the close
76 /// operation will finish as much as possible. A stream that failed to
77 /// close will still return [`IOErrorEnum::Closed`][crate::IOErrorEnum::Closed] for all operations. Still, it
78 /// is important to check and report the error to the user, otherwise
79 /// there might be a loss of data as all data might not be written.
80 ///
81 /// If @cancellable is not [`None`], then the operation can be cancelled by
82 /// triggering the cancellable object from another thread. If the operation
83 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
84 /// Cancelling a close will still leave the stream closed, but there some streams
85 /// can use a faster close that doesn't block to e.g. check errors. On
86 /// cancellation (as with any error) there is no guarantee that all written
87 /// data will reach the target.
88 /// ## `cancellable`
89 /// optional cancellable object
90 ///
91 /// # Returns
92 ///
93 /// [`true`] on success, [`false`] on failure
94 #[doc(alias = "g_output_stream_close")]
95 fn close(&self, cancellable: Option<&impl IsA<Cancellable>>) -> Result<(), glib::Error> {
96 unsafe {
97 let mut error = std::ptr::null_mut();
98 let is_ok = ffi::g_output_stream_close(
99 self.as_ref().to_glib_none().0,
100 cancellable.map(|p| p.as_ref()).to_glib_none().0,
101 &mut error,
102 );
103 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
104 if error.is_null() {
105 Ok(())
106 } else {
107 Err(from_glib_full(error))
108 }
109 }
110 }
111
112 /// Requests an asynchronous close of the stream, releasing resources
113 /// related to it. When the operation is finished @callback will be
114 /// called. You can then call g_output_stream_close_finish() to get
115 /// the result of the operation.
116 ///
117 /// For behaviour details see g_output_stream_close().
118 ///
119 /// The asynchronous methods have a default fallback that uses threads
120 /// to implement asynchronicity, so they are optional for inheriting
121 /// classes. However, if you override one you must override all.
122 /// ## `io_priority`
123 /// the io priority of the request.
124 /// ## `cancellable`
125 /// optional cancellable object
126 /// ## `callback`
127 /// a #GAsyncReadyCallback
128 /// to call when the request is satisfied
129 #[doc(alias = "g_output_stream_close_async")]
130 fn close_async<P: FnOnce(Result<(), glib::Error>) + 'static>(
131 &self,
132 io_priority: glib::Priority,
133 cancellable: Option<&impl IsA<Cancellable>>,
134 callback: P,
135 ) {
136 let main_context = glib::MainContext::ref_thread_default();
137 let is_main_context_owner = main_context.is_owner();
138 let has_acquired_main_context = (!is_main_context_owner)
139 .then(|| main_context.acquire().ok())
140 .flatten();
141 assert!(
142 is_main_context_owner || has_acquired_main_context.is_some(),
143 "Async operations only allowed if the thread is owning the MainContext"
144 );
145
146 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
147 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
148 unsafe extern "C" fn close_async_trampoline<
149 P: FnOnce(Result<(), glib::Error>) + 'static,
150 >(
151 _source_object: *mut glib::gobject_ffi::GObject,
152 res: *mut crate::ffi::GAsyncResult,
153 user_data: glib::ffi::gpointer,
154 ) {
155 unsafe {
156 let mut error = std::ptr::null_mut();
157 ffi::g_output_stream_close_finish(_source_object as *mut _, res, &mut error);
158 let result = if error.is_null() {
159 Ok(())
160 } else {
161 Err(from_glib_full(error))
162 };
163 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
164 Box_::from_raw(user_data as *mut _);
165 let callback: P = callback.into_inner();
166 callback(result);
167 }
168 }
169 let callback = close_async_trampoline::<P>;
170 unsafe {
171 ffi::g_output_stream_close_async(
172 self.as_ref().to_glib_none().0,
173 io_priority.into_glib(),
174 cancellable.map(|p| p.as_ref()).to_glib_none().0,
175 Some(callback),
176 Box_::into_raw(user_data) as *mut _,
177 );
178 }
179 }
180
181 fn close_future(
182 &self,
183 io_priority: glib::Priority,
184 ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
185 Box_::pin(crate::GioFuture::new(
186 self,
187 move |obj, cancellable, send| {
188 obj.close_async(io_priority, Some(cancellable), move |res| {
189 send.resolve(res);
190 });
191 },
192 ))
193 }
194
195 /// Forces a write of all user-space buffered data for the given
196 /// @self. Will block during the operation. Closing the stream will
197 /// implicitly cause a flush.
198 ///
199 /// This function is optional for inherited classes.
200 ///
201 /// If @cancellable is not [`None`], then the operation can be cancelled by
202 /// triggering the cancellable object from another thread. If the operation
203 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned.
204 /// ## `cancellable`
205 /// optional cancellable object
206 ///
207 /// # Returns
208 ///
209 /// [`true`] on success, [`false`] on error
210 #[doc(alias = "g_output_stream_flush")]
211 fn flush(&self, cancellable: Option<&impl IsA<Cancellable>>) -> Result<(), glib::Error> {
212 unsafe {
213 let mut error = std::ptr::null_mut();
214 let is_ok = ffi::g_output_stream_flush(
215 self.as_ref().to_glib_none().0,
216 cancellable.map(|p| p.as_ref()).to_glib_none().0,
217 &mut error,
218 );
219 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
220 if error.is_null() {
221 Ok(())
222 } else {
223 Err(from_glib_full(error))
224 }
225 }
226 }
227
228 /// Forces an asynchronous write of all user-space buffered data for
229 /// the given @self.
230 /// For behaviour details see g_output_stream_flush().
231 ///
232 /// When the operation is finished @callback will be
233 /// called. You can then call g_output_stream_flush_finish() to get the
234 /// result of the operation.
235 /// ## `io_priority`
236 /// the io priority of the request.
237 /// ## `cancellable`
238 /// optional #GCancellable object, [`None`] to ignore.
239 /// ## `callback`
240 /// a #GAsyncReadyCallback
241 /// to call when the request is satisfied
242 #[doc(alias = "g_output_stream_flush_async")]
243 fn flush_async<P: FnOnce(Result<(), glib::Error>) + 'static>(
244 &self,
245 io_priority: glib::Priority,
246 cancellable: Option<&impl IsA<Cancellable>>,
247 callback: P,
248 ) {
249 let main_context = glib::MainContext::ref_thread_default();
250 let is_main_context_owner = main_context.is_owner();
251 let has_acquired_main_context = (!is_main_context_owner)
252 .then(|| main_context.acquire().ok())
253 .flatten();
254 assert!(
255 is_main_context_owner || has_acquired_main_context.is_some(),
256 "Async operations only allowed if the thread is owning the MainContext"
257 );
258
259 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
260 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
261 unsafe extern "C" fn flush_async_trampoline<
262 P: FnOnce(Result<(), glib::Error>) + 'static,
263 >(
264 _source_object: *mut glib::gobject_ffi::GObject,
265 res: *mut crate::ffi::GAsyncResult,
266 user_data: glib::ffi::gpointer,
267 ) {
268 unsafe {
269 let mut error = std::ptr::null_mut();
270 ffi::g_output_stream_flush_finish(_source_object as *mut _, res, &mut error);
271 let result = if error.is_null() {
272 Ok(())
273 } else {
274 Err(from_glib_full(error))
275 };
276 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
277 Box_::from_raw(user_data as *mut _);
278 let callback: P = callback.into_inner();
279 callback(result);
280 }
281 }
282 let callback = flush_async_trampoline::<P>;
283 unsafe {
284 ffi::g_output_stream_flush_async(
285 self.as_ref().to_glib_none().0,
286 io_priority.into_glib(),
287 cancellable.map(|p| p.as_ref()).to_glib_none().0,
288 Some(callback),
289 Box_::into_raw(user_data) as *mut _,
290 );
291 }
292 }
293
294 fn flush_future(
295 &self,
296 io_priority: glib::Priority,
297 ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
298 Box_::pin(crate::GioFuture::new(
299 self,
300 move |obj, cancellable, send| {
301 obj.flush_async(io_priority, Some(cancellable), move |res| {
302 send.resolve(res);
303 });
304 },
305 ))
306 }
307
308 /// Checks if an output stream has pending actions.
309 ///
310 /// # Returns
311 ///
312 /// [`true`] if @self has pending actions.
313 #[doc(alias = "g_output_stream_has_pending")]
314 fn has_pending(&self) -> bool {
315 unsafe {
316 from_glib(ffi::g_output_stream_has_pending(
317 self.as_ref().to_glib_none().0,
318 ))
319 }
320 }
321
322 /// Checks if an output stream has been closed.
323 ///
324 /// This only indicates whether the stream has been closed from this end by
325 /// calling [`close()`][Self::close()]. If the stream is a pipe or socket,
326 /// for example, and the process on the other end has closed its end, this method
327 /// will still return false. Methods which try to write to the output stream will
328 /// return an error, however.
329 ///
330 /// # Returns
331 ///
332 /// true if the stream has been closed; false otherwise
333 #[doc(alias = "g_output_stream_is_closed")]
334 fn is_closed(&self) -> bool {
335 unsafe {
336 from_glib(ffi::g_output_stream_is_closed(
337 self.as_ref().to_glib_none().0,
338 ))
339 }
340 }
341
342 /// Checks if an output stream is being closed. This can be
343 /// used inside e.g. a flush implementation to see if the
344 /// flush (or other i/o operation) is called from within
345 /// the closing operation.
346 ///
347 /// # Returns
348 ///
349 /// [`true`] if @self is being closed. [`false`] otherwise.
350 #[doc(alias = "g_output_stream_is_closing")]
351 fn is_closing(&self) -> bool {
352 unsafe {
353 from_glib(ffi::g_output_stream_is_closing(
354 self.as_ref().to_glib_none().0,
355 ))
356 }
357 }
358
359 //#[doc(alias = "g_output_stream_printf")]
360 //fn printf(&self, cancellable: Option<&impl IsA<Cancellable>>, error: &mut glib::Error, format: &str, : /*Unknown conversion*//*Unimplemented*/Basic: VarArgs) -> Option<usize> {
361 // unsafe { TODO: call ffi:g_output_stream_printf() }
362 //}
363
364 /// Sets @self to have actions pending. If the pending flag is
365 /// already set or @self is closed, it will return [`false`] and set
366 /// @error.
367 ///
368 /// # Returns
369 ///
370 /// [`true`] if pending was previously unset and is now set.
371 #[doc(alias = "g_output_stream_set_pending")]
372 fn set_pending(&self) -> Result<(), glib::Error> {
373 unsafe {
374 let mut error = std::ptr::null_mut();
375 let is_ok =
376 ffi::g_output_stream_set_pending(self.as_ref().to_glib_none().0, &mut error);
377 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
378 if error.is_null() {
379 Ok(())
380 } else {
381 Err(from_glib_full(error))
382 }
383 }
384 }
385
386 /// Splices an input stream into an output stream.
387 /// ## `source`
388 /// a #GInputStream.
389 /// ## `flags`
390 /// a set of #GOutputStreamSpliceFlags.
391 /// ## `cancellable`
392 /// optional #GCancellable object, [`None`] to ignore.
393 ///
394 /// # Returns
395 ///
396 /// a #gssize containing the size of the data spliced, or
397 /// -1 if an error occurred. Note that if the number of bytes
398 /// spliced is greater than `G_MAXSSIZE`, then that will be
399 /// returned, and there is no way to determine the actual number
400 /// of bytes spliced.
401 #[doc(alias = "g_output_stream_splice")]
402 fn splice(
403 &self,
404 source: &impl IsA<InputStream>,
405 flags: OutputStreamSpliceFlags,
406 cancellable: Option<&impl IsA<Cancellable>>,
407 ) -> Result<isize, glib::Error> {
408 unsafe {
409 let mut error = std::ptr::null_mut();
410 let ret = ffi::g_output_stream_splice(
411 self.as_ref().to_glib_none().0,
412 source.as_ref().to_glib_none().0,
413 flags.into_glib(),
414 cancellable.map(|p| p.as_ref()).to_glib_none().0,
415 &mut error,
416 );
417 if error.is_null() {
418 Ok(ret)
419 } else {
420 Err(from_glib_full(error))
421 }
422 }
423 }
424
425 /// Splices a stream asynchronously.
426 /// When the operation is finished @callback will be called.
427 /// You can then call g_output_stream_splice_finish() to get the
428 /// result of the operation.
429 ///
430 /// For the synchronous, blocking version of this function, see
431 /// g_output_stream_splice().
432 /// ## `source`
433 /// a #GInputStream.
434 /// ## `flags`
435 /// a set of #GOutputStreamSpliceFlags.
436 /// ## `io_priority`
437 /// the io priority of the request.
438 /// ## `cancellable`
439 /// optional #GCancellable object, [`None`] to ignore.
440 /// ## `callback`
441 /// a #GAsyncReadyCallback
442 /// to call when the request is satisfied
443 #[doc(alias = "g_output_stream_splice_async")]
444 fn splice_async<P: FnOnce(Result<isize, glib::Error>) + 'static>(
445 &self,
446 source: &impl IsA<InputStream>,
447 flags: OutputStreamSpliceFlags,
448 io_priority: glib::Priority,
449 cancellable: Option<&impl IsA<Cancellable>>,
450 callback: P,
451 ) {
452 let main_context = glib::MainContext::ref_thread_default();
453 let is_main_context_owner = main_context.is_owner();
454 let has_acquired_main_context = (!is_main_context_owner)
455 .then(|| main_context.acquire().ok())
456 .flatten();
457 assert!(
458 is_main_context_owner || has_acquired_main_context.is_some(),
459 "Async operations only allowed if the thread is owning the MainContext"
460 );
461
462 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
463 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
464 unsafe extern "C" fn splice_async_trampoline<
465 P: FnOnce(Result<isize, glib::Error>) + 'static,
466 >(
467 _source_object: *mut glib::gobject_ffi::GObject,
468 res: *mut crate::ffi::GAsyncResult,
469 user_data: glib::ffi::gpointer,
470 ) {
471 unsafe {
472 let mut error = std::ptr::null_mut();
473 let ret =
474 ffi::g_output_stream_splice_finish(_source_object as *mut _, res, &mut error);
475 let result = if error.is_null() {
476 Ok(ret)
477 } else {
478 Err(from_glib_full(error))
479 };
480 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
481 Box_::from_raw(user_data as *mut _);
482 let callback: P = callback.into_inner();
483 callback(result);
484 }
485 }
486 let callback = splice_async_trampoline::<P>;
487 unsafe {
488 ffi::g_output_stream_splice_async(
489 self.as_ref().to_glib_none().0,
490 source.as_ref().to_glib_none().0,
491 flags.into_glib(),
492 io_priority.into_glib(),
493 cancellable.map(|p| p.as_ref()).to_glib_none().0,
494 Some(callback),
495 Box_::into_raw(user_data) as *mut _,
496 );
497 }
498 }
499
500 fn splice_future(
501 &self,
502 source: &(impl IsA<InputStream> + Clone + 'static),
503 flags: OutputStreamSpliceFlags,
504 io_priority: glib::Priority,
505 ) -> Pin<Box_<dyn std::future::Future<Output = Result<isize, glib::Error>> + 'static>> {
506 let source = source.clone();
507 Box_::pin(crate::GioFuture::new(
508 self,
509 move |obj, cancellable, send| {
510 obj.splice_async(&source, flags, io_priority, Some(cancellable), move |res| {
511 send.resolve(res);
512 });
513 },
514 ))
515 }
516
517 //#[doc(alias = "g_output_stream_vprintf")]
518 //fn vprintf(&self, cancellable: Option<&impl IsA<Cancellable>>, error: &mut glib::Error, format: &str, args: /*Unknown conversion*//*Unimplemented*/Unsupported) -> Option<usize> {
519 // unsafe { TODO: call ffi:g_output_stream_vprintf() }
520 //}
521
522 /// Tries to write @count bytes from @buffer into the stream. Will block
523 /// during the operation.
524 ///
525 /// If count is 0, returns 0 and does nothing. A value of @count
526 /// larger than `G_MAXSSIZE` will cause a [`IOErrorEnum::InvalidArgument`][crate::IOErrorEnum::InvalidArgument] error.
527 ///
528 /// On success, the number of bytes written to the stream is returned.
529 /// It is not an error if this is not the same as the requested size, as it
530 /// can happen e.g. on a partial I/O error, or if there is not enough
531 /// storage in the stream. All writes block until at least one byte
532 /// is written or an error occurs; 0 is never returned (unless
533 /// @count is 0).
534 ///
535 /// If @cancellable is not [`None`], then the operation can be cancelled by
536 /// triggering the cancellable object from another thread. If the operation
537 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned. If an
538 /// operation was partially finished when the operation was cancelled the
539 /// partial result will be returned, without an error.
540 ///
541 /// On error -1 is returned and @error is set accordingly.
542 /// ## `buffer`
543 /// the buffer containing the data to write.
544 /// ## `cancellable`
545 /// optional cancellable object
546 ///
547 /// # Returns
548 ///
549 /// Number of bytes written, or -1 on error
550 #[doc(alias = "g_output_stream_write")]
551 fn write(
552 &self,
553 buffer: &[u8],
554 cancellable: Option<&impl IsA<Cancellable>>,
555 ) -> Result<isize, glib::Error> {
556 let count = buffer.len() as _;
557 unsafe {
558 let mut error = std::ptr::null_mut();
559 let ret = ffi::g_output_stream_write(
560 self.as_ref().to_glib_none().0,
561 buffer.to_glib_none().0,
562 count,
563 cancellable.map(|p| p.as_ref()).to_glib_none().0,
564 &mut error,
565 );
566 if error.is_null() {
567 Ok(ret)
568 } else {
569 Err(from_glib_full(error))
570 }
571 }
572 }
573
574 /// A wrapper function for g_output_stream_write() which takes a
575 /// #GBytes as input. This can be more convenient for use by language
576 /// bindings or in other cases where the refcounted nature of #GBytes
577 /// is helpful over a bare pointer interface.
578 ///
579 /// However, note that this function may still perform partial writes,
580 /// just like g_output_stream_write(). If that occurs, to continue
581 /// writing, you will need to create a new #GBytes containing just the
582 /// remaining bytes, using g_bytes_new_from_bytes(). Passing the same
583 /// #GBytes instance multiple times potentially can result in duplicated
584 /// data in the output stream.
585 /// ## `bytes`
586 /// the #GBytes to write
587 /// ## `cancellable`
588 /// optional cancellable object
589 ///
590 /// # Returns
591 ///
592 /// Number of bytes written, or -1 on error
593 #[doc(alias = "g_output_stream_write_bytes")]
594 fn write_bytes(
595 &self,
596 bytes: &glib::Bytes,
597 cancellable: Option<&impl IsA<Cancellable>>,
598 ) -> Result<isize, glib::Error> {
599 unsafe {
600 let mut error = std::ptr::null_mut();
601 let ret = ffi::g_output_stream_write_bytes(
602 self.as_ref().to_glib_none().0,
603 bytes.to_glib_none().0,
604 cancellable.map(|p| p.as_ref()).to_glib_none().0,
605 &mut error,
606 );
607 if error.is_null() {
608 Ok(ret)
609 } else {
610 Err(from_glib_full(error))
611 }
612 }
613 }
614
615 /// This function is similar to g_output_stream_write_async(), but
616 /// takes a #GBytes as input. Due to the refcounted nature of #GBytes,
617 /// this allows the stream to avoid taking a copy of the data.
618 ///
619 /// However, note that this function may still perform partial writes,
620 /// just like g_output_stream_write_async(). If that occurs, to continue
621 /// writing, you will need to create a new #GBytes containing just the
622 /// remaining bytes, using g_bytes_new_from_bytes(). Passing the same
623 /// #GBytes instance multiple times potentially can result in duplicated
624 /// data in the output stream.
625 ///
626 /// For the synchronous, blocking version of this function, see
627 /// g_output_stream_write_bytes().
628 /// ## `bytes`
629 /// The bytes to write
630 /// ## `io_priority`
631 /// the io priority of the request.
632 /// ## `cancellable`
633 /// optional #GCancellable object, [`None`] to ignore.
634 /// ## `callback`
635 /// a #GAsyncReadyCallback
636 /// to call when the request is satisfied
637 #[doc(alias = "g_output_stream_write_bytes_async")]
638 fn write_bytes_async<P: FnOnce(Result<isize, glib::Error>) + 'static>(
639 &self,
640 bytes: &glib::Bytes,
641 io_priority: glib::Priority,
642 cancellable: Option<&impl IsA<Cancellable>>,
643 callback: P,
644 ) {
645 let main_context = glib::MainContext::ref_thread_default();
646 let is_main_context_owner = main_context.is_owner();
647 let has_acquired_main_context = (!is_main_context_owner)
648 .then(|| main_context.acquire().ok())
649 .flatten();
650 assert!(
651 is_main_context_owner || has_acquired_main_context.is_some(),
652 "Async operations only allowed if the thread is owning the MainContext"
653 );
654
655 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
656 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
657 unsafe extern "C" fn write_bytes_async_trampoline<
658 P: FnOnce(Result<isize, glib::Error>) + 'static,
659 >(
660 _source_object: *mut glib::gobject_ffi::GObject,
661 res: *mut crate::ffi::GAsyncResult,
662 user_data: glib::ffi::gpointer,
663 ) {
664 unsafe {
665 let mut error = std::ptr::null_mut();
666 let ret = ffi::g_output_stream_write_bytes_finish(
667 _source_object as *mut _,
668 res,
669 &mut error,
670 );
671 let result = if error.is_null() {
672 Ok(ret)
673 } else {
674 Err(from_glib_full(error))
675 };
676 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
677 Box_::from_raw(user_data as *mut _);
678 let callback: P = callback.into_inner();
679 callback(result);
680 }
681 }
682 let callback = write_bytes_async_trampoline::<P>;
683 unsafe {
684 ffi::g_output_stream_write_bytes_async(
685 self.as_ref().to_glib_none().0,
686 bytes.to_glib_none().0,
687 io_priority.into_glib(),
688 cancellable.map(|p| p.as_ref()).to_glib_none().0,
689 Some(callback),
690 Box_::into_raw(user_data) as *mut _,
691 );
692 }
693 }
694
695 fn write_bytes_future(
696 &self,
697 bytes: &glib::Bytes,
698 io_priority: glib::Priority,
699 ) -> Pin<Box_<dyn std::future::Future<Output = Result<isize, glib::Error>> + 'static>> {
700 let bytes = bytes.clone();
701 Box_::pin(crate::GioFuture::new(
702 self,
703 move |obj, cancellable, send| {
704 obj.write_bytes_async(&bytes, io_priority, Some(cancellable), move |res| {
705 send.resolve(res);
706 });
707 },
708 ))
709 }
710}
711
712impl<O: IsA<OutputStream>> OutputStreamExt for O {}