1use std::{io, mem, ops};
4
5use glib::translate::*;
6
7use crate::{ffi, Adapter};
8
9impl Adapter {
10 #[doc(alias = "gst_adapter_copy")]
11 pub fn copy(&self, offset: usize, dest: &mut [u8]) -> Result<(), glib::BoolError> {
12 assert!(
13 offset
14 .checked_add(dest.len())
15 .map(|end| end <= self.available())
16 == Some(true)
17 );
18
19 if dest.is_empty() {
20 return Ok(());
21 }
22
23 unsafe {
24 let size = dest.len();
25 ffi::gst_adapter_copy(
26 self.to_glib_none().0,
27 dest.as_mut_ptr() as *mut _,
28 offset,
29 size,
30 );
31 }
32
33 Ok(())
34 }
35
36 #[doc(alias = "gst_adapter_copy_bytes")]
37 pub fn copy_bytes(&self, offset: usize, size: usize) -> Result<glib::Bytes, glib::BoolError> {
38 assert!(offset.checked_add(size).map(|end| end <= self.available()) == Some(true));
39
40 if size == 0 {
41 return Ok(glib::Bytes::from_static(&[]));
42 }
43
44 unsafe {
45 Ok(from_glib_full(ffi::gst_adapter_copy_bytes(
46 self.to_glib_none().0,
47 offset,
48 size,
49 )))
50 }
51 }
52
53 #[doc(alias = "gst_adapter_flush")]
54 pub fn flush(&self, flush: usize) {
55 assert!(flush <= self.available());
56
57 if flush == 0 {
58 return;
59 }
60
61 unsafe {
62 ffi::gst_adapter_flush(self.to_glib_none().0, flush);
63 }
64 }
65
66 #[doc(alias = "get_buffer")]
67 #[doc(alias = "gst_adapter_get_buffer")]
68 pub fn buffer(&self, nbytes: usize) -> Result<gst::Buffer, glib::BoolError> {
69 assert!(nbytes <= self.available());
70 assert!(nbytes != 0);
71
72 unsafe {
73 Option::<_>::from_glib_full(ffi::gst_adapter_get_buffer(self.to_glib_none().0, nbytes))
74 .ok_or_else(|| glib::bool_error!("Failed to get buffer"))
75 }
76 }
77
78 #[doc(alias = "get_buffer_fast")]
79 #[doc(alias = "gst_adapter_get_buffer_fast")]
80 pub fn buffer_fast(&self, nbytes: usize) -> Result<gst::Buffer, glib::BoolError> {
81 assert!(nbytes <= self.available());
82 assert!(nbytes != 0);
83
84 unsafe {
85 Option::<_>::from_glib_full(ffi::gst_adapter_get_buffer_fast(
86 self.to_glib_none().0,
87 nbytes,
88 ))
89 .ok_or_else(|| glib::bool_error!("Failed to get buffer"))
90 }
91 }
92
93 #[doc(alias = "get_buffer_list")]
94 #[doc(alias = "gst_adapter_get_buffer_list")]
95 pub fn buffer_list(&self, nbytes: usize) -> Result<gst::BufferList, glib::BoolError> {
96 assert!(nbytes <= self.available());
97 assert!(nbytes != 0);
98
99 unsafe {
100 Option::<_>::from_glib_full(ffi::gst_adapter_get_buffer_list(
101 self.to_glib_none().0,
102 nbytes,
103 ))
104 .ok_or_else(|| glib::bool_error!("Failed to get buffer list"))
105 }
106 }
107
108 #[doc(alias = "get_list")]
109 #[doc(alias = "gst_adapter_get_list")]
110 pub fn list(&self, nbytes: usize) -> Result<Vec<gst::Buffer>, glib::BoolError> {
111 assert!(nbytes <= self.available());
112 assert!(nbytes != 0);
113
114 unsafe {
115 Ok(FromGlibPtrContainer::from_glib_full(
116 ffi::gst_adapter_get_list(self.to_glib_none().0, nbytes),
117 ))
118 }
119 }
120
121 #[doc(alias = "gst_adapter_masked_scan_uint32")]
122 pub fn masked_scan_uint32(
123 &self,
124 mask: u32,
125 pattern: u32,
126 offset: usize,
127 size: usize,
128 ) -> Result<Option<usize>, glib::BoolError> {
129 assert!(offset.checked_add(size).map(|end| end <= self.available()) == Some(true));
130 assert!(size != 0);
131 assert!(((!mask) & pattern) == 0);
132
133 unsafe {
134 let ret = ffi::gst_adapter_masked_scan_uint32(
135 self.to_glib_none().0,
136 mask,
137 pattern,
138 offset,
139 size,
140 );
141 if ret == -1 {
142 Ok(None)
143 } else {
144 assert!(ret >= 0);
145 Ok(Some(ret as usize))
146 }
147 }
148 }
149
150 #[doc(alias = "gst_adapter_masked_scan_uint32_peek")]
151 pub fn masked_scan_uint32_peek(
152 &self,
153 mask: u32,
154 pattern: u32,
155 offset: usize,
156 size: usize,
157 ) -> Result<Option<(usize, u32)>, glib::BoolError> {
158 assert!(offset.checked_add(size).map(|end| end <= self.available()) == Some(true));
159 assert!(size != 0);
160 assert!(((!mask) & pattern) == 0);
161
162 unsafe {
163 let mut value = mem::MaybeUninit::uninit();
164 let ret = ffi::gst_adapter_masked_scan_uint32_peek(
165 self.to_glib_none().0,
166 mask,
167 pattern,
168 offset,
169 size,
170 value.as_mut_ptr(),
171 );
172
173 if ret == -1 {
174 Ok(None)
175 } else {
176 assert!(ret >= 0);
177 let value = value.assume_init();
178 Ok(Some((ret as usize, value)))
179 }
180 }
181 }
182
183 #[doc(alias = "gst_adapter_take_buffer")]
184 pub fn take_buffer(&self, nbytes: usize) -> Result<gst::Buffer, glib::BoolError> {
185 assert!(nbytes <= self.available());
186 assert!(nbytes != 0);
187
188 unsafe {
189 Option::<_>::from_glib_full(ffi::gst_adapter_take_buffer(self.to_glib_none().0, nbytes))
190 .ok_or_else(|| glib::bool_error!("Failed to take buffer"))
191 }
192 }
193
194 #[doc(alias = "gst_adapter_take_buffer_fast")]
195 pub fn take_buffer_fast(&self, nbytes: usize) -> Result<gst::Buffer, glib::BoolError> {
196 assert!(nbytes <= self.available());
197 assert!(nbytes != 0);
198
199 unsafe {
200 Option::<_>::from_glib_full(ffi::gst_adapter_take_buffer_fast(
201 self.to_glib_none().0,
202 nbytes,
203 ))
204 .ok_or_else(|| glib::bool_error!("Failed to take buffer"))
205 }
206 }
207
208 #[doc(alias = "gst_adapter_take_buffer_list")]
209 pub fn take_buffer_list(&self, nbytes: usize) -> Result<gst::BufferList, glib::BoolError> {
210 assert!(nbytes <= self.available());
211 assert!(nbytes != 0);
212
213 unsafe {
214 Option::<_>::from_glib_full(ffi::gst_adapter_take_buffer_list(
215 self.to_glib_none().0,
216 nbytes,
217 ))
218 .ok_or_else(|| glib::bool_error!("Failed to take buffer list"))
219 }
220 }
221
222 #[doc(alias = "gst_adapter_take_list")]
223 pub fn take_list(&self, nbytes: usize) -> Result<Vec<gst::Buffer>, glib::BoolError> {
224 assert!(nbytes <= self.available());
225 assert!(nbytes != 0);
226
227 unsafe {
228 Ok(FromGlibPtrContainer::from_glib_full(
229 ffi::gst_adapter_take_list(self.to_glib_none().0, nbytes),
230 ))
231 }
232 }
233
234 #[doc(alias = "gst_adapter_push")]
235 pub fn push(&self, buf: gst::Buffer) {
236 unsafe {
237 ffi::gst_adapter_push(self.to_glib_none().0, buf.into_glib_ptr());
238 }
239 }
240}
241
242impl io::Read for Adapter {
243 fn read(&mut self, buf: &mut [u8]) -> Result<usize, io::Error> {
244 let mut len = self.available();
245
246 if len == 0 {
247 return Err(io::Error::new(
248 io::ErrorKind::WouldBlock,
249 format!(
250 "Missing data: requesting {} but only got {}.",
251 buf.len(),
252 len
253 ),
254 ));
255 }
256
257 if buf.len() < len {
258 len = buf.len();
259 }
260
261 self.copy(0, &mut buf[0..len]).map_err(io::Error::other)?;
262
263 self.flush(len);
264
265 Ok(len)
266 }
267}
268
269#[derive(Debug)]
270pub struct UniqueAdapter(Adapter);
271
272unsafe impl Send for UniqueAdapter {}
273unsafe impl Sync for UniqueAdapter {}
274
275impl UniqueAdapter {
276 pub fn new() -> Self {
277 Self(Adapter::new())
278 }
279
280 pub fn available(&self) -> usize {
281 self.0.available()
282 }
283
284 pub fn available_fast(&self) -> usize {
285 self.0.available_fast()
286 }
287
288 pub fn clear(&mut self) {
289 self.0.clear();
290 }
291
292 pub fn copy_bytes(&self, offset: usize, size: usize) -> Result<glib::Bytes, glib::BoolError> {
293 self.0.copy_bytes(offset, size)
294 }
295
296 pub fn distance_from_discont(&self) -> u64 {
297 self.0.distance_from_discont()
298 }
299
300 pub fn dts_at_discont(&self) -> Option<gst::ClockTime> {
301 self.0.dts_at_discont()
302 }
303
304 pub fn flush(&mut self, flush: usize) {
305 self.0.flush(flush);
306 }
307
308 #[doc(alias = "get_buffer")]
309 pub fn buffer(&self, nbytes: usize) -> Result<gst::Buffer, glib::BoolError> {
310 self.0.buffer(nbytes)
311 }
312
313 #[doc(alias = "get_buffer_fast")]
314 pub fn buffer_fast(&self, nbytes: usize) -> Result<gst::Buffer, glib::BoolError> {
315 self.0.buffer_fast(nbytes)
316 }
317
318 #[doc(alias = "get_buffer_list")]
319 pub fn buffer_list(&self, nbytes: usize) -> Result<gst::BufferList, glib::BoolError> {
320 self.0.buffer_list(nbytes)
321 }
322
323 #[doc(alias = "get_list")]
324 pub fn list(&self, nbytes: usize) -> Result<Vec<gst::Buffer>, glib::BoolError> {
325 self.0.list(nbytes)
326 }
327
328 pub fn masked_scan_uint32(
329 &self,
330 mask: u32,
331 pattern: u32,
332 offset: usize,
333 size: usize,
334 ) -> Result<Option<usize>, glib::BoolError> {
335 self.0.masked_scan_uint32(mask, pattern, offset, size)
336 }
337
338 pub fn masked_scan_uint32_peek(
339 &self,
340 mask: u32,
341 pattern: u32,
342 offset: usize,
343 size: usize,
344 ) -> Result<Option<(usize, u32)>, glib::BoolError> {
345 self.0.masked_scan_uint32_peek(mask, pattern, offset, size)
346 }
347
348 pub fn offset_at_discont(&self) -> u64 {
349 self.0.offset_at_discont()
350 }
351
352 pub fn prev_dts(&self) -> (Option<gst::ClockTime>, u64) {
353 self.0.prev_dts()
354 }
355
356 pub fn prev_dts_at_offset(&self, offset: usize) -> (Option<gst::ClockTime>, u64) {
357 self.0.prev_dts_at_offset(offset)
358 }
359
360 pub fn prev_offset(&self) -> (u64, u64) {
361 self.0.prev_offset()
362 }
363
364 pub fn prev_pts(&self) -> (Option<gst::ClockTime>, u64) {
365 self.0.prev_pts()
366 }
367
368 pub fn prev_pts_at_offset(&self, offset: usize) -> (Option<gst::ClockTime>, u64) {
369 self.0.prev_pts_at_offset(offset)
370 }
371
372 pub fn pts_at_discont(&self) -> Option<gst::ClockTime> {
373 self.0.pts_at_discont()
374 }
375
376 pub fn take_buffer(&mut self, nbytes: usize) -> Result<gst::Buffer, glib::BoolError> {
377 self.0.take_buffer(nbytes)
378 }
379
380 pub fn take_buffer_fast(&mut self, nbytes: usize) -> Result<gst::Buffer, glib::BoolError> {
381 self.0.take_buffer_fast(nbytes)
382 }
383
384 pub fn take_buffer_list(&mut self, nbytes: usize) -> Result<gst::BufferList, glib::BoolError> {
385 self.0.take_buffer_list(nbytes)
386 }
387
388 pub fn take_list(&mut self, nbytes: usize) -> Result<Vec<gst::Buffer>, glib::BoolError> {
389 self.0.take_list(nbytes)
390 }
391
392 pub fn copy(&self, offset: usize, dest: &mut [u8]) -> Result<(), glib::BoolError> {
393 self.0.copy(offset, dest)
394 }
395
396 pub fn push(&mut self, buf: gst::Buffer) {
397 self.0.push(buf);
398 }
399
400 #[doc(alias = "gst_adapter_map")]
401 pub fn map(&mut self, nbytes: usize) -> Result<UniqueAdapterMap<'_>, glib::error::BoolError> {
402 assert!(nbytes <= self.available());
403 assert!(nbytes != 0);
404
405 use std::slice;
406
407 unsafe {
408 let ptr = ffi::gst_adapter_map(self.0.to_glib_none().0, nbytes);
409 if ptr.is_null() {
410 Err(glib::bool_error!("size bytes are not available"))
411 } else {
412 Ok(UniqueAdapterMap(
413 self,
414 slice::from_raw_parts(ptr as *const u8, nbytes),
415 ))
416 }
417 }
418 }
419}
420
421#[derive(Debug)]
422pub struct UniqueAdapterMap<'a>(&'a UniqueAdapter, &'a [u8]);
423
424impl Drop for UniqueAdapterMap<'_> {
425 #[inline]
426 fn drop(&mut self) {
427 unsafe {
428 ffi::gst_adapter_unmap((self.0).0.to_glib_none().0);
429 }
430 }
431}
432
433impl ops::Deref for UniqueAdapterMap<'_> {
434 type Target = [u8];
435
436 #[inline]
437 fn deref(&self) -> &[u8] {
438 self.1
439 }
440}
441
442impl AsRef<[u8]> for UniqueAdapterMap<'_> {
443 #[inline]
444 fn as_ref(&self) -> &[u8] {
445 self.1
446 }
447}
448
449impl Default for UniqueAdapter {
450 #[inline]
451 fn default() -> Self {
452 Self::new()
453 }
454}
455
456impl io::Read for UniqueAdapter {
457 #[inline]
458 fn read(&mut self, buf: &mut [u8]) -> Result<usize, io::Error> {
459 self.0.read(buf)
460 }
461}