1use std::{convert::TryFrom, fmt::Debug, os::fd::RawFd};
5
6#[derive(Copy, Clone, PartialEq, Eq)]
7pub struct DataType(spa_sys::spa_data_type);
8
9#[allow(non_upper_case_globals)]
10impl DataType {
11 pub const Invalid: Self = Self(spa_sys::SPA_DATA_Invalid);
12 pub const MemPtr: Self = Self(spa_sys::SPA_DATA_MemPtr);
14 pub const MemFd: Self = Self(spa_sys::SPA_DATA_MemFd);
16 pub const DmaBuf: Self = Self(spa_sys::SPA_DATA_DmaBuf);
18 pub const MemId: Self = Self(spa_sys::SPA_DATA_MemId);
20
21 pub fn from_raw(raw: spa_sys::spa_data_type) -> Self {
22 Self(raw)
23 }
24
25 pub fn as_raw(&self) -> spa_sys::spa_data_type {
26 self.0
27 }
28}
29
30impl std::fmt::Debug for DataType {
31 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
32 let name = format!(
33 "DataType::{}",
34 match *self {
35 Self::Invalid => "Invalid",
36 Self::MemPtr => "MemPtr",
37 Self::MemFd => "MemFd",
38 Self::DmaBuf => "DmaBuf",
39 Self::MemId => "MemId",
40 _ => "Unknown",
41 }
42 );
43 f.write_str(&name)
44 }
45}
46
47bitflags::bitflags! {
48 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
49 pub struct DataFlags: u32 {
50 const READABLE = 1<<0;
52 const WRITABLE = 1<<1;
54 const DYNAMIC = 1<<2;
56 const READWRITE = Self::READABLE.bits() | Self::WRITABLE.bits();
57 }
58}
59
60#[repr(transparent)]
61pub struct Data(spa_sys::spa_data);
62
63impl Data {
64 pub fn as_raw(&self) -> &spa_sys::spa_data {
65 &self.0
66 }
67
68 pub fn type_(&self) -> DataType {
69 DataType::from_raw(self.0.type_)
70 }
71
72 pub fn flags(&self) -> DataFlags {
73 DataFlags::from_bits_retain(self.0.flags)
74 }
75
76 pub fn fd(&self) -> RawFd {
77 self.0.fd as RawFd
80 }
81
82 pub fn data(&mut self) -> Option<&mut [u8]> {
83 if self.0.data.is_null() {
85 None
86 } else {
87 unsafe {
88 Some(std::slice::from_raw_parts_mut(
89 self.0.data as *mut u8,
90 usize::try_from(self.0.maxsize).unwrap(),
91 ))
92 }
93 }
94 }
95
96 pub fn chunk(&self) -> &Chunk {
97 assert_ne!(self.0.chunk, std::ptr::null_mut());
98 unsafe {
99 let chunk: *const spa_sys::spa_chunk = self.0.chunk;
100 &*(chunk as *const Chunk)
101 }
102 }
103
104 pub fn chunk_mut(&mut self) -> &mut Chunk {
105 assert_ne!(self.0.chunk, std::ptr::null_mut());
106 unsafe {
107 let chunk: *mut spa_sys::spa_chunk = self.0.chunk;
108 &mut *(chunk as *mut Chunk)
109 }
110 }
111}
112
113impl Debug for Data {
114 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
115 f.debug_struct("Data")
116 .field("type", &self.type_())
117 .field("flags", &self.flags())
118 .field("fd", &self.fd())
119 .field("data", &self.0.data) .field("chunk", &self.chunk())
121 .finish()
122 }
123}
124
125bitflags::bitflags! {
126 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
127 pub struct ChunkFlags: i32 {
128 const CORRUPTED = 1<<0;
130 }
131}
132
133#[repr(transparent)]
134pub struct Chunk(spa_sys::spa_chunk);
135
136impl Chunk {
137 pub fn as_raw(&self) -> &spa_sys::spa_chunk {
138 &self.0
139 }
140
141 pub fn size(&self) -> u32 {
142 self.0.size
143 }
144
145 pub fn size_mut(&mut self) -> &mut u32 {
146 &mut self.0.size
147 }
148
149 pub fn offset(&self) -> u32 {
150 self.0.offset
151 }
152
153 pub fn offset_mut(&mut self) -> &mut u32 {
154 &mut self.0.offset
155 }
156
157 pub fn stride(&self) -> i32 {
158 self.0.stride
159 }
160
161 pub fn stride_mut(&mut self) -> &mut i32 {
162 &mut self.0.stride
163 }
164
165 pub fn flags(&self) -> ChunkFlags {
166 ChunkFlags::from_bits_retain(self.0.flags)
167 }
168}
169
170impl Debug for Chunk {
171 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
172 f.debug_struct("Chunk")
173 .field("offset", &self.offset())
174 .field("size", &self.size())
175 .field("stride", &self.stride())
176 .field("flags", &self.flags())
177 .finish()
178 }
179}