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 
15 namespace 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.