mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-31 13:07:46 +00:00
Get rid of unsafe indexing
Unsafe indexing is replaced by ImmutableEqVector::position_elem() and a few branches have been eliminated. The performance is about the same as for unsafe indexing.
This commit is contained in:
parent
7d7b9dde43
commit
2a238e3c0f
1 changed files with 44 additions and 39 deletions
|
@ -65,24 +65,23 @@ impl<R: Reader> BufReader<R> {
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match self.maybe_fill_buf() {
|
match self.maybe_fill_buf() {
|
||||||
Err(IoError { kind: std::io::EndOfFile, .. }) => (),
|
Ok(0) | Err(IoError { kind: std::io::EndOfFile, .. })
|
||||||
|
if self.start == self.end => return bytes_consumed,
|
||||||
Err(err) => fail!("read error: {}", err.desc),
|
Err(err) => fail!("read error: {}", err.desc),
|
||||||
_ => ()
|
_ => ()
|
||||||
}
|
}
|
||||||
|
|
||||||
let buffer_used = self.end - self.start;
|
let filled_buf = self.buffer.slice(self.start, self.end);
|
||||||
|
|
||||||
if buffer_used == 0 { return bytes_consumed; }
|
match filled_buf.position_elem(&b'\n') {
|
||||||
|
Some(idx) => {
|
||||||
for idx in range(self.start, self.end) {
|
self.start += idx + 1;
|
||||||
// the indices are always correct, use unsafe for speed
|
|
||||||
if unsafe { *self.buffer.unsafe_ref(idx) } == b'\n' {
|
|
||||||
self.start = idx + 1;
|
|
||||||
return bytes_consumed + idx + 1;
|
return bytes_consumed + idx + 1;
|
||||||
}
|
}
|
||||||
|
_ => ()
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes_consumed += buffer_used;
|
bytes_consumed += filled_buf.len();
|
||||||
|
|
||||||
self.start = 0;
|
self.start = 0;
|
||||||
self.end = 0;
|
self.end = 0;
|
||||||
|
@ -98,41 +97,47 @@ impl<R: Reader> Bytes::Select for BufReader<R> {
|
||||||
_ => ()
|
_ => ()
|
||||||
}
|
}
|
||||||
|
|
||||||
let buffer_used = self.end - self.start;
|
let newline_idx = match self.end - self.start {
|
||||||
|
0 => return Bytes::EndOfFile,
|
||||||
|
buf_used if bytes < buf_used => {
|
||||||
|
// because the output delimiter should only be placed between
|
||||||
|
// segments check if the byte after bytes is a newline
|
||||||
|
let buf_slice = self.buffer.slice(self.start,
|
||||||
|
self.start + bytes + 1);
|
||||||
|
|
||||||
if buffer_used == 0 { return Bytes::EndOfFile; }
|
match buf_slice.position_elem(&b'\n') {
|
||||||
|
Some(idx) => idx,
|
||||||
let (complete, max_segment_len) = {
|
None => {
|
||||||
if bytes < buffer_used {
|
|
||||||
(true, bytes + 1)
|
|
||||||
} else {
|
|
||||||
(false, buffer_used)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
for idx in range(self.start, self.start + max_segment_len) {
|
|
||||||
// the indices are always correct, use unsafe for speed
|
|
||||||
if unsafe { *self.buffer.unsafe_ref(idx) } == b'\n' {
|
|
||||||
let segment = self.buffer.slice(self.start, idx + 1);
|
|
||||||
|
|
||||||
self.start = idx + 1;
|
|
||||||
|
|
||||||
return Bytes::NewlineFound(segment);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if complete {
|
|
||||||
let segment = self.buffer.slice(self.start,
|
let segment = self.buffer.slice(self.start,
|
||||||
self.start + bytes);
|
self.start + bytes);
|
||||||
|
|
||||||
self.start += bytes;
|
self.start += bytes;
|
||||||
Bytes::Complete(segment)
|
|
||||||
} else {
|
return Bytes::Complete(segment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
let buf_filled = self.buffer.slice(self.start, self.end);
|
||||||
|
|
||||||
|
match buf_filled.position_elem(&b'\n') {
|
||||||
|
Some(idx) => idx,
|
||||||
|
None => {
|
||||||
let segment = self.buffer.slice(self.start, self.end);
|
let segment = self.buffer.slice(self.start, self.end);
|
||||||
|
|
||||||
self.start = 0;
|
self.start = 0;
|
||||||
self.end = 0;
|
self.end = 0;
|
||||||
Bytes::Partial(segment)
|
|
||||||
|
return Bytes::Partial(segment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let new_start = self.start + newline_idx + 1;
|
||||||
|
let segment = self.buffer.slice(self.start, new_start);
|
||||||
|
|
||||||
|
self.start = new_start;
|
||||||
|
Bytes::NewlineFound(segment)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue