@@ -34,6 +34,70 @@ fn compute_c_flag(mode: &str) -> u16 {
3434 }
3535}
3636
37+ fn byte_count ( bytes : OptionalArg < Option < PyObjectRef > > ) -> i64 {
38+ match bytes {
39+ OptionalArg :: Present ( Some ( ref int) ) => objint:: get_value ( int) . to_i64 ( ) . unwrap ( ) ,
40+ _ => ( -1 as i64 ) ,
41+ }
42+ }
43+
44+ #[ derive( Debug ) ]
45+ struct BufferedIO {
46+ cursor : Cursor < Vec < u8 > > ,
47+ }
48+
49+ impl BufferedIO {
50+ fn new ( cursor : Cursor < Vec < u8 > > ) -> BufferedIO {
51+ BufferedIO { cursor : cursor }
52+ }
53+
54+ fn write ( & mut self , data : Vec < u8 > ) -> Option < u64 > {
55+ let length = data. len ( ) ;
56+
57+ match self . cursor . write_all ( & data) {
58+ Ok ( _) => Some ( length as u64 ) ,
59+ Err ( _) => None ,
60+ }
61+ }
62+
63+ //return the entire contents of the underlying
64+ fn getvalue ( & self ) -> Vec < u8 > {
65+ self . cursor . clone ( ) . into_inner ( )
66+ }
67+
68+ //skip to the jth position
69+ fn seek ( & mut self , offset : u64 ) -> Option < u64 > {
70+ match self . cursor . seek ( SeekFrom :: Start ( offset. clone ( ) ) ) {
71+ Ok ( _) => Some ( offset) ,
72+ Err ( _) => None ,
73+ }
74+ }
75+
76+ //Read k bytes from the object and return.
77+ fn read ( & mut self , bytes : i64 ) -> Option < Vec < u8 > > {
78+ let mut buffer = Vec :: new ( ) ;
79+
80+ //for a defined number of bytes, i.e. bytes != -1
81+ if bytes > 0 {
82+ let mut handle = self . cursor . clone ( ) . take ( bytes as u64 ) ;
83+ //read handle into buffer
84+ if let Err ( _) = handle. read_to_end ( & mut buffer) {
85+ return None ;
86+ }
87+ //the take above consumes the struct value
88+ //we add this back in with the takes into_inner method
89+ self . cursor = handle. into_inner ( ) ;
90+ } else {
91+ //read handle into buffer
92+ if let Err ( _) = self . cursor . read_to_end ( & mut buffer) {
93+ return None ;
94+ }
95+ } ;
96+
97+ Some ( buffer)
98+ }
99+ }
100+
37101#[ derive( Debug ) ]
38102struct PyStringIO {
39103 data : RefCell < Cursor < Vec < u8 > > > ,
@@ -131,7 +195,7 @@ fn string_io_new(
131195
132196#[ derive( Debug ) ]
133197struct PyBytesIO {
134- data : RefCell < Cursor < Vec < u8 > > > ,
198+ buffer : RefCell < BufferedIO > ,
135199}
136200
137201type PyBytesIORef = PyRef < PyBytesIO > ;
@@ -143,65 +207,36 @@ impl PyValue for PyBytesIO {
143207}
144208
145209impl PyBytesIORef {
146- //write string to underlying vector
147210 fn write ( self , data : objbytes:: PyBytesRef , vm : & VirtualMachine ) -> PyResult {
148211 let bytes = data. get_value ( ) ;
149- let length = bytes. len ( ) ;
150212
151- let mut cursor = self . data . borrow_mut ( ) ;
152- match cursor. write_all ( bytes) {
153- Ok ( _) => Ok ( vm. ctx . new_int ( length) ) ,
154- Err ( _) => Err ( vm. new_type_error ( "Error Writing String" . to_string ( ) ) ) ,
213+ match self . buffer . borrow_mut ( ) . write ( bytes. to_vec ( ) ) {
214+ Some ( value) => Ok ( vm. ctx . new_int ( value) ) ,
215+ None => Err ( vm. new_type_error ( "Error Writing Bytes" . to_string ( ) ) ) ,
155216 }
156217 }
157-
158- //return the entire contents of the underlying
218+ //Retrieves the entire bytes object value from the underlying buffer
159219 fn getvalue ( self , vm : & VirtualMachine ) -> PyResult {
160- Ok ( vm. ctx . new_bytes ( self . data . borrow ( ) . clone ( ) . into_inner ( ) ) )
161- }
162-
163- //skip to the jth position
164- fn seek ( self , offset : PyObjectRef , vm : & VirtualMachine ) -> PyResult {
165- let position = objint:: get_value ( & offset) . to_u64 ( ) . unwrap ( ) ;
166- if let Err ( _) = self
167- . data
168- . borrow_mut ( )
169- . seek ( SeekFrom :: Start ( position. clone ( ) ) )
170- {
171- return Err ( vm. new_value_error ( "Error Retrieving Value" . to_string ( ) ) ) ;
172- }
173-
174- Ok ( vm. ctx . new_int ( position) )
220+ Ok ( vm. ctx . new_bytes ( self . buffer . borrow ( ) . getvalue ( ) ) )
175221 }
176222
177- //Read k bytes from the object and return.
223+ //Takes an integer k ( bytes) and returns them from the underlying buffer
178224 //If k is undefined || k == -1, then we read all bytes until the end of the file.
179225 //This also increments the stream position by the value of k
180226 fn read ( self , bytes : OptionalArg < Option < PyObjectRef > > , vm : & VirtualMachine ) -> PyResult {
181- let mut buffer = Vec :: new ( ) ;
182-
183- match bytes {
184- OptionalArg :: Present ( Some ( ref integer) ) => {
185- let k = objint:: get_value ( integer) . to_u64 ( ) . unwrap ( ) ;
186- let mut handle = self . data . borrow ( ) . clone ( ) . take ( k) ;
187-
188- //read bytes into string
189- if let Err ( _) = handle. read_to_end ( & mut buffer) {
190- return Err ( vm. new_value_error ( "Error Retrieving Value" . to_string ( ) ) ) ;
191- }
192-
193- //the take above consumes the struct value
194- //we add this back in with the takes into_inner method
195- self . data . replace ( handle. into_inner ( ) ) ;
196- }
197- _ => {
198- if let Err ( _) = self . data . borrow_mut ( ) . read_to_end ( & mut buffer) {
199- return Err ( vm. new_value_error ( "Error Retrieving Value" . to_string ( ) ) ) ;
200- }
201- }
202- } ;
227+ match self . buffer . borrow_mut ( ) . read ( byte_count ( bytes) ) {
228+ Some ( value) => Ok ( vm. ctx . new_bytes ( value) ) ,
229+ None => Err ( vm. new_value_error ( "Error Retrieving Value" . to_string ( ) ) ) ,
230+ }
231+ }
203232
204- Ok ( vm. ctx . new_bytes ( buffer) )
233+ //skip to the jth position
234+ fn seek ( self , offset : PyObjectRef , vm : & VirtualMachine ) -> PyResult {
235+ let position = objint:: get_value ( & offset) . to_u64 ( ) . unwrap ( ) ;
236+ match self . buffer . borrow_mut ( ) . seek ( position) {
237+ Some ( value) => Ok ( vm. ctx . new_int ( value) ) ,
238+ None => Err ( vm. new_value_error ( "Error Performing Operation" . to_string ( ) ) ) ,
239+ }
205240 }
206241}
207242
@@ -216,7 +251,7 @@ fn bytes_io_new(
216251 } ;
217252
218253 PyBytesIO {
219- data : RefCell :: new ( Cursor :: new ( raw_bytes) ) ,
254+ buffer : RefCell :: new ( BufferedIO :: new ( Cursor :: new ( raw_bytes) ) ) ,
220255 }
221256 . into_ref_with_type ( vm, cls)
222257}
@@ -729,4 +764,25 @@ mod tests {
729764 ) ;
730765 }
731766
767+ #[ test]
768+ fn test_buffered_read ( ) {
769+ let data = vec ! [ 1 , 2 , 3 , 4 ] ;
770+ let bytes: i64 = -1 ;
771+ let mut buffered = BufferedIO {
772+ cursor : Cursor :: new ( data. clone ( ) ) ,
773+ } ;
774+
775+ assert_eq ! ( buffered. read( bytes) . unwrap( ) , data) ;
776+ }
777+
778+ #[ test]
779+ fn test_buffered_seek ( ) {
780+ let data = vec ! [ 1 , 2 , 3 , 4 ] ;
781+ let offset: u64 = 2 ;
782+ let mut buffered = BufferedIO {
783+ cursor : Cursor :: new ( data. clone ( ) ) ,
784+ } ;
785+
786+ assert_eq ! ( buffered. seek( offset. clone( ) ) . unwrap( ) , offset) ;
787+ }
732788}
0 commit comments