logging/filter: Use std::string_view in ParseFilterString()

Allows avoiding constructing std::string instances, since this only
reads an arbitrary sequence of characters.

We can also make ParseFilterRule() internal, since it doesn't depend on
any private instance state of Filter
master
Lioncash 2018-07-20 15:42:42 +07:00
parent 7a1a860abe
commit f63ccbd936
2 changed files with 40 additions and 41 deletions

@ -8,39 +8,9 @@
#include "common/string_util.h"
namespace Log {
Filter::Filter(Level default_level) {
ResetAll(default_level);
}
void Filter::ResetAll(Level level) {
class_levels.fill(level);
}
void Filter::SetClassLevel(Class log_class, Level level) {
class_levels[static_cast<size_t>(log_class)] = level;
}
void Filter::ParseFilterString(const std::string& filter_str) {
auto clause_begin = filter_str.cbegin();
while (clause_begin != filter_str.cend()) {
auto clause_end = std::find(clause_begin, filter_str.cend(), ' ');
// If clause isn't empty
if (clause_end != clause_begin) {
ParseFilterRule(clause_begin, clause_end);
}
if (clause_end != filter_str.cend()) {
// Skip over the whitespace
++clause_end;
}
clause_begin = clause_end;
}
}
namespace {
template <typename It>
static Level GetLevelByName(const It begin, const It end) {
Level GetLevelByName(const It begin, const It end) {
for (u8 i = 0; i < static_cast<u8>(Level::Count); ++i) {
const char* level_name = GetLevelName(static_cast<Level>(i));
if (Common::ComparePartialString(begin, end, level_name)) {
@ -51,7 +21,7 @@ static Level GetLevelByName(const It begin, const It end) {
}
template <typename It>
static Class GetClassByName(const It begin, const It end) {
Class GetClassByName(const It begin, const It end) {
for (ClassType i = 0; i < static_cast<ClassType>(Class::Count); ++i) {
const char* level_name = GetLogClassName(static_cast<Class>(i));
if (Common::ComparePartialString(begin, end, level_name)) {
@ -61,8 +31,8 @@ static Class GetClassByName(const It begin, const It end) {
return Class::Count;
}
bool Filter::ParseFilterRule(const std::string::const_iterator begin,
const std::string::const_iterator end) {
template <typename Iterator>
bool ParseFilterRule(Filter& instance, Iterator begin, Iterator end) {
auto level_separator = std::find(begin, end, ':');
if (level_separator == end) {
LOG_ERROR(Log, "Invalid log filter. Must specify a log level after `:`: {}",
@ -77,7 +47,7 @@ bool Filter::ParseFilterRule(const std::string::const_iterator begin,
}
if (Common::ComparePartialString(begin, level_separator, "*")) {
ResetAll(level);
instance.ResetAll(level);
return true;
}
@ -87,9 +57,40 @@ bool Filter::ParseFilterRule(const std::string::const_iterator begin,
return false;
}
SetClassLevel(log_class, level);
instance.SetClassLevel(log_class, level);
return true;
}
} // Anonymous namespace
Filter::Filter(Level default_level) {
ResetAll(default_level);
}
void Filter::ResetAll(Level level) {
class_levels.fill(level);
}
void Filter::SetClassLevel(Class log_class, Level level) {
class_levels[static_cast<size_t>(log_class)] = level;
}
void Filter::ParseFilterString(std::string_view filter_view) {
auto clause_begin = filter_view.cbegin();
while (clause_begin != filter_view.cend()) {
auto clause_end = std::find(clause_begin, filter_view.cend(), ' ');
// If clause isn't empty
if (clause_end != clause_begin) {
ParseFilterRule(*this, clause_begin, clause_end);
}
if (clause_end != filter_view.cend()) {
// Skip over the whitespace
++clause_end;
}
clause_begin = clause_end;
}
}
bool Filter::CheckMessage(Class log_class, Level level) const {
return static_cast<u8>(level) >= static_cast<u8>(class_levels[static_cast<size_t>(log_class)]);

@ -6,7 +6,7 @@
#include <array>
#include <cstddef>
#include <string>
#include <string_view>
#include "common/logging/log.h"
namespace Log {
@ -40,9 +40,7 @@ public:
* - `Service:Info` -- Sets the level of Service to Info.
* - `Service.FS:Trace` -- Sets the level of the Service.FS class to Trace.
*/
void ParseFilterString(const std::string& filter_str);
bool ParseFilterRule(const std::string::const_iterator start,
const std::string::const_iterator end);
void ParseFilterString(std::string_view filter_view);
/// Matches class/level combination against the filter, returning true if it passed.
bool CheckMessage(Class log_class, Level level) const;