memoryview object, FileIO Methods

This commit is contained in:
rmliddle
2019-01-01 23:39:21 +11:00
parent f325ef1499
commit 08a9fd9819
5 changed files with 197 additions and 7 deletions

View File

@@ -499,8 +499,6 @@ fn builtin_max(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
Ok(x)
}
// builtin_memoryview
fn builtin_min(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
let candidates = if args.args.len() > 1 {
args.args.clone()
@@ -774,6 +772,7 @@ pub fn make_module(ctx: &PyContext) -> PyObjectRef {
ctx.set_attr(&py_mod, "locals", ctx.new_rustfunc(builtin_locals));
ctx.set_attr(&py_mod, "map", ctx.new_rustfunc(builtin_map));
ctx.set_attr(&py_mod, "max", ctx.new_rustfunc(builtin_max));
ctx.set_attr(&py_mod, "memoryview", ctx.memoryview_type());
ctx.set_attr(&py_mod, "min", ctx.new_rustfunc(builtin_min));
ctx.set_attr(&py_mod, "object", ctx.object());
ctx.set_attr(&py_mod, "oct", ctx.new_rustfunc(builtin_oct));

View File

@@ -13,6 +13,7 @@ pub mod objgenerator;
pub mod objint;
pub mod objiter;
pub mod objlist;
pub mod objmemory;
pub mod objobject;
pub mod objproperty;
pub mod objsequence;

27
vm/src/obj/objmemory.rs Normal file
View File

@@ -0,0 +1,27 @@
use super::objtype;
use super::super::pyobject::{
PyContext, PyFuncArgs, PyObject, PyObjectKind, PyObjectRef, PyResult, TypeProtocol
};
use super::super::vm::VirtualMachine;
pub fn new_memory_view(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(
vm,
args,
required = [(cls, None), (bytes_object, None)]
);
vm.ctx.set_attr(&cls, "obj", bytes_object.clone());
Ok(PyObject::new(
PyObjectKind::MemoryView { obj: bytes_object.clone() },
cls.clone()
))
}
pub fn init(ctx: &PyContext) {
let ref memoryview_type = ctx.memoryview_type;
ctx.set_attr(&memoryview_type, "__new__", ctx.new_rustfunc(new_memory_view));
}

View File

@@ -14,6 +14,7 @@ use super::obj::objgenerator;
use super::obj::objint;
use super::obj::objiter;
use super::obj::objlist;
use super::obj::objmemory;
use super::obj::objobject;
use super::obj::objproperty;
use super::obj::objset;
@@ -114,6 +115,7 @@ pub struct PyContext {
pub true_value: PyObjectRef,
pub false_value: PyObjectRef,
pub list_type: PyObjectRef,
pub memoryview_type: PyObjectRef,
pub none: PyObjectRef,
pub tuple_type: PyObjectRef,
pub set_type: PyObjectRef,
@@ -197,6 +199,7 @@ impl PyContext {
let tuple_type = create_type("tuple", &type_type, &object_type, &dict_type);
let iter_type = create_type("iter", &type_type, &object_type, &dict_type);
let bool_type = create_type("bool", &type_type, &int_type, &dict_type);
let memoryview_type = create_type("memoryview", &type_type, &object_type, &dict_type);
let code_type = create_type("code", &type_type, &int_type, &dict_type);
let exceptions = exceptions::ExceptionZoo::new(&type_type, &object_type, &dict_type);
@@ -217,6 +220,7 @@ impl PyContext {
);
let context = PyContext {
bool_type: bool_type,
memoryview_type : memoryview_type,
bytearray_type: bytearray_type,
bytes_type: bytes_type,
code_type: code_type,
@@ -261,6 +265,7 @@ impl PyContext {
objbytes::init(&context);
objbytearray::init(&context);
objproperty::init(&context);
objmemory::init(&context);
objstr::init(&context);
objsuper::init(&context);
objtuple::init(&context);
@@ -320,6 +325,10 @@ impl PyContext {
self.bool_type.clone()
}
pub fn memoryview_type(&self) -> PyObjectRef {
self.memoryview_type.clone()
}
pub fn tuple_type(&self) -> PyObjectRef {
self.tuple_type.clone()
}
@@ -831,6 +840,9 @@ pub enum PyObjectKind {
stop: Option<i32>,
step: Option<i32>,
},
MemoryView {
obj : PyObjectRef
},
Code {
code: bytecode::CodeObject,
},
@@ -881,6 +893,7 @@ impl fmt::Debug for PyObjectKind {
&PyObjectKind::Float { ref value } => write!(f, "float {}", value),
&PyObjectKind::Complex { ref value } => write!(f, "complex {}", value),
&PyObjectKind::Bytes { ref value } => write!(f, "bytes/bytearray {:?}", value),
&PyObjectKind::MemoryView { ref obj } => write!(f, "bytes/bytearray {:?}", obj),
&PyObjectKind::Sequence { elements: _ } => write!(f, "list or tuple"),
&PyObjectKind::Dict { elements: _ } => write!(f, "dict"),
&PyObjectKind::Set { elements: _ } => write!(f, "set"),
@@ -934,6 +947,7 @@ impl PyObject {
PyObjectKind::Float { ref value } => format!("{:?}", value),
PyObjectKind::Complex { ref value } => format!("{:?}", value),
PyObjectKind::Bytes { ref value } => format!("b'{:?}'", value),
PyObjectKind::MemoryView { ref obj } => format!("b'{:?}'", obj),
PyObjectKind::Sequence { ref elements } => format!(
"(/[{}]/)",
elements

View File

@@ -2,9 +2,21 @@
* I/O core tools.
*/
// use super::super::obj::{objstr, objtype};
use super::super::pyobject::{PyContext, PyFuncArgs, PyObjectRef, PyResult};
use super::super::VirtualMachine;
use std::fs::File;
use std::io::prelude::*;
use std::io::{BufReader,BufWriter};
use super::super::obj::objstr::get_value;
use super::super::obj::objtype;
use super::super::pyobject::{
PyContext, PyFuncArgs, PyObjectKind, PyObjectRef, PyResult, TypeProtocol, AttributeProtocol
};
use super::super::vm::VirtualMachine;
fn string_io_init(vm: &mut VirtualMachine, _args: PyFuncArgs) -> PyResult {
// arg_check!(vm, args, required = [(s, Some(vm.ctx.str_type()))]);
@@ -29,21 +41,158 @@ fn bytes_io_getvalue(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
Ok(vm.get_none())
}
fn buffered_io_base_init(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
// arg_check!(vm, args);
// TODO
Ok(vm.get_none())
}
fn file_io_init(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(
vm,
args,
required = [(file_io, None), (name, Some(vm.ctx.str_type()))]
);
vm.ctx.set_attr(&file_io, "name", name.clone());
Ok(vm.get_none())
}
fn file_io_read(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(
vm,
args,
required = [(file_io, None)]
);
let py_name = file_io.get_attr("name").unwrap();
let f = match File::open(get_value(& py_name)) {
Ok(v) => Ok(v),
Err(v) => Err(vm.new_type_error("Error opening file".to_string())),
};
let buffer = match f {
Ok(v) => Ok(BufReader::new(v)),
Err(v) => Err(vm.new_type_error("Error reading from file".to_string()))
};
let mut bytes = vec![];
if let Ok(mut buff) = buffer {
buff.read_to_end(&mut bytes);
}
Ok(vm.ctx.new_bytes(bytes))
}
fn file_io_read_into(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(
vm,
args,
required = [(file_io, None), (view, Some(vm.ctx.bytes_type()))]
);
let py_name = file_io.get_attr("name").unwrap();
let f = match File::open(get_value(& py_name)) {
Ok(v) => Ok(v),
Err(v) => Err(vm.new_type_error("Error opening file".to_string())),
};
let buffer = match f {
Ok(v) => Ok(BufReader::new(v)),
Err(v) => Err(vm.new_type_error("Error reading from file".to_string()))
};
match view.borrow_mut().kind {
PyObjectKind::Bytes { ref mut value } => {
if let Ok(mut buff) = buffer {
buff.read_to_end(&mut *value);
};
},
_ => {}
};
Ok(vm.get_none())
}
fn buffered_reader_read(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(vm, args);
// TODO
Ok(vm.get_none())
}
fn io_open(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(
vm,
args,
required = [(file, None), (mode, None)]
);
Ok(vm.get_none())
//mode is optional: 'rt' is the default mode (open from reading text)
//To start we construct a FileIO (subclass of RawIOBase)
//This is subsequently consumed by a Buffered_class of type depending
//operation in the mode. i.e:
// updating => PyBufferedRandom
// creating || writing || appending => BufferedWriter
// reading => BufferedReader
// If the mode is binary this Buffered class is returned directly at
// this point.
//If the mode is text this buffer type is consumed on construction of
//a TextIOWrapper which is subsequently returned.
}
pub fn mk_module(ctx: &PyContext) -> PyObjectRef {
let py_mod = ctx.new_module(&"io".to_string(), ctx.new_scope(None));
ctx.set_attr(&py_mod, "open", ctx.new_rustfunc(io_open));
//IOBase the abstract base class of the IO Module
let io_base = ctx.new_class("IOBase", ctx.object());
ctx.set_attr(&py_mod, "IOBase", io_base.clone());
// IOBase Subclasses
let raw_io_base = ctx.new_class("RawIOBase", ctx.object());
ctx.set_attr(&py_mod, "RawIOBase", raw_io_base.clone());
let buffered_io_base = ctx.new_class("BufferedIOBase", io_base.clone());
ctx.set_attr(&buffered_io_base, "__init__", ctx.new_rustfunc(buffered_io_base_init));
ctx.set_attr(&py_mod, "BufferedIOBase", buffered_io_base.clone());
let text_io_base = ctx.new_class("TextIOBase", io_base.clone());
ctx.set_attr(&py_mod, "TextIOBase", text_io_base.clone());
// RawBaseIO Subclasses
let file_io = ctx.new_class("FileIO", raw_io_base.clone());
ctx.set_attr(&file_io, "__init__", ctx.new_rustfunc(file_io_init));
ctx.set_attr(&file_io, "name", ctx.str_type());
ctx.set_attr(&file_io, "read", ctx.new_rustfunc(file_io_read));
ctx.set_attr(&file_io, "read_into", ctx.new_rustfunc(file_io_read_into));
ctx.set_attr(&py_mod, "FileIO", file_io.clone());
// BufferedIOBase Subclasses
let buffered_reader = ctx.new_class("BufferedReader", buffered_io_base.clone());
ctx.set_attr(&py_mod, "BufferedReader", buffered_reader.clone());
let buffered_reader = ctx.new_class("BufferedWriter", buffered_io_base.clone());
ctx.set_attr(&py_mod, "BufferedWriter", buffered_reader.clone());
//TextIOBase Subclass
let text_io_wrapper = ctx.new_class("TextIOWrapper", ctx.object());
ctx.set_attr(&py_mod, "TextIOWrapper", text_io_wrapper.clone());
// BytesIO: in-memory bytes
let string_io = ctx.new_class("StringIO", io_base.clone());
ctx.set_attr(&string_io, "__init__", ctx.new_rustfunc(string_io_init));
ctx.set_attr(&string_io, "getvalue", ctx.new_rustfunc(string_io_getvalue));
ctx.set_attr(&py_mod, "StringIO", string_io);
// StringIO: in-memory text
let bytes_io = ctx.new_class("BytesIO", io_base.clone());
ctx.set_attr(&bytes_io, "__init__", ctx.new_rustfunc(bytes_io_init));
ctx.set_attr(&bytes_io, "getvalue", ctx.new_rustfunc(bytes_io_getvalue));
ctx.set_attr(&py_mod, "BytesIO", bytes_io);
py_mod
}
}