dd_lib/opts/flags/cflag.rs
1use super::{Kind, Result, Unimplemented};
2bitflags!{
3
4/// Each CONV symbol may be:
5///
6/// - **ascii** from EBCDIC to ASCII
7///
8/// - **ebcdic** from ASCII to EBCDIC
9///
10/// - **ibm** from ASCII to alternate EBCDIC
11///
12/// - **block** pad newline-terminated records with spaces to cbs-size
13///
14/// - **unblock** replace trailing spaces in cbs-size records with newline
15///
16/// - **lcase** change upper case to lower case
17///
18/// - **ucase** change lower case to upper case
19///
20/// - **sparse** try to seek rather than write the output for NUL input blocks
21///
22/// - **swab** swap every pair of input bytes
23///
24/// - **sync** pad every input block with NULs to ibs-size; when used with
25/// block or unblock, pad with spaces rather than NULs
26///
27/// - **excl** fail if the output file already exists
28///
29/// - **nocreat** do not create the output file
30///
31/// - **notrunc** do not truncate the output file
32///
33/// - **noerror** continue after read errors
34///
35/// - **fdatasync**
36/// physically write output file data before finishing
37/// - **fsync** likewise, but also write metadata
38
39 pub struct CFlag: u32 {
40
41 /// Translate from EBCDIC to ASCII
42 const ASCII = 0x0001 ;
43 /// Translate from ASCII to EBCDIC
44 const EBCDIC= 0x0002;
45 /// <NOT IMPLEMENTED> Translate from ASCII to IBM
46 const IBM = 0x0004;
47 /// <NOT IMPLEMENTED> Translate from EBCDIC to old ASCII
48 const OLDASCII = 0x0008 ;
49 /// <NOT IMPLEMENTED> Translate from ASCII to old EBCDIC
50 const OLDEBCDIC = 0x0010 ;
51 /// <NOT IMPLEMENTED> Translate from ASCII to old IBM
52 const OLDIBM = 0x0020 ;
53 /// "block" mode: Treats the input as a sequence of newline or end-of-file terminated variable length records independent of input and output block bound-
54 /// aries. Any trailing newline character is discarded. Each input record is converted to a fixed length output record where the length is
55 /// specified by the cbs operand. Input records shorter than the conversion record size are padded with spaces. Input records longer than
56 /// the conversion record size are truncated. The number of truncated input records, if any, are reported to the standard error output at
57 /// the completion of the copy.
58 const BLOCK = 0x0040;
59 /// Treats the input as a sequence of fixed length records independent of input and output block boundaries. The length of the input records
60 /// is specified by the cbs operand. Any trailing space characters are discarded and a newline character is appended.
61 const UNBLOCK = 0x0080 ;
62 /// Transform uppercase [A-Z] characters into lowercase [a-z] characters.
63 const LCASE = 0x0100;
64 /// Transform lowercase [a-z] characters into uppercase [A-Z] characters
65 const UCASE = 0x0200;
66 /// Pad every input block to the input buffer size. Spaces are used for pad bytes if a
67 /// block oriented conversion value is specified, otherwise NUL bytes are used.
68 const SYNC = 0x0400;
69 /// <NOT IMPLEMENTED> Pad the final output block to the full output block size. If the input file is not a multiple of the output block size after conversion,
70 /// this conversion forces the final output block to be the same size as preceding blocks for use on devices that require regularly sized
71 /// blocks to be written. This option is incompatible with use of the bs=n block size specification.
72 /// sparse If one or more output blocks would consist solely of NUL bytes, try to seek the output file by the required space instead of filling them
73 /// with NULs, resulting in a sparse file.
74 const OSYNC = 0x0800;
75 /// <NOT IMPLEMENTED> Do not stop processing on an input error. When an input error occurs, a diagnostic message followed by the current input and output
76 /// block counts will be written to the standard error output in the same format as the standard completion message. If the sync conversion
77 /// is also specified, any missing input data will be replaced with NUL bytes (or with spaces if a block oriented conversion value was speci-
78 /// fied) and processed as a normal input buffer. If the sync conversion is not specified, the input block is omitted from the output. On
79 /// input files which are not tapes or pipes, the file offset will be positioned past the block in which the error occurred using lseek(2).
80 const NOERROR = 0x1000;
81 /// Do not truncate the output file. This will preserve any blocks in the output file not explicitly written by dd. The notrunc value is
82 /// not supported for tapes.
83 const NOTRUNC = 0x2000;
84 /// If one or more output blocks would consist solely of NUL bytes, try to seek the out-
85 /// put file by the required space instead of filling them with NULs, resulting in a
86 /// sparse file.
87 const SPARSE = 0x4000;
88 /// Swap every pair of input bytes. If an input buffer has an odd number of bytes, the last byte will be ignored during swapping.
89 const SWAB = 0x8000;
90 }
91}
92
93impl CFlag {
94 pub fn new(s: &str) -> Result<Self> {
95 let mut flags = CFlag::default();
96 for flag in s.split(',').map(str::trim).filter(|s| s.len() > 0) {
97 Self::check_if_implemented(flag)?;
98 flags |= Self::from_str(flag)?;
99 }
100 Ok(flags)
101 }
102
103 fn from_str(flag: &str) -> Result<Self> {
104 Ok(match flag {
105 "ascii" => Self::ASCII,
106 "ebcdic" => Self::EBCDIC,
107 "oldascii" => Self::OLDASCII,
108 "ibm" => Self::IBM,
109 "oldebcdic" => Self::OLDEBCDIC,
110 "oldibm" => Self::OLDIBM,
111 "noerror" => Self::NOERROR,
112 "osync" => Self::OSYNC,
113 "block" => Self::BLOCK,
114
115 "lcase" => Self::LCASE,
116 "notrunc" => Self::NOTRUNC,
117 "sparse" => Self::SPARSE,
118 "swab" => Self::SWAB,
119 "sync" => Self::SYNC,
120 "ucase" => Self::UCASE,
121 "unblock" => Self::UNBLOCK,
122 arg => return Self::unknown(arg.to_owned()),
123 })
124 }
125}
126
127impl Unimplemented for CFlag {
128 const KIND: Kind = Kind::CFlag;
129 const UNIMPLEMENTED: &'static [&'static str] = &["oldascii", "ibm", "oldebcdic", "noerror", "osync", "oldibm"];
130}
131impl Default for CFlag {
132 fn default() -> CFlag { CFlag::empty() }
133}