1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/*
 * SPDX-License-Identifier: MIT
 */
use std::ffi::c_void;
use std::io::{Seek, Write};
use std::ptr::addr_of;

use pipewire_wrapper_proc_macro::RawWrapper;

use crate::spa::pod::restricted::{PodHeader, PodRawValue};
use crate::spa::pod::{PodRef, PodResult, PodValue, SizedPod, WritePod, WriteValue};
use crate::spa::type_::Type;
use crate::wrapper::RawWrapper;

#[derive(RawWrapper, Debug)]
#[repr(transparent)]
struct PodPointerBodyRef {
    #[raw]
    raw: spa_sys::spa_pod_pointer_body,
}

#[derive(RawWrapper, Debug)]
#[repr(transparent)]
pub struct PodPointerRef {
    #[raw]
    raw: spa_sys::spa_pod_pointer,
}

impl PodPointerBodyRef {
    fn pointer_type(&self) -> Type {
        Type::from_raw(self.raw.type_)
    }
}

impl PodPointerRef {
    fn body(&self) -> &PodPointerBodyRef {
        unsafe { PodPointerBodyRef::from_raw_ptr(addr_of!(self.raw.body)) }
    }

    fn pointer_type(&self) -> Type {
        self.body().pointer_type()
    }
}

impl PodHeader for PodPointerRef {
    fn pod_header(&self) -> &spa_sys::spa_pod {
        &self.raw.pod
    }

    fn static_type() -> Type {
        Type::POINTER
    }
}

impl<'a> PodRawValue for &'a PodPointerRef {
    // Can PodRef be used here?
    type RawValue = spa_sys::spa_pod_pointer_body;

    fn raw_value_ptr(&self) -> *const Self::RawValue {
        &self.raw.body
    }

    fn parse_raw_value(ptr: *const Self::RawValue, _size: usize) -> PodResult<Self::Value> {
        unsafe { Ok((*ptr).value) }
    }
}

impl<'a> PodValue for &'a PodPointerRef {
    type Value = *const c_void;
    fn value(&self) -> PodResult<Self::Value> {
        Self::parse_raw_value(self.raw_value_ptr(), self.pod_header().size as usize)
    }
}

impl<'a> WritePod for &'a PodPointerRef {
    fn write_pod<W>(buffer: &mut W, value: &<Self as PodValue>::Value) -> PodResult<()>
    where
        W: Write + Seek,
    {
        todo!()
    }
}

impl<'a> WriteValue for &'a PodPointerRef {
    fn write_raw_value<W>(buffer: &mut W, value: &<Self as PodValue>::Value) -> PodResult<()>
    where
        W: Write + Seek,
    {
        todo!()
    }
}