Skip to content

Commit

Permalink
Make LEndianBytesToInt and BEndianBytesToInt compatible with `u8s…
Browse files Browse the repository at this point in the history
…tring_view` (pixie-io#1592)

Summary: Make `LEndianBytesToInt` and `BEndianBytesToInt` compatible
with `u8string_view`

In order to parse Go's buildinfo header, we need to convert bytes
contained within a
[u8string_view](https://github.com/pixie-io/pixie/blob/c092058a5172396ea9bead1e209c2ed4e2336943/src/common/base/byte_utils.h#L30-L31)
(return values from
[ElfReader](https://github.com/pixie-io/pixie/blob/c092058a5172396ea9bead1e209c2ed4e2336943/src/stirling/obj_tools/elf_reader.cc#L608)).
This PR adds template specializations to the existing
`LEndianBytesToInt` and `BEndianBytesToInt` functions so they are
compatible with the `u8string_view` data type. This will allow the code
that will eventually parse a Go buildinfo header to be cleaner by
preventing an explicit conversion via `CreateStringView` as seen in
[this
commit](pixie-io@ae5dd20#diff-a5cd29c11ef9bc8c2ae92c1eb15bdace92d54e4e634fe5889a64979bd272e0b8R109-R110).

Relevant Issues: pixie-io#1300 pixie-io#1318

Type of change: /kind feature

Test Plan: Verified that the new test cases fail to compile without this
change and that this interface is more compatible for code linked above.

Signed-off-by: Dom Del Nano <ddelnano@pixielabs.ai>
  • Loading branch information
ddelnano authored Jul 11, 2023
1 parent a5bba59 commit 9571af1
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 4 deletions.
28 changes: 24 additions & 4 deletions src/common/base/byte_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ T ReverseBytes(const T* x) {
* @param buf The sequence of bytes.
* @return The decoded int value.
*/
template <typename T, size_t N = sizeof(T)>
T LEndianBytesToInt(std::string_view buf) {
template <typename T, typename TCharType = char, size_t N = sizeof(T)>
T LEndianBytesToIntInternal(std::basic_string_view<TCharType> buf) {
// Doesn't make sense to process more bytes than the destination type.
// Less bytes is okay, on the other hand, since the value will still fit.
static_assert(N <= sizeof(T));
Expand All @@ -78,6 +78,16 @@ T LEndianBytesToInt(std::string_view buf) {
return result;
}

template <typename T, size_t N = sizeof(T)>
T LEndianBytesToInt(std::string_view buf) {
return LEndianBytesToIntInternal<T, char, N>(buf);
}

template <typename T, size_t N = sizeof(T), typename TCharType = char>
T LEndianBytesToInt(std::basic_string_view<TCharType> buf) {
return LEndianBytesToIntInternal<T, TCharType, N>(buf);
}

/**
* Convert a little-endian string of bytes to a float/double.
*
Expand Down Expand Up @@ -134,8 +144,8 @@ void IntToBEndianBytes(int64_t num, TCharType (&result)[N]) {
* @param buf The sequence of bytes.
* @return The decoded int value.
*/
template <typename T, size_t N = sizeof(T)>
T BEndianBytesToInt(std::string_view buf) {
template <typename T, typename TCharType, size_t N = sizeof(T)>
T BEndianBytesToIntInternal(std::basic_string_view<TCharType> buf) {
// Doesn't make sense to process more bytes than the destination type.
// Less bytes is okay, on the other hand, since the value will still fit.
static_assert(N <= sizeof(T));
Expand All @@ -150,6 +160,16 @@ T BEndianBytesToInt(std::string_view buf) {
return result;
}

template <typename T, size_t N = sizeof(T)>
T BEndianBytesToInt(std::string_view buf) {
return BEndianBytesToIntInternal<T, char, N>(buf);
}

template <typename T, size_t N = sizeof(T), typename TCharType = char>
T BEndianBytesToInt(std::basic_string_view<TCharType> buf) {
return BEndianBytesToIntInternal<T, TCharType, N>(buf);
}

/**
* Convert a big-endian string of bytes to a float/double.
*
Expand Down
11 changes: 11 additions & 0 deletions src/common/base/byte_utils_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

#include "src/common/base/byte_utils.h"
#include "src/common/base/types.h"
#include "src/common/base/utils.h"

namespace px {
namespace utils {
Expand Down Expand Up @@ -109,6 +110,11 @@ TEST(UtilsTest, TestLEndianBytesToInt) {
EXPECT_EQ(
LEndianBytesToInt<int64_t>(std::string(ConstStringView("\xf0\xde\xbc\x9a\x78\x56\x34\xf2"))),
-0xdcba98765432110);

// Verify other std::basic_string_view types are supported
EXPECT_EQ(LEndianBytesToInt<int64_t>(
CreateStringView<u8string_view::value_type>("\xf0\xde\xbc\x9a\x78\x56\x34\x12")),
0x123456789abcdef0);
}

TEST(UtilsTest, TestLEndianBytesToFloat) {
Expand Down Expand Up @@ -238,6 +244,11 @@ TEST(UtilsTest, TestBEndianBytesToInt) {
EXPECT_EQ(
BEndianBytesToInt<int64_t>(std::string(ConstStringView("\xf2\x34\x56\x78\x9a\xbc\xde\xf0"))),
-0xdcba98765432110);

// Verify other std::basic_string_view types are supported
EXPECT_EQ(BEndianBytesToInt<int64_t>(
CreateStringView<u8string_view::value_type>("\x12\x34\x56\x78\x9a\xbc\xde\xf0")),
0x123456789abcdef0);
}

TEST(UtilsTest, TestBEndianBytesToFloat) {
Expand Down

0 comments on commit 9571af1

Please sign in to comment.