1 use foreign_types::ForeignTypeRef;
2 use libc::{c_char, c_void};
3 use std::convert::AsRef;
4 use std::ffi::CStr;
5 use std::fmt;
6 use std::ops::Deref;
7 use std::str;
8 
9 use crate::stack::Stackable;
10 
11 foreign_type_and_impl_send_sync! {
12     type CType = c_char;
13     fn drop = free;
14 
15     pub struct OpensslString;
16     pub struct OpensslStringRef;
17 }
18 
19 impl fmt::Display for OpensslString {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result20     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
21         fmt::Display::fmt(&**self, f)
22     }
23 }
24 
25 impl fmt::Debug for OpensslString {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result26     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27         fmt::Debug::fmt(&**self, f)
28     }
29 }
30 
31 impl Stackable for OpensslString {
32     type StackType = ffi::stack_st_OPENSSL_STRING;
33 }
34 
35 impl AsRef<str> for OpensslString {
as_ref(&self) -> &str36     fn as_ref(&self) -> &str {
37         &**self
38     }
39 }
40 
41 impl AsRef<[u8]> for OpensslString {
as_ref(&self) -> &[u8]42     fn as_ref(&self) -> &[u8] {
43         self.as_bytes()
44     }
45 }
46 
47 impl Deref for OpensslStringRef {
48     type Target = str;
49 
deref(&self) -> &str50     fn deref(&self) -> &str {
51         unsafe {
52             let slice = CStr::from_ptr(self.as_ptr()).to_bytes();
53             str::from_utf8_unchecked(slice)
54         }
55     }
56 }
57 
58 impl AsRef<str> for OpensslStringRef {
as_ref(&self) -> &str59     fn as_ref(&self) -> &str {
60         &*self
61     }
62 }
63 
64 impl AsRef<[u8]> for OpensslStringRef {
as_ref(&self) -> &[u8]65     fn as_ref(&self) -> &[u8] {
66         self.as_bytes()
67     }
68 }
69 
70 impl fmt::Display for OpensslStringRef {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result71     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
72         fmt::Display::fmt(&**self, f)
73     }
74 }
75 
76 impl fmt::Debug for OpensslStringRef {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result77     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
78         fmt::Debug::fmt(&**self, f)
79     }
80 }
81 
82 #[cfg(not(ossl110))]
free(buf: *mut c_char)83 unsafe fn free(buf: *mut c_char) {
84     ::ffi::CRYPTO_free(buf as *mut c_void);
85 }
86 
87 #[cfg(ossl110)]
free(buf: *mut c_char)88 unsafe fn free(buf: *mut c_char) {
89     ffi::CRYPTO_free(
90         buf as *mut c_void,
91         concat!(file!(), "\0").as_ptr() as *const c_char,
92         line!() as ::libc::c_int,
93     );
94 }
95