Skip to content

Commit edc720e

Browse files
committed
Buffered Objects for Open
1 parent 2bbd4fd commit edc720e

File tree

1 file changed

+51
-38
lines changed

1 file changed

+51
-38
lines changed

vm/src/stdlib/io.rs

Lines changed: 51 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,14 @@ fn buffered_io_base_init(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult
5858
Ok(vm.get_none())
5959
}
6060

61-
fn buffered_io_base_read(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
61+
fn buffered_reader_read(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
6262
arg_check!(
6363
vm,
6464
args,
6565
required = [(buffered, None)]
6666
);
67-
let buff_size = 8;
68-
let mut buffer = vm.ctx.new_bytes(vec![0; buff_size]);
67+
let buff_size = 8*1024;
68+
let buffer = vm.ctx.new_bytes(vec![0; buff_size]);
6969

7070
//buffer method
7171
let mut result = vec![];
@@ -75,8 +75,12 @@ fn buffered_io_base_read(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult
7575

7676
while length == buff_size {
7777
let raw_read = vm.get_method(raw.clone(), &"readinto".to_string()).unwrap();
78-
vm.invoke(raw_read, PyFuncArgs::new(vec![buffer.clone()], vec![]));
79-
78+
match vm.invoke(raw_read, PyFuncArgs::new(vec![buffer.clone()], vec![])) {
79+
Ok(_) => {},
80+
Err(_) => {
81+
return Err(vm.new_value_error("IO Error".to_string()))
82+
}
83+
}
8084

8185
match buffer.borrow_mut().kind {
8286
PyObjectKind::Bytes { ref mut value } => {
@@ -140,7 +144,10 @@ fn file_io_read(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
140144

141145
let mut bytes = vec![];
142146
if let Ok(mut buff) = buffer {
143-
buff.read_to_end(&mut bytes);
147+
match buff.read_to_end(&mut bytes) {
148+
Ok(_) => {},
149+
Err(_) => return Err(vm.new_value_error("Error reading from Buffer".to_string()))
150+
}
144151
}
145152

146153
Ok(vm.ctx.new_bytes(bytes))
@@ -172,7 +179,10 @@ fn file_io_readinto(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
172179
match obj.borrow_mut().kind {
173180
PyObjectKind::Bytes { ref mut value } => {
174181
value.clear();
175-
f.read_to_end(&mut *value);
182+
match f.read_to_end(&mut *value) {
183+
Ok(_) => {},
184+
Err(_) => return Err(vm.new_value_error("Error reading from Take".to_string()))
185+
}
176186

177187
},
178188
_ => {}
@@ -203,31 +213,34 @@ fn file_io_write(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
203213
match obj.borrow_mut().kind {
204214
PyObjectKind::Bytes { ref mut value } => {
205215
match handle.write(&value[..]) {
206-
Ok(k) => { println!("{}", k); },
216+
Ok(k) => { println!("{}", k); },//set result to py_int and return
207217
Err(_) => {}
208218
}
209219
},
210220
_ => {}
211221
};
212222

223+
let new_handle = handle.into_raw_fd().to_bigint();
224+
vm.ctx.set_attr(&file_io, "fileno", vm.ctx.new_int(new_handle.unwrap()));
225+
213226
let len_method = vm.get_method(obj.clone(), &"__len__".to_string());
214227
vm.invoke(len_method.unwrap(), PyFuncArgs::default())
215228

216-
//TODO: reset fileno
217-
218229
}
219230

220-
fn buffered_reader_init(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
231+
fn buffered_writer_write(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
221232
arg_check!(
222-
vm,
223-
args,
224-
required = [(buffed_reader, None), (raw, None)]
233+
vm,
234+
args,
235+
required = [(buffered, None), (obj, Some(vm.ctx.bytes_type()))]
225236
);
226237

238+
let raw = vm.ctx.get_attr(&buffered, "raw").unwrap();
239+
let raw_write = vm.get_method(raw.clone(), &"write".to_string()).unwrap();
240+
241+
//This should be replaced with a more appropriate chunking implementation
242+
vm.invoke(raw_write, PyFuncArgs::new(vec![obj.clone()], vec![]))
227243

228-
//simple calls read on the read class!
229-
// TODO
230-
Ok(vm.get_none())
231244
}
232245

233246
fn io_open(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
@@ -239,32 +252,31 @@ fn io_open(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
239252

240253
let module = mk_module(&vm.ctx);
241254

242-
let rust_mode = objstr::get_value(mode);
243-
if rust_mode.contains("w") {
244-
vm.new_not_implemented_error("Writes are not yet implemented".to_string());
245-
}
246-
255+
//mode is optional: 'rt' is the default mode (open from reading text)
256+
//To start we construct a FileIO (subclass of RawIOBase)
247257
let file_io_class = vm.ctx.get_attr(&module, "FileIO").unwrap();
248-
vm.invoke(file_io_class, PyFuncArgs::new(vec![file.clone()], vec![]))
249-
250-
251-
252-
// vm.get_method(fi.clone(), &"__new__".to_string());
258+
let buffered_writer_class = vm.ctx.get_attr(&module, "BufferedWriter").unwrap();
259+
let buffered_reader_class = vm.ctx.get_attr(&module, "BufferedReader").unwrap();
253260

254-
// let buffer = vm.ctx.new_bytearray(vec![]);
255-
// vm.invoke(new_file_io.unwrap(), PyFuncArgs {
256-
// args: vec![fi.clone(), file.clone()],
257-
// kwargs: vec![]
258-
// });
259-
// Ok(fi)
261+
//instantiate raw fileio
262+
let file_io = vm.invoke(file_io_class, PyFuncArgs::new(vec![file.clone()], vec![])).unwrap();
260263

261-
//mode is optional: 'rt' is the default mode (open from reading text)
262-
//To start we construct a FileIO (subclass of RawIOBase)
263264
//This is subsequently consumed by a Buffered_class of type depending
264265
//operation in the mode. i.e:
266+
let rust_mode = objstr::get_value(mode);
267+
265268
// updating => PyBufferedRandom
266269
// creating || writing || appending => BufferedWriter
270+
let buffered = if rust_mode.contains("w") {
271+
// vm.new_not_implemented_error("Writes are not yet implemented".to_string());
272+
println!("writer class");
273+
vm.invoke(buffered_writer_class, PyFuncArgs::new(vec![file_io.clone()], vec![]))
267274
// reading => BufferedReader
275+
} else {
276+
vm.invoke(buffered_reader_class, PyFuncArgs::new(vec![file_io.clone()], vec![]))
277+
};
278+
279+
buffered
268280
// If the mode is binary this Buffered class is returned directly at
269281
// this point.
270282
//For Buffered class construct "raw" IO class e.g. FileIO and pass this into corresponding field
@@ -288,7 +300,6 @@ pub fn mk_module(ctx: &PyContext) -> PyObjectRef {
288300

289301
let buffered_io_base = ctx.new_class("BufferedIOBase", io_base.clone());
290302
ctx.set_attr(&buffered_io_base, "__init__", ctx.new_rustfunc(buffered_io_base_init));
291-
ctx.set_attr(&buffered_io_base, "read", ctx.new_rustfunc(buffered_io_base_read));
292303
ctx.set_attr(&py_mod, "BufferedIOBase", buffered_io_base.clone());
293304

294305
let text_io_base = ctx.new_class("TextIOBase", io_base.clone());
@@ -305,10 +316,12 @@ pub fn mk_module(ctx: &PyContext) -> PyObjectRef {
305316

306317
// BufferedIOBase Subclasses
307318
let buffered_reader = ctx.new_class("BufferedReader", buffered_io_base.clone());
319+
ctx.set_attr(&buffered_reader, "read", ctx.new_rustfunc(buffered_reader_read));
308320
ctx.set_attr(&py_mod, "BufferedReader", buffered_reader.clone());
309321

310-
let buffered_reader = ctx.new_class("BufferedWriter", buffered_io_base.clone());
311-
ctx.set_attr(&py_mod, "BufferedWriter", buffered_reader.clone());
322+
let buffered_writer = ctx.new_class("BufferedWriter", buffered_io_base.clone());
323+
ctx.set_attr(&buffered_writer, "write", ctx.new_rustfunc(buffered_writer_write));
324+
ctx.set_attr(&py_mod, "BufferedWriter", buffered_writer.clone());
312325

313326
//TextIOBase Subclass
314327
let text_io_wrapper = ctx.new_class("TextIOWrapper", ctx.object());

0 commit comments

Comments
 (0)