1 // Copyright (c) 2023 Huawei Device Co., Ltd. 2 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // you may not use this file except in compliance with the License. 4 // You may obtain a copy of the License at 5 // 6 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software 9 // distributed under the License is distributed on an "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 use core::cell::UnsafeCell; 15 16 pub struct ForeignRefWrapper(UnsafeCell<()>); 17 18 pub trait Foreign: Sized { 19 /// The raw C struct. 20 type CStruct; 21 /// A reference to the rust type. 22 type Ref: ForeignRef<CStruct = Self::CStruct>; 23 24 /// The raw C struct pointer to rust type. from_ptr(ptr: *mut Self::CStruct) -> Self25 fn from_ptr(ptr: *mut Self::CStruct) -> Self; 26 /// Returns a raw pointer to the C struct. as_ptr(&self) -> *mut Self::CStruct27 fn as_ptr(&self) -> *mut Self::CStruct; 28 } 29 30 pub trait ForeignRef: Sized { 31 /// The raw C struct. 32 type CStruct; 33 34 /// # Safety 35 /// Dereference of raw pointer. 36 #[inline] from_ptr<'a>(ptr: *mut Self::CStruct) -> &'a Self37 unsafe fn from_ptr<'a>(ptr: *mut Self::CStruct) -> &'a Self { 38 &*(ptr as *mut _) 39 } 40 41 /// # Safety 42 /// Dereference of raw pointer. 43 #[inline] from_ptr_mut<'a>(ptr: *mut Self::CStruct) -> &'a mut Self44 unsafe fn from_ptr_mut<'a>(ptr: *mut Self::CStruct) -> &'a mut Self { 45 &mut *(ptr as *mut _) 46 } 47 48 /// Returns a raw pointer to the C struct. 49 #[inline] as_ptr(&self) -> *mut Self::CStruct50 fn as_ptr(&self) -> *mut Self::CStruct { 51 self as *const _ as *mut _ 52 } 53 } 54 55 macro_rules! foreign_type { 56 ( 57 type CStruct = $ctype:ty; 58 fn drop = $drop:expr; 59 60 $(#[$own_attr:meta])* 61 pub(crate) struct $owned:ident; 62 63 $(#[$borrow_attr:meta])* 64 pub(crate) struct $borrowed:ident; 65 ) => { 66 // Wraps * mut C struct. 67 $(#[$own_attr])* 68 pub(crate) struct $owned(*mut $ctype); 69 70 impl crate::util::c_openssl::foreign::Foreign for $owned { 71 type CStruct = $ctype; 72 type Ref = $borrowed; 73 74 #[inline] 75 fn from_ptr(ptr: *mut $ctype) -> $owned { 76 $owned(ptr) 77 } 78 79 #[inline] 80 fn as_ptr(&self) -> *mut $ctype { 81 self.0 82 } 83 } 84 85 impl Drop for $owned { 86 #[inline] 87 fn drop(&mut self) { 88 unsafe { $drop(self.0) } 89 } 90 } 91 92 // * owned -> * Deref::deref(&owned) -> * &borrowed -> borrowed 93 impl core::ops::Deref for $owned { 94 type Target = $borrowed; 95 96 #[inline] 97 fn deref(&self) -> &$borrowed { 98 unsafe{ crate::util::c_openssl::foreign::ForeignRef::from_ptr(self.0) } 99 } 100 } 101 102 // * owned -> * DerefMut::deref_mut(&mut owned) -> * &mut borrowed -> mut borrowed 103 impl core::ops::DerefMut for $owned { 104 #[inline] 105 fn deref_mut(&mut self) -> &mut $borrowed { 106 unsafe{ crate::util::c_openssl::foreign::ForeignRef::from_ptr_mut(self.0) } 107 } 108 } 109 110 // owned.borrow -> & borrowed 111 impl std::borrow::Borrow<$borrowed> for $owned { 112 #[inline] 113 fn borrow(&self) -> &$borrowed { 114 &**self 115 } 116 } 117 118 // owned.as_ref -> & borrowed 119 impl AsRef<$borrowed> for $owned { 120 #[inline] 121 fn as_ref(&self) -> &$borrowed { 122 &**self 123 } 124 } 125 126 // A type implementing `ForeignRef` should simply be a newtype wrapper around `ForeignRefWrapper`. 127 $(#[$borrow_attr:meta])* 128 pub(crate) struct $borrowed(crate::util::c_openssl::foreign::ForeignRefWrapper); 129 130 impl crate::util::c_openssl::foreign::ForeignRef for $borrowed { 131 type CStruct = $ctype; 132 } 133 134 // Unsate Send and Sync mark. 135 unsafe impl Send for $owned {} 136 unsafe impl Send for $borrowed {} 137 unsafe impl Sync for $owned {} 138 unsafe impl Sync for $borrowed {} 139 }; 140 } 141