@@ -15,50 +15,67 @@ use crate::sliceable::{convert_slice, saturate_range, wrap_index, SequenceIndex}
1515use crate :: slots:: { BufferProtocol , Comparable , Hashable , PyComparisonOp } ;
1616use crate :: stdlib:: pystruct:: _struct:: FormatSpec ;
1717use crate :: utils:: Either ;
18- use crate :: VirtualMachine ;
1918use crate :: {
2019 IdProtocol , IntoPyObject , PyClassImpl , PyComparisonValue , PyContext , PyObjectRef , PyRef ,
2120 PyResult , PyThreadingConstraint , PyValue , TypeProtocol ,
2221} ;
22+ use crate :: { TryFromObject , VirtualMachine } ;
2323use crossbeam_utils:: atomic:: AtomicCell ;
2424use itertools:: Itertools ;
2525use num_bigint:: BigInt ;
2626use num_traits:: { One , Signed , ToPrimitive , Zero } ;
2727
2828#[ derive( Debug ) ]
29- pub struct BufferRef ( Box < dyn Buffer > ) ;
30- impl Drop for BufferRef {
29+ pub struct PyBufferRef ( Box < dyn PyBuffer > ) ;
30+
31+ impl TryFromObject for PyBufferRef {
32+ // FIXME: `obj: &PyObjectRef` is enough
33+ fn try_from_object ( vm : & VirtualMachine , obj : PyObjectRef ) -> PyResult < Self > {
34+ let obj_cls = obj. class ( ) ;
35+ for cls in obj_cls. iter_mro ( ) {
36+ if let Some ( f) = cls. slots . as_buffer . as_ref ( ) {
37+ return f ( & obj, vm) . map ( |x| PyBufferRef ( x) ) ;
38+ }
39+ }
40+ Err ( vm. new_type_error ( format ! (
41+ "a bytes-like object is required, not '{}'" ,
42+ obj_cls. name
43+ ) ) )
44+ }
45+ }
46+
47+ impl Drop for PyBufferRef {
3148 fn drop ( & mut self ) {
3249 self . 0 . release ( ) ;
3350 }
3451}
35- impl Deref for BufferRef {
36- type Target = dyn Buffer ;
52+ impl Deref for PyBufferRef {
53+ type Target = dyn PyBuffer ;
3754
3855 fn deref ( & self ) -> & Self :: Target {
3956 self . 0 . deref ( )
4057 }
4158}
42- impl BufferRef {
43- pub fn new ( buffer : impl Buffer + ' static ) -> Self {
59+ impl PyBufferRef {
60+ pub fn new ( buffer : impl PyBuffer + ' static ) -> Self {
4461 Self ( Box :: new ( buffer) )
4562 }
4663 pub fn into_rcbuf ( self ) -> RcBuffer {
47- // move self.0 out of self; BufferRef impls Drop so it's tricky
64+ // move self.0 out of self; PyBufferRef impls Drop so it's tricky
4865 let this = std:: mem:: ManuallyDrop :: new ( self ) ;
4966 let buf_box = unsafe { std:: ptr:: read ( & this. 0 ) } ;
5067 RcBuffer ( buf_box. into ( ) )
5168 }
5269}
53- impl From < Box < dyn Buffer > > for BufferRef {
54- fn from ( buffer : Box < dyn Buffer > ) -> Self {
55- BufferRef ( buffer)
70+ impl From < Box < dyn PyBuffer > > for PyBufferRef {
71+ fn from ( buffer : Box < dyn PyBuffer > ) -> Self {
72+ PyBufferRef ( buffer)
5673 }
5774}
5875#[ derive( Debug , Clone ) ]
59- pub struct RcBuffer ( PyRc < dyn Buffer > ) ;
76+ pub struct RcBuffer ( PyRc < dyn PyBuffer > ) ;
6077impl Deref for RcBuffer {
61- type Target = dyn Buffer ;
78+ type Target = dyn PyBuffer ;
6279 fn deref ( & self ) -> & Self :: Target {
6380 self . 0 . deref ( )
6481 }
@@ -71,7 +88,7 @@ impl Drop for RcBuffer {
7188 }
7289 }
7390}
74- impl Buffer for RcBuffer {
91+ impl PyBuffer for RcBuffer {
7592 fn get_options ( & self ) -> & BufferOptions {
7693 self . 0 . get_options ( )
7794 }
@@ -93,7 +110,7 @@ impl Buffer for RcBuffer {
93110 }
94111}
95112
96- pub trait Buffer : Debug + PyThreadingConstraint {
113+ pub trait PyBuffer : Debug + PyThreadingConstraint {
97114 fn get_options ( & self ) -> & BufferOptions ;
98115 /// Get the full inner buffer of this memory. You probably want [`as_contiguous()`], as
99116 /// `obj_bytes` doesn't take into account the range a memoryview might operate on, among other
@@ -171,7 +188,7 @@ struct PyMemoryViewNewArgs {
171188#[ derive( Debug ) ]
172189pub struct PyMemoryView {
173190 obj : PyObjectRef ,
174- buffer : BufferRef ,
191+ buffer : PyBufferRef ,
175192 options : BufferOptions ,
176193 pub ( crate ) released : AtomicCell < bool > ,
177194 // start should always less or equal to the stop
@@ -195,7 +212,11 @@ impl PyMemoryView {
195212 . map_err ( |msg| vm. new_exception_msg ( vm. ctx . types . memoryview_type . clone ( ) , msg) )
196213 }
197214
198- pub fn from_buffer ( obj : PyObjectRef , buffer : BufferRef , vm : & VirtualMachine ) -> PyResult < Self > {
215+ pub fn from_buffer (
216+ obj : PyObjectRef ,
217+ buffer : PyBufferRef ,
218+ vm : & VirtualMachine ,
219+ ) -> PyResult < Self > {
199220 // when we get a buffer means the buffered object is size locked
200221 // so we can assume the buffer's options will never change as long
201222 // as memoryview is still alive
@@ -219,7 +240,7 @@ impl PyMemoryView {
219240
220241 pub fn from_buffer_range (
221242 obj : PyObjectRef ,
222- buffer : BufferRef ,
243+ buffer : PyBufferRef ,
223244 range : std:: ops:: Range < usize > ,
224245 vm : & VirtualMachine ,
225246 ) -> PyResult < Self > {
@@ -256,7 +277,7 @@ impl PyMemoryView {
256277 args : PyMemoryViewNewArgs ,
257278 vm : & VirtualMachine ,
258279 ) -> PyResult < PyRef < Self > > {
259- let buffer = try_buffer_from_object ( vm, & args. object ) ?;
280+ let buffer = PyBufferRef :: try_from_object ( vm, args. object . clone ( ) ) ?;
260281 let zelf = PyMemoryView :: from_buffer ( args. object , buffer, vm) ?;
261282 zelf. into_ref_with_type ( vm, cls)
262283 }
@@ -373,7 +394,7 @@ impl PyMemoryView {
373394 let itemsize = zelf. options . itemsize ;
374395
375396 let obj = zelf. obj . clone ( ) ;
376- let buffer = BufferRef ( Box :: new ( zelf. clone ( ) ) ) ;
397+ let buffer = PyBufferRef ( Box :: new ( zelf. clone ( ) ) ) ;
377398 zelf. exports . fetch_add ( 1 ) ;
378399 let options = zelf. options . clone ( ) ;
379400 let format_spec = zelf. format_spec . clone ( ) ;
@@ -517,7 +538,7 @@ impl PyMemoryView {
517538 items : PyObjectRef ,
518539 vm : & VirtualMachine ,
519540 ) -> PyResult < ( ) > {
520- let items = try_buffer_from_object ( vm, & items) ?;
541+ let items = PyBufferRef :: try_from_object ( vm, items) ?;
521542 let options = items. get_options ( ) ;
522543 let len = options. len ;
523544 let itemsize = options. itemsize ;
@@ -660,7 +681,7 @@ impl PyMemoryView {
660681 #[ pymethod]
661682 fn toreadonly ( zelf : PyRef < Self > , vm : & VirtualMachine ) -> PyResult < PyRef < Self > > {
662683 zelf. try_not_released ( vm) ?;
663- let buffer = BufferRef ( Box :: new ( zelf. clone ( ) ) ) ;
684+ let buffer = PyBufferRef ( Box :: new ( zelf. clone ( ) ) ) ;
664685 zelf. exports . fetch_add ( 1 ) ;
665686 Ok ( PyMemoryView {
666687 obj : zelf. obj . clone ( ) ,
@@ -731,7 +752,7 @@ impl PyMemoryView {
731752 ) ;
732753 }
733754
734- let buffer = BufferRef ( Box :: new ( zelf. clone ( ) ) ) ;
755+ let buffer = PyBufferRef ( Box :: new ( zelf. clone ( ) ) ) ;
735756 zelf. exports . fetch_add ( 1 ) ;
736757
737758 Ok ( PyMemoryView {
@@ -761,7 +782,7 @@ impl PyMemoryView {
761782 return Ok ( false ) ;
762783 }
763784
764- let other = match try_buffer_from_object ( vm, other) {
785+ let other = match PyBufferRef :: try_from_object ( vm, other. clone ( ) ) {
765786 Ok ( buf) => buf,
766787 Err ( _) => return Ok ( false ) ,
767788 } ;
@@ -829,7 +850,7 @@ impl Drop for PyMemoryView {
829850}
830851
831852impl BufferProtocol for PyMemoryView {
832- fn get_buffer ( zelf : & PyRef < Self > , vm : & VirtualMachine ) -> PyResult < Box < dyn Buffer > > {
853+ fn get_buffer ( zelf : & PyRef < Self > , vm : & VirtualMachine ) -> PyResult < Box < dyn PyBuffer > > {
833854 if zelf. released . load ( ) {
834855 Err ( vm. new_value_error ( "operation forbidden on released memoryview object" . to_owned ( ) ) )
835856 } else {
@@ -838,7 +859,7 @@ impl BufferProtocol for PyMemoryView {
838859 }
839860}
840861
841- impl Buffer for PyMemoryViewRef {
862+ impl PyBuffer for PyMemoryViewRef {
842863 fn get_options ( & self ) -> & BufferOptions {
843864 & self . options
844865 }
@@ -940,19 +961,6 @@ pub(crate) fn init(ctx: &PyContext) {
940961 PyMemoryView :: extend_class ( ctx, & ctx. types . memoryview_type )
941962}
942963
943- pub fn try_buffer_from_object ( vm : & VirtualMachine , obj : & PyObjectRef ) -> PyResult < BufferRef > {
944- let obj_cls = obj. class ( ) ;
945- for cls in obj_cls. iter_mro ( ) {
946- if let Some ( f) = cls. slots . buffer . as_ref ( ) {
947- return f ( obj, vm) . map ( |x| BufferRef ( x) ) ;
948- }
949- }
950- Err ( vm. new_type_error ( format ! (
951- "a bytes-like object is required, not '{}'" ,
952- obj_cls. name
953- ) ) )
954- }
955-
956964fn format_unpack (
957965 format_spec : & FormatSpec ,
958966 bytes : & [ u8 ] ,
0 commit comments