Some updates on value parsing

This commit is contained in:
Jean Pierre Cimalando 2020-06-10 23:10:49 +02:00
parent 014f9ff5af
commit 8629179e2e
2 changed files with 26 additions and 8 deletions

View file

@ -12,6 +12,7 @@
#include "StringViewHelpers.h"
#include "absl/types/optional.h"
#include "absl/meta/type_traits.h"
#include "absl/strings/ascii.h"
#include <string_view>
#include <vector>
#include <type_traits>
@ -115,16 +116,18 @@ private:
template <typename ValueType, absl::enable_if_t<std::is_integral<ValueType>::value, int> = 0>
inline absl::optional<ValueType> readOpcode(absl::string_view value, const Range<ValueType>& validRange)
{
const auto numberEnd = value.find_first_not_of("-1234567890.");
size_t numberEnd = 0;
if (numberEnd < value.size() && (value[numberEnd] == '+' || value[numberEnd] == '-'))
++numberEnd;
while (numberEnd < value.size() && absl::ascii_isdigit(value[numberEnd]))
++numberEnd;
value = value.substr(0, numberEnd);
int64_t returnedValue;
if (!absl::SimpleAtoi(value, &returnedValue)) {
float floatValue;
if (!absl::SimpleAtof(value, &floatValue))
if (!absl::SimpleAtoi(value, &returnedValue))
return absl::nullopt;
returnedValue = static_cast<int64_t>(floatValue);
}
if (returnedValue > std::numeric_limits<ValueType>::max())
returnedValue = std::numeric_limits<ValueType>::max();
@ -147,12 +150,24 @@ inline absl::optional<ValueType> readOpcode(absl::string_view value, const Range
template <typename ValueType, absl::enable_if_t<std::is_floating_point<ValueType>::value, int> = 0>
inline absl::optional<ValueType> readOpcode(absl::string_view value, const Range<ValueType>& validRange)
{
const auto numberEnd = value.find_first_not_of("-1234567890.");
size_t numberEnd = 0;
if (numberEnd < value.size() && (value[numberEnd] == '+' || value[numberEnd] == '-'))
++numberEnd;
while (numberEnd < value.size() && absl::ascii_isdigit(value[numberEnd]))
++numberEnd;
if (numberEnd < value.size() && value[numberEnd] == '.') {
++numberEnd;
while (numberEnd < value.size() && absl::ascii_isdigit(value[numberEnd]))
++numberEnd;
}
value = value.substr(0, numberEnd);
float returnedValue;
if (!absl::SimpleAtof(value, &returnedValue))
return absl::nullopt;
return absl::nullopt;
return validRange.clamp(returnedValue);
}

View file

@ -250,12 +250,15 @@ TEST_CASE("[Opcode] Normalization")
TEST_CASE("[Opcode] readOpcode")
{
REQUIRE( sfz::readOpcode("16", sfz::Range<uint8_t>(0, 100)).value() == 16 );
REQUIRE( sfz::readOpcode("+16", sfz::Range<uint8_t>(0, 100)).value() == 16 );
REQUIRE( sfz::readOpcode("110", sfz::Range<uint8_t>(0, 100)).value() == 100 );
REQUIRE( sfz::readOpcode("-1", sfz::Range<uint8_t>(0, 100)).value() == 0 );
REQUIRE( sfz::readOpcode("12.5", sfz::Range<int>(-100, 100)).value() == 12 );
REQUIRE( sfz::readOpcode("+12.5", sfz::Range<int>(-100, 100)).value() == 12 );
REQUIRE( sfz::readOpcode("-40", sfz::Range<int>(-100, 100)).value() == -40 );
REQUIRE( sfz::readOpcode("-140", sfz::Range<int>(-100, 100)).value() == -100 );
REQUIRE( sfz::readOpcode("12.5", sfz::Range<float>(0.0f, 100.0f)).value() == 12.5_a );
REQUIRE( sfz::readOpcode("+12.5", sfz::Range<float>(0.0f, 100.0f)).value() == 12.5_a );
REQUIRE( sfz::readOpcode("-22.5", sfz::Range<float>(-20.0f, 100.0f)).value() == -20.0_a );
REQUIRE( sfz::readOpcode("150.5", sfz::Range<float>(-20.0f, 100.0f)).value() == 100.0_a );
REQUIRE( sfz::readOpcode("50.25garbage", sfz::Range<float>(-20.0f, 100.0f)).value() == 50.25_a );