From f40ccf38e1819484bc28baa829cfc4148c153d3f Mon Sep 17 00:00:00 2001 From: Will Eccles Date: Fri, 10 May 2024 16:25:35 -0400 Subject: [PATCH] oopsie: add missing files --- src/ScpiUtil.h | 94 ++++++++++++++++++++++++++++++++++++++++++++++++ src/StringUtil.h | 50 ++++++++++++++++++++++++++ 2 files changed, 144 insertions(+) create mode 100644 src/ScpiUtil.h create mode 100644 src/StringUtil.h diff --git a/src/ScpiUtil.h b/src/ScpiUtil.h new file mode 100644 index 0000000..9ecbb5a --- /dev/null +++ b/src/ScpiUtil.h @@ -0,0 +1,94 @@ +#ifndef ABS_SCPI_DRIVER_SRC_SCPIUTIL_H +#define ABS_SCPI_DRIVER_SRC_SCPIUTIL_H + +#include + +#include +#include +#include + +#include "StringUtil.h" +#include "Util.h" + +namespace bci::abs::scpi { + +template +constexpr ErrorCode SplitRespFloats(std::string_view resp, + std::span out) { + resp = util::Trim(resp); + + std::size_t i = 0; + for (const auto val : std::views::split(resp, ',')) { + if (i >= out.size()) { + return ErrorCode::kInvalidResponse; + } + + if (auto v = + util::StrViewToFloat(std::string_view(val.begin(), val.end()))) { + out[i++] = *v; + } else { + return ErrorCode::kInvalidResponse; + } + } + + if (i < out.size()) { + return ErrorCode::kInvalidResponse; + } + + return ErrorCode::kSuccess; +} + +template +constexpr ErrorCode SplitRespFloats(std::string_view resp, + std::array& out) { + return SplitRespFloats(resp, std::span{out}); +} + +template +ErrorCode SplitRespMnemonics(std::string_view resp, + std::array& out) { + resp = util::Trim(resp); + + std::size_t i = 0; + for (const auto val : std::views::split(resp, ',')) { + if (i >= out.size()) { + return ErrorCode::kInvalidResponse; + } + + out[i++] = std::string(val.begin(), val.end()); + } + + if (i < out.size()) { + return ErrorCode::kInvalidResponse; + } +} + +template +constexpr ErrorCode SplitRespMnemonics( + std::string_view resp, std::array& out) { + resp = util::Trim(resp); + + std::size_t i = 0; + for (const auto val : std::views::split(resp, ',')) { + if (i >= out.size()) { + return ErrorCode::kInvalidResponse; + } + + out[i++] = std::string_view(val.begin(), val.end()); + } + + if (i < out.size()) { + return ErrorCode::kInvalidResponse; + } +} + +constexpr Result ParseFloatResponse(std::string_view text) { + if (auto f = util::StrViewToFloat(text)) { + return *f; + } + return util::Err(ErrorCode::kInvalidResponse); +} + +} // namespace bci::abs::scpi + +#endif /* ABS_SCPI_DRIVER_SRC_SCPIUTIL_H */ diff --git a/src/StringUtil.h b/src/StringUtil.h new file mode 100644 index 0000000..b2fba71 --- /dev/null +++ b/src/StringUtil.h @@ -0,0 +1,50 @@ +#ifndef ABS_SCPI_DRIVER_SRC_STRINGUTIL_H +#define ABS_SCPI_DRIVER_SRC_STRINGUTIL_H + +#include +#include +#include +#include + +#include + +namespace bci::abs::util { + +inline constexpr std::string_view kTrimChars{" \t\v\r\n\0"}; + +inline constexpr std::string_view Trim(std::string_view v) noexcept { + if (v.size() == 0) { + return v; + } + + auto s = v.find_first_not_of(kTrimChars); + v.remove_prefix((std::min)(s, v.size())); + if (v.size() <= 1) { + return v; + } + + s = v.find_last_not_of(kTrimChars); + if (s != v.npos) { + v.remove_suffix(v.size() - s - 1); + } + + return v; +} + +inline constexpr std::optional StrViewToFloat(std::string_view sv) { + if (sv.empty()) { + return std::nullopt; + } + + float f; + auto [ptr, ec] = fast_float::from_chars(sv.data(), sv.data() + sv.size(), f); + if (ec == std::errc()) { + return f; + } else { + return std::nullopt; + } +} + +} // namespace bci::abs::util + +#endif /* ABS_SCPI_DRIVER_SRC_STRINGUTIL_H */