1use std::ptr;
4
5use glib::{prelude::*, subclass::prelude::*, translate::*, Error, SeekType};
6
7use crate::{ffi, Cancellable, Seekable};
8
9pub trait SeekableImpl: Send + ObjectImpl + ObjectSubclass<Type: IsA<Seekable>> {
10 fn tell(&self) -> i64;
11 fn can_seek(&self) -> bool;
12 fn seek(
13 &self,
14 offset: i64,
15 type_: SeekType,
16 cancellable: Option<&Cancellable>,
17 ) -> Result<(), Error>;
18 fn can_truncate(&self) -> bool;
19 fn truncate(&self, offset: i64, cancellable: Option<&Cancellable>) -> Result<(), Error>;
20}
21
22pub trait SeekableImplExt: SeekableImpl {
23 fn parent_tell(&self) -> i64 {
24 unsafe {
25 let type_data = Self::type_data();
26 let parent_iface =
27 type_data.as_ref().parent_interface::<Seekable>() as *const ffi::GSeekableIface;
28
29 let func = (*parent_iface)
30 .tell
31 .expect("no parent \"tell\" implementation");
32 func(self.obj().unsafe_cast_ref::<Seekable>().to_glib_none().0)
33 }
34 }
35
36 fn parent_can_seek(&self) -> bool {
37 unsafe {
38 let type_data = Self::type_data();
39 let parent_iface =
40 type_data.as_ref().parent_interface::<Seekable>() as *const ffi::GSeekableIface;
41
42 let func = (*parent_iface)
43 .can_seek
44 .expect("no parent \"can_seek\" implementation");
45 let ret = func(self.obj().unsafe_cast_ref::<Seekable>().to_glib_none().0);
46 from_glib(ret)
47 }
48 }
49
50 fn parent_seek(
51 &self,
52 offset: i64,
53 type_: SeekType,
54 cancellable: Option<&Cancellable>,
55 ) -> Result<(), Error> {
56 unsafe {
57 let type_data = Self::type_data();
58 let parent_iface =
59 type_data.as_ref().parent_interface::<Seekable>() as *const ffi::GSeekableIface;
60
61 let func = (*parent_iface)
62 .seek
63 .expect("no parent \"seek\" implementation");
64
65 let mut err = ptr::null_mut();
66 func(
67 self.obj().unsafe_cast_ref::<Seekable>().to_glib_none().0,
68 offset,
69 type_.into_glib(),
70 cancellable.to_glib_none().0,
71 &mut err,
72 );
73
74 if err.is_null() {
75 Ok(())
76 } else {
77 Err(from_glib_full(err))
78 }
79 }
80 }
81
82 fn parent_can_truncate(&self) -> bool {
83 unsafe {
84 let type_data = Self::type_data();
85 let parent_iface =
86 type_data.as_ref().parent_interface::<Seekable>() as *const ffi::GSeekableIface;
87
88 let func = (*parent_iface)
89 .can_truncate
90 .expect("no parent \"can_truncate\" implementation");
91 let ret = func(self.obj().unsafe_cast_ref::<Seekable>().to_glib_none().0);
92 from_glib(ret)
93 }
94 }
95
96 fn parent_truncate(&self, offset: i64, cancellable: Option<&Cancellable>) -> Result<(), Error> {
97 unsafe {
98 let type_data = Self::type_data();
99 let parent_iface =
100 type_data.as_ref().parent_interface::<Seekable>() as *const ffi::GSeekableIface;
101
102 let func = (*parent_iface)
103 .truncate_fn
104 .expect("no parent \"truncate\" implementation");
105
106 let mut err = ptr::null_mut();
107 func(
108 self.obj().unsafe_cast_ref::<Seekable>().to_glib_none().0,
109 offset,
110 cancellable.to_glib_none().0,
111 &mut err,
112 );
113
114 if err.is_null() {
115 Ok(())
116 } else {
117 Err(from_glib_full(err))
118 }
119 }
120 }
121}
122
123impl<T: SeekableImpl> SeekableImplExt for T {}
124
125unsafe impl<T: SeekableImpl> IsImplementable<T> for Seekable {
126 fn interface_init(iface: &mut glib::Interface<Self>) {
127 let iface = iface.as_mut();
128
129 iface.tell = Some(seekable_tell::<T>);
130 iface.can_seek = Some(seekable_can_seek::<T>);
131 iface.seek = Some(seekable_seek::<T>);
132 iface.can_truncate = Some(seekable_can_truncate::<T>);
133 iface.truncate_fn = Some(seekable_truncate::<T>);
134 }
135}
136
137unsafe extern "C" fn seekable_tell<T: SeekableImpl>(seekable: *mut ffi::GSeekable) -> i64 {
138 let instance = &*(seekable as *mut T::Instance);
139 let imp = instance.imp();
140
141 imp.tell()
142}
143
144unsafe extern "C" fn seekable_can_seek<T: SeekableImpl>(
145 seekable: *mut ffi::GSeekable,
146) -> glib::ffi::gboolean {
147 let instance = &*(seekable as *mut T::Instance);
148 let imp = instance.imp();
149
150 imp.can_seek().into_glib()
151}
152
153unsafe extern "C" fn seekable_seek<T: SeekableImpl>(
154 seekable: *mut ffi::GSeekable,
155 offset: i64,
156 type_: glib::ffi::GSeekType,
157 cancellable: *mut ffi::GCancellable,
158 err: *mut *mut glib::ffi::GError,
159) -> glib::ffi::gboolean {
160 let instance = &*(seekable as *mut T::Instance);
161 let imp = instance.imp();
162
163 match imp.seek(
164 offset,
165 from_glib(type_),
166 Option::<Cancellable>::from_glib_borrow(cancellable)
167 .as_ref()
168 .as_ref(),
169 ) {
170 Ok(()) => glib::ffi::GTRUE,
171 Err(e) => {
172 if !err.is_null() {
173 *err = e.into_glib_ptr();
174 }
175 glib::ffi::GFALSE
176 }
177 }
178}
179
180unsafe extern "C" fn seekable_can_truncate<T: SeekableImpl>(
181 seekable: *mut ffi::GSeekable,
182) -> glib::ffi::gboolean {
183 let instance = &*(seekable as *mut T::Instance);
184 let imp = instance.imp();
185
186 imp.can_truncate().into_glib()
187}
188
189unsafe extern "C" fn seekable_truncate<T: SeekableImpl>(
190 seekable: *mut ffi::GSeekable,
191 offset: i64,
192 cancellable: *mut ffi::GCancellable,
193 err: *mut *mut glib::ffi::GError,
194) -> glib::ffi::gboolean {
195 let instance = &*(seekable as *mut T::Instance);
196 let imp = instance.imp();
197
198 match imp.truncate(
199 offset,
200 Option::<Cancellable>::from_glib_borrow(cancellable)
201 .as_ref()
202 .as_ref(),
203 ) {
204 Ok(()) => glib::ffi::GTRUE,
205 Err(e) => {
206 if !err.is_null() {
207 *err = e.into_glib_ptr();
208 }
209 glib::ffi::GFALSE
210 }
211 }
212}