|
1 | | -use super::{PropCursor, RefDtb}; |
2 | | -use core::{fmt::Debug, marker::PhantomData, mem::MaybeUninit}; |
3 | | -use serde::{de, Deserialize}; |
| 1 | +use super::{PropCursor, RefDtb, ValueCursor, ValueDeserializer}; |
| 2 | +use core::{fmt::Debug, mem::MaybeUninit}; |
| 3 | +use serde::Deserialize; |
4 | 4 |
|
5 | 5 | /// 一组 '\0' 分隔字符串的映射。 |
6 | 6 | /// |
@@ -31,70 +31,23 @@ impl<'de> Deserialize<'de> for StrSeq<'_> { |
31 | 31 | where |
32 | 32 | D: serde::Deserializer<'de>, |
33 | 33 | { |
34 | | - struct Visitor<'de, 'b> { |
35 | | - marker: PhantomData<StrSeq<'b>>, |
36 | | - lifetime: PhantomData<&'de ()>, |
37 | | - } |
38 | | - impl<'de, 'b> de::Visitor<'de> for Visitor<'de, 'b> { |
39 | | - type Value = StrSeq<'b>; |
40 | | - |
41 | | - fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result { |
42 | | - write!(formatter, "struct StrSeq") |
43 | | - } |
| 34 | + let value_deserialzer = super::ValueDeserializer::deserialize(deserializer)?; |
44 | 35 |
|
45 | | - fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E> |
46 | | - where |
47 | | - E: de::Error, |
48 | | - { |
49 | | - // 结构体转为内存切片,然后拷贝过来 |
50 | | - if v.len() == core::mem::size_of::<Self::Value>() { |
51 | | - Ok(Self::Value::from_raw_parts(v.as_ptr())) |
52 | | - } else { |
53 | | - Err(E::invalid_length( |
54 | | - v.len(), |
55 | | - &"`StrSeq` is copied with wrong size.", |
56 | | - )) |
| 36 | + let inner = Inner { |
| 37 | + dtb: value_deserialzer.dtb, |
| 38 | + cursor: match value_deserialzer.cursor { |
| 39 | + ValueCursor::Prop(_, cursor) => cursor, |
| 40 | + _ => { |
| 41 | + unreachable!("Reg Deserialize should only be called by prop cursor") |
57 | 42 | } |
58 | | - } |
59 | | - } |
60 | | - |
61 | | - serde::Deserializer::deserialize_newtype_struct( |
62 | | - deserializer, |
63 | | - "StrSeq", |
64 | | - Visitor { |
65 | | - marker: PhantomData, |
66 | | - lifetime: PhantomData, |
67 | 43 | }, |
68 | | - ) |
| 44 | + }; |
| 45 | + |
| 46 | + Ok(Self(inner)) |
69 | 47 | } |
70 | 48 | } |
71 | 49 |
|
72 | 50 | impl StrSeq<'_> { |
73 | | - fn from_raw_parts(ptr: *const u8) -> Self { |
74 | | - // 直接从指针拷贝 |
75 | | - let res = unsafe { |
76 | | - let mut res = MaybeUninit::<Self>::uninit(); |
77 | | - core::ptr::copy_nonoverlapping( |
78 | | - ptr, |
79 | | - res.as_mut_ptr() as *mut _, |
80 | | - core::mem::size_of::<Self>(), |
81 | | - ); |
82 | | - res.assume_init() |
83 | | - }; |
84 | | - // 初始化 |
85 | | - res.0.cursor.operate_on(res.0.dtb, |data| { |
86 | | - let mut i = data.len() - 1; |
87 | | - for j in (0..data.len() - 1).rev() { |
88 | | - if data[j] == b'\0' { |
89 | | - data[i] = (i - j - 1) as _; |
90 | | - i = j; |
91 | | - } |
92 | | - } |
93 | | - data[i] = i as u8; |
94 | | - }); |
95 | | - res |
96 | | - } |
97 | | - |
98 | 51 | /// 构造一个可访问每个字符串的迭代器。 |
99 | 52 | pub fn iter(&self) -> StrSeqIter { |
100 | 53 | StrSeqIter { |
@@ -125,27 +78,15 @@ impl<'de> Iterator for StrSeqIter<'de> { |
125 | 78 | if self.data.is_empty() { |
126 | 79 | None |
127 | 80 | } else { |
128 | | - let len = *self.data.last().unwrap() as usize; |
129 | | - let (a, b) = self.data.split_at(self.data.len() - len - 1); |
130 | | - self.data = a; |
131 | | - Some(unsafe { core::str::from_utf8_unchecked(&b[..len]) }) |
| 81 | + let pos = self |
| 82 | + .data |
| 83 | + .iter() |
| 84 | + .position(|&x| x == b'\0') |
| 85 | + .unwrap_or_else(|| self.data.len()); |
| 86 | + let (a, b) = self.data.split_at(pos + 1); |
| 87 | + self.data = b; |
| 88 | + // Remove \0 at end |
| 89 | + Some(unsafe { core::str::from_utf8_unchecked(&a[..a.len() - 1]) }) |
132 | 90 | } |
133 | 91 | } |
134 | 92 | } |
135 | | - |
136 | | -impl Drop for StrSeq<'_> { |
137 | | - fn drop(&mut self) { |
138 | | - self.0.cursor.operate_on(self.0.dtb, |data| { |
139 | | - let mut idx = data.len() - 1; |
140 | | - loop { |
141 | | - let len = data[idx] as usize; |
142 | | - data[idx] = 0; |
143 | | - if idx > len { |
144 | | - idx -= len + 1; |
145 | | - } else { |
146 | | - break; |
147 | | - } |
148 | | - } |
149 | | - }) |
150 | | - } |
151 | | -} |
0 commit comments