Apache Mesos
bytes.hpp
Go to the documentation of this file.
1 // Licensed under the Apache License, Version 2.0 (the "License");
2 // you may not use this file except in compliance with the License.
3 // You may obtain a copy of the License at
4 //
5 // http://www.apache.org/licenses/LICENSE-2.0
6 //
7 // Unless required by applicable law or agreed to in writing, software
8 // distributed under the License is distributed on an "AS IS" BASIS,
9 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 // See the License for the specific language governing permissions and
11 // limitations under the License.
12 
13 #ifndef __STOUT_BYTES_HPP__
14 #define __STOUT_BYTES_HPP__
15 
16 #include <ctype.h> // For 'isdigit'.
17 #include <stdint.h>
18 
19 #include <iomanip>
20 #include <iostream>
21 #include <string>
22 
23 #include <stout/abort.hpp>
24 #include <stout/numify.hpp>
25 #include <stout/stringify.hpp>
26 #include <stout/strings.hpp>
27 #include <stout/try.hpp>
28 
29 
30 class Bytes
31 {
32 public:
33  static constexpr uint64_t BYTES = 1;
34  static constexpr uint64_t KILOBYTES = 1024 * BYTES;
35  static constexpr uint64_t MEGABYTES = 1024 * KILOBYTES;
36  static constexpr uint64_t GIGABYTES = 1024 * MEGABYTES;
37  static constexpr uint64_t TERABYTES = 1024 * GIGABYTES;
38 
39  static Try<Bytes> parse(const std::string& s)
40  {
41  size_t index = 0;
42 
43  while (index < s.size()) {
44  if (isdigit(s[index])) {
45  index++;
46  continue;
47  } else if (s[index] == '.') {
48  return Error("Fractional bytes '" + s + "'");
49  }
50 
51  Try<uint64_t> value = numify<uint64_t>(s.substr(0, index));
52 
53  if (value.isError()) {
54  return Error(value.error());
55  }
56 
57  const std::string unit = strings::upper(s.substr(index));
58 
59  if (unit == "B") {
60  return Bytes(value.get(), BYTES);
61  } else if (unit == "KB") {
62  return Bytes(value.get(), KILOBYTES);
63  } else if (unit == "MB") {
64  return Bytes(value.get(), MEGABYTES);
65  } else if (unit == "GB") {
66  return Bytes(value.get(), GIGABYTES);
67  } else if (unit == "TB") {
68  return Bytes(value.get(), TERABYTES);
69  } else {
70  return Error("Unknown bytes unit '" + unit + "'");
71  }
72  }
73  return Error("Invalid bytes '" + s + "'");
74  }
75 
76  constexpr Bytes(uint64_t bytes = 0) : value(bytes) {}
77  constexpr Bytes(uint64_t _value, uint64_t _unit) : value(_value * _unit) {}
78 
79  uint64_t bytes() const { return value; }
80 
81  bool operator<(const Bytes& that) const { return value < that.value; }
82  bool operator<=(const Bytes& that) const { return value <= that.value; }
83  bool operator>(const Bytes& that) const { return value > that.value; }
84  bool operator>=(const Bytes& that) const { return value >= that.value; }
85  bool operator==(const Bytes& that) const { return value == that.value; }
86  bool operator!=(const Bytes& that) const { return value != that.value; }
87 
88  Bytes& operator+=(const Bytes& that)
89  {
90  value += that.value;
91  return *this;
92  }
93 
94  Bytes& operator-=(const Bytes& that)
95  {
96  value -= that.value;
97  return *this;
98  }
99 
100  Bytes& operator*=(uint64_t multiplier)
101  {
102  value *= multiplier;
103  return *this;
104  }
105 
106  Bytes& operator/=(uint64_t divisor)
107  {
108  value /= divisor;
109  return *this;
110  }
111 
112 private:
113  uint64_t value;
114 };
115 
116 
117 inline constexpr Bytes Kilobytes(uint64_t value)
118 {
119  return Bytes(value, Bytes::KILOBYTES);
120 }
121 
122 
123 inline constexpr Bytes Megabytes(uint64_t value)
124 {
125  return Bytes(value, Bytes::MEGABYTES);
126 }
127 
128 
129 inline constexpr Bytes Gigabytes(uint64_t value)
130 {
131  return Bytes(value, Bytes::GIGABYTES);
132 }
133 
134 
135 inline constexpr Bytes Terabytes(uint64_t value)
136 {
137  return Bytes(value, Bytes::TERABYTES);
138 }
139 
140 
141 inline std::ostream& operator<<(std::ostream& stream, const Bytes& bytes)
142 {
143  // Only raise the unit when there is no loss of information.
144  if (bytes.bytes() == 0) {
145  return stream << "0B";
146  } else if (bytes.bytes() % Bytes::KILOBYTES != 0) {
147  return stream << bytes.bytes() << "B";
148  } else if (bytes.bytes() % Bytes::MEGABYTES != 0) {
149  return stream << (bytes.bytes() / Bytes::KILOBYTES) << "KB";
150  } else if (bytes.bytes() % Bytes::GIGABYTES != 0) {
151  return stream << (bytes.bytes() / Bytes::MEGABYTES) << "MB";
152  } else if (bytes.bytes() % Bytes::TERABYTES != 0) {
153  return stream << (bytes.bytes() / Bytes::GIGABYTES) << "GB";
154  } else {
155  return stream << (bytes.bytes() / Bytes::TERABYTES) << "TB";
156  }
157 }
158 
159 
160 inline Bytes operator+(const Bytes& lhs, const Bytes& rhs)
161 {
162  Bytes sum = lhs;
163  sum += rhs;
164  return sum;
165 }
166 
167 
168 inline Bytes operator-(const Bytes& lhs, const Bytes& rhs)
169 {
170  Bytes diff = lhs;
171  diff -= rhs;
172  return diff;
173 }
174 
175 
176 inline Bytes operator*(const Bytes& lhs, uint64_t multiplier)
177 {
178  Bytes result = lhs;
179  result *= multiplier;
180  return result;
181 }
182 
183 
184 inline Bytes operator/(const Bytes& lhs, uint64_t divisor)
185 {
186  Bytes result = lhs;
187  result /= divisor;
188  return result;
189 }
190 
191 #endif // __STOUT_BYTES_HPP__
constexpr Bytes Terabytes(uint64_t value)
Definition: bytes.hpp:135
Try< Diff > diff(const std::string &from, const std::string &to)
Definition: svn.hpp:72
static constexpr uint64_t MEGABYTES
Definition: bytes.hpp:35
Bytes & operator/=(uint64_t divisor)
Definition: bytes.hpp:106
Definition: errorbase.hpp:35
bool operator!=(const Bytes &that) const
Definition: bytes.hpp:86
Definition: try.hpp:34
constexpr Bytes Megabytes(uint64_t value)
Definition: bytes.hpp:123
Bytes operator*(const Bytes &lhs, uint64_t multiplier)
Definition: bytes.hpp:176
bool operator<(const Bytes &that) const
Definition: bytes.hpp:81
bool operator>(const Bytes &that) const
Definition: bytes.hpp:83
static Try< Bytes > parse(const std::string &s)
Definition: bytes.hpp:39
Resources operator-(const google::protobuf::RepeatedPtrField< Resource > &left, const Resources &right)
Definition: resources.hpp:660
static constexpr uint64_t GIGABYTES
Definition: bytes.hpp:36
bool operator==(const Bytes &that) const
Definition: bytes.hpp:85
bool operator>=(const Bytes &that) const
Definition: bytes.hpp:84
Bytes operator/(const Bytes &lhs, uint64_t divisor)
Definition: bytes.hpp:184
constexpr Bytes(uint64_t _value, uint64_t _unit)
Definition: bytes.hpp:77
Bytes & operator*=(uint64_t multiplier)
Definition: bytes.hpp:100
constexpr Bytes(uint64_t bytes=0)
Definition: bytes.hpp:76
static Try error(const E &e)
Definition: try.hpp:42
Resources operator+(const google::protobuf::RepeatedPtrField< Resource > &left, const Resources &right)
Definition: resources.hpp:652
std::string upper(const std::string &s)
Definition: strings.hpp:420
bool isError() const
Definition: try.hpp:71
std::ostream & operator<<(std::ostream &stream, const Call::Type &type)
Definition: agent.hpp:28
constexpr Bytes Gigabytes(uint64_t value)
Definition: bytes.hpp:129
uint64_t bytes() const
Definition: bytes.hpp:79
static constexpr uint64_t BYTES
Definition: bytes.hpp:33
static constexpr uint64_t TERABYTES
Definition: bytes.hpp:37
constexpr Bytes Kilobytes(uint64_t value)
Definition: bytes.hpp:117
Bytes & operator+=(const Bytes &that)
Definition: bytes.hpp:88
bool operator<=(const Bytes &that) const
Definition: bytes.hpp:82
Definition: bytes.hpp:30
const T & get() const
Definition: try.hpp:73
static constexpr uint64_t KILOBYTES
Definition: bytes.hpp:34
Bytes & operator-=(const Bytes &that)
Definition: bytes.hpp:94