1use crate::{ffi, AsyncResult, Cancellable};
6use glib::{prelude::*, translate::*};
7use std::{boxed::Box as Box_, pin::Pin};
8
9glib::wrapper! {
10 #[doc(alias = "GInputStream")]
11 pub struct InputStream(Object<ffi::GInputStream, ffi::GInputStreamClass>);
12
13 match fn {
14 type_ => || ffi::g_input_stream_get_type(),
15 }
16}
17
18impl InputStream {
19 pub const NONE: Option<&'static InputStream> = None;
20}
21
22pub trait InputStreamExt: IsA<InputStream> + 'static {
23 #[doc(alias = "g_input_stream_clear_pending")]
24 fn clear_pending(&self) {
25 unsafe {
26 ffi::g_input_stream_clear_pending(self.as_ref().to_glib_none().0);
27 }
28 }
29
30 #[doc(alias = "g_input_stream_close")]
31 fn close(&self, cancellable: Option<&impl IsA<Cancellable>>) -> Result<(), glib::Error> {
32 unsafe {
33 let mut error = std::ptr::null_mut();
34 let is_ok = ffi::g_input_stream_close(
35 self.as_ref().to_glib_none().0,
36 cancellable.map(|p| p.as_ref()).to_glib_none().0,
37 &mut error,
38 );
39 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
40 if error.is_null() {
41 Ok(())
42 } else {
43 Err(from_glib_full(error))
44 }
45 }
46 }
47
48 #[doc(alias = "g_input_stream_close_async")]
49 fn close_async<P: FnOnce(Result<(), glib::Error>) + 'static>(
50 &self,
51 io_priority: glib::Priority,
52 cancellable: Option<&impl IsA<Cancellable>>,
53 callback: P,
54 ) {
55 let main_context = glib::MainContext::ref_thread_default();
56 let is_main_context_owner = main_context.is_owner();
57 let has_acquired_main_context = (!is_main_context_owner)
58 .then(|| main_context.acquire().ok())
59 .flatten();
60 assert!(
61 is_main_context_owner || has_acquired_main_context.is_some(),
62 "Async operations only allowed if the thread is owning the MainContext"
63 );
64
65 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
66 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
67 unsafe extern "C" fn close_async_trampoline<
68 P: FnOnce(Result<(), glib::Error>) + 'static,
69 >(
70 _source_object: *mut glib::gobject_ffi::GObject,
71 res: *mut crate::ffi::GAsyncResult,
72 user_data: glib::ffi::gpointer,
73 ) {
74 let mut error = std::ptr::null_mut();
75 ffi::g_input_stream_close_finish(_source_object as *mut _, res, &mut error);
76 let result = if error.is_null() {
77 Ok(())
78 } else {
79 Err(from_glib_full(error))
80 };
81 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
82 Box_::from_raw(user_data as *mut _);
83 let callback: P = callback.into_inner();
84 callback(result);
85 }
86 let callback = close_async_trampoline::<P>;
87 unsafe {
88 ffi::g_input_stream_close_async(
89 self.as_ref().to_glib_none().0,
90 io_priority.into_glib(),
91 cancellable.map(|p| p.as_ref()).to_glib_none().0,
92 Some(callback),
93 Box_::into_raw(user_data) as *mut _,
94 );
95 }
96 }
97
98 fn close_future(
99 &self,
100 io_priority: glib::Priority,
101 ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
102 Box_::pin(crate::GioFuture::new(
103 self,
104 move |obj, cancellable, send| {
105 obj.close_async(io_priority, Some(cancellable), move |res| {
106 send.resolve(res);
107 });
108 },
109 ))
110 }
111
112 #[doc(alias = "g_input_stream_has_pending")]
113 fn has_pending(&self) -> bool {
114 unsafe {
115 from_glib(ffi::g_input_stream_has_pending(
116 self.as_ref().to_glib_none().0,
117 ))
118 }
119 }
120
121 #[doc(alias = "g_input_stream_is_closed")]
122 fn is_closed(&self) -> bool {
123 unsafe {
124 from_glib(ffi::g_input_stream_is_closed(
125 self.as_ref().to_glib_none().0,
126 ))
127 }
128 }
129
130 #[doc(alias = "g_input_stream_read_bytes")]
131 fn read_bytes(
132 &self,
133 count: usize,
134 cancellable: Option<&impl IsA<Cancellable>>,
135 ) -> Result<glib::Bytes, glib::Error> {
136 unsafe {
137 let mut error = std::ptr::null_mut();
138 let ret = ffi::g_input_stream_read_bytes(
139 self.as_ref().to_glib_none().0,
140 count,
141 cancellable.map(|p| p.as_ref()).to_glib_none().0,
142 &mut error,
143 );
144 if error.is_null() {
145 Ok(from_glib_full(ret))
146 } else {
147 Err(from_glib_full(error))
148 }
149 }
150 }
151
152 #[doc(alias = "g_input_stream_read_bytes_async")]
153 fn read_bytes_async<P: FnOnce(Result<glib::Bytes, glib::Error>) + 'static>(
154 &self,
155 count: usize,
156 io_priority: glib::Priority,
157 cancellable: Option<&impl IsA<Cancellable>>,
158 callback: P,
159 ) {
160 let main_context = glib::MainContext::ref_thread_default();
161 let is_main_context_owner = main_context.is_owner();
162 let has_acquired_main_context = (!is_main_context_owner)
163 .then(|| main_context.acquire().ok())
164 .flatten();
165 assert!(
166 is_main_context_owner || has_acquired_main_context.is_some(),
167 "Async operations only allowed if the thread is owning the MainContext"
168 );
169
170 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
171 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
172 unsafe extern "C" fn read_bytes_async_trampoline<
173 P: FnOnce(Result<glib::Bytes, glib::Error>) + 'static,
174 >(
175 _source_object: *mut glib::gobject_ffi::GObject,
176 res: *mut crate::ffi::GAsyncResult,
177 user_data: glib::ffi::gpointer,
178 ) {
179 let mut error = std::ptr::null_mut();
180 let ret =
181 ffi::g_input_stream_read_bytes_finish(_source_object as *mut _, res, &mut error);
182 let result = if error.is_null() {
183 Ok(from_glib_full(ret))
184 } else {
185 Err(from_glib_full(error))
186 };
187 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
188 Box_::from_raw(user_data as *mut _);
189 let callback: P = callback.into_inner();
190 callback(result);
191 }
192 let callback = read_bytes_async_trampoline::<P>;
193 unsafe {
194 ffi::g_input_stream_read_bytes_async(
195 self.as_ref().to_glib_none().0,
196 count,
197 io_priority.into_glib(),
198 cancellable.map(|p| p.as_ref()).to_glib_none().0,
199 Some(callback),
200 Box_::into_raw(user_data) as *mut _,
201 );
202 }
203 }
204
205 fn read_bytes_future(
206 &self,
207 count: usize,
208 io_priority: glib::Priority,
209 ) -> Pin<Box_<dyn std::future::Future<Output = Result<glib::Bytes, glib::Error>> + 'static>>
210 {
211 Box_::pin(crate::GioFuture::new(
212 self,
213 move |obj, cancellable, send| {
214 obj.read_bytes_async(count, io_priority, Some(cancellable), move |res| {
215 send.resolve(res);
216 });
217 },
218 ))
219 }
220
221 #[doc(alias = "g_input_stream_set_pending")]
222 fn set_pending(&self) -> Result<(), glib::Error> {
223 unsafe {
224 let mut error = std::ptr::null_mut();
225 let is_ok = ffi::g_input_stream_set_pending(self.as_ref().to_glib_none().0, &mut error);
226 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
227 if error.is_null() {
228 Ok(())
229 } else {
230 Err(from_glib_full(error))
231 }
232 }
233 }
234
235 #[doc(alias = "g_input_stream_skip")]
236 fn skip(
237 &self,
238 count: usize,
239 cancellable: Option<&impl IsA<Cancellable>>,
240 ) -> Result<isize, glib::Error> {
241 unsafe {
242 let mut error = std::ptr::null_mut();
243 let ret = ffi::g_input_stream_skip(
244 self.as_ref().to_glib_none().0,
245 count,
246 cancellable.map(|p| p.as_ref()).to_glib_none().0,
247 &mut error,
248 );
249 if error.is_null() {
250 Ok(ret)
251 } else {
252 Err(from_glib_full(error))
253 }
254 }
255 }
256
257 #[doc(alias = "g_input_stream_skip_async")]
258 fn skip_async<P: FnOnce(Result<isize, glib::Error>) + 'static>(
259 &self,
260 count: usize,
261 io_priority: glib::Priority,
262 cancellable: Option<&impl IsA<Cancellable>>,
263 callback: P,
264 ) {
265 let main_context = glib::MainContext::ref_thread_default();
266 let is_main_context_owner = main_context.is_owner();
267 let has_acquired_main_context = (!is_main_context_owner)
268 .then(|| main_context.acquire().ok())
269 .flatten();
270 assert!(
271 is_main_context_owner || has_acquired_main_context.is_some(),
272 "Async operations only allowed if the thread is owning the MainContext"
273 );
274
275 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
276 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
277 unsafe extern "C" fn skip_async_trampoline<
278 P: FnOnce(Result<isize, glib::Error>) + 'static,
279 >(
280 _source_object: *mut glib::gobject_ffi::GObject,
281 res: *mut crate::ffi::GAsyncResult,
282 user_data: glib::ffi::gpointer,
283 ) {
284 let mut error = std::ptr::null_mut();
285 let ret = ffi::g_input_stream_skip_finish(_source_object as *mut _, res, &mut error);
286 let result = if error.is_null() {
287 Ok(ret)
288 } else {
289 Err(from_glib_full(error))
290 };
291 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
292 Box_::from_raw(user_data as *mut _);
293 let callback: P = callback.into_inner();
294 callback(result);
295 }
296 let callback = skip_async_trampoline::<P>;
297 unsafe {
298 ffi::g_input_stream_skip_async(
299 self.as_ref().to_glib_none().0,
300 count,
301 io_priority.into_glib(),
302 cancellable.map(|p| p.as_ref()).to_glib_none().0,
303 Some(callback),
304 Box_::into_raw(user_data) as *mut _,
305 );
306 }
307 }
308
309 fn skip_future(
310 &self,
311 count: usize,
312 io_priority: glib::Priority,
313 ) -> Pin<Box_<dyn std::future::Future<Output = Result<isize, glib::Error>> + 'static>> {
314 Box_::pin(crate::GioFuture::new(
315 self,
316 move |obj, cancellable, send| {
317 obj.skip_async(count, io_priority, Some(cancellable), move |res| {
318 send.resolve(res);
319 });
320 },
321 ))
322 }
323}
324
325impl<O: IsA<InputStream>> InputStreamExt for O {}