1#include "StreamWriter.h"
2#include "llvm/ADT/StringExtras.h"
3#include "llvm/Support/Format.h"
4#include <cctype>
5
6using namespace llvm::support;
7
8namespace llvm {
9
10raw_ostream &operator<<(raw_ostream &OS, const HexNumber& Value) {
11  uint64_t N = Value.Value;
12  // Zero is a special case.
13  if (N == 0)
14    return OS << "0x0";
15
16  char NumberBuffer[20];
17  char *EndPtr = NumberBuffer + sizeof(NumberBuffer);
18  char *CurPtr = EndPtr;
19
20  while (N) {
21    uintptr_t X = N % 16;
22    *--CurPtr = (X < 10 ? '0' + X : 'A' + X - 10);
23    N /= 16;
24  }
25
26  OS << "0x";
27  return OS.write(CurPtr, EndPtr - CurPtr);
28}
29
30void StreamWriter::printBinaryImpl(StringRef Label, StringRef Str,
31                                   ArrayRef<uint8_t> Data, bool Block) {
32  if (Data.size() > 16)
33    Block = true;
34
35  if (Block) {
36    startLine() << Label;
37    if (Str.size() > 0)
38      OS << ": " << Str;
39    OS << " (\n";
40    for (size_t addr = 0, end = Data.size(); addr < end; addr += 16) {
41      startLine() << format("  %04" PRIX64 ": ", uint64_t(addr));
42      // Dump line of hex.
43      for (size_t i = 0; i < 16; ++i) {
44        if (i != 0 && i % 4 == 0)
45          OS << ' ';
46        if (addr + i < end)
47          OS << hexdigit((Data[addr + i] >> 4) & 0xF, false)
48             << hexdigit(Data[addr + i] & 0xF, false);
49        else
50          OS << "  ";
51      }
52      // Print ascii.
53      OS << "  |";
54      for (std::size_t i = 0; i < 16 && addr + i < end; ++i) {
55        if (std::isprint(Data[addr + i] & 0xFF))
56          OS << Data[addr + i];
57        else
58          OS << ".";
59      }
60      OS << "|\n";
61    }
62
63    startLine() << ")\n";
64  } else {
65    startLine() << Label << ":";
66    if (Str.size() > 0)
67      OS << " " << Str;
68    OS << " (";
69    for (size_t i = 0; i < Data.size(); ++i) {
70      if (i > 0)
71        OS << " ";
72
73      OS << format("%02X", static_cast<int>(Data[i]));
74    }
75    OS << ")\n";
76  }
77}
78
79} // namespace llvm
80