summaryrefslogtreecommitdiffstats
path: root/buffered-reader
diff options
context:
space:
mode:
authorNeal H. Walfield <neal@pep.foundation>2018-07-24 00:16:25 +0200
committerNeal H. Walfield <neal@pep.foundation>2018-07-24 16:34:33 +0200
commit66300af90efc98b37739054302a7d653fbb8f08a (patch)
tree9c50efa3446b95a7442632ccbb5d0906b189e5ce /buffered-reader
parentaf1857c2ca08c5f2d8cb81a663b12fd82736bc6a (diff)
buffered-reader: Add a function to read to a particular byte
- This is useful for reading a line at a time.
Diffstat (limited to 'buffered-reader')
-rw-r--r--buffered-reader/src/lib.rs36
1 files changed, 36 insertions, 0 deletions
diff --git a/buffered-reader/src/lib.rs b/buffered-reader/src/lib.rs
index cf50ff84..11b93ce0 100644
--- a/buffered-reader/src/lib.rs
+++ b/buffered-reader/src/lib.rs
@@ -152,6 +152,37 @@ pub trait BufferedReader<C> : io::Read + fmt::Debug {
+ ((input[2] as u32) << 8) + (input[3] as u32));
}
+ /// Read until either `terminal` is encountered or EOF.
+ ///
+ /// Returns either a `&[u8]` terminating in `terminal` or the rest
+ /// of the data, if EOF was encountered.
+ ///
+ /// Note: this function does *not* consume the data.
+ fn read_to(&mut self, terminal: u8) -> Result<&[u8], std::io::Error> {
+ let mut n = 128;
+ let len;
+
+ loop {
+ let data = self.data(n)?;
+
+ if let Some(newline)
+ = data.iter().position(|c| *c == terminal)
+ {
+ len = newline + 1;
+ break;
+ } else if data.len() < n {
+ // EOF.
+ len = data.len();
+ break;
+ } else {
+ // Read more data.
+ n = cmp::max(2 * n, data.len() + 1024);
+ }
+ }
+
+ Ok(&self.buffer()[..len])
+ }
+
/// Reads and consumes `amount` bytes, and returns them in a
/// caller-owned buffer. Implementations may optimize this to
/// avoid a copy.
@@ -297,6 +328,11 @@ impl <'a, C> BufferedReader<C> for Box<BufferedReader<C> + 'a> {
return self.as_mut().read_be_u32();
}
+ fn read_to(&mut self, terminal: u8) -> Result<&[u8], std::io::Error>
+ {
+ return self.as_mut().read_to(terminal);
+ }
+
fn steal(&mut self, amount: usize) -> Result<Vec<u8>, std::io::Error> {
return self.as_mut().steal(amount);
}