1use crate::{AsyncResult, Cancellable, ffi};
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 unsafe {
75 let mut error = std::ptr::null_mut();
76 ffi::g_input_stream_close_finish(_source_object as *mut _, res, &mut error);
77 let result = if error.is_null() {
78 Ok(())
79 } else {
80 Err(from_glib_full(error))
81 };
82 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
83 Box_::from_raw(user_data as *mut _);
84 let callback: P = callback.into_inner();
85 callback(result);
86 }
87 }
88 let callback = close_async_trampoline::<P>;
89 unsafe {
90 ffi::g_input_stream_close_async(
91 self.as_ref().to_glib_none().0,
92 io_priority.into_glib(),
93 cancellable.map(|p| p.as_ref()).to_glib_none().0,
94 Some(callback),
95 Box_::into_raw(user_data) as *mut _,
96 );
97 }
98 }
99
100 fn close_future(
101 &self,
102 io_priority: glib::Priority,
103 ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
104 Box_::pin(crate::GioFuture::new(
105 self,
106 move |obj, cancellable, send| {
107 obj.close_async(io_priority, Some(cancellable), move |res| {
108 send.resolve(res);
109 });
110 },
111 ))
112 }
113
114 #[doc(alias = "g_input_stream_has_pending")]
115 fn has_pending(&self) -> bool {
116 unsafe {
117 from_glib(ffi::g_input_stream_has_pending(
118 self.as_ref().to_glib_none().0,
119 ))
120 }
121 }
122
123 #[doc(alias = "g_input_stream_is_closed")]
124 fn is_closed(&self) -> bool {
125 unsafe {
126 from_glib(ffi::g_input_stream_is_closed(
127 self.as_ref().to_glib_none().0,
128 ))
129 }
130 }
131
132 #[doc(alias = "g_input_stream_read_bytes")]
133 fn read_bytes(
134 &self,
135 count: usize,
136 cancellable: Option<&impl IsA<Cancellable>>,
137 ) -> Result<glib::Bytes, glib::Error> {
138 unsafe {
139 let mut error = std::ptr::null_mut();
140 let ret = ffi::g_input_stream_read_bytes(
141 self.as_ref().to_glib_none().0,
142 count,
143 cancellable.map(|p| p.as_ref()).to_glib_none().0,
144 &mut error,
145 );
146 if error.is_null() {
147 Ok(from_glib_full(ret))
148 } else {
149 Err(from_glib_full(error))
150 }
151 }
152 }
153
154 #[doc(alias = "g_input_stream_read_bytes_async")]
155 fn read_bytes_async<P: FnOnce(Result<glib::Bytes, glib::Error>) + 'static>(
156 &self,
157 count: usize,
158 io_priority: glib::Priority,
159 cancellable: Option<&impl IsA<Cancellable>>,
160 callback: P,
161 ) {
162 let main_context = glib::MainContext::ref_thread_default();
163 let is_main_context_owner = main_context.is_owner();
164 let has_acquired_main_context = (!is_main_context_owner)
165 .then(|| main_context.acquire().ok())
166 .flatten();
167 assert!(
168 is_main_context_owner || has_acquired_main_context.is_some(),
169 "Async operations only allowed if the thread is owning the MainContext"
170 );
171
172 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
173 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
174 unsafe extern "C" fn read_bytes_async_trampoline<
175 P: FnOnce(Result<glib::Bytes, glib::Error>) + 'static,
176 >(
177 _source_object: *mut glib::gobject_ffi::GObject,
178 res: *mut crate::ffi::GAsyncResult,
179 user_data: glib::ffi::gpointer,
180 ) {
181 unsafe {
182 let mut error = std::ptr::null_mut();
183 let ret = ffi::g_input_stream_read_bytes_finish(
184 _source_object as *mut _,
185 res,
186 &mut error,
187 );
188 let result = if error.is_null() {
189 Ok(from_glib_full(ret))
190 } else {
191 Err(from_glib_full(error))
192 };
193 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
194 Box_::from_raw(user_data as *mut _);
195 let callback: P = callback.into_inner();
196 callback(result);
197 }
198 }
199 let callback = read_bytes_async_trampoline::<P>;
200 unsafe {
201 ffi::g_input_stream_read_bytes_async(
202 self.as_ref().to_glib_none().0,
203 count,
204 io_priority.into_glib(),
205 cancellable.map(|p| p.as_ref()).to_glib_none().0,
206 Some(callback),
207 Box_::into_raw(user_data) as *mut _,
208 );
209 }
210 }
211
212 fn read_bytes_future(
213 &self,
214 count: usize,
215 io_priority: glib::Priority,
216 ) -> Pin<Box_<dyn std::future::Future<Output = Result<glib::Bytes, glib::Error>> + 'static>>
217 {
218 Box_::pin(crate::GioFuture::new(
219 self,
220 move |obj, cancellable, send| {
221 obj.read_bytes_async(count, io_priority, Some(cancellable), move |res| {
222 send.resolve(res);
223 });
224 },
225 ))
226 }
227
228 #[doc(alias = "g_input_stream_set_pending")]
229 fn set_pending(&self) -> Result<(), glib::Error> {
230 unsafe {
231 let mut error = std::ptr::null_mut();
232 let is_ok = ffi::g_input_stream_set_pending(self.as_ref().to_glib_none().0, &mut error);
233 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
234 if error.is_null() {
235 Ok(())
236 } else {
237 Err(from_glib_full(error))
238 }
239 }
240 }
241
242 #[doc(alias = "g_input_stream_skip")]
243 fn skip(
244 &self,
245 count: usize,
246 cancellable: Option<&impl IsA<Cancellable>>,
247 ) -> Result<isize, glib::Error> {
248 unsafe {
249 let mut error = std::ptr::null_mut();
250 let ret = ffi::g_input_stream_skip(
251 self.as_ref().to_glib_none().0,
252 count,
253 cancellable.map(|p| p.as_ref()).to_glib_none().0,
254 &mut error,
255 );
256 if error.is_null() {
257 Ok(ret)
258 } else {
259 Err(from_glib_full(error))
260 }
261 }
262 }
263
264 #[doc(alias = "g_input_stream_skip_async")]
265 fn skip_async<P: FnOnce(Result<isize, glib::Error>) + 'static>(
266 &self,
267 count: usize,
268 io_priority: glib::Priority,
269 cancellable: Option<&impl IsA<Cancellable>>,
270 callback: P,
271 ) {
272 let main_context = glib::MainContext::ref_thread_default();
273 let is_main_context_owner = main_context.is_owner();
274 let has_acquired_main_context = (!is_main_context_owner)
275 .then(|| main_context.acquire().ok())
276 .flatten();
277 assert!(
278 is_main_context_owner || has_acquired_main_context.is_some(),
279 "Async operations only allowed if the thread is owning the MainContext"
280 );
281
282 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
283 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
284 unsafe extern "C" fn skip_async_trampoline<
285 P: FnOnce(Result<isize, glib::Error>) + 'static,
286 >(
287 _source_object: *mut glib::gobject_ffi::GObject,
288 res: *mut crate::ffi::GAsyncResult,
289 user_data: glib::ffi::gpointer,
290 ) {
291 unsafe {
292 let mut error = std::ptr::null_mut();
293 let ret =
294 ffi::g_input_stream_skip_finish(_source_object as *mut _, res, &mut error);
295 let result = if error.is_null() {
296 Ok(ret)
297 } else {
298 Err(from_glib_full(error))
299 };
300 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
301 Box_::from_raw(user_data as *mut _);
302 let callback: P = callback.into_inner();
303 callback(result);
304 }
305 }
306 let callback = skip_async_trampoline::<P>;
307 unsafe {
308 ffi::g_input_stream_skip_async(
309 self.as_ref().to_glib_none().0,
310 count,
311 io_priority.into_glib(),
312 cancellable.map(|p| p.as_ref()).to_glib_none().0,
313 Some(callback),
314 Box_::into_raw(user_data) as *mut _,
315 );
316 }
317 }
318
319 fn skip_future(
320 &self,
321 count: usize,
322 io_priority: glib::Priority,
323 ) -> Pin<Box_<dyn std::future::Future<Output = Result<isize, glib::Error>> + 'static>> {
324 Box_::pin(crate::GioFuture::new(
325 self,
326 move |obj, cancellable, send| {
327 obj.skip_async(count, io_priority, Some(cancellable), move |res| {
328 send.resolve(res);
329 });
330 },
331 ))
332 }
333}
334
335impl<O: IsA<InputStream>> InputStreamExt for O {}