diff options
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/include/llvm/ADT/StringExtras.h | 30 | ||||
-rw-r--r-- | llvm/unittests/ADT/StringExtrasTest.cpp | 16 |
2 files changed, 46 insertions, 0 deletions
diff --git a/llvm/include/llvm/ADT/StringExtras.h b/llvm/include/llvm/ADT/StringExtras.h index 8214782bfe8..26f11924b77 100644 --- a/llvm/include/llvm/ADT/StringExtras.h +++ b/llvm/include/llvm/ADT/StringExtras.h @@ -76,6 +76,36 @@ static inline std::string toHex(StringRef Input) { return Output; } +static inline uint8_t hexFromNibbles(char MSB, char LSB) { + unsigned U1 = hexDigitValue(MSB); + unsigned U2 = hexDigitValue(LSB); + assert(U1 != -1U && U2 != -1U); + + return static_cast<uint8_t>((U1 << 4) | U2); +} + +/// Convert hexadecimal string \p Input to its binary representation. +/// The return string is half the size of \p Input. +static inline std::string fromHex(StringRef Input) { + if (Input.empty()) + return std::string(); + + std::string Output; + Output.reserve((Input.size() + 1) / 2); + if (Input.size() % 2 == 1) { + Output.push_back(hexFromNibbles('0', Input.front())); + Input = Input.drop_front(); + } + + assert(Input.size() % 2 == 0); + while (!Input.empty()) { + uint8_t Hex = hexFromNibbles(Input[0], Input[1]); + Output.push_back(Hex); + Input = Input.drop_front(2); + } + return Output; +} + static inline std::string utostr(uint64_t X, bool isNeg = false) { char Buffer[21]; char *BufPtr = std::end(Buffer); diff --git a/llvm/unittests/ADT/StringExtrasTest.cpp b/llvm/unittests/ADT/StringExtrasTest.cpp index afb984e405d..2cc9cad32b0 100644 --- a/llvm/unittests/ADT/StringExtrasTest.cpp +++ b/llvm/unittests/ADT/StringExtrasTest.cpp @@ -50,3 +50,19 @@ TEST(StringExtrasTest, JoinItems) { EXPECT_EQ("foo/bar/baz/x", join_items('/', Foo, Bar, Baz, X)); } + +TEST(StringExtrasTest, ToAndFromHex) { + std::vector<uint8_t> OddBytes = {0x5, 0xBD, 0x0D, 0x3E, 0xCD}; + std::string OddStr = "05BD0D3ECD"; + StringRef OddData(reinterpret_cast<const char *>(OddBytes.data()), + OddBytes.size()); + EXPECT_EQ(OddStr, toHex(OddData)); + EXPECT_EQ(OddData, fromHex(StringRef(OddStr).drop_front())); + + std::vector<uint8_t> EvenBytes = {0xA5, 0xBD, 0x0D, 0x3E, 0xCD}; + std::string EvenStr = "A5BD0D3ECD"; + StringRef EvenData(reinterpret_cast<const char *>(EvenBytes.data()), + EvenBytes.size()); + EXPECT_EQ(EvenStr, toHex(EvenData)); + EXPECT_EQ(EvenData, fromHex(EvenStr)); +}
\ No newline at end of file |