1use crate::raw::{RetrieveHandle, StoreHandle};
2use std::collections::HashMap;
3use std::ffi::c_void;
4use std::ops::{Deref, DerefMut};
5use urid::*;
6
7pub struct Storage {
13 items: HashMap<URID, (URID, Vec<u8>)>,
14}
15
16impl Default for Storage {
17 fn default() -> Self {
18 Self {
19 items: HashMap::new(),
20 }
21 }
22}
23
24impl Storage {
25 pub fn store<K: ?Sized, T: ?Sized>(&mut self, key: URID<K>, type_: URID<T>, value: &[u8]) {
27 self.items
28 .insert(key.into_general(), (type_.into_general(), value.to_owned()));
29 }
30
31 pub unsafe extern "C" fn extern_store(
41 handle: sys::LV2_State_Handle,
42 key: u32,
43 value: *const c_void,
44 size: usize,
45 type_: u32,
46 _: u32,
47 ) -> sys::LV2_State_Status {
48 let handle = (handle as *mut Self).as_mut().unwrap();
49 let key = URID::new(key).unwrap();
50 let value = std::slice::from_raw_parts(value as *const u8, size);
51 let type_ = URID::new(type_).unwrap();
52 handle.store(key, type_, value);
53 sys::LV2_State_Status_LV2_STATE_SUCCESS
54 }
55
56 pub fn store_handle(&mut self) -> StoreHandle {
58 StoreHandle::new(Some(Self::extern_store), self as *mut Self as *mut c_void)
59 }
60
61 pub fn retrieve<K: ?Sized>(&self, key: URID<K>) -> Option<(URID, &[u8])> {
65 self.items
66 .get(&key.into_general())
67 .map(|(urid, data)| (*urid, data.as_ref()))
68 }
69
70 pub unsafe extern "C" fn extern_retrieve(
80 handle: sys::LV2_State_Handle,
81 key: u32,
82 size: *mut usize,
83 type_: *mut u32,
84 flags: *mut u32,
85 ) -> *const c_void {
86 if !flags.is_null() {
87 *flags = (sys::LV2_State_Flags::LV2_STATE_IS_POD
88 | sys::LV2_State_Flags::LV2_STATE_IS_PORTABLE)
89 .into();
90 }
91
92 let handle = (handle as *mut Self).as_mut().unwrap();
93 let key = URID::new(key).unwrap();
94 if let Some((type_urid, data)) = handle.retrieve(key) {
95 *size = data.len();
96 *type_ = type_urid.get();
97 data.as_ptr() as *const c_void
98 } else {
99 std::ptr::null()
100 }
101 }
102
103 pub fn retrieve_handle(&mut self) -> RetrieveHandle {
105 RetrieveHandle::new(
106 Some(Self::extern_retrieve),
107 self as *mut Self as *mut c_void,
108 )
109 }
110}
111
112impl Deref for Storage {
113 type Target = HashMap<URID, (URID, Vec<u8>)>;
114
115 fn deref(&self) -> &Self::Target {
116 &self.items
117 }
118}
119
120impl DerefMut for Storage {
121 fn deref_mut(&mut self) -> &mut Self::Target {
122 &mut self.items
123 }
124}