Rewrite IO to use core-io library
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
use platform::types::*;
|
||||
|
||||
pub const EOF: c_int = -1;
|
||||
pub const BUFSIZ: size_t = 1024;
|
||||
|
||||
pub const UNGET: size_t = 8;
|
||||
|
||||
+22
-33
@@ -1,12 +1,28 @@
|
||||
use super::{constants, BUFSIZ, FILE, UNGET};
|
||||
use super::{constants, Buffer, BUFSIZ, FILE, UNGET};
|
||||
use core::cell::UnsafeCell;
|
||||
use core::ptr;
|
||||
use core::sync::atomic::AtomicBool;
|
||||
|
||||
use fs::File;
|
||||
use io::LineWriter;
|
||||
use platform::types::*;
|
||||
|
||||
pub struct GlobalFile(UnsafeCell<FILE>);
|
||||
impl GlobalFile {
|
||||
const fn new(file: FILE) -> Self {
|
||||
GlobalFile(UnsafeCell::new(file))
|
||||
fn new(file: c_int, flags: c_int) -> Self {
|
||||
let file = File::new(file);
|
||||
let writer = LineWriter::new(unsafe { file.get_ref() });
|
||||
GlobalFile(UnsafeCell::new(FILE {
|
||||
lock: AtomicBool::new(false),
|
||||
|
||||
file,
|
||||
flags: constants::F_PERM | flags,
|
||||
read_buf: Buffer::Owned(vec![0; BUFSIZ]),
|
||||
read_pos: 0,
|
||||
read_size: 0,
|
||||
unget: None,
|
||||
writer
|
||||
}))
|
||||
}
|
||||
pub fn get(&self) -> *mut FILE {
|
||||
self.0.get()
|
||||
@@ -17,40 +33,13 @@ unsafe impl Sync for GlobalFile {}
|
||||
|
||||
lazy_static! {
|
||||
#[allow(non_upper_case_globals)]
|
||||
pub static ref default_stdin: GlobalFile = GlobalFile::new(FILE {
|
||||
flags: constants::F_PERM | constants::F_NOWR,
|
||||
read: None,
|
||||
write: None,
|
||||
fd: 0,
|
||||
buf: vec![0u8;(BUFSIZ + UNGET) as usize],
|
||||
buf_char: -1,
|
||||
unget: UNGET,
|
||||
lock: AtomicBool::new(false),
|
||||
});
|
||||
pub static ref default_stdin: GlobalFile = GlobalFile::new(0, constants::F_NOWR);
|
||||
|
||||
#[allow(non_upper_case_globals)]
|
||||
pub static ref default_stdout: GlobalFile = GlobalFile::new(FILE {
|
||||
flags: constants::F_PERM | constants::F_NORD,
|
||||
read: None,
|
||||
write: None,
|
||||
fd: 1,
|
||||
buf: vec![0u8;(BUFSIZ + UNGET) as usize],
|
||||
buf_char: b'\n' as i8,
|
||||
unget: 0,
|
||||
lock: AtomicBool::new(false),
|
||||
});
|
||||
pub static ref default_stdout: GlobalFile = GlobalFile::new(1, constants::F_NORD);
|
||||
|
||||
#[allow(non_upper_case_globals)]
|
||||
pub static ref default_stderr: GlobalFile = GlobalFile::new(FILE {
|
||||
flags: constants::F_PERM | constants::F_NORD,
|
||||
read: None,
|
||||
write: None,
|
||||
fd: 2,
|
||||
buf: vec![0u8;(BUFSIZ + UNGET) as usize],
|
||||
buf_char: -1,
|
||||
unget: 0,
|
||||
lock: AtomicBool::new(false),
|
||||
});
|
||||
pub static ref default_stderr: GlobalFile = GlobalFile::new(2, constants::F_NORD);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
||||
+19
-102
@@ -1,14 +1,17 @@
|
||||
use alloc::boxed::Box;
|
||||
use core::sync::atomic::AtomicBool;
|
||||
use core::{mem, ptr};
|
||||
|
||||
use fs::File;
|
||||
use header::errno;
|
||||
use header::fcntl::*;
|
||||
use header::string::strchr;
|
||||
use platform;
|
||||
use io::LineWriter;
|
||||
use platform::types::*;
|
||||
use platform;
|
||||
|
||||
use super::constants::*;
|
||||
use super::{BUFSIZ, FILE, UNGET};
|
||||
use super::{Buffer, FILE};
|
||||
|
||||
/// Parse mode flags as a string and output a mode flags integer
|
||||
pub unsafe fn parse_mode_flags(mode_str: *const c_char) -> i32 {
|
||||
@@ -61,104 +64,18 @@ pub unsafe fn _fdopen(fd: c_int, mode: *const c_char) -> Option<*mut FILE> {
|
||||
flags |= F_APP;
|
||||
}
|
||||
|
||||
let f = platform::alloc(mem::size_of::<FILE>()) as *mut FILE;
|
||||
// Allocate the file
|
||||
if f.is_null() {
|
||||
None
|
||||
} else {
|
||||
ptr::write(
|
||||
f,
|
||||
FILE {
|
||||
flags: flags,
|
||||
read: None,
|
||||
write: None,
|
||||
fd: fd,
|
||||
buf: vec![0u8; BUFSIZ + UNGET],
|
||||
buf_char: -1,
|
||||
unget: UNGET,
|
||||
lock: AtomicBool::new(false),
|
||||
},
|
||||
);
|
||||
Some(f)
|
||||
}
|
||||
}
|
||||
|
||||
/// Write buffer `buf` of length `l` into `stream`
|
||||
pub fn fwritex(buf: *const u8, l: size_t, stream: &mut FILE) -> size_t {
|
||||
use core::ptr::copy_nonoverlapping;
|
||||
use core::slice;
|
||||
|
||||
let buf: &'static [u8] = unsafe { slice::from_raw_parts(buf, l) };
|
||||
let mut l = l;
|
||||
let mut advance = 0;
|
||||
|
||||
if stream.write.is_none() && !stream.can_write() {
|
||||
// We can't write to this stream
|
||||
return 0;
|
||||
}
|
||||
if let Some((wbase, mut wpos, wend)) = stream.write {
|
||||
if l > wend - wpos {
|
||||
// We can't fit all of buf in the buffer
|
||||
return stream.write(buf);
|
||||
}
|
||||
|
||||
let i = if stream.buf_char >= 0 {
|
||||
let mut i = l;
|
||||
while i > 0 && buf[i - 1] != b'\n' {
|
||||
i -= 1;
|
||||
}
|
||||
if i > 0 {
|
||||
let n = stream.write(buf);
|
||||
match stream.write {
|
||||
Some((_, new_wpos, _)) => wpos = new_wpos,
|
||||
None => unreachable!("stream.write should never be None after a write call")
|
||||
}
|
||||
|
||||
if n < i {
|
||||
return n;
|
||||
}
|
||||
advance += i;
|
||||
l -= i;
|
||||
}
|
||||
i
|
||||
} else {
|
||||
0
|
||||
};
|
||||
|
||||
unsafe {
|
||||
copy_nonoverlapping(
|
||||
&buf[advance..] as *const _ as *const u8,
|
||||
&mut stream.buf[wpos..] as *mut _ as *mut u8,
|
||||
l,
|
||||
);
|
||||
}
|
||||
stream.write = Some((wbase, wpos + l, wend));
|
||||
l + i
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
/// Flush `stream` without locking it.
|
||||
pub fn fflush_unlocked(stream: &mut FILE) -> c_int {
|
||||
if let Some((wbase, wpos, _)) = stream.write {
|
||||
if wpos > wbase {
|
||||
stream.write(&[]);
|
||||
/*
|
||||
if stream.wpos.is_null() {
|
||||
return -1;
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
if let Some((rpos, rend)) = stream.read {
|
||||
if rpos < rend {
|
||||
stream.seek(rpos as i64 - rend as i64, SEEK_CUR);
|
||||
}
|
||||
}
|
||||
|
||||
stream.write = None;
|
||||
stream.read = None;
|
||||
0
|
||||
let file = File::new(fd);
|
||||
let writer = LineWriter::new(file.get_ref());
|
||||
|
||||
Some(Box::into_raw(Box::new(FILE {
|
||||
lock: AtomicBool::new(false),
|
||||
|
||||
file,
|
||||
flags,
|
||||
read_buf: Buffer::Owned(vec![0; BUFSIZ as usize]),
|
||||
read_pos: 0,
|
||||
read_size: 0,
|
||||
unget: None,
|
||||
writer
|
||||
})))
|
||||
}
|
||||
|
||||
@@ -1,31 +1,31 @@
|
||||
use super::{constants, FILE};
|
||||
use platform::types::*;
|
||||
|
||||
pub fn ftello(stream: &mut FILE) -> off_t {
|
||||
let pos = stream.seek(
|
||||
0,
|
||||
if let Some((wbase, wpos, _)) = stream.write {
|
||||
if (stream.flags & constants::F_APP > 0) && wpos > wbase {
|
||||
constants::SEEK_END
|
||||
} else {
|
||||
constants::SEEK_CUR
|
||||
}
|
||||
} else {
|
||||
constants::SEEK_CUR
|
||||
},
|
||||
);
|
||||
if pos < 0 {
|
||||
return pos;
|
||||
}
|
||||
let rdiff = if let Some((rpos, rend)) = stream.read {
|
||||
rend - rpos
|
||||
} else {
|
||||
0
|
||||
};
|
||||
let wdiff = if let Some((wbase, wpos, _)) = stream.write {
|
||||
wpos - wbase
|
||||
} else {
|
||||
0
|
||||
};
|
||||
pos - rdiff as i64 + wdiff as i64
|
||||
}
|
||||
//use super::{constants, FILE};
|
||||
//use platform::types::*;
|
||||
//
|
||||
//pub fn ftello(stream: &mut FILE) -> off_t {
|
||||
// let pos = stream.seek(
|
||||
// 0,
|
||||
// if let Some((wbase, wpos, _)) = stream.write {
|
||||
// if (stream.flags & constants::F_APP > 0) && wpos > wbase {
|
||||
// constants::SEEK_END
|
||||
// } else {
|
||||
// constants::SEEK_CUR
|
||||
// }
|
||||
// } else {
|
||||
// constants::SEEK_CUR
|
||||
// },
|
||||
// );
|
||||
// if pos < 0 {
|
||||
// return pos;
|
||||
// }
|
||||
// let rdiff = if let Some((rpos, rend)) = stream.read {
|
||||
// rend - rpos
|
||||
// } else {
|
||||
// 0
|
||||
// };
|
||||
// let wdiff = if let Some((wbase, wpos, _)) = stream.write {
|
||||
// wpos - wbase
|
||||
// } else {
|
||||
// 0
|
||||
// };
|
||||
// pos - rdiff as i64 + wdiff as i64
|
||||
//}
|
||||
|
||||
+317
-481
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
use alloc::String;
|
||||
use alloc::Vec;
|
||||
use io::Read;
|
||||
use platform::types::*;
|
||||
use platform::ReadByte;
|
||||
use va_list::VaList;
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
@@ -27,7 +27,7 @@ unsafe fn next_byte(string: &mut *const c_char) -> Result<u8, c_int> {
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn inner_scanf<R: ReadByte>(
|
||||
unsafe fn inner_scanf<R: Read>(
|
||||
mut r: R,
|
||||
mut format: *const c_char,
|
||||
mut ap: VaList,
|
||||
@@ -39,14 +39,15 @@ unsafe fn inner_scanf<R: ReadByte>(
|
||||
|
||||
macro_rules! read {
|
||||
() => {{
|
||||
match r.read_u8() {
|
||||
Ok(Some(b)) => {
|
||||
byte = b;
|
||||
let mut buf = &mut [byte];
|
||||
match r.read(buf) {
|
||||
Ok(0) => false,
|
||||
Ok(_) => {
|
||||
byte = buf[0];
|
||||
count += 1;
|
||||
true
|
||||
}
|
||||
Ok(None) => false,
|
||||
Err(()) => return Err(-1),
|
||||
Err(_) => return Err(-1),
|
||||
}
|
||||
}};
|
||||
}
|
||||
@@ -420,7 +421,7 @@ unsafe fn inner_scanf<R: ReadByte>(
|
||||
}
|
||||
Ok(matched)
|
||||
}
|
||||
pub unsafe fn scanf<R: ReadByte>(r: R, format: *const c_char, ap: VaList) -> c_int {
|
||||
pub unsafe fn scanf<R: Read>(r: R, format: *const c_char, ap: VaList) -> c_int {
|
||||
match inner_scanf(r, format, ap) {
|
||||
Ok(n) => n,
|
||||
Err(n) => n,
|
||||
|
||||
Reference in New Issue
Block a user