7
7
8
8
use clap:: { crate_version, Arg , ArgAction , Command } ;
9
9
use std:: fs:: File ;
10
- use std:: io:: { self , ErrorKind , Read , Stdin } ;
11
- use std:: path:: Path ;
10
+ use std:: io:: { self , ErrorKind , Read } ;
11
+ use std:: path:: { Path , PathBuf } ;
12
12
use uucore:: display:: Quotable ;
13
13
use uucore:: encoding:: {
14
- for_fast_encode :: { BASE32 , BASE32HEX , BASE64 , BASE64URL , HEXUPPER } ,
14
+ for_base_common :: { BASE32 , BASE32HEX , BASE64 , BASE64URL , HEXUPPER } ,
15
15
Format , Z85Wrapper , BASE2LSBF , BASE2MSBF ,
16
16
} ;
17
17
use uucore:: encoding:: { EncodingWrapper , SupportsFastDecodeAndEncode } ;
@@ -31,7 +31,7 @@ pub struct Config {
31
31
pub decode : bool ,
32
32
pub ignore_garbage : bool ,
33
33
pub wrap_cols : Option < usize > ,
34
- pub to_read : Option < String > ,
34
+ pub to_read : Option < PathBuf > ,
35
35
}
36
36
37
37
pub mod options {
@@ -43,9 +43,10 @@ pub mod options {
43
43
44
44
impl Config {
45
45
pub fn from ( options : & clap:: ArgMatches ) -> UResult < Self > {
46
- let file : Option < String > = match options. get_many :: < String > ( options:: FILE ) {
46
+ let to_read = match options. get_many :: < String > ( options:: FILE ) {
47
47
Some ( mut values) => {
48
48
let name = values. next ( ) . unwrap ( ) ;
49
+
49
50
if let Some ( extra_op) = values. next ( ) {
50
51
return Err ( UUsageError :: new (
51
52
BASE_CMD_PARSE_ERROR ,
@@ -56,19 +57,22 @@ impl Config {
56
57
if name == "-" {
57
58
None
58
59
} else {
59
- if !Path :: exists ( Path :: new ( name) ) {
60
+ let path = Path :: new ( name) ;
61
+
62
+ if !path. exists ( ) {
60
63
return Err ( USimpleError :: new (
61
64
BASE_CMD_PARSE_ERROR ,
62
- format ! ( "{}: No such file or directory" , name . maybe_quote( ) ) ,
65
+ format ! ( "{}: No such file or directory" , path . maybe_quote( ) ) ,
63
66
) ) ;
64
67
}
65
- Some ( name. clone ( ) )
68
+
69
+ Some ( path. to_owned ( ) )
66
70
}
67
71
}
68
72
None => None ,
69
73
} ;
70
74
71
- let cols = options
75
+ let wrap_cols = options
72
76
. get_one :: < String > ( options:: WRAP )
73
77
. map ( |num| {
74
78
num. parse :: < usize > ( ) . map_err ( |_| {
@@ -83,8 +87,8 @@ impl Config {
83
87
Ok ( Self {
84
88
decode : options. get_flag ( options:: DECODE ) ,
85
89
ignore_garbage : options. get_flag ( options:: IGNORE_GARBAGE ) ,
86
- wrap_cols : cols ,
87
- to_read : file ,
90
+ wrap_cols,
91
+ to_read,
88
92
} )
89
93
}
90
94
}
@@ -139,42 +143,43 @@ pub fn base_app(about: &'static str, usage: &str) -> Command {
139
143
)
140
144
}
141
145
142
- pub fn get_input < ' a > ( config : & Config , stdin_ref : & ' a Stdin ) -> UResult < Box < dyn Read + ' a > > {
146
+ pub fn get_input ( config : & Config ) -> UResult < Box < dyn Read > > {
143
147
match & config. to_read {
144
- Some ( name ) => {
148
+ Some ( path_buf ) => {
145
149
// Do not buffer input, because buffering is handled by `fast_decode` and `fast_encode`
146
- let file_buf =
147
- File :: open ( Path :: new ( name) ) . map_err_context ( || name. maybe_quote ( ) . to_string ( ) ) ?;
148
- Ok ( Box :: new ( file_buf) )
150
+ let file =
151
+ File :: open ( path_buf) . map_err_context ( || path_buf. maybe_quote ( ) . to_string ( ) ) ?;
152
+
153
+ Ok ( Box :: new ( file) )
154
+ }
155
+ None => {
156
+ let stdin_lock = io:: stdin ( ) . lock ( ) ;
157
+
158
+ Ok ( Box :: new ( stdin_lock) )
149
159
}
150
- None => Ok ( Box :: new ( stdin_ref. lock ( ) ) ) ,
151
160
}
152
161
}
153
162
154
- pub fn handle_input < R : Read > (
155
- input : & mut R ,
156
- format : Format ,
157
- wrap : Option < usize > ,
158
- ignore_garbage : bool ,
159
- decode : bool ,
160
- ) -> UResult < ( ) > {
163
+ pub fn handle_input < R : Read > ( input : & mut R , format : Format , config : Config ) -> UResult < ( ) > {
161
164
let supports_fast_decode_and_encode = get_supports_fast_decode_and_encode ( format) ;
162
165
166
+ let supports_fast_decode_and_encode_ref = supports_fast_decode_and_encode. as_ref ( ) ;
167
+
163
168
let mut stdout_lock = io:: stdout ( ) . lock ( ) ;
164
169
165
- if decode {
170
+ if config . decode {
166
171
fast_decode:: fast_decode (
167
172
input,
168
173
& mut stdout_lock,
169
- supports_fast_decode_and_encode . as_ref ( ) ,
170
- ignore_garbage,
174
+ supports_fast_decode_and_encode_ref ,
175
+ config . ignore_garbage ,
171
176
)
172
177
} else {
173
178
fast_encode:: fast_encode (
174
179
input,
175
180
& mut stdout_lock,
176
- supports_fast_decode_and_encode . as_ref ( ) ,
177
- wrap ,
181
+ supports_fast_decode_and_encode_ref ,
182
+ config . wrap_cols ,
178
183
)
179
184
}
180
185
}
@@ -423,15 +428,15 @@ pub mod fast_encode {
423
428
} ;
424
429
425
430
// Start of buffers
426
- // Data that was read from stdin
431
+ // Data that was read from `input`
427
432
let mut input_buffer = vec ! [ 0 ; INPUT_BUFFER_SIZE ] ;
428
433
429
434
assert ! ( !input_buffer. is_empty( ) ) ;
430
435
431
- // Data that was read from stdin but has not been encoded yet
436
+ // Data that was read from `input` but has not been encoded yet
432
437
let mut leftover_buffer = VecDeque :: < u8 > :: new ( ) ;
433
438
434
- // Encoded data that needs to be written to output
439
+ // Encoded data that needs to be written to ` output`
435
440
let mut encoded_buffer = VecDeque :: < u8 > :: new ( ) ;
436
441
// End of buffers
437
442
@@ -469,7 +474,7 @@ pub mod fast_encode {
469
474
470
475
assert ! ( leftover_buffer. len( ) < encode_in_chunks_of_size) ;
471
476
472
- // Write all data in `encoded_buffer` to output
477
+ // Write all data in `encoded_buffer` to ` output`
473
478
write_to_output ( & mut line_wrapping, & mut encoded_buffer, & mut output, false ) ?;
474
479
}
475
480
Err ( er) => {
@@ -511,7 +516,7 @@ pub mod fast_decode {
511
516
512
517
// Start of helper functions
513
518
fn alphabet_to_table ( alphabet : & [ u8 ] , ignore_garbage : bool ) -> [ bool ; 256 ] {
514
- // If " ignore_garbage" is enabled, all characters outside the alphabet are ignored
519
+ // If ` ignore_garbage` is enabled, all characters outside the alphabet are ignored
515
520
// If it is not enabled, only '\n' and '\r' are ignored
516
521
if ignore_garbage {
517
522
// Note: "false" here
@@ -618,31 +623,31 @@ pub mod fast_decode {
618
623
619
624
assert ! ( decode_in_chunks_of_size > 0 ) ;
620
625
621
- // Note that it's not worth using "data-encoding"'s ignore functionality if " ignore_garbage" is true, because
626
+ // Note that it's not worth using "data-encoding"'s ignore functionality if ` ignore_garbage` is true, because
622
627
// "data-encoding"'s ignore functionality cannot discard non-ASCII bytes. The data has to be filtered before
623
628
// passing it to "data-encoding", so there is no point in doing any filtering in "data-encoding". This also
624
629
// allows execution to stay on the happy path in "data-encoding":
625
630
// https://github.com/ia0/data-encoding/blob/4f42ad7ef242f6d243e4de90cd1b46a57690d00e/lib/src/lib.rs#L754-L756
626
- // Update: it is not even worth it to use "data-encoding"'s ignore functionality when " ignore_garbage" is
631
+ // It is also not worth using "data-encoding"'s ignore functionality when ` ignore_garbage` is
627
632
// false.
628
633
// Note that the alphabet constants above already include the padding characters
629
634
// TODO
630
635
// Precompute this
631
636
let table = alphabet_to_table ( alphabet, ignore_garbage) ;
632
637
633
638
// Start of buffers
634
- // Data that was read from stdin
639
+ // Data that was read from `input`
635
640
let mut input_buffer = vec ! [ 0 ; INPUT_BUFFER_SIZE ] ;
636
641
637
642
assert ! ( !input_buffer. is_empty( ) ) ;
638
643
639
- // Data that was read from stdin but has not been decoded yet
644
+ // Data that was read from `input` but has not been decoded yet
640
645
let mut leftover_buffer = Vec :: < u8 > :: new ( ) ;
641
646
642
647
// Decoded data that needs to be written to `output`
643
648
let mut decoded_buffer = Vec :: < u8 > :: new ( ) ;
644
649
645
- // Buffer that will be used when " ignore_garbage" is true, and the chunk read from " input" contains garbage
650
+ // Buffer that will be used when ` ignore_garbage` is true, and the chunk read from ` input` contains garbage
646
651
// data
647
652
let mut non_garbage_buffer = Vec :: < u8 > :: new ( ) ;
648
653
// End of buffers
0 commit comments