From 9c48188b75828a2f591b835e42c6d713b3080e75 Mon Sep 17 00:00:00 2001 From: Mingun Date: Mon, 4 Sep 2023 22:30:27 +0500 Subject: [PATCH] Move namespace buffer into NamespaceResolver No need to store it outside of resolver, because its lifetime is the same as resolver lifetime --- src/name.rs | 197 ++++++++++++++++++---------------------- src/reader/ns_reader.rs | 32 ++----- 2 files changed, 97 insertions(+), 132 deletions(-) diff --git a/src/name.rs b/src/name.rs index 07d261ab..57154788 100644 --- a/src/name.rs +++ b/src/name.rs @@ -392,6 +392,9 @@ impl NamespaceEntry { /// Holds all internal logic to push/pop namespaces with their levels. #[derive(Debug, Default, Clone)] pub(crate) struct NamespaceResolver { + /// Buffer that contains names of namespace prefixes (the part between `xmlns:` + /// and an `=`) and namespace values. + buffer: Vec, /// A stack of namespace bindings to prefixes that currently in scope bindings: Vec, /// The number of open tags at the moment. We need to keep track of this to know which namespace @@ -404,7 +407,7 @@ impl NamespaceResolver { /// the specified start element. /// /// [namespace binding]: https://www.w3.org/TR/xml-names11/#dt-NSDecl - pub fn push(&mut self, start: &BytesStart, buffer: &mut Vec) { + pub fn push(&mut self, start: &BytesStart) { self.nesting_level += 1; let level = self.nesting_level; // adds new namespaces for attributes starting with 'xmlns:' and for the 'xmlns' @@ -413,8 +416,8 @@ impl NamespaceResolver { if let Ok(Attribute { key: k, value: v }) = a { match k.as_namespace_binding() { Some(PrefixDeclaration::Default) => { - let start = buffer.len(); - buffer.extend_from_slice(&v); + let start = self.buffer.len(); + self.buffer.extend_from_slice(&v); self.bindings.push(NamespaceEntry { start, prefix_len: 0, @@ -423,9 +426,9 @@ impl NamespaceResolver { }); } Some(PrefixDeclaration::Named(prefix)) => { - let start = buffer.len(); - buffer.extend_from_slice(prefix); - buffer.extend_from_slice(&v); + let start = self.buffer.len(); + self.buffer.extend_from_slice(prefix); + self.buffer.extend_from_slice(&v); self.bindings.push(NamespaceEntry { start, prefix_len: prefix.len(), @@ -445,20 +448,20 @@ impl NamespaceResolver { /// last call to [`Self::push()`]. /// /// [namespace binding]: https://www.w3.org/TR/xml-names11/#dt-NSDecl - pub fn pop(&mut self, buffer: &mut Vec) { + pub fn pop(&mut self) { self.nesting_level -= 1; let current_level = self.nesting_level; // from the back (most deeply nested scope), look for the first scope that is still valid match self.bindings.iter().rposition(|n| n.level <= current_level) { // none of the namespaces are valid, remove all of them None => { - buffer.clear(); + self.buffer.clear(); self.bindings.clear(); } // drop all namespaces past the last valid namespace Some(last_valid_pos) => { if let Some(len) = self.bindings.get(last_valid_pos + 1).map(|n| n.start) { - buffer.truncate(len); + self.buffer.truncate(len); self.bindings.truncate(last_valid_pos + 1); } } @@ -478,50 +481,39 @@ impl NamespaceResolver { /// # Lifetimes /// /// - `'n`: lifetime of an attribute or an element name - /// - `'ns`: lifetime of a namespaces buffer, where all found namespaces are stored #[inline] - pub fn resolve<'n, 'ns>( + pub fn resolve<'n>( &self, name: QName<'n>, - buffer: &'ns [u8], use_default: bool, - ) -> (ResolveResult<'ns>, LocalName<'n>) { + ) -> (ResolveResult, LocalName<'n>) { let (local_name, prefix) = name.decompose(); - (self.resolve_prefix(prefix, buffer, use_default), local_name) + (self.resolve_prefix(prefix, use_default), local_name) } /// Finds a [namespace name] for a given qualified **element name**, borrow - /// it from the specified buffer. + /// it from the internal buffer. /// /// Returns `None`, if: /// - name is unqualified /// - prefix not found in the current scope /// - prefix was [unbound] using `xmlns:prefix=""` /// - /// # Lifetimes - /// - /// - `'ns`: lifetime of a namespaces buffer, where all found namespaces are stored - /// /// [namespace name]: https://www.w3.org/TR/xml-names11/#dt-NSName /// [unbound]: https://www.w3.org/TR/xml-names11/#scoping #[inline] - pub fn find<'ns>(&self, element_name: QName, buffer: &'ns [u8]) -> ResolveResult<'ns> { - self.resolve_prefix(element_name.prefix(), buffer, true) + pub fn find(&self, element_name: QName) -> ResolveResult { + self.resolve_prefix(element_name.prefix(), true) } - fn resolve_prefix<'ns>( - &self, - prefix: Option, - buffer: &'ns [u8], - use_default: bool, - ) -> ResolveResult<'ns> { + fn resolve_prefix(&self, prefix: Option, use_default: bool) -> ResolveResult { self.bindings .iter() // Find the last defined binding that corresponds to the given prefix .rev() - .find_map(|n| match (n.prefix(buffer), prefix) { + .find_map(|n| match (n.prefix(&self.buffer), prefix) { // This is default namespace definition and name has no explicit prefix - (None, None) if use_default => Some(n.namespace(buffer)), + (None, None) if use_default => Some(n.namespace(&self.buffer)), (None, None) => Some(ResolveResult::Unbound), // One part has prefix but other is not -> skip @@ -534,7 +526,7 @@ impl NamespaceResolver { // Prefixes the same, entry defines binding reset (corresponds to `xmlns:p=""`) _ if n.value_len == 0 => Some(Self::maybe_unknown(prefix)), // Prefixes the same, returns corresponding namespace - _ => Some(n.namespace(buffer)), + _ => Some(n.namespace(&self.buffer)), }) .unwrap_or_else(|| Self::maybe_unknown(prefix)) } @@ -572,29 +564,25 @@ mod namespaces { let ns = Namespace(b"default"); let mut resolver = NamespaceResolver::default(); - let mut buffer = Vec::new(); - resolver.push( - &BytesStart::from_content(" xmlns='default'", 0), - &mut buffer, - ); - assert_eq!(buffer, b"default"); + resolver.push(&BytesStart::from_content(" xmlns='default'", 0)); + assert_eq!(resolver.buffer, b"default"); // Check that tags without namespaces does not change result - resolver.push(&BytesStart::from_content("", 0), &mut buffer); - assert_eq!(buffer, b"default"); - resolver.pop(&mut buffer); + resolver.push(&BytesStart::from_content("", 0)); + assert_eq!(resolver.buffer, b"default"); + resolver.pop(); - assert_eq!(buffer, b"default"); + assert_eq!(resolver.buffer, b"default"); assert_eq!( - resolver.resolve(name, &buffer, true), + resolver.resolve(name, true), (Bound(ns), LocalName(b"simple")) ); assert_eq!( - resolver.resolve(name, &buffer, false), + resolver.resolve(name, false), (Unbound, LocalName(b"simple")) ); - assert_eq!(resolver.find(name, &buffer), Bound(ns)); + assert_eq!(resolver.find(name), Bound(ns)); } /// Test adding a second level of namespaces, which replaces the previous binding @@ -605,33 +593,32 @@ mod namespaces { let new_ns = Namespace(b"new"); let mut resolver = NamespaceResolver::default(); - let mut buffer = Vec::new(); - resolver.push(&BytesStart::from_content(" xmlns='old'", 0), &mut buffer); - resolver.push(&BytesStart::from_content(" xmlns='new'", 0), &mut buffer); + resolver.push(&BytesStart::from_content(" xmlns='old'", 0)); + resolver.push(&BytesStart::from_content(" xmlns='new'", 0)); - assert_eq!(buffer, b"oldnew"); + assert_eq!(resolver.buffer, b"oldnew"); assert_eq!( - resolver.resolve(name, &buffer, true), + resolver.resolve(name, true), (Bound(new_ns), LocalName(b"simple")) ); assert_eq!( - resolver.resolve(name, &buffer, false), + resolver.resolve(name, false), (Unbound, LocalName(b"simple")) ); - assert_eq!(resolver.find(name, &buffer), Bound(new_ns)); + assert_eq!(resolver.find(name), Bound(new_ns)); - resolver.pop(&mut buffer); - assert_eq!(buffer, b"old"); + resolver.pop(); + assert_eq!(resolver.buffer, b"old"); assert_eq!( - resolver.resolve(name, &buffer, true), + resolver.resolve(name, true), (Bound(old_ns), LocalName(b"simple")) ); assert_eq!( - resolver.resolve(name, &buffer, false), + resolver.resolve(name, false), (Unbound, LocalName(b"simple")) ); - assert_eq!(resolver.find(name, &buffer), Bound(old_ns)); + assert_eq!(resolver.find(name), Bound(old_ns)); } /// Test adding a second level of namespaces, which reset the previous binding @@ -644,33 +631,32 @@ mod namespaces { let old_ns = Namespace(b"old"); let mut resolver = NamespaceResolver::default(); - let mut buffer = Vec::new(); - resolver.push(&BytesStart::from_content(" xmlns='old'", 0), &mut buffer); - resolver.push(&BytesStart::from_content(" xmlns=''", 0), &mut buffer); + resolver.push(&BytesStart::from_content(" xmlns='old'", 0)); + resolver.push(&BytesStart::from_content(" xmlns=''", 0)); - assert_eq!(buffer, b"old"); + assert_eq!(resolver.buffer, b"old"); assert_eq!( - resolver.resolve(name, &buffer, true), + resolver.resolve(name, true), (Unbound, LocalName(b"simple")) ); assert_eq!( - resolver.resolve(name, &buffer, false), + resolver.resolve(name, false), (Unbound, LocalName(b"simple")) ); - assert_eq!(resolver.find(name, &buffer), Unbound); + assert_eq!(resolver.find(name), Unbound); - resolver.pop(&mut buffer); - assert_eq!(buffer, b"old"); + resolver.pop(); + assert_eq!(resolver.buffer, b"old"); assert_eq!( - resolver.resolve(name, &buffer, true), + resolver.resolve(name, true), (Bound(old_ns), LocalName(b"simple")) ); assert_eq!( - resolver.resolve(name, &buffer, false), + resolver.resolve(name, false), (Unbound, LocalName(b"simple")) ); - assert_eq!(resolver.find(name, &buffer), Bound(old_ns)); + assert_eq!(resolver.find(name), Bound(old_ns)); } } @@ -685,29 +671,25 @@ mod namespaces { let ns = Namespace(b"default"); let mut resolver = NamespaceResolver::default(); - let mut buffer = Vec::new(); - resolver.push( - &BytesStart::from_content(" xmlns:p='default'", 0), - &mut buffer, - ); - assert_eq!(buffer, b"pdefault"); + resolver.push(&BytesStart::from_content(" xmlns:p='default'", 0)); + assert_eq!(resolver.buffer, b"pdefault"); // Check that tags without namespaces does not change result - resolver.push(&BytesStart::from_content("", 0), &mut buffer); - assert_eq!(buffer, b"pdefault"); - resolver.pop(&mut buffer); + resolver.push(&BytesStart::from_content("", 0)); + assert_eq!(resolver.buffer, b"pdefault"); + resolver.pop(); - assert_eq!(buffer, b"pdefault"); + assert_eq!(resolver.buffer, b"pdefault"); assert_eq!( - resolver.resolve(name, &buffer, true), + resolver.resolve(name, true), (Bound(ns), LocalName(b"with-declared-prefix")) ); assert_eq!( - resolver.resolve(name, &buffer, false), + resolver.resolve(name, false), (Bound(ns), LocalName(b"with-declared-prefix")) ); - assert_eq!(resolver.find(name, &buffer), Bound(ns)); + assert_eq!(resolver.find(name), Bound(ns)); } /// Test adding a second level of namespaces, which replaces the previous binding @@ -718,33 +700,32 @@ mod namespaces { let new_ns = Namespace(b"new"); let mut resolver = NamespaceResolver::default(); - let mut buffer = Vec::new(); - resolver.push(&BytesStart::from_content(" xmlns:p='old'", 0), &mut buffer); - resolver.push(&BytesStart::from_content(" xmlns:p='new'", 0), &mut buffer); + resolver.push(&BytesStart::from_content(" xmlns:p='old'", 0)); + resolver.push(&BytesStart::from_content(" xmlns:p='new'", 0)); - assert_eq!(buffer, b"poldpnew"); + assert_eq!(resolver.buffer, b"poldpnew"); assert_eq!( - resolver.resolve(name, &buffer, true), + resolver.resolve(name, true), (Bound(new_ns), LocalName(b"with-declared-prefix")) ); assert_eq!( - resolver.resolve(name, &buffer, false), + resolver.resolve(name, false), (Bound(new_ns), LocalName(b"with-declared-prefix")) ); - assert_eq!(resolver.find(name, &buffer), Bound(new_ns)); + assert_eq!(resolver.find(name), Bound(new_ns)); - resolver.pop(&mut buffer); - assert_eq!(buffer, b"pold"); + resolver.pop(); + assert_eq!(resolver.buffer, b"pold"); assert_eq!( - resolver.resolve(name, &buffer, true), + resolver.resolve(name, true), (Bound(old_ns), LocalName(b"with-declared-prefix")) ); assert_eq!( - resolver.resolve(name, &buffer, false), + resolver.resolve(name, false), (Bound(old_ns), LocalName(b"with-declared-prefix")) ); - assert_eq!(resolver.find(name, &buffer), Bound(old_ns)); + assert_eq!(resolver.find(name), Bound(old_ns)); } /// Test adding a second level of namespaces, which reset the previous binding @@ -757,33 +738,32 @@ mod namespaces { let old_ns = Namespace(b"old"); let mut resolver = NamespaceResolver::default(); - let mut buffer = Vec::new(); - resolver.push(&BytesStart::from_content(" xmlns:p='old'", 0), &mut buffer); - resolver.push(&BytesStart::from_content(" xmlns:p=''", 0), &mut buffer); + resolver.push(&BytesStart::from_content(" xmlns:p='old'", 0)); + resolver.push(&BytesStart::from_content(" xmlns:p=''", 0)); - assert_eq!(buffer, b"poldp"); + assert_eq!(resolver.buffer, b"poldp"); assert_eq!( - resolver.resolve(name, &buffer, true), + resolver.resolve(name, true), (Unknown(b"p".to_vec()), LocalName(b"with-declared-prefix")) ); assert_eq!( - resolver.resolve(name, &buffer, false), + resolver.resolve(name, false), (Unknown(b"p".to_vec()), LocalName(b"with-declared-prefix")) ); - assert_eq!(resolver.find(name, &buffer), Unknown(b"p".to_vec())); + assert_eq!(resolver.find(name), Unknown(b"p".to_vec())); - resolver.pop(&mut buffer); - assert_eq!(buffer, b"pold"); + resolver.pop(); + assert_eq!(resolver.buffer, b"pold"); assert_eq!( - resolver.resolve(name, &buffer, true), + resolver.resolve(name, true), (Bound(old_ns), LocalName(b"with-declared-prefix")) ); assert_eq!( - resolver.resolve(name, &buffer, false), + resolver.resolve(name, false), (Bound(old_ns), LocalName(b"with-declared-prefix")) ); - assert_eq!(resolver.find(name, &buffer), Bound(old_ns)); + assert_eq!(resolver.find(name), Bound(old_ns)); } } @@ -792,18 +772,17 @@ mod namespaces { let name = QName(b"unknown:prefix"); let resolver = NamespaceResolver::default(); - let buffer = Vec::new(); - assert_eq!(buffer, b""); + assert_eq!(resolver.buffer, b""); assert_eq!( - resolver.resolve(name, &buffer, true), + resolver.resolve(name, true), (Unknown(b"unknown".to_vec()), LocalName(b"prefix")) ); assert_eq!( - resolver.resolve(name, &buffer, false), + resolver.resolve(name, false), (Unknown(b"unknown".to_vec()), LocalName(b"prefix")) ); - assert_eq!(resolver.find(name, &buffer), Unknown(b"unknown".to_vec())); + assert_eq!(resolver.find(name), Unknown(b"unknown".to_vec())); } /// Checks how the QName is decomposed to a prefix and a local name diff --git a/src/reader/ns_reader.rs b/src/reader/ns_reader.rs index 09457f28..35502be3 100644 --- a/src/reader/ns_reader.rs +++ b/src/reader/ns_reader.rs @@ -21,9 +21,6 @@ use crate::reader::{Reader, Span, XmlSource}; pub struct NsReader { /// An XML reader pub(super) reader: Reader, - /// Buffer that contains names of namespace prefixes (the part between `xmlns:` - /// and an `=`) and namespace values. - buffer: Vec, /// A buffer to manage namespaces ns_resolver: NamespaceResolver, /// We cannot pop data from the namespace stack until returned `Empty` or `End` @@ -49,7 +46,6 @@ impl NsReader { fn new(reader: Reader) -> Self { Self { reader, - buffer: Vec::new(), ns_resolver: NamespaceResolver::default(), pending_pop: false, } @@ -66,7 +62,7 @@ impl NsReader { pub(super) fn pop(&mut self) { if self.pending_pop { - self.ns_resolver.pop(&mut self.buffer); + self.ns_resolver.pop(); self.pending_pop = false; } } @@ -74,11 +70,11 @@ impl NsReader { pub(super) fn process_event<'i>(&mut self, event: Result>) -> Result> { match event { Ok(Event::Start(e)) => { - self.ns_resolver.push(&e, &mut self.buffer); + self.ns_resolver.push(&e); Ok(Event::Start(e)) } Ok(Event::Empty(e)) => { - self.ns_resolver.push(&e, &mut self.buffer); + self.ns_resolver.push(&e); // notify next `read_event_impl()` invocation that it needs to pop this // namespace scope self.pending_pop = true; @@ -99,19 +95,9 @@ impl NsReader { event: Result>, ) -> Result<(ResolveResult, Event<'i>)> { match event { - Ok(Event::Start(e)) => Ok(( - self.ns_resolver.find(e.name(), &self.buffer), - Event::Start(e), - )), - Ok(Event::Empty(e)) => Ok(( - self.ns_resolver.find(e.name(), &self.buffer), - Event::Empty(e), - )), - Ok(Event::End(e)) => Ok(( - // Comment that prevent cargo rmt - self.ns_resolver.find(e.name(), &self.buffer), - Event::End(e), - )), + Ok(Event::Start(e)) => Ok((self.ns_resolver.find(e.name()), Event::Start(e))), + Ok(Event::Empty(e)) => Ok((self.ns_resolver.find(e.name()), Event::Empty(e))), + Ok(Event::End(e)) => Ok((self.ns_resolver.find(e.name()), Event::End(e))), Ok(e) => Ok((ResolveResult::Unbound, e)), Err(e) => Err(e), } @@ -169,7 +155,7 @@ impl NsReader { /// [`resolve_element()`]: Self::resolve_element() #[inline] pub fn resolve<'n>(&self, name: QName<'n>, attribute: bool) -> (ResolveResult, LocalName<'n>) { - self.ns_resolver.resolve(name, &self.buffer, !attribute) + self.ns_resolver.resolve(name, !attribute) } /// Resolves a potentially qualified **element name** into _(namespace name, local name)_. @@ -225,7 +211,7 @@ impl NsReader { /// [`read_resolved_event()`]: Self::read_resolved_event #[inline] pub fn resolve_element<'n>(&self, name: QName<'n>) -> (ResolveResult, LocalName<'n>) { - self.ns_resolver.resolve(name, &self.buffer, true) + self.ns_resolver.resolve(name, true) } /// Resolves a potentially qualified **attribute name** into _(namespace name, local name)_. @@ -296,7 +282,7 @@ impl NsReader { /// [`Unknown`]: ResolveResult::Unknown #[inline] pub fn resolve_attribute<'n>(&self, name: QName<'n>) -> (ResolveResult, LocalName<'n>) { - self.ns_resolver.resolve(name, &self.buffer, false) + self.ns_resolver.resolve(name, false) } }