Skip to content

Commit

Permalink
Merge pull request #438 from dralley/split-readers
Browse files Browse the repository at this point in the history
Add example for buffered access when reading from a file
  • Loading branch information
Mingun committed Jul 24, 2022
2 parents d8ae1c3 + 33b6e6d commit c590fdf
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 0 deletions.
34 changes: 34 additions & 0 deletions examples/read_buffered.rs
@@ -0,0 +1,34 @@
// This example demonstrates how a reader (for example when reading from a file)
// can be buffered. In that case, data read from the file is written to a supplied
// buffer and returned XML events borrow from that buffer.
// That way, allocations can be kept to a minimum.

fn main() -> Result<(), quick_xml::Error> {
use quick_xml::events::Event;
use quick_xml::Reader;

let mut reader = Reader::from_file("tests/documents/document.xml")?;
reader.trim_text(true);

let mut buf = Vec::new();

let mut count = 0;

loop {
match reader.read_event_into(&mut buf) {
Ok(Event::Start(ref e)) => {
let name = e.name();
let name = reader.decoder().decode(name.as_ref())?;
println!("read start event {:?}", name.as_ref());
count += 1;
}
Ok(Event::Eof) => break, // exits the loop when reaching end of file
Err(e) => panic!("Error at position {}: {:?}", reader.buffer_position(), e),
_ => (), // There are several other `Event`s we do not consider here
}
}

println!("read {} start events in total", count);

Ok(())
}
6 changes: 6 additions & 0 deletions src/reader/buffered_reader.rs
Expand Up @@ -238,6 +238,9 @@ impl<'b, R: BufRead> XmlSource<'b, &'b mut Vec<u8>> for R {
buf: &'b mut Vec<u8>,
position: &mut usize,
) -> Result<Option<&'b [u8]>> {
// search byte must be within the ascii range
debug_assert!(byte.is_ascii());

let mut read = 0;
let mut done = false;
let start = buf.len();
Expand Down Expand Up @@ -397,6 +400,9 @@ impl<'b, R: BufRead> XmlSource<'b, &'b mut Vec<u8>> for R {
/// Consume and discard one character if it matches the given byte. Return
/// true if it matched.
fn skip_one(&mut self, byte: u8, position: &mut usize) -> Result<bool> {
// search byte must be within the ascii range
debug_assert!(byte.is_ascii());

match self.peek_one()? {
Some(b) if b == byte => {
*position += 1;
Expand Down
4 changes: 4 additions & 0 deletions src/reader/slice_reader.rs
Expand Up @@ -147,6 +147,8 @@ impl<'a> XmlSource<'a, ()> for &'a [u8] {
_buf: (),
position: &mut usize,
) -> Result<Option<&'a [u8]>> {
// search byte must be within the ascii range
debug_assert!(byte.is_ascii());
if self.is_empty() {
return Ok(None);
}
Expand Down Expand Up @@ -217,6 +219,8 @@ impl<'a> XmlSource<'a, ()> for &'a [u8] {
}

fn skip_one(&mut self, byte: u8, position: &mut usize) -> Result<bool> {
// search byte must be within the ascii range
debug_assert!(byte.is_ascii());
if self.first() == Some(&byte) {
*self = &self[1..];
*position += 1;
Expand Down

0 comments on commit c590fdf

Please sign in to comment.