Reflow logcat_entry.cpp
This commit is contained in:
parent
d1afe12773
commit
55210a7e30
171
logcat_entry.cpp
171
logcat_entry.cpp
|
@ -7,9 +7,24 @@
|
|||
#include "logcat_entry.h"
|
||||
#include "pcre2_wrapper.h"
|
||||
|
||||
static const Pcre2Regex LogcatEntryRegex("^\\s*(\\d+)(?:\\.\\d+)?(?:\\s+([\\w\\d._-]+))?\\s+(\\d+)\\s+(\\d+)\\s+([A-Z])\\s+(.+?)\\s*:\\s(.*)$");
|
||||
static const Pcre2Regex LogcatEntryRegex(
|
||||
"^ *(\\d+)(?:\\.\\d+)?" // time
|
||||
"(?: +([\\w\\d._-]+))?" // optional user
|
||||
" +(\\d+)" // pid
|
||||
" +(\\d+)" // tid
|
||||
" +([A-Z])" // priority
|
||||
" +(.+?) *: (.*)$" // tag and message
|
||||
);
|
||||
static const Pcre2Regex BufferRegex("^--------- (?:beginning of|switch to) (\\w+)$");
|
||||
|
||||
static std::string leftpad(const std::string& str, size_t characters);
|
||||
static inline char to_char(Priority priority);
|
||||
static inline std::string rightpad(const std::string& str, size_t characters);
|
||||
|
||||
static inline Priority priority_from(char c);
|
||||
static inline long to_long(const char* str, const char* expected_end);
|
||||
static unsigned long long to_ull(const char* str, const char* expected_end);
|
||||
|
||||
const char* to_string(Priority priority) {
|
||||
switch (priority) {
|
||||
case Priority::Verbose: return "Verbose";
|
||||
|
@ -44,30 +59,6 @@ const char* to_string_lower(Buffer buffer) {
|
|||
}
|
||||
}
|
||||
|
||||
static std::string leftpad(const std::string& str, size_t characters) {
|
||||
return str.size() >= characters
|
||||
? str
|
||||
: std::string(characters - str.size(), ' ') + str;
|
||||
}
|
||||
|
||||
static inline char to_char(Priority priority) {
|
||||
switch (priority) {
|
||||
case Priority::Verbose: return 'V';
|
||||
case Priority::Debug: return 'D';
|
||||
case Priority::Info: return 'I';
|
||||
case Priority::Warn: return 'W';
|
||||
case Priority::Error: return 'E';
|
||||
case Priority::Fatal: return 'F';
|
||||
case Priority::Unknown: return 'U';
|
||||
}
|
||||
}
|
||||
|
||||
static inline std::string rightpad(const std::string& str, size_t characters) {
|
||||
return str.size() >= characters
|
||||
? str
|
||||
: str + std::string(characters - str.size(), ' ');
|
||||
}
|
||||
|
||||
std::string to_string(const LogcatEntry& logcat_entry) {
|
||||
char logcat_style_time_as_str[32] = {0};
|
||||
strftime(logcat_style_time_as_str, 31 * sizeof(char), "%Y-%m-%d %H:%M:%S", &logcat_entry.time);
|
||||
|
@ -81,45 +72,6 @@ std::string to_string(const LogcatEntry& logcat_entry) {
|
|||
+ ": " + logcat_entry.message;
|
||||
}
|
||||
|
||||
static inline Priority priority_from(char c) {
|
||||
switch (c) {
|
||||
case 'V': return Priority::Verbose;
|
||||
case 'D': return Priority::Debug;
|
||||
case 'I': return Priority::Info;
|
||||
case 'W': return Priority::Warn;
|
||||
case 'E': return Priority::Error;
|
||||
case 'F': return Priority::Fatal;
|
||||
default: return Priority::Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
static inline long to_long(const char* str, const char* expected_end) {
|
||||
char* endptr;
|
||||
|
||||
errno = 0;
|
||||
long res = strtol(str, &endptr, 10);
|
||||
if (endptr != expected_end) {
|
||||
throw std::invalid_argument(std::string(str) + " has trailing text");
|
||||
} else if (res == LONG_MAX && errno == ERANGE) {
|
||||
throw std::overflow_error(std::string(str) + " is too big");
|
||||
} else if (res == LONG_MIN && errno == ERANGE) {
|
||||
throw std::underflow_error(std::string(str) + " is too small");
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static unsigned long long to_unsigned_long_long(const char* str, const char* expected_end) {
|
||||
char* endptr;
|
||||
|
||||
errno = 0;
|
||||
unsigned long long res = strtoull(str, &endptr, 10);
|
||||
if (endptr != expected_end) {
|
||||
throw std::invalid_argument(std::string(str) + " has trailing text");
|
||||
} else if (res == ULLONG_MAX && errno == ERANGE) {
|
||||
throw std::overflow_error(std::string(str) + " is too big");
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
std::optional<LogcatEntry> try_parse_logcat_entry(char* buf, size_t length, Buffer buffer) {
|
||||
regmatch_t matches[8];
|
||||
|
@ -133,24 +85,25 @@ std::optional<LogcatEntry> try_parse_logcat_entry(char* buf, size_t length, Buff
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> user;
|
||||
if (matches[2].rm_so > -1 && matches[2].rm_eo > -1) {
|
||||
user = std::string(&buf[matches[2].rm_so], static_cast<size_t>(matches[2].rm_eo - matches[2].rm_so));
|
||||
}
|
||||
auto group_exists = [](const regmatch_t& match) { return match.rm_so > -1 && match.rm_eo > -1; };
|
||||
auto group_long = [&](const regmatch_t& match) { return to_long(&buf[match.rm_so], &buf[match.rm_eo]); };
|
||||
auto group_ull = [&](const regmatch_t& match) { return to_ull(&buf[match.rm_so], &buf[match.rm_eo]); };
|
||||
auto group_string = [&](const regmatch_t& match) { return std::string(&buf[match.rm_so], static_cast<size_t>(match.rm_eo - match.rm_so)); };
|
||||
auto group_priority = [&](const regmatch_t& match) { return priority_from(buf[match.rm_so]); };
|
||||
|
||||
// if pcre2 gives us negative offsets then i'll die
|
||||
LogcatEntry logcat_entry = {
|
||||
.buffer = buffer,
|
||||
.buffer = buffer,
|
||||
// time to be set at the end
|
||||
.user = std::move(user),
|
||||
.pid = to_unsigned_long_long(&buf[matches[3].rm_so], &buf[matches[3].rm_eo]),
|
||||
.tid = to_unsigned_long_long(&buf[matches[4].rm_so], &buf[matches[4].rm_eo]),
|
||||
.priority = priority_from(buf[matches[5].rm_so]),
|
||||
.tag = std::string(&buf[matches[6].rm_so], static_cast<size_t>(matches[6].rm_eo - matches[6].rm_so)),
|
||||
.message = std::string(&buf[matches[7].rm_so], static_cast<size_t>(matches[7].rm_eo - matches[7].rm_so)),
|
||||
.user = group_exists(matches[2]) ? std::optional(group_string(matches[2])) : std::nullopt,
|
||||
.pid = group_ull(matches[3]),
|
||||
.tid = group_ull(matches[4]),
|
||||
.priority = group_priority(matches[5]),
|
||||
.tag = group_string(matches[6]),
|
||||
.message = group_string(matches[7]),
|
||||
};
|
||||
|
||||
time_t time = to_long(&buf[matches[1].rm_so], &buf[matches[1].rm_eo]);
|
||||
time_t time = group_long(matches[1]);
|
||||
localtime_r(&time, &logcat_entry.time);
|
||||
return std::move(logcat_entry);
|
||||
}
|
||||
|
@ -241,3 +194,69 @@ void to_json(nlohmann::json& j, const Priority& priority) {
|
|||
case Priority::Fatal: j = "FATAL"; break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static std::string leftpad(const std::string& str, size_t characters) {
|
||||
return str.size() >= characters
|
||||
? str
|
||||
: std::string(characters - str.size(), ' ') + str;
|
||||
}
|
||||
|
||||
static inline char to_char(Priority priority) {
|
||||
switch (priority) {
|
||||
case Priority::Verbose: return 'V';
|
||||
case Priority::Debug: return 'D';
|
||||
case Priority::Info: return 'I';
|
||||
case Priority::Warn: return 'W';
|
||||
case Priority::Error: return 'E';
|
||||
case Priority::Fatal: return 'F';
|
||||
case Priority::Unknown: return 'U';
|
||||
}
|
||||
}
|
||||
|
||||
static inline std::string rightpad(const std::string& str, size_t characters) {
|
||||
return str.size() >= characters
|
||||
? str
|
||||
: str + std::string(characters - str.size(), ' ');
|
||||
}
|
||||
|
||||
|
||||
static inline Priority priority_from(char c) {
|
||||
switch (c) {
|
||||
case 'V': return Priority::Verbose;
|
||||
case 'D': return Priority::Debug;
|
||||
case 'I': return Priority::Info;
|
||||
case 'W': return Priority::Warn;
|
||||
case 'E': return Priority::Error;
|
||||
case 'F': return Priority::Fatal;
|
||||
default: return Priority::Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
static inline long to_long(const char* str, const char* expected_end) {
|
||||
char* endptr;
|
||||
|
||||
errno = 0;
|
||||
long res = strtol(str, &endptr, 10);
|
||||
if (endptr != expected_end) {
|
||||
throw std::invalid_argument(std::string(str) + " has trailing text");
|
||||
} else if (res == LONG_MAX && errno == ERANGE) {
|
||||
throw std::overflow_error(std::string(str) + " is too big");
|
||||
} else if (res == LONG_MIN && errno == ERANGE) {
|
||||
throw std::underflow_error(std::string(str) + " is too small");
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static unsigned long long to_ull(const char* str, const char* expected_end) {
|
||||
char* endptr;
|
||||
|
||||
errno = 0;
|
||||
unsigned long long res = strtoull(str, &endptr, 10);
|
||||
if (endptr != expected_end) {
|
||||
throw std::invalid_argument(std::string(str) + " has trailing text");
|
||||
} else if (res == ULLONG_MAX && errno == ERANGE) {
|
||||
throw std::overflow_error(std::string(str) + " is too big");
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue