summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/SongFilter.cxx57
-rw-r--r--src/SongFilter.hxx48
2 files changed, 64 insertions, 41 deletions
diff --git a/src/SongFilter.cxx b/src/SongFilter.cxx
index b25496192..886a7b71a 100644
--- a/src/SongFilter.cxx
+++ b/src/SongFilter.cxx
@@ -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);
diff --git a/src/SongFilter.hxx b/src/SongFilter.hxx
index f5910e440..90b579007 100644
--- a/src/SongFilter.hxx
+++ b/src/SongFilter.hxx
@@ -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;