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