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