Silently ignore ampersands in opcode name

This commit is contained in:
Paul Fd 2020-03-05 16:07:23 +01:00
parent a17f6b9169
commit 692b2cda6a
3 changed files with 51 additions and 2 deletions

View file

@ -20,7 +20,7 @@ sfz::Opcode::Opcode(absl::string_view inputOpcode, absl::string_view inputValue)
while (nextNumIndex != opcode.npos) {
const auto numLetters = nextNumIndex - nextCharIndex;
parameterPosition += numLetters;
lettersOnlyHash = hash(opcode.substr(nextCharIndex, numLetters), lettersOnlyHash);
lettersOnlyHash = hashNoAmpersand(opcode.substr(nextCharIndex, numLetters), lettersOnlyHash);
nextCharIndex = opcode.find_first_not_of("1234567890", nextNumIndex);
uint32_t returnedValue;
@ -34,5 +34,5 @@ sfz::Opcode::Opcode(absl::string_view inputOpcode, absl::string_view inputValue)
}
if (nextCharIndex != opcode.npos)
lettersOnlyHash = hash(opcode.substr(nextCharIndex), lettersOnlyHash);
lettersOnlyHash = hashNoAmpersand(opcode.substr(nextCharIndex), lettersOnlyHash);
}

View file

@ -66,3 +66,24 @@ constexpr uint64_t hash(absl::string_view s, uint64_t h = Fnv1aBasis)
return h;
}
/**
* @brief Same function as `hash()` but ignores ampersands (&)
*
* See e.g. the Region.cpp file
*
* @param s the input string to be hashed
* @param h the hashing seed to use
* @return uint64_t
*/
constexpr uint64_t hashNoAmpersand(absl::string_view s, uint64_t h = Fnv1aBasis)
{
if (s.length() > 0) {
if (s.front() == '&')
return hashNoAmpersand( { s.data() + 1, s.length() - 1 }, h );
else
return hashNoAmpersand( { s.data() + 1, s.length() - 1 }, (h ^ s.front()) * Fnv1aPrime );
}
return h;
}

View file

@ -28,6 +28,24 @@ TEST_CASE("[Opcode] Construction")
REQUIRE(opcode.value == "dummy");
}
SECTION("Normal construction with ampersand")
{
sfz::Opcode opcode { "sample&_ampersand", "dummy" };
REQUIRE(opcode.opcode == "sample&_ampersand");
REQUIRE(opcode.lettersOnlyHash == hash("sample_ampersand"));
REQUIRE(opcode.parameters.empty());
REQUIRE(opcode.value == "dummy");
}
SECTION("Normal construction with multiple ampersands")
{
sfz::Opcode opcode { "&sample&_ampersand&", "dummy" };
REQUIRE(opcode.opcode == "&sample&_ampersand&");
REQUIRE(opcode.lettersOnlyHash == hash("sample_ampersand"));
REQUIRE(opcode.parameters.empty());
REQUIRE(opcode.value == "dummy");
}
SECTION("Parameterized opcode")
{
sfz::Opcode opcode { "sample123", "dummy" };
@ -38,6 +56,16 @@ TEST_CASE("[Opcode] Construction")
REQUIRE(opcode.parameters == std::vector<uint16_t>({ 123 }));
}
SECTION("Parameterized opcode with ampersand")
{
sfz::Opcode opcode { "sample&123", "dummy" };
REQUIRE(opcode.opcode == "sample&123");
REQUIRE(opcode.lettersOnlyHash == hash("sample&"));
REQUIRE(opcode.value == "dummy");
REQUIRE(opcode.parameters.size() == 1);
REQUIRE(opcode.parameters == std::vector<uint16_t>({ 123 }));
}
SECTION("Parameterized opcode with underscore")
{
sfz::Opcode opcode { "sample_underscore123", "dummy" };