summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorZachary Turner <zturner@google.com>2017-04-25 20:21:35 +0000
committerZachary Turner <zturner@google.com>2017-04-25 20:21:35 +0000
commite46b4498b8f11925986704196094eb6a89f6e3dc (patch)
tree37c5d2542da365ca1f66184ff66cb8cf223bf220 /llvm
parent9b52d67e1729f5972cdd366c62f314de531c3f7d (diff)
downloadbcm5719-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.h30
-rw-r--r--llvm/unittests/ADT/StringExtrasTest.cpp16
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
OpenPOWER on IntegriCloud