message/pack: Support packing string_views
Now we don't need to make an intermediate copy of our data into an array
before packing it into a payload.
Change-Id: Iac79a79e0ae95835cb67d617a966a92ce8dcd5f8
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/include/ipmid/message/pack.hpp b/include/ipmid/message/pack.hpp
index deb0a5a..388bf2f 100644
--- a/include/ipmid/message/pack.hpp
+++ b/include/ipmid/message/pack.hpp
@@ -20,6 +20,7 @@
#include <memory>
#include <optional>
#include <phosphor-logging/log.hpp>
+#include <string_view>
#include <tuple>
#include <utility>
#include <variant>
@@ -249,6 +250,22 @@
}
};
+/** @brief Specialization of PackSingle for std::string_view */
+template <>
+struct PackSingle<std::string_view>
+{
+ static int op(Payload& p, const std::string_view& t)
+ {
+ if (p.bitCount != 0)
+ {
+ return 1;
+ }
+ p.raw.reserve(p.raw.size() + t.size());
+ p.raw.insert(p.raw.end(), t.begin(), t.end());
+ return 0;
+ }
+};
+
/** @brief Specialization of PackSingle for std::variant<T, N> */
template <typename... T>
struct PackSingle<std::variant<T...>>
diff --git a/test/message/pack.cpp b/test/message/pack.cpp
index 7e6cf31..939b356 100644
--- a/test/message/pack.cpp
+++ b/test/message/pack.cpp
@@ -242,6 +242,20 @@
EXPECT_EQ(p.raw, std::vector<uint8_t>{0b1});
}
+TEST(PackBasics, StringView)
+{
+ ipmi::message::Payload p;
+ EXPECT_EQ(p.pack(std::string_view{"\x24\x30\x11"}), 0);
+ EXPECT_EQ(p.raw, std::vector<uint8_t>({0x24, 0x30, 0x11}));
+}
+
+TEST(PackBasics, StringViewUnaligned)
+{
+ ipmi::message::Payload p;
+ EXPECT_EQ(p.pack(true, std::string_view{"abc"}), 1);
+ EXPECT_EQ(p.raw, std::vector<uint8_t>({0b1}));
+}
+
TEST(PackBasics, OptionalEmpty)
{
// an optional will only pack if the value is present