/rust/registry/src/index.crates.io-1949cf8c6b5b557f/rkyv-0.8.15/src/ffi.rs
Line | Count | Source |
1 | | //! Archived versions of FFI types. |
2 | | |
3 | | use core::{ |
4 | | borrow::Borrow, |
5 | | cmp, |
6 | | ffi::CStr, |
7 | | fmt, hash, |
8 | | ops::{Deref, Index, RangeFull}, |
9 | | }; |
10 | | |
11 | | use munge::munge; |
12 | | use rancor::Fallible; |
13 | | |
14 | | use crate::{ |
15 | | primitive::FixedUsize, ser::Writer, ArchiveUnsized, Place, Portable, |
16 | | RelPtr, SerializeUnsized, |
17 | | }; |
18 | | |
19 | | /// An archived [`CString`](crate::alloc::ffi::CString). |
20 | | /// |
21 | | /// Uses a [`RelPtr`] to a `CStr` under the hood. |
22 | | #[derive(Portable)] |
23 | | #[rkyv(crate)] |
24 | | #[cfg_attr( |
25 | | feature = "bytecheck", |
26 | | derive(bytecheck::CheckBytes), |
27 | | bytecheck(verify) |
28 | | )] |
29 | | #[repr(transparent)] |
30 | | pub struct ArchivedCString { |
31 | | ptr: RelPtr<CStr>, |
32 | | } |
33 | | |
34 | | impl ArchivedCString { |
35 | | /// Returns the contents of this CString as a slice of bytes. |
36 | | /// |
37 | | /// The returned slice does **not** contain the trailing nul terminator, and |
38 | | /// it is guaranteed to not have any interior nul bytes. If you need the |
39 | | /// nul terminator, use |
40 | | /// [`as_bytes_with_nul`][ArchivedCString::as_bytes_with_nul()] instead. |
41 | | #[inline] |
42 | 0 | pub fn as_bytes(&self) -> &[u8] { |
43 | 0 | self.as_c_str().to_bytes() |
44 | 0 | } Unexecuted instantiation: <rkyv::ffi::ArchivedCString>::as_bytes Unexecuted instantiation: <rkyv::ffi::ArchivedCString>::as_bytes |
45 | | |
46 | | /// Equivalent to [`as_bytes`][ArchivedCString::as_bytes()] except that the |
47 | | /// returned slice includes the trailing nul terminator. |
48 | | #[inline] |
49 | 0 | pub fn as_bytes_with_nul(&self) -> &[u8] { |
50 | 0 | self.as_c_str().to_bytes_with_nul() |
51 | 0 | } Unexecuted instantiation: <rkyv::ffi::ArchivedCString>::as_bytes_with_nul Unexecuted instantiation: <rkyv::ffi::ArchivedCString>::as_bytes_with_nul |
52 | | |
53 | | /// Extracts a `CStr` slice containing the entire string. |
54 | | #[inline] |
55 | 0 | pub fn as_c_str(&self) -> &CStr { |
56 | 0 | unsafe { &*self.ptr.as_ptr() } |
57 | 0 | } Unexecuted instantiation: <rkyv::ffi::ArchivedCString>::as_c_str Unexecuted instantiation: <rkyv::ffi::ArchivedCString>::as_c_str |
58 | | |
59 | | /// Resolves an archived C string from the given C string and parameters. |
60 | | #[inline] |
61 | 0 | pub fn resolve_from_c_str( |
62 | 0 | c_str: &CStr, |
63 | 0 | resolver: CStringResolver, |
64 | 0 | out: Place<Self>, |
65 | 0 | ) { |
66 | 0 | munge!(let ArchivedCString { ptr } = out); |
67 | 0 | RelPtr::emplace_unsized( |
68 | 0 | resolver.pos as usize, |
69 | 0 | c_str.archived_metadata(), |
70 | 0 | ptr, |
71 | | ); |
72 | 0 | } Unexecuted instantiation: <rkyv::ffi::ArchivedCString>::resolve_from_c_str Unexecuted instantiation: <rkyv::ffi::ArchivedCString>::resolve_from_c_str |
73 | | |
74 | | /// Serializes a C string. |
75 | 0 | pub fn serialize_from_c_str<S: Fallible + Writer + ?Sized>( |
76 | 0 | c_str: &CStr, |
77 | 0 | serializer: &mut S, |
78 | 0 | ) -> Result<CStringResolver, S::Error> { |
79 | | Ok(CStringResolver { |
80 | 0 | pos: c_str.serialize_unsized(serializer)? as FixedUsize, |
81 | | }) |
82 | 0 | } Unexecuted instantiation: <rkyv::ffi::ArchivedCString>::serialize_from_c_str::<_> Unexecuted instantiation: <rkyv::ffi::ArchivedCString>::serialize_from_c_str::<_> |
83 | | } |
84 | | |
85 | | impl AsRef<CStr> for ArchivedCString { |
86 | 0 | fn as_ref(&self) -> &CStr { |
87 | 0 | self.as_c_str() |
88 | 0 | } Unexecuted instantiation: <rkyv::ffi::ArchivedCString as core::convert::AsRef<core::ffi::c_str::CStr>>::as_ref Unexecuted instantiation: <rkyv::ffi::ArchivedCString as core::convert::AsRef<core::ffi::c_str::CStr>>::as_ref |
89 | | } |
90 | | |
91 | | impl Borrow<CStr> for ArchivedCString { |
92 | | #[inline] |
93 | 0 | fn borrow(&self) -> &CStr { |
94 | 0 | self.as_c_str() |
95 | 0 | } Unexecuted instantiation: <rkyv::ffi::ArchivedCString as core::borrow::Borrow<core::ffi::c_str::CStr>>::borrow Unexecuted instantiation: <rkyv::ffi::ArchivedCString as core::borrow::Borrow<core::ffi::c_str::CStr>>::borrow |
96 | | } |
97 | | |
98 | | impl fmt::Debug for ArchivedCString { |
99 | | #[inline] |
100 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
101 | 0 | self.as_c_str().fmt(f) |
102 | 0 | } Unexecuted instantiation: <rkyv::ffi::ArchivedCString as core::fmt::Debug>::fmt Unexecuted instantiation: <rkyv::ffi::ArchivedCString as core::fmt::Debug>::fmt |
103 | | } |
104 | | |
105 | | impl Deref for ArchivedCString { |
106 | | type Target = CStr; |
107 | | |
108 | | #[inline] |
109 | 0 | fn deref(&self) -> &Self::Target { |
110 | 0 | self.as_c_str() |
111 | 0 | } Unexecuted instantiation: <rkyv::ffi::ArchivedCString as core::ops::deref::Deref>::deref Unexecuted instantiation: <rkyv::ffi::ArchivedCString as core::ops::deref::Deref>::deref |
112 | | } |
113 | | |
114 | | impl Eq for ArchivedCString {} |
115 | | |
116 | | impl hash::Hash for ArchivedCString { |
117 | 0 | fn hash<H: hash::Hasher>(&self, state: &mut H) { |
118 | 0 | self.as_bytes_with_nul().hash(state); |
119 | 0 | } Unexecuted instantiation: <rkyv::ffi::ArchivedCString as core::hash::Hash>::hash::<_> Unexecuted instantiation: <rkyv::ffi::ArchivedCString as core::hash::Hash>::hash::<_> |
120 | | } |
121 | | |
122 | | impl Index<RangeFull> for ArchivedCString { |
123 | | type Output = CStr; |
124 | | |
125 | | #[inline] |
126 | 0 | fn index(&self, _: RangeFull) -> &Self::Output { |
127 | 0 | self.as_c_str() |
128 | 0 | } Unexecuted instantiation: <rkyv::ffi::ArchivedCString as core::ops::index::Index<core::ops::range::RangeFull>>::index Unexecuted instantiation: <rkyv::ffi::ArchivedCString as core::ops::index::Index<core::ops::range::RangeFull>>::index |
129 | | } |
130 | | |
131 | | impl Ord for ArchivedCString { |
132 | | #[inline] |
133 | 0 | fn cmp(&self, other: &Self) -> cmp::Ordering { |
134 | 0 | self.as_bytes().cmp(other.as_bytes()) |
135 | 0 | } Unexecuted instantiation: <rkyv::ffi::ArchivedCString as core::cmp::Ord>::cmp Unexecuted instantiation: <rkyv::ffi::ArchivedCString as core::cmp::Ord>::cmp |
136 | | } |
137 | | |
138 | | impl PartialEq for ArchivedCString { |
139 | | #[inline] |
140 | 0 | fn eq(&self, other: &Self) -> bool { |
141 | 0 | self.as_bytes() == other.as_bytes() |
142 | 0 | } Unexecuted instantiation: <rkyv::ffi::ArchivedCString as core::cmp::PartialEq>::eq Unexecuted instantiation: <rkyv::ffi::ArchivedCString as core::cmp::PartialEq>::eq |
143 | | } |
144 | | |
145 | | impl PartialEq<&CStr> for ArchivedCString { |
146 | | #[inline] |
147 | 0 | fn eq(&self, other: &&CStr) -> bool { |
148 | 0 | PartialEq::eq(self.as_c_str(), other) |
149 | 0 | } Unexecuted instantiation: <rkyv::ffi::ArchivedCString as core::cmp::PartialEq<&core::ffi::c_str::CStr>>::eq Unexecuted instantiation: <rkyv::ffi::ArchivedCString as core::cmp::PartialEq<&core::ffi::c_str::CStr>>::eq |
150 | | } |
151 | | |
152 | | impl PartialEq<ArchivedCString> for &CStr { |
153 | | #[inline] |
154 | 0 | fn eq(&self, other: &ArchivedCString) -> bool { |
155 | 0 | PartialEq::eq(other.as_c_str(), self) |
156 | 0 | } Unexecuted instantiation: <&core::ffi::c_str::CStr as core::cmp::PartialEq<rkyv::ffi::ArchivedCString>>::eq Unexecuted instantiation: <&core::ffi::c_str::CStr as core::cmp::PartialEq<rkyv::ffi::ArchivedCString>>::eq |
157 | | } |
158 | | |
159 | | impl PartialOrd for ArchivedCString { |
160 | | #[inline] |
161 | 0 | fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> { |
162 | 0 | Some(self.cmp(other)) |
163 | 0 | } Unexecuted instantiation: <rkyv::ffi::ArchivedCString as core::cmp::PartialOrd>::partial_cmp Unexecuted instantiation: <rkyv::ffi::ArchivedCString as core::cmp::PartialOrd>::partial_cmp |
164 | | } |
165 | | |
166 | | /// The resolver for `CString`. |
167 | | pub struct CStringResolver { |
168 | | pos: FixedUsize, |
169 | | } |
170 | | |
171 | | #[cfg(feature = "bytecheck")] |
172 | | mod verify { |
173 | | use core::ffi::CStr; |
174 | | |
175 | | use bytecheck::{ |
176 | | rancor::{Fallible, Source}, |
177 | | CheckBytes, Verify, |
178 | | }; |
179 | | |
180 | | use crate::{ |
181 | | ffi::ArchivedCString, |
182 | | validation::{ArchiveContext, ArchiveContextExt}, |
183 | | }; |
184 | | |
185 | | unsafe impl<C> Verify<C> for ArchivedCString |
186 | | where |
187 | | C: Fallible + ArchiveContext + ?Sized, |
188 | | C::Error: Source, |
189 | | { |
190 | 0 | fn verify(&self, context: &mut C) -> Result<(), C::Error> { |
191 | 0 | let ptr = self.ptr.as_ptr_wrapping(); |
192 | 0 | context.in_subtree(ptr, |context| unsafe { |
193 | 0 | CStr::check_bytes(ptr, context) |
194 | 0 | }) Unexecuted instantiation: <rkyv::ffi::ArchivedCString as bytecheck::Verify<_>>::verify::{closure#0}Unexecuted instantiation: <rkyv::ffi::ArchivedCString as bytecheck::Verify<_>>::verify::{closure#0} |
195 | 0 | } Unexecuted instantiation: <rkyv::ffi::ArchivedCString as bytecheck::Verify<_>>::verify Unexecuted instantiation: <rkyv::ffi::ArchivedCString as bytecheck::Verify<_>>::verify |
196 | | } |
197 | | } |