Browse Source

Add read_to_end function

pull/10/head
Fenrir 8 years ago
parent
commit
1a99cf387f
  1. 34
      src/services/fs.rs

34
src/services/fs.rs

@ -1,5 +1,6 @@ @@ -1,5 +1,6 @@
use core::marker::PhantomData;
use core::ptr;
use core::slice;
use collections::Vec;
use path::Path;
@ -151,6 +152,12 @@ impl File { @@ -151,6 +152,12 @@ impl File {
}
}
pub fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize, i32> {
unsafe {
read_to_end_uninitialized(self, buf)
}
}
pub fn write(&mut self, buf: &[u8]) -> Result<usize, i32> {
unsafe {
let mut n_written = 0;
@ -249,6 +256,33 @@ pub fn remove_file<P: AsRef<Path>>(arch: &Archive, path: P) -> Result<(), i32> { @@ -249,6 +256,33 @@ pub fn remove_file<P: AsRef<Path>>(arch: &Archive, path: P) -> Result<(), i32> {
}
}
// Adapted from sys/common/io.rs in libstd
unsafe fn read_to_end_uninitialized(f: &mut File, buf: &mut Vec<u8>) -> Result<usize, i32> {
let start_len = buf.len();
buf.reserve(16);
// Always try to read into the empty space of the vector (from the length to the capacity).
// If the vector ever fills up then we reserve an extra byte which should trigger the normal
// reallocation routines for the vector, which will likely double the size.
//
// This function is similar to the read_to_end function in std::io, but the logic about
// reservations and slicing is different enough that this is duplicated here.
loop {
if buf.len() == buf.capacity() {
buf.reserve(1);
}
let buf_slice = slice::from_raw_parts_mut(buf.as_mut_ptr().offset(buf.len() as isize),
buf.capacity() - buf.len());
match f.read(buf_slice) {
Ok(0) => { return Ok(buf.len() - start_len); }
Ok(n) => { let len = buf.len() + n; buf.set_len(len); },
Err(e) => { return Err(e); }
}
}
}
impl Drop for Fs {
fn drop(&mut self) {
unsafe {

Loading…
Cancel
Save