@@ -9,6 +9,7 @@ use crate::bytesinner::bytes_to_hex;
99use crate :: common:: borrow:: { BorrowedValue , BorrowedValueMut } ;
1010use crate :: common:: hash:: PyHash ;
1111use crate :: common:: lock:: OnceCell ;
12+ use crate :: common:: rc:: PyRc ;
1213use crate :: function:: OptionalArg ;
1314use crate :: pyobject:: {
1415 Either , IdProtocol , IntoPyObject , PyClassImpl , PyComparisonValue , PyContext , PyObjectRef ,
@@ -41,12 +42,55 @@ impl BufferRef {
4142 pub fn new ( buffer : impl Buffer + ' static ) -> Self {
4243 Self ( Box :: new ( buffer) )
4344 }
45+ pub fn into_rcbuf ( self ) -> RcBuffer {
46+ // move self.0 out of self; BufferRef impls Drop so it's tricky
47+ let this = std:: mem:: ManuallyDrop :: new ( self ) ;
48+ let buf_box = unsafe { std:: ptr:: read ( & this. 0 ) } ;
49+ RcBuffer ( buf_box. into ( ) )
50+ }
4451}
4552impl From < Box < dyn Buffer > > for BufferRef {
4653 fn from ( buffer : Box < dyn Buffer > ) -> Self {
4754 BufferRef ( buffer)
4855 }
4956}
57+ #[ derive( Debug , Clone ) ]
58+ pub struct RcBuffer ( PyRc < dyn Buffer > ) ;
59+ impl Deref for RcBuffer {
60+ type Target = dyn Buffer ;
61+ fn deref ( & self ) -> & Self :: Target {
62+ self . 0 . deref ( )
63+ }
64+ }
65+ impl Drop for RcBuffer {
66+ fn drop ( & mut self ) {
67+ // check if this is the last rc before the inner buffer gets dropped
68+ if let Some ( buf) = PyRc :: get_mut ( & mut self . 0 ) {
69+ buf. release ( )
70+ }
71+ }
72+ }
73+ impl Buffer for RcBuffer {
74+ fn get_options ( & self ) -> BorrowedValue < BufferOptions > {
75+ self . 0 . get_options ( )
76+ }
77+ fn obj_bytes ( & self ) -> BorrowedValue < [ u8 ] > {
78+ self . 0 . obj_bytes ( )
79+ }
80+ fn obj_bytes_mut ( & self ) -> BorrowedValueMut < [ u8 ] > {
81+ self . 0 . obj_bytes_mut ( )
82+ }
83+ fn release ( & self ) { }
84+ fn as_contiguous ( & self ) -> Option < BorrowedValue < [ u8 ] > > {
85+ self . 0 . as_contiguous ( )
86+ }
87+ fn as_contiguous_mut ( & self ) -> Option < BorrowedValueMut < [ u8 ] > > {
88+ self . 0 . as_contiguous_mut ( )
89+ }
90+ fn to_contiguous ( & self ) -> Vec < u8 > {
91+ self . 0 . to_contiguous ( )
92+ }
93+ }
5094
5195pub trait Buffer : Debug + PyThreadingConstraint {
5296 fn get_options ( & self ) -> BorrowedValue < BufferOptions > ;
@@ -168,6 +212,29 @@ impl PyMemoryView {
168212 } )
169213 }
170214
215+ pub fn from_buffer_range (
216+ obj : PyObjectRef ,
217+ buffer : BufferRef ,
218+ range : std:: ops:: Range < usize > ,
219+ vm : & VirtualMachine ,
220+ ) -> PyResult < Self > {
221+ let options = buffer. get_options ( ) . clone ( ) ;
222+ let itemsize = options. itemsize ;
223+ let format_spec = Self :: parse_format ( & options. format , vm) ?;
224+ Ok ( PyMemoryView {
225+ obj,
226+ buffer,
227+ options,
228+ released : AtomicCell :: new ( false ) ,
229+ start : range. start * itemsize,
230+ stop : range. end * itemsize,
231+ step : 1 ,
232+ exports : AtomicCell :: new ( 0 ) ,
233+ format_spec,
234+ hash : OnceCell :: new ( ) ,
235+ } )
236+ }
237+
171238 pub fn try_bytes < F , R > ( & self , vm : & VirtualMachine , f : F ) -> PyResult < R >
172239 where
173240 F : FnOnce ( & [ u8 ] ) -> R ,
0 commit comments