1use crate::ffi;
2use crate::libc_types::size_t;
3use foreign_types::{ForeignType, ForeignTypeRef, Opaque};
4use std::borrow::Borrow;
5use std::convert::AsRef;
6use std::fmt;
7use std::iter;
8use std::marker::PhantomData;
9use std::mem;
10use std::ops::{Deref, DerefMut, Index, IndexMut, Range};
11
12use crate::error::ErrorStack;
13use crate::{cvt_0, cvt_p};
14
15use crate::ffi::{
16 sk_free as OPENSSL_sk_free, sk_new_null as OPENSSL_sk_new_null, sk_num as OPENSSL_sk_num,
17 sk_pop as OPENSSL_sk_pop, sk_push as OPENSSL_sk_push, sk_value as OPENSSL_sk_value,
18 _STACK as OPENSSL_STACK,
19};
20
21pub trait Stackable: ForeignType {
25 type StackType;
30}
31
32pub struct Stack<T: Stackable>(*mut T::StackType);
34
35unsafe impl<T: Stackable + Send> Send for Stack<T> {}
36unsafe impl<T: Stackable + Sync> Sync for Stack<T> {}
37
38impl<T> fmt::Debug for Stack<T>
39where
40 T: Stackable,
41 T::Ref: fmt::Debug,
42{
43 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
44 fmt.debug_list().entries(self).finish()
45 }
46}
47impl<T: Stackable> Drop for Stack<T> {
48 fn drop(&mut self) {
49 unsafe {
50 while self.pop().is_some() {}
51 OPENSSL_sk_free(self.0.cast());
52 }
53 }
54}
55
56impl<T: Stackable> Stack<T> {
57 pub fn new() -> Result<Stack<T>, ErrorStack> {
58 unsafe {
59 ffi::init();
60 let ptr = cvt_p(OPENSSL_sk_new_null())?;
61 Ok(Stack(ptr.cast()))
62 }
63 }
64}
65
66impl<T: Stackable> iter::IntoIterator for Stack<T> {
67 type IntoIter = IntoIter<T>;
68 type Item = T;
69
70 fn into_iter(self) -> IntoIter<T> {
71 let it = IntoIter {
72 stack: self.0,
73 idxs: 0..self.len(),
74 };
75 mem::forget(self);
76 it
77 }
78}
79
80impl<T: Stackable> AsRef<StackRef<T>> for Stack<T> {
81 fn as_ref(&self) -> &StackRef<T> {
82 self
83 }
84}
85
86impl<T: Stackable> Borrow<StackRef<T>> for Stack<T> {
87 fn borrow(&self) -> &StackRef<T> {
88 self
89 }
90}
91
92unsafe impl<T: Stackable> ForeignType for Stack<T> {
93 type CType = T::StackType;
94 type Ref = StackRef<T>;
95
96 #[inline]
97 unsafe fn from_ptr(ptr: *mut T::StackType) -> Stack<T> {
98 assert!(
99 !ptr.is_null(),
100 "Must not instantiate a Stack from a null-ptr - use Stack::new() in \
101 that case"
102 );
103 Stack(ptr)
104 }
105
106 #[inline]
107 fn as_ptr(&self) -> *mut T::StackType {
108 self.0
109 }
110}
111
112impl<T: Stackable> Deref for Stack<T> {
113 type Target = StackRef<T>;
114
115 fn deref(&self) -> &StackRef<T> {
116 unsafe { StackRef::from_ptr(self.0) }
117 }
118}
119
120impl<T: Stackable> DerefMut for Stack<T> {
121 fn deref_mut(&mut self) -> &mut StackRef<T> {
122 unsafe { StackRef::from_ptr_mut(self.0) }
123 }
124}
125
126pub struct IntoIter<T: Stackable> {
127 stack: *mut T::StackType,
128 idxs: Range<size_t>,
129}
130
131impl<T: Stackable> Drop for IntoIter<T> {
132 fn drop(&mut self) {
133 unsafe {
134 for _ in &mut *self {}
135 OPENSSL_sk_free(self.stack.cast());
136 }
137 }
138}
139
140impl<T: Stackable> Iterator for IntoIter<T> {
141 type Item = T;
142
143 fn next(&mut self) -> Option<T> {
144 unsafe {
145 self.idxs
146 .next()
147 .map(|i| T::from_ptr(OPENSSL_sk_value(self.stack.cast(), i).cast()))
148 }
149 }
150
151 fn size_hint(&self) -> (usize, Option<usize>) {
152 self.idxs.size_hint()
153 }
154}
155
156impl<T: Stackable> DoubleEndedIterator for IntoIter<T> {
157 fn next_back(&mut self) -> Option<T> {
158 unsafe {
159 self.idxs
160 .next_back()
161 .map(|i| T::from_ptr(OPENSSL_sk_value(self.stack.cast(), i).cast()))
162 }
163 }
164}
165
166impl<T: Stackable> ExactSizeIterator for IntoIter<T> {}
167
168pub struct StackRef<T: Stackable>(Opaque, PhantomData<T>);
169
170unsafe impl<T: Stackable + Send> Send for StackRef<T> {}
171unsafe impl<T: Stackable + Sync> Sync for StackRef<T> {}
172
173unsafe impl<T: Stackable> ForeignTypeRef for StackRef<T> {
174 type CType = T::StackType;
175}
176
177impl<T: Stackable> StackRef<T> {
178 fn as_stack(&self) -> *mut OPENSSL_STACK {
179 self.as_ptr().cast()
180 }
181
182 #[must_use]
184 pub fn len(&self) -> usize {
185 unsafe { OPENSSL_sk_num(self.as_stack()) }
186 }
187
188 #[must_use]
190 pub fn is_empty(&self) -> bool {
191 self.len() == 0
192 }
193
194 #[must_use]
195 pub fn iter(&self) -> Iter<'_, T> {
196 Iter {
197 stack: self,
198 idxs: 0..self.len(),
199 }
200 }
201
202 pub fn iter_mut(&mut self) -> IterMut<'_, T> {
203 IterMut {
204 idxs: 0..self.len(),
205 stack: self,
206 }
207 }
208
209 #[must_use]
212 pub fn get(&self, idx: usize) -> Option<&T::Ref> {
213 unsafe {
214 if idx >= self.len() {
215 return None;
216 }
217
218 Some(T::Ref::from_ptr(self._get(idx)))
219 }
220 }
221
222 pub fn get_mut(&mut self, idx: usize) -> Option<&mut T::Ref> {
225 unsafe {
226 if idx >= self.len() {
227 return None;
228 }
229
230 Some(T::Ref::from_ptr_mut(self._get(idx)))
231 }
232 }
233
234 pub fn push(&mut self, data: T) -> Result<(), ErrorStack> {
236 unsafe {
237 cvt_0(OPENSSL_sk_push(self.as_stack(), data.as_ptr().cast()))?;
238 mem::forget(data);
239 Ok(())
240 }
241 }
242
243 pub fn pop(&mut self) -> Option<T> {
245 unsafe {
246 let ptr = OPENSSL_sk_pop(self.as_stack());
247 if ptr.is_null() {
248 None
249 } else {
250 Some(T::from_ptr(ptr.cast()))
251 }
252 }
253 }
254
255 unsafe fn _get(&self, idx: usize) -> *mut T::CType {
256 OPENSSL_sk_value(self.as_stack(), idx).cast()
257 }
258}
259
260impl<T: Stackable> Index<usize> for StackRef<T> {
261 type Output = T::Ref;
262
263 fn index(&self, index: usize) -> &T::Ref {
264 self.get(index).unwrap()
265 }
266}
267
268impl<T: Stackable> IndexMut<usize> for StackRef<T> {
269 fn index_mut(&mut self, index: usize) -> &mut T::Ref {
270 self.get_mut(index).unwrap()
271 }
272}
273
274impl<'a, T: Stackable> iter::IntoIterator for &'a StackRef<T> {
275 type Item = &'a T::Ref;
276 type IntoIter = Iter<'a, T>;
277
278 fn into_iter(self) -> Iter<'a, T> {
279 self.iter()
280 }
281}
282
283impl<'a, T: Stackable> iter::IntoIterator for &'a mut StackRef<T> {
284 type Item = &'a mut T::Ref;
285 type IntoIter = IterMut<'a, T>;
286
287 fn into_iter(self) -> IterMut<'a, T> {
288 self.iter_mut()
289 }
290}
291
292impl<'a, T: Stackable> iter::IntoIterator for &'a Stack<T> {
293 type Item = &'a T::Ref;
294 type IntoIter = Iter<'a, T>;
295
296 fn into_iter(self) -> Iter<'a, T> {
297 self.iter()
298 }
299}
300
301impl<'a, T: Stackable> iter::IntoIterator for &'a mut Stack<T> {
302 type Item = &'a mut T::Ref;
303 type IntoIter = IterMut<'a, T>;
304
305 fn into_iter(self) -> IterMut<'a, T> {
306 self.iter_mut()
307 }
308}
309
310pub struct Iter<'a, T: Stackable>
312where
313 T: 'a,
314{
315 stack: &'a StackRef<T>,
316 idxs: Range<size_t>,
317}
318
319impl<'a, T: Stackable> Iterator for Iter<'a, T> {
320 type Item = &'a T::Ref;
321
322 fn next(&mut self) -> Option<&'a T::Ref> {
323 unsafe {
324 self.idxs
325 .next()
326 .map(|i| T::Ref::from_ptr(OPENSSL_sk_value(self.stack.as_stack(), i).cast()))
327 }
328 }
329
330 fn size_hint(&self) -> (usize, Option<usize>) {
331 self.idxs.size_hint()
332 }
333}
334
335impl<'a, T: Stackable> DoubleEndedIterator for Iter<'a, T> {
336 fn next_back(&mut self) -> Option<&'a T::Ref> {
337 unsafe {
338 self.idxs
339 .next_back()
340 .map(|i| T::Ref::from_ptr(OPENSSL_sk_value(self.stack.as_stack(), i).cast()))
341 }
342 }
343}
344
345impl<T: Stackable> ExactSizeIterator for Iter<'_, T> {}
346
347pub struct IterMut<'a, T: Stackable + 'a> {
349 stack: &'a mut StackRef<T>,
350 idxs: Range<size_t>,
351}
352
353impl<'a, T: Stackable> Iterator for IterMut<'a, T> {
354 type Item = &'a mut T::Ref;
355
356 fn next(&mut self) -> Option<&'a mut T::Ref> {
357 unsafe {
358 self.idxs
359 .next()
360 .map(|i| T::Ref::from_ptr_mut(OPENSSL_sk_value(self.stack.as_stack(), i).cast()))
361 }
362 }
363
364 fn size_hint(&self) -> (usize, Option<usize>) {
365 self.idxs.size_hint()
366 }
367}
368
369impl<'a, T: Stackable> DoubleEndedIterator for IterMut<'a, T> {
370 fn next_back(&mut self) -> Option<&'a mut T::Ref> {
371 unsafe {
372 self.idxs
373 .next_back()
374 .map(|i| T::Ref::from_ptr_mut(OPENSSL_sk_value(self.stack.as_stack(), i).cast()))
375 }
376 }
377}
378
379impl<T: Stackable> ExactSizeIterator for IterMut<'_, T> {}