Avoid copying strings in StringFilter

This commit is contained in:
blankie 2023-02-17 12:33:08 +07:00
parent 12cf71130f
commit 0e709f25cd
Signed by: blankie
GPG Key ID: CC15FC822C7F61F5
2 changed files with 37 additions and 27 deletions

View File

@ -94,55 +94,64 @@ const std::string* StringFilter::error() const {
} }
bool StringFilter::_match_no_regex(const LogcatEntry& entry) const { bool StringFilter::_match_no_regex(const LogcatEntry& entry) const {
bool matched;
if (this->exact_match) { if (this->exact_match) {
switch (this->key) { switch (this->key) {
case FilterKey::User: matched = entry.user.value_or("") == this->other; break; case FilterKey::User: return entry.user && *entry.user == this->other;
case FilterKey::Tag: matched = entry.tag == this->other; break; case FilterKey::Tag: return entry.tag == this->other;
case FilterKey::Message: matched = entry.message == this->other; break; case FilterKey::Message: return entry.message == this->other;
default: throw std::runtime_error("StringFilter::match received unhandled key"); default: throw std::runtime_error("StringFilter::match received unhandled key");
} }
} else { } else {
switch (this->key) { switch (this->key) {
case FilterKey::User: matched = entry.user.value_or("").find(this->other) != std::string::npos; break; case FilterKey::User: return entry.user && entry.user->find(this->other) != std::string::npos;
case FilterKey::Tag: matched = entry.tag.find(this->other) != std::string::npos; break; case FilterKey::Tag: return entry.tag.find(this->other) != std::string::npos;
case FilterKey::Message: matched = entry.message.find(this->other) != std::string::npos; break; case FilterKey::Message: return entry.message.find(this->other) != std::string::npos;
default: throw std::runtime_error("StringFilter::match received unhandled key"); default: throw std::runtime_error("StringFilter::match received unhandled key");
} }
} }
return !this->inverted ? matched : !matched;
} }
bool StringFilter::match(const LogcatEntry& entry) const { bool StringFilter::_match_regex(const LogcatEntry& entry) const {
bool matched;
if (this->error()) {
log(std::string("StringFilter::match called despite there being an error: ") + *this->error());
return true;
}
if (!this->other.starts_with("regex:")) {
return this->_match_no_regex(entry);
}
if (!this->_regex) { if (!this->_regex) {
log("StringFilter::match called with a regex despite there being no regex"); log("StringFilter::match called with a regex despite there being no regex");
return true; return true;
} }
std::string str; bool matched;
const std::string* str;
regmatch_t pmatch[1]; regmatch_t pmatch[1];
int eflags = REG_STARTEND;
switch (this->key) { switch (this->key) {
case FilterKey::User: str = entry.user.value_or(""); break; case FilterKey::User: str = entry.user ? &*entry.user : nullptr; break;
case FilterKey::Tag: str = entry.tag; break; case FilterKey::Tag: str = &entry.tag; break;
case FilterKey::Message: str = entry.message; break; case FilterKey::Message: str = &entry.message; break;
default: throw std::runtime_error("StringFilter::match received unhandled key"); default: throw std::runtime_error("StringFilter::match received unhandled key");
} }
pmatch[0].rm_so = 0; pmatch[0].rm_so = 0;
pmatch[0].rm_eo = static_cast<regoff_t>(str.size()); pmatch[0].rm_eo = str ? static_cast<regoff_t>(str->size()) : 0;
if (!this->exact_match) {
matched = this->_regex->match(str.data(), 1, pmatch, REG_STARTEND); eflags |= REG_NOSUB;
if (this->exact_match) {
matched = matched && pmatch[0].rm_so == 0 && static_cast<size_t>(pmatch[0].rm_eo) == str.size();
} }
matched = this->_regex->match(str ? str->data() : "", 1, pmatch, eflags);
if (this->exact_match) {
matched = matched && pmatch[0].rm_so == 0 && str
? static_cast<size_t>(pmatch[0].rm_eo) == str->size()
: pmatch[0].rm_so == 0;
}
return matched;
}
bool StringFilter::match(const LogcatEntry& entry) const {
if (this->error()) {
log(std::string("StringFilter::match called despite there being an error: ") + *this->error());
return true;
}
bool matched = !this->other.starts_with("regex:")
? this->_match_no_regex(entry)
: this->_match_regex(entry);
return !this->inverted ? matched : !matched; return !this->inverted ? matched : !matched;
} }

View File

@ -74,6 +74,7 @@ public:
private: private:
bool _match_no_regex(const LogcatEntry& entry) const; bool _match_no_regex(const LogcatEntry& entry) const;
bool _match_regex(const LogcatEntry& entry) const;
std::string _error; std::string _error;
std::optional<Pcre2Regex> _regex; std::optional<Pcre2Regex> _regex;