1use std::{
13 convert::TryInto,
14 ffi::CString,
15 io::{Seek, SeekFrom, Write},
16 marker::PhantomData,
17};
18
19pub use cookie_factory::GenError;
20use cookie_factory::{
21 bytes::{ne_u32, ne_u64, ne_u8},
22 combinator::slice,
23 gen,
24 multi::all,
25 sequence::{pair, tuple},
26 SerializeFn,
27};
28
29use crate::{
30 pod::ChoiceValue,
31 utils::{Choice, ChoiceEnum},
32};
33
34use super::{CanonicalFixedSizedPod, FixedSizedPod, PropertyFlags, Value, ValueArray};
35
36pub trait PodSerialize {
110 fn serialize<O: Write + Seek>(
112 &self,
113 serializer: PodSerializer<O>,
114 ) -> Result<SerializeSuccess<O>, GenError>;
115}
116
117impl PodSerialize for str {
119 fn serialize<O: Write + Seek>(
120 &self,
121 serializer: PodSerializer<O>,
122 ) -> Result<SerializeSuccess<O>, GenError> {
123 serializer.serialize_string(self)
124 }
125}
126
127impl PodSerialize for [u8] {
129 fn serialize<O: Write + Seek>(
130 &self,
131 serializer: PodSerializer<O>,
132 ) -> Result<SerializeSuccess<O>, GenError> {
133 serializer.serialize_bytes(self)
134 }
135}
136
137impl PodSerialize for Value {
139 fn serialize<O: Write + Seek>(
140 &self,
141 serializer: PodSerializer<O>,
142 ) -> Result<SerializeSuccess<O>, GenError> {
143 fn serialize_array<E: FixedSizedPod, O: Write + Seek>(
145 array: &[E],
146 serializer: PodSerializer<O>,
147 ) -> Result<SerializeSuccess<O>, GenError> {
148 let mut arr_serializer = serializer.serialize_array(array.len() as u32)?;
149 for e in array.iter() {
150 arr_serializer.serialize_element(e)?;
151 }
152 arr_serializer.end()
153 }
154
155 match self {
156 Value::None => serializer.serialized_fixed_sized_pod(&()),
157 Value::Bool(b) => serializer.serialized_fixed_sized_pod(b),
158 Value::Id(id) => serializer.serialized_fixed_sized_pod(id),
159 Value::Int(i) => serializer.serialized_fixed_sized_pod(i),
160 Value::Long(l) => serializer.serialized_fixed_sized_pod(l),
161 Value::Float(f) => serializer.serialized_fixed_sized_pod(f),
162 Value::Double(d) => serializer.serialized_fixed_sized_pod(d),
163 Value::String(s) => serializer.serialize_string(s.as_str()),
164 Value::Bytes(b) => serializer.serialize_bytes(b.as_slice()),
165 Value::Rectangle(rect) => serializer.serialized_fixed_sized_pod(rect),
166 Value::Fraction(frac) => serializer.serialized_fixed_sized_pod(frac),
167 Value::Fd(fd) => serializer.serialized_fixed_sized_pod(fd),
168 Value::ValueArray(array) => match array {
169 ValueArray::None(arr) => serialize_array(arr, serializer),
170 ValueArray::Bool(arr) => serialize_array(arr, serializer),
171 ValueArray::Id(arr) => serialize_array(arr, serializer),
172 ValueArray::Int(arr) => serialize_array(arr, serializer),
173 ValueArray::Long(arr) => serialize_array(arr, serializer),
174 ValueArray::Float(arr) => serialize_array(arr, serializer),
175 ValueArray::Double(arr) => serialize_array(arr, serializer),
176 ValueArray::Rectangle(arr) => serialize_array(arr, serializer),
177 ValueArray::Fraction(arr) => serialize_array(arr, serializer),
178 ValueArray::Fd(arr) => serialize_array(arr, serializer),
179 },
180 Value::Struct(array) => {
181 let mut struct_serializer = serializer.serialize_struct()?;
182 for elem in array.iter() {
183 struct_serializer.serialize_field(elem)?;
184 }
185 struct_serializer.end()
186 }
187 Value::Object(object) => {
188 let mut object_serializer = serializer.serialize_object(object.type_, object.id)?;
189 for prop in object.properties.iter() {
190 object_serializer.serialize_property(prop.key, &prop.value, prop.flags)?;
191 }
192 object_serializer.end()
193 }
194 Value::Choice(choice) => match choice {
195 ChoiceValue::Bool(choice) => serializer.serialize_choice(choice),
196 ChoiceValue::Int(choice) => serializer.serialize_choice(choice),
197 ChoiceValue::Long(choice) => serializer.serialize_choice(choice),
198 ChoiceValue::Float(choice) => serializer.serialize_choice(choice),
199 ChoiceValue::Double(choice) => serializer.serialize_choice(choice),
200 ChoiceValue::Id(choice) => serializer.serialize_choice(choice),
201 ChoiceValue::Rectangle(choice) => serializer.serialize_choice(choice),
202 ChoiceValue::Fraction(choice) => serializer.serialize_choice(choice),
203 ChoiceValue::Fd(choice) => serializer.serialize_choice(choice),
204 },
205 Value::Pointer(type_, pointer) => serializer.serialize_pointer(*type_, *pointer),
206 }
207 }
208}
209
210impl<P: FixedSizedPod> PodSerialize for [P] {
211 fn serialize<O: Write + Seek>(
212 &self,
213 serializer: PodSerializer<O>,
214 ) -> Result<SerializeSuccess<O>, GenError> {
215 let mut arr_serializer = serializer.serialize_array(
216 self.len()
217 .try_into()
218 .expect("Array length does not fit in a u32"),
219 )?;
220
221 for element in self.iter() {
222 arr_serializer.serialize_element(element)?;
223 }
224
225 arr_serializer.end()
226 }
227}
228
229impl<T> PodSerialize for (u32, *const T) {
230 fn serialize<O: Write + Seek>(
231 &self,
232 serializer: PodSerializer<O>,
233 ) -> Result<SerializeSuccess<O>, GenError> {
234 serializer.serialize_pointer(self.0, self.1)
235 }
236}
237
238pub struct SerializeSuccess<O: Write + Seek> {
243 serializer: PodSerializer<O>,
246 len: u64,
248}
249
250pub struct PodSerializer<O: Write + Seek> {
252 out: Option<O>,
258}
259
260impl<O: Write + Seek> PodSerializer<O> {
261 pub fn serialize<P>(out: O, pod: &P) -> Result<(O, u64), GenError>
269 where
270 P: PodSerialize + ?Sized,
271 {
272 let serializer = Self { out: Some(out) };
273
274 pod.serialize(serializer).map(|success| {
275 (
276 success
277 .serializer
278 .out
279 .expect("Serializer does not contain a writer"),
280 success.len,
281 )
282 })
283 }
284
285 fn header(size: usize, ty: u32) -> impl SerializeFn<O> {
291 pair(ne_u32(size as u32), ne_u32(ty))
292 }
293
294 fn padding(len: usize) -> impl SerializeFn<O> {
298 let zeroes = std::iter::repeat(0u8);
299 all(zeroes.take(len).map(ne_u8))
300 }
301
302 fn gen(&mut self, f: impl SerializeFn<O>) -> Result<u64, GenError> {
304 gen(
305 f,
306 self.out
307 .take()
308 .expect("PodSerializer does not contain a writer"),
309 )
310 .map(|(writer, len)| {
311 self.out = Some(writer);
312 len
313 })
314 }
315
316 fn write_pod(
318 mut self,
319 size: usize,
320 type_: u32,
321 f: impl SerializeFn<O>,
322 ) -> Result<SerializeSuccess<O>, GenError> {
323 let padding = if size % 8 == 0 { 0 } else { 8 - (size % 8) };
324 let written = self.gen(tuple((
325 Self::header(size, type_),
326 f,
327 Self::padding(padding),
328 )))?;
329
330 Ok(SerializeSuccess {
331 serializer: self,
332 len: written,
333 })
334 }
335
336 pub fn serialized_fixed_sized_pod<P>(self, pod: &P) -> Result<SerializeSuccess<O>, GenError>
344 where
345 P: FixedSizedPod + ?Sized,
346 {
347 self.write_pod(
348 P::CanonicalType::SIZE as usize,
349 P::CanonicalType::TYPE,
350 |out| pod.as_canonical_type().serialize_body(out),
351 )
352 }
353
354 pub fn serialize_string(self, string: &str) -> Result<SerializeSuccess<O>, GenError> {
356 let cstr = CString::new(string)
357 .expect("Pod::String contains string with '\0' byte")
358 .into_bytes_with_nul();
359 self.write_pod(cstr.len(), spa_sys::SPA_TYPE_String, slice(cstr))
360 }
361
362 pub fn serialize_bytes(self, bytes: &[u8]) -> Result<SerializeSuccess<O>, GenError> {
364 self.write_pod(bytes.len(), spa_sys::SPA_TYPE_Bytes, slice(bytes))
365 }
366
367 pub fn serialize_array<P: FixedSizedPod>(
369 mut self,
370 length: u32,
371 ) -> Result<ArrayPodSerializer<O, P>, GenError> {
372 self.gen(pair(
373 Self::header(
374 (8 + length * P::CanonicalType::SIZE) as usize,
375 spa_sys::SPA_TYPE_Array,
376 ),
377 Self::header(P::CanonicalType::SIZE as usize, P::CanonicalType::TYPE),
378 ))?;
379
380 Ok(ArrayPodSerializer {
381 serializer: self,
382 length,
383 written: 0,
384 _phantom: PhantomData,
385 })
386 }
387
388 pub fn serialize_struct(mut self) -> Result<StructPodSerializer<O>, GenError> {
390 let header_position = self
391 .out
392 .as_mut()
393 .expect("PodSerializer does not contain a writer")
394 .stream_position()
395 .expect("Could not get current position in writer");
396
397 self.gen(Self::header(0, spa_sys::SPA_TYPE_Struct))?;
399
400 Ok(StructPodSerializer {
401 serializer: Some(self),
402 header_position,
403 written: 0,
404 })
405 }
406
407 pub fn serialize_object(
409 mut self,
410 object_type: u32,
411 object_id: u32,
412 ) -> Result<ObjectPodSerializer<O>, GenError> {
413 let header_position = self
414 .out
415 .as_mut()
416 .expect("PodSerializer does not contain a writer")
417 .stream_position()
418 .expect("Could not get current position in writer");
419
420 self.gen(Self::header(0, spa_sys::SPA_TYPE_Object))?;
422 self.gen(pair(ne_u32(object_type), ne_u32(object_id)))?;
423
424 Ok(ObjectPodSerializer {
425 serializer: Some(self),
426 header_position,
427 written: 0,
428 })
429 }
430
431 pub fn serialize_choice<T: CanonicalFixedSizedPod>(
433 mut self,
434 choice: &Choice<T>,
435 ) -> Result<SerializeSuccess<O>, GenError> {
436 let flags = choice.0;
437
438 let (choice_type, values) = match &choice.1 {
439 ChoiceEnum::None(value) => (spa_sys::SPA_CHOICE_None, vec![value]),
440 ChoiceEnum::Range { default, min, max } => {
441 (spa_sys::SPA_CHOICE_Range, vec![default, min, max])
442 }
443 ChoiceEnum::Step {
444 default,
445 min,
446 max,
447 step,
448 } => (spa_sys::SPA_CHOICE_Step, vec![default, min, max, step]),
449 ChoiceEnum::Enum {
450 default,
451 alternatives,
452 } => {
453 let mut values = vec![default];
454 values.extend(alternatives);
455 (spa_sys::SPA_CHOICE_Enum, values)
456 }
457 ChoiceEnum::Flags { default, flags } => {
458 let mut values = vec![default];
459 values.extend(flags);
460 (spa_sys::SPA_CHOICE_Flags, values)
461 }
462 };
463
464 let len: usize = 2 * 8 + values.len() * (T::SIZE as usize);
465
466 self.gen(Self::header(len, spa_sys::SPA_TYPE_Choice))?;
467 self.gen(pair(ne_u32(choice_type), ne_u32(flags.bits())))?;
468 self.gen(pair(ne_u32(T::SIZE), ne_u32(T::TYPE)))?;
469
470 for v in values {
471 self.gen(|out| v.serialize_body(out))?;
472 }
473
474 let padding = if len % 8 == 0 { 0 } else { 8 - (len % 8) };
475
476 let pad_bytes = self.gen(PodSerializer::padding(padding))?;
478
479 Ok(SerializeSuccess {
480 serializer: self,
481 len: 8 + len as u64 + pad_bytes,
483 })
484 }
485
486 pub fn serialize_pointer<T>(
488 mut self,
489 type_: u32,
490 ptr: *const T,
491 ) -> Result<SerializeSuccess<O>, GenError> {
492 let ptr_size = std::mem::size_of::<usize>();
493 let len = 8 + ptr_size;
494
495 let mut written = self.gen(Self::header(len, spa_sys::SPA_TYPE_Pointer))?;
496 written += self.gen(pair(ne_u32(type_), ne_u32(0)))?;
497
498 written += match ptr_size {
499 4 => self.gen(ne_u32(ptr as u32))?,
500 8 => self.gen(ne_u64(ptr as u64))?,
501 _ => panic!("unsupported pointer size {ptr_size}"),
502 };
503
504 Ok(SerializeSuccess {
505 serializer: self,
506 len: written,
507 })
508 }
509}
510
511pub struct ArrayPodSerializer<O: Write + Seek, P: FixedSizedPod> {
519 serializer: PodSerializer<O>,
520 length: u32,
522 written: u32,
524 _phantom: PhantomData<P>,
527}
528
529impl<O: Write + Seek, P: FixedSizedPod> ArrayPodSerializer<O, P> {
530 pub fn serialize_element(&mut self, elem: &P) -> Result<u64, GenError> {
534 if !self.written < self.length {
535 panic!("More elements than specified were serialized into the array POD");
536 }
537
538 let result = self
539 .serializer
540 .gen(|out| elem.as_canonical_type().serialize_body(out));
541 self.written += 1;
542 result
543 }
544
545 pub fn end(mut self) -> Result<SerializeSuccess<O>, GenError> {
547 assert_eq!(
548 self.length, self.written,
549 "Array POD was not serialized with the specified amount of elements"
550 );
551
552 let bytes_written = self.written * P::CanonicalType::SIZE;
553
554 let padding = if bytes_written % 8 == 0 {
555 0
556 } else {
557 8 - (bytes_written as usize % 8)
558 };
559
560 let pad_bytes = self.serializer.gen(PodSerializer::padding(padding))?;
562
563 Ok(SerializeSuccess {
564 serializer: self.serializer,
565 len: 16 + u64::from(self.written * P::CanonicalType::SIZE) + pad_bytes,
567 })
568 }
569}
570
571pub struct StructPodSerializer<O: Write + Seek> {
578 serializer: Option<PodSerializer<O>>,
584 header_position: u64,
586 written: usize,
587}
588
589impl<O: Write + Seek> StructPodSerializer<O> {
590 pub fn serialize_field<P>(&mut self, field: &P) -> Result<u64, GenError>
594 where
595 P: PodSerialize + ?Sized,
596 {
597 let success = field.serialize(
598 self.serializer
599 .take()
600 .expect("StructSerializer does not contain a serializer"),
601 )?;
602 self.written += success.len as usize;
603 self.serializer = Some(success.serializer);
604 Ok(success.len)
605 }
606
607 pub fn end(self) -> Result<SerializeSuccess<O>, GenError> {
609 let mut serializer = self
610 .serializer
611 .expect("StructSerializer does not contain a serializer");
612
613 serializer
615 .out
616 .as_mut()
617 .expect("Serializer does not contain a writer")
618 .seek(SeekFrom::Start(self.header_position))
619 .expect("Failed to seek to header position");
620
621 serializer.gen(PodSerializer::header(
622 self.written,
623 spa_sys::SPA_TYPE_Struct,
624 ))?;
625
626 serializer
627 .out
628 .as_mut()
629 .expect("Serializer does not contain a writer")
630 .seek(SeekFrom::End(0))
631 .expect("Failed to seek to end");
632
633 Ok(SerializeSuccess {
637 serializer,
638 len: self.written as u64 + 8,
639 })
640 }
641}
642
643pub struct ObjectPodSerializer<O: Write + Seek> {
650 serializer: Option<PodSerializer<O>>,
656 header_position: u64,
658 written: usize,
659}
660
661impl<O: Write + Seek> ObjectPodSerializer<O> {
662 pub fn serialize_property<P>(
666 &mut self,
667 key: u32,
668 value: &P,
669 flags: PropertyFlags,
670 ) -> Result<u64, GenError>
671 where
672 P: PodSerialize + ?Sized,
673 {
674 let mut serializer = self
675 .serializer
676 .take()
677 .expect("ObjectPodSerializer does not contain a serializer");
678
679 serializer.gen(pair(ne_u32(key), ne_u32(flags.bits())))?;
680 let mut success = value.serialize(serializer)?;
681 success.len += 8; self.written += success.len as usize;
684 self.serializer = Some(success.serializer);
685
686 Ok(success.len)
687 }
688
689 pub fn end(self) -> Result<SerializeSuccess<O>, GenError> {
691 let mut serializer = self
692 .serializer
693 .expect("ObjectSerializer does not contain a serializer");
694
695 serializer
697 .out
698 .as_mut()
699 .expect("Serializer does not contain a writer")
700 .seek(SeekFrom::Start(self.header_position))
701 .expect("Failed to seek to header position");
702
703 let written = self.written + 8;
705
706 serializer.gen(PodSerializer::header(written, spa_sys::SPA_TYPE_Object))?;
707
708 serializer
709 .out
710 .as_mut()
711 .expect("Serializer does not contain a writer")
712 .seek(SeekFrom::End(0))
713 .expect("Failed to seek to end");
714
715 Ok(SerializeSuccess {
719 serializer,
720 len: 8 + written as u64,
722 })
723 }
724}
725
726impl<T: CanonicalFixedSizedPod + FixedSizedPod> PodSerialize for Choice<T> {
727 fn serialize<O: Write + Seek>(
728 &self,
729 serializer: PodSerializer<O>,
730 ) -> Result<SerializeSuccess<O>, GenError> {
731 serializer.serialize_choice(self)
732 }
733}