mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-17 01:51:39 +09:00
bytes and bytearray
This commit is contained in:
@@ -1,17 +1,47 @@
|
||||
//! Implementation of the python bytearray object.
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
use crate::pyobject::{PyContext, PyFuncArgs, PyObject, PyObjectPayload, PyResult, TypeProtocol};
|
||||
use crate::pyobject::{
|
||||
PyContext, PyFuncArgs, PyObject, PyObjectPayload, PyObjectPayload2, PyObjectRef, PyResult,
|
||||
TypeProtocol,
|
||||
};
|
||||
|
||||
use super::objint;
|
||||
|
||||
use super::objbytes::get_mut_value;
|
||||
use super::objbytes::get_value;
|
||||
use super::objtype;
|
||||
use crate::vm::VirtualMachine;
|
||||
use num_traits::ToPrimitive;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PyByteArray {
|
||||
// TODO: shouldn't be public
|
||||
pub value: RefCell<Vec<u8>>,
|
||||
}
|
||||
|
||||
impl PyByteArray {
|
||||
pub fn new(data: Vec<u8>) -> Self {
|
||||
PyByteArray {
|
||||
value: RefCell::new(data),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PyObjectPayload2 for PyByteArray {
|
||||
fn required_type(ctx: &PyContext) -> PyObjectRef {
|
||||
ctx.bytearray_type()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_value<'a>(obj: &'a PyObjectRef) -> impl Deref<Target = Vec<u8>> + 'a {
|
||||
obj.payload::<PyByteArray>().unwrap().value.borrow()
|
||||
}
|
||||
|
||||
pub fn get_mut_value<'a>(obj: &'a PyObjectRef) -> impl DerefMut<Target = Vec<u8>> + 'a {
|
||||
obj.payload::<PyByteArray>().unwrap().value.borrow_mut()
|
||||
}
|
||||
|
||||
// Binary data support
|
||||
|
||||
/// Fill bytearray class methods dictionary.
|
||||
@@ -143,8 +173,8 @@ fn bytearray_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
vec![]
|
||||
};
|
||||
Ok(PyObject::new(
|
||||
PyObjectPayload::Bytes {
|
||||
value: RefCell::new(value),
|
||||
PyObjectPayload::AnyRustValue {
|
||||
value: Box::new(PyByteArray::new(value)),
|
||||
},
|
||||
cls.clone(),
|
||||
))
|
||||
@@ -290,13 +320,8 @@ fn bytearray_repr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
|
||||
fn bytearray_clear(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(vm, args, required = [(zelf, Some(vm.ctx.bytearray_type()))]);
|
||||
match zelf.payload {
|
||||
PyObjectPayload::Bytes { ref value } => {
|
||||
value.borrow_mut().clear();
|
||||
Ok(vm.get_none())
|
||||
}
|
||||
_ => panic!("Bytearray has incorrect payload."),
|
||||
}
|
||||
get_mut_value(zelf).clear();
|
||||
Ok(vm.get_none())
|
||||
}
|
||||
|
||||
fn bytearray_pop(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
|
||||
@@ -1,16 +1,41 @@
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::cell::Cell;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::ops::Deref;
|
||||
use std::ops::DerefMut;
|
||||
|
||||
use super::objint;
|
||||
use super::objtype;
|
||||
use crate::pyobject::{
|
||||
PyContext, PyFuncArgs, PyObject, PyObjectPayload, PyObjectRef, PyResult, TypeProtocol,
|
||||
PyContext, PyFuncArgs, PyObject, PyObjectPayload, PyObjectPayload2, PyObjectRef, PyResult,
|
||||
TypeProtocol,
|
||||
};
|
||||
use crate::vm::VirtualMachine;
|
||||
use num_traits::ToPrimitive;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PyBytes {
|
||||
value: Vec<u8>,
|
||||
}
|
||||
|
||||
impl PyBytes {
|
||||
pub fn new(data: Vec<u8>) -> Self {
|
||||
PyBytes { value: data }
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for PyBytes {
|
||||
type Target = [u8];
|
||||
|
||||
fn deref(&self) -> &[u8] {
|
||||
&self.value
|
||||
}
|
||||
}
|
||||
|
||||
impl PyObjectPayload2 for PyBytes {
|
||||
fn required_type(ctx: &PyContext) -> PyObjectRef {
|
||||
ctx.bytes_type()
|
||||
}
|
||||
}
|
||||
|
||||
// Binary data support
|
||||
|
||||
// Fill bytes class methods:
|
||||
@@ -71,8 +96,8 @@ fn bytes_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
};
|
||||
|
||||
Ok(PyObject::new(
|
||||
PyObjectPayload::Bytes {
|
||||
value: RefCell::new(value),
|
||||
PyObjectPayload::AnyRustValue {
|
||||
value: Box::new(PyBytes::new(value)),
|
||||
},
|
||||
cls.clone(),
|
||||
))
|
||||
@@ -170,19 +195,7 @@ fn bytes_hash(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
}
|
||||
|
||||
pub fn get_value<'a>(obj: &'a PyObjectRef) -> impl Deref<Target = Vec<u8>> + 'a {
|
||||
if let PyObjectPayload::Bytes { ref value } = obj.payload {
|
||||
value.borrow()
|
||||
} else {
|
||||
panic!("Inner error getting bytearray {:?}", obj);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_mut_value<'a>(obj: &'a PyObjectRef) -> impl DerefMut<Target = Vec<u8>> + 'a {
|
||||
if let PyObjectPayload::Bytes { ref value } = obj.payload {
|
||||
value.borrow_mut()
|
||||
} else {
|
||||
panic!("Inner error getting bytearray {:?}", obj);
|
||||
}
|
||||
&obj.payload::<PyBytes>().unwrap().value
|
||||
}
|
||||
|
||||
fn bytes_repr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
|
||||
@@ -8,6 +8,8 @@ use crate::pyobject::{
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
use super::objbool;
|
||||
use super::objbytearray::PyByteArray;
|
||||
use super::objbytes::PyBytes;
|
||||
use super::objrange::PyRange;
|
||||
use super::objtype;
|
||||
|
||||
@@ -137,6 +139,22 @@ fn iter_next(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
} else {
|
||||
Err(new_stop_iteration(vm))
|
||||
}
|
||||
} else if let Some(bytes) = iterated_obj_ref.payload::<PyBytes>() {
|
||||
if position.get() < bytes.len() {
|
||||
let obj_ref = vm.ctx.new_int(bytes[position.get()]);
|
||||
position.set(position.get() + 1);
|
||||
Ok(obj_ref)
|
||||
} else {
|
||||
Err(new_stop_iteration(vm))
|
||||
}
|
||||
} else if let Some(bytes) = iterated_obj_ref.payload::<PyByteArray>() {
|
||||
if position.get() < bytes.value.borrow().len() {
|
||||
let obj_ref = vm.ctx.new_int(bytes.value.borrow()[position.get()]);
|
||||
position.set(position.get() + 1);
|
||||
Ok(obj_ref)
|
||||
} else {
|
||||
Err(new_stop_iteration(vm))
|
||||
}
|
||||
} else {
|
||||
match iterated_obj_ref.payload {
|
||||
PyObjectPayload::Sequence { ref elements } => {
|
||||
@@ -148,16 +166,6 @@ fn iter_next(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
Err(new_stop_iteration(vm))
|
||||
}
|
||||
}
|
||||
PyObjectPayload::Bytes { ref value } => {
|
||||
if position.get() < value.borrow().len() {
|
||||
let obj_ref = vm.ctx.new_int(value.borrow()[position.get()]);
|
||||
position.set(position.get() + 1);
|
||||
Ok(obj_ref)
|
||||
} else {
|
||||
Err(new_stop_iteration(vm))
|
||||
}
|
||||
}
|
||||
|
||||
_ => {
|
||||
panic!("NOT IMPL");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user