Skip to content

Commit f2f26fc

Browse files
committed
util:dump-hex
1 parent d9245cd commit f2f26fc

File tree

4 files changed

+141
-0
lines changed

4 files changed

+141
-0
lines changed

util/BUILD

+23
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,28 @@
11
package(default_visibility = ["//visibility:public"])
22

3+
cc_library(
4+
name = "dump-hex",
5+
srcs = ["dump-hex.cc"],
6+
hdrs = ["dump-hex.h"],
7+
deps = [
8+
"//base:types",
9+
"//io:file",
10+
"//io:file-utils",
11+
"@com_google_absl//absl/container:fixed_array",
12+
],
13+
)
14+
15+
cc_test(
16+
name = "dump-hex_test",
17+
srcs = ["dump-hex_test.cc"],
18+
deps = [
19+
":dump-hex",
20+
"//base:types",
21+
"//io:memory-file",
22+
"@com_google_googletest//:gtest_main",
23+
],
24+
)
25+
326
cc_library(
427
name = "fibonacci-sequence",
528
hdrs = ["fibonacci-sequence.h"],

util/dump-hex.cc

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#include "util/dump-hex.h"
2+
3+
#include <cstddef>
4+
5+
#include "absl/container/fixed_array.h"
6+
#include "io/file-utils.h"
7+
8+
namespace util {
9+
namespace {
10+
11+
inline char to_hex(int value) {
12+
return value < 10 ? '0' + value : 'a' + value - 10;
13+
}
14+
15+
inline char to_char(int value) {
16+
return value >= 32 && value <= 127 ? value : '.';
17+
}
18+
19+
void put_uint8_hex(uint8_t value, char output[2]) {
20+
output[0] = to_hex(value >> 4);
21+
output[1] = to_hex(value & 0xf);
22+
}
23+
24+
void put_uint32_hex(uint32_t value, char output[8]) {
25+
for (int i = 0; i < 8; ++i) {
26+
output[i] = to_hex(value >> 28);
27+
value <<= 4;
28+
}
29+
}
30+
31+
} // namespace
32+
33+
void dump_hex(
34+
ConstBufferSpan input,
35+
io::File &output,
36+
const DumpHexOptions &options) {
37+
const size_t width = options.width;
38+
const size_t char_start = (width * 5 + 23) / 2;
39+
40+
absl::FixedArray<char, 80> line_buffer(char_start + width + 1, ' ');
41+
line_buffer[8] = ':';
42+
43+
uint32_t offset = options.offset;
44+
while (input.size() >= width) {
45+
put_uint32_hex(offset, &line_buffer[0]);
46+
for (size_t i = 0; i < width; ++i) {
47+
put_uint8_hex(input[i], &line_buffer[i * 5 / 2 + 10]);
48+
line_buffer[char_start + i] = to_char(input[i]);
49+
}
50+
line_buffer[char_start + width] = '\n';
51+
io::write(output, {line_buffer.data(), line_buffer.size()});
52+
input.remove_prefix(width);
53+
offset += width;
54+
}
55+
if (!input.empty()) {
56+
put_uint32_hex(offset, &line_buffer[0]);
57+
size_t i;
58+
for (i = 0; i < input.size(); ++i) {
59+
put_uint8_hex(input[i], &line_buffer[i * 5 / 2 + 10]);
60+
line_buffer[char_start + i] = to_char(input[i]);
61+
}
62+
for (; i < width; ++i) {
63+
line_buffer[i * 5 / 2 + 10] = ' ';
64+
line_buffer[i * 5 / 2 + 11] = ' ';
65+
}
66+
line_buffer[char_start + input.size()] = '\n';
67+
io::write(output, {line_buffer.data(), char_start + input.size() + 1});
68+
}
69+
}
70+
71+
} // namespace util

util/dump-hex.h

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#ifndef _UTIL_DUMP_HEX_H
2+
#define _UTIL_DUMP_HEX_H
3+
4+
#include <cstdint>
5+
6+
#include "base/types.h"
7+
#include "io/file.h"
8+
9+
namespace util {
10+
11+
struct DumpHexOptions {
12+
int width = 16;
13+
uint32_t offset = 0;
14+
};
15+
16+
void dump_hex(
17+
ConstBufferSpan input,
18+
io::File &output,
19+
const DumpHexOptions &options);
20+
21+
} // namespace util
22+
23+
#endif // _UTIL_DUMP_HEX_H

util/dump-hex_test.cc

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#include "util/dump-hex.h"
2+
3+
#include <string_view>
4+
#include <gtest/gtest.h>
5+
6+
#include "base/types.h"
7+
#include "io/memory-file.h"
8+
9+
namespace util {
10+
namespace {
11+
12+
TEST(DumpHexTest, basic) {
13+
io::MemoryFile file;
14+
DumpHexOptions options;
15+
options.width = 7;
16+
options.offset = 12;
17+
dump_hex("hello world\n", file, options);
18+
EXPECT_EQ(std::string_view(ConstBufferSpan(file.content())),
19+
"0000000c: 6865 6c6c 6f20 77 hello w\n"
20+
"00000013: 6f72 6c64 0a orld.\n");
21+
}
22+
23+
} // namespace
24+
} // namespace util

0 commit comments

Comments
 (0)