1use std::{boxed::Box as Box_, mem, pin::Pin, ptr};
4
5use glib::{prelude::*, translate::*, GString};
6
7use crate::{ffi, Cancellable, DataInputStream};
8
9mod sealed {
10 pub trait Sealed {}
11 impl<T: super::IsA<super::DataInputStream>> Sealed for T {}
12}
13
14pub trait DataInputStreamExtManual: sealed::Sealed + IsA<DataInputStream> + 'static {
15 #[doc(alias = "g_data_input_stream_read_line")]
37 fn read_line<P: IsA<Cancellable>>(
38 &self,
39 cancellable: Option<&P>,
40 ) -> Result<glib::collections::Slice<u8>, glib::Error> {
41 unsafe {
42 let mut length = mem::MaybeUninit::uninit();
43 let mut error = ptr::null_mut();
44 let ret = ffi::g_data_input_stream_read_line(
45 self.as_ref().to_glib_none().0,
46 length.as_mut_ptr(),
47 cancellable.map(|p| p.as_ref()).to_glib_none().0,
48 &mut error,
49 );
50 let length = length.assume_init();
51 if error.is_null() {
52 Ok(FromGlibContainer::from_glib_full_num(ret, length))
53 } else {
54 Err(from_glib_full(error))
55 }
56 }
57 }
58
59 #[doc(alias = "g_data_input_stream_read_line_async")]
72 fn read_line_async<
73 P: IsA<Cancellable>,
74 Q: FnOnce(Result<glib::collections::Slice<u8>, glib::Error>) + 'static,
75 >(
76 &self,
77 io_priority: glib::Priority,
78 cancellable: Option<&P>,
79 callback: Q,
80 ) {
81 let main_context = glib::MainContext::ref_thread_default();
82 let is_main_context_owner = main_context.is_owner();
83 let has_acquired_main_context = (!is_main_context_owner)
84 .then(|| main_context.acquire().ok())
85 .flatten();
86 assert!(
87 is_main_context_owner || has_acquired_main_context.is_some(),
88 "Async operations only allowed if the thread is owning the MainContext"
89 );
90
91 let user_data: Box_<glib::thread_guard::ThreadGuard<Q>> =
92 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
93 unsafe extern "C" fn read_line_async_trampoline<
94 Q: FnOnce(Result<glib::collections::Slice<u8>, glib::Error>) + 'static,
95 >(
96 _source_object: *mut glib::gobject_ffi::GObject,
97 res: *mut ffi::GAsyncResult,
98 user_data: glib::ffi::gpointer,
99 ) {
100 let mut error = ptr::null_mut();
101 let mut length = mem::MaybeUninit::uninit();
102 let ret = ffi::g_data_input_stream_read_line_finish(
103 _source_object as *mut _,
104 res,
105 length.as_mut_ptr(),
106 &mut error,
107 );
108 let length = length.assume_init();
109 let result = if error.is_null() {
110 Ok(FromGlibContainer::from_glib_full_num(ret, length))
111 } else {
112 Err(from_glib_full(error))
113 };
114 let callback: Box_<glib::thread_guard::ThreadGuard<Q>> =
115 Box_::from_raw(user_data as *mut _);
116 let callback = callback.into_inner();
117 callback(result);
118 }
119 let callback = read_line_async_trampoline::<Q>;
120 unsafe {
121 ffi::g_data_input_stream_read_line_async(
122 self.as_ref().to_glib_none().0,
123 io_priority.into_glib(),
124 cancellable.map(|p| p.as_ref()).to_glib_none().0,
125 Some(callback),
126 Box_::into_raw(user_data) as *mut _,
127 );
128 }
129 }
130
131 fn read_line_future(
132 &self,
133 io_priority: glib::Priority,
134 ) -> Pin<
135 Box_<
136 dyn std::future::Future<Output = Result<glib::collections::Slice<u8>, glib::Error>>
137 + 'static,
138 >,
139 > {
140 Box_::pin(crate::GioFuture::new(
141 self,
142 move |obj, cancellable, send| {
143 obj.read_line_async(io_priority, Some(cancellable), move |res| {
144 send.resolve(res);
145 });
146 },
147 ))
148 }
149
150 #[doc(alias = "g_data_input_stream_read_line_utf8")]
171 fn read_line_utf8<P: IsA<Cancellable>>(
172 &self,
173 cancellable: Option<&P>,
174 ) -> Result<Option<GString>, glib::Error> {
175 unsafe {
176 let mut error = ptr::null_mut();
177 let ret = ffi::g_data_input_stream_read_line_utf8(
178 self.as_ref().to_glib_none().0,
179 ptr::null_mut(),
180 cancellable.map(|p| p.as_ref()).to_glib_none().0,
181 &mut error,
182 );
183 if error.is_null() {
184 Ok(from_glib_full(ret))
185 } else {
186 Err(from_glib_full(error))
187 }
188 }
189 }
190
191 fn read_line_utf8_async<
192 P: IsA<Cancellable>,
193 Q: FnOnce(Result<Option<GString>, glib::Error>) + 'static,
194 >(
195 &self,
196 io_priority: glib::Priority,
197 cancellable: Option<&P>,
198 callback: Q,
199 ) {
200 let main_context = glib::MainContext::ref_thread_default();
201 let is_main_context_owner = main_context.is_owner();
202 let has_acquired_main_context = (!is_main_context_owner)
203 .then(|| main_context.acquire().ok())
204 .flatten();
205 assert!(
206 is_main_context_owner || has_acquired_main_context.is_some(),
207 "Async operations only allowed if the thread is owning the MainContext"
208 );
209
210 let user_data: Box_<glib::thread_guard::ThreadGuard<Q>> =
211 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
212 unsafe extern "C" fn read_line_async_trampoline<
213 Q: FnOnce(Result<Option<GString>, glib::Error>) + 'static,
214 >(
215 _source_object: *mut glib::gobject_ffi::GObject,
216 res: *mut ffi::GAsyncResult,
217 user_data: glib::ffi::gpointer,
218 ) {
219 let mut error = ptr::null_mut();
220 let ret = ffi::g_data_input_stream_read_line_finish(
221 _source_object as *mut _,
222 res,
223 ptr::null_mut(),
224 &mut error,
225 );
226 let result = if error.is_null() {
227 Ok(from_glib_full(ret))
228 } else {
229 Err(from_glib_full(error))
230 };
231 let callback: Box_<glib::thread_guard::ThreadGuard<Q>> =
232 Box_::from_raw(user_data as *mut _);
233 let callback = callback.into_inner();
234 callback(result);
235 }
236 let callback = read_line_async_trampoline::<Q>;
237 unsafe {
238 ffi::g_data_input_stream_read_line_async(
239 self.as_ref().to_glib_none().0,
240 io_priority.into_glib(),
241 cancellable.map(|p| p.as_ref()).to_glib_none().0,
242 Some(callback),
243 Box_::into_raw(user_data) as *mut _,
244 );
245 }
246 }
247
248 fn read_line_utf8_future(
249 &self,
250 io_priority: glib::Priority,
251 ) -> Pin<Box_<dyn std::future::Future<Output = Result<Option<GString>, glib::Error>> + 'static>>
252 {
253 Box_::pin(crate::GioFuture::new(
254 self,
255 move |obj, cancellable, send| {
256 obj.read_line_utf8_async(io_priority, Some(cancellable), move |res| {
257 send.resolve(res);
258 });
259 },
260 ))
261 }
262
263 #[doc(alias = "g_data_input_stream_read_upto")]
293 fn read_upto<P: IsA<Cancellable>>(
294 &self,
295 stop_chars: &[u8],
296 cancellable: Option<&P>,
297 ) -> Result<glib::collections::Slice<u8>, glib::Error> {
298 let stop_chars_len = stop_chars.len() as isize;
299 unsafe {
300 let mut error = ptr::null_mut();
301 let mut length = mem::MaybeUninit::uninit();
302 let ret = ffi::g_data_input_stream_read_upto(
303 self.as_ref().to_glib_none().0,
304 stop_chars.to_glib_none().0 as *const _,
305 stop_chars_len,
306 length.as_mut_ptr(),
307 cancellable.map(|p| p.as_ref()).to_glib_none().0,
308 &mut error,
309 );
310 if error.is_null() {
311 let length = length.assume_init();
312 Ok(FromGlibContainer::from_glib_full_num(
313 ret as *mut u8,
314 length,
315 ))
316 } else {
317 Err(from_glib_full(error))
318 }
319 }
320 }
321
322 #[doc(alias = "g_data_input_stream_read_upto_async")]
348 fn read_upto_async<
349 P: IsA<Cancellable>,
350 Q: FnOnce(Result<glib::collections::Slice<u8>, glib::Error>) + 'static,
351 >(
352 &self,
353 stop_chars: &[u8],
354 io_priority: glib::Priority,
355 cancellable: Option<&P>,
356 callback: Q,
357 ) {
358 let main_context = glib::MainContext::ref_thread_default();
359 let is_main_context_owner = main_context.is_owner();
360 let has_acquired_main_context = (!is_main_context_owner)
361 .then(|| main_context.acquire().ok())
362 .flatten();
363 assert!(
364 is_main_context_owner || has_acquired_main_context.is_some(),
365 "Async operations only allowed if the thread is owning the MainContext"
366 );
367
368 let stop_chars_len = stop_chars.len() as isize;
369 let user_data: Box_<glib::thread_guard::ThreadGuard<Q>> =
370 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
371 unsafe extern "C" fn read_upto_async_trampoline<
372 Q: FnOnce(Result<glib::collections::Slice<u8>, glib::Error>) + 'static,
373 >(
374 _source_object: *mut glib::gobject_ffi::GObject,
375 res: *mut ffi::GAsyncResult,
376 user_data: glib::ffi::gpointer,
377 ) {
378 let mut error = ptr::null_mut();
379 let mut length = mem::MaybeUninit::uninit();
380 let ret = ffi::g_data_input_stream_read_upto_finish(
381 _source_object as *mut _,
382 res,
383 length.as_mut_ptr(),
384 &mut error,
385 );
386 let result = if error.is_null() {
387 let length = length.assume_init();
388 Ok(FromGlibContainer::from_glib_full_num(
389 ret as *mut u8,
390 length,
391 ))
392 } else {
393 Err(from_glib_full(error))
394 };
395 let callback: Box_<glib::thread_guard::ThreadGuard<Q>> =
396 Box_::from_raw(user_data as *mut _);
397 let callback = callback.into_inner();
398 callback(result);
399 }
400 let callback = read_upto_async_trampoline::<Q>;
401 unsafe {
402 ffi::g_data_input_stream_read_upto_async(
403 self.as_ref().to_glib_none().0,
404 stop_chars.to_glib_none().0 as *const _,
405 stop_chars_len,
406 io_priority.into_glib(),
407 cancellable.map(|p| p.as_ref()).to_glib_none().0,
408 Some(callback),
409 Box_::into_raw(user_data) as *mut _,
410 );
411 }
412 }
413
414 fn read_upto_future(
415 &self,
416 stop_chars: &[u8],
417 io_priority: glib::Priority,
418 ) -> Pin<
419 Box_<
420 dyn std::future::Future<Output = Result<glib::collections::Slice<u8>, glib::Error>>
421 + 'static,
422 >,
423 > {
424 let stop_chars = Vec::from(stop_chars);
425 Box_::pin(crate::GioFuture::new(
426 self,
427 move |obj, cancellable, send| {
428 obj.read_upto_async(&stop_chars, io_priority, Some(cancellable), move |res| {
429 send.resolve(res);
430 });
431 },
432 ))
433 }
434}
435
436impl<O: IsA<DataInputStream>> DataInputStreamExtManual for O {}