rkyv_test/impls/std/
ffi.rs1use crate::{
2 ffi::{ArchivedCString, CStringResolver},
3 ser::Serializer,
4 Archive, ArchivePointee, ArchiveUnsized, Archived, ArchivedMetadata, Deserialize,
5 DeserializeUnsized, Fallible, FixedUsize, Serialize, SerializeUnsized,
6};
7use core::{alloc::Layout, ptr};
8use ptr_meta::Pointee;
9use std::alloc;
10use std::ffi::{CStr, CString};
11
12impl ArchiveUnsized for CStr {
15 type Archived = CStr;
16
17 type MetadataResolver = ();
18
19 #[inline]
20 unsafe fn resolve_metadata(
21 &self,
22 _: usize,
23 _: Self::MetadataResolver,
24 out: *mut ArchivedMetadata<Self>,
25 ) {
26 out.write(to_archived!(ptr_meta::metadata(self) as FixedUsize))
27 }
28}
29
30impl ArchivePointee for CStr {
31 type ArchivedMetadata = Archived<usize>;
32
33 #[inline]
34 fn pointer_metadata(archived: &Self::ArchivedMetadata) -> <Self as Pointee>::Metadata {
35 <[u8]>::pointer_metadata(archived)
36 }
37}
38
39impl<S: Serializer + ?Sized> SerializeUnsized<S> for CStr {
40 #[inline]
41 fn serialize_unsized(&self, serializer: &mut S) -> Result<usize, S::Error> {
42 let result = serializer.pos();
43 serializer.write(self.to_bytes_with_nul())?;
44 Ok(result)
45 }
46
47 #[inline]
48 fn serialize_metadata(&self, _: &mut S) -> Result<Self::MetadataResolver, S::Error> {
49 Ok(())
50 }
51}
52
53impl<D: Fallible + ?Sized> DeserializeUnsized<CStr, D> for <CStr as ArchiveUnsized>::Archived {
54 #[inline]
55 unsafe fn deserialize_unsized(
56 &self,
57 _: &mut D,
58 mut alloc: impl FnMut(Layout) -> *mut u8,
59 ) -> Result<*mut (), D::Error> {
60 let slice = self.to_bytes_with_nul();
61 let bytes = alloc(Layout::array::<u8>(slice.len()).unwrap());
62 assert!(!bytes.is_null());
63 ptr::copy_nonoverlapping(slice.as_ptr(), bytes, slice.len());
64 Ok(bytes.cast())
65 }
66
67 #[inline]
68 fn deserialize_metadata(&self, _: &mut D) -> Result<<CStr as Pointee>::Metadata, D::Error> {
69 Ok(ptr_meta::metadata(self))
70 }
71}
72
73impl PartialEq<CString> for ArchivedCString {
76 #[inline]
77 fn eq(&self, other: &CString) -> bool {
78 PartialEq::eq(self.as_c_str(), other.as_c_str())
79 }
80}
81
82impl PartialEq<ArchivedCString> for CString {
83 #[inline]
84 fn eq(&self, other: &ArchivedCString) -> bool {
85 PartialEq::eq(other.as_c_str(), self.as_c_str())
86 }
87}
88
89impl Archive for CString {
90 type Archived = ArchivedCString;
91 type Resolver = CStringResolver;
92
93 #[inline]
94 unsafe fn resolve(&self, pos: usize, resolver: Self::Resolver, out: *mut Self::Archived) {
95 ArchivedCString::resolve_from_c_str(self.as_c_str(), pos, resolver, out);
96 }
97}
98
99impl<S: Serializer + ?Sized> Serialize<S> for CString {
100 #[inline]
101 fn serialize(&self, serializer: &mut S) -> Result<Self::Resolver, S::Error> {
102 ArchivedCString::serialize_from_c_str(self.as_c_str(), serializer)
103 }
104}
105
106impl<D: Fallible + ?Sized> Deserialize<CString, D> for Archived<CString>
107where
108 CStr: DeserializeUnsized<CStr, D>,
109{
110 #[inline]
111 fn deserialize(&self, deserializer: &mut D) -> Result<CString, D::Error> {
112 unsafe {
113 let data_address = self
114 .as_c_str()
115 .deserialize_unsized(deserializer, |layout| alloc::alloc(layout))?;
116 let metadata = self.as_c_str().deserialize_metadata(deserializer)?;
117 let ptr = ptr_meta::from_raw_parts_mut(data_address, metadata);
118 Ok(Box::<CStr>::from_raw(ptr).into())
119 }
120 }
121}