Skip to content

Commit

Permalink
Misc cleanup from other branches added (#340)
Browse files Browse the repository at this point in the history
  • Loading branch information
hhvrc authored Jan 24, 2025
1 parent 124471b commit 1397bd6
Show file tree
Hide file tree
Showing 6 changed files with 162 additions and 32 deletions.
126 changes: 119 additions & 7 deletions include/util/StringUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,43 +6,133 @@
#include <limits>
#include <string>
#include <string_view>
#include <utility>
#include <vector>

namespace OpenShock {
bool FormatToString(std::string& out, const char* format, ...);

constexpr std::string_view StringTrimLeft(std::string_view view) {
constexpr std::string_view StringTrimLeft(std::string_view view)
{
if (view.empty()) {
return view;
}

std::size_t pos = 0;
while (pos < view.size() && isspace(view[pos])) {
while (pos < view.size() && isspace(view[pos]) != 0) {
++pos;
}

return view.substr(pos);
}
constexpr std::string_view StringTrimRight(std::string_view view) {
constexpr std::string_view StringTrimRight(std::string_view view)
{
if (view.empty()) {
return view;
}

std::size_t pos = view.size() - 1;
while (pos > 0 && isspace(view[pos])) {
while (pos > 0 && isspace(view[pos]) != 0) {
--pos;
}

return view.substr(0, pos + 1);
}
constexpr std::string_view StringTrim(std::string_view view) {
constexpr std::string_view StringTrim(std::string_view view)
{
return StringTrimLeft(StringTrimRight(view));
}
constexpr bool StringStartsWith(std::string_view view, std::string_view prefix) {

constexpr bool StringHasPrefix(std::string_view view, char prefix)
{
return !view.empty() && view.front() == prefix;
}
constexpr bool StringHasPrefix(std::string_view view, std::string_view prefix)
{
return view.size() >= prefix.size() && view.substr(0, prefix.size()) == prefix;
}
constexpr bool StringHasSuffix(std::string_view view, char suffix)
{
return !view.empty() && view.back() == suffix;
}
constexpr bool StringHasSuffix(std::string_view view, std::string_view suffix)
{
return view.size() >= suffix.size() && view.substr(view.size() - suffix.size(), view.size()) == suffix;
}

constexpr std::string_view StringRemovePrefix(std::string_view view, char prefix)
{
if (StringHasPrefix(view, prefix)) view.remove_prefix(1);
return view;
}
constexpr std::string_view StringRemovePrefix(std::string_view view, std::string_view prefix)
{
if (StringHasPrefix(view, prefix)) view.remove_prefix(prefix.length());
return view;
}
constexpr std::string_view StringRemoveSuffix(std::string_view view, char suffix)
{
if (StringHasSuffix(view, suffix)) view.remove_suffix(1);
return view;
}
constexpr std::string_view StringRemoveSuffix(std::string_view view, std::string_view suffix)
{
if (StringHasSuffix(view, suffix)) view.remove_prefix(suffix.length());
return view;
}

constexpr std::string_view StringBeforeFirst(std::string_view view, char delimiter)
{
size_t pos = view.find(delimiter);
if (pos == std::string_view::npos) return view;
return view.substr(0, pos);
}
constexpr std::string_view StringBeforeFirst(std::string_view view, std::string_view delimiter)
{
size_t pos = view.find(delimiter);
if (pos == std::string_view::npos) return view;
return view.substr(0, pos);
}
constexpr std::string_view StringBeforeLast(std::string_view view, char delimiter)
{
size_t pos = view.find_last_of(delimiter);
if (pos == std::string_view::npos) return view;
return view.substr(0, pos);
}
constexpr std::string_view StringBeforeLast(std::string_view view, std::string_view delimiter)
{
size_t pos = view.find_last_of(delimiter);
if (pos == std::string_view::npos) return view;
return view.substr(0, pos);
}
constexpr std::string_view StringAfterFirst(std::string_view view, char delimiter)
{
size_t pos = view.find(delimiter);
if (pos == std::string_view::npos) return view;
return view.substr(pos + 1);
}
constexpr std::string_view StringAfterFirst(std::string_view view, std::string_view delimiter)
{
size_t pos = view.find(delimiter);
if (pos == std::string_view::npos) return view;
return view.substr(pos + delimiter.length());
}
constexpr std::string_view StringAfterLast(std::string_view view, char delimiter)
{
size_t pos = view.find_last_of(delimiter);
if (pos == std::string_view::npos) return view;
return view.substr(pos + 1);
}
constexpr std::string_view StringAfterLast(std::string_view view, std::string_view delimiter)
{
size_t pos = view.find_last_of(delimiter);
if (pos == std::string_view::npos) return view;
return view.substr(pos + delimiter.length());
}

template<std::size_t N>
constexpr bool TryStringSplit(std::string_view view, char delimiter, std::string_view (&out)[N]) {
constexpr bool TryStringSplit(std::string_view view, char delimiter, std::string_view (&out)[N])
{
std::size_t pos = 0;
std::size_t idx = 0;
while (pos < view.size() && idx < N) {
Expand All @@ -62,8 +152,30 @@ namespace OpenShock {
std::vector<std::string_view> StringSplit(std::string_view view, bool (*predicate)(char delimiter), std::size_t maxSplits = std::numeric_limits<std::size_t>::max());
std::vector<std::string_view> StringSplitNewLines(std::string_view view, std::size_t maxSplits = std::numeric_limits<std::size_t>::max());
std::vector<std::string_view> StringSplitWhiteSpace(std::string_view view, std::size_t maxSplits = std::numeric_limits<std::size_t>::max());
constexpr std::pair<std::string_view, std::string_view> StringSplitByFirst(std::string_view view, char delimiter)
{
size_t pos = view.find(delimiter);
return std::make_pair(view.substr(0, pos), pos == std::string_view::npos ? std::string_view() : view.substr(pos + 1));
}
constexpr std::pair<std::string_view, std::string_view> StringSplitByFirst(std::string_view view, std::string_view delimiter)
{
size_t pos = view.find(delimiter);
return std::make_pair(view.substr(0, pos), pos == std::string_view::npos ? std::string_view() : view.substr(pos + delimiter.length()));
}
constexpr std::pair<std::string_view, std::string_view> StringSplitByLast(std::string_view view, char delimiter)
{
size_t pos = view.find_last_of(delimiter);
return std::make_pair(view.substr(0, pos), pos == std::string_view::npos ? std::string_view() : view.substr(pos + 1));
}
constexpr std::pair<std::string_view, std::string_view> StringSplitByLast(std::string_view view, std::string_view delimiter)
{
size_t pos = view.find_last_of(delimiter);
return std::make_pair(view.substr(0, pos), pos == std::string_view::npos ? std::string_view() : view.substr(pos + delimiter.length()));
}

bool StringIEquals(std::string_view a, std::string_view b);
bool StringIContains(std::string_view haystack, std::string_view needle);
bool StringHasPrefixIC(std::string_view view, std::string_view prefix);

String StringToArduinoString(std::string_view view);
} // namespace OpenShock
4 changes: 1 addition & 3 deletions src/OtaUpdateManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -639,9 +639,7 @@ bool OtaUpdateManager::TryGetFirmwareRelease(const OpenShock::SemVer& version, F
auto hash = OpenShock::StringTrim(parts[0]);
auto file = OpenShock::StringTrim(parts[1]);

if (OpenShock::StringStartsWith(file, "./"sv)) {
file = file.substr(2);
}
file = OpenShock::StringRemovePrefix(file, "./"sv);

if (hash.size() != 64) {
OS_LOGE(TAG, "Invalid hash: %.*s", hash.size(), hash.data());
Expand Down
39 changes: 22 additions & 17 deletions src/SemVer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -331,17 +331,11 @@ bool OpenShock::TryParseSemVer(std::string_view semverStr, SemVer& semver)

std::string_view majorStr = parts[0], minorStr = parts[1], patchStr = parts[2];

auto dashIdx = patchStr.find('-');
if (dashIdx != std::string_view::npos) {
semver.prerelease = patchStr.substr(dashIdx + 1);
patchStr = patchStr.substr(0, dashIdx);
}
size_t plusIdx = patchStr.find('+');
size_t dashIdx = patchStr.find('-');

auto plusIdx = semver.prerelease.find('+');
if (plusIdx != std::string_view::npos) {
semver.build = semver.prerelease.substr(plusIdx + 1);
semver.prerelease = semver.prerelease.substr(0, plusIdx);
}
std::string_view restStr = patchStr.substr(std::min(dashIdx, plusIdx));
patchStr.remove_suffix(restStr.length());

if (!Convert::ToUint16(majorStr, semver.major)) {
OS_LOGE(TAG, "Invalid major version: %.*s", majorStr.length(), majorStr.data());
Expand All @@ -358,14 +352,25 @@ bool OpenShock::TryParseSemVer(std::string_view semverStr, SemVer& semver)
return false;
}

if (!semver.prerelease.empty() && !_semverIsPrerelease(semver.prerelease)) {
OS_LOGE(TAG, "Invalid prerelease: %s", semver.prerelease.c_str());
return false;
}
if (!restStr.empty()) {
if (plusIdx != std::string_view::npos) {
semver.build = restStr.substr((plusIdx - patchStr.length()) + 1);
patchStr.remove_suffix(semver.build.length() + 1);

if (!semver.build.empty() && !_semverIsBuild(semver.build)) {
OS_LOGE(TAG, "Invalid build: %s", semver.build.c_str());
return false;
if (!semver.build.empty() && !_semverIsBuild(semver.build)) {
OS_LOGE(TAG, "Invalid build: %s", semver.build.c_str());
return false;
}
}

if (dashIdx != std::string_view::npos) {
semver.prerelease = patchStr.substr(1);

if (!semver.prerelease.empty() && !_semverIsPrerelease(semver.prerelease)) {
OS_LOGE(TAG, "Invalid prerelease: %s", semver.prerelease.c_str());
return false;
}
}
}

return true;
Expand Down
2 changes: 1 addition & 1 deletion src/serial/SerialInputHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ void _echoHandleSerialInput(std::string_view buffer, bool hasData)
}

// If the command starts with a $, it's a automated command, don't echo it
if (!buffer.empty() && buffer[0] == '$') {
if (OpenShock::StringHasPrefix(buffer, '$')) {
return;
}

Expand Down
10 changes: 6 additions & 4 deletions src/serial/command_handlers/lcgoverride.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@

const char* TAG = "Serial::CommandHandlers::LcgOverride";

void _handleLcgOverrideCommand(std::string_view arg, bool isAutomated) {
void _handleLcgOverrideCommand(std::string_view arg, bool isAutomated)
{
if (arg.empty()) {
std::string lcgOverride;
if (!OpenShock::Config::GetBackendLCGOverride(lcgOverride)) {
Expand All @@ -20,7 +21,7 @@ void _handleLcgOverrideCommand(std::string_view arg, bool isAutomated) {
return;
}

if (OpenShock::StringStartsWith(arg, "clear"sv)) {
if (OpenShock::StringHasPrefix(arg, "clear"sv)) {
if (arg.size() != 5) {
SERPR_ERROR("Invalid command (clear command should not have any arguments)");
return;
Expand All @@ -35,7 +36,7 @@ void _handleLcgOverrideCommand(std::string_view arg, bool isAutomated) {
return;
}

if (OpenShock::StringStartsWith(arg, "set "sv)) {
if (OpenShock::StringHasPrefix(arg, "set "sv)) {
if (arg.size() <= 4) {
SERPR_ERROR("Invalid command (set command should have an argument)");
return;
Expand Down Expand Up @@ -90,7 +91,8 @@ void _handleLcgOverrideCommand(std::string_view arg, bool isAutomated) {
SERPR_ERROR("Invalid subcommand");
}

OpenShock::Serial::CommandGroup OpenShock::Serial::CommandHandlers::LcgOverrideHandler() {
OpenShock::Serial::CommandGroup OpenShock::Serial::CommandHandlers::LcgOverrideHandler()
{
auto group = OpenShock::Serial::CommandGroup("lcgoverride"sv);

auto& getCommand = group.addCommand("Get the domain overridden for LCG endpoint (if any)."sv, _handleLcgOverrideCommand);
Expand Down
13 changes: 13 additions & 0 deletions src/util/StringUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const char* const TAG = "StringUtils";

#include "Logging.h"

#include <algorithm>
#include <cstdarg>
#include <cstring>

Expand Down Expand Up @@ -128,6 +129,18 @@ bool OpenShock::StringIEquals(std::string_view a, std::string_view b)
if (a.size() != b.size()) return false;
return strncasecmp(a.data(), b.data(), a.size()) == 0;
}
bool OpenShock::StringIContains(std::string_view haystack, std::string_view needle)
{
if (haystack.size() < needle.size()) return false;
if (haystack.size() == needle.size()) return StringIEquals(haystack, needle);

return std::search(haystack.begin(), haystack.end(), needle.begin(), needle.end(), [](char hc, char nc) { return tolower(hc) == tolower(nc); }) != haystack.end();
}
bool OpenShock::StringHasPrefixIC(std::string_view view, std::string_view prefix)
{
if (view.size() < prefix.size()) return false;
return StringIEquals(view.substr(0, prefix.size()), prefix);
}

String OpenShock::StringToArduinoString(std::string_view view) {
return String(view.data(), view.size());
Expand Down

1 comment on commit 1397bd6

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cpp-Linter Report ⚠️

Some files did not pass the configured checks!

clang-format (v18.1.3) reports: 1 file(s) not formatted
  • src/util/StringUtils.cpp

Have any feedback or feature suggestions? Share it here.

Please sign in to comment.