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