1use std::ffi::c_void;
2use std::mem;
3
4use crate::foreign::*;
5
6impl<T> FreeForeign for [T]
7where
8 T: FixedAlloc,
9{
10 type Foreign = T::Foreign;
11
12 unsafe fn free_foreign(ptr: *mut Self::Foreign) {
13 libc::free(ptr.cast::<c_void>());
14 }
15}
16
17impl<T> CloneToForeign for [T]
18where
19 T: FixedAlloc,
20{
21 fn clone_to_foreign(&self) -> OwnedPointer<Self> {
22 unsafe {
25 let size = mem::size_of::<Self::Foreign>();
26 let p = libc::malloc(self.len() * size).cast::<Self::Foreign>();
27 T::clone_from_native_slice(p, self);
28 OwnedPointer::new(p)
29 }
30 }
31}
32
33impl<'a, T> BorrowForeign<'a> for [T]
34where
35 T: FixedAlloc + FreeForeign<Foreign = T> + BorrowForeign<'a, Foreign = T, Storage = &'a T> + 'a,
36{
37 type Storage = &'a Self;
38
39 fn borrow_foreign(&self) -> BorrowedPointer<Self, &Self> {
40 unsafe { BorrowedPointer::new(self.as_ptr(), self) }
43 }
44}
45
46impl<'a, T> BorrowForeignMut<'a> for [T]
47where
48 T: FixedAlloc
49 + FreeForeign<Foreign = T>
50 + BorrowForeignMut<'a, Foreign = T, Storage = &'a mut T>
51 + 'a,
52{
53 type Storage = &'a mut Self;
54
55 fn borrow_foreign_mut(&mut self) -> BorrowedMutPointer<Self, &mut Self> {
56 unsafe { BorrowedMutPointer::new(self.as_mut_ptr(), self) }
59 }
60}
61
62impl<T, const N: usize> FreeForeign for [T; N]
63where
64 T: FixedAlloc,
65{
66 type Foreign = T::Foreign;
67
68 unsafe fn free_foreign(ptr: *mut Self::Foreign) {
69 libc::free(ptr.cast::<c_void>());
70 }
71}
72
73impl<T, const N: usize> CloneToForeign for [T; N]
74where
75 T: FixedAlloc,
76{
77 fn clone_to_foreign(&self) -> OwnedPointer<Self> {
78 self[..].clone_to_foreign().into()
79 }
80}
81
82impl<T, const N: usize> FromForeign for [T; N]
83where
84 T: FixedAlloc,
85{
86 unsafe fn cloned_from_foreign(src: *const Self::Foreign) -> Self {
87 T::clone_array_from_foreign(src)
88 }
89}
90
91impl<'a, T, const N: usize> BorrowForeign<'a> for [T; N]
92where
93 T: FixedAlloc + BorrowForeign<'a, Foreign = T, Storage = &'a T> + 'a,
94{
95 type Storage = &'a [T; N];
96
97 fn borrow_foreign(&'a self) -> BorrowedPointer<Self, &'a Self> {
98 unsafe { BorrowedPointer::new(self[..].as_ptr(), self) }
101 }
102}
103
104impl<'a, T, const N: usize> BorrowForeignMut<'a> for [T; N]
105where
106 T: FixedAlloc + BorrowForeignMut<'a, Foreign = T, Storage = &'a mut T> + 'a,
107{
108 type Storage = &'a mut [T; N];
109
110 fn borrow_foreign_mut(&'a mut self) -> BorrowedMutPointer<Self, &'a mut Self> {
111 unsafe { BorrowedMutPointer::new(self[..].as_mut_ptr(), self) }
114 }
115}
116
117unsafe impl<T, const N: usize> FixedAlloc for [T; N]
118where
119 T: FixedAlloc,
120{
121 unsafe fn clone_into_foreign(dest: *mut Self::Foreign, src: &Self) {
122 T::clone_from_native_slice(dest, &src[..]);
123 }
124}
125
126#[cfg(test)]
127mod tests {
128 use std::ffi::c_void;
129 use std::ptr;
130
131 use crate::foreign::*;
132
133 #[test]
134 fn test_slice_convert() {
135 let a = [123i8, 45i8, 67i8];
136 let i = &a[0..=1];
137 let p = i.clone_to_foreign();
138 unsafe {
139 assert_eq!(
140 libc::memcmp(
141 i.as_ptr().cast::<c_void>(),
142 p.as_ptr().cast::<c_void>(),
143 i.len()
144 ),
145 0
146 );
147 assert_eq!(i, <[i8; 2]>::cloned_from_foreign(p.as_ptr()));
148 }
149
150 let p = i.clone_to_foreign();
151 unsafe {
152 assert_eq!(i, <[i8; 2]>::from_foreign(p.into_inner()));
153 }
154 }
155
156 #[test]
157 fn test_slice_borrow() {
158 let i = [123i8, 45i8];
159 let borrowed = i.borrow_foreign();
160 unsafe {
161 assert_eq!(
162 libc::memcmp(
163 i.as_ptr().cast::<c_void>(),
164 borrowed.as_ptr().cast::<c_void>(),
165 i.len()
166 ),
167 0
168 );
169
170 let cloned = <[i8; 2]>::cloned_from_foreign(borrowed.as_ptr());
171 assert_eq!(i, cloned);
172 }
173 }
174
175 #[test]
176 fn test_slice_borrow_mut() {
177 let mut i = [123u8, 45u8];
178 let (p, len) = (i.as_ptr(), i.len());
179 let mut borrowed = i.borrow_foreign_mut();
180 unsafe {
181 assert_eq!(
182 libc::memcmp(p.cast::<c_void>(), borrowed.as_ptr().cast::<c_void>(), len),
183 0
184 );
185
186 ptr::write(borrowed.as_mut_ptr().offset(1), 234);
187 let cloned = <[u8; 2]>::cloned_from_foreign(borrowed.as_ptr());
188
189 assert_eq!(i[1], 234);
190 assert_eq!(i, cloned);
191 }
192 }
193
194 #[test]
195 fn test_array_convert() {
196 let i = [123i8, 45i8];
197 let p = i.clone_to_foreign();
198 unsafe {
199 assert_eq!(
200 libc::memcmp(
201 i.as_ptr().cast::<c_void>(),
202 p.as_ptr().cast::<c_void>(),
203 i.len()
204 ),
205 0
206 );
207 assert_eq!(i, <[i8; 2]>::cloned_from_foreign(p.as_ptr()));
208 }
209
210 let p = i.clone_to_foreign();
211 unsafe {
212 assert_eq!(i, <[i8; 2]>::from_foreign(p.into_inner()));
213 }
214 }
215}