1use foreign_types::ForeignTypeRef; 2use libc::{c_char, c_void}; 3use std::convert::AsRef; 4use std::ffi::CStr; 5use std::fmt; 6use std::ops::Deref; 7use std::str; 8 9use crate::stack::Stackable; 10 11foreign_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 19impl fmt::Display for OpensslString { 20 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 21 fmt::Display::fmt(&**self, f) 22 } 23} 24 25impl fmt::Debug for OpensslString { 26 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 27 fmt::Debug::fmt(&**self, f) 28 } 29} 30 31impl Stackable for OpensslString { 32 type StackType = ffi::stack_st_OPENSSL_STRING; 33} 34 35impl AsRef<str> for OpensslString { 36 fn as_ref(&self) -> &str { 37 self 38 } 39} 40 41impl AsRef<[u8]> for OpensslString { 42 fn as_ref(&self) -> &[u8] { 43 self.as_bytes() 44 } 45} 46 47impl Deref for OpensslStringRef { 48 type Target = str; 49 50 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 58impl AsRef<str> for OpensslStringRef { 59 fn as_ref(&self) -> &str { 60 self 61 } 62} 63 64impl AsRef<[u8]> for OpensslStringRef { 65 fn as_ref(&self) -> &[u8] { 66 self.as_bytes() 67 } 68} 69 70impl fmt::Display for OpensslStringRef { 71 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 72 fmt::Display::fmt(&**self, f) 73 } 74} 75 76impl fmt::Debug for OpensslStringRef { 77 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 78 fmt::Debug::fmt(&**self, f) 79 } 80} 81 82#[inline] 83#[cfg(not(boringssl))] 84unsafe fn free(buf: *mut c_char) { 85 ffi::OPENSSL_free(buf as *mut c_void); 86} 87 88#[inline] 89#[cfg(boringssl)] 90unsafe fn free(buf: *mut c_char) { 91 ffi::CRYPTO_free( 92 buf as *mut c_void, 93 concat!(file!(), "\0").as_ptr() as *const c_char, 94 line!() as ::libc::c_int, 95 ); 96} 97