Skip to content

Commit 9041129

Browse files
committed
read_into on FileIO
1 parent 6deb71d commit 9041129

File tree

4 files changed

+49
-26
lines changed

4 files changed

+49
-26
lines changed

vm/src/pyobject.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,10 @@ impl PyContext {
411411
PyObject::new(PyObjectKind::Bytes { value: data }, self.bytes_type())
412412
}
413413

414+
pub fn new_bytearray(&self, data: Vec<u8>) -> PyObjectRef {
415+
PyObject::new(PyObjectKind::Bytes { value: data }, self.bytearray_type())
416+
}
417+
414418
pub fn new_bool(&self, b: bool) -> PyObjectRef {
415419
if b {
416420
self.true_value.clone()

vm/src/stdlib/io.rs

Lines changed: 42 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44

55

66
use std::fs::File;
7+
use std::io::Take;
8+
use std::os::unix::io::{FromRawFd,IntoRawFd};
9+
710
use std::io::prelude::*;
811
use std::io::{BufReader,BufWriter};
912

@@ -12,6 +15,7 @@ use super::super::obj::objint;
1215
use num_bigint::{BigInt, ToBigInt};
1316

1417
use super::super::obj::objtype;
18+
use super::os::os_open;
1519

1620
use super::super::pyobject::{
1721
PyContext, PyFuncArgs, PyObjectKind, PyObjectRef, PyResult, TypeProtocol, AttributeProtocol
@@ -57,9 +61,9 @@ fn file_io_init(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
5761
args,
5862
required = [(file_io, None), (name, Some(vm.ctx.str_type()))]
5963
);
60-
64+
let fileno = os_open(vm, PyFuncArgs::new(vec![name.clone()], vec![]));
6165
vm.ctx.set_attr(&file_io, "name", name.clone());
62-
vm.ctx.set_attr(&file_io, "__offset__", vm.ctx.new_int(0.to_bigint().unwrap()));
66+
vm.ctx.set_attr(&file_io, "fileno", fileno.unwrap());
6367
Ok(vm.get_none())
6468
}
6569

@@ -101,30 +105,24 @@ fn file_io_readinto(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
101105
let py_length = vm.invoke(len_method.unwrap(), PyFuncArgs::default());
102106
let length = objint::get_value(&py_length.unwrap()).to_u64().unwrap();
103107

104-
let py_offset = vm.ctx.get_attr(&file_io, &"__offset__".to_string());
105-
let offset = objint::get_value(&py_offset.unwrap()).to_u64().unwrap();
108+
let fileno = file_io.get_attr("fileno").unwrap();
109+
let raw_fd = objint::get_value(&fileno).to_i32().unwrap();
106110

107-
//extract file name and open a file handle, taking length many bytes
108-
let py_name = file_io.get_attr("name").unwrap();
111+
let handle = unsafe {
112+
File::from_raw_fd(raw_fd)
113+
};
109114

110-
let handle = match File::open(objstr::get_value(&py_name)) {
111-
Ok(v) => Ok(v.take(offset + length)),
112-
Err(v) => Err(vm.new_type_error("Error opening file".to_string())),
113-
};
115+
let mut f = handle.take(length);
114116

115-
if let Ok(mut f) = handle {
116-
match obj.borrow_mut().kind {
117-
PyObjectKind::Bytes { ref mut value } => {
118-
value.clear();
119-
f.read_to_end(&mut *value);
120-
*value = value.iter().skip(offset as usize).cloned().collect();
121-
},
122-
_ => {}
123-
};
124-
}
125-
126-
vm.ctx.set_attr(&file_io, "__offset__", vm.ctx.new_int(offset+length.to_bigint().unwrap()));
127-
117+
match obj.borrow_mut().kind {
118+
PyObjectKind::Bytes { ref mut value } => {
119+
value.clear();
120+
f.read_to_end(&mut *value);
121+
},
122+
_ => {}
123+
};
124+
let new_handle = f.into_inner().into_raw_fd().to_bigint();
125+
vm.ctx.set_attr(&file_io, "fileno", vm.ctx.new_int(new_handle.unwrap()));
128126
Ok(vm.get_none())
129127
}
130128

@@ -140,11 +138,29 @@ fn io_open(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
140138
arg_check!(
141139
vm,
142140
args,
143-
required = [(file, None), (mode, None)]
141+
required = [(file, Some(vm.ctx.str_type())), (mode, Some(vm.ctx.str_type()))]
144142
);
145143

144+
let module = mk_module(&vm.ctx);
146145

147-
Ok(vm.get_none())
146+
let rust_mode = objstr::get_value(mode);
147+
if rust_mode.contains("w") {
148+
vm.new_not_implemented_error("Writes are not yet implemented".to_string());
149+
}
150+
151+
let file_io_class = vm.ctx.get_attr(&module, "FileIO").unwrap();
152+
vm.invoke(file_io_class, PyFuncArgs::new(vec![file.clone()], vec![]))
153+
154+
155+
156+
// vm.get_method(fi.clone(), &"__new__".to_string());
157+
158+
// let buffer = vm.ctx.new_bytearray(vec![]);
159+
// vm.invoke(new_file_io.unwrap(), PyFuncArgs {
160+
// args: vec![fi.clone(), file.clone()],
161+
// kwargs: vec![]
162+
// });
163+
// Ok(fi)
148164

149165
//mode is optional: 'rt' is the default mode (open from reading text)
150166
//To start we construct a FileIO (subclass of RawIOBase)
@@ -159,6 +175,7 @@ fn io_open(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
159175

160176
//If the mode is text this buffer type is consumed on construction of
161177
//a TextIOWrapper which is subsequently returned.
178+
// Ok(vm.get_none())
162179
}
163180

164181

vm/src/stdlib/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ mod time_module;
1010
mod tokenize;
1111
mod types;
1212
mod weakref;
13+
mod os;
1314
use std::collections::HashMap;
1415

1516
use super::pyobject::{PyContext, PyObjectRef};
@@ -23,6 +24,7 @@ pub fn get_module_inits() -> HashMap<String, StdlibInitFunc> {
2324
modules.insert("json".to_string(), json::mk_module as StdlibInitFunc);
2425
modules.insert("keyword".to_string(), keyword::mk_module as StdlibInitFunc);
2526
modules.insert("math".to_string(), math::mk_module as StdlibInitFunc);
27+
modules.insert("os".to_string(), os::mk_module as StdlibInitFunc);
2628
modules.insert("re".to_string(), re::mk_module as StdlibInitFunc);
2729
modules.insert("random".to_string(), random::mk_module as StdlibInitFunc);
2830
modules.insert("struct".to_string(), pystruct::mk_module as StdlibInitFunc);

vm/src/stdlib/os.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use super::super::pyobject::{
1515
use super::super::vm::VirtualMachine;
1616

1717

18-
fn os_open(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
18+
pub fn os_open(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
1919
arg_check!(
2020
vm,
2121
args,

0 commit comments

Comments
 (0)