@@ -34,6 +34,70 @@ fn compute_c_flag(mode: &str) -> u16 {
34
34
}
35
35
}
36
36
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
+
37
101
#[ derive( Debug ) ]
38
102
struct PyStringIO {
39
103
data : RefCell < Cursor < Vec < u8 > > > ,
@@ -131,7 +195,7 @@ fn string_io_new(
131
195
132
196
#[ derive( Debug ) ]
133
197
struct PyBytesIO {
134
- data : RefCell < Cursor < Vec < u8 > > > ,
198
+ buffer : RefCell < BufferedIO > ,
135
199
}
136
200
137
201
type PyBytesIORef = PyRef < PyBytesIO > ;
@@ -143,65 +207,36 @@ impl PyValue for PyBytesIO {
143
207
}
144
208
145
209
impl PyBytesIORef {
146
- //write string to underlying vector
147
210
fn write ( self , data : objbytes:: PyBytesRef , vm : & VirtualMachine ) -> PyResult {
148
211
let bytes = data. get_value ( ) ;
149
- let length = bytes. len ( ) ;
150
212
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 ( ) ) ) ,
155
216
}
156
217
}
157
-
158
- //return the entire contents of the underlying
218
+ //Retrieves the entire bytes object value from the underlying buffer
159
219
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 ( ) ) )
175
221
}
176
222
177
- //Read k bytes from the object and return.
223
+ //Takes an integer k ( bytes) and returns them from the underlying buffer
178
224
//If k is undefined || k == -1, then we read all bytes until the end of the file.
179
225
//This also increments the stream position by the value of k
180
226
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
+ }
203
232
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
+ }
205
240
}
206
241
}
207
242
@@ -216,7 +251,7 @@ fn bytes_io_new(
216
251
} ;
217
252
218
253
PyBytesIO {
219
- data : RefCell :: new ( Cursor :: new ( raw_bytes) ) ,
254
+ buffer : RefCell :: new ( BufferedIO :: new ( Cursor :: new ( raw_bytes) ) ) ,
220
255
}
221
256
. into_ref_with_type ( vm, cls)
222
257
}
@@ -729,4 +764,25 @@ mod tests {
729
764
) ;
730
765
}
731
766
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
+ }
732
788
}
0 commit comments