blob: aa82461e8d0bdb8af504953ec0a488e176d77ee5 [file] [log] [blame]
Yingdi Yu38317e52015-07-22 13:58:02 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2013-2016 Regents of the University of California.
4 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6 *
7 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
20 */
21
22#include "hex-decode.hpp"
23
24namespace ndn {
25namespace security {
26namespace transform {
27
28static 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
48HexDecode::HexDecode()
49 : m_hasOddByte(false)
50 , m_oddByte(0)
51{
52}
53
54size_t
55HexDecode::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
73void
74HexDecode::finalize()
75{
76 if (m_hasOddByte)
77 BOOST_THROW_EXCEPTION(Error(getIndex(), "Incomplete input"));
78}
79
80unique_ptr<Transform::OBuffer>
81HexDecode::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
110unique_ptr<Transform>
111hexDecode()
112{
113 return make_unique<HexDecode>();
114}
115
116} // namespace transform
117} // namespace security
118} // namespace ndn