* Return (potentially multi-line) string hex dump of a binary buffer in * 'hexdump -C' style. * Note that this exceeds 80 characters due to 64-bit offsets. */
| 73 | * Note that this exceeds 80 characters due to 64-bit offsets. |
| 74 | */ |
| 75 | std::string |
| 76 | hexDump(const void *buf, uint64_t bytes) |
| 77 | { |
| 78 | const unsigned char *cbuf = reinterpret_cast<const unsigned char *>(buf); |
| 79 | uint64_t i, j; |
| 80 | |
| 81 | std::ostringstream output; |
| 82 | for (i = 0; i < bytes; i += 16) { |
| 83 | char offset[17]; |
| 84 | char hex[16][3]; |
| 85 | char ascii[17]; |
| 86 | |
| 87 | snprintf(offset, sizeof(offset), "%016lx", i); |
| 88 | offset[sizeof(offset) - 1] = '\0'; |
| 89 | |
| 90 | for (j = 0; j < 16; j++) { |
| 91 | if ((i + j) >= bytes) { |
| 92 | snprintf(hex[j], sizeof(hex[0]), " "); |
| 93 | ascii[j] = '\0'; |
| 94 | } else { |
| 95 | snprintf(hex[j], sizeof(hex[0]), "%02x", |
| 96 | cbuf[i + j]); |
| 97 | hex[j][sizeof(hex[0]) - 1] = '\0'; |
| 98 | if (isprint(static_cast<int>(cbuf[i + j]))) |
| 99 | ascii[j] = cbuf[i + j]; |
| 100 | else |
| 101 | ascii[j] = '.'; |
| 102 | } |
| 103 | } |
| 104 | ascii[sizeof(ascii) - 1] = '\0'; |
| 105 | |
| 106 | output << |
| 107 | format("%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s " |
| 108 | "|%s|\n", offset, hex[0], hex[1], hex[2], hex[3], hex[4], |
| 109 | hex[5], hex[6], hex[7], hex[8], hex[9], hex[10], hex[11], |
| 110 | hex[12], hex[13], hex[14], hex[15], ascii); |
| 111 | } |
| 112 | return output.str(); |
| 113 | } |
| 114 | |
| 115 | |
| 116 | } // namespace Util |