OpenVPN 3 Core Library
Loading...
Searching...
No Matches
number.hpp
Go to the documentation of this file.
1// OpenVPN -- An application to securely tunnel IP networks
2// over a single port, with support for SSL/TLS-based
3// session authentication and key exchange,
4// packet encryption, packet authentication, and
5// packet compression.
6//
7// Copyright (C) 2012- OpenVPN Inc.
8//
9// SPDX-License-Identifier: MPL-2.0 OR AGPL-3.0-only WITH openvpn3-openssl-exception
10//
11
12// General purpose methods for dealing with numbers.
13
14#ifndef OPENVPN_COMMON_NUMBER_H
15#define OPENVPN_COMMON_NUMBER_H
16
17#include <algorithm>
18#include <string>
19#include <limits>
20
23
24namespace openvpn {
25
26OPENVPN_EXCEPTION(number_parse_exception);
27
28// Parse the number of type T in str, returning
29// value in retval. Returns true on success.
30// Note -- currently doesn't detect overflow.
31// If nondigit_term is true, any non-digit char
32// can terminate the numerical value. Otherwise,
33// only '\0' can terminate the value.
34template <typename T>
35inline bool parse_number(const char *str,
36 T &retval,
37 const bool nondigit_term = false)
38{
39 if (!str[0])
40 return false; // empty string
41 bool neg = false;
42 size_t i = 0;
43 if (std::numeric_limits<T>::min() < 0 && str[0] == '-')
44 {
45 neg = true;
46 i = 1;
47 }
48 T ret = T(0);
49 while (true)
50 {
51 const char c = str[i++];
52 if (c >= '0' && c <= '9')
53 {
54 ret *= T(10);
55 ret += T(c - '0');
56 }
57 else if (!c || nondigit_term)
58 {
59 retval = neg ? -ret : ret;
60 return true;
61 }
62 else
63 return false; // non-digit
64 }
65}
66
67// like parse_number above, but accepts std::string
68template <typename T>
69inline bool parse_number(const std::string &str, T &retval)
70{
71 return parse_number<T>(str.c_str(), retval);
72}
73
74template <typename T>
75inline T parse_number_throw(const std::string &str, const std::string &error)
76{
77 T ret;
78 if (parse_number<T>(str.c_str(), ret))
79 return ret;
80 throw number_parse_exception(error);
81}
82
83template <typename T>
84inline T parse_number_throw(const std::string &str, const char *error)
85{
86 T ret;
87 if (parse_number<T>(str.c_str(), ret))
88 return ret;
89 throw number_parse_exception(std::string(error));
90}
91
92template <typename T>
93inline T parse_number_throw(const char *str, const char *error)
94{
95 T ret;
96 if (parse_number<T>(str, ret))
97 return ret;
98 throw number_parse_exception(std::string(error));
99}
100
101template <typename T>
102inline bool parse_number_validate(const std::string &numstr,
103 const size_t max_len,
104 const T minimum,
105 const T maximum,
106 T *value_return = nullptr)
107{
108 if (numstr.length() <= max_len)
109 {
110 T value;
111 if (parse_number<T>(numstr.c_str(), value))
112 {
113 if (value >= minimum && value <= maximum)
114 {
115 if (value_return)
116 *value_return = value;
117 return true;
118 }
119 }
120 }
121 return false;
122}
123
124inline bool is_number(std::string_view str)
125{
126 return !str.empty() && std::ranges::all_of(str, [](const unsigned char c)
127 { return std::isdigit(c); });
128}
129
130} // namespace openvpn
131
132#endif // OPENVPN_COMMON_NUMBER_H
#define OPENVPN_EXCEPTION(C)
Definition exception.hpp:99
bool is_number(std::string_view str)
Definition number.hpp:124
bool parse_number_validate(const std::string &numstr, const size_t max_len, const T minimum, const T maximum, T *value_return=nullptr)
Definition number.hpp:102
bool parse_number(const char *str, T &retval, const bool nondigit_term=false)
Definition number.hpp:35
T parse_number_throw(const std::string &str, const std::string &error)
Definition number.hpp:75