diff --git a/examples/qemu-virt.rs b/examples/qemu-virt.rs index 4f22fd3..b2bc5a4 100644 --- a/examples/qemu-virt.rs +++ b/examples/qemu-virt.rs @@ -142,7 +142,7 @@ fn main() -> Result<(), Error> { // 解析过程中,设备树的内容被修改了。 // 因此若要以其他方式再次访问设备树,先将这次解析的结果释放。 - assert_ne!(slice, RAW_DEVICE_TREE); + // assert_ne!(slice, RAW_DEVICE_TREE); } // 释放后,内存会恢复原状。 assert_eq!(slice, RAW_DEVICE_TREE); diff --git a/src/de_mut/cursor.rs b/src/de_mut/cursor.rs index df27d65..b1ab059 100644 --- a/src/de_mut/cursor.rs +++ b/src/de_mut/cursor.rs @@ -246,16 +246,6 @@ impl PropCursor { )) } } - - pub fn operate_on(&self, dtb: RefDtb<'_>, f: impl FnOnce(&mut [u8])) { - if let [_, len_data, _, data @ ..] = &mut dtb.borrow_mut().structure[self.0..] { - f(unsafe { - core::slice::from_raw_parts_mut(data.as_mut_ptr() as _, len_data.as_usize()) - }); - } else { - todo!() - } - } } #[derive(Debug)] diff --git a/src/de_mut/data.rs b/src/de_mut/data.rs index 0074c1c..9145ccd 100644 --- a/src/de_mut/data.rs +++ b/src/de_mut/data.rs @@ -239,37 +239,7 @@ impl<'de> de::Deserializer<'de> for &mut ValueDeserializer<'de> { if name == super::VALUE_DESERIALIZER_NAME { return visitor.visit_newtype_struct(self); } - match self.cursor { - ValueCursor::Prop(_, cursor) => match name { - "StrSeq" => { - let inner = super::str_seq::Inner { - dtb: self.dtb, - cursor, - }; - visitor.visit_borrowed_bytes(unsafe { - core::slice::from_raw_parts( - &inner as *const _ as *const u8, - core::mem::size_of_val(&inner), - ) - }) - } - "Reg" => { - let inner = super::reg::Inner { - dtb: self.dtb, - reg: self.reg, - cursor, - }; - visitor.visit_borrowed_bytes(unsafe { - core::slice::from_raw_parts( - &inner as *const _ as *const u8, - core::mem::size_of_val(&inner), - ) - }) - } - _ => visitor.visit_newtype_struct(self), - }, - ValueCursor::Body(_) => visitor.visit_newtype_struct(self), - } + unreachable!("unknown newtype struct"); } fn deserialize_seq(self, visitor: V) -> Result diff --git a/src/de_mut/reg.rs b/src/de_mut/reg.rs index cd2f4ac..c8721fa 100644 --- a/src/de_mut/reg.rs +++ b/src/de_mut/reg.rs @@ -1,6 +1,6 @@ -use super::{PropCursor, RefDtb, StructureBlock, BLOCK_LEN}; -use core::{fmt::Debug, marker::PhantomData, mem::MaybeUninit, ops::Range}; -use serde::{de, Deserialize}; +use super::{PropCursor, RefDtb, StructureBlock, ValueCursor, BLOCK_LEN}; +use core::{fmt::Debug, ops::Range}; +use serde::Deserialize; /// 节点地址空间。 pub struct Reg<'de>(Inner<'de>); @@ -40,58 +40,24 @@ impl<'de> Deserialize<'de> for Reg<'_> { where D: serde::Deserializer<'de>, { - struct Visitor<'de, 'b> { - marker: PhantomData>, - lifetime: PhantomData<&'de ()>, - } - impl<'de, 'b> de::Visitor<'de> for Visitor<'de, 'b> { - type Value = Reg<'b>; - - fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result { - write!(formatter, "struct Reg") - } + let value_deserialzer = super::ValueDeserializer::deserialize(deserializer)?; - fn visit_borrowed_bytes(self, v: &'de [u8]) -> Result - where - E: de::Error, - { - // 结构体转为内存切片,然后拷贝过来 - if v.len() == core::mem::size_of::() { - Ok(Self::Value::from_raw_parts(v.as_ptr())) - } else { - Err(E::invalid_length( - v.len(), - &"`Reg` is copied with wrong size.", - )) + let inner = Inner { + dtb: value_deserialzer.dtb, + reg: value_deserialzer.reg, + cursor: match value_deserialzer.cursor { + ValueCursor::Prop(_, cursor) => cursor, + _ => { + unreachable!("Reg Deserialize should only be called by prop cursor") } - } - } - - serde::Deserializer::deserialize_newtype_struct( - deserializer, - "Reg", - Visitor { - marker: PhantomData, - lifetime: PhantomData, }, - ) + }; + + Ok(Self(inner)) } } impl Reg<'_> { - fn from_raw_parts(ptr: *const u8) -> Self { - // 直接从指针拷贝 - unsafe { - let mut res = MaybeUninit::::uninit(); - core::ptr::copy_nonoverlapping( - ptr, - res.as_mut_ptr() as *mut _, - core::mem::size_of::(), - ); - res.assume_init() - } - } - pub fn iter(&self) -> RegIter { RegIter { data: self.0.cursor.data_on(self.0.dtb), diff --git a/src/de_mut/str_seq.rs b/src/de_mut/str_seq.rs index 086d390..2858b35 100644 --- a/src/de_mut/str_seq.rs +++ b/src/de_mut/str_seq.rs @@ -1,6 +1,6 @@ -use super::{PropCursor, RefDtb}; -use core::{fmt::Debug, marker::PhantomData, mem::MaybeUninit}; -use serde::{de, Deserialize}; +use super::{PropCursor, RefDtb, ValueCursor}; +use core::fmt::Debug; +use serde::Deserialize; /// 一组 '\0' 分隔字符串的映射。 /// @@ -31,70 +31,23 @@ impl<'de> Deserialize<'de> for StrSeq<'_> { where D: serde::Deserializer<'de>, { - struct Visitor<'de, 'b> { - marker: PhantomData>, - lifetime: PhantomData<&'de ()>, - } - impl<'de, 'b> de::Visitor<'de> for Visitor<'de, 'b> { - type Value = StrSeq<'b>; - - fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result { - write!(formatter, "struct StrSeq") - } + let value_deserialzer = super::ValueDeserializer::deserialize(deserializer)?; - fn visit_borrowed_bytes(self, v: &'de [u8]) -> Result - where - E: de::Error, - { - // 结构体转为内存切片,然后拷贝过来 - if v.len() == core::mem::size_of::() { - Ok(Self::Value::from_raw_parts(v.as_ptr())) - } else { - Err(E::invalid_length( - v.len(), - &"`StrSeq` is copied with wrong size.", - )) + let inner = Inner { + dtb: value_deserialzer.dtb, + cursor: match value_deserialzer.cursor { + ValueCursor::Prop(_, cursor) => cursor, + _ => { + unreachable!("Reg Deserialize should only be called by prop cursor") } - } - } - - serde::Deserializer::deserialize_newtype_struct( - deserializer, - "StrSeq", - Visitor { - marker: PhantomData, - lifetime: PhantomData, }, - ) + }; + + Ok(Self(inner)) } } impl StrSeq<'_> { - fn from_raw_parts(ptr: *const u8) -> Self { - // 直接从指针拷贝 - let res = unsafe { - let mut res = MaybeUninit::::uninit(); - core::ptr::copy_nonoverlapping( - ptr, - res.as_mut_ptr() as *mut _, - core::mem::size_of::(), - ); - res.assume_init() - }; - // 初始化 - res.0.cursor.operate_on(res.0.dtb, |data| { - let mut i = data.len() - 1; - for j in (0..data.len() - 1).rev() { - if data[j] == b'\0' { - data[i] = (i - j - 1) as _; - i = j; - } - } - data[i] = i as u8; - }); - res - } - /// 构造一个可访问每个字符串的迭代器。 pub fn iter(&self) -> StrSeqIter { StrSeqIter { @@ -125,27 +78,15 @@ impl<'de> Iterator for StrSeqIter<'de> { if self.data.is_empty() { None } else { - let len = *self.data.last().unwrap() as usize; - let (a, b) = self.data.split_at(self.data.len() - len - 1); - self.data = a; - Some(unsafe { core::str::from_utf8_unchecked(&b[..len]) }) + let pos = self + .data + .iter() + .position(|&x| x == b'\0') + .unwrap_or(self.data.len()); + let (a, b) = self.data.split_at(pos + 1); + self.data = b; + // Remove \0 at end + Some(unsafe { core::str::from_utf8_unchecked(&a[..a.len() - 1]) }) } } } - -impl Drop for StrSeq<'_> { - fn drop(&mut self) { - self.0.cursor.operate_on(self.0.dtb, |data| { - let mut idx = data.len() - 1; - loop { - let len = data[idx] as usize; - data[idx] = 0; - if idx > len { - idx -= len + 1; - } else { - break; - } - } - }) - } -}