openMSX
HexDump.cc
Go to the documentation of this file.
1 #include "HexDump.hh"
2 #include "likely.hh"
3 #include "strCat.hh"
4 #include <algorithm>
5 #include <cassert>
6 
7 namespace HexDump {
8 
9 using std::string;
10 using openmsx::MemBuffer;
11 
12 static char encode2(uint8_t x)
13 {
14  return (x < 10) ? (x + '0') : (x - 10 + 'A');
15 }
16 static string encode(uint8_t x)
17 {
18  return strCat(encode2(x >> 4), encode2(x & 15));
19 }
20 string encode(const uint8_t* input, size_t len, bool newlines)
21 {
22  string ret;
23  while (len) {
24  if (newlines && !ret.empty()) ret += '\n';
25  int t = int(std::min<size_t>(16, len));
26  for (int i = 0; i < t; ++i) {
27  ret += encode(*input++);
28  if (i != (t - 1)) ret += ' ';
29  }
30  len -= t;
31  }
32  return ret;
33 }
34 
35 static 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(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::make_pair(std::move(ret), out);
70 }
71 
72 bool decode_inplace(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
#define unlikely(x)
Definition: likely.hh:15
void resize(size_t size)
Grow or shrink the memory block.
Definition: MemBuffer.hh:120
bool decode_inplace(string_view input, uint8_t *output, size_t outSize)
Definition: HexDump.cc:72
This class implements a (close approximation) of the std::string_view class.
Definition: string_view.hh:16
std::string strCat(Ts &&...ts)
Definition: strCat.hh:577
size_type size() const
Definition: string_view.hh:44
This class manages the lifetime of a block of memory.
Definition: MemBuffer.hh:37
TclObject t