@@ -80,6 +80,17 @@ enum AsciiConv {
80
80
IBM ,
81
81
}
82
82
83
+ #[ derive( Debug ) ]
84
+ enum Conversion {
85
+ Ascii ( AsciiConv ) ,
86
+ Lcase ,
87
+ Ucase ,
88
+ Swab ,
89
+ Block ,
90
+ Unblock ,
91
+ Sync ,
92
+ }
93
+
83
94
#[ derive( Debug ) ]
84
95
struct Config {
85
96
ifile : String ,
@@ -91,15 +102,9 @@ struct Config {
91
102
seek : usize ,
92
103
skip : usize ,
93
104
count : usize ,
94
-
95
- ascii : Option < AsciiConv > ,
96
- block : Option < bool > ,
97
- lcase : bool ,
98
- ucase : bool ,
99
- swab : bool ,
105
+ conversions : Vec < Conversion > ,
100
106
noerror : bool ,
101
107
notrunc : bool ,
102
- sync : bool ,
103
108
}
104
109
105
110
impl Config {
@@ -114,14 +119,9 @@ impl Config {
114
119
seek : 0 ,
115
120
skip : 0 ,
116
121
count : 0 ,
117
- ascii : None ,
118
- block : None ,
119
- lcase : false ,
120
- ucase : false ,
121
- swab : false ,
122
+ conversions : Vec :: new ( ) ,
122
123
noerror : false ,
123
124
notrunc : false ,
124
- sync : false ,
125
125
}
126
126
}
127
127
}
@@ -169,17 +169,22 @@ fn convert_ucase(data: &mut [u8]) {
169
169
}
170
170
171
171
fn apply_conversions ( data : & mut [ u8 ] , config : & Config ) {
172
- if let Some ( ascii_conv) = & config. ascii {
173
- convert_ascii ( data, ascii_conv) ;
174
- }
175
- if config. swab {
176
- convert_swab ( data) ;
177
- }
178
- if config. lcase {
179
- convert_lcase ( data) ;
180
- }
181
- if config. ucase {
182
- convert_ucase ( data) ;
172
+ for conversion in & config. conversions {
173
+ match conversion {
174
+ Conversion :: Ascii ( ascii_conv) => convert_ascii ( data, ascii_conv) ,
175
+ Conversion :: Lcase => convert_lcase ( data) ,
176
+ Conversion :: Ucase => convert_ucase ( data) ,
177
+ Conversion :: Swab => convert_swab ( data) ,
178
+ Conversion :: Block => {
179
+ todo ! ( )
180
+ } // implement block conversion
181
+ Conversion :: Unblock => {
182
+ todo ! ( )
183
+ } // implement unblock conversion
184
+ Conversion :: Sync => {
185
+ todo ! ( )
186
+ } // implement sync conversion
187
+ }
183
188
}
184
189
}
185
190
@@ -200,20 +205,21 @@ fn copy_convert_file(config: &Config) -> Result<(), Box<dyn std::error::Error>>
200
205
let mut ibuf = vec ! [ 0u8 ; config. ibs] ;
201
206
let mut obuf = vec ! [ 0u8 ; config. obs] ;
202
207
208
+ // Skip the specified number of bytes
209
+ let mut skipped = 0 ;
210
+ while skipped < config. skip {
211
+ let bytes_to_skip = std:: cmp:: min ( config. skip - skipped, config. ibs ) ;
212
+ let n = ifile. read ( & mut ibuf[ ..bytes_to_skip] ) ?;
213
+ if n == 0 {
214
+ break ;
215
+ }
216
+ skipped += n;
217
+ }
218
+
203
219
let mut count = 0 ;
204
- let mut skip = config. skip ;
205
220
let mut seek = config. seek ;
206
221
207
222
loop {
208
- if skip > 0 {
209
- let n = ifile. read ( & mut ibuf) ?;
210
- if n == 0 {
211
- break ;
212
- }
213
- skip -= n;
214
- continue ;
215
- }
216
-
217
223
if seek > 0 {
218
224
let n = ifile. read ( & mut ibuf) ?;
219
225
if n == 0 {
@@ -250,23 +256,30 @@ fn copy_convert_file(config: &Config) -> Result<(), Box<dyn std::error::Error>>
250
256
251
257
fn parse_conv_list ( config : & mut Config , s : & str ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
252
258
for convstr in s. split ( "," ) {
253
- match convstr {
254
- "ascii" => config. ascii = Some ( AsciiConv :: Ascii ) ,
255
- "ebcdic" => config. ascii = Some ( AsciiConv :: EBCDIC ) ,
256
- "ibm" => config. ascii = Some ( AsciiConv :: IBM ) ,
257
- "block" => config. block = Some ( true ) ,
258
- "unblock" => config. block = Some ( false ) ,
259
- "lcase" => config. lcase = true ,
260
- "ucase" => config. ucase = true ,
261
- "swab" => config. swab = true ,
262
- "noerror" => config. noerror = true ,
263
- "notrunc" => config. notrunc = true ,
264
- "sync" => config. sync = true ,
259
+ let conversion = match convstr {
260
+ "ascii" => Conversion :: Ascii ( AsciiConv :: Ascii ) ,
261
+ "ebcdic" => Conversion :: Ascii ( AsciiConv :: EBCDIC ) ,
262
+ "ibm" => Conversion :: Ascii ( AsciiConv :: IBM ) ,
263
+ "block" => Conversion :: Block ,
264
+ "unblock" => Conversion :: Unblock ,
265
+ "lcase" => Conversion :: Lcase ,
266
+ "ucase" => Conversion :: Ucase ,
267
+ "swab" => Conversion :: Swab ,
268
+ "sync" => Conversion :: Sync ,
269
+ "noerror" => {
270
+ config. noerror = true ;
271
+ continue ;
272
+ }
273
+ "notrunc" => {
274
+ config. notrunc = true ;
275
+ continue ;
276
+ }
265
277
_ => {
266
278
eprintln ! ( "{}: {}" , gettext( "invalid conv option" ) , convstr) ;
267
279
return Err ( "invalid conv option" . into ( ) ) ;
268
280
}
269
- }
281
+ } ;
282
+ config. conversions . push ( conversion) ;
270
283
}
271
284
Ok ( ( ) )
272
285
}
0 commit comments