-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
/
Copy pathparse_nrofbytes.rs
97 lines (91 loc) · 3.23 KB
/
parse_nrofbytes.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
// This file is part of the uutils coreutils package.
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.
use uucore::parser::parse_size::{ParseSizeError, parse_size_u64};
pub fn parse_number_of_bytes(s: &str) -> Result<u64, ParseSizeError> {
let mut start = 0;
let mut len = s.len();
let mut radix = 16;
let mut multiply = 1;
if s.starts_with("0x") || s.starts_with("0X") {
start = 2;
} else if s.starts_with('0') {
radix = 8;
} else {
return parse_size_u64(&s[start..]);
}
let mut ends_with = s.chars().rev();
match ends_with.next() {
Some('b') if radix != 16 => {
multiply = 512;
len -= 1;
}
Some('k' | 'K') => {
multiply = 1024;
len -= 1;
}
Some('m' | 'M') => {
multiply = 1024 * 1024;
len -= 1;
}
Some('G') => {
multiply = 1024 * 1024 * 1024;
len -= 1;
}
#[cfg(target_pointer_width = "64")]
Some('T') => {
multiply = 1024 * 1024 * 1024 * 1024;
len -= 1;
}
#[cfg(target_pointer_width = "64")]
Some('P') => {
multiply = 1024 * 1024 * 1024 * 1024 * 1024;
len -= 1;
}
#[cfg(target_pointer_width = "64")]
Some('E') if radix != 16 => {
multiply = 1024 * 1024 * 1024 * 1024 * 1024 * 1024;
len -= 1;
}
Some('B') if radix != 16 => {
len -= 2;
multiply = match ends_with.next() {
Some('k' | 'K') => 1000,
Some('m' | 'M') => 1000 * 1000,
Some('G') => 1000 * 1000 * 1000,
#[cfg(target_pointer_width = "64")]
Some('T') => 1000 * 1000 * 1000 * 1000,
#[cfg(target_pointer_width = "64")]
Some('P') => 1000 * 1000 * 1000 * 1000 * 1000,
#[cfg(target_pointer_width = "64")]
Some('E') => 1000 * 1000 * 1000 * 1000 * 1000 * 1000,
_ => return Err(ParseSizeError::ParseFailure(s.to_string())),
}
}
_ => {}
}
let factor = match u64::from_str_radix(&s[start..len], radix) {
Ok(f) => f,
Err(e) => return Err(ParseSizeError::ParseFailure(e.to_string())),
};
factor
.checked_mul(multiply)
.ok_or_else(|| ParseSizeError::SizeTooBig(s.to_string()))
}
#[test]
#[allow(clippy::cognitive_complexity)]
fn test_parse_number_of_bytes() {
// octal input
assert_eq!(8, parse_number_of_bytes("010").unwrap());
assert_eq!(8 * 512, parse_number_of_bytes("010b").unwrap());
assert_eq!(8 * 1024, parse_number_of_bytes("010k").unwrap());
assert_eq!(8 * 1_048_576, parse_number_of_bytes("010m").unwrap());
// hex input
assert_eq!(15, parse_number_of_bytes("0xf").unwrap());
assert_eq!(14, parse_number_of_bytes("0XE").unwrap());
assert_eq!(15, parse_number_of_bytes("0XF").unwrap());
assert_eq!(27, parse_number_of_bytes("0x1b").unwrap());
assert_eq!(16 * 1024, parse_number_of_bytes("0x10k").unwrap());
assert_eq!(16 * 1_048_576, parse_number_of_bytes("0x10m").unwrap());
}