blob: ed3c961a1f3e60b19c920e5cba39a81d629ca745 [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"
23#include "../encoding/buffer-stream.hpp"
Davide Pesavento03115ce2017-01-27 01:17:55 -050024#include "../security/transform/buffer-source.hpp"
25#include "../security/transform/hex-decode.hpp"
26#include "../security/transform/stream-sink.hpp"
27
28#include <boost/algorithm/string/trim.hpp>
Alexander Afanasyev8828ca62015-07-02 13:40:09 -070029
30#include <sstream>
31#include <iomanip>
32
Alexander Afanasyev8828ca62015-07-02 13:40:09 -070033namespace ndn {
34
35void
36printHex(std::ostream& os, const uint8_t* buffer, size_t length, bool isUpperCase/* = true*/)
37{
38 if (buffer == nullptr || length == 0)
39 return;
40
41 auto newFlags = std::ios::hex;
42 if (isUpperCase) {
43 newFlags |= std::ios::uppercase;
44 }
45 auto oldFlags = os.flags(newFlags);
46 auto oldFill = os.fill('0');
47 for (size_t i = 0; i < length; ++i) {
48 os << std::setw(2) << static_cast<unsigned int>(buffer[i]);
49 }
50 os.fill(oldFill);
51 os.flags(oldFlags);
52}
53
54void
55printHex(std::ostream& os, const Buffer& buffer, bool isUpperCase/* = true*/)
56{
57 return printHex(os, buffer.buf(), buffer.size(), isUpperCase);
58}
59
60std::string
61toHex(const uint8_t* buffer, size_t length, bool isUpperCase/* = true*/)
62{
63 if (buffer == nullptr || length == 0)
64 return "";
65
66 std::ostringstream result;
67 printHex(result, buffer, length, isUpperCase);
68 return result.str();
69}
70
71std::string
72toHex(const Buffer& buffer, bool isUpperCase/* = true*/)
73{
74 return toHex(buffer.buf(), buffer.size(), isUpperCase);
75}
76
77int
Davide Pesavento03115ce2017-01-27 01:17:55 -050078fromHexChar(char c)
Alexander Afanasyev8828ca62015-07-02 13:40:09 -070079{
80 if (c >= '0' && c <= '9')
81 return c - '0';
82 else if (c >= 'A' && c <= 'F')
83 return c - 'A' + 0xA;
84 else if (c >= 'a' && c <= 'f')
85 return c - 'a' + 0xA;
86 else
87 return -1;
88}
89
Davide Pesavento03115ce2017-01-27 01:17:55 -050090shared_ptr<Buffer>
Alexander Afanasyev8828ca62015-07-02 13:40:09 -070091fromHex(const std::string& hexString)
92{
Davide Pesavento03115ce2017-01-27 01:17:55 -050093 namespace tr = security::transform;
Alexander Afanasyev8828ca62015-07-02 13:40:09 -070094
95 OBufferStream os;
Davide Pesavento03115ce2017-01-27 01:17:55 -050096 try {
97 tr::bufferSource(hexString) >> tr::hexDecode() >> tr::streamSink(os);
98 }
99 catch (const tr::Error& e) {
100 BOOST_THROW_EXCEPTION(StringHelperError(std::string("Conversion from hex failed: ") + e.what()));
Alexander Afanasyev8828ca62015-07-02 13:40:09 -0700101 }
102
Davide Pesavento03115ce2017-01-27 01:17:55 -0500103 return os.buf();
Alexander Afanasyev8828ca62015-07-02 13:40:09 -0700104}
105
106void
107trimLeft(std::string& str)
108{
109 boost::algorithm::trim_left(str);
110}
111
112void
113trimRight(std::string& str)
114{
115 boost::algorithm::trim_right(str);
116}
117
118void
119trim(std::string& str)
120{
121 boost::algorithm::trim(str);
122}
123
124std::string
125unescape(const std::string& str)
126{
127 std::ostringstream result;
128
129 for (size_t i = 0; i < str.size(); ++i) {
130 if (str[i] == '%' && i + 2 < str.size()) {
131 int hi = fromHexChar(str[i + 1]);
132 int lo = fromHexChar(str[i + 2]);
133
134 if (hi < 0 || lo < 0)
135 // Invalid hex characters, so just keep the escaped string.
136 result << str[i] << str[i + 1] << str[i + 2];
137 else
138 result << static_cast<char>((hi << 4) | lo);
139
140 // Skip ahead past the escaped value.
141 i += 2;
142 }
143 else
144 // Just copy through.
145 result << str[i];
146 }
147
148 return result.str();
149}
150
151} // namespace ndn