blob: e38b5f29c37b9c1b750cf4720da3e3d4e6de4fc0 [file] [log] [blame]
Alexander Afanasyevd1de3972014-08-14 19:47:41 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Junxiao Shic18aa192017-07-07 06:06:38 +00002/*
Davide Pesavento187e9f92023-03-20 22:46:22 -04003 * Copyright (c) 2013-2023 Regents of the University of California.
Alexander Afanasyevd1de3972014-08-14 19:47:41 -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
Davide Pesavento7e780642018-11-24 15:51:34 -050022#include "ndn-cxx/encoding/tlv.hpp"
23#include "ndn-cxx/encoding/buffer.hpp"
Davide Pesaventoffddbbf2022-11-21 16:33:47 -050024#include "ndn-cxx/util/span.hpp"
Alexander Afanasyevd1de3972014-08-14 19:47:41 -070025
Davide Pesavento7e780642018-11-24 15:51:34 -050026#include "tests/boost-test.hpp"
Davide Pesaventoeee3e822016-11-26 19:19:34 +010027
Davide Pesavento4ab3be22017-07-18 00:38:52 -040028#include <array>
29#include <deque>
30#include <list>
Davide Pesaventoa84f4642017-08-23 16:14:51 -040031#include <sstream>
Junxiao Shi46a9bd32017-07-14 19:12:11 +000032#include <boost/concept_archetype.hpp>
Alexander Afanasyevd1de3972014-08-14 19:47:41 -070033#include <boost/iostreams/stream.hpp>
Davide Pesaventoeee3e822016-11-26 19:19:34 +010034#include <boost/iostreams/device/array.hpp>
Alexander Afanasyev5f1820e2017-01-04 18:12:42 -080035#include <boost/lexical_cast.hpp>
Alexander Afanasyevd1de3972014-08-14 19:47:41 -070036
Davide Pesavento47ce2ee2023-05-09 01:33:33 -040037namespace ndn::tests {
38
39using namespace ndn::tlv;
Alexander Afanasyevd1de3972014-08-14 19:47:41 -070040
Davide Pesaventoeee3e822016-11-26 19:19:34 +010041BOOST_AUTO_TEST_SUITE(Encoding)
42BOOST_AUTO_TEST_SUITE(TestTlv)
Alexander Afanasyevd1de3972014-08-14 19:47:41 -070043
Junxiao Shia2550a92018-04-10 05:07:48 +000044BOOST_AUTO_TEST_CASE(CriticalType)
45{
46 BOOST_CHECK_EQUAL(isCriticalType(0), true);
47 BOOST_CHECK_EQUAL(isCriticalType(1), true);
48 BOOST_CHECK_EQUAL(isCriticalType(2), true);
49 BOOST_CHECK_EQUAL(isCriticalType(30), true);
50 BOOST_CHECK_EQUAL(isCriticalType(31), true);
51 BOOST_CHECK_EQUAL(isCriticalType(32), false);
52 BOOST_CHECK_EQUAL(isCriticalType(33), true);
53 BOOST_CHECK_EQUAL(isCriticalType(34), false);
54 BOOST_CHECK_EQUAL(isCriticalType(10000), false);
55 BOOST_CHECK_EQUAL(isCriticalType(10001), true);
56}
57
Davide Pesaventoeee3e822016-11-26 19:19:34 +010058using ArrayStream = boost::iostreams::stream<boost::iostreams::array_source>;
Junxiao Shi46a9bd32017-07-14 19:12:11 +000059using StreamIterator = std::istream_iterator<uint8_t>;
60
61#define ASSERT_READ_NUMBER_IS_FAST(T) \
Davide Pesavento47ce2ee2023-05-09 01:33:33 -040062 static_assert(ndn::tlv::detail::IsContiguousIterator<T>, #T " is not fast")
Junxiao Shi46a9bd32017-07-14 19:12:11 +000063#define ASSERT_READ_NUMBER_IS_SLOW(T) \
Davide Pesavento47ce2ee2023-05-09 01:33:33 -040064 static_assert(!ndn::tlv::detail::IsContiguousIterator<T>, #T " is not slow")
Junxiao Shi46a9bd32017-07-14 19:12:11 +000065
66ASSERT_READ_NUMBER_IS_FAST(const uint8_t*);
67ASSERT_READ_NUMBER_IS_FAST(uint8_t*);
68ASSERT_READ_NUMBER_IS_FAST(int8_t*);
69ASSERT_READ_NUMBER_IS_FAST(char*);
70ASSERT_READ_NUMBER_IS_FAST(unsigned char*);
71ASSERT_READ_NUMBER_IS_FAST(signed char*);
72ASSERT_READ_NUMBER_IS_FAST(const uint8_t[]);
73ASSERT_READ_NUMBER_IS_FAST(uint8_t[]);
74ASSERT_READ_NUMBER_IS_FAST(const uint8_t[12]);
75ASSERT_READ_NUMBER_IS_FAST(uint8_t[12]);
76using Uint8Array = std::array<uint8_t, 87>;
77ASSERT_READ_NUMBER_IS_FAST(Uint8Array::const_iterator);
78ASSERT_READ_NUMBER_IS_FAST(Uint8Array::iterator);
79using CharArray = std::array<char, 87>;
80ASSERT_READ_NUMBER_IS_FAST(CharArray::iterator);
Davide Pesavento21b7f1b2023-04-28 23:21:02 -040081ASSERT_READ_NUMBER_IS_FAST(span<const uint8_t>::iterator);
82ASSERT_READ_NUMBER_IS_FAST(span<uint8_t>::iterator);
Junxiao Shi46a9bd32017-07-14 19:12:11 +000083ASSERT_READ_NUMBER_IS_FAST(std::string::const_iterator);
84ASSERT_READ_NUMBER_IS_FAST(std::string::iterator);
85ASSERT_READ_NUMBER_IS_FAST(Buffer::const_iterator);
86ASSERT_READ_NUMBER_IS_FAST(Buffer::iterator);
87ASSERT_READ_NUMBER_IS_FAST(std::vector<uint8_t>::const_iterator);
88ASSERT_READ_NUMBER_IS_FAST(std::vector<uint8_t>::iterator);
89ASSERT_READ_NUMBER_IS_FAST(std::vector<int8_t>::iterator);
90ASSERT_READ_NUMBER_IS_FAST(std::vector<char>::iterator);
91ASSERT_READ_NUMBER_IS_FAST(std::vector<unsigned char>::iterator);
92ASSERT_READ_NUMBER_IS_FAST(std::vector<signed char>::iterator);
93ASSERT_READ_NUMBER_IS_SLOW(std::vector<bool>::iterator);
94ASSERT_READ_NUMBER_IS_SLOW(std::vector<uint16_t>::iterator);
95ASSERT_READ_NUMBER_IS_SLOW(std::vector<uint32_t>::iterator);
96ASSERT_READ_NUMBER_IS_SLOW(std::vector<uint64_t>::iterator);
Davide Pesavento4ab3be22017-07-18 00:38:52 -040097ASSERT_READ_NUMBER_IS_SLOW(std::deque<uint8_t>::iterator);
Junxiao Shi46a9bd32017-07-14 19:12:11 +000098ASSERT_READ_NUMBER_IS_SLOW(std::list<uint8_t>::iterator);
99ASSERT_READ_NUMBER_IS_SLOW(StreamIterator);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700100
101BOOST_AUTO_TEST_SUITE(VarNumber)
102
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000103// This check ensures readVarNumber and readType only require InputIterator concept and nothing
104// more. This function should compile, but should never be executed.
105void
106checkArchetype()
107{
108 boost::input_iterator_archetype<uint8_t> begin, end;
109 uint64_t number = readVarNumber(begin, end);
Davide Pesavento140e9cb2019-08-19 00:02:05 -0400110 uint32_t type = readType(begin, end);
111 bool ok = readVarNumber(begin, end, number);
112 ok = readType(begin, end, type);
113 static_cast<void>(ok);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000114}
115
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700116BOOST_AUTO_TEST_CASE(SizeOf)
117{
Davide Pesavento6b330402019-04-24 00:14:01 -0400118 BOOST_CHECK_EQUAL(sizeOfVarNumber(0), 1);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700119 BOOST_CHECK_EQUAL(sizeOfVarNumber(1), 1);
120 BOOST_CHECK_EQUAL(sizeOfVarNumber(252), 1);
121 BOOST_CHECK_EQUAL(sizeOfVarNumber(253), 3);
122 BOOST_CHECK_EQUAL(sizeOfVarNumber(65536), 5);
Davide Pesavento6b330402019-04-24 00:14:01 -0400123 BOOST_CHECK_EQUAL(sizeOfVarNumber(4294967295), 5);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000124 BOOST_CHECK_EQUAL(sizeOfVarNumber(4294967296), 9);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700125}
126
Davide Pesaventoffddbbf2022-11-21 16:33:47 -0500127static const uint8_t BUFFER[] = {
128 0x00, // == 0
129 0x01, // == 1
130 0xfc, // == 252
131 0xfd, 0x00, 0xfd, // == 253
132 0xfe, 0x00, 0x01, 0x00, 0x00, // == 65536
133 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 // == 4294967296
134};
135
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700136BOOST_AUTO_TEST_CASE(Write)
137{
Davide Pesaventoeee3e822016-11-26 19:19:34 +0100138 std::ostringstream os;
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700139
Davide Pesavento6b330402019-04-24 00:14:01 -0400140 writeVarNumber(os, 0);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700141 writeVarNumber(os, 1);
142 writeVarNumber(os, 252);
143 writeVarNumber(os, 253);
144 writeVarNumber(os, 65536);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000145 writeVarNumber(os, 4294967296);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700146
147 std::string buffer = os.str();
Davide Pesaventoffddbbf2022-11-21 16:33:47 -0500148 BOOST_TEST(make_span(reinterpret_cast<const uint8_t*>(buffer.data()), buffer.size()) == BUFFER,
149 boost::test_tools::per_element());
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700150}
151
152BOOST_AUTO_TEST_CASE(ReadFromBuffer)
153{
154 const uint8_t* begin;
155 uint64_t value;
156
157 begin = BUFFER;
158 BOOST_CHECK_EQUAL(readVarNumber(begin, begin + 1, value), true);
159 begin = BUFFER;
160 BOOST_CHECK_NO_THROW(readVarNumber(begin, begin + 1));
Davide Pesavento6b330402019-04-24 00:14:01 -0400161 BOOST_CHECK_EQUAL(value, 0);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700162
163 begin = BUFFER + 1;
164 BOOST_CHECK_EQUAL(readVarNumber(begin, begin + 1, value), true);
165 begin = BUFFER + 1;
166 BOOST_CHECK_NO_THROW(readVarNumber(begin, begin + 1));
Davide Pesavento6b330402019-04-24 00:14:01 -0400167 BOOST_CHECK_EQUAL(value, 1);
168
169 begin = BUFFER + 2;
170 BOOST_CHECK_EQUAL(readVarNumber(begin, begin + 1, value), true);
171 begin = BUFFER + 2;
172 BOOST_CHECK_NO_THROW(readVarNumber(begin, begin + 1));
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700173 BOOST_CHECK_EQUAL(value, 252);
174
Davide Pesavento6b330402019-04-24 00:14:01 -0400175 begin = BUFFER + 3;
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700176 BOOST_CHECK_EQUAL(readVarNumber(begin, begin + 1, value), false);
Davide Pesavento6b330402019-04-24 00:14:01 -0400177 begin = BUFFER + 3;
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700178 BOOST_CHECK_THROW(readVarNumber(begin, begin + 1), Error);
179
Davide Pesavento6b330402019-04-24 00:14:01 -0400180 begin = BUFFER + 3;
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700181 BOOST_CHECK_EQUAL(readVarNumber(begin, begin + 2, value), false);
Davide Pesavento6b330402019-04-24 00:14:01 -0400182 begin = BUFFER + 3;
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700183 BOOST_CHECK_THROW(readVarNumber(begin, begin + 2), Error);
184
Davide Pesavento6b330402019-04-24 00:14:01 -0400185 begin = BUFFER + 3;
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700186 BOOST_CHECK_EQUAL(readVarNumber(begin, begin + 3, value), true);
Davide Pesavento6b330402019-04-24 00:14:01 -0400187 begin = BUFFER + 3;
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700188 BOOST_CHECK_NO_THROW(readVarNumber(begin, begin + 3));
189 BOOST_CHECK_EQUAL(value, 253);
190
Davide Pesavento6b330402019-04-24 00:14:01 -0400191 begin = BUFFER + 6;
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700192 BOOST_CHECK_EQUAL(readVarNumber(begin, begin + 1, value), false);
Davide Pesavento6b330402019-04-24 00:14:01 -0400193 begin = BUFFER + 6;
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700194 BOOST_CHECK_THROW(readVarNumber(begin, begin + 1), Error);
195
Davide Pesavento6b330402019-04-24 00:14:01 -0400196 begin = BUFFER + 6;
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700197 BOOST_CHECK_EQUAL(readVarNumber(begin, begin + 4, value), false);
Davide Pesavento6b330402019-04-24 00:14:01 -0400198 begin = BUFFER + 6;
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700199 BOOST_CHECK_THROW(readVarNumber(begin, begin + 4), Error);
200
Davide Pesavento6b330402019-04-24 00:14:01 -0400201 begin = BUFFER + 6;
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700202 BOOST_CHECK_EQUAL(readVarNumber(begin, begin + 5, value), true);
Davide Pesavento6b330402019-04-24 00:14:01 -0400203 begin = BUFFER + 6;
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700204 BOOST_CHECK_NO_THROW(readVarNumber(begin, begin + 5));
205 BOOST_CHECK_EQUAL(value, 65536);
206
Davide Pesavento6b330402019-04-24 00:14:01 -0400207 begin = BUFFER + 11;
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700208 BOOST_CHECK_EQUAL(readVarNumber(begin, begin + 1, value), false);
Davide Pesavento6b330402019-04-24 00:14:01 -0400209 begin = BUFFER + 11;
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700210 BOOST_CHECK_THROW(readVarNumber(begin, begin + 1), Error);
211
Davide Pesavento6b330402019-04-24 00:14:01 -0400212 begin = BUFFER + 11;
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700213 BOOST_CHECK_EQUAL(readVarNumber(begin, begin + 8, value), false);
Davide Pesavento6b330402019-04-24 00:14:01 -0400214 begin = BUFFER + 11;
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700215 BOOST_CHECK_THROW(readVarNumber(begin, begin + 8), Error);
216
Davide Pesavento6b330402019-04-24 00:14:01 -0400217 begin = BUFFER + 11;
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700218 BOOST_CHECK_EQUAL(readVarNumber(begin, begin + 9, value), true);
Davide Pesavento6b330402019-04-24 00:14:01 -0400219 begin = BUFFER + 11;
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700220 BOOST_CHECK_NO_THROW(readVarNumber(begin, begin + 9));
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000221 BOOST_CHECK_EQUAL(value, 4294967296);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700222}
223
224BOOST_AUTO_TEST_CASE(ReadFromStream)
225{
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000226 StreamIterator end; // end of stream
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700227 uint64_t value;
Davide Pesavento6b330402019-04-24 00:14:01 -0400228
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700229 {
230 ArrayStream stream(reinterpret_cast<const char*>(BUFFER), 1);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000231 StreamIterator begin(stream);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700232 BOOST_CHECK_EQUAL(readVarNumber(begin, end, value), true);
233 }
234 {
235 ArrayStream stream(reinterpret_cast<const char*>(BUFFER), 1);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000236 StreamIterator begin(stream);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700237 BOOST_CHECK_NO_THROW(readVarNumber(begin, end));
Davide Pesavento6b330402019-04-24 00:14:01 -0400238 BOOST_CHECK_EQUAL(value, 0);
239 }
240
241 {
242 ArrayStream stream(reinterpret_cast<const char*>(BUFFER) + 1, 1);
243 StreamIterator begin(stream);
244 BOOST_CHECK_EQUAL(readVarNumber(begin, end, value), true);
245 }
246 {
247 ArrayStream stream(reinterpret_cast<const char*>(BUFFER) + 1, 1);
248 StreamIterator begin(stream);
249 BOOST_CHECK_NO_THROW(readVarNumber(begin, end));
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700250 BOOST_CHECK_EQUAL(value, 1);
251 }
252
253 {
Davide Pesavento6b330402019-04-24 00:14:01 -0400254 ArrayStream stream(reinterpret_cast<const char*>(BUFFER) + 2, 1);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000255 StreamIterator begin(stream);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700256 BOOST_CHECK_EQUAL(readVarNumber(begin, end, value), true);
257 }
258 {
Davide Pesavento6b330402019-04-24 00:14:01 -0400259 ArrayStream stream(reinterpret_cast<const char*>(BUFFER) + 2, 1);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000260 StreamIterator begin(stream);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700261 BOOST_CHECK_NO_THROW(readVarNumber(begin, end));
262 BOOST_CHECK_EQUAL(value, 252);
263 }
264
265 {
Davide Pesavento6b330402019-04-24 00:14:01 -0400266 ArrayStream stream(reinterpret_cast<const char*>(BUFFER) + 3, 1);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000267 StreamIterator begin(stream);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700268 BOOST_CHECK_EQUAL(readVarNumber(begin, end, value), false);
269 }
270 {
Davide Pesavento6b330402019-04-24 00:14:01 -0400271 ArrayStream stream(reinterpret_cast<const char*>(BUFFER) + 3, 1);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000272 StreamIterator begin(stream);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700273 BOOST_CHECK_THROW(readVarNumber(begin, end), Error);
274 }
275
276 {
Davide Pesavento6b330402019-04-24 00:14:01 -0400277 ArrayStream stream(reinterpret_cast<const char*>(BUFFER) + 3, 2);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000278 StreamIterator begin(stream);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700279 BOOST_CHECK_EQUAL(readVarNumber(begin, end, value), false);
280 }
281 {
Davide Pesavento6b330402019-04-24 00:14:01 -0400282 ArrayStream stream(reinterpret_cast<const char*>(BUFFER) + 3, 2);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000283 StreamIterator begin(stream);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700284 BOOST_CHECK_THROW(readVarNumber(begin, end), Error);
285 }
286
287 {
Davide Pesavento6b330402019-04-24 00:14:01 -0400288 ArrayStream stream(reinterpret_cast<const char*>(BUFFER) + 3, 3);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000289 StreamIterator begin(stream);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700290 BOOST_CHECK_EQUAL(readVarNumber(begin, end, value), true);
291 }
292 {
Davide Pesavento6b330402019-04-24 00:14:01 -0400293 ArrayStream stream(reinterpret_cast<const char*>(BUFFER) + 3, 3);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000294 StreamIterator begin(stream);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700295 BOOST_CHECK_NO_THROW(readVarNumber(begin, end));
296 BOOST_CHECK_EQUAL(value, 253);
297 }
298
299 {
Davide Pesavento6b330402019-04-24 00:14:01 -0400300 ArrayStream stream(reinterpret_cast<const char*>(BUFFER) + 6, 1);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000301 StreamIterator begin(stream);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700302 BOOST_CHECK_EQUAL(readVarNumber(begin, end, value), false);
303 }
304 {
Davide Pesavento6b330402019-04-24 00:14:01 -0400305 ArrayStream stream(reinterpret_cast<const char*>(BUFFER) + 6, 1);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000306 StreamIterator begin(stream);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700307 BOOST_CHECK_THROW(readVarNumber(begin, end), Error);
308 }
309
310 {
Davide Pesavento6b330402019-04-24 00:14:01 -0400311 ArrayStream stream(reinterpret_cast<const char*>(BUFFER) + 6, 4);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000312 StreamIterator begin(stream);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700313 BOOST_CHECK_EQUAL(readVarNumber(begin, end, value), false);
314 }
315 {
Davide Pesavento6b330402019-04-24 00:14:01 -0400316 ArrayStream stream(reinterpret_cast<const char*>(BUFFER) + 6, 4);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000317 StreamIterator begin(stream);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700318 BOOST_CHECK_THROW(readVarNumber(begin, end), Error);
319 }
320
321 {
Davide Pesavento6b330402019-04-24 00:14:01 -0400322 ArrayStream stream(reinterpret_cast<const char*>(BUFFER) + 6, 5);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000323 StreamIterator begin(stream);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700324 BOOST_CHECK_EQUAL(readVarNumber(begin, end, value), true);
325 }
326 {
Davide Pesavento6b330402019-04-24 00:14:01 -0400327 ArrayStream stream(reinterpret_cast<const char*>(BUFFER) + 6, 5);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000328 StreamIterator begin(stream);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700329 BOOST_CHECK_NO_THROW(readVarNumber(begin, end));
330 BOOST_CHECK_EQUAL(value, 65536);
331 }
332
333 {
Davide Pesavento6b330402019-04-24 00:14:01 -0400334 ArrayStream stream(reinterpret_cast<const char*>(BUFFER) + 11, 1);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000335 StreamIterator begin(stream);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700336 BOOST_CHECK_EQUAL(readVarNumber(begin, end, value), false);
337 }
338 {
Davide Pesavento6b330402019-04-24 00:14:01 -0400339 ArrayStream stream(reinterpret_cast<const char*>(BUFFER) + 11, 1);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000340 StreamIterator begin(stream);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700341 BOOST_CHECK_THROW(readVarNumber(begin, end), Error);
342 }
343
344 {
Davide Pesavento6b330402019-04-24 00:14:01 -0400345 ArrayStream stream(reinterpret_cast<const char*>(BUFFER) + 11, 8);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000346 StreamIterator begin(stream);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700347 BOOST_CHECK_EQUAL(readVarNumber(begin, end, value), false);
348 }
349 {
Davide Pesavento6b330402019-04-24 00:14:01 -0400350 ArrayStream stream(reinterpret_cast<const char*>(BUFFER) + 11, 8);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000351 StreamIterator begin(stream);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700352 BOOST_CHECK_THROW(readVarNumber(begin, end), Error);
353 }
354
355 {
Davide Pesavento6b330402019-04-24 00:14:01 -0400356 ArrayStream stream(reinterpret_cast<const char*>(BUFFER) + 11, 9);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000357 StreamIterator begin(stream);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700358 BOOST_CHECK_EQUAL(readVarNumber(begin, end, value), true);
359 }
360 {
Davide Pesavento6b330402019-04-24 00:14:01 -0400361 ArrayStream stream(reinterpret_cast<const char*>(BUFFER) + 11, 9);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000362 StreamIterator begin(stream);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700363 BOOST_CHECK_NO_THROW(readVarNumber(begin, end));
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000364 BOOST_CHECK_EQUAL(value, 4294967296);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700365 }
366}
367
368BOOST_AUTO_TEST_SUITE_END() // VarNumber
369
Davide Pesavento6b330402019-04-24 00:14:01 -0400370BOOST_AUTO_TEST_SUITE(Type)
371
372static const uint8_t BUFFER[] = {
373 0x00, // == 0 (illegal)
374 0x01, // == 1
375 0xfd, 0x00, 0xfd, // == 253
376 0xfe, 0xff, 0xff, 0xff, 0xff, // == 4294967295
377 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 // == 4294967296 (illegal)
378};
379
380BOOST_AUTO_TEST_CASE(Read)
381{
382 const uint8_t* begin;
383 uint32_t type;
384
385 begin = BUFFER;
386 BOOST_CHECK_EQUAL(readType(begin, begin + 1, type), false);
387 begin = BUFFER;
388 BOOST_CHECK_THROW(readType(begin, begin + 1), Error);
389
390 begin = BUFFER + 1;
391 BOOST_CHECK_EQUAL(readType(begin, begin + 1, type), true);
392 begin = BUFFER + 1;
393 BOOST_CHECK_NO_THROW(readType(begin, begin + 1));
394 BOOST_CHECK_EQUAL(type, 1);
395
396 begin = BUFFER + 2;
397 BOOST_CHECK_EQUAL(readType(begin, begin + 1, type), false);
398 begin = BUFFER + 2;
399 BOOST_CHECK_THROW(readType(begin, begin + 1), Error);
400
401 begin = BUFFER + 2;
402 BOOST_CHECK_EQUAL(readType(begin, begin + 2, type), false);
403 begin = BUFFER + 2;
404 BOOST_CHECK_THROW(readType(begin, begin + 2), Error);
405
406 begin = BUFFER + 2;
407 BOOST_CHECK_EQUAL(readType(begin, begin + 3, type), true);
408 begin = BUFFER + 2;
409 BOOST_CHECK_NO_THROW(readType(begin, begin + 3));
410 BOOST_CHECK_EQUAL(type, 253);
411
412 begin = BUFFER + 5;
413 BOOST_CHECK_EQUAL(readType(begin, begin + 1, type), false);
414 begin = BUFFER + 5;
415 BOOST_CHECK_THROW(readType(begin, begin + 1), Error);
416
417 begin = BUFFER + 5;
418 BOOST_CHECK_EQUAL(readType(begin, begin + 5, type), true);
419 begin = BUFFER + 5;
420 BOOST_CHECK_NO_THROW(readType(begin, begin + 5));
421 BOOST_CHECK_EQUAL(type, 4294967295);
422
423 begin = BUFFER + 10;
424 BOOST_CHECK_EQUAL(readType(begin, begin + 1, type), false);
425 begin = BUFFER + 10;
426 BOOST_CHECK_THROW(readType(begin, begin + 1), Error);
427
428 begin = BUFFER + 10;
429 BOOST_CHECK_EQUAL(readType(begin, begin + 9, type), false);
430 begin = BUFFER + 10;
431 BOOST_CHECK_THROW(readType(begin, begin + 9), Error);
432}
433
434BOOST_AUTO_TEST_SUITE_END() // Type
435
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700436BOOST_AUTO_TEST_SUITE(NonNegativeInteger)
437
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000438// This check ensures readNonNegativeInteger only requires InputIterator concept and nothing more.
439// This function should compile, but should never be executed.
440void
441checkArchetype()
442{
443 boost::input_iterator_archetype<uint8_t> begin, end;
444 readNonNegativeInteger(0, begin, end);
445}
446
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700447BOOST_AUTO_TEST_CASE(SizeOf)
448{
449 BOOST_CHECK_EQUAL(sizeOfNonNegativeInteger(1), 1);
Junxiao Shic18aa192017-07-07 06:06:38 +0000450 BOOST_CHECK_EQUAL(sizeOfNonNegativeInteger(253), 1);
451 BOOST_CHECK_EQUAL(sizeOfNonNegativeInteger(255), 1);
452 BOOST_CHECK_EQUAL(sizeOfNonNegativeInteger(256), 2);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700453 BOOST_CHECK_EQUAL(sizeOfNonNegativeInteger(65536), 4);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000454 BOOST_CHECK_EQUAL(sizeOfNonNegativeInteger(16843009), 4);
455 BOOST_CHECK_EQUAL(sizeOfNonNegativeInteger(4294967296), 8);
456 BOOST_CHECK_EQUAL(sizeOfNonNegativeInteger(72340172838076673), 8);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700457}
458
Davide Pesaventoffddbbf2022-11-21 16:33:47 -0500459static const uint8_t BUFFER[] = {
460 0x01, // 1
461 0xff, // 255
462 0x01, 0x02, // 258
463 0x01, 0x01, 0x01, 0x02, // 16843010
464 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02 // 72340172838076674
465};
466
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700467BOOST_AUTO_TEST_CASE(Write)
468{
Davide Pesaventoeee3e822016-11-26 19:19:34 +0100469 std::ostringstream os;
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700470
471 writeNonNegativeInteger(os, 1);
Junxiao Shic18aa192017-07-07 06:06:38 +0000472 writeNonNegativeInteger(os, 255);
473 writeNonNegativeInteger(os, 258);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000474 writeNonNegativeInteger(os, 16843010);
475 writeNonNegativeInteger(os, 72340172838076674);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700476
477 std::string buffer = os.str();
Davide Pesaventoffddbbf2022-11-21 16:33:47 -0500478 BOOST_TEST(make_span(reinterpret_cast<const uint8_t*>(buffer.data()), buffer.size()) == BUFFER,
479 boost::test_tools::per_element());
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700480}
481
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700482BOOST_AUTO_TEST_CASE(ReadFromBuffer)
483{
Junxiao Shic18aa192017-07-07 06:06:38 +0000484 const uint8_t* begin = nullptr;
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700485
486 begin = BUFFER;
Junxiao Shic18aa192017-07-07 06:06:38 +0000487 BOOST_CHECK_EQUAL(readNonNegativeInteger(1, begin, begin + 1), 1);
488 BOOST_CHECK_EQUAL(begin, BUFFER + 1);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700489
490 begin = BUFFER + 1;
Junxiao Shic18aa192017-07-07 06:06:38 +0000491 BOOST_CHECK_EQUAL(readNonNegativeInteger(1, begin, begin + 1), 255);
492 BOOST_CHECK_EQUAL(begin, BUFFER + 2);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700493
Junxiao Shic18aa192017-07-07 06:06:38 +0000494 begin = BUFFER + 2;
495 BOOST_CHECK_EQUAL(readNonNegativeInteger(2, begin, begin + 2), 258);
496 BOOST_CHECK_EQUAL(begin, BUFFER + 4);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700497
Junxiao Shic18aa192017-07-07 06:06:38 +0000498 begin = BUFFER + 4;
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000499 BOOST_CHECK_EQUAL(readNonNegativeInteger(4, begin, begin + 4), 16843010);
Junxiao Shic18aa192017-07-07 06:06:38 +0000500 BOOST_CHECK_EQUAL(begin, BUFFER + 8);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700501
Junxiao Shic18aa192017-07-07 06:06:38 +0000502 begin = BUFFER + 8;
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000503 BOOST_CHECK_EQUAL(readNonNegativeInteger(8, begin, begin + 8), 72340172838076674);
Junxiao Shic18aa192017-07-07 06:06:38 +0000504 BOOST_CHECK_EQUAL(begin, BUFFER + 16);
505
506 // invalid size
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700507 begin = BUFFER;
Junxiao Shic18aa192017-07-07 06:06:38 +0000508 BOOST_CHECK_THROW(readNonNegativeInteger(3, begin, begin + 3), Error);
509
510 // available buffer smaller than size
511 begin = BUFFER;
512 BOOST_CHECK_THROW(readNonNegativeInteger(1, begin, begin + 0), Error);
513 begin = BUFFER;
514 BOOST_CHECK_THROW(readNonNegativeInteger(2, begin, begin + 1), Error);
515 begin = BUFFER;
516 BOOST_CHECK_THROW(readNonNegativeInteger(4, begin, begin + 3), Error);
517 begin = BUFFER;
518 BOOST_CHECK_THROW(readNonNegativeInteger(8, begin, begin + 7), Error);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700519}
520
521BOOST_AUTO_TEST_CASE(ReadFromStream)
522{
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000523 StreamIterator end; // end of stream
Junxiao Shic18aa192017-07-07 06:06:38 +0000524
525 {
526 ArrayStream stream(reinterpret_cast<const char*>(BUFFER), sizeof(BUFFER));
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000527 StreamIterator begin(stream);
Junxiao Shic18aa192017-07-07 06:06:38 +0000528 BOOST_CHECK_EQUAL(readNonNegativeInteger(1, begin, end), 1);
529 BOOST_CHECK_EQUAL(readNonNegativeInteger(1, begin, end), 255);
530 BOOST_CHECK_EQUAL(readNonNegativeInteger(2, begin, end), 258);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000531 BOOST_CHECK_EQUAL(readNonNegativeInteger(4, begin, end), 16843010);
532 BOOST_CHECK_EQUAL(readNonNegativeInteger(8, begin, end), 72340172838076674);
Junxiao Shic18aa192017-07-07 06:06:38 +0000533 BOOST_CHECK(begin == end);
534 }
535
536 // invalid size
537 {
538 ArrayStream stream(reinterpret_cast<const char*>(BUFFER), 3);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000539 StreamIterator begin(stream);
Junxiao Shic18aa192017-07-07 06:06:38 +0000540 BOOST_CHECK_THROW(readNonNegativeInteger(3, begin, end), Error);
541 }
542
543 // available buffer smaller than size
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700544 {
545 ArrayStream stream(reinterpret_cast<const char*>(BUFFER), 0);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000546 StreamIterator begin(stream);
Junxiao Shic18aa192017-07-07 06:06:38 +0000547 BOOST_CHECK_THROW(readNonNegativeInteger(1, begin, end), Error);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700548 }
549 {
550 ArrayStream stream(reinterpret_cast<const char*>(BUFFER), 1);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000551 StreamIterator begin(stream);
Junxiao Shic18aa192017-07-07 06:06:38 +0000552 BOOST_CHECK_THROW(readNonNegativeInteger(2, begin, end), Error);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700553 }
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700554 {
555 ArrayStream stream(reinterpret_cast<const char*>(BUFFER), 3);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000556 StreamIterator begin(stream);
Junxiao Shic18aa192017-07-07 06:06:38 +0000557 BOOST_CHECK_THROW(readNonNegativeInteger(4, begin, end), Error);
558 }
559 {
560 ArrayStream stream(reinterpret_cast<const char*>(BUFFER), 7);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000561 StreamIterator begin(stream);
Junxiao Shic18aa192017-07-07 06:06:38 +0000562 BOOST_CHECK_THROW(readNonNegativeInteger(8, begin, end), Error);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700563 }
564}
565
566BOOST_AUTO_TEST_SUITE_END() // NonNegativeInteger
567
Davide Pesavento287a7fa2020-10-01 22:46:43 -0400568BOOST_AUTO_TEST_SUITE(OutputOperators)
Alexander Afanasyev5f1820e2017-01-04 18:12:42 -0800569
570BOOST_AUTO_TEST_CASE(PrintSignatureTypeValue)
571{
Davide Pesavento7e6f6f82017-10-31 18:05:28 -0400572 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(DigestSha256), "DigestSha256");
573 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(SignatureSha256WithRsa), "SignatureSha256WithRsa");
Junxiao Shi426d5002018-08-23 10:52:29 +0000574 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(static_cast<SignatureTypeValue>(2)), "Unknown(2)");
Davide Pesavento7e6f6f82017-10-31 18:05:28 -0400575 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(SignatureSha256WithEcdsa), "SignatureSha256WithEcdsa");
Junxiao Shi426d5002018-08-23 10:52:29 +0000576 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(SignatureHmacWithSha256), "SignatureHmacWithSha256");
Davide Pesaventoffddbbf2022-11-21 16:33:47 -0500577 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(SignatureEd25519), "SignatureEd25519");
578 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(static_cast<SignatureTypeValue>(6)), "Unknown(6)");
Davide Pesavento287a7fa2020-10-01 22:46:43 -0400579 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(static_cast<SignatureTypeValue>(199)), "Unknown(199)");
580 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(NullSignature), "NullSignature");
581 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(static_cast<SignatureTypeValue>(201)), "Unknown(201)");
Junxiao Shi426d5002018-08-23 10:52:29 +0000582}
583
584BOOST_AUTO_TEST_CASE(PrintContentTypeValue)
585{
586 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(ContentType_Blob), "Blob");
587 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(ContentType_Link), "Link");
588 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(ContentType_Key), "Key");
589 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(ContentType_Nack), "Nack");
590 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(ContentType_Manifest), "Manifest");
591 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(ContentType_PrefixAnn), "PrefixAnn");
592 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(static_cast<ContentTypeValue>(6)), "Reserved(6)");
593 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(static_cast<ContentTypeValue>(1023)), "Reserved(1023)");
594 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(ContentType_Flic), "FLIC");
595 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(static_cast<ContentTypeValue>(1025)), "Unknown(1025)");
596 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(static_cast<ContentTypeValue>(8999)), "Unknown(8999)");
597 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(static_cast<ContentTypeValue>(9000)), "Experimental(9000)");
598 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(static_cast<ContentTypeValue>(9999)), "Experimental(9999)");
599 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(static_cast<ContentTypeValue>(10000)), "Unknown(10000)");
600 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(static_cast<ContentTypeValue>(19910118)), "Unknown(19910118)");
Alexander Afanasyev5f1820e2017-01-04 18:12:42 -0800601}
602
Davide Pesavento287a7fa2020-10-01 22:46:43 -0400603BOOST_AUTO_TEST_SUITE_END() // OutputOperators
Alexander Afanasyev5f1820e2017-01-04 18:12:42 -0800604
Davide Pesaventoeee3e822016-11-26 19:19:34 +0100605BOOST_AUTO_TEST_SUITE_END() // TestTlv
606BOOST_AUTO_TEST_SUITE_END() // Encoding
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700607
Davide Pesavento47ce2ee2023-05-09 01:33:33 -0400608} // namespace ndn::tests