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