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