Skip to content

Commit

Permalink
Move name length computation to a helper function
Browse files Browse the repository at this point in the history
  • Loading branch information
Mingun committed Jun 14, 2024
1 parent 8d38e4c commit 0f9444a
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 12 deletions.
10 changes: 10 additions & 0 deletions src/reader/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -996,6 +996,16 @@ pub(crate) const fn is_whitespace(b: u8) -> bool {
matches!(b, b' ' | b'\r' | b'\n' | b'\t')
}

/// Calculates name from an element-like content. Name is the first word in `content`,
/// where word boundaries is XML space characters.
#[inline]
pub(crate) fn name_len(content: &[u8]) -> usize {
content
.iter()
.position(|&b| is_whitespace(b))
.unwrap_or(content.len())
}

////////////////////////////////////////////////////////////////////////////////////////////////////

#[cfg(test)]
Expand Down
20 changes: 8 additions & 12 deletions src/reader/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::errors::{Error, IllFormedError, Result, SyntaxError};
use crate::events::{BytesCData, BytesDecl, BytesEnd, BytesStart, BytesText, Event};
#[cfg(feature = "encoding")]
use crate::reader::EncodingRef;
use crate::reader::{is_whitespace, BangType, Config, ParseState};
use crate::reader::{is_whitespace, name_len, BangType, Config, ParseState};

/// A struct that holds a current reader state and a parser configuration.
/// It is independent on a way of reading data: the reader feed data into it and
Expand Down Expand Up @@ -258,31 +258,27 @@ impl ReaderState {
/// # Parameters
/// - `content`: Content of a tag between `<` and `>`
pub fn emit_start<'b>(&mut self, content: &'b [u8]) -> Result<Event<'b>> {
let len = content.len();
let name_end = content
.iter()
.position(|&b| is_whitespace(b))
.unwrap_or(len);
if let Some(&b'/') = content.last() {
if let Some(content) = content.strip_suffix(b"/") {
// This is self-closed tag `<something/>`
let name_len = if name_end < len { name_end } else { len - 1 };
let event = BytesStart::wrap(&content[..len - 1], name_len);
let event = BytesStart::wrap(content, name_len(content));

if self.config.expand_empty_elements {
self.state = ParseState::Empty;
self.opened_starts.push(self.opened_buffer.len());
self.opened_buffer.extend(&content[..name_len]);
self.opened_buffer.extend(event.name().as_ref());
Ok(Event::Start(event))
} else {
Ok(Event::Empty(event))
}
} else {
let event = BytesStart::wrap(content, name_len(content));

// #514: Always store names event when .check_end_names == false,
// because checks can be temporary disabled and when they would be
// enabled, we should have that information
self.opened_starts.push(self.opened_buffer.len());
self.opened_buffer.extend(&content[..name_end]);
Ok(Event::Start(BytesStart::wrap(content, name_end)))
self.opened_buffer.extend(event.name().as_ref());
Ok(Event::Start(event))
}
}

Expand Down

0 comments on commit 0f9444a

Please sign in to comment.