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}