use crate::{
CHARDATA_CHUNK_LENGTH,
error::XMLError,
sax::{InputSource, ParserSpec, SAXHandler, XMLReader, error::fatal_error},
};
impl<'a, Spec: ParserSpec<Reader = InputSource<'a>>, H: SAXHandler + ?Sized> XMLReader<Spec, H> {
pub(crate) fn parse_comment(&mut self) -> Result<(), XMLError> {
self.grow()?;
if !self.source.content_bytes().starts_with(b"<!--") {
fatal_error!(
self,
ParserInvalidComment,
"Comment does not start with '<!--'."
);
return Err(XMLError::ParserInvalidComment);
}
self.source.advance(4);
self.locator.update_column(|c| c + 4);
if let Some(Some((_, validator))) = self.validation_stack.last_mut() {
validator.push_misc();
}
self.grow()?;
self.text_buffer.clear();
while !self.source.content_bytes().starts_with(b"-->") {
let next = self.source.next_char()?;
match next {
Some('-') => {
if self.source.peek_char()? == Some('-') {
fatal_error!(
self,
ParserInvalidComment,
"Comment must not contain '--' except for delimiters."
);
}
self.text_buffer.push('-');
}
Some('\r') => {
if self.source.peek_char()? != Some('\n') {
self.locator.update_line(|l| l + 1);
self.locator.set_column(1);
self.text_buffer.push('\n');
}
}
Some('\n') => {
self.locator.update_line(|l| l + 1);
self.locator.set_column(1);
self.text_buffer.push('\n');
}
Some(c) if self.is_char(c) => {
self.locator.update_column(|c| c + 1);
self.text_buffer.push(c)
}
Some(c) => {
self.locator.update_column(|c| c + 1);
fatal_error!(
self,
ParserInvalidCharacter,
"A character '0x{:X}' is not allowed in XML documents.",
c as u32
);
}
None => {
return Err(XMLError::ParserUnexpectedEOF);
}
}
if self.text_buffer.len() >= CHARDATA_CHUNK_LENGTH {
if !self.fatal_error_occurred {
self.handler.comment(&self.text_buffer);
}
self.text_buffer.clear();
}
if self.source.content_bytes().len() < 3 {
self.grow()?;
}
}
if !self.text_buffer.is_empty() && !self.fatal_error_occurred {
self.handler.comment(&self.text_buffer);
}
if !self.source.content_bytes().starts_with(b"-->") {
fatal_error!(
self,
ParserInvalidComment,
"Comment does not end with '-->'."
);
return Err(XMLError::ParserInvalidComment);
}
self.source.advance(3);
self.locator.update_column(|c| c + 3);
Ok(())
}
}