1249259Sdim#include "StreamWriter.h"
2249259Sdim#include "llvm/ADT/StringExtras.h"
3249259Sdim#include "llvm/Support/Format.h"
4249259Sdim#include <cctype>
5249259Sdim
6249259Sdimusing namespace llvm::support;
7249259Sdim
8249259Sdimnamespace llvm {
9249259Sdim
10249259Sdimraw_ostream &operator<<(raw_ostream &OS, const HexNumber& Value) {
11249259Sdim  uint64_t N = Value.Value;
12249259Sdim  // Zero is a special case.
13249259Sdim  if (N == 0)
14249259Sdim    return OS << "0x0";
15249259Sdim
16249259Sdim  char NumberBuffer[20];
17249259Sdim  char *EndPtr = NumberBuffer + sizeof(NumberBuffer);
18249259Sdim  char *CurPtr = EndPtr;
19249259Sdim
20249259Sdim  while (N) {
21249259Sdim    uintptr_t X = N % 16;
22249259Sdim    *--CurPtr = (X < 10 ? '0' + X : 'A' + X - 10);
23249259Sdim    N /= 16;
24249259Sdim  }
25249259Sdim
26249259Sdim  OS << "0x";
27249259Sdim  return OS.write(CurPtr, EndPtr - CurPtr);
28249259Sdim}
29249259Sdim
30249259Sdimvoid StreamWriter::printBinaryImpl(StringRef Label, StringRef Str,
31249259Sdim                                   ArrayRef<uint8_t> Data, bool Block) {
32249259Sdim  if (Data.size() > 16)
33249259Sdim    Block = true;
34249259Sdim
35249259Sdim  if (Block) {
36249259Sdim    startLine() << Label;
37249259Sdim    if (Str.size() > 0)
38249259Sdim      OS << ": " << Str;
39249259Sdim    OS << " (\n";
40249259Sdim    for (size_t addr = 0, end = Data.size(); addr < end; addr += 16) {
41249259Sdim      startLine() << format("  %04" PRIX64 ": ", uint64_t(addr));
42249259Sdim      // Dump line of hex.
43249259Sdim      for (size_t i = 0; i < 16; ++i) {
44249259Sdim        if (i != 0 && i % 4 == 0)
45249259Sdim          OS << ' ';
46249259Sdim        if (addr + i < end)
47249259Sdim          OS << hexdigit((Data[addr + i] >> 4) & 0xF, false)
48249259Sdim             << hexdigit(Data[addr + i] & 0xF, false);
49249259Sdim        else
50249259Sdim          OS << "  ";
51249259Sdim      }
52249259Sdim      // Print ascii.
53249259Sdim      OS << "  |";
54249259Sdim      for (std::size_t i = 0; i < 16 && addr + i < end; ++i) {
55249259Sdim        if (std::isprint(Data[addr + i] & 0xFF))
56249259Sdim          OS << Data[addr + i];
57249259Sdim        else
58249259Sdim          OS << ".";
59249259Sdim      }
60249259Sdim      OS << "|\n";
61249259Sdim    }
62249259Sdim
63249259Sdim    startLine() << ")\n";
64249259Sdim  } else {
65249259Sdim    startLine() << Label << ":";
66249259Sdim    if (Str.size() > 0)
67249259Sdim      OS << " " << Str;
68249259Sdim    OS << " (";
69249259Sdim    for (size_t i = 0; i < Data.size(); ++i) {
70249259Sdim      if (i > 0)
71249259Sdim        OS << " ";
72249259Sdim
73249259Sdim      OS << format("%02X", static_cast<int>(Data[i]));
74249259Sdim    }
75249259Sdim    OS << ")\n";
76249259Sdim  }
77249259Sdim}
78249259Sdim
79249259Sdim} // namespace llvm
80