1#[cfg(feature = "futures")]
6use futures::future;
7use gio_sys;
8use glib;
9use glib::object::IsA;
10use glib::translate::*;
11use glib_sys;
12use gobject_sys;
13#[cfg(feature = "futures")]
14use std::boxed::Box as Box_;
15use std::fmt;
16use std::ptr;
17use Cancellable;
18use Error;
19use InputStream;
20use OutputStreamSpliceFlags;
21
22glib_wrapper! {
23 pub struct OutputStream(Object<gio_sys::GOutputStream, gio_sys::GOutputStreamClass, OutputStreamClass>);
24
25 match fn {
26 get_type => || gio_sys::g_output_stream_get_type(),
27 }
28}
29
30pub const NONE_OUTPUT_STREAM: Option<&OutputStream> = None;
31
32pub trait OutputStreamExt: 'static {
33 fn clear_pending(&self);
34
35 fn close<P: IsA<Cancellable>>(&self, cancellable: Option<&P>) -> Result<(), Error>;
36
37 fn close_async<P: IsA<Cancellable>, Q: FnOnce(Result<(), Error>) + Send + 'static>(
38 &self,
39 io_priority: glib::Priority,
40 cancellable: Option<&P>,
41 callback: Q,
42 );
43
44 #[cfg(feature = "futures")]
45 fn close_async_future(
46 &self,
47 io_priority: glib::Priority,
48 ) -> Box_<dyn future::Future<Output = Result<(), Error>> + std::marker::Unpin>;
49
50 fn flush<P: IsA<Cancellable>>(&self, cancellable: Option<&P>) -> Result<(), Error>;
51
52 fn flush_async<P: IsA<Cancellable>, Q: FnOnce(Result<(), Error>) + Send + 'static>(
53 &self,
54 io_priority: glib::Priority,
55 cancellable: Option<&P>,
56 callback: Q,
57 );
58
59 #[cfg(feature = "futures")]
60 fn flush_async_future(
61 &self,
62 io_priority: glib::Priority,
63 ) -> Box_<dyn future::Future<Output = Result<(), Error>> + std::marker::Unpin>;
64
65 fn has_pending(&self) -> bool;
66
67 fn is_closed(&self) -> bool;
68
69 fn is_closing(&self) -> bool;
70
71 fn set_pending(&self) -> Result<(), Error>;
74
75 fn splice<P: IsA<InputStream>, Q: IsA<Cancellable>>(
76 &self,
77 source: &P,
78 flags: OutputStreamSpliceFlags,
79 cancellable: Option<&Q>,
80 ) -> Result<isize, Error>;
81
82 fn splice_async<
83 P: IsA<InputStream>,
84 Q: IsA<Cancellable>,
85 R: FnOnce(Result<isize, Error>) + Send + 'static,
86 >(
87 &self,
88 source: &P,
89 flags: OutputStreamSpliceFlags,
90 io_priority: glib::Priority,
91 cancellable: Option<&Q>,
92 callback: R,
93 );
94
95 #[cfg(feature = "futures")]
96 fn splice_async_future<P: IsA<InputStream> + Clone + 'static>(
97 &self,
98 source: &P,
99 flags: OutputStreamSpliceFlags,
100 io_priority: glib::Priority,
101 ) -> Box_<dyn future::Future<Output = Result<isize, Error>> + std::marker::Unpin>;
102
103 fn write<P: IsA<Cancellable>>(
106 &self,
107 buffer: &[u8],
108 cancellable: Option<&P>,
109 ) -> Result<isize, Error>;
110
111 fn write_bytes<P: IsA<Cancellable>>(
112 &self,
113 bytes: &glib::Bytes,
114 cancellable: Option<&P>,
115 ) -> Result<isize, Error>;
116
117 fn write_bytes_async<P: IsA<Cancellable>, Q: FnOnce(Result<isize, Error>) + Send + 'static>(
118 &self,
119 bytes: &glib::Bytes,
120 io_priority: glib::Priority,
121 cancellable: Option<&P>,
122 callback: Q,
123 );
124
125 #[cfg(feature = "futures")]
126 fn write_bytes_async_future(
127 &self,
128 bytes: &glib::Bytes,
129 io_priority: glib::Priority,
130 ) -> Box_<dyn future::Future<Output = Result<isize, Error>> + std::marker::Unpin>;
131}
132
133impl<O: IsA<OutputStream>> OutputStreamExt for O {
134 fn clear_pending(&self) {
135 unsafe {
136 gio_sys::g_output_stream_clear_pending(self.as_ref().to_glib_none().0);
137 }
138 }
139
140 fn close<P: IsA<Cancellable>>(&self, cancellable: Option<&P>) -> Result<(), Error> {
141 unsafe {
142 let mut error = ptr::null_mut();
143 let _ = gio_sys::g_output_stream_close(
144 self.as_ref().to_glib_none().0,
145 cancellable.map(|p| p.as_ref()).to_glib_none().0,
146 &mut error,
147 );
148 if error.is_null() {
149 Ok(())
150 } else {
151 Err(from_glib_full(error))
152 }
153 }
154 }
155
156 fn close_async<P: IsA<Cancellable>, Q: FnOnce(Result<(), Error>) + Send + 'static>(
157 &self,
158 io_priority: glib::Priority,
159 cancellable: Option<&P>,
160 callback: Q,
161 ) {
162 let user_data: Box<Q> = Box::new(callback);
163 unsafe extern "C" fn close_async_trampoline<
164 Q: FnOnce(Result<(), Error>) + Send + 'static,
165 >(
166 _source_object: *mut gobject_sys::GObject,
167 res: *mut gio_sys::GAsyncResult,
168 user_data: glib_sys::gpointer,
169 ) {
170 let mut error = ptr::null_mut();
171 let _ =
172 gio_sys::g_output_stream_close_finish(_source_object as *mut _, res, &mut error);
173 let result = if error.is_null() {
174 Ok(())
175 } else {
176 Err(from_glib_full(error))
177 };
178 let callback: Box<Q> = Box::from_raw(user_data as *mut _);
179 callback(result);
180 }
181 let callback = close_async_trampoline::<Q>;
182 unsafe {
183 gio_sys::g_output_stream_close_async(
184 self.as_ref().to_glib_none().0,
185 io_priority.to_glib(),
186 cancellable.map(|p| p.as_ref()).to_glib_none().0,
187 Some(callback),
188 Box::into_raw(user_data) as *mut _,
189 );
190 }
191 }
192
193 #[cfg(feature = "futures")]
194 fn close_async_future(
195 &self,
196 io_priority: glib::Priority,
197 ) -> Box_<dyn future::Future<Output = Result<(), Error>> + std::marker::Unpin> {
198 use fragile::Fragile;
199 use GioFuture;
200
201 GioFuture::new(self, move |obj, send| {
202 let cancellable = Cancellable::new();
203 let send = Fragile::new(send);
204 obj.close_async(io_priority, Some(&cancellable), move |res| {
205 let _ = send.into_inner().send(res);
206 });
207
208 cancellable
209 })
210 }
211
212 fn flush<P: IsA<Cancellable>>(&self, cancellable: Option<&P>) -> Result<(), Error> {
213 unsafe {
214 let mut error = ptr::null_mut();
215 let _ = gio_sys::g_output_stream_flush(
216 self.as_ref().to_glib_none().0,
217 cancellable.map(|p| p.as_ref()).to_glib_none().0,
218 &mut error,
219 );
220 if error.is_null() {
221 Ok(())
222 } else {
223 Err(from_glib_full(error))
224 }
225 }
226 }
227
228 fn flush_async<P: IsA<Cancellable>, Q: FnOnce(Result<(), Error>) + Send + 'static>(
229 &self,
230 io_priority: glib::Priority,
231 cancellable: Option<&P>,
232 callback: Q,
233 ) {
234 let user_data: Box<Q> = Box::new(callback);
235 unsafe extern "C" fn flush_async_trampoline<
236 Q: FnOnce(Result<(), Error>) + Send + 'static,
237 >(
238 _source_object: *mut gobject_sys::GObject,
239 res: *mut gio_sys::GAsyncResult,
240 user_data: glib_sys::gpointer,
241 ) {
242 let mut error = ptr::null_mut();
243 let _ =
244 gio_sys::g_output_stream_flush_finish(_source_object as *mut _, res, &mut error);
245 let result = if error.is_null() {
246 Ok(())
247 } else {
248 Err(from_glib_full(error))
249 };
250 let callback: Box<Q> = Box::from_raw(user_data as *mut _);
251 callback(result);
252 }
253 let callback = flush_async_trampoline::<Q>;
254 unsafe {
255 gio_sys::g_output_stream_flush_async(
256 self.as_ref().to_glib_none().0,
257 io_priority.to_glib(),
258 cancellable.map(|p| p.as_ref()).to_glib_none().0,
259 Some(callback),
260 Box::into_raw(user_data) as *mut _,
261 );
262 }
263 }
264
265 #[cfg(feature = "futures")]
266 fn flush_async_future(
267 &self,
268 io_priority: glib::Priority,
269 ) -> Box_<dyn future::Future<Output = Result<(), Error>> + std::marker::Unpin> {
270 use fragile::Fragile;
271 use GioFuture;
272
273 GioFuture::new(self, move |obj, send| {
274 let cancellable = Cancellable::new();
275 let send = Fragile::new(send);
276 obj.flush_async(io_priority, Some(&cancellable), move |res| {
277 let _ = send.into_inner().send(res);
278 });
279
280 cancellable
281 })
282 }
283
284 fn has_pending(&self) -> bool {
285 unsafe {
286 from_glib(gio_sys::g_output_stream_has_pending(
287 self.as_ref().to_glib_none().0,
288 ))
289 }
290 }
291
292 fn is_closed(&self) -> bool {
293 unsafe {
294 from_glib(gio_sys::g_output_stream_is_closed(
295 self.as_ref().to_glib_none().0,
296 ))
297 }
298 }
299
300 fn is_closing(&self) -> bool {
301 unsafe {
302 from_glib(gio_sys::g_output_stream_is_closing(
303 self.as_ref().to_glib_none().0,
304 ))
305 }
306 }
307
308 fn set_pending(&self) -> Result<(), Error> {
313 unsafe {
314 let mut error = ptr::null_mut();
315 let _ =
316 gio_sys::g_output_stream_set_pending(self.as_ref().to_glib_none().0, &mut error);
317 if error.is_null() {
318 Ok(())
319 } else {
320 Err(from_glib_full(error))
321 }
322 }
323 }
324
325 fn splice<P: IsA<InputStream>, Q: IsA<Cancellable>>(
326 &self,
327 source: &P,
328 flags: OutputStreamSpliceFlags,
329 cancellable: Option<&Q>,
330 ) -> Result<isize, Error> {
331 unsafe {
332 let mut error = ptr::null_mut();
333 let ret = gio_sys::g_output_stream_splice(
334 self.as_ref().to_glib_none().0,
335 source.as_ref().to_glib_none().0,
336 flags.to_glib(),
337 cancellable.map(|p| p.as_ref()).to_glib_none().0,
338 &mut error,
339 );
340 if error.is_null() {
341 Ok(ret)
342 } else {
343 Err(from_glib_full(error))
344 }
345 }
346 }
347
348 fn splice_async<
349 P: IsA<InputStream>,
350 Q: IsA<Cancellable>,
351 R: FnOnce(Result<isize, Error>) + Send + 'static,
352 >(
353 &self,
354 source: &P,
355 flags: OutputStreamSpliceFlags,
356 io_priority: glib::Priority,
357 cancellable: Option<&Q>,
358 callback: R,
359 ) {
360 let user_data: Box<R> = Box::new(callback);
361 unsafe extern "C" fn splice_async_trampoline<
362 R: FnOnce(Result<isize, Error>) + Send + 'static,
363 >(
364 _source_object: *mut gobject_sys::GObject,
365 res: *mut gio_sys::GAsyncResult,
366 user_data: glib_sys::gpointer,
367 ) {
368 let mut error = ptr::null_mut();
369 let ret =
370 gio_sys::g_output_stream_splice_finish(_source_object as *mut _, res, &mut error);
371 let result = if error.is_null() {
372 Ok(ret)
373 } else {
374 Err(from_glib_full(error))
375 };
376 let callback: Box<R> = Box::from_raw(user_data as *mut _);
377 callback(result);
378 }
379 let callback = splice_async_trampoline::<R>;
380 unsafe {
381 gio_sys::g_output_stream_splice_async(
382 self.as_ref().to_glib_none().0,
383 source.as_ref().to_glib_none().0,
384 flags.to_glib(),
385 io_priority.to_glib(),
386 cancellable.map(|p| p.as_ref()).to_glib_none().0,
387 Some(callback),
388 Box::into_raw(user_data) as *mut _,
389 );
390 }
391 }
392
393 #[cfg(feature = "futures")]
394 fn splice_async_future<P: IsA<InputStream> + Clone + 'static>(
395 &self,
396 source: &P,
397 flags: OutputStreamSpliceFlags,
398 io_priority: glib::Priority,
399 ) -> Box_<dyn future::Future<Output = Result<isize, Error>> + std::marker::Unpin> {
400 use fragile::Fragile;
401 use GioFuture;
402
403 let source = source.clone();
404 GioFuture::new(self, move |obj, send| {
405 let cancellable = Cancellable::new();
406 let send = Fragile::new(send);
407 obj.splice_async(
408 &source,
409 flags,
410 io_priority,
411 Some(&cancellable),
412 move |res| {
413 let _ = send.into_inner().send(res);
414 },
415 );
416
417 cancellable
418 })
419 }
420
421 fn write<P: IsA<Cancellable>>(
426 &self,
427 buffer: &[u8],
428 cancellable: Option<&P>,
429 ) -> Result<isize, Error> {
430 let count = buffer.len() as usize;
431 unsafe {
432 let mut error = ptr::null_mut();
433 let ret = gio_sys::g_output_stream_write(
434 self.as_ref().to_glib_none().0,
435 buffer.to_glib_none().0,
436 count,
437 cancellable.map(|p| p.as_ref()).to_glib_none().0,
438 &mut error,
439 );
440 if error.is_null() {
441 Ok(ret)
442 } else {
443 Err(from_glib_full(error))
444 }
445 }
446 }
447
448 fn write_bytes<P: IsA<Cancellable>>(
449 &self,
450 bytes: &glib::Bytes,
451 cancellable: Option<&P>,
452 ) -> Result<isize, Error> {
453 unsafe {
454 let mut error = ptr::null_mut();
455 let ret = gio_sys::g_output_stream_write_bytes(
456 self.as_ref().to_glib_none().0,
457 bytes.to_glib_none().0,
458 cancellable.map(|p| p.as_ref()).to_glib_none().0,
459 &mut error,
460 );
461 if error.is_null() {
462 Ok(ret)
463 } else {
464 Err(from_glib_full(error))
465 }
466 }
467 }
468
469 fn write_bytes_async<P: IsA<Cancellable>, Q: FnOnce(Result<isize, Error>) + Send + 'static>(
470 &self,
471 bytes: &glib::Bytes,
472 io_priority: glib::Priority,
473 cancellable: Option<&P>,
474 callback: Q,
475 ) {
476 let user_data: Box<Q> = Box::new(callback);
477 unsafe extern "C" fn write_bytes_async_trampoline<
478 Q: FnOnce(Result<isize, Error>) + Send + 'static,
479 >(
480 _source_object: *mut gobject_sys::GObject,
481 res: *mut gio_sys::GAsyncResult,
482 user_data: glib_sys::gpointer,
483 ) {
484 let mut error = ptr::null_mut();
485 let ret = gio_sys::g_output_stream_write_bytes_finish(
486 _source_object as *mut _,
487 res,
488 &mut error,
489 );
490 let result = if error.is_null() {
491 Ok(ret)
492 } else {
493 Err(from_glib_full(error))
494 };
495 let callback: Box<Q> = Box::from_raw(user_data as *mut _);
496 callback(result);
497 }
498 let callback = write_bytes_async_trampoline::<Q>;
499 unsafe {
500 gio_sys::g_output_stream_write_bytes_async(
501 self.as_ref().to_glib_none().0,
502 bytes.to_glib_none().0,
503 io_priority.to_glib(),
504 cancellable.map(|p| p.as_ref()).to_glib_none().0,
505 Some(callback),
506 Box::into_raw(user_data) as *mut _,
507 );
508 }
509 }
510
511 #[cfg(feature = "futures")]
512 fn write_bytes_async_future(
513 &self,
514 bytes: &glib::Bytes,
515 io_priority: glib::Priority,
516 ) -> Box_<dyn future::Future<Output = Result<isize, Error>> + std::marker::Unpin> {
517 use fragile::Fragile;
518 use GioFuture;
519
520 let bytes = bytes.clone();
521 GioFuture::new(self, move |obj, send| {
522 let cancellable = Cancellable::new();
523 let send = Fragile::new(send);
524 obj.write_bytes_async(&bytes, io_priority, Some(&cancellable), move |res| {
525 let _ = send.into_inner().send(res);
526 });
527
528 cancellable
529 })
530 }
531}
532
533impl fmt::Display for OutputStream {
534 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
535 write!(f, "OutputStream")
536 }
537}