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