1use crate::ffi;
2use foreign_types::{ForeignType, ForeignTypeRef, Opaque};
3use libc::size_t;
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 as *mut _);
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 as *mut _))
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 as *mut _);
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 as *mut _, i) as *mut _))
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 as *mut _, i) as *mut _))
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() as *mut _
180 }
181
182 pub fn len(&self) -> usize {
184 unsafe { OPENSSL_sk_num(self.as_stack()) }
185 }
186
187 pub fn is_empty(&self) -> bool {
189 self.len() == 0
190 }
191
192 pub fn iter(&self) -> Iter<T> {
193 Iter {
194 stack: self,
195 idxs: 0..self.len(),
196 }
197 }
198
199 pub fn iter_mut(&mut self) -> IterMut<T> {
200 IterMut {
201 idxs: 0..self.len(),
202 stack: self,
203 }
204 }
205
206 pub fn get(&self, idx: usize) -> Option<&T::Ref> {
209 unsafe {
210 if idx >= self.len() {
211 return None;
212 }
213
214 Some(T::Ref::from_ptr(self._get(idx)))
215 }
216 }
217
218 pub fn get_mut(&mut self, idx: usize) -> Option<&mut T::Ref> {
221 unsafe {
222 if idx >= self.len() {
223 return None;
224 }
225
226 Some(T::Ref::from_ptr_mut(self._get(idx)))
227 }
228 }
229
230 pub fn push(&mut self, data: T) -> Result<(), ErrorStack> {
232 unsafe {
233 cvt_0(OPENSSL_sk_push(self.as_stack(), data.as_ptr() as *mut _))?;
234 mem::forget(data);
235 Ok(())
236 }
237 }
238
239 pub fn pop(&mut self) -> Option<T> {
241 unsafe {
242 let ptr = OPENSSL_sk_pop(self.as_stack());
243 if ptr.is_null() {
244 None
245 } else {
246 Some(T::from_ptr(ptr as *mut _))
247 }
248 }
249 }
250
251 unsafe fn _get(&self, idx: usize) -> *mut T::CType {
252 OPENSSL_sk_value(self.as_stack(), idx) as *mut _
253 }
254}
255
256impl<T: Stackable> Index<usize> for StackRef<T> {
257 type Output = T::Ref;
258
259 fn index(&self, index: usize) -> &T::Ref {
260 self.get(index).unwrap()
261 }
262}
263
264impl<T: Stackable> IndexMut<usize> for StackRef<T> {
265 fn index_mut(&mut self, index: usize) -> &mut T::Ref {
266 self.get_mut(index).unwrap()
267 }
268}
269
270impl<'a, T: Stackable> iter::IntoIterator for &'a StackRef<T> {
271 type Item = &'a T::Ref;
272 type IntoIter = Iter<'a, T>;
273
274 fn into_iter(self) -> Iter<'a, T> {
275 self.iter()
276 }
277}
278
279impl<'a, T: Stackable> iter::IntoIterator for &'a mut StackRef<T> {
280 type Item = &'a mut T::Ref;
281 type IntoIter = IterMut<'a, T>;
282
283 fn into_iter(self) -> IterMut<'a, T> {
284 self.iter_mut()
285 }
286}
287
288impl<'a, T: Stackable> iter::IntoIterator for &'a Stack<T> {
289 type Item = &'a T::Ref;
290 type IntoIter = Iter<'a, T>;
291
292 fn into_iter(self) -> Iter<'a, T> {
293 self.iter()
294 }
295}
296
297impl<'a, T: Stackable> iter::IntoIterator for &'a mut Stack<T> {
298 type Item = &'a mut T::Ref;
299 type IntoIter = IterMut<'a, T>;
300
301 fn into_iter(self) -> IterMut<'a, T> {
302 self.iter_mut()
303 }
304}
305
306pub struct Iter<'a, T: Stackable>
308where
309 T: 'a,
310{
311 stack: &'a StackRef<T>,
312 idxs: Range<size_t>,
313}
314
315impl<'a, T: Stackable> Iterator for Iter<'a, T> {
316 type Item = &'a T::Ref;
317
318 fn next(&mut self) -> Option<&'a T::Ref> {
319 unsafe {
320 self.idxs
321 .next()
322 .map(|i| T::Ref::from_ptr(OPENSSL_sk_value(self.stack.as_stack(), i) as *mut _))
323 }
324 }
325
326 fn size_hint(&self) -> (usize, Option<usize>) {
327 self.idxs.size_hint()
328 }
329}
330
331impl<'a, T: Stackable> DoubleEndedIterator for Iter<'a, T> {
332 fn next_back(&mut self) -> Option<&'a T::Ref> {
333 unsafe {
334 self.idxs
335 .next_back()
336 .map(|i| T::Ref::from_ptr(OPENSSL_sk_value(self.stack.as_stack(), i) as *mut _))
337 }
338 }
339}
340
341impl<'a, T: Stackable> ExactSizeIterator for Iter<'a, T> {}
342
343pub struct IterMut<'a, T: Stackable + 'a> {
345 stack: &'a mut StackRef<T>,
346 idxs: Range<size_t>,
347}
348
349impl<'a, T: Stackable> Iterator for IterMut<'a, T> {
350 type Item = &'a mut T::Ref;
351
352 fn next(&mut self) -> Option<&'a mut T::Ref> {
353 unsafe {
354 self.idxs
355 .next()
356 .map(|i| T::Ref::from_ptr_mut(OPENSSL_sk_value(self.stack.as_stack(), i) as *mut _))
357 }
358 }
359
360 fn size_hint(&self) -> (usize, Option<usize>) {
361 self.idxs.size_hint()
362 }
363}
364
365impl<'a, T: Stackable> DoubleEndedIterator for IterMut<'a, T> {
366 fn next_back(&mut self) -> Option<&'a mut T::Ref> {
367 unsafe {
368 self.idxs
369 .next_back()
370 .map(|i| T::Ref::from_ptr_mut(OPENSSL_sk_value(self.stack.as_stack(), i) as *mut _))
371 }
372 }
373}
374
375impl<'a, T: Stackable> ExactSizeIterator for IterMut<'a, T> {}