diff options
| author | Zachary Turner <zturner@google.com> | 2017-04-25 20:21:35 +0000 | 
|---|---|---|
| committer | Zachary Turner <zturner@google.com> | 2017-04-25 20:21:35 +0000 | 
| commit | e46b4498b8f11925986704196094eb6a89f6e3dc (patch) | |
| tree | 37c5d2542da365ca1f66184ff66cb8cf223bf220 /llvm | |
| parent | 9b52d67e1729f5972cdd366c62f314de531c3f7d (diff) | |
| download | bcm5719-llvm-e46b4498b8f11925986704196094eb6a89f6e3dc.tar.gz bcm5719-llvm-e46b4498b8f11925986704196094eb6a89f6e3dc.zip  | |
[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.
llvm-svn: 301356
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  | 

