hex-decode.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
22 #include "hex-decode.hpp"
23 
24 namespace ndn {
25 namespace security {
26 namespace transform {
27 
28 static const int8_t C2H[256] = { // hex decoding pad.
29 // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
30  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0-15
31  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 16-31
32  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 32-47
33  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, // 48-63
34  -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 64-79
35  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 80-95
36  -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 96-111
37  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 112-127
38  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 128-143
39  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 144-159
40  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 160-175
41  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 176-191
42  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 192-207
43  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 208-223
44  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 224-239
45  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 240-255
46 };
47 
49  : m_hasOddByte(false)
50  , m_oddByte(0)
51 {
52 }
53 
54 size_t
55 HexDecode::convert(const uint8_t* hex, size_t hexLen)
56 {
57  if (hexLen == 0)
58  return 0;
59 
60  setOutputBuffer(toBytes(hex, hexLen));
61 
62  size_t totalDecodedLen = hexLen + (m_hasOddByte ? 1 : 0);
63  if (totalDecodedLen % 2 == 1) {
64  m_oddByte = hex[hexLen - 1];
65  m_hasOddByte = true;
66  }
67  else
68  m_hasOddByte = false;
69 
70  return hexLen;
71 }
72 
73 void
74 HexDecode::finalize()
75 {
76  if (m_hasOddByte)
77  BOOST_THROW_EXCEPTION(Error(getIndex(), "Incomplete input"));
78 }
79 
80 unique_ptr<Transform::OBuffer>
81 HexDecode::toBytes(const uint8_t* hex, size_t hexLen)
82 {
83  size_t bufferSize = (hexLen + (m_hasOddByte ? 1 : 0)) >> 1;
84  auto buffer = make_unique<OBuffer>(bufferSize);
85  uint8_t* buf = &buffer->front();
86 
87  if (m_hasOddByte) {
88  if (C2H[hex[0]] < 0 || C2H[m_oddByte] < 0)
89  BOOST_THROW_EXCEPTION(Error(getIndex(), "Wrong input byte"));
90 
91  buf[0] = (C2H[m_oddByte] << 4) + (C2H[hex[0]]);
92  buf += 1;
93  hex += 1;
94  hexLen -= 1;
95  }
96 
97  while (hexLen > 1) {
98  if (C2H[hex[0]] < 0 || C2H[hex[1]] < 0)
99  BOOST_THROW_EXCEPTION(Error(getIndex(), "Wrong input byte"));
100 
101  buf[0] = (C2H[hex[0]] << 4) + (C2H[hex[1]]);
102  buf += 1;
103  hex += 2;
104  hexLen -= 2;
105  }
106 
107  return buffer;
108 }
109 
110 unique_ptr<Transform>
112 {
113  return make_unique<HexDecode>();
114 }
115 
116 } // namespace transform
117 } // namespace security
118 } // namespace ndn
static const int8_t C2H[256]
Definition: hex-decode.cpp:28
Copyright (c) 2013-2017 Regents of the University of California.
Definition: common.hpp:66
void setOutputBuffer(unique_ptr< OBuffer > buffer)
Set output buffer to buffer.
Base class of transformation error.
HexDecode()
Create a hex decoding module.
Definition: hex-decode.cpp:48
unique_ptr< Transform > hexDecode()
Definition: hex-decode.cpp:111
size_t getIndex() const
Get the module index.