Alexander Afanasyev | 8828ca6 | 2015-07-02 13:40:09 -0700 | [diff] [blame] | 1 | /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ |
Davide Pesavento | 38a061d | 2018-02-15 22:45:48 -0500 | [diff] [blame] | 2 | /* |
| 3 | * Copyright (c) 2013-2018 Regents of the University of California. |
Alexander Afanasyev | 8828ca6 | 2015-07-02 13:40:09 -0700 | [diff] [blame] | 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 "util/string-helper.hpp" |
Davide Pesavento | dd46143 | 2017-01-28 21:47:26 -0500 | [diff] [blame] | 23 | #include "encoding/buffer.hpp" |
Alexander Afanasyev | 8828ca6 | 2015-07-02 13:40:09 -0700 | [diff] [blame] | 24 | |
| 25 | #include "boost-test.hpp" |
Alexander Afanasyev | 8828ca6 | 2015-07-02 13:40:09 -0700 | [diff] [blame] | 26 | |
Davide Pesavento | 38a061d | 2018-02-15 22:45:48 -0500 | [diff] [blame] | 27 | #include <cctype> |
| 28 | #include <cstring> |
| 29 | |
Alexander Afanasyev | 8828ca6 | 2015-07-02 13:40:09 -0700 | [diff] [blame] | 30 | namespace ndn { |
| 31 | namespace util { |
| 32 | namespace test { |
| 33 | |
Davide Pesavento | 38a061d | 2018-02-15 22:45:48 -0500 | [diff] [blame] | 34 | using boost::test_tools::output_test_stream; |
| 35 | |
Davide Pesavento | eee3e82 | 2016-11-26 19:19:34 +0100 | [diff] [blame] | 36 | BOOST_AUTO_TEST_SUITE(Util) |
| 37 | BOOST_AUTO_TEST_SUITE(TestStringHelper) |
Alexander Afanasyev | 8828ca6 | 2015-07-02 13:40:09 -0700 | [diff] [blame] | 38 | |
Davide Pesavento | e78eeca | 2017-02-23 23:22:32 -0500 | [diff] [blame] | 39 | BOOST_AUTO_TEST_CASE(PrintHex) |
| 40 | { |
Davide Pesavento | 38a061d | 2018-02-15 22:45:48 -0500 | [diff] [blame] | 41 | output_test_stream os; |
Davide Pesavento | e78eeca | 2017-02-23 23:22:32 -0500 | [diff] [blame] | 42 | |
| 43 | printHex(os, 0); |
| 44 | BOOST_CHECK(os.is_equal("0x0")); |
| 45 | |
| 46 | printHex(os, 42); |
| 47 | BOOST_CHECK(os.is_equal("0x2a")); |
| 48 | |
| 49 | printHex(os, 2748, true); |
| 50 | BOOST_CHECK(os.is_equal("0xABC")); |
| 51 | |
| 52 | printHex(os, static_cast<uint64_t>(-1)); |
| 53 | BOOST_CHECK(os.is_equal("0xffffffffffffffff")); |
| 54 | |
| 55 | printHex(os, ~0U, true); |
| 56 | BOOST_CHECK(os.is_equal("0xFFFFFFFF")); |
| 57 | |
| 58 | printHex(os, ~0ULL, true); |
| 59 | BOOST_CHECK(os.is_equal("0xFFFFFFFFFFFFFFFF")); |
| 60 | } |
| 61 | |
| 62 | BOOST_AUTO_TEST_CASE(AsHex) |
| 63 | { |
| 64 | using ndn::AsHex; |
Davide Pesavento | 38a061d | 2018-02-15 22:45:48 -0500 | [diff] [blame] | 65 | output_test_stream os; |
Davide Pesavento | e78eeca | 2017-02-23 23:22:32 -0500 | [diff] [blame] | 66 | |
| 67 | os << AsHex{0}; |
| 68 | BOOST_CHECK(os.is_equal("0x0")); |
| 69 | |
| 70 | os << AsHex{42}; |
| 71 | BOOST_CHECK(os.is_equal("0x2a")); |
| 72 | |
| 73 | os << std::uppercase << AsHex{~0U}; |
| 74 | BOOST_CHECK(os.is_equal("0xFFFFFFFF")); |
| 75 | |
| 76 | os << std::nouppercase << AsHex{~0U}; |
| 77 | BOOST_CHECK(os.is_equal("0xffffffff")); |
| 78 | } |
| 79 | |
Alexander Afanasyev | 8828ca6 | 2015-07-02 13:40:09 -0700 | [diff] [blame] | 80 | BOOST_AUTO_TEST_CASE(ToHex) |
| 81 | { |
| 82 | std::string test = "Hello, world!"; |
| 83 | BOOST_CHECK_EQUAL(toHex(reinterpret_cast<const uint8_t*>(test.data()), test.size()), |
| 84 | "48656C6C6F2C20776F726C6421"); |
Alexander Afanasyev | 8828ca6 | 2015-07-02 13:40:09 -0700 | [diff] [blame] | 85 | BOOST_CHECK_EQUAL(toHex(reinterpret_cast<const uint8_t*>(test.data()), test.size(), false), |
| 86 | "48656c6c6f2c20776f726c6421"); |
Alexander Afanasyev | 8828ca6 | 2015-07-02 13:40:09 -0700 | [diff] [blame] | 87 | BOOST_CHECK_EQUAL(toHex(nullptr, 0), ""); |
| 88 | |
| 89 | Buffer buffer(test.data(), test.size()); |
| 90 | BOOST_CHECK_EQUAL(toHex(buffer, false), "48656c6c6f2c20776f726c6421"); |
Davide Pesavento | fdda241 | 2017-01-28 18:53:51 -0500 | [diff] [blame] | 91 | BOOST_CHECK_EQUAL(toHex(Buffer{}), ""); |
Alexander Afanasyev | 8828ca6 | 2015-07-02 13:40:09 -0700 | [diff] [blame] | 92 | } |
| 93 | |
Davide Pesavento | 38a061d | 2018-02-15 22:45:48 -0500 | [diff] [blame] | 94 | BOOST_AUTO_TEST_CASE(FromHex) |
| 95 | { |
| 96 | BOOST_CHECK(*fromHex("") == Buffer{}); |
| 97 | BOOST_CHECK(*fromHex("48656c6c6f2c20776f726c6421") == |
| 98 | (std::vector<uint8_t>{0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20, |
| 99 | 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21})); |
| 100 | BOOST_CHECK(*fromHex("012a3Bc4defAB5CdEF") == |
| 101 | (std::vector<uint8_t>{0x01, 0x2a, 0x3b, 0xc4, 0xde, |
| 102 | 0xfa, 0xb5, 0xcd, 0xef})); |
| 103 | |
| 104 | BOOST_CHECK_THROW(fromHex("1"), StringHelperError); |
| 105 | BOOST_CHECK_THROW(fromHex("zz"), StringHelperError); |
| 106 | BOOST_CHECK_THROW(fromHex("00az"), StringHelperError); |
| 107 | BOOST_CHECK_THROW(fromHex("1234z"), StringHelperError); |
| 108 | } |
| 109 | |
| 110 | BOOST_AUTO_TEST_CASE(ToHexChar) |
| 111 | { |
| 112 | static const std::vector<std::pair<unsigned int, char>> hexMap{ |
| 113 | {0, '0'}, {1, '1'}, {2, '2'}, {3, '3'}, {4, '4'}, {5, '5'}, {6, '6'}, {7, '7'}, |
| 114 | {8, '8'}, {9, '9'}, {10, 'A'}, {11, 'B'}, {12, 'C'}, {13, 'D'}, {14, 'E'}, {15, 'F'} |
| 115 | }; |
| 116 | |
| 117 | for (const auto& i : hexMap) { |
| 118 | BOOST_CHECK_EQUAL(toHexChar(i.first), i.second); |
| 119 | BOOST_CHECK_EQUAL(toHexChar(i.first + 16), i.second); |
| 120 | BOOST_CHECK_EQUAL(toHexChar(i.first + 32), i.second); |
| 121 | BOOST_CHECK_EQUAL(toHexChar(i.first + 240), i.second); |
| 122 | BOOST_CHECK_EQUAL(toHexChar(i.first, false), std::tolower(static_cast<unsigned char>(i.second))); |
| 123 | } |
| 124 | } |
| 125 | |
Alexander Afanasyev | 8828ca6 | 2015-07-02 13:40:09 -0700 | [diff] [blame] | 126 | BOOST_AUTO_TEST_CASE(FromHexChar) |
| 127 | { |
| 128 | // for (int ch = 0; ch <= std::numeric_limits<uint8_t>::max(); ++ch) { |
| 129 | // std::cout << "{0x" << std::hex << ch << ", " |
| 130 | // << std::dec << fromHexChar(static_cast<char>(ch)) << "}, "; |
| 131 | // if (ch % 8 == 7) |
| 132 | // std::cout << std::endl; |
| 133 | // } |
Davide Pesavento | 03115ce | 2017-01-27 01:17:55 -0500 | [diff] [blame] | 134 | static const std::vector<std::pair<char, int>> hexMap{ |
Alexander Afanasyev | 8828ca6 | 2015-07-02 13:40:09 -0700 | [diff] [blame] | 135 | {0x0, -1}, {0x1, -1}, {0x2, -1}, {0x3, -1}, {0x4, -1}, {0x5, -1}, {0x6, -1}, {0x7, -1}, |
| 136 | {0x8, -1}, {0x9, -1}, {0xa, -1}, {0xb, -1}, {0xc, -1}, {0xd, -1}, {0xe, -1}, {0xf, -1}, |
| 137 | {0x10, -1}, {0x11, -1}, {0x12, -1}, {0x13, -1}, {0x14, -1}, {0x15, -1}, {0x16, -1}, {0x17, -1}, |
| 138 | {0x18, -1}, {0x19, -1}, {0x1a, -1}, {0x1b, -1}, {0x1c, -1}, {0x1d, -1}, {0x1e, -1}, {0x1f, -1}, |
| 139 | {0x20, -1}, {0x21, -1}, {0x22, -1}, {0x23, -1}, {0x24, -1}, {0x25, -1}, {0x26, -1}, {0x27, -1}, |
| 140 | {0x28, -1}, {0x29, -1}, {0x2a, -1}, {0x2b, -1}, {0x2c, -1}, {0x2d, -1}, {0x2e, -1}, {0x2f, -1}, |
| 141 | {0x30, 0}, {0x31, 1}, {0x32, 2}, {0x33, 3}, {0x34, 4}, {0x35, 5}, {0x36, 6}, {0x37, 7}, |
| 142 | {0x38, 8}, {0x39, 9}, {0x3a, -1}, {0x3b, -1}, {0x3c, -1}, {0x3d, -1}, {0x3e, -1}, {0x3f, -1}, |
| 143 | {0x40, -1}, {0x41, 10}, {0x42, 11}, {0x43, 12}, {0x44, 13}, {0x45, 14}, {0x46, 15}, {0x47, -1}, |
| 144 | {0x48, -1}, {0x49, -1}, {0x4a, -1}, {0x4b, -1}, {0x4c, -1}, {0x4d, -1}, {0x4e, -1}, {0x4f, -1}, |
| 145 | {0x50, -1}, {0x51, -1}, {0x52, -1}, {0x53, -1}, {0x54, -1}, {0x55, -1}, {0x56, -1}, {0x57, -1}, |
| 146 | {0x58, -1}, {0x59, -1}, {0x5a, -1}, {0x5b, -1}, {0x5c, -1}, {0x5d, -1}, {0x5e, -1}, {0x5f, -1}, |
| 147 | {0x60, -1}, {0x61, 10}, {0x62, 11}, {0x63, 12}, {0x64, 13}, {0x65, 14}, {0x66, 15}, {0x67, -1}, |
| 148 | {0x68, -1}, {0x69, -1}, {0x6a, -1}, {0x6b, -1}, {0x6c, -1}, {0x6d, -1}, {0x6e, -1}, {0x6f, -1}, |
| 149 | {0x70, -1}, {0x71, -1}, {0x72, -1}, {0x73, -1}, {0x74, -1}, {0x75, -1}, {0x76, -1}, {0x77, -1}, |
| 150 | {0x78, -1}, {0x79, -1}, {0x7a, -1}, {0x7b, -1}, {0x7c, -1}, {0x7d, -1}, {0x7e, -1}, {0x7f, -1}, |
| 151 | {0x80, -1}, {0x81, -1}, {0x82, -1}, {0x83, -1}, {0x84, -1}, {0x85, -1}, {0x86, -1}, {0x87, -1}, |
| 152 | {0x88, -1}, {0x89, -1}, {0x8a, -1}, {0x8b, -1}, {0x8c, -1}, {0x8d, -1}, {0x8e, -1}, {0x8f, -1}, |
| 153 | {0x90, -1}, {0x91, -1}, {0x92, -1}, {0x93, -1}, {0x94, -1}, {0x95, -1}, {0x96, -1}, {0x97, -1}, |
| 154 | {0x98, -1}, {0x99, -1}, {0x9a, -1}, {0x9b, -1}, {0x9c, -1}, {0x9d, -1}, {0x9e, -1}, {0x9f, -1}, |
| 155 | {0xa0, -1}, {0xa1, -1}, {0xa2, -1}, {0xa3, -1}, {0xa4, -1}, {0xa5, -1}, {0xa6, -1}, {0xa7, -1}, |
| 156 | {0xa8, -1}, {0xa9, -1}, {0xaa, -1}, {0xab, -1}, {0xac, -1}, {0xad, -1}, {0xae, -1}, {0xaf, -1}, |
| 157 | {0xb0, -1}, {0xb1, -1}, {0xb2, -1}, {0xb3, -1}, {0xb4, -1}, {0xb5, -1}, {0xb6, -1}, {0xb7, -1}, |
| 158 | {0xb8, -1}, {0xb9, -1}, {0xba, -1}, {0xbb, -1}, {0xbc, -1}, {0xbd, -1}, {0xbe, -1}, {0xbf, -1}, |
| 159 | {0xc0, -1}, {0xc1, -1}, {0xc2, -1}, {0xc3, -1}, {0xc4, -1}, {0xc5, -1}, {0xc6, -1}, {0xc7, -1}, |
| 160 | {0xc8, -1}, {0xc9, -1}, {0xca, -1}, {0xcb, -1}, {0xcc, -1}, {0xcd, -1}, {0xce, -1}, {0xcf, -1}, |
| 161 | {0xd0, -1}, {0xd1, -1}, {0xd2, -1}, {0xd3, -1}, {0xd4, -1}, {0xd5, -1}, {0xd6, -1}, {0xd7, -1}, |
| 162 | {0xd8, -1}, {0xd9, -1}, {0xda, -1}, {0xdb, -1}, {0xdc, -1}, {0xdd, -1}, {0xde, -1}, {0xdf, -1}, |
| 163 | {0xe0, -1}, {0xe1, -1}, {0xe2, -1}, {0xe3, -1}, {0xe4, -1}, {0xe5, -1}, {0xe6, -1}, {0xe7, -1}, |
| 164 | {0xe8, -1}, {0xe9, -1}, {0xea, -1}, {0xeb, -1}, {0xec, -1}, {0xed, -1}, {0xee, -1}, {0xef, -1}, |
| 165 | {0xf0, -1}, {0xf1, -1}, {0xf2, -1}, {0xf3, -1}, {0xf4, -1}, {0xf5, -1}, {0xf6, -1}, {0xf7, -1}, |
| 166 | {0xf8, -1}, {0xf9, -1}, {0xfa, -1}, {0xfb, -1}, {0xfc, -1}, {0xfd, -1}, {0xfe, -1}, {0xff, -1} |
| 167 | }; |
Davide Pesavento | 03115ce | 2017-01-27 01:17:55 -0500 | [diff] [blame] | 168 | |
Alexander Afanasyev | 8828ca6 | 2015-07-02 13:40:09 -0700 | [diff] [blame] | 169 | for (const auto& item : hexMap) { |
Davide Pesavento | 03115ce | 2017-01-27 01:17:55 -0500 | [diff] [blame] | 170 | BOOST_CHECK_EQUAL(fromHexChar(item.first), item.second); |
Alexander Afanasyev | 8828ca6 | 2015-07-02 13:40:09 -0700 | [diff] [blame] | 171 | } |
| 172 | } |
| 173 | |
Davide Pesavento | 38a061d | 2018-02-15 22:45:48 -0500 | [diff] [blame] | 174 | BOOST_AUTO_TEST_CASE(Escape) |
Alexander Afanasyev | 8828ca6 | 2015-07-02 13:40:09 -0700 | [diff] [blame] | 175 | { |
Davide Pesavento | 38a061d | 2018-02-15 22:45:48 -0500 | [diff] [blame] | 176 | BOOST_CHECK_EQUAL(escape(""), ""); |
| 177 | BOOST_CHECK_EQUAL(escape("foo42"), "foo42"); |
| 178 | BOOST_CHECK_EQUAL(escape("foo%bar"), "foo%25bar"); |
| 179 | BOOST_CHECK_EQUAL(escape("lower UPPER"), "lower%20UPPER"); |
| 180 | BOOST_CHECK_EQUAL(escape("-._~"), "-._~"); |
| 181 | BOOST_CHECK_EQUAL(escape(":/?#[]@"), "%3A%2F%3F%23%5B%5D%40"); |
Alexander Afanasyev | 8828ca6 | 2015-07-02 13:40:09 -0700 | [diff] [blame] | 182 | |
Davide Pesavento | 38a061d | 2018-02-15 22:45:48 -0500 | [diff] [blame] | 183 | output_test_stream os; |
| 184 | const char str[] = "\x01\x2a\x3b\xc4\xde\xfa\xb5\xcd\xef"; |
| 185 | escape(os, str, std::strlen(str)); |
| 186 | BOOST_CHECK(os.is_equal("%01%2A%3B%C4%DE%FA%B5%CD%EF")); |
Alexander Afanasyev | 8828ca6 | 2015-07-02 13:40:09 -0700 | [diff] [blame] | 187 | } |
| 188 | |
Alexander Afanasyev | 8828ca6 | 2015-07-02 13:40:09 -0700 | [diff] [blame] | 189 | BOOST_AUTO_TEST_CASE(Unescape) |
| 190 | { |
Davide Pesavento | 38a061d | 2018-02-15 22:45:48 -0500 | [diff] [blame] | 191 | BOOST_CHECK_EQUAL(unescape(""), ""); |
| 192 | BOOST_CHECK_EQUAL(unescape("Hello%01, world!%AA "), "Hello\x01, world!\xAA "); |
| 193 | BOOST_CHECK_EQUAL(unescape("Bad %ZZ (not a hex value)"), "Bad %ZZ (not a hex value)"); |
| 194 | BOOST_CHECK_EQUAL(unescape("Bad %a (should be two hex chars)"), "Bad %a (should be two hex chars)"); |
| 195 | BOOST_CHECK_EQUAL(unescape("Bad %a"), "Bad %a"); |
Alexander Afanasyev | 8828ca6 | 2015-07-02 13:40:09 -0700 | [diff] [blame] | 196 | |
Davide Pesavento | 38a061d | 2018-02-15 22:45:48 -0500 | [diff] [blame] | 197 | output_test_stream os; |
| 198 | const char str[] = "%01%2a%3B%c4%de%fA%B5%Cd%EF"; |
| 199 | unescape(os, str, std::strlen(str)); |
| 200 | BOOST_CHECK(os.is_equal("\x01\x2a\x3b\xc4\xde\xfa\xb5\xcd\xef")); |
Alexander Afanasyev | 8828ca6 | 2015-07-02 13:40:09 -0700 | [diff] [blame] | 201 | } |
| 202 | |
Davide Pesavento | eee3e82 | 2016-11-26 19:19:34 +0100 | [diff] [blame] | 203 | BOOST_AUTO_TEST_SUITE_END() // TestStringHelper |
| 204 | BOOST_AUTO_TEST_SUITE_END() // Util |
Alexander Afanasyev | 8828ca6 | 2015-07-02 13:40:09 -0700 | [diff] [blame] | 205 | |
| 206 | } // namespace test |
| 207 | } // namespace util |
| 208 | } // namespace ndn |