MCPcopy Create free account
hub / github.com/ClassicOldSong/Apollo / parse_refresh_rate_string

Function parse_refresh_rate_string

src/display_device.cpp:198–258  ·  view source on GitHub ↗

* @brief Parse refresh rate value from the string. * @param input String to be parsed. * @param output Reference to output variable to fill in. * @param allow_decimal_point Specify whether the decimal point is allowed or not. * @returns True on successful parsing (empty string allowed), false otherwise. * * @examples * std::optional refresh_rate;

Source from the content-addressed store, hash-verified

196 * @examples_end
197 */
198 bool parse_refresh_rate_string(const std::string &input, std::optional<FloatingPoint> &output, const bool allow_decimal_point = true) {
199 static const auto is_zero {[](const auto &character) {
200 return character == '0';
201 }};
202 const std::string trimmed_input {boost::algorithm::trim_copy(input)};
203 const std::regex refresh_rate_regex {allow_decimal_point ? R"(^(\d+)(?:\.(\d+))?$)" : R"(^(\d+)$)"};
204
205 if (std::smatch match; std::regex_match(trimmed_input, match, refresh_rate_regex)) {
206 try {
207 // Here we are trimming zeros from the string to possibly reduce out of bounds case
208 std::string trimmed_match_1 {boost::algorithm::trim_left_copy_if(match[1].str(), is_zero)};
209 if (trimmed_match_1.empty()) {
210 trimmed_match_1 = "0"s; // Just in case ALL the string is full of zeros, we want to leave one
211 }
212
213 std::string trimmed_match_2;
214 if (allow_decimal_point && match[2].matched) {
215 trimmed_match_2 = boost::algorithm::trim_right_copy_if(match[2].str(), is_zero);
216 }
217
218 if (!trimmed_match_2.empty()) {
219 // We have a decimal point and will have to split it into numerator and denominator.
220 // For example:
221 // 59.995:
222 // numerator = 59995
223 // denominator = 1000
224
225 // We are essentially removing the decimal point here: 59.995 -> 59995
226 const std::string numerator_str {trimmed_match_1 + trimmed_match_2};
227 const auto numerator {stou(numerator_str)};
228
229 // Here we are counting decimal places and calculating denominator: 10^decimal_places
230 const auto denominator {static_cast<unsigned int>(std::pow(10, trimmed_match_2.size()))};
231
232 output = Rational {numerator, denominator};
233 } else {
234 // We do not have a decimal point, just a valid number.
235 // For example:
236 // 60:
237 // numerator = 60
238 // denominator = 1
239 output = Rational {stou(trimmed_match_1), 1};
240 }
241 return true;
242 } catch (const std::out_of_range &) {
243 BOOST_LOG(error) << "Failed to parse refresh rate string " << trimmed_input << " (number out of range).";
244 } catch (const std::exception &err) {
245 BOOST_LOG(error) << "Failed to parse refresh rate string " << trimmed_input << ":\n"
246 << err.what();
247 }
248 } else {
249 if (trimmed_input.empty()) {
250 output = std::nullopt;
251 return true;
252 }
253
254 BOOST_LOG(error) << "Failed to parse refresh rate string " << trimmed_input << ". Must have a pattern of " << (allow_decimal_point ? R"("123" or "123.456")" : R"("123")") << "!";
255 }

Callers 2

parse_remapping_entryFunction · 0.85

Calls 2

stouFunction · 0.85
sizeMethod · 0.45

Tested by

no test coverage detected