mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-09 22:49:57 +09:00
Generalized Mode Handling
This commit is contained in:
@@ -2,6 +2,8 @@
|
||||
* I/O core tools.
|
||||
*/
|
||||
|
||||
use std::collections::HashSet;
|
||||
|
||||
use std::io::prelude::*;
|
||||
use std::os::unix::io::{FromRawFd,IntoRawFd};
|
||||
|
||||
@@ -12,7 +14,7 @@ use super::super::obj::objstr;
|
||||
use super::super::obj::objint;
|
||||
use super::super::obj::objbytes;
|
||||
use super::super::obj::objtype;
|
||||
use super::os::os_open;
|
||||
use super::os;
|
||||
|
||||
use num_bigint::{ToBigInt};
|
||||
use num_traits::ToPrimitive;
|
||||
@@ -23,6 +25,16 @@ use super::super::pyobject::{
|
||||
|
||||
use super::super::vm::VirtualMachine;
|
||||
|
||||
fn compute_c_flag(mode : &String) -> u16 {
|
||||
match mode.as_ref() {
|
||||
"w" => 512,
|
||||
"x" => 512,
|
||||
"a" => 8,
|
||||
"+" => 2,
|
||||
_ => 0
|
||||
}
|
||||
}
|
||||
|
||||
fn string_io_init(vm: &mut VirtualMachine, _args: PyFuncArgs) -> PyResult {
|
||||
// arg_check!(vm, args, required = [(s, Some(vm.ctx.str_type()))]);
|
||||
// TODO
|
||||
@@ -71,6 +83,9 @@ fn buffered_reader_read(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
|
||||
let raw = vm.ctx.get_attr(&buffered, "raw").unwrap();
|
||||
|
||||
//Iterates through the raw class, invoking the readinto method
|
||||
//to obtain buff_size many bytes. Exit when less than buff_size many
|
||||
//bytes are returned (when the end of the file is reached).
|
||||
while length == buff_size {
|
||||
let raw_read = vm.get_method(raw.clone(), &"readinto".to_string()).unwrap();
|
||||
match vm.invoke(raw_read, PyFuncArgs::new(vec![buffer.clone()], vec![])) {
|
||||
@@ -80,6 +95,7 @@ fn buffered_reader_read(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
}
|
||||
}
|
||||
|
||||
//Copy bytes from the buffer vector into the results vector
|
||||
match buffer.borrow_mut().kind {
|
||||
PyObjectKind::Bytes { ref mut value } => {
|
||||
result.extend(value.iter().cloned());
|
||||
@@ -103,23 +119,22 @@ fn file_io_init(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
optional = [(mode, Some(vm.ctx.str_type()))]
|
||||
);
|
||||
|
||||
let mode = if let Some(m) = mode {
|
||||
objstr::get_value(m)
|
||||
} else {
|
||||
"r".to_string()
|
||||
let rust_mode = match mode {
|
||||
Some(m) => objstr::get_value(m),
|
||||
None => "r".to_string()
|
||||
};
|
||||
|
||||
let os_mode = match mode.as_ref() {
|
||||
"r" => 0.to_bigint(),
|
||||
_ => 512.to_bigint()
|
||||
};
|
||||
let args = vec![name.clone(), vm.ctx.new_int(os_mode.unwrap())];
|
||||
let fileno = os_open(vm, PyFuncArgs::new(args, vec![]));
|
||||
match compute_c_flag(&rust_mode).to_bigint() {
|
||||
Some(os_mode) => {
|
||||
let args = vec![name.clone(), vm.ctx.new_int(os_mode)];
|
||||
let fileno = os::os_open(vm, PyFuncArgs::new(args, vec![]));
|
||||
|
||||
|
||||
vm.ctx.set_attr(&file_io, "name", name.clone());
|
||||
vm.ctx.set_attr(&file_io, "fileno", fileno.unwrap());
|
||||
Ok(vm.get_none())
|
||||
vm.ctx.set_attr(&file_io, "name", name.clone());
|
||||
vm.ctx.set_attr(&file_io, "fileno", fileno.unwrap());
|
||||
Ok(vm.get_none())
|
||||
},
|
||||
None => Err(vm.new_type_error(format!("invalid mode {}", rust_mode)))
|
||||
}
|
||||
}
|
||||
|
||||
fn file_io_read(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
@@ -174,7 +189,7 @@ fn file_io_readinto(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
};
|
||||
|
||||
let mut f = handle.take(length);
|
||||
match obj.borrow_mut().kind {
|
||||
match obj.borrow_mut().kind {
|
||||
PyObjectKind::Bytes { ref mut value } => {
|
||||
value.clear();
|
||||
match f.read_to_end(&mut *value) {
|
||||
@@ -252,7 +267,6 @@ fn text_io_wrapper_init(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
Ok(vm.get_none())
|
||||
}
|
||||
|
||||
|
||||
fn text_io_base_read(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(
|
||||
vm,
|
||||
@@ -278,7 +292,7 @@ pub fn io_open(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(
|
||||
vm,
|
||||
args,
|
||||
required = [(_file, Some(vm.ctx.str_type()))],
|
||||
required = [(file, Some(vm.ctx.str_type()))],
|
||||
optional = [(mode, Some(vm.ctx.str_type()))]
|
||||
);
|
||||
|
||||
@@ -291,6 +305,24 @@ pub fn io_open(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
"rt".to_string()
|
||||
};
|
||||
|
||||
let mut raw_modes = HashSet::new();
|
||||
|
||||
// Add some books.
|
||||
raw_modes.insert("a".to_string());
|
||||
raw_modes.insert("r".to_string());
|
||||
raw_modes.insert("x".to_string());
|
||||
raw_modes.insert("w".to_string());
|
||||
|
||||
//This is not a terribly elegant way to separate the file mode from
|
||||
//the "type" flag - this should be improved. The intention here is to
|
||||
//match a valid flag for the file_io_init call:
|
||||
//https://docs.python.org/3/library/io.html#io.FileIO
|
||||
let modes: Vec<char> = rust_mode.chars().filter(|a| raw_modes.contains(&a.to_string())).collect();
|
||||
|
||||
if modes.len() == 0 || modes.len() > 1 {
|
||||
return Err(vm.new_value_error("Invalid Mode".to_string()))
|
||||
}
|
||||
|
||||
//Class objects (potentially) consumed by io.open
|
||||
//RawIO: FileIO
|
||||
//Buffered: BufferedWriter, BufferedReader
|
||||
@@ -302,7 +334,8 @@ pub fn io_open(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
|
||||
//Construct a FileIO (subclass of RawIOBase)
|
||||
//This is subsequently consumed by a Buffered Class.
|
||||
let file_io = vm.invoke(file_io_class, args.clone()).unwrap();
|
||||
let file_args = PyFuncArgs::new(vec![file.clone(), vm.ctx.new_str(modes[0].to_string())] , vec![]);
|
||||
let file_io = vm.invoke(file_io_class, file_args).unwrap();
|
||||
|
||||
//Create Buffered class to consume FileIO. The type of buffered class depends on
|
||||
//the operation in the mode.
|
||||
|
||||
@@ -51,6 +51,7 @@ pub fn mk_module(ctx: &PyContext) -> PyObjectRef {
|
||||
ctx.set_attr(&py_mod, "O_WRONLY", ctx.new_int(1.to_bigint().unwrap()));
|
||||
ctx.set_attr(&py_mod, "O_RDWR", ctx.new_int(2.to_bigint().unwrap()));
|
||||
ctx.set_attr(&py_mod, "O_NONBLOCK", ctx.new_int(3.to_bigint().unwrap()));
|
||||
ctx.set_attr(&py_mod, "O_APPEND", ctx.new_int(8.to_bigint().unwrap()));
|
||||
ctx.set_attr(&py_mod, "O_CREAT", ctx.new_int(512.to_bigint().unwrap()));
|
||||
py_mod
|
||||
}
|
||||
Reference in New Issue
Block a user