openMSX
HexDump.cc
Go to the documentation of this file.
1#include "HexDump.hh"
2#include "narrow.hh"
3#include "strCat.hh"
4#include "xrange.hh"
5#include <algorithm>
6#include <cassert>
7
8namespace HexDump {
9
11
12[[nodiscard]] static constexpr char encode2(uint8_t x)
13{
14 return (x < 10) ? char(x + '0') : char(x - 10 + 'A');
15}
16[[nodiscard]] static auto encode(uint8_t x)
17{
18 return tmpStrCat(encode2(x >> 4), encode2(x & 15));
19}
20std::string encode(std::span<const uint8_t> input, bool newlines)
21{
22 std::string ret;
23 size_t in = 0;
24 auto len = input.size();
25 while (len) {
26 if (newlines && !ret.empty()) ret += '\n';
27 auto t = int(std::min<size_t>(16, len));
28 for (auto i : xrange(t)) {
29 ret += encode(input[in++]);
30 if (i != (t - 1)) ret += ' ';
31 }
32 len -= t;
33 }
34 return ret;
35}
36
37[[nodiscard]] static constexpr int decode(char x)
38{
39 if (('0' <= x) && (x <= '9')) {
40 return x - '0';
41 } else if (('A' <= x) && (x <= 'F')) {
42 return x - 'A' + 10;
43 } else if (('a' <= x) && (x <= 'f')) {
44 return x - 'a' + 10;
45 } else {
46 return -1;
47 }
48}
49std::pair<MemBuffer<uint8_t>, size_t> decode(std::string_view input)
50{
51 auto inSize = input.size();
52 auto outSize = inSize / 2; // overestimation
53 MemBuffer<uint8_t> ret(outSize); // too big
54
55 size_t out = 0;
56 bool flip = true;
57 uint8_t tmp = 0;
58 for (char c : input) {
59 int d = decode(c);
60 if (d == -1) continue;
61 assert(d >= 0);
62 assert(d <= 15);
63 if (flip) {
64 tmp = narrow<uint8_t>(d);
65 } else {
66 ret[out++] = narrow<uint8_t>((tmp << 4) | d);
67 }
68 flip = !flip;
69 }
70
71 assert(outSize >= out);
72 ret.resize(out); // shrink to correct size
73 return {std::move(ret), out};
74}
75
76bool decode_inplace(std::string_view input, std::span<uint8_t> output)
77{
78 size_t out = 0;
79 auto outSize = output.size();
80 bool flip = true;
81 uint8_t tmp = 0;
82 for (char c : input) {
83 int d = decode(c);
84 if (d == -1) continue;
85 assert(d >= 0);
86 assert(d <= 15);
87 if (flip) {
88 tmp = narrow<uint8_t>(d);
89 } else {
90 if (out == outSize) [[unlikely]] return false;
91 output[out++] = narrow<uint8_t>((tmp << 4) | d);
92 }
93 flip = !flip;
94 }
95
96 return out == outSize;
97}
98
99} // namespace HexDump
TclObject t
This class manages the lifetime of a block of memory.
Definition MemBuffer.hh:29
void resize(size_t size)
Grow or shrink the memory block.
Definition MemBuffer.hh:111
bool decode_inplace(std::string_view input, std::span< uint8_t > output)
Definition HexDump.cc:76
TemporaryString tmpStrCat(Ts &&... ts)
Definition strCat.hh:742
constexpr auto xrange(T e)
Definition xrange.hh:132