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 already been closed.
323 ///
324 /// # Returns
325 ///
326 /// [`true`] if @self is closed. [`false`] otherwise.
327 #[doc(alias = "g_output_stream_is_closed")]
328 fn is_closed(&self) -> bool {
329 unsafe {
330 from_glib(ffi::g_output_stream_is_closed(
331 self.as_ref().to_glib_none().0,
332 ))
333 }
334 }
335
336 /// Checks if an output stream is being closed. This can be
337 /// used inside e.g. a flush implementation to see if the
338 /// flush (or other i/o operation) is called from within
339 /// the closing operation.
340 ///
341 /// # Returns
342 ///
343 /// [`true`] if @self is being closed. [`false`] otherwise.
344 #[doc(alias = "g_output_stream_is_closing")]
345 fn is_closing(&self) -> bool {
346 unsafe {
347 from_glib(ffi::g_output_stream_is_closing(
348 self.as_ref().to_glib_none().0,
349 ))
350 }
351 }
352
353 //#[doc(alias = "g_output_stream_printf")]
354 //fn printf(&self, cancellable: Option<&impl IsA<Cancellable>>, error: &mut glib::Error, format: &str, : /*Unknown conversion*//*Unimplemented*/Basic: VarArgs) -> Option<usize> {
355 // unsafe { TODO: call ffi:g_output_stream_printf() }
356 //}
357
358 /// Sets @self to have actions pending. If the pending flag is
359 /// already set or @self is closed, it will return [`false`] and set
360 /// @error.
361 ///
362 /// # Returns
363 ///
364 /// [`true`] if pending was previously unset and is now set.
365 #[doc(alias = "g_output_stream_set_pending")]
366 fn set_pending(&self) -> Result<(), glib::Error> {
367 unsafe {
368 let mut error = std::ptr::null_mut();
369 let is_ok =
370 ffi::g_output_stream_set_pending(self.as_ref().to_glib_none().0, &mut error);
371 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
372 if error.is_null() {
373 Ok(())
374 } else {
375 Err(from_glib_full(error))
376 }
377 }
378 }
379
380 /// Splices an input stream into an output stream.
381 /// ## `source`
382 /// a #GInputStream.
383 /// ## `flags`
384 /// a set of #GOutputStreamSpliceFlags.
385 /// ## `cancellable`
386 /// optional #GCancellable object, [`None`] to ignore.
387 ///
388 /// # Returns
389 ///
390 /// a #gssize containing the size of the data spliced, or
391 /// -1 if an error occurred. Note that if the number of bytes
392 /// spliced is greater than `G_MAXSSIZE`, then that will be
393 /// returned, and there is no way to determine the actual number
394 /// of bytes spliced.
395 #[doc(alias = "g_output_stream_splice")]
396 fn splice(
397 &self,
398 source: &impl IsA<InputStream>,
399 flags: OutputStreamSpliceFlags,
400 cancellable: Option<&impl IsA<Cancellable>>,
401 ) -> Result<isize, glib::Error> {
402 unsafe {
403 let mut error = std::ptr::null_mut();
404 let ret = ffi::g_output_stream_splice(
405 self.as_ref().to_glib_none().0,
406 source.as_ref().to_glib_none().0,
407 flags.into_glib(),
408 cancellable.map(|p| p.as_ref()).to_glib_none().0,
409 &mut error,
410 );
411 if error.is_null() {
412 Ok(ret)
413 } else {
414 Err(from_glib_full(error))
415 }
416 }
417 }
418
419 /// Splices a stream asynchronously.
420 /// When the operation is finished @callback will be called.
421 /// You can then call g_output_stream_splice_finish() to get the
422 /// result of the operation.
423 ///
424 /// For the synchronous, blocking version of this function, see
425 /// g_output_stream_splice().
426 /// ## `source`
427 /// a #GInputStream.
428 /// ## `flags`
429 /// a set of #GOutputStreamSpliceFlags.
430 /// ## `io_priority`
431 /// the io priority of the request.
432 /// ## `cancellable`
433 /// optional #GCancellable object, [`None`] to ignore.
434 /// ## `callback`
435 /// a #GAsyncReadyCallback
436 /// to call when the request is satisfied
437 #[doc(alias = "g_output_stream_splice_async")]
438 fn splice_async<P: FnOnce(Result<isize, glib::Error>) + 'static>(
439 &self,
440 source: &impl IsA<InputStream>,
441 flags: OutputStreamSpliceFlags,
442 io_priority: glib::Priority,
443 cancellable: Option<&impl IsA<Cancellable>>,
444 callback: P,
445 ) {
446 let main_context = glib::MainContext::ref_thread_default();
447 let is_main_context_owner = main_context.is_owner();
448 let has_acquired_main_context = (!is_main_context_owner)
449 .then(|| main_context.acquire().ok())
450 .flatten();
451 assert!(
452 is_main_context_owner || has_acquired_main_context.is_some(),
453 "Async operations only allowed if the thread is owning the MainContext"
454 );
455
456 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
457 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
458 unsafe extern "C" fn splice_async_trampoline<
459 P: FnOnce(Result<isize, glib::Error>) + 'static,
460 >(
461 _source_object: *mut glib::gobject_ffi::GObject,
462 res: *mut crate::ffi::GAsyncResult,
463 user_data: glib::ffi::gpointer,
464 ) {
465 unsafe {
466 let mut error = std::ptr::null_mut();
467 let ret =
468 ffi::g_output_stream_splice_finish(_source_object as *mut _, res, &mut error);
469 let result = if error.is_null() {
470 Ok(ret)
471 } else {
472 Err(from_glib_full(error))
473 };
474 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
475 Box_::from_raw(user_data as *mut _);
476 let callback: P = callback.into_inner();
477 callback(result);
478 }
479 }
480 let callback = splice_async_trampoline::<P>;
481 unsafe {
482 ffi::g_output_stream_splice_async(
483 self.as_ref().to_glib_none().0,
484 source.as_ref().to_glib_none().0,
485 flags.into_glib(),
486 io_priority.into_glib(),
487 cancellable.map(|p| p.as_ref()).to_glib_none().0,
488 Some(callback),
489 Box_::into_raw(user_data) as *mut _,
490 );
491 }
492 }
493
494 fn splice_future(
495 &self,
496 source: &(impl IsA<InputStream> + Clone + 'static),
497 flags: OutputStreamSpliceFlags,
498 io_priority: glib::Priority,
499 ) -> Pin<Box_<dyn std::future::Future<Output = Result<isize, glib::Error>> + 'static>> {
500 let source = source.clone();
501 Box_::pin(crate::GioFuture::new(
502 self,
503 move |obj, cancellable, send| {
504 obj.splice_async(&source, flags, io_priority, Some(cancellable), move |res| {
505 send.resolve(res);
506 });
507 },
508 ))
509 }
510
511 //#[doc(alias = "g_output_stream_vprintf")]
512 //fn vprintf(&self, cancellable: Option<&impl IsA<Cancellable>>, error: &mut glib::Error, format: &str, args: /*Unknown conversion*//*Unimplemented*/Unsupported) -> Option<usize> {
513 // unsafe { TODO: call ffi:g_output_stream_vprintf() }
514 //}
515
516 /// Tries to write @count bytes from @buffer into the stream. Will block
517 /// during the operation.
518 ///
519 /// If count is 0, returns 0 and does nothing. A value of @count
520 /// larger than `G_MAXSSIZE` will cause a [`IOErrorEnum::InvalidArgument`][crate::IOErrorEnum::InvalidArgument] error.
521 ///
522 /// On success, the number of bytes written to the stream is returned.
523 /// It is not an error if this is not the same as the requested size, as it
524 /// can happen e.g. on a partial I/O error, or if there is not enough
525 /// storage in the stream. All writes block until at least one byte
526 /// is written or an error occurs; 0 is never returned (unless
527 /// @count is 0).
528 ///
529 /// If @cancellable is not [`None`], then the operation can be cancelled by
530 /// triggering the cancellable object from another thread. If the operation
531 /// was cancelled, the error [`IOErrorEnum::Cancelled`][crate::IOErrorEnum::Cancelled] will be returned. If an
532 /// operation was partially finished when the operation was cancelled the
533 /// partial result will be returned, without an error.
534 ///
535 /// On error -1 is returned and @error is set accordingly.
536 /// ## `buffer`
537 /// the buffer containing the data to write.
538 /// ## `cancellable`
539 /// optional cancellable object
540 ///
541 /// # Returns
542 ///
543 /// Number of bytes written, or -1 on error
544 #[doc(alias = "g_output_stream_write")]
545 fn write(
546 &self,
547 buffer: &[u8],
548 cancellable: Option<&impl IsA<Cancellable>>,
549 ) -> Result<isize, glib::Error> {
550 let count = buffer.len() as _;
551 unsafe {
552 let mut error = std::ptr::null_mut();
553 let ret = ffi::g_output_stream_write(
554 self.as_ref().to_glib_none().0,
555 buffer.to_glib_none().0,
556 count,
557 cancellable.map(|p| p.as_ref()).to_glib_none().0,
558 &mut error,
559 );
560 if error.is_null() {
561 Ok(ret)
562 } else {
563 Err(from_glib_full(error))
564 }
565 }
566 }
567
568 /// A wrapper function for g_output_stream_write() which takes a
569 /// #GBytes as input. This can be more convenient for use by language
570 /// bindings or in other cases where the refcounted nature of #GBytes
571 /// is helpful over a bare pointer interface.
572 ///
573 /// However, note that this function may still perform partial writes,
574 /// just like g_output_stream_write(). If that occurs, to continue
575 /// writing, you will need to create a new #GBytes containing just the
576 /// remaining bytes, using g_bytes_new_from_bytes(). Passing the same
577 /// #GBytes instance multiple times potentially can result in duplicated
578 /// data in the output stream.
579 /// ## `bytes`
580 /// the #GBytes to write
581 /// ## `cancellable`
582 /// optional cancellable object
583 ///
584 /// # Returns
585 ///
586 /// Number of bytes written, or -1 on error
587 #[doc(alias = "g_output_stream_write_bytes")]
588 fn write_bytes(
589 &self,
590 bytes: &glib::Bytes,
591 cancellable: Option<&impl IsA<Cancellable>>,
592 ) -> Result<isize, glib::Error> {
593 unsafe {
594 let mut error = std::ptr::null_mut();
595 let ret = ffi::g_output_stream_write_bytes(
596 self.as_ref().to_glib_none().0,
597 bytes.to_glib_none().0,
598 cancellable.map(|p| p.as_ref()).to_glib_none().0,
599 &mut error,
600 );
601 if error.is_null() {
602 Ok(ret)
603 } else {
604 Err(from_glib_full(error))
605 }
606 }
607 }
608
609 /// This function is similar to g_output_stream_write_async(), but
610 /// takes a #GBytes as input. Due to the refcounted nature of #GBytes,
611 /// this allows the stream to avoid taking a copy of the data.
612 ///
613 /// However, note that this function may still perform partial writes,
614 /// just like g_output_stream_write_async(). If that occurs, to continue
615 /// writing, you will need to create a new #GBytes containing just the
616 /// remaining bytes, using g_bytes_new_from_bytes(). Passing the same
617 /// #GBytes instance multiple times potentially can result in duplicated
618 /// data in the output stream.
619 ///
620 /// For the synchronous, blocking version of this function, see
621 /// g_output_stream_write_bytes().
622 /// ## `bytes`
623 /// The bytes to write
624 /// ## `io_priority`
625 /// the io priority of the request.
626 /// ## `cancellable`
627 /// optional #GCancellable object, [`None`] to ignore.
628 /// ## `callback`
629 /// a #GAsyncReadyCallback
630 /// to call when the request is satisfied
631 #[doc(alias = "g_output_stream_write_bytes_async")]
632 fn write_bytes_async<P: FnOnce(Result<isize, glib::Error>) + 'static>(
633 &self,
634 bytes: &glib::Bytes,
635 io_priority: glib::Priority,
636 cancellable: Option<&impl IsA<Cancellable>>,
637 callback: P,
638 ) {
639 let main_context = glib::MainContext::ref_thread_default();
640 let is_main_context_owner = main_context.is_owner();
641 let has_acquired_main_context = (!is_main_context_owner)
642 .then(|| main_context.acquire().ok())
643 .flatten();
644 assert!(
645 is_main_context_owner || has_acquired_main_context.is_some(),
646 "Async operations only allowed if the thread is owning the MainContext"
647 );
648
649 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
650 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
651 unsafe extern "C" fn write_bytes_async_trampoline<
652 P: FnOnce(Result<isize, glib::Error>) + 'static,
653 >(
654 _source_object: *mut glib::gobject_ffi::GObject,
655 res: *mut crate::ffi::GAsyncResult,
656 user_data: glib::ffi::gpointer,
657 ) {
658 unsafe {
659 let mut error = std::ptr::null_mut();
660 let ret = ffi::g_output_stream_write_bytes_finish(
661 _source_object as *mut _,
662 res,
663 &mut error,
664 );
665 let result = if error.is_null() {
666 Ok(ret)
667 } else {
668 Err(from_glib_full(error))
669 };
670 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
671 Box_::from_raw(user_data as *mut _);
672 let callback: P = callback.into_inner();
673 callback(result);
674 }
675 }
676 let callback = write_bytes_async_trampoline::<P>;
677 unsafe {
678 ffi::g_output_stream_write_bytes_async(
679 self.as_ref().to_glib_none().0,
680 bytes.to_glib_none().0,
681 io_priority.into_glib(),
682 cancellable.map(|p| p.as_ref()).to_glib_none().0,
683 Some(callback),
684 Box_::into_raw(user_data) as *mut _,
685 );
686 }
687 }
688
689 fn write_bytes_future(
690 &self,
691 bytes: &glib::Bytes,
692 io_priority: glib::Priority,
693 ) -> Pin<Box_<dyn std::future::Future<Output = Result<isize, glib::Error>> + 'static>> {
694 let bytes = bytes.clone();
695 Box_::pin(crate::GioFuture::new(
696 self,
697 move |obj, cancellable, send| {
698 obj.write_bytes_async(&bytes, io_priority, Some(cancellable), move |res| {
699 send.resolve(res);
700 });
701 },
702 ))
703 }
704}
705
706impl<O: IsA<OutputStream>> OutputStreamExt for O {}