YPC  0.2.0
bytes_common.h
1 #pragma once
2 #include <cstdint>
3 #include <stdexcept>
4 
5 namespace ypc {
6 namespace utc {
7 enum class byte_encode { raw_bytes, hex_bytes, base58_bytes, base64_bytes };
8 
9 namespace internal {
10 static inline char dec2hex(uint8_t dec) {
11  if (dec >= 16) {
12  throw std::invalid_argument("Invalid decimal");
13  }
14  if (dec >= 0 && dec <= 9) {
15  return '0' + dec;
16  }
17  return 'a' + dec - 10;
18 }
19 
20 static inline void to_hex(uint8_t num, uint8_t *high, uint8_t *low) {
21  *low = dec2hex(num & 0x0f);
22  *high = dec2hex(num >> 4);
23 }
24 
25 static inline uint8_t hex2dec(uint8_t hex) {
26  if (hex >= '0' && hex <= '9') {
27  return hex - '0';
28  }
29  if (hex >= 'A' && hex <= 'F') {
30  return hex - 'A' + 10;
31  }
32  if (hex >= 'a' && hex <= 'f') {
33  return hex - 'a' + 10;
34  }
35  throw std::invalid_argument("Invalid hex");
36 }
37 template <typename ByteType1, typename ByteType2>
38 bool convert_hex_to_bytes(const ByteType1 *s, size_t s_size, ByteType2 *to,
39  size_t len) {
40  static_assert(sizeof(ByteType1) == sizeof(ByteType2));
41  static_assert(sizeof(ByteType1) == 1);
42  if (len < s_size / 2) {
43  return false;
44  }
45  try {
46  size_t i = 0;
47  while (i * 2 < s_size && i * 2 + 1 < s_size) {
48  if (to) {
49  to[i] = (hex2dec(s[i * 2]) << 4) + hex2dec(s[i * 2 + 1]);
50  }
51  i++;
52  }
53  } catch (std::exception &e) {
54  return false;
55  }
56  return true;
57 }
58 
59 template <typename ByteType1, typename ByteType2>
60 bool convert_bytes_to_hex(const ByteType1 *s, size_t s_size, ByteType2 *to,
61  size_t len) {
62  if (len < 2 * s_size) {
63  return false;
64  }
65  for (size_t i = 0; i < s_size; i++) {
66  to_hex(s[i], to + 2 * i, to + 2 * i + 1);
67  }
68  return true;
69 }
70 
71 } // namespace internal
72 } // namespace utc
73 } // namespace ypc