diff --git a/src/de_mut/cursor.rs b/src/de_mut/cursor.rs index 1ca239c..df27d65 100644 --- a/src/de_mut/cursor.rs +++ b/src/de_mut/cursor.rs @@ -7,7 +7,6 @@ pub(super) struct AnyCursor(usize, PhantomData); pub(super) type BodyCursor = AnyCursor; pub(super) type TitleCursor = AnyCursor; -pub(super) type GroupCursor = AnyCursor<Group>; pub(super) type PropCursor = AnyCursor<Prop>; pub(super) trait Type {} @@ -17,13 +16,10 @@ pub(super) struct Body {} #[derive(Clone, Copy, Debug)] pub(super) struct Title {} #[derive(Clone, Copy, Debug)] -pub(super) struct Group {} -#[derive(Clone, Copy, Debug)] pub(super) struct Prop {} impl Type for Body {} impl Type for Title {} -impl Type for Group {} impl Type for Prop {} pub enum MoveResult { @@ -107,7 +103,7 @@ impl BodyCursor { self.0 += 1; MoveResult::Others } - _ => todo!(), + _ => todo!("unknown block {}", structure[self.0]), } } @@ -149,10 +145,10 @@ impl TitleCursor { } /// 生成组光标。 - pub fn take_group_on(&self, dtb: RefDtb, name: &str) -> (GroupCursor, usize, BodyCursor) { + pub fn take_group_on(&self, dtb: RefDtb, name: &str) -> (BodyCursor, usize, BodyCursor) { let name_bytes = name.as_bytes(); let name_skip = align(name_bytes.len() + 1, BLOCK_LEN); - let group = AnyCursor::<Group>(self.0, PhantomData); + let group = AnyCursor::<Body>(self.0, PhantomData); let mut body = AnyCursor::<Body>(self.0 + 1 + name_skip, PhantomData); let mut len = 1; @@ -194,57 +190,6 @@ impl TitleCursor { } } -impl GroupCursor { - /// 读取缓存的下一项偏移。 - pub fn offset_on(&self, dtb: RefDtb) -> usize { - (dtb.borrow().structure[self.0].0 >> 8) as _ - } - - /// 利用缓存的名字长度取出名字。 - pub fn name_on<'a>(&self, dtb: RefDtb<'a>) -> (&'a [u8], BodyCursor) { - let structure = &dtb.borrow().structure; - let len_name = (structure[self.0].0 & 0xff) as usize; - let bytes = structure[self.0 + 1].lead_slice(len_name); - ( - bytes, - AnyCursor(self.0 + 1 + align(len_name + 1, BLOCK_LEN), PhantomData), - ) - } - - /// 初始化组反序列化。 - pub fn init_on(&self, dtb: RefDtb, len_item: usize, len_name: usize) { - let mut body = AnyCursor::<Body>(self.0, PhantomData); - for _ in 0..len_item { - let current = body.0; - let len_total = dtb.borrow().structure[current + 1] - .lead_slice(u16::MAX as _) - .iter() - .enumerate() - .skip(len_name + 1) - .find(|(_, b)| **b == b'\0') - .map(|(i, _)| i) - .unwrap(); - body.step_n(align(len_total, BLOCK_LEN)); - body.skip_str_on(dtb); - body.escape_from(dtb); - let off_next = body.0 - current; - dtb.borrow_mut().structure[current].0 = (off_next << 8 | len_total) as _; - } - } - - /// 组结构恢复原状。 - pub fn drop_on(&self, dtb: RefDtb, len_item: usize) { - use StructureBlock as B; - let structure = &mut *dtb.borrow_mut().structure; - let mut i = self.0; - for _ in 0..len_item { - let offset = (structure[i].0 >> 8) as usize; - structure[i] = B::NODE_BEGIN; - i += offset; - } - } -} - impl PropCursor { pub fn name_on<'a>(&self, dtb: RefDtb<'a>) -> (&'a str, BodyCursor) { let dtb = dtb.borrow(); diff --git a/src/de_mut/data.rs b/src/de_mut/data.rs index 3420a51..0074c1c 100644 --- a/src/de_mut/data.rs +++ b/src/de_mut/data.rs @@ -1,4 +1,4 @@ -use super::BodyCursor; +use super::{BodyCursor, Cursor}; use super::{DtError, PropCursor, RefDtb, RegConfig}; use core::marker::PhantomData; @@ -6,15 +6,14 @@ use serde::{de, Deserialize}; #[derive(Clone, Copy, Debug)] pub(super) enum ValueCursor { - Prop(PropCursor), + Prop(BodyCursor, PropCursor), Body(BodyCursor), } -#[derive(Clone)] +#[derive(Clone, Copy)] pub(super) struct ValueDeserializer<'de> { pub dtb: RefDtb<'de>, pub reg: RegConfig, - pub body_cursor: BodyCursor, pub cursor: ValueCursor, } @@ -39,8 +38,7 @@ impl<'de> Deserialize<'de> for ValueDeserializer<'_> { D: de::Deserializer<'de>, { Ok(unsafe { - (*(core::ptr::addr_of!(deserializer) as *const _ as *const &ValueDeserializer)) - .clone() + *(*(core::ptr::addr_of!(deserializer) as *const _ as *const &ValueDeserializer)) }) } } @@ -70,7 +68,7 @@ impl<'de> de::Deserializer<'de> for &mut ValueDeserializer<'de> { where V: de::Visitor<'de>, { - if let ValueCursor::Prop(cursor) = self.cursor { + if let ValueCursor::Prop(_, cursor) = self.cursor { let val = cursor.map_on(self.dtb, |data| { if data.is_empty() { true @@ -129,7 +127,7 @@ impl<'de> de::Deserializer<'de> for &mut ValueDeserializer<'de> { where V: de::Visitor<'de>, { - if let ValueCursor::Prop(cursor) = self.cursor { + if let ValueCursor::Prop(_, cursor) = self.cursor { return visitor.visit_u32(cursor.map_u32_on(self.dtb)?); } unreachable!("node -> u32"); @@ -181,7 +179,7 @@ impl<'de> de::Deserializer<'de> for &mut ValueDeserializer<'de> { where V: de::Visitor<'de>, { - if let ValueCursor::Prop(cursor) = self.cursor { + if let ValueCursor::Prop(_, cursor) = self.cursor { let data = cursor.data_on(self.dtb); return visitor.visit_borrowed_bytes(data); } @@ -200,7 +198,7 @@ impl<'de> de::Deserializer<'de> for &mut ValueDeserializer<'de> { V: de::Visitor<'de>, { match self.cursor { - ValueCursor::Prop(cursor) => { + ValueCursor::Prop(_, cursor) => { let data = cursor.data_on(self.dtb); if data.is_empty() { visitor.visit_none() @@ -242,7 +240,7 @@ impl<'de> de::Deserializer<'de> for &mut ValueDeserializer<'de> { return visitor.visit_newtype_struct(self); } match self.cursor { - ValueCursor::Prop(cursor) => match name { + ValueCursor::Prop(_, cursor) => match name { "StrSeq" => { let inner = super::str_seq::Inner { dtb: self.dtb, @@ -274,11 +272,31 @@ impl<'de> de::Deserializer<'de> for &mut ValueDeserializer<'de> { } } - fn deserialize_seq<V>(self, _visitor: V) -> Result<V::Value, Self::Error> + fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: de::Visitor<'de>, { - unreachable!("seq") + use super::{StructAccess, StructAccessType, Temp}; + match self.move_on() { + Cursor::Title(c) => { + let (name, _) = c.split_on(self.dtb); + let cursor = match self.cursor { + ValueCursor::Body(cursor) => cursor, + _ => unreachable!(""), + }; + + let pre_len = name.as_bytes().iter().take_while(|b| **b != b'@').count(); + let name_bytes = &name.as_bytes()[..pre_len]; + let name = unsafe { core::str::from_utf8_unchecked(name_bytes) }; + + visitor.visit_seq(StructAccess { + access_type: StructAccessType::Seq(name), + temp: Temp::Node(cursor, cursor), + de: self, + }) + } + _ => unreachable!("seq request on a none seq cursor"), + } } fn deserialize_tuple<V>(self, _len: usize, _visitor: V) -> Result<V::Value, Self::Error> @@ -308,7 +326,7 @@ impl<'de> de::Deserializer<'de> for &mut ValueDeserializer<'de> { if let ValueCursor::Body(cursor) = self.cursor { return visitor.visit_map(StructAccess { access_type: StructAccessType::Map(false), - temp: Temp::Node(self.body_cursor, cursor), + temp: Temp::Node(cursor, cursor), de: self, }); }; @@ -328,7 +346,7 @@ impl<'de> de::Deserializer<'de> for &mut ValueDeserializer<'de> { if let ValueCursor::Body(cursor) = self.cursor { return visitor.visit_map(StructAccess { access_type: StructAccessType::Struct(fields), - temp: Temp::Node(self.body_cursor, cursor), + temp: Temp::Node(cursor, cursor), de: self, }); }; @@ -364,7 +382,7 @@ impl<'de> de::Deserializer<'de> for &mut ValueDeserializer<'de> { impl ValueDeserializer<'_> { #[inline] - pub fn move_next(&mut self) -> super::Cursor { + pub fn move_on(&mut self) -> super::Cursor { if let ValueCursor::Body(ref mut cursor) = self.cursor { return cursor.move_on(self.dtb); }; diff --git a/src/de_mut/group.rs b/src/de_mut/group.rs deleted file mode 100644 index 4c70202..0000000 --- a/src/de_mut/group.rs +++ /dev/null @@ -1,251 +0,0 @@ -use super::{DtError, GroupCursor, RefDtb, RegConfig}; -use serde::de; - -#[allow(unused)] -#[derive(Clone, Copy)] -pub(super) struct GroupDeserializer<'de> { - pub dtb: RefDtb<'de>, - pub cursor: GroupCursor, - pub reg: RegConfig, - pub len_item: usize, - pub len_name: usize, -} - -impl<'de> de::Deserializer<'de> for &mut GroupDeserializer<'de> { - type Error = DtError; - - fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value, Self::Error> - where - V: de::Visitor<'de>, - { - todo!("any") - } - - fn deserialize_bool<V>(self, _visitor: V) -> Result<V::Value, Self::Error> - where - V: de::Visitor<'de>, - { - todo!("bool") - } - - fn deserialize_i8<V>(self, _visitor: V) -> Result<V::Value, Self::Error> - where - V: de::Visitor<'de>, - { - todo!("i8") - } - - fn deserialize_i16<V>(self, _visitor: V) -> Result<V::Value, Self::Error> - where - V: de::Visitor<'de>, - { - todo!("i16") - } - - fn deserialize_i32<V>(self, _visitor: V) -> Result<V::Value, Self::Error> - where - V: de::Visitor<'de>, - { - todo!("i32") - } - - fn deserialize_i64<V>(self, _visitor: V) -> Result<V::Value, Self::Error> - where - V: de::Visitor<'de>, - { - todo!("i64") - } - - fn deserialize_u8<V>(self, _visitor: V) -> Result<V::Value, Self::Error> - where - V: de::Visitor<'de>, - { - todo!("u8") - } - - fn deserialize_u16<V>(self, _visitor: V) -> Result<V::Value, Self::Error> - where - V: de::Visitor<'de>, - { - todo!("u16") - } - - fn deserialize_u32<V>(self, _visitor: V) -> Result<V::Value, Self::Error> - where - V: de::Visitor<'de>, - { - todo!("u32") - } - - fn deserialize_u64<V>(self, _visitor: V) -> Result<V::Value, Self::Error> - where - V: de::Visitor<'de>, - { - todo!("u64") - } - - fn deserialize_f32<V>(self, _visitor: V) -> Result<V::Value, Self::Error> - where - V: de::Visitor<'de>, - { - todo!("f32") - } - - fn deserialize_f64<V>(self, _visitor: V) -> Result<V::Value, Self::Error> - where - V: de::Visitor<'de>, - { - todo!("f64") - } - - fn deserialize_char<V>(self, _visitor: V) -> Result<V::Value, Self::Error> - where - V: de::Visitor<'de>, - { - todo!("char") - } - - fn deserialize_str<V>(self, _visitor: V) -> Result<V::Value, Self::Error> - where - V: de::Visitor<'de>, - { - todo!("str") - } - - fn deserialize_string<V>(self, _visitor: V) -> Result<V::Value, Self::Error> - where - V: de::Visitor<'de>, - { - todo!("string") - } - - fn deserialize_bytes<V>(self, _visitor: V) -> Result<V::Value, Self::Error> - where - V: de::Visitor<'de>, - { - todo!("bytes") - } - - fn deserialize_byte_buf<V>(self, _visitor: V) -> Result<V::Value, Self::Error> - where - V: de::Visitor<'de>, - { - todo!("byte_buf") - } - - fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error> - where - V: de::Visitor<'de>, - { - visitor.visit_some(self) - } - - fn deserialize_unit<V>(self, _visitor: V) -> Result<V::Value, Self::Error> - where - V: de::Visitor<'de>, - { - todo!("unit") - } - - fn deserialize_unit_struct<V>( - self, - _name: &'static str, - _visitor: V, - ) -> Result<V::Value, Self::Error> - where - V: de::Visitor<'de>, - { - todo!("unit_struct") - } - - fn deserialize_newtype_struct<V>( - self, - name: &'static str, - visitor: V, - ) -> Result<V::Value, Self::Error> - where - V: de::Visitor<'de>, - { - if name == "NodeSeq" { - visitor.visit_borrowed_bytes(unsafe { - core::slice::from_raw_parts( - self as *const _ as *const u8, - core::mem::size_of::<GroupDeserializer<'_>>(), - ) - }) - } else { - visitor.visit_newtype_struct(self) - } - } - - fn deserialize_seq<V>(self, _visitor: V) -> Result<V::Value, Self::Error> - where - V: de::Visitor<'de>, - { - todo!("seq") - } - - fn deserialize_tuple<V>(self, _len: usize, _visitor: V) -> Result<V::Value, Self::Error> - where - V: de::Visitor<'de>, - { - todo!("tuple") - } - - fn deserialize_tuple_struct<V>( - self, - _name: &'static str, - _len: usize, - _visitor: V, - ) -> Result<V::Value, Self::Error> - where - V: de::Visitor<'de>, - { - todo!("tuple_struct") - } - - fn deserialize_map<V>(self, _visitor: V) -> Result<V::Value, Self::Error> - where - V: de::Visitor<'de>, - { - todo!("map") - } - - fn deserialize_struct<V>( - self, - _name: &'static str, - _fields: &'static [&'static str], - _visitor: V, - ) -> Result<V::Value, Self::Error> - where - V: de::Visitor<'de>, - { - todo!("struct") - } - - fn deserialize_enum<V>( - self, - _name: &'static str, - _variants: &'static [&'static str], - _visitor: V, - ) -> Result<V::Value, Self::Error> - where - V: de::Visitor<'de>, - { - todo!("enum") - } - - fn deserialize_identifier<V>(self, _visitor: V) -> Result<V::Value, Self::Error> - where - V: de::Visitor<'de>, - { - todo!("identifer") - } - - fn deserialize_ignored_any<V>(self, _visitor: V) -> Result<V::Value, Self::Error> - where - V: de::Visitor<'de>, - { - todo!("ignored_any") - } -} diff --git a/src/de_mut/mod.rs b/src/de_mut/mod.rs index 0f9a60e..44c996e 100644 --- a/src/de_mut/mod.rs +++ b/src/de_mut/mod.rs @@ -6,7 +6,7 @@ use serde::de; mod cursor; mod data; -mod group; +// mod group; mod node; mod node_seq; mod reg; @@ -21,9 +21,8 @@ pub mod buildin { pub use super::{node::Node, node_seq::NodeSeq, reg::Reg, str_seq::StrSeq}; } -use cursor::{BodyCursor, Cursor, GroupCursor, PropCursor}; +use cursor::{BodyCursor, Cursor, PropCursor}; use data::{ValueCursor, ValueDeserializer}; -use group::GroupDeserializer; use reg::RegConfig; use structs::{RefDtb, StructureBlock, BLOCK_LEN}; @@ -40,7 +39,6 @@ where let mut d = ValueDeserializer { dtb, reg: RegConfig::DEFAULT, - body_cursor: BodyCursor::ROOT, cursor: ValueCursor::Body(BodyCursor::ROOT), }; T::deserialize(&mut d).and_then(|t| { @@ -54,14 +52,15 @@ where } // For map type, we should send root item to trans dtb and reg -enum StructAccessType { +enum StructAccessType<'de> { Map(bool), + Seq(&'de str), Struct(&'static [&'static str]), } /// 结构体解析状态。 struct StructAccess<'de, 'b> { - access_type: StructAccessType, + access_type: StructAccessType<'de>, temp: Temp, de: &'b mut ValueDeserializer<'de>, } @@ -72,7 +71,7 @@ struct StructAccess<'de, 'b> { /// 根据状态分发值解析器。 enum Temp { Node(BodyCursor, BodyCursor), - Group(GroupCursor, usize, usize), + Group(BodyCursor), Prop(BodyCursor, PropCursor), } @@ -101,7 +100,7 @@ impl<'de> de::MapAccess<'de> for StructAccess<'de, '_> { ValueCursor::Body(cursor) => cursor, _ => unreachable!("map access's cursor should always be body cursor"), }; - match self.de.move_next() { + match self.de.move_on() { // 子节点名字 Cursor::Title(c) => { let (name, _) = c.split_on(self.de.dtb); @@ -120,10 +119,10 @@ impl<'de> de::MapAccess<'de> for StructAccess<'de, '_> { else { let name_bytes = &name.as_bytes()[..pre_len]; let name = unsafe { core::str::from_utf8_unchecked(name_bytes) }; - let (group, len, next) = c.take_group_on(self.de.dtb, name); + let (group, _, next) = c.take_group_on(self.de.dtb, name); self.de.cursor = ValueCursor::Body(next); if check_contains(name) { - self.temp = Temp::Group(group, len, name.len()); + self.temp = Temp::Group(group); break name; } } @@ -167,40 +166,83 @@ impl<'de> de::MapAccess<'de> for StructAccess<'de, '_> { return seed.deserialize(&mut ValueDeserializer { dtb: self.de.dtb, reg: self.de.reg, - body_cursor: self.de.body_cursor, cursor: self.de.cursor, }); } } match self.temp { - Temp::Node(origin_cursor, cursor) => { + Temp::Node(cursor, node_cursor) => { // 键是独立节点名字,递归 - seed.deserialize(&mut ValueDeserializer { - dtb: self.de.dtb, - reg: self.de.reg, - body_cursor: origin_cursor, - cursor: ValueCursor::Body(cursor), - }) + match self.access_type { + StructAccessType::Map(_) => seed.deserialize(&mut ValueDeserializer { + dtb: self.de.dtb, + reg: self.de.reg, + cursor: ValueCursor::Body(cursor), + }), + StructAccessType::Struct(_) => seed.deserialize(&mut ValueDeserializer { + dtb: self.de.dtb, + reg: self.de.reg, + cursor: ValueCursor::Body(node_cursor), + }), + _ => unreachable!(), + } } - Temp::Group(cursor, len_item, len_name) => { + Temp::Group(cursor) => { // 键是组名字,构造组反序列化器 - seed.deserialize(&mut GroupDeserializer { + seed.deserialize(&mut ValueDeserializer { dtb: self.de.dtb, - cursor, reg: self.de.reg, - len_item, - len_name, + cursor: ValueCursor::Body(cursor), }) } Temp::Prop(origin_cursor, cursor) => { // 键是属性名字,构造属性反序列化器 seed.deserialize(&mut ValueDeserializer { dtb: self.de.dtb, - body_cursor: origin_cursor, reg: self.de.reg, - cursor: ValueCursor::Prop(cursor), + cursor: ValueCursor::Prop(origin_cursor, cursor), }) } } } } + +impl<'de> de::SeqAccess<'de> for StructAccess<'de, '_> { + type Error = DtError; + + fn next_element_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error> + where + K: de::DeserializeSeed<'de>, + { + if let StructAccessType::Seq(pre_name) = self.access_type { + match self.de.move_on() { + // 子节点名字 + Cursor::Title(c) => { + let (name, _) = c.split_on(self.de.dtb); + let (_, next) = c.take_node_on(self.de.dtb, name); + let prev_cursor = match self.de.cursor { + ValueCursor::Body(cursor) => cursor, + _ => unreachable!(), + }; + + let pre_len = name.as_bytes().iter().take_while(|b| **b != b'@').count(); + let name_bytes = &name.as_bytes()[..pre_len]; + let name = unsafe { core::str::from_utf8_unchecked(name_bytes) }; + if pre_name != name { + return Ok(None); + } + self.de.cursor = ValueCursor::Body(next); + seed.deserialize(&mut ValueDeserializer { + dtb: self.de.dtb, + reg: self.de.reg, + cursor: ValueCursor::Body(prev_cursor), + }) + .map(Some) + } + _ => Ok(None), + } + } else { + unreachable!("SeqAccess should only be accessed by seq"); + } + } +} diff --git a/src/de_mut/node.rs b/src/de_mut/node.rs index 302229a..318d62f 100644 --- a/src/de_mut/node.rs +++ b/src/de_mut/node.rs @@ -49,26 +49,20 @@ impl<'de> Node<'de> { // TODO: Maybe use BTreeMap when have alloc /// 获得节点迭代器。 pub fn nodes<'b>(&'b self) -> Option<NodeIter<'de, 'b>> { - match self.nodes_start { - None => None, - Some(node_cursor) => Some(NodeIter { + self.nodes_start.map(|node_cursor| NodeIter { node: self, cursor: node_cursor, i: 0, - }), - } + }) } /// 获得属性迭代器。 pub fn props<'b>(&'b self) -> Option<PropIter<'de, 'b>> { - match self.props_start { - None => None, - Some(node_cursor) => Some(PropIter { + self.props_start.map(|node_cursor| PropIter { node: self, cursor: node_cursor, i: 0, - }), - } + }) } } @@ -186,14 +180,14 @@ impl<'de> Deserialize<'de> for Node<'_> { continue; } match value.cursor { - ValueCursor::Prop(_) => { + ValueCursor::Prop(cursor, _) => { if props_start.is_none() { - props_start = Some(value.body_cursor); + props_start = Some(cursor); } } - ValueCursor::Body(_) => { + ValueCursor::Body(cursor) => { if nodes_start.is_none() { - nodes_start = Some(value.body_cursor); + nodes_start = Some(cursor); } } } @@ -224,7 +218,6 @@ impl<'de> NodeItem<'de> { T::deserialize(&mut ValueDeserializer { dtb: self.dtb, reg: self.reg, - body_cursor: self.node, cursor: ValueCursor::Body(self.node), }) .unwrap() @@ -261,8 +254,7 @@ impl<'de> PropItem<'de> { T::deserialize(&mut ValueDeserializer { dtb: self.dtb, reg: self.reg, - body_cursor: self.body, - cursor: ValueCursor::Prop(self.prop), + cursor: ValueCursor::Prop(self.body, self.prop), }) .unwrap() } diff --git a/src/de_mut/node_seq.rs b/src/de_mut/node_seq.rs index 824e024..3b5a7b5 100644 --- a/src/de_mut/node_seq.rs +++ b/src/de_mut/node_seq.rs @@ -1,6 +1,6 @@ -use super::{BodyCursor, GroupCursor, RefDtb, RegConfig, ValueCursor, ValueDeserializer}; -use crate::de_mut::GroupDeserializer; +use super::{BodyCursor, Cursor, RefDtb, RegConfig, ValueCursor, ValueDeserializer}; use core::{fmt::Debug, marker::PhantomData}; +use serde::de::SeqAccess; use serde::{de, Deserialize}; /// 一组名字以 `@...` 区分,同类、同级且连续的节点的映射。 @@ -9,13 +9,15 @@ use serde::{de, Deserialize}; /// 因此这些节点将延迟解析。 /// 迭代 `NodeSeq` 可获得一系列 [`NodeSeqItem`],再调用 `deserialize` 方法分别解析每个节点。 pub struct NodeSeq<'de> { - inner: GroupDeserializer<'de>, + name: &'de str, + count: usize, + starter: ValueDeserializer<'de>, } /// 连续节点迭代器。 pub struct NodeSeqIter<'de, 'b> { seq: &'b NodeSeq<'de>, - cursor: GroupCursor, + de: ValueDeserializer<'de>, i: usize, } @@ -40,28 +42,43 @@ impl<'de> Deserialize<'de> for NodeSeq<'_> { type Value = NodeSeq<'b>; fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result { - write!(formatter, "struct StrSeq") + write!(formatter, "struct ValueDeserializer") } - fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E> + fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error> where - E: de::Error, + A: SeqAccess<'de>, { - // 结构体转为内存切片,然后拷贝过来 - if v.len() == core::mem::size_of::<Self::Value>() { - Ok(Self::Value::from_raw_inner_parts(v.as_ptr())) - } else { - Err(E::invalid_length( - v.len(), - &"`NodeSeq` is copied with wrong size.", - )) + let mut starter: Option<ValueDeserializer> = None; + let mut count = 0; + while let Some(node) = seq.next_element()? { + if starter.is_none() { + starter = Some(node); + } + count += 1 + } + let mut starter = starter.unwrap(); + + match starter.move_on() { + Cursor::Title(c) => { + let (name, _) = c.split_on(starter.dtb); + + let pre_len = name.as_bytes().iter().take_while(|b| **b != b'@').count(); + let name_bytes = &name.as_bytes()[..pre_len]; + let name = unsafe { core::str::from_utf8_unchecked(name_bytes) }; + Ok(NodeSeq { + name, + count, + starter, + }) + } + _ => unreachable!("NodeSeq should be inited by a node"), } } } - serde::Deserializer::deserialize_newtype_struct( + serde::Deserializer::deserialize_seq( deserializer, - "NodeSeq", Visitor { marker: PhantomData, lifetime: PhantomData, @@ -71,22 +88,9 @@ impl<'de> Deserialize<'de> for NodeSeq<'_> { } impl<'de> NodeSeq<'de> { - fn from_raw_inner_parts(ptr: *const u8) -> Self { - // 直接从指针拷贝 - let original_inner = unsafe { &*(ptr as *const GroupDeserializer<'_>) }; - let res = Self { - inner: *original_inner, - }; - // 初始化 - res.inner - .cursor - .init_on(res.inner.dtb, res.inner.len_item, res.inner.len_name); - res - } - /// 连续节点总数。 pub const fn len(&self) -> usize { - self.inner.len_item + self.count } /// 如果连续节点数量为零,返回 true。但连续节点数量不可能为零。 @@ -98,7 +102,7 @@ impl<'de> NodeSeq<'de> { pub const fn iter<'b>(&'b self) -> NodeSeqIter<'de, 'b> { NodeSeqIter { seq: self, - cursor: self.inner.cursor, + de: self.starter, i: 0, } } @@ -119,32 +123,38 @@ impl Debug for NodeSeq<'_> { } } -impl Drop for NodeSeq<'_> { - fn drop(&mut self) { - self.inner - .cursor - .drop_on(self.inner.dtb, self.inner.len_item); - } -} - impl<'de> Iterator for NodeSeqIter<'de, '_> { type Item = NodeSeqItem<'de>; fn next(&mut self) -> Option<Self::Item> { - if self.i >= self.seq.inner.len_item { + if self.i >= self.seq.len() { None } else { self.i += 1; - let dtb = self.seq.inner.dtb; - let (name, body) = self.cursor.name_on(dtb); - let off_next = self.cursor.offset_on(dtb); - self.cursor.step_n(off_next); - Some(Self::Item { - dtb, - reg: self.seq.inner.reg, - body, - at: unsafe { core::str::from_utf8_unchecked(&name[self.seq.inner.len_name + 1..]) }, - }) + match self.de.move_on() { + // 子节点名字 + Cursor::Title(c) => { + let (name, _) = c.split_on(self.de.dtb); + let (node, next) = c.take_node_on(self.de.dtb, name); + + let pre_len = name.as_bytes().iter().take_while(|b| **b != b'@').count(); + let name_bytes = &name.as_bytes()[..pre_len]; + let name = unsafe { core::str::from_utf8_unchecked(name_bytes) }; + if self.seq.name != name { + return None; + } + + self.de.cursor = ValueCursor::Body(next); + + Some(Self::Item { + dtb: self.de.dtb, + reg: self.de.reg, + body: node, + at: &name[pre_len..], + }) + } + _ => None, + } } } } @@ -162,7 +172,6 @@ impl<'de> NodeSeqItem<'de> { T::deserialize(&mut ValueDeserializer { dtb: self.dtb, reg: self.reg, - body_cursor: self.body, cursor: ValueCursor::Body(self.body), }) .unwrap() diff --git a/src/de_mut/structs.rs b/src/de_mut/structs.rs index acd9c17..88b5481 100644 --- a/src/de_mut/structs.rs +++ b/src/de_mut/structs.rs @@ -94,6 +94,7 @@ impl StructureBlock { /// 构造字节切片。 /// /// TODO + #[allow(unused)] pub fn lead_slice<'a>(&self, len: usize) -> &'a [u8] { unsafe { core::slice::from_raw_parts(self as *const _ as *const u8, len) } } diff --git a/src/utils/mod.rs b/src/utils/mod.rs index e9e7ba3..86a0e58 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -58,7 +58,7 @@ mod tests { buildin::{Node, StrSeq}, from_raw_mut, Dtb, DtbPtr, }; - static RAW_DEVICE_TREE: &'static [u8] = + static RAW_DEVICE_TREE: &[u8] = include_bytes!("../../examples/hifive-unmatched-a00.dtb"); const BUFFER_SIZE: usize = RAW_DEVICE_TREE.len(); #[repr(align(8))] diff --git a/tests/hifive-unmatched-a00.rs b/tests/hifive-unmatched-a00.rs index eea8ef9..e01238a 100644 --- a/tests/hifive-unmatched-a00.rs +++ b/tests/hifive-unmatched-a00.rs @@ -55,5 +55,5 @@ fn hifive_unmatched() { } } assert_eq!(t.cpus.timebase_frequency, 1000000); - assert_eq!(t.cpus.u_boot_dm_spl, true); + assert!(t.cpus.u_boot_dm_spl); }