tlx
parse_si_iec_units.cpp
Go to the documentation of this file.
1/*******************************************************************************
2 * tlx/string/parse_si_iec_units.cpp
3 *
4 * Part of tlx - http://panthema.net/tlx
5 *
6 * Copyright (C) 2016-2017 Timo Bingmann <tb@panthema.net>
7 *
8 * All rights reserved. Published under the Boost Software License, Version 1.0
9 ******************************************************************************/
10
12
13#include <cstdlib>
14
15namespace tlx {
16
18 const char* str, uint64_t* out_size, char default_unit) {
19
20 char* endptr;
21 *out_size = strtoul(str, &endptr, 10);
22 if (endptr == nullptr) return false; // parse failed, no number
23
24 while (*endptr == ' ') ++endptr; // skip over spaces
25
26 // multiply with base ^ power
27 unsigned int base = 1000;
28 unsigned int power = 0;
29
30 if (*endptr == 'k' || *endptr == 'K')
31 power = 1, ++endptr;
32 else if (*endptr == 'm' || *endptr == 'M')
33 power = 2, ++endptr;
34 else if (*endptr == 'g' || *endptr == 'G')
35 power = 3, ++endptr;
36 else if (*endptr == 't' || *endptr == 'T')
37 power = 4, ++endptr;
38 else if (*endptr == 'p' || *endptr == 'P')
39 power = 5, ++endptr;
40
41 // switch to power of two (only if power was set above)
42 if ((*endptr == 'i' || *endptr == 'I') && power != 0)
43 base = 1024, ++endptr;
44
45 // byte indicator
46 if (*endptr == 'b' || *endptr == 'B') {
47 ++endptr;
48 }
49 else if (power == 0)
50 {
51 // no explicit power indicator, and no 'b' or 'B' -> apply default unit
52 switch (default_unit)
53 {
54 default: break;
55 case 'k': power = 1, base = 1000;
56 break;
57 case 'm': power = 2, base = 1000;
58 break;
59 case 'g': power = 3, base = 1000;
60 break;
61 case 't': power = 4, base = 1000;
62 break;
63 case 'p': power = 5, base = 1000;
64 break;
65 case 'K': power = 1, base = 1024;
66 break;
67 case 'M': power = 2, base = 1024;
68 break;
69 case 'G': power = 3, base = 1024;
70 break;
71 case 'T': power = 4, base = 1024;
72 break;
73 case 'P': power = 5, base = 1024;
74 break;
75 }
76 }
77
78 // skip over spaces
79 while (*endptr == ' ') ++endptr;
80
81 // multiply size
82 for (unsigned int p = 0; p < power; ++p)
83 *out_size *= base;
84
85 return (*endptr == 0);
86}
87
89 const std::string& str, uint64_t* out_size, char default_unit) {
90 return parse_si_iec_units(str.c_str(), out_size, default_unit);
91}
92
93} // namespace tlx
94
95/******************************************************************************/
bool parse_si_iec_units(const char *str, uint64_t *out_size, char default_unit)
Parse a string like "343KB" or "44 GiB" into the corresponding size in bytes.