blob: 3d4ea3ff598bf72c4c3b98e55cffbada422b8ca2 [file] [log] [blame]
Alexander Afanasyev8828ca62015-07-02 13:40:09 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Davide Pesavento03115ce2017-01-27 01:17:55 -05003 * Copyright (c) 2013-2017 Regents of the University of California.
Alexander Afanasyev8828ca62015-07-02 13:40:09 -07004 *
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 "string-helper.hpp"
Davide Pesaventodd461432017-01-28 21:47:26 -050023#include "../encoding/buffer.hpp"
Alexander Afanasyev8828ca62015-07-02 13:40:09 -070024#include "../encoding/buffer-stream.hpp"
Davide Pesavento03115ce2017-01-27 01:17:55 -050025#include "../security/transform/buffer-source.hpp"
26#include "../security/transform/hex-decode.hpp"
Davide Pesaventofdda2412017-01-28 18:53:51 -050027#include "../security/transform/hex-encode.hpp"
Davide Pesavento03115ce2017-01-27 01:17:55 -050028#include "../security/transform/stream-sink.hpp"
29
Alexander Afanasyev8828ca62015-07-02 13:40:09 -070030#include <sstream>
Alexander Afanasyev8828ca62015-07-02 13:40:09 -070031
Alexander Afanasyev8828ca62015-07-02 13:40:09 -070032namespace ndn {
33
34void
Davide Pesaventofdda2412017-01-28 18:53:51 -050035printHex(std::ostream& os, const uint8_t* buffer, size_t length, bool wantUpperCase)
Alexander Afanasyev8828ca62015-07-02 13:40:09 -070036{
Davide Pesavento218e5be2017-02-03 00:13:47 -050037 namespace tr = security::transform;
38 BOOST_ASSERT(buffer != nullptr || length == 0);
39 tr::bufferSource(buffer, length) >> tr::hexEncode(wantUpperCase) >> tr::streamSink(os);
Alexander Afanasyev8828ca62015-07-02 13:40:09 -070040}
41
42void
Davide Pesaventofdda2412017-01-28 18:53:51 -050043printHex(std::ostream& os, const Buffer& buffer, bool wantUpperCase)
Alexander Afanasyev8828ca62015-07-02 13:40:09 -070044{
Davide Pesaventofdda2412017-01-28 18:53:51 -050045 return printHex(os, buffer.buf(), buffer.size(), wantUpperCase);
Alexander Afanasyev8828ca62015-07-02 13:40:09 -070046}
47
48std::string
Davide Pesaventofdda2412017-01-28 18:53:51 -050049toHex(const uint8_t* buffer, size_t length, bool wantUpperCase)
Alexander Afanasyev8828ca62015-07-02 13:40:09 -070050{
Alexander Afanasyev8828ca62015-07-02 13:40:09 -070051 std::ostringstream result;
Davide Pesavento218e5be2017-02-03 00:13:47 -050052 printHex(result, buffer, length, wantUpperCase);
Alexander Afanasyev8828ca62015-07-02 13:40:09 -070053 return result.str();
54}
55
56std::string
Davide Pesaventofdda2412017-01-28 18:53:51 -050057toHex(const Buffer& buffer, bool wantUpperCase)
Alexander Afanasyev8828ca62015-07-02 13:40:09 -070058{
Davide Pesavento218e5be2017-02-03 00:13:47 -050059 return toHex(buffer.buf(), buffer.size(), wantUpperCase);
Alexander Afanasyev8828ca62015-07-02 13:40:09 -070060}
61
62int
Davide Pesavento03115ce2017-01-27 01:17:55 -050063fromHexChar(char c)
Alexander Afanasyev8828ca62015-07-02 13:40:09 -070064{
65 if (c >= '0' && c <= '9')
66 return c - '0';
67 else if (c >= 'A' && c <= 'F')
68 return c - 'A' + 0xA;
69 else if (c >= 'a' && c <= 'f')
70 return c - 'a' + 0xA;
71 else
72 return -1;
73}
74
Davide Pesavento03115ce2017-01-27 01:17:55 -050075shared_ptr<Buffer>
Alexander Afanasyev8828ca62015-07-02 13:40:09 -070076fromHex(const std::string& hexString)
77{
Davide Pesavento03115ce2017-01-27 01:17:55 -050078 namespace tr = security::transform;
Alexander Afanasyev8828ca62015-07-02 13:40:09 -070079
80 OBufferStream os;
Davide Pesavento03115ce2017-01-27 01:17:55 -050081 try {
82 tr::bufferSource(hexString) >> tr::hexDecode() >> tr::streamSink(os);
83 }
84 catch (const tr::Error& e) {
85 BOOST_THROW_EXCEPTION(StringHelperError(std::string("Conversion from hex failed: ") + e.what()));
Alexander Afanasyev8828ca62015-07-02 13:40:09 -070086 }
87
Davide Pesavento03115ce2017-01-27 01:17:55 -050088 return os.buf();
Alexander Afanasyev8828ca62015-07-02 13:40:09 -070089}
90
Alexander Afanasyev8828ca62015-07-02 13:40:09 -070091std::string
92unescape(const std::string& str)
93{
94 std::ostringstream result;
95
96 for (size_t i = 0; i < str.size(); ++i) {
97 if (str[i] == '%' && i + 2 < str.size()) {
98 int hi = fromHexChar(str[i + 1]);
99 int lo = fromHexChar(str[i + 2]);
100
101 if (hi < 0 || lo < 0)
102 // Invalid hex characters, so just keep the escaped string.
103 result << str[i] << str[i + 1] << str[i + 2];
104 else
105 result << static_cast<char>((hi << 4) | lo);
106
107 // Skip ahead past the escaped value.
108 i += 2;
109 }
Davide Pesavento218e5be2017-02-03 00:13:47 -0500110 else {
Alexander Afanasyev8828ca62015-07-02 13:40:09 -0700111 // Just copy through.
112 result << str[i];
Davide Pesavento218e5be2017-02-03 00:13:47 -0500113 }
Alexander Afanasyev8828ca62015-07-02 13:40:09 -0700114 }
115
116 return result.str();
117}
118
119} // namespace ndn