/rust/registry/src/index.crates.io-1949cf8c6b5b557f/openssl-0.10.62/src/stack.rs
Line | Count | Source |
1 | | use cfg_if::cfg_if; |
2 | | use foreign_types::{ForeignType, ForeignTypeRef, Opaque}; |
3 | | use libc::c_int; |
4 | | use std::borrow::Borrow; |
5 | | use std::convert::AsRef; |
6 | | use std::fmt; |
7 | | use std::iter; |
8 | | use std::marker::PhantomData; |
9 | | use std::mem; |
10 | | use std::ops::{Deref, DerefMut, Index, IndexMut, Range}; |
11 | | |
12 | | use crate::error::ErrorStack; |
13 | | use crate::util::ForeignTypeExt; |
14 | | use crate::{cvt, cvt_p, LenType}; |
15 | | |
16 | | cfg_if! { |
17 | | if #[cfg(ossl110)] { |
18 | | use ffi::{ |
19 | | OPENSSL_sk_pop, OPENSSL_sk_free, OPENSSL_sk_num, OPENSSL_sk_value, OPENSSL_STACK, |
20 | | OPENSSL_sk_new_null, OPENSSL_sk_push, |
21 | | }; |
22 | | } else { |
23 | | use ffi::{ |
24 | | sk_pop as OPENSSL_sk_pop, sk_free as OPENSSL_sk_free, sk_num as OPENSSL_sk_num, |
25 | | sk_value as OPENSSL_sk_value, _STACK as OPENSSL_STACK, |
26 | | sk_new_null as OPENSSL_sk_new_null, sk_push as OPENSSL_sk_push, |
27 | | }; |
28 | | } |
29 | | } |
30 | | |
31 | | /// Trait implemented by types which can be placed in a stack. |
32 | | /// |
33 | | /// It should not be implemented for any type outside of this crate. |
34 | | pub trait Stackable: ForeignType { |
35 | | /// The C stack type for this element. |
36 | | /// |
37 | | /// Generally called `stack_st_{ELEMENT_TYPE}`, normally hidden by the |
38 | | /// `STACK_OF(ELEMENT_TYPE)` macro in the OpenSSL API. |
39 | | type StackType; |
40 | | } |
41 | | |
42 | | /// An owned stack of `T`. |
43 | | pub struct Stack<T: Stackable>(*mut T::StackType); |
44 | | |
45 | | unsafe impl<T: Stackable + Send> Send for Stack<T> {} |
46 | | unsafe impl<T: Stackable + Sync> Sync for Stack<T> {} |
47 | | |
48 | | impl<T> fmt::Debug for Stack<T> |
49 | | where |
50 | | T: Stackable, |
51 | | T::Ref: fmt::Debug, |
52 | | { |
53 | 0 | fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
54 | 0 | fmt.debug_list().entries(self).finish() |
55 | 0 | } |
56 | | } |
57 | | impl<T: Stackable> Drop for Stack<T> { |
58 | 0 | fn drop(&mut self) { |
59 | | unsafe { |
60 | 0 | while self.pop().is_some() {} |
61 | 0 | OPENSSL_sk_free(self.0 as *mut _); |
62 | | } |
63 | 0 | } Unexecuted instantiation: <openssl::stack::Stack<openssl::asn1::Asn1Object> as core::ops::drop::Drop>::drop Unexecuted instantiation: <openssl::stack::Stack<openssl::x509::GeneralName> as core::ops::drop::Drop>::drop Unexecuted instantiation: <openssl::stack::Stack<openssl::x509::X509> as core::ops::drop::Drop>::drop |
64 | | } |
65 | | |
66 | | impl<T: Stackable> Stack<T> { |
67 | 0 | pub fn new() -> Result<Stack<T>, ErrorStack> { |
68 | | unsafe { |
69 | 0 | ffi::init(); |
70 | 0 | let ptr = cvt_p(OPENSSL_sk_new_null())?; |
71 | 0 | Ok(Stack(ptr as *mut _)) |
72 | | } |
73 | 0 | } Unexecuted instantiation: <openssl::stack::Stack<openssl::asn1::Asn1Object>>::new Unexecuted instantiation: <openssl::stack::Stack<openssl::x509::GeneralName>>::new |
74 | | } |
75 | | |
76 | | impl<T: Stackable> iter::IntoIterator for Stack<T> { |
77 | | type IntoIter = IntoIter<T>; |
78 | | type Item = T; |
79 | | |
80 | 0 | fn into_iter(self) -> IntoIter<T> { |
81 | 0 | let it = IntoIter { |
82 | 0 | stack: self.0, |
83 | 0 | idxs: 0..self.len() as LenType, |
84 | 0 | }; |
85 | 0 | mem::forget(self); |
86 | 0 | it |
87 | 0 | } |
88 | | } |
89 | | |
90 | | impl<T: Stackable> AsRef<StackRef<T>> for Stack<T> { |
91 | 0 | fn as_ref(&self) -> &StackRef<T> { |
92 | 0 | self |
93 | 0 | } |
94 | | } |
95 | | |
96 | | impl<T: Stackable> Borrow<StackRef<T>> for Stack<T> { |
97 | 0 | fn borrow(&self) -> &StackRef<T> { |
98 | 0 | self |
99 | 0 | } |
100 | | } |
101 | | |
102 | | impl<T: Stackable> ForeignType for Stack<T> { |
103 | | type CType = T::StackType; |
104 | | type Ref = StackRef<T>; |
105 | | |
106 | | #[inline] |
107 | 0 | unsafe fn from_ptr(ptr: *mut T::StackType) -> Stack<T> { |
108 | 0 | assert!( |
109 | 0 | !ptr.is_null(), |
110 | | "Must not instantiate a Stack from a null-ptr - use Stack::new() in \ |
111 | | that case" |
112 | | ); |
113 | 0 | Stack(ptr) |
114 | 0 | } Unexecuted instantiation: <openssl::stack::Stack<openssl::ssl::SslCipher> as foreign_types_shared::ForeignType>::from_ptr Unexecuted instantiation: <openssl::stack::Stack<openssl::x509::GeneralName> as foreign_types_shared::ForeignType>::from_ptr Unexecuted instantiation: <openssl::stack::Stack<openssl::x509::X509Extension> as foreign_types_shared::ForeignType>::from_ptr Unexecuted instantiation: <openssl::stack::Stack<openssl::x509::AccessDescription> as foreign_types_shared::ForeignType>::from_ptr Unexecuted instantiation: <openssl::stack::Stack<openssl::x509::DistPoint> as foreign_types_shared::ForeignType>::from_ptr Unexecuted instantiation: <openssl::stack::Stack<openssl::string::OpensslString> as foreign_types_shared::ForeignType>::from_ptr Unexecuted instantiation: <openssl::stack::Stack<openssl::x509::X509> as foreign_types_shared::ForeignType>::from_ptr |
115 | | |
116 | | #[inline] |
117 | 0 | fn as_ptr(&self) -> *mut T::StackType { |
118 | 0 | self.0 |
119 | 0 | } Unexecuted instantiation: <openssl::stack::Stack<openssl::x509::X509Name> as foreign_types_shared::ForeignType>::as_ptr Unexecuted instantiation: <openssl::stack::Stack<openssl::x509::X509> as foreign_types_shared::ForeignType>::as_ptr Unexecuted instantiation: <openssl::stack::Stack<openssl::asn1::Asn1Object> as foreign_types_shared::ForeignType>::as_ptr Unexecuted instantiation: <openssl::stack::Stack<openssl::x509::GeneralName> as foreign_types_shared::ForeignType>::as_ptr |
120 | | } |
121 | | |
122 | | impl<T: Stackable> Deref for Stack<T> { |
123 | | type Target = StackRef<T>; |
124 | | |
125 | 0 | fn deref(&self) -> &StackRef<T> { |
126 | 0 | unsafe { StackRef::from_ptr(self.0) } |
127 | 0 | } Unexecuted instantiation: <openssl::stack::Stack<openssl::x509::X509> as core::ops::deref::Deref>::deref Unexecuted instantiation: <openssl::stack::Stack<openssl::x509::GeneralName> as core::ops::deref::Deref>::deref |
128 | | } |
129 | | |
130 | | impl<T: Stackable> DerefMut for Stack<T> { |
131 | 0 | fn deref_mut(&mut self) -> &mut StackRef<T> { |
132 | 0 | unsafe { StackRef::from_ptr_mut(self.0) } |
133 | 0 | } Unexecuted instantiation: <openssl::stack::Stack<openssl::asn1::Asn1Object> as core::ops::deref::DerefMut>::deref_mut Unexecuted instantiation: <openssl::stack::Stack<openssl::x509::GeneralName> as core::ops::deref::DerefMut>::deref_mut Unexecuted instantiation: <openssl::stack::Stack<openssl::x509::X509> as core::ops::deref::DerefMut>::deref_mut |
134 | | } |
135 | | |
136 | | pub struct IntoIter<T: Stackable> { |
137 | | stack: *mut T::StackType, |
138 | | idxs: Range<LenType>, |
139 | | } |
140 | | |
141 | | impl<T: Stackable> Drop for IntoIter<T> { |
142 | 0 | fn drop(&mut self) { |
143 | | unsafe { |
144 | | // https://github.com/rust-lang/rust-clippy/issues/7510 |
145 | | #[allow(clippy::while_let_on_iterator)] |
146 | 0 | while let Some(_) = self.next() {} |
147 | 0 | OPENSSL_sk_free(self.stack as *mut _); |
148 | | } |
149 | 0 | } |
150 | | } |
151 | | |
152 | | impl<T: Stackable> Iterator for IntoIter<T> { |
153 | | type Item = T; |
154 | | |
155 | 0 | fn next(&mut self) -> Option<T> { |
156 | | unsafe { |
157 | 0 | self.idxs |
158 | 0 | .next() |
159 | 0 | .map(|i| T::from_ptr(OPENSSL_sk_value(self.stack as *mut _, i) as *mut _)) |
160 | | } |
161 | 0 | } |
162 | | |
163 | 0 | fn size_hint(&self) -> (usize, Option<usize>) { |
164 | 0 | self.idxs.size_hint() |
165 | 0 | } |
166 | | } |
167 | | |
168 | | impl<T: Stackable> DoubleEndedIterator for IntoIter<T> { |
169 | 0 | fn next_back(&mut self) -> Option<T> { |
170 | | unsafe { |
171 | 0 | self.idxs |
172 | 0 | .next_back() |
173 | 0 | .map(|i| T::from_ptr(OPENSSL_sk_value(self.stack as *mut _, i) as *mut _)) |
174 | | } |
175 | 0 | } |
176 | | } |
177 | | |
178 | | impl<T: Stackable> ExactSizeIterator for IntoIter<T> {} |
179 | | |
180 | | pub struct StackRef<T: Stackable>(Opaque, PhantomData<T>); |
181 | | |
182 | | unsafe impl<T: Stackable + Send> Send for StackRef<T> {} |
183 | | unsafe impl<T: Stackable + Sync> Sync for StackRef<T> {} |
184 | | |
185 | | impl<T: Stackable> ForeignTypeRef for StackRef<T> { |
186 | | type CType = T::StackType; |
187 | | } |
188 | | |
189 | | impl<T: Stackable> StackRef<T> { |
190 | 0 | fn as_stack(&self) -> *mut OPENSSL_STACK { |
191 | 0 | self.as_ptr() as *mut _ |
192 | 0 | } Unexecuted instantiation: <openssl::stack::StackRef<openssl::asn1::Asn1Object>>::as_stack Unexecuted instantiation: <openssl::stack::StackRef<openssl::x509::GeneralName>>::as_stack Unexecuted instantiation: <openssl::stack::StackRef<openssl::x509::X509>>::as_stack |
193 | | |
194 | | /// Returns the number of items in the stack. |
195 | 0 | pub fn len(&self) -> usize { |
196 | 0 | unsafe { OPENSSL_sk_num(self.as_stack()) as usize } |
197 | 0 | } Unexecuted instantiation: <openssl::stack::StackRef<openssl::x509::X509>>::len Unexecuted instantiation: <openssl::stack::StackRef<openssl::x509::GeneralName>>::len |
198 | | |
199 | | /// Determines if the stack is empty. |
200 | 0 | pub fn is_empty(&self) -> bool { |
201 | 0 | self.len() == 0 |
202 | 0 | } |
203 | | |
204 | 0 | pub fn iter(&self) -> Iter<'_, T> { |
205 | 0 | Iter { |
206 | 0 | stack: self, |
207 | 0 | idxs: 0..self.len() as LenType, |
208 | 0 | } |
209 | 0 | } Unexecuted instantiation: <openssl::stack::StackRef<openssl::x509::X509>>::iter Unexecuted instantiation: <openssl::stack::StackRef<openssl::x509::GeneralName>>::iter |
210 | | |
211 | 0 | pub fn iter_mut(&mut self) -> IterMut<'_, T> { |
212 | 0 | IterMut { |
213 | 0 | idxs: 0..self.len() as LenType, |
214 | 0 | stack: self, |
215 | 0 | } |
216 | 0 | } |
217 | | |
218 | | /// Returns a reference to the element at the given index in the |
219 | | /// stack or `None` if the index is out of bounds |
220 | 0 | pub fn get(&self, idx: usize) -> Option<&T::Ref> { |
221 | | unsafe { |
222 | 0 | if idx >= self.len() { |
223 | 0 | return None; |
224 | 0 | } |
225 | | |
226 | 0 | Some(T::Ref::from_ptr(self._get(idx))) |
227 | | } |
228 | 0 | } |
229 | | |
230 | | /// Returns a mutable reference to the element at the given index in the |
231 | | /// stack or `None` if the index is out of bounds |
232 | 0 | pub fn get_mut(&mut self, idx: usize) -> Option<&mut T::Ref> { |
233 | | unsafe { |
234 | 0 | if idx >= self.len() { |
235 | 0 | return None; |
236 | 0 | } |
237 | | |
238 | 0 | Some(T::Ref::from_ptr_mut(self._get(idx))) |
239 | | } |
240 | 0 | } |
241 | | |
242 | | /// Pushes a value onto the top of the stack. |
243 | 0 | pub fn push(&mut self, data: T) -> Result<(), ErrorStack> { |
244 | | unsafe { |
245 | 0 | cvt(OPENSSL_sk_push(self.as_stack(), data.as_ptr() as *mut _) as c_int)?; |
246 | 0 | mem::forget(data); |
247 | 0 | Ok(()) |
248 | | } |
249 | 0 | } Unexecuted instantiation: <openssl::stack::StackRef<openssl::asn1::Asn1Object>>::push Unexecuted instantiation: <openssl::stack::StackRef<openssl::x509::GeneralName>>::push |
250 | | |
251 | | /// Removes the last element from the stack and returns it. |
252 | 0 | pub fn pop(&mut self) -> Option<T> { |
253 | | unsafe { |
254 | 0 | let ptr = OPENSSL_sk_pop(self.as_stack()); |
255 | 0 | T::from_ptr_opt(ptr as *mut _) |
256 | | } |
257 | 0 | } Unexecuted instantiation: <openssl::stack::StackRef<openssl::asn1::Asn1Object>>::pop Unexecuted instantiation: <openssl::stack::StackRef<openssl::x509::GeneralName>>::pop Unexecuted instantiation: <openssl::stack::StackRef<openssl::x509::X509>>::pop |
258 | | |
259 | 0 | unsafe fn _get(&self, idx: usize) -> *mut T::CType { |
260 | 0 | OPENSSL_sk_value(self.as_stack(), idx as LenType) as *mut _ |
261 | 0 | } |
262 | | } |
263 | | |
264 | | impl<T: Stackable> Index<usize> for StackRef<T> { |
265 | | type Output = T::Ref; |
266 | | |
267 | 0 | fn index(&self, index: usize) -> &T::Ref { |
268 | 0 | self.get(index).unwrap() |
269 | 0 | } |
270 | | } |
271 | | |
272 | | impl<T: Stackable> IndexMut<usize> for StackRef<T> { |
273 | 0 | fn index_mut(&mut self, index: usize) -> &mut T::Ref { |
274 | 0 | self.get_mut(index).unwrap() |
275 | 0 | } |
276 | | } |
277 | | |
278 | | impl<'a, T: Stackable> iter::IntoIterator for &'a StackRef<T> { |
279 | | type Item = &'a T::Ref; |
280 | | type IntoIter = Iter<'a, T>; |
281 | | |
282 | 0 | fn into_iter(self) -> Iter<'a, T> { |
283 | 0 | self.iter() |
284 | 0 | } |
285 | | } |
286 | | |
287 | | impl<'a, T: Stackable> iter::IntoIterator for &'a mut StackRef<T> { |
288 | | type Item = &'a mut T::Ref; |
289 | | type IntoIter = IterMut<'a, T>; |
290 | | |
291 | 0 | fn into_iter(self) -> IterMut<'a, T> { |
292 | 0 | self.iter_mut() |
293 | 0 | } |
294 | | } |
295 | | |
296 | | impl<'a, T: Stackable> iter::IntoIterator for &'a Stack<T> { |
297 | | type Item = &'a T::Ref; |
298 | | type IntoIter = Iter<'a, T>; |
299 | | |
300 | 0 | fn into_iter(self) -> Iter<'a, T> { |
301 | 0 | self.iter() |
302 | 0 | } Unexecuted instantiation: <&openssl::stack::Stack<openssl::x509::X509> as core::iter::traits::collect::IntoIterator>::into_iter Unexecuted instantiation: <&openssl::stack::Stack<openssl::x509::GeneralName> as core::iter::traits::collect::IntoIterator>::into_iter |
303 | | } |
304 | | |
305 | | impl<'a, T: Stackable> iter::IntoIterator for &'a mut Stack<T> { |
306 | | type Item = &'a mut T::Ref; |
307 | | type IntoIter = IterMut<'a, T>; |
308 | | |
309 | 0 | fn into_iter(self) -> IterMut<'a, T> { |
310 | 0 | self.iter_mut() |
311 | 0 | } |
312 | | } |
313 | | |
314 | | /// An iterator over the stack's contents. |
315 | | pub struct Iter<'a, T: Stackable> { |
316 | | stack: &'a StackRef<T>, |
317 | | idxs: Range<LenType>, |
318 | | } |
319 | | |
320 | | impl<'a, T: Stackable> Iterator for Iter<'a, T> { |
321 | | type Item = &'a T::Ref; |
322 | | |
323 | 0 | fn next(&mut self) -> Option<&'a T::Ref> { |
324 | | unsafe { |
325 | 0 | self.idxs |
326 | 0 | .next() |
327 | 0 | .map(|i| T::Ref::from_ptr(OPENSSL_sk_value(self.stack.as_stack(), i) as *mut _)) Unexecuted instantiation: <openssl::stack::Iter<openssl::x509::GeneralName> as core::iter::traits::iterator::Iterator>::next::{closure#0}Unexecuted instantiation: <openssl::stack::Iter<openssl::x509::X509> as core::iter::traits::iterator::Iterator>::next::{closure#0} |
328 | | } |
329 | 0 | } Unexecuted instantiation: <openssl::stack::Iter<openssl::x509::GeneralName> as core::iter::traits::iterator::Iterator>::next Unexecuted instantiation: <openssl::stack::Iter<openssl::x509::X509> as core::iter::traits::iterator::Iterator>::next |
330 | | |
331 | 0 | fn size_hint(&self) -> (usize, Option<usize>) { |
332 | 0 | self.idxs.size_hint() |
333 | 0 | } |
334 | | } |
335 | | |
336 | | impl<'a, T: Stackable> DoubleEndedIterator for Iter<'a, T> { |
337 | 0 | fn next_back(&mut self) -> Option<&'a T::Ref> { |
338 | | unsafe { |
339 | 0 | self.idxs |
340 | 0 | .next_back() |
341 | 0 | .map(|i| T::Ref::from_ptr(OPENSSL_sk_value(self.stack.as_stack(), i) as *mut _)) |
342 | | } |
343 | 0 | } |
344 | | } |
345 | | |
346 | | impl<'a, T: Stackable> ExactSizeIterator for Iter<'a, T> {} |
347 | | |
348 | | /// A mutable iterator over the stack's contents. |
349 | | pub struct IterMut<'a, T: Stackable> { |
350 | | stack: &'a mut StackRef<T>, |
351 | | idxs: Range<LenType>, |
352 | | } |
353 | | |
354 | | impl<'a, T: Stackable> Iterator for IterMut<'a, T> { |
355 | | type Item = &'a mut T::Ref; |
356 | | |
357 | 0 | fn next(&mut self) -> Option<&'a mut T::Ref> { |
358 | | unsafe { |
359 | 0 | self.idxs |
360 | 0 | .next() |
361 | 0 | .map(|i| T::Ref::from_ptr_mut(OPENSSL_sk_value(self.stack.as_stack(), i) as *mut _)) |
362 | | } |
363 | 0 | } |
364 | | |
365 | 0 | fn size_hint(&self) -> (usize, Option<usize>) { |
366 | 0 | self.idxs.size_hint() |
367 | 0 | } |
368 | | } |
369 | | |
370 | | impl<'a, T: Stackable> DoubleEndedIterator for IterMut<'a, T> { |
371 | 0 | fn next_back(&mut self) -> Option<&'a mut T::Ref> { |
372 | | unsafe { |
373 | 0 | self.idxs |
374 | 0 | .next_back() |
375 | 0 | .map(|i| T::Ref::from_ptr_mut(OPENSSL_sk_value(self.stack.as_stack(), i) as *mut _)) |
376 | | } |
377 | 0 | } |
378 | | } |
379 | | |
380 | | impl<'a, T: Stackable> ExactSizeIterator for IterMut<'a, T> {} |