SongFilter: move code to class StringFilter

This commit is contained in:
Max Kellermann 2018-07-25 10:18:02 +02:00
parent 29d5ad667c
commit 438366effc
2 changed files with 64 additions and 41 deletions

View File

@ -63,10 +63,23 @@ locate_parse_type(const char *str) noexcept
return tag_name_parse_i(str);
}
bool
StringFilter::Match(const char *s) const noexcept
{
#if !CLANG_CHECK_VERSION(3,6)
/* disabled on clang due to -Wtautological-pointer-compare */
assert(s != nullptr);
#endif
if (fold_case) {
return fold_case.IsIn(s);
} else {
return StringIsEqual(s, value.c_str());
}
}
SongFilter::Item::Item(unsigned _tag, std::string &&_value, bool _fold_case)
:tag(_tag),
value(std::move(_value)),
fold_case(_fold_case ? IcuCompare(value.c_str()) : IcuCompare())
:tag(_tag), string_filter(std::move(_value), _fold_case)
{
}
@ -81,36 +94,19 @@ SongFilter::Item::ToExpression() const noexcept
{
switch (tag) {
case LOCATE_TAG_FILE_TYPE:
return std::string("(" LOCATE_TAG_FILE_KEY " ") + (IsNegated() ? "!=" : "==") + " \"" + value + "\")";
return std::string("(" LOCATE_TAG_FILE_KEY " ") + (IsNegated() ? "!=" : "==") + " \"" + string_filter.GetValue() + "\")";
case LOCATE_TAG_BASE_TYPE:
return "(base \"" + value + "\")";
return "(base \"" + string_filter.GetValue() + "\")";
case LOCATE_TAG_MODIFIED_SINCE:
return "(modified-since \"" + value + "\")";
return "(modified-since \"" + string_filter.GetValue() + "\")";
case LOCATE_TAG_ANY_TYPE:
return std::string("(" LOCATE_TAG_ANY_KEY " ") + (IsNegated() ? "!=" : "==") + " \"" + value + "\")";
return std::string("(" LOCATE_TAG_ANY_KEY " ") + (IsNegated() ? "!=" : "==") + " \"" + string_filter.GetValue() + "\")";
default:
return std::string("(") + tag_item_names[tag] + " " + (IsNegated() ? "!=" : "==") + " \"" + value + "\")";
}
}
bool
SongFilter::Item::StringMatchNN(const char *s) const noexcept
{
#if !CLANG_CHECK_VERSION(3,6)
/* disabled on clang due to -Wtautological-pointer-compare */
assert(s != nullptr);
#endif
assert(tag != LOCATE_TAG_MODIFIED_SINCE);
if (fold_case) {
return fold_case.IsIn(s);
} else {
return StringIsEqual(s, value.c_str());
return std::string("(") + tag_item_names[tag] + " " + (IsNegated() ? "!=" : "==") + " \"" + string_filter.GetValue() + "\")";
}
}
@ -118,7 +114,7 @@ bool
SongFilter::Item::MatchNN(const TagItem &item) const noexcept
{
return (tag == LOCATE_TAG_ANY_TYPE || (unsigned)item.type == tag) &&
StringMatchNN(item.value);
string_filter.Match(item.value);
}
bool
@ -141,7 +137,7 @@ SongFilter::Item::MatchNN(const Tag &_tag) const noexcept
searched string is also empty
then it's a match as well and we should return
true. */
if (value.empty())
if (string_filter.empty())
return true;
if (tag == TAG_ALBUM_ARTIST && visited_types[TAG_ARTIST]) {
@ -149,7 +145,7 @@ SongFilter::Item::MatchNN(const Tag &_tag) const noexcept
only "artist" exists, use that */
for (const auto &item : _tag)
if (item.type == TAG_ARTIST &&
StringMatchNN(item.value))
string_filter.Match(item.value))
return true;
}
}
@ -162,7 +158,8 @@ SongFilter::Item::MatchNN(const LightSong &song) const noexcept
{
if (tag == LOCATE_TAG_BASE_TYPE) {
const auto uri = song.GetURI();
return uri_is_child_or_same(value.c_str(), uri.c_str());
return uri_is_child_or_same(string_filter.GetValue().c_str(),
uri.c_str());
}
if (tag == LOCATE_TAG_MODIFIED_SINCE)
@ -170,7 +167,7 @@ SongFilter::Item::MatchNN(const LightSong &song) const noexcept
if (tag == LOCATE_TAG_FILE_TYPE) {
const auto uri = song.GetURI();
return StringMatchNN(uri.c_str());
return string_filter.Match(uri.c_str());
}
return MatchNN(song.tag);

View File

@ -46,6 +46,40 @@ struct Tag;
struct TagItem;
struct LightSong;
class StringFilter {
std::string value;
/**
* This value is only set if case folding is enabled.
*/
IcuCompare fold_case;
public:
StringFilter() = default;
template<typename V>
StringFilter(V &&_value, bool _fold_case)
:value(std::forward<V>(_value)),
fold_case(_fold_case
? IcuCompare(value.c_str())
: IcuCompare()) {}
bool empty() const noexcept {
return value.empty();
}
const auto &GetValue() const noexcept {
return value;
}
bool GetFoldCase() const noexcept {
return fold_case;
}
gcc_pure
bool Match(const char *s) const noexcept;
};
class SongFilter {
public:
class Item {
@ -53,12 +87,7 @@ public:
bool negated = false;
std::string value;
/**
* This value is only set if case folding is enabled.
*/
IcuCompare fold_case;
StringFilter string_filter;
/**
* For #LOCATE_TAG_MODIFIED_SINCE
@ -88,11 +117,11 @@ public:
}
bool GetFoldCase() const {
return fold_case;
return string_filter.GetFoldCase();
}
const char *GetValue() const {
return value.c_str();
return string_filter.GetValue().c_str();
}
private:
@ -100,9 +129,6 @@ public:
method pretends negation is unset, and the caller
is responsibly for considering it */
gcc_pure gcc_nonnull(2)
bool StringMatchNN(const char *s) const noexcept;
gcc_pure
bool MatchNN(const TagItem &tag_item) const noexcept;