|
1 | 1 | use super::{
|
2 |
| - PyBytes, PyBytesRef, PyList, PyListRef, PySlice, PyStr, PyStrRef, PyTuple, PyTupleRef, |
3 |
| - PyTypeRef, |
| 2 | + PyBytes, PyBytesRef, PyListRef, PySlice, PyStr, PyStrRef, PyTuple, PyTupleRef, PyTypeRef, |
4 | 3 | };
|
5 | 4 | use crate::common::{
|
6 | 5 | borrow::{BorrowedValue, BorrowedValueMut},
|
@@ -94,7 +93,7 @@ impl PyMemoryView {
|
94 | 93 | let mut zelf = PyMemoryView {
|
95 | 94 | buffer: ManuallyDrop::new(buffer),
|
96 | 95 | released: AtomicCell::new(false),
|
97 |
| - start: range.start, |
| 96 | + start: 0, |
98 | 97 | format_spec,
|
99 | 98 | desc,
|
100 | 99 | hash: OnceCell::new(),
|
@@ -363,10 +362,12 @@ impl PyMemoryView {
|
363 | 362 |
|
364 | 363 | let mut bytes_mut = dest.buffer.obj_bytes_mut();
|
365 | 364 | let src_bytes = src.obj_bytes();
|
366 |
| - dest.desc.zip_eq(&src.desc, true, |a_pos, b_pos, len| { |
367 |
| - let a_pos = (a_pos + self.start as isize) as usize; |
368 |
| - let b_pos = b_pos as usize; |
369 |
| - bytes_mut[a_pos..a_pos + len].copy_from_slice(&src_bytes[b_pos..b_pos + len]); |
| 365 | + dest.desc.zip_eq(&src.desc, true, |a_range, b_range| { |
| 366 | + let a_range = (a_range.start + self.start as isize) as usize |
| 367 | + ..(a_range.end + self.start as isize) as usize; |
| 368 | + let b_range = b_range.start as usize..b_range.end as usize; |
| 369 | + bytes_mut[a_range].copy_from_slice(&src_bytes[b_range]); |
| 370 | + false |
370 | 371 | });
|
371 | 372 |
|
372 | 373 | Ok(())
|
@@ -418,8 +419,8 @@ impl PyMemoryView {
|
418 | 419 | }
|
419 | 420 |
|
420 | 421 | fn init_len(&mut self) {
|
421 |
| - let product = self.desc.dim_desc.iter().map(|x| x.0).product(); |
422 |
| - self.desc.len = product; |
| 422 | + let product: usize = self.desc.dim_desc.iter().map(|x| x.0).product(); |
| 423 | + self.desc.len = product * self.desc.itemsize; |
423 | 424 | }
|
424 | 425 |
|
425 | 426 | fn init_range(&mut self, range: Range<usize>, dim: usize) {
|
@@ -523,11 +524,14 @@ impl PyMemoryView {
|
523 | 524 | #[pymethod]
|
524 | 525 | fn tolist(&self, vm: &VirtualMachine) -> PyResult<PyListRef> {
|
525 | 526 | self.try_not_released(vm)?;
|
| 527 | + let bytes = self.buffer.obj_bytes(); |
526 | 528 | if self.desc.ndim() == 0 {
|
527 |
| - // TODO: unpack_single(view->buf, fmt) |
528 |
| - return Ok(vm.ctx.new_list(vec![])); |
| 529 | + return Ok(vm.ctx.new_list(vec![format_unpack( |
| 530 | + &self.format_spec, |
| 531 | + &bytes[..self.desc.itemsize], |
| 532 | + vm, |
| 533 | + )?])); |
529 | 534 | }
|
530 |
| - let bytes = self.buffer.obj_bytes(); |
531 | 535 | self._to_list(&bytes, 0, 0, vm)
|
532 | 536 | }
|
533 | 537 |
|
@@ -693,15 +697,36 @@ impl PyMemoryView {
|
693 | 697 | return Ok(vm.bool_eq(&a_val, &b_val)?);
|
694 | 698 | }
|
695 | 699 |
|
696 |
| - zelf.contiguous_or_collect(|a| { |
697 |
| - other.contiguous_or_collect(|b| { |
698 |
| - // TODO: optimize cmp by format |
699 |
| - let a_list = unpack_bytes_seq_to_list(a, a_format_spec, vm)?; |
700 |
| - let b_list = unpack_bytes_seq_to_list(b, b_format_spec, vm)?; |
701 |
| - |
702 |
| - vm.bool_eq(a_list.as_object(), b_list.as_object()) |
703 |
| - }) |
704 |
| - }) |
| 700 | + // TODO: optimize cmp by format |
| 701 | + let mut ret = Ok(true); |
| 702 | + let a_bytes = zelf.buffer.obj_bytes(); |
| 703 | + let b_bytes = other.obj_bytes(); |
| 704 | + zelf.desc.zip_eq(&other.desc, false, |a_range, b_range| { |
| 705 | + let a_range = (a_range.start + zelf.start as isize) as usize |
| 706 | + ..(a_range.end + zelf.start as isize) as usize; |
| 707 | + let b_range = b_range.start as usize..b_range.end as usize; |
| 708 | + let a_val = match format_unpack(&a_format_spec, &a_bytes[a_range], vm) { |
| 709 | + Ok(val) => val, |
| 710 | + Err(e) => { |
| 711 | + ret = Err(e); |
| 712 | + return true; |
| 713 | + } |
| 714 | + }; |
| 715 | + let b_val = match format_unpack(&b_format_spec, &b_bytes[b_range], vm) { |
| 716 | + Ok(val) => val, |
| 717 | + Err(e) => { |
| 718 | + ret = Err(e); |
| 719 | + return true; |
| 720 | + } |
| 721 | + }; |
| 722 | + ret = vm.bool_eq(&a_val, &b_val); |
| 723 | + if let Ok(b) = ret { |
| 724 | + !b |
| 725 | + } else { |
| 726 | + true |
| 727 | + } |
| 728 | + }); |
| 729 | + ret |
705 | 730 | }
|
706 | 731 |
|
707 | 732 | #[pymethod(magic)]
|
@@ -900,26 +925,6 @@ fn format_unpack(
|
900 | 925 | })
|
901 | 926 | }
|
902 | 927 |
|
903 |
| -fn unpack_bytes_seq_to_list( |
904 |
| - bytes: &[u8], |
905 |
| - format_spec: &FormatSpec, |
906 |
| - vm: &VirtualMachine, |
907 |
| -) -> PyResult<PyListRef> { |
908 |
| - let itemsize = format_spec.size(); |
909 |
| - |
910 |
| - if bytes.len() % itemsize != 0 { |
911 |
| - return Err(vm.new_value_error("bytes length not a multiple of item size".to_owned())); |
912 |
| - } |
913 |
| - |
914 |
| - let len = bytes.len() / itemsize; |
915 |
| - |
916 |
| - let elements: Vec<PyObjectRef> = (0..len) |
917 |
| - .map(|i| format_unpack(&format_spec, &bytes[i..i + itemsize], vm)) |
918 |
| - .try_collect()?; |
919 |
| - |
920 |
| - Ok(PyList::from(elements).into_ref(vm)) |
921 |
| -} |
922 |
| - |
923 | 928 | fn is_equiv_shape(a: &BufferDescriptor, b: &BufferDescriptor) -> bool {
|
924 | 929 | if a.ndim() != b.ndim() {
|
925 | 930 | return false;
|
|
0 commit comments