blob: be0d0df86ea9a72c13c1ccc55f67e9f004f2d352 [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 Pesaventof14e4e22025-04-02 23:00:23 -04003 * Copyright (c) 2013-2025 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 Pesaventof14e4e22025-04-02 23:00:23 -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 Pesaventof14e4e22025-04-02 23:00:23 -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);
Davide Pesaventof14e4e22025-04-02 23:00:23 -040083ASSERT_READ_NUMBER_IS_FAST(span<int8_t>::iterator);
84ASSERT_READ_NUMBER_IS_FAST(span<char>::iterator);
Junxiao Shi46a9bd32017-07-14 19:12:11 +000085ASSERT_READ_NUMBER_IS_FAST(std::string::const_iterator);
86ASSERT_READ_NUMBER_IS_FAST(std::string::iterator);
87ASSERT_READ_NUMBER_IS_FAST(Buffer::const_iterator);
88ASSERT_READ_NUMBER_IS_FAST(Buffer::iterator);
89ASSERT_READ_NUMBER_IS_FAST(std::vector<uint8_t>::const_iterator);
90ASSERT_READ_NUMBER_IS_FAST(std::vector<uint8_t>::iterator);
91ASSERT_READ_NUMBER_IS_FAST(std::vector<int8_t>::iterator);
92ASSERT_READ_NUMBER_IS_FAST(std::vector<char>::iterator);
93ASSERT_READ_NUMBER_IS_FAST(std::vector<unsigned char>::iterator);
94ASSERT_READ_NUMBER_IS_FAST(std::vector<signed char>::iterator);
95ASSERT_READ_NUMBER_IS_SLOW(std::vector<bool>::iterator);
96ASSERT_READ_NUMBER_IS_SLOW(std::vector<uint16_t>::iterator);
97ASSERT_READ_NUMBER_IS_SLOW(std::vector<uint32_t>::iterator);
98ASSERT_READ_NUMBER_IS_SLOW(std::vector<uint64_t>::iterator);
Davide Pesaventof14e4e22025-04-02 23:00:23 -040099ASSERT_READ_NUMBER_IS_SLOW(std::vector<std::vector<uint8_t>>::iterator);
Davide Pesavento4ab3be22017-07-18 00:38:52 -0400100ASSERT_READ_NUMBER_IS_SLOW(std::deque<uint8_t>::iterator);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000101ASSERT_READ_NUMBER_IS_SLOW(std::list<uint8_t>::iterator);
102ASSERT_READ_NUMBER_IS_SLOW(StreamIterator);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700103
104BOOST_AUTO_TEST_SUITE(VarNumber)
105
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000106// This check ensures readVarNumber and readType only require InputIterator concept and nothing
107// more. This function should compile, but should never be executed.
108void
109checkArchetype()
110{
111 boost::input_iterator_archetype<uint8_t> begin, end;
112 uint64_t number = readVarNumber(begin, end);
Davide Pesavento140e9cb2019-08-19 00:02:05 -0400113 uint32_t type = readType(begin, end);
114 bool ok = readVarNumber(begin, end, number);
115 ok = readType(begin, end, type);
116 static_cast<void>(ok);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000117}
118
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700119BOOST_AUTO_TEST_CASE(SizeOf)
120{
Davide Pesavento6b330402019-04-24 00:14:01 -0400121 BOOST_CHECK_EQUAL(sizeOfVarNumber(0), 1);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700122 BOOST_CHECK_EQUAL(sizeOfVarNumber(1), 1);
123 BOOST_CHECK_EQUAL(sizeOfVarNumber(252), 1);
124 BOOST_CHECK_EQUAL(sizeOfVarNumber(253), 3);
125 BOOST_CHECK_EQUAL(sizeOfVarNumber(65536), 5);
Davide Pesavento6b330402019-04-24 00:14:01 -0400126 BOOST_CHECK_EQUAL(sizeOfVarNumber(4294967295), 5);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000127 BOOST_CHECK_EQUAL(sizeOfVarNumber(4294967296), 9);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700128}
129
Davide Pesaventoffddbbf2022-11-21 16:33:47 -0500130static const uint8_t BUFFER[] = {
131 0x00, // == 0
132 0x01, // == 1
133 0xfc, // == 252
134 0xfd, 0x00, 0xfd, // == 253
135 0xfe, 0x00, 0x01, 0x00, 0x00, // == 65536
136 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 // == 4294967296
137};
138
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700139BOOST_AUTO_TEST_CASE(Write)
140{
Davide Pesaventoeee3e822016-11-26 19:19:34 +0100141 std::ostringstream os;
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700142
Davide Pesavento6b330402019-04-24 00:14:01 -0400143 writeVarNumber(os, 0);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700144 writeVarNumber(os, 1);
145 writeVarNumber(os, 252);
146 writeVarNumber(os, 253);
147 writeVarNumber(os, 65536);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000148 writeVarNumber(os, 4294967296);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700149
150 std::string buffer = os.str();
Davide Pesaventoffddbbf2022-11-21 16:33:47 -0500151 BOOST_TEST(make_span(reinterpret_cast<const uint8_t*>(buffer.data()), buffer.size()) == BUFFER,
152 boost::test_tools::per_element());
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700153}
154
155BOOST_AUTO_TEST_CASE(ReadFromBuffer)
156{
157 const uint8_t* begin;
158 uint64_t value;
159
160 begin = BUFFER;
161 BOOST_CHECK_EQUAL(readVarNumber(begin, begin + 1, value), true);
162 begin = BUFFER;
163 BOOST_CHECK_NO_THROW(readVarNumber(begin, begin + 1));
Davide Pesavento6b330402019-04-24 00:14:01 -0400164 BOOST_CHECK_EQUAL(value, 0);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700165
166 begin = BUFFER + 1;
167 BOOST_CHECK_EQUAL(readVarNumber(begin, begin + 1, value), true);
168 begin = BUFFER + 1;
169 BOOST_CHECK_NO_THROW(readVarNumber(begin, begin + 1));
Davide Pesavento6b330402019-04-24 00:14:01 -0400170 BOOST_CHECK_EQUAL(value, 1);
171
172 begin = BUFFER + 2;
173 BOOST_CHECK_EQUAL(readVarNumber(begin, begin + 1, value), true);
174 begin = BUFFER + 2;
175 BOOST_CHECK_NO_THROW(readVarNumber(begin, begin + 1));
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700176 BOOST_CHECK_EQUAL(value, 252);
177
Davide Pesavento6b330402019-04-24 00:14:01 -0400178 begin = BUFFER + 3;
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700179 BOOST_CHECK_EQUAL(readVarNumber(begin, begin + 1, value), false);
Davide Pesavento6b330402019-04-24 00:14:01 -0400180 begin = BUFFER + 3;
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700181 BOOST_CHECK_THROW(readVarNumber(begin, begin + 1), Error);
182
Davide Pesavento6b330402019-04-24 00:14:01 -0400183 begin = BUFFER + 3;
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700184 BOOST_CHECK_EQUAL(readVarNumber(begin, begin + 2, value), false);
Davide Pesavento6b330402019-04-24 00:14:01 -0400185 begin = BUFFER + 3;
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700186 BOOST_CHECK_THROW(readVarNumber(begin, begin + 2), Error);
187
Davide Pesavento6b330402019-04-24 00:14:01 -0400188 begin = BUFFER + 3;
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700189 BOOST_CHECK_EQUAL(readVarNumber(begin, begin + 3, value), true);
Davide Pesavento6b330402019-04-24 00:14:01 -0400190 begin = BUFFER + 3;
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700191 BOOST_CHECK_NO_THROW(readVarNumber(begin, begin + 3));
192 BOOST_CHECK_EQUAL(value, 253);
193
Davide Pesavento6b330402019-04-24 00:14:01 -0400194 begin = BUFFER + 6;
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700195 BOOST_CHECK_EQUAL(readVarNumber(begin, begin + 1, value), false);
Davide Pesavento6b330402019-04-24 00:14:01 -0400196 begin = BUFFER + 6;
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700197 BOOST_CHECK_THROW(readVarNumber(begin, begin + 1), Error);
198
Davide Pesavento6b330402019-04-24 00:14:01 -0400199 begin = BUFFER + 6;
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700200 BOOST_CHECK_EQUAL(readVarNumber(begin, begin + 4, value), false);
Davide Pesavento6b330402019-04-24 00:14:01 -0400201 begin = BUFFER + 6;
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700202 BOOST_CHECK_THROW(readVarNumber(begin, begin + 4), Error);
203
Davide Pesavento6b330402019-04-24 00:14:01 -0400204 begin = BUFFER + 6;
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700205 BOOST_CHECK_EQUAL(readVarNumber(begin, begin + 5, value), true);
Davide Pesavento6b330402019-04-24 00:14:01 -0400206 begin = BUFFER + 6;
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700207 BOOST_CHECK_NO_THROW(readVarNumber(begin, begin + 5));
208 BOOST_CHECK_EQUAL(value, 65536);
209
Davide Pesavento6b330402019-04-24 00:14:01 -0400210 begin = BUFFER + 11;
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700211 BOOST_CHECK_EQUAL(readVarNumber(begin, begin + 1, value), false);
Davide Pesavento6b330402019-04-24 00:14:01 -0400212 begin = BUFFER + 11;
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700213 BOOST_CHECK_THROW(readVarNumber(begin, begin + 1), Error);
214
Davide Pesavento6b330402019-04-24 00:14:01 -0400215 begin = BUFFER + 11;
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700216 BOOST_CHECK_EQUAL(readVarNumber(begin, begin + 8, value), false);
Davide Pesavento6b330402019-04-24 00:14:01 -0400217 begin = BUFFER + 11;
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700218 BOOST_CHECK_THROW(readVarNumber(begin, begin + 8), Error);
219
Davide Pesavento6b330402019-04-24 00:14:01 -0400220 begin = BUFFER + 11;
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700221 BOOST_CHECK_EQUAL(readVarNumber(begin, begin + 9, value), true);
Davide Pesavento6b330402019-04-24 00:14:01 -0400222 begin = BUFFER + 11;
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700223 BOOST_CHECK_NO_THROW(readVarNumber(begin, begin + 9));
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000224 BOOST_CHECK_EQUAL(value, 4294967296);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700225}
226
227BOOST_AUTO_TEST_CASE(ReadFromStream)
228{
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000229 StreamIterator end; // end of stream
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700230 uint64_t value;
Davide Pesavento6b330402019-04-24 00:14:01 -0400231
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700232 {
233 ArrayStream stream(reinterpret_cast<const char*>(BUFFER), 1);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000234 StreamIterator begin(stream);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700235 BOOST_CHECK_EQUAL(readVarNumber(begin, end, value), true);
236 }
237 {
238 ArrayStream stream(reinterpret_cast<const char*>(BUFFER), 1);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000239 StreamIterator begin(stream);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700240 BOOST_CHECK_NO_THROW(readVarNumber(begin, end));
Davide Pesavento6b330402019-04-24 00:14:01 -0400241 BOOST_CHECK_EQUAL(value, 0);
242 }
243
244 {
245 ArrayStream stream(reinterpret_cast<const char*>(BUFFER) + 1, 1);
246 StreamIterator begin(stream);
247 BOOST_CHECK_EQUAL(readVarNumber(begin, end, value), true);
248 }
249 {
250 ArrayStream stream(reinterpret_cast<const char*>(BUFFER) + 1, 1);
251 StreamIterator begin(stream);
252 BOOST_CHECK_NO_THROW(readVarNumber(begin, end));
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700253 BOOST_CHECK_EQUAL(value, 1);
254 }
255
256 {
Davide Pesavento6b330402019-04-24 00:14:01 -0400257 ArrayStream stream(reinterpret_cast<const char*>(BUFFER) + 2, 1);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000258 StreamIterator begin(stream);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700259 BOOST_CHECK_EQUAL(readVarNumber(begin, end, value), true);
260 }
261 {
Davide Pesavento6b330402019-04-24 00:14:01 -0400262 ArrayStream stream(reinterpret_cast<const char*>(BUFFER) + 2, 1);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000263 StreamIterator begin(stream);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700264 BOOST_CHECK_NO_THROW(readVarNumber(begin, end));
265 BOOST_CHECK_EQUAL(value, 252);
266 }
267
268 {
Davide Pesavento6b330402019-04-24 00:14:01 -0400269 ArrayStream stream(reinterpret_cast<const char*>(BUFFER) + 3, 1);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000270 StreamIterator begin(stream);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700271 BOOST_CHECK_EQUAL(readVarNumber(begin, end, value), false);
272 }
273 {
Davide Pesavento6b330402019-04-24 00:14:01 -0400274 ArrayStream stream(reinterpret_cast<const char*>(BUFFER) + 3, 1);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000275 StreamIterator begin(stream);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700276 BOOST_CHECK_THROW(readVarNumber(begin, end), Error);
277 }
278
279 {
Davide Pesavento6b330402019-04-24 00:14:01 -0400280 ArrayStream stream(reinterpret_cast<const char*>(BUFFER) + 3, 2);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000281 StreamIterator begin(stream);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700282 BOOST_CHECK_EQUAL(readVarNumber(begin, end, value), false);
283 }
284 {
Davide Pesavento6b330402019-04-24 00:14:01 -0400285 ArrayStream stream(reinterpret_cast<const char*>(BUFFER) + 3, 2);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000286 StreamIterator begin(stream);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700287 BOOST_CHECK_THROW(readVarNumber(begin, end), Error);
288 }
289
290 {
Davide Pesavento6b330402019-04-24 00:14:01 -0400291 ArrayStream stream(reinterpret_cast<const char*>(BUFFER) + 3, 3);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000292 StreamIterator begin(stream);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700293 BOOST_CHECK_EQUAL(readVarNumber(begin, end, value), true);
294 }
295 {
Davide Pesavento6b330402019-04-24 00:14:01 -0400296 ArrayStream stream(reinterpret_cast<const char*>(BUFFER) + 3, 3);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000297 StreamIterator begin(stream);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700298 BOOST_CHECK_NO_THROW(readVarNumber(begin, end));
299 BOOST_CHECK_EQUAL(value, 253);
300 }
301
302 {
Davide Pesavento6b330402019-04-24 00:14:01 -0400303 ArrayStream stream(reinterpret_cast<const char*>(BUFFER) + 6, 1);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000304 StreamIterator begin(stream);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700305 BOOST_CHECK_EQUAL(readVarNumber(begin, end, value), false);
306 }
307 {
Davide Pesavento6b330402019-04-24 00:14:01 -0400308 ArrayStream stream(reinterpret_cast<const char*>(BUFFER) + 6, 1);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000309 StreamIterator begin(stream);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700310 BOOST_CHECK_THROW(readVarNumber(begin, end), Error);
311 }
312
313 {
Davide Pesavento6b330402019-04-24 00:14:01 -0400314 ArrayStream stream(reinterpret_cast<const char*>(BUFFER) + 6, 4);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000315 StreamIterator begin(stream);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700316 BOOST_CHECK_EQUAL(readVarNumber(begin, end, value), false);
317 }
318 {
Davide Pesavento6b330402019-04-24 00:14:01 -0400319 ArrayStream stream(reinterpret_cast<const char*>(BUFFER) + 6, 4);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000320 StreamIterator begin(stream);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700321 BOOST_CHECK_THROW(readVarNumber(begin, end), Error);
322 }
323
324 {
Davide Pesavento6b330402019-04-24 00:14:01 -0400325 ArrayStream stream(reinterpret_cast<const char*>(BUFFER) + 6, 5);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000326 StreamIterator begin(stream);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700327 BOOST_CHECK_EQUAL(readVarNumber(begin, end, value), true);
328 }
329 {
Davide Pesavento6b330402019-04-24 00:14:01 -0400330 ArrayStream stream(reinterpret_cast<const char*>(BUFFER) + 6, 5);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000331 StreamIterator begin(stream);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700332 BOOST_CHECK_NO_THROW(readVarNumber(begin, end));
333 BOOST_CHECK_EQUAL(value, 65536);
334 }
335
336 {
Davide Pesavento6b330402019-04-24 00:14:01 -0400337 ArrayStream stream(reinterpret_cast<const char*>(BUFFER) + 11, 1);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000338 StreamIterator begin(stream);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700339 BOOST_CHECK_EQUAL(readVarNumber(begin, end, value), false);
340 }
341 {
Davide Pesavento6b330402019-04-24 00:14:01 -0400342 ArrayStream stream(reinterpret_cast<const char*>(BUFFER) + 11, 1);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000343 StreamIterator begin(stream);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700344 BOOST_CHECK_THROW(readVarNumber(begin, end), Error);
345 }
346
347 {
Davide Pesavento6b330402019-04-24 00:14:01 -0400348 ArrayStream stream(reinterpret_cast<const char*>(BUFFER) + 11, 8);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000349 StreamIterator begin(stream);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700350 BOOST_CHECK_EQUAL(readVarNumber(begin, end, value), false);
351 }
352 {
Davide Pesavento6b330402019-04-24 00:14:01 -0400353 ArrayStream stream(reinterpret_cast<const char*>(BUFFER) + 11, 8);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000354 StreamIterator begin(stream);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700355 BOOST_CHECK_THROW(readVarNumber(begin, end), Error);
356 }
357
358 {
Davide Pesavento6b330402019-04-24 00:14:01 -0400359 ArrayStream stream(reinterpret_cast<const char*>(BUFFER) + 11, 9);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000360 StreamIterator begin(stream);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700361 BOOST_CHECK_EQUAL(readVarNumber(begin, end, value), true);
362 }
363 {
Davide Pesavento6b330402019-04-24 00:14:01 -0400364 ArrayStream stream(reinterpret_cast<const char*>(BUFFER) + 11, 9);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000365 StreamIterator begin(stream);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700366 BOOST_CHECK_NO_THROW(readVarNumber(begin, end));
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000367 BOOST_CHECK_EQUAL(value, 4294967296);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700368 }
369}
370
371BOOST_AUTO_TEST_SUITE_END() // VarNumber
372
Davide Pesavento6b330402019-04-24 00:14:01 -0400373BOOST_AUTO_TEST_SUITE(Type)
374
375static const uint8_t BUFFER[] = {
376 0x00, // == 0 (illegal)
377 0x01, // == 1
378 0xfd, 0x00, 0xfd, // == 253
379 0xfe, 0xff, 0xff, 0xff, 0xff, // == 4294967295
380 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 // == 4294967296 (illegal)
381};
382
383BOOST_AUTO_TEST_CASE(Read)
384{
385 const uint8_t* begin;
386 uint32_t type;
387
388 begin = BUFFER;
389 BOOST_CHECK_EQUAL(readType(begin, begin + 1, type), false);
390 begin = BUFFER;
391 BOOST_CHECK_THROW(readType(begin, begin + 1), Error);
392
393 begin = BUFFER + 1;
394 BOOST_CHECK_EQUAL(readType(begin, begin + 1, type), true);
395 begin = BUFFER + 1;
396 BOOST_CHECK_NO_THROW(readType(begin, begin + 1));
397 BOOST_CHECK_EQUAL(type, 1);
398
399 begin = BUFFER + 2;
400 BOOST_CHECK_EQUAL(readType(begin, begin + 1, type), false);
401 begin = BUFFER + 2;
402 BOOST_CHECK_THROW(readType(begin, begin + 1), Error);
403
404 begin = BUFFER + 2;
405 BOOST_CHECK_EQUAL(readType(begin, begin + 2, type), false);
406 begin = BUFFER + 2;
407 BOOST_CHECK_THROW(readType(begin, begin + 2), Error);
408
409 begin = BUFFER + 2;
410 BOOST_CHECK_EQUAL(readType(begin, begin + 3, type), true);
411 begin = BUFFER + 2;
412 BOOST_CHECK_NO_THROW(readType(begin, begin + 3));
413 BOOST_CHECK_EQUAL(type, 253);
414
415 begin = BUFFER + 5;
416 BOOST_CHECK_EQUAL(readType(begin, begin + 1, type), false);
417 begin = BUFFER + 5;
418 BOOST_CHECK_THROW(readType(begin, begin + 1), Error);
419
420 begin = BUFFER + 5;
421 BOOST_CHECK_EQUAL(readType(begin, begin + 5, type), true);
422 begin = BUFFER + 5;
423 BOOST_CHECK_NO_THROW(readType(begin, begin + 5));
424 BOOST_CHECK_EQUAL(type, 4294967295);
425
426 begin = BUFFER + 10;
427 BOOST_CHECK_EQUAL(readType(begin, begin + 1, type), false);
428 begin = BUFFER + 10;
429 BOOST_CHECK_THROW(readType(begin, begin + 1), Error);
430
431 begin = BUFFER + 10;
432 BOOST_CHECK_EQUAL(readType(begin, begin + 9, type), false);
433 begin = BUFFER + 10;
434 BOOST_CHECK_THROW(readType(begin, begin + 9), Error);
435}
436
437BOOST_AUTO_TEST_SUITE_END() // Type
438
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700439BOOST_AUTO_TEST_SUITE(NonNegativeInteger)
440
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000441// This check ensures readNonNegativeInteger only requires InputIterator concept and nothing more.
442// This function should compile, but should never be executed.
443void
444checkArchetype()
445{
446 boost::input_iterator_archetype<uint8_t> begin, end;
447 readNonNegativeInteger(0, begin, end);
448}
449
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700450BOOST_AUTO_TEST_CASE(SizeOf)
451{
452 BOOST_CHECK_EQUAL(sizeOfNonNegativeInteger(1), 1);
Junxiao Shic18aa192017-07-07 06:06:38 +0000453 BOOST_CHECK_EQUAL(sizeOfNonNegativeInteger(253), 1);
454 BOOST_CHECK_EQUAL(sizeOfNonNegativeInteger(255), 1);
455 BOOST_CHECK_EQUAL(sizeOfNonNegativeInteger(256), 2);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700456 BOOST_CHECK_EQUAL(sizeOfNonNegativeInteger(65536), 4);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000457 BOOST_CHECK_EQUAL(sizeOfNonNegativeInteger(16843009), 4);
458 BOOST_CHECK_EQUAL(sizeOfNonNegativeInteger(4294967296), 8);
459 BOOST_CHECK_EQUAL(sizeOfNonNegativeInteger(72340172838076673), 8);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700460}
461
Davide Pesaventoffddbbf2022-11-21 16:33:47 -0500462static const uint8_t BUFFER[] = {
463 0x01, // 1
464 0xff, // 255
465 0x01, 0x02, // 258
466 0x01, 0x01, 0x01, 0x02, // 16843010
467 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02 // 72340172838076674
468};
469
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700470BOOST_AUTO_TEST_CASE(Write)
471{
Davide Pesaventoeee3e822016-11-26 19:19:34 +0100472 std::ostringstream os;
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700473
474 writeNonNegativeInteger(os, 1);
Junxiao Shic18aa192017-07-07 06:06:38 +0000475 writeNonNegativeInteger(os, 255);
476 writeNonNegativeInteger(os, 258);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000477 writeNonNegativeInteger(os, 16843010);
478 writeNonNegativeInteger(os, 72340172838076674);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700479
480 std::string buffer = os.str();
Davide Pesaventoffddbbf2022-11-21 16:33:47 -0500481 BOOST_TEST(make_span(reinterpret_cast<const uint8_t*>(buffer.data()), buffer.size()) == BUFFER,
482 boost::test_tools::per_element());
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700483}
484
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700485BOOST_AUTO_TEST_CASE(ReadFromBuffer)
486{
Junxiao Shic18aa192017-07-07 06:06:38 +0000487 const uint8_t* begin = nullptr;
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700488
489 begin = BUFFER;
Junxiao Shic18aa192017-07-07 06:06:38 +0000490 BOOST_CHECK_EQUAL(readNonNegativeInteger(1, begin, begin + 1), 1);
491 BOOST_CHECK_EQUAL(begin, BUFFER + 1);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700492
493 begin = BUFFER + 1;
Junxiao Shic18aa192017-07-07 06:06:38 +0000494 BOOST_CHECK_EQUAL(readNonNegativeInteger(1, begin, begin + 1), 255);
495 BOOST_CHECK_EQUAL(begin, BUFFER + 2);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700496
Junxiao Shic18aa192017-07-07 06:06:38 +0000497 begin = BUFFER + 2;
498 BOOST_CHECK_EQUAL(readNonNegativeInteger(2, begin, begin + 2), 258);
499 BOOST_CHECK_EQUAL(begin, BUFFER + 4);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700500
Junxiao Shic18aa192017-07-07 06:06:38 +0000501 begin = BUFFER + 4;
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000502 BOOST_CHECK_EQUAL(readNonNegativeInteger(4, begin, begin + 4), 16843010);
Junxiao Shic18aa192017-07-07 06:06:38 +0000503 BOOST_CHECK_EQUAL(begin, BUFFER + 8);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700504
Junxiao Shic18aa192017-07-07 06:06:38 +0000505 begin = BUFFER + 8;
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000506 BOOST_CHECK_EQUAL(readNonNegativeInteger(8, begin, begin + 8), 72340172838076674);
Junxiao Shic18aa192017-07-07 06:06:38 +0000507 BOOST_CHECK_EQUAL(begin, BUFFER + 16);
508
509 // invalid size
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700510 begin = BUFFER;
Junxiao Shic18aa192017-07-07 06:06:38 +0000511 BOOST_CHECK_THROW(readNonNegativeInteger(3, begin, begin + 3), Error);
512
513 // available buffer smaller than size
514 begin = BUFFER;
515 BOOST_CHECK_THROW(readNonNegativeInteger(1, begin, begin + 0), Error);
516 begin = BUFFER;
517 BOOST_CHECK_THROW(readNonNegativeInteger(2, begin, begin + 1), Error);
518 begin = BUFFER;
519 BOOST_CHECK_THROW(readNonNegativeInteger(4, begin, begin + 3), Error);
520 begin = BUFFER;
521 BOOST_CHECK_THROW(readNonNegativeInteger(8, begin, begin + 7), Error);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700522}
523
524BOOST_AUTO_TEST_CASE(ReadFromStream)
525{
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000526 StreamIterator end; // end of stream
Junxiao Shic18aa192017-07-07 06:06:38 +0000527
528 {
529 ArrayStream stream(reinterpret_cast<const char*>(BUFFER), sizeof(BUFFER));
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000530 StreamIterator begin(stream);
Junxiao Shic18aa192017-07-07 06:06:38 +0000531 BOOST_CHECK_EQUAL(readNonNegativeInteger(1, begin, end), 1);
532 BOOST_CHECK_EQUAL(readNonNegativeInteger(1, begin, end), 255);
533 BOOST_CHECK_EQUAL(readNonNegativeInteger(2, begin, end), 258);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000534 BOOST_CHECK_EQUAL(readNonNegativeInteger(4, begin, end), 16843010);
535 BOOST_CHECK_EQUAL(readNonNegativeInteger(8, begin, end), 72340172838076674);
Junxiao Shic18aa192017-07-07 06:06:38 +0000536 BOOST_CHECK(begin == end);
537 }
538
539 // invalid size
540 {
541 ArrayStream stream(reinterpret_cast<const char*>(BUFFER), 3);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000542 StreamIterator begin(stream);
Junxiao Shic18aa192017-07-07 06:06:38 +0000543 BOOST_CHECK_THROW(readNonNegativeInteger(3, begin, end), Error);
544 }
545
546 // available buffer smaller than size
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700547 {
548 ArrayStream stream(reinterpret_cast<const char*>(BUFFER), 0);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000549 StreamIterator begin(stream);
Junxiao Shic18aa192017-07-07 06:06:38 +0000550 BOOST_CHECK_THROW(readNonNegativeInteger(1, begin, end), Error);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700551 }
552 {
553 ArrayStream stream(reinterpret_cast<const char*>(BUFFER), 1);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000554 StreamIterator begin(stream);
Junxiao Shic18aa192017-07-07 06:06:38 +0000555 BOOST_CHECK_THROW(readNonNegativeInteger(2, begin, end), Error);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700556 }
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700557 {
558 ArrayStream stream(reinterpret_cast<const char*>(BUFFER), 3);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000559 StreamIterator begin(stream);
Junxiao Shic18aa192017-07-07 06:06:38 +0000560 BOOST_CHECK_THROW(readNonNegativeInteger(4, begin, end), Error);
561 }
562 {
563 ArrayStream stream(reinterpret_cast<const char*>(BUFFER), 7);
Junxiao Shi46a9bd32017-07-14 19:12:11 +0000564 StreamIterator begin(stream);
Junxiao Shic18aa192017-07-07 06:06:38 +0000565 BOOST_CHECK_THROW(readNonNegativeInteger(8, begin, end), Error);
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700566 }
567}
568
569BOOST_AUTO_TEST_SUITE_END() // NonNegativeInteger
570
Davide Pesavento287a7fa2020-10-01 22:46:43 -0400571BOOST_AUTO_TEST_SUITE(OutputOperators)
Alexander Afanasyev5f1820e2017-01-04 18:12:42 -0800572
573BOOST_AUTO_TEST_CASE(PrintSignatureTypeValue)
574{
Davide Pesavento7e6f6f82017-10-31 18:05:28 -0400575 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(DigestSha256), "DigestSha256");
576 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(SignatureSha256WithRsa), "SignatureSha256WithRsa");
Junxiao Shi426d5002018-08-23 10:52:29 +0000577 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(static_cast<SignatureTypeValue>(2)), "Unknown(2)");
Davide Pesavento7e6f6f82017-10-31 18:05:28 -0400578 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(SignatureSha256WithEcdsa), "SignatureSha256WithEcdsa");
Junxiao Shi426d5002018-08-23 10:52:29 +0000579 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(SignatureHmacWithSha256), "SignatureHmacWithSha256");
Davide Pesaventoffddbbf2022-11-21 16:33:47 -0500580 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(SignatureEd25519), "SignatureEd25519");
581 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(static_cast<SignatureTypeValue>(6)), "Unknown(6)");
Davide Pesavento287a7fa2020-10-01 22:46:43 -0400582 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(static_cast<SignatureTypeValue>(199)), "Unknown(199)");
583 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(NullSignature), "NullSignature");
584 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(static_cast<SignatureTypeValue>(201)), "Unknown(201)");
Junxiao Shi426d5002018-08-23 10:52:29 +0000585}
586
587BOOST_AUTO_TEST_CASE(PrintContentTypeValue)
588{
589 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(ContentType_Blob), "Blob");
590 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(ContentType_Link), "Link");
591 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(ContentType_Key), "Key");
592 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(ContentType_Nack), "Nack");
593 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(ContentType_Manifest), "Manifest");
594 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(ContentType_PrefixAnn), "PrefixAnn");
595 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(static_cast<ContentTypeValue>(6)), "Reserved(6)");
596 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(static_cast<ContentTypeValue>(1023)), "Reserved(1023)");
597 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(ContentType_Flic), "FLIC");
598 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(static_cast<ContentTypeValue>(1025)), "Unknown(1025)");
599 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(static_cast<ContentTypeValue>(8999)), "Unknown(8999)");
600 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(static_cast<ContentTypeValue>(9000)), "Experimental(9000)");
601 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(static_cast<ContentTypeValue>(9999)), "Experimental(9999)");
602 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(static_cast<ContentTypeValue>(10000)), "Unknown(10000)");
603 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(static_cast<ContentTypeValue>(19910118)), "Unknown(19910118)");
Alexander Afanasyev5f1820e2017-01-04 18:12:42 -0800604}
605
Davide Pesavento287a7fa2020-10-01 22:46:43 -0400606BOOST_AUTO_TEST_SUITE_END() // OutputOperators
Alexander Afanasyev5f1820e2017-01-04 18:12:42 -0800607
Davide Pesaventoeee3e822016-11-26 19:19:34 +0100608BOOST_AUTO_TEST_SUITE_END() // TestTlv
609BOOST_AUTO_TEST_SUITE_END() // Encoding
Alexander Afanasyevd1de3972014-08-14 19:47:41 -0700610
Davide Pesavento47ce2ee2023-05-09 01:33:33 -0400611} // namespace ndn::tests