2
2
* I/O core tools.
3
3
*/
4
4
5
+ use std:: collections:: HashSet ;
6
+
5
7
use std:: io:: prelude:: * ;
6
8
use std:: os:: unix:: io:: { FromRawFd , IntoRawFd } ;
7
9
@@ -12,7 +14,7 @@ use super::super::obj::objstr;
12
14
use super :: super :: obj:: objint;
13
15
use super :: super :: obj:: objbytes;
14
16
use super :: super :: obj:: objtype;
15
- use super :: os:: os_open ;
17
+ use super :: os;
16
18
17
19
use num_bigint:: { ToBigInt } ;
18
20
use num_traits:: ToPrimitive ;
@@ -23,6 +25,16 @@ use super::super::pyobject::{
23
25
24
26
use super :: super :: vm:: VirtualMachine ;
25
27
28
+ fn compute_c_flag ( mode : & String ) -> u16 {
29
+ match mode. as_ref ( ) {
30
+ "w" => 512 ,
31
+ "x" => 512 ,
32
+ "a" => 8 ,
33
+ "+" => 2 ,
34
+ _ => 0
35
+ }
36
+ }
37
+
26
38
fn string_io_init ( vm : & mut VirtualMachine , _args : PyFuncArgs ) -> PyResult {
27
39
// arg_check!(vm, args, required = [(s, Some(vm.ctx.str_type()))]);
28
40
// TODO
@@ -71,6 +83,9 @@ fn buffered_reader_read(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
71
83
72
84
let raw = vm. ctx . get_attr ( & buffered, "raw" ) . unwrap ( ) ;
73
85
86
+ //Iterates through the raw class, invoking the readinto method
87
+ //to obtain buff_size many bytes. Exit when less than buff_size many
88
+ //bytes are returned (when the end of the file is reached).
74
89
while length == buff_size {
75
90
let raw_read = vm. get_method ( raw. clone ( ) , & "readinto" . to_string ( ) ) . unwrap ( ) ;
76
91
match vm. invoke ( raw_read, PyFuncArgs :: new ( vec ! [ buffer. clone( ) ] , vec ! [ ] ) ) {
@@ -80,6 +95,7 @@ fn buffered_reader_read(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
80
95
}
81
96
}
82
97
98
+ //Copy bytes from the buffer vector into the results vector
83
99
match buffer. borrow_mut ( ) . kind {
84
100
PyObjectKind :: Bytes { ref mut value } => {
85
101
result. extend ( value. iter ( ) . cloned ( ) ) ;
@@ -103,23 +119,22 @@ fn file_io_init(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
103
119
optional = [ ( mode, Some ( vm. ctx. str_type( ) ) ) ]
104
120
) ;
105
121
106
- let mode = if let Some ( m) = mode {
107
- objstr:: get_value ( m)
108
- } else {
109
- "r" . to_string ( )
110
- } ;
111
-
112
- let os_mode = match mode. as_ref ( ) {
113
- "r" => 0 . to_bigint ( ) ,
114
- _ => 512 . to_bigint ( )
122
+ let rust_mode = match mode {
123
+ Some ( m) => objstr:: get_value ( m) ,
124
+ None => "r" . to_string ( )
115
125
} ;
116
- let args = vec ! [ name. clone( ) , vm. ctx. new_int( os_mode. unwrap( ) ) ] ;
117
- let fileno = os_open ( vm, PyFuncArgs :: new ( args, vec ! [ ] ) ) ;
118
126
127
+ match compute_c_flag ( & rust_mode) . to_bigint ( ) {
128
+ Some ( os_mode) => {
129
+ let args = vec ! [ name. clone( ) , vm. ctx. new_int( os_mode) ] ;
130
+ let fileno = os:: os_open ( vm, PyFuncArgs :: new ( args, vec ! [ ] ) ) ;
119
131
120
- vm. ctx . set_attr ( & file_io, "name" , name. clone ( ) ) ;
121
- vm. ctx . set_attr ( & file_io, "fileno" , fileno. unwrap ( ) ) ;
122
- Ok ( vm. get_none ( ) )
132
+ vm. ctx . set_attr ( & file_io, "name" , name. clone ( ) ) ;
133
+ vm. ctx . set_attr ( & file_io, "fileno" , fileno. unwrap ( ) ) ;
134
+ Ok ( vm. get_none ( ) )
135
+ } ,
136
+ None => Err ( vm. new_type_error ( format ! ( "invalid mode {}" , rust_mode) ) )
137
+ }
123
138
}
124
139
125
140
fn file_io_read ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
@@ -174,7 +189,7 @@ fn file_io_readinto(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
174
189
} ;
175
190
176
191
let mut f = handle. take ( length) ;
177
- match obj. borrow_mut ( ) . kind {
192
+ match obj. borrow_mut ( ) . kind {
178
193
PyObjectKind :: Bytes { ref mut value } => {
179
194
value. clear ( ) ;
180
195
match f. read_to_end ( & mut * value) {
@@ -252,7 +267,6 @@ fn text_io_wrapper_init(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
252
267
Ok ( vm. get_none ( ) )
253
268
}
254
269
255
-
256
270
fn text_io_base_read ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
257
271
arg_check ! (
258
272
vm,
@@ -278,7 +292,7 @@ pub fn io_open(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
278
292
arg_check ! (
279
293
vm,
280
294
args,
281
- required = [ ( _file , Some ( vm. ctx. str_type( ) ) ) ] ,
295
+ required = [ ( file , Some ( vm. ctx. str_type( ) ) ) ] ,
282
296
optional = [ ( mode, Some ( vm. ctx. str_type( ) ) ) ]
283
297
) ;
284
298
@@ -291,6 +305,24 @@ pub fn io_open(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
291
305
"rt" . to_string ( )
292
306
} ;
293
307
308
+ let mut raw_modes = HashSet :: new ( ) ;
309
+
310
+ // Add some books.
311
+ raw_modes. insert ( "a" . to_string ( ) ) ;
312
+ raw_modes. insert ( "r" . to_string ( ) ) ;
313
+ raw_modes. insert ( "x" . to_string ( ) ) ;
314
+ raw_modes. insert ( "w" . to_string ( ) ) ;
315
+
316
+ //This is not a terribly elegant way to separate the file mode from
317
+ //the "type" flag - this should be improved. The intention here is to
318
+ //match a valid flag for the file_io_init call:
319
+ //https://docs.python.org/3/library/io.html#io.FileIO
320
+ let modes: Vec < char > = rust_mode. chars ( ) . filter ( |a| raw_modes. contains ( & a. to_string ( ) ) ) . collect ( ) ;
321
+
322
+ if modes. len ( ) == 0 || modes. len ( ) > 1 {
323
+ return Err ( vm. new_value_error ( "Invalid Mode" . to_string ( ) ) )
324
+ }
325
+
294
326
//Class objects (potentially) consumed by io.open
295
327
//RawIO: FileIO
296
328
//Buffered: BufferedWriter, BufferedReader
@@ -302,7 +334,8 @@ pub fn io_open(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
302
334
303
335
//Construct a FileIO (subclass of RawIOBase)
304
336
//This is subsequently consumed by a Buffered Class.
305
- let file_io = vm. invoke ( file_io_class, args. clone ( ) ) . unwrap ( ) ;
337
+ let file_args = PyFuncArgs :: new ( vec ! [ file. clone( ) , vm. ctx. new_str( modes[ 0 ] . to_string( ) ) ] , vec ! [ ] ) ;
338
+ let file_io = vm. invoke ( file_io_class, file_args) . unwrap ( ) ;
306
339
307
340
//Create Buffered class to consume FileIO. The type of buffered class depends on
308
341
//the operation in the mode.
0 commit comments