[llvm] r301356 - [StringExtras] Add a fromHex to complement toHex.

Zachary Turner via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 25 13:21:36 PDT 2017


Author: zturner
Date: Tue Apr 25 15:21:35 2017
New Revision: 301356

URL: http://llvm.org/viewvc/llvm-project?rev=301356&view=rev
Log:
[StringExtras] Add a fromHex to complement toHex.

We already have a function toHex that will convert a string like
"\xFF\xFF" to the string "FFFF", but we do not have one that goes
the other way - i.e. to convert a textual string representing a
sequence of hexadecimal characters into the corresponding actual
bytes.  This patch adds such a function.

Modified:
    llvm/trunk/include/llvm/ADT/StringExtras.h
    llvm/trunk/unittests/ADT/StringExtrasTest.cpp

Modified: llvm/trunk/include/llvm/ADT/StringExtras.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/StringExtras.h?rev=301356&r1=301355&r2=301356&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/StringExtras.h (original)
+++ llvm/trunk/include/llvm/ADT/StringExtras.h Tue Apr 25 15:21:35 2017
@@ -76,6 +76,36 @@ static inline std::string toHex(StringRe
   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);

Modified: llvm/trunk/unittests/ADT/StringExtrasTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/StringExtrasTest.cpp?rev=301356&r1=301355&r2=301356&view=diff
==============================================================================
--- llvm/trunk/unittests/ADT/StringExtrasTest.cpp (original)
+++ llvm/trunk/unittests/ADT/StringExtrasTest.cpp Tue Apr 25 15:21:35 2017
@@ -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




More information about the llvm-commits mailing list