aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Support/raw_ostream.cpp
diff options
context:
space:
mode:
authorGreg Clayton <gclayton@apple.com>2016-11-09 00:15:54 +0000
committerGreg Clayton <gclayton@apple.com>2016-11-09 00:15:54 +0000
commitbde0a1632b36a4f47a378459d9b333a91ac3948c (patch)
treef798b490df74f6247b20bb1bb76c40c8c5354bb5 /llvm/lib/Support/raw_ostream.cpp
parent4e9d6cd35404b8804150c43ea7a8375f398664f4 (diff)
downloadllvm-bde0a1632b36a4f47a378459d9b333a91ac3948c.zip
llvm-bde0a1632b36a4f47a378459d9b333a91ac3948c.tar.gz
llvm-bde0a1632b36a4f47a378459d9b333a91ac3948c.tar.bz2
Added the ability to dump hex bytes easily into a raw_ostream.
Unit tests were added to verify this functionality keeps working correctly. Example output for raw hex bytes: llvm::ArrayRef<uint8_t> Bytes = ...; llvm::outs() << format_hex_bytes(Bytes); 554889e5 4881ec70 04000048 8d051002 00004c8d 05fd0100 004c8b0d d0020000 Example output for raw hex bytes with offsets: llvm::outs() << format_hex_bytes(Bytes, 0x100000d10); 0x0000000100000d10: 554889e5 4881ec70 04000048 8d051002 0x0000000100000d20: 00004c8d 05fd0100 004c8b0d d0020000 Example output for raw hex bytes with ASCII with offsets: llvm::outs() << format_hex_bytes_with_ascii(Bytes, 0x100000d10); 0x0000000100000d10: 554889e5 4881ec70 04000048 8d051002 |UH.?H.?p...H....| 0x0000000100000d20: 00004c8d 05fd0100 004c8b0d d0020000 |..L..?...L..?...| The default groups bytes into 4 byte groups, but this can be changed to 1 byte: llvm::outs() << format_hex_bytes(Bytes, 0x100000d10, 16 /*NumPerLine*/, 1 /*ByteGroupSize*/); 0x0000000100000d10: 55 48 89 e5 48 81 ec 70 04 00 00 48 8d 05 10 02 0x0000000100000d20: 00 00 4c 8d 05 fd 01 00 00 4c 8b 0d d0 02 00 00 llvm::outs() << format_hex_bytes(Bytes, 0x100000d10, 16 /*NumPerLine*/, 2 /*ByteGroupSize*/); 0x0000000100000d10: 5548 89e5 4881 ec70 0400 0048 8d05 1002 0x0000000100000d20: 0000 4c8d 05fd 0100 004c 8b0d d002 0000 llvm::outs() << format_hex_bytes(Bytes, 0x100000d10, 8 /*NumPerLine*/, 1 /*ByteGroupSize*/); 0x0000000100000d10: 55 48 89 e5 48 81 ec 70 0x0000000100000d18: 04 00 00 48 8d 05 10 02 0x0000000100000d20: 00 00 4c 8d 05 fd 01 00 0x0000000100000d28: 00 4c 8b 0d d0 02 00 00 https://reviews.llvm.org/D26405 llvm-svn: 286316
Diffstat (limited to 'llvm/lib/Support/raw_ostream.cpp')
-rw-r--r--llvm/lib/Support/raw_ostream.cpp55
1 files changed, 55 insertions, 0 deletions
diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp
index b6835e3..42f121d 100644
--- a/llvm/lib/Support/raw_ostream.cpp
+++ b/llvm/lib/Support/raw_ostream.cpp
@@ -352,6 +352,61 @@ raw_ostream &raw_ostream::operator<<(const FormattedNumber &FN) {
return *this;
}
+raw_ostream &raw_ostream::operator<<(const FormattedHexBytes &FB) {
+ size_t LineIndex = 0;
+ const size_t Size = FB.Bytes.size();
+ HexPrintStyle OffsetStyle =
+ FB.Upper ? HexPrintStyle::PrefixUpper : HexPrintStyle::PrefixLower;
+ HexPrintStyle ByteStyle =
+ FB.Upper ? HexPrintStyle::Upper : HexPrintStyle::Lower;
+ while (LineIndex < Size) {
+ if (FB.FirstByteOffset.hasValue()) {
+ uint64_t Offset = FB.FirstByteOffset.getValue();
+ llvm::write_hex(*this, Offset + LineIndex, OffsetStyle,
+ sizeof(Offset) * 2 + 2);
+ *this << ": ";
+ }
+ // Print the hex bytes for this line
+ uint32_t I = 0;
+ for (I = 0; I < FB.NumPerLine; ++I) {
+ size_t Index = LineIndex + I;
+ if (Index >= Size)
+ break;
+ if (I && (I % FB.ByteGroupSize) == 0)
+ *this << " ";
+ llvm::write_hex(*this, FB.Bytes[Index], ByteStyle, 2);
+ }
+ uint32_t BytesDisplayed = I;
+ if (FB.ASCII) {
+ // Print any spaces needed for any bytes that we didn't print on this
+ // line so that the ASCII bytes are correctly aligned.
+ for (; I < FB.NumPerLine; ++I) {
+ if (I && (I % FB.ByteGroupSize) == 0)
+ indent(3);
+ else
+ indent(2);
+ }
+ *this << " |";
+ // Print the ASCII char values for each byte on this line
+ for (I = 0; I < FB.NumPerLine; ++I) {
+ size_t Index = LineIndex + I;
+ if (Index >= Size)
+ break;
+ char ch = (char)FB.Bytes[Index];
+ if (isprint(ch))
+ *this << ch;
+ else
+ *this << '.';
+ }
+ *this << '|';
+ }
+ LineIndex += BytesDisplayed;
+ if (LineIndex < Size)
+ *this << '\n';
+ }
+ return *this;
+}
+
/// indent - Insert 'NumSpaces' spaces.
raw_ostream &raw_ostream::indent(unsigned NumSpaces) {
static const char Spaces[] = " "