1use std::ptr;
4
5use glib::{Error, SeekType, prelude::*, subclass::prelude::*, translate::*};
6
7use crate::{Cancellable, Seekable, ffi};
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 unsafe {
139 let instance = &*(seekable as *mut T::Instance);
140 let imp = instance.imp();
141
142 imp.tell()
143 }
144}
145
146unsafe extern "C" fn seekable_can_seek<T: SeekableImpl>(
147 seekable: *mut ffi::GSeekable,
148) -> glib::ffi::gboolean {
149 unsafe {
150 let instance = &*(seekable as *mut T::Instance);
151 let imp = instance.imp();
152
153 imp.can_seek().into_glib()
154 }
155}
156
157unsafe extern "C" fn seekable_seek<T: SeekableImpl>(
158 seekable: *mut ffi::GSeekable,
159 offset: i64,
160 type_: glib::ffi::GSeekType,
161 cancellable: *mut ffi::GCancellable,
162 err: *mut *mut glib::ffi::GError,
163) -> glib::ffi::gboolean {
164 unsafe {
165 let instance = &*(seekable as *mut T::Instance);
166 let imp = instance.imp();
167
168 match imp.seek(
169 offset,
170 from_glib(type_),
171 Option::<Cancellable>::from_glib_borrow(cancellable)
172 .as_ref()
173 .as_ref(),
174 ) {
175 Ok(()) => glib::ffi::GTRUE,
176 Err(e) => {
177 if !err.is_null() {
178 *err = e.into_glib_ptr();
179 }
180 glib::ffi::GFALSE
181 }
182 }
183 }
184}
185
186unsafe extern "C" fn seekable_can_truncate<T: SeekableImpl>(
187 seekable: *mut ffi::GSeekable,
188) -> glib::ffi::gboolean {
189 unsafe {
190 let instance = &*(seekable as *mut T::Instance);
191 let imp = instance.imp();
192
193 imp.can_truncate().into_glib()
194 }
195}
196
197unsafe extern "C" fn seekable_truncate<T: SeekableImpl>(
198 seekable: *mut ffi::GSeekable,
199 offset: i64,
200 cancellable: *mut ffi::GCancellable,
201 err: *mut *mut glib::ffi::GError,
202) -> glib::ffi::gboolean {
203 unsafe {
204 let instance = &*(seekable as *mut T::Instance);
205 let imp = instance.imp();
206
207 match imp.truncate(
208 offset,
209 Option::<Cancellable>::from_glib_borrow(cancellable)
210 .as_ref()
211 .as_ref(),
212 ) {
213 Ok(()) => glib::ffi::GTRUE,
214 Err(e) => {
215 if !err.is_null() {
216 *err = e.into_glib_ptr();
217 }
218 glib::ffi::GFALSE
219 }
220 }
221 }
222}