blob: 18126e857432b633369123d009cd3c9c988afef4 [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Junxiao Shidb7464d2017-07-13 03:11:17 +00002/*
Davide Pesavento5c803b92019-02-02 19:23:48 -05003 * Copyright (c) 2013-2019 Regents of the University of California.
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07006 *
Alexander Afanasyevc169a812014-05-20 20:37:29 -04007 * 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.
Alexander Afanasyev233750e2014-02-16 00:50:07 -080020 */
21
Davide Pesavento7e780642018-11-24 15:51:34 -050022#include "ndn-cxx/encoding/block.hpp"
23#include "ndn-cxx/encoding/block-helpers.hpp"
Alexander Afanasyev233750e2014-02-16 00:50:07 -080024
Davide Pesavento7e780642018-11-24 15:51:34 -050025#include "tests/boost-test.hpp"
26
Junxiao Shi72c0c642018-04-20 15:41:09 +000027#include <boost/lexical_cast.hpp>
Junxiao Shidc4277a2017-07-17 11:34:02 +000028#include <cstring>
29#include <sstream>
Davide Pesaventoeee3e822016-11-26 19:19:34 +010030
Alexander Afanasyev233750e2014-02-16 00:50:07 -080031namespace ndn {
Alexander Afanasyev74633892015-02-08 18:08:46 -080032namespace tests {
Alexander Afanasyev233750e2014-02-16 00:50:07 -080033
Davide Pesaventoeee3e822016-11-26 19:19:34 +010034BOOST_AUTO_TEST_SUITE(Encoding)
35BOOST_AUTO_TEST_SUITE(TestBlock)
Alexander Afanasyev233750e2014-02-16 00:50:07 -080036
Junxiao Shidc4277a2017-07-17 11:34:02 +000037BOOST_AUTO_TEST_SUITE(Construction)
38
39static const uint8_t TEST_BUFFER[] = {
40 0x00, 0x01, 0xfa, // ok
41 0x01, 0x01, 0xfb, // ok
42 0x03, 0x02, 0xff // bad: TLV-LENGTH is 2 but there's only 1-octet TLV-VALUE
Alexander Afanasyev74633892015-02-08 18:08:46 -080043};
Alexander Afanasyev2d0b4572014-02-24 16:02:12 -080044
Junxiao Shidc4277a2017-07-17 11:34:02 +000045BOOST_AUTO_TEST_CASE(Empty)
Alexander Afanasyev74633892015-02-08 18:08:46 -080046{
Junxiao Shidc4277a2017-07-17 11:34:02 +000047 Block b;
48 BOOST_CHECK_EQUAL(b.empty(), true);
Alexander Afanasyev74633892015-02-08 18:08:46 -080049}
Alexander Afanasyev937aa782014-03-21 13:17:57 -070050
Junxiao Shidc4277a2017-07-17 11:34:02 +000051BOOST_AUTO_TEST_CASE(FromEncodingBuffer)
Alexander Afanasyev74633892015-02-08 18:08:46 -080052{
Junxiao Shidc4277a2017-07-17 11:34:02 +000053 EncodingBuffer encoder;
Davide Pesavento5c803b92019-02-02 19:23:48 -050054 BOOST_CHECK_THROW(Block{encoder}, tlv::Error);
55
56 const uint8_t VALUE[] = {0x11, 0x12, 0x13, 0x14};
Junxiao Shidc4277a2017-07-17 11:34:02 +000057 size_t length = encoder.prependByteArray(VALUE, sizeof(VALUE));
58 encoder.prependVarNumber(length);
59 encoder.prependVarNumber(0xe0);
60
61 Block b = encoder.block();
62 BOOST_CHECK_EQUAL(b.type(), 0xe0);
63 BOOST_CHECK_EQUAL(b.value_size(), sizeof(VALUE));
64 BOOST_CHECK_EQUAL_COLLECTIONS(b.value_begin(), b.value_end(),
65 VALUE, VALUE + sizeof(VALUE));
66
67 b = Block(encoder);
68 BOOST_CHECK_EQUAL(b.type(), 0xe0);
69 BOOST_CHECK_EQUAL(b.value_size(), sizeof(VALUE));
70 BOOST_CHECK_EQUAL_COLLECTIONS(b.value_begin(), b.value_end(),
71 VALUE, VALUE + sizeof(VALUE));
Alexander Afanasyev74633892015-02-08 18:08:46 -080072}
Alexander Afanasyev937aa782014-03-21 13:17:57 -070073
Davide Pesaventoeee3e822016-11-26 19:19:34 +010074BOOST_AUTO_TEST_CASE(FromBlock)
Alexander Afanasyev4448d292015-08-09 20:11:37 -070075{
Davide Pesavento5c803b92019-02-02 19:23:48 -050076 const uint8_t BUFFER[] = {0x80, 0x06, 0x81, 0x01, 0x01, 0x82, 0x01, 0x01};
77 Block block(BUFFER, sizeof(BUFFER));
Alexander Afanasyev4448d292015-08-09 20:11:37 -070078
79 Block derivedBlock(block, block.begin(), block.end());
80 BOOST_CHECK_EQUAL(derivedBlock.wire(), block.wire()); // pointers should match
81 BOOST_CHECK(derivedBlock == block); // blocks should match
82
83 derivedBlock = Block(block, block.begin() + 2, block.begin() + 5);
84 BOOST_CHECK(derivedBlock.begin() == block.begin() + 2);
Davide Pesavento5c803b92019-02-02 19:23:48 -050085 BOOST_CHECK(derivedBlock == Block(BUFFER + 2, 3));
Alexander Afanasyev4448d292015-08-09 20:11:37 -070086
Davide Pesavento5c803b92019-02-02 19:23:48 -050087 Buffer otherBuffer(BUFFER, sizeof(BUFFER));
Junxiao Shidb7464d2017-07-13 03:11:17 +000088 BOOST_CHECK_THROW(Block(block, otherBuffer.begin(), block.end()), std::invalid_argument);
89 BOOST_CHECK_THROW(Block(block, block.begin(), otherBuffer.end()), std::invalid_argument);
90 BOOST_CHECK_THROW(Block(block, otherBuffer.begin(), otherBuffer.end()), std::invalid_argument);
Alexander Afanasyev4448d292015-08-09 20:11:37 -070091}
92
Davide Pesaventoeee3e822016-11-26 19:19:34 +010093BOOST_AUTO_TEST_CASE(FromBlockCopyOnWriteModifyOriginal)
Eric Newberry6235aac2015-08-13 16:03:47 -070094{
Junxiao Shidc4277a2017-07-17 11:34:02 +000095 const uint8_t BUFFER[] = {
Eric Newberry6235aac2015-08-13 16:03:47 -070096 0x05, 0x0b, 0x07, 0x03, 0x01, 0x02, 0x03, 0x0a, 0x04, 0x04, 0x05, 0x06, 0x07,
97 };
98
Junxiao Shidc4277a2017-07-17 11:34:02 +000099 Block b1(BUFFER, sizeof(BUFFER));
Eric Newberry6235aac2015-08-13 16:03:47 -0700100
Junxiao Shidc4277a2017-07-17 11:34:02 +0000101 Block b2(b1, b1.begin(), b1.end());
102 auto buf2 = b2.getBuffer();
Eric Newberry6235aac2015-08-13 16:03:47 -0700103
Junxiao Shidc4277a2017-07-17 11:34:02 +0000104 b1.parse();
105 b1.remove(tlv::Name);
106 b1.encode();
Eric Newberry6235aac2015-08-13 16:03:47 -0700107
Junxiao Shidc4277a2017-07-17 11:34:02 +0000108 b2.parse();
Eric Newberry6235aac2015-08-13 16:03:47 -0700109
Junxiao Shidc4277a2017-07-17 11:34:02 +0000110 BOOST_CHECK_EQUAL_COLLECTIONS(b2.begin(), b2.end(), BUFFER, BUFFER + sizeof(BUFFER));
111 BOOST_CHECK_EQUAL(buf2, b2.getBuffer());
Eric Newberry6235aac2015-08-13 16:03:47 -0700112}
113
Davide Pesaventoeee3e822016-11-26 19:19:34 +0100114BOOST_AUTO_TEST_CASE(FromBlockCopyOnWriteModifyCopy)
Eric Newberry6235aac2015-08-13 16:03:47 -0700115{
Junxiao Shidc4277a2017-07-17 11:34:02 +0000116 const uint8_t BUFFER[] = {
Eric Newberry6235aac2015-08-13 16:03:47 -0700117 0x05, 0x0b, 0x07, 0x03, 0x01, 0x02, 0x03, 0x0a, 0x04, 0x04, 0x05, 0x06, 0x07,
118 };
119
Junxiao Shidc4277a2017-07-17 11:34:02 +0000120 Block b1(BUFFER, sizeof(BUFFER));
121 auto buf1 = b1.getBuffer();
Eric Newberry6235aac2015-08-13 16:03:47 -0700122
Junxiao Shidc4277a2017-07-17 11:34:02 +0000123 Block b2(b1, b1.begin(), b1.end());
Eric Newberry6235aac2015-08-13 16:03:47 -0700124
Junxiao Shidc4277a2017-07-17 11:34:02 +0000125 b2.parse();
126 b2.remove(tlv::Name);
127 b2.encode();
Eric Newberry6235aac2015-08-13 16:03:47 -0700128
Junxiao Shidc4277a2017-07-17 11:34:02 +0000129 b1.parse();
130 BOOST_CHECK_EQUAL_COLLECTIONS(b1.begin(), b1.end(), BUFFER, BUFFER + sizeof(BUFFER));
131 BOOST_CHECK_EQUAL(buf1, b1.getBuffer());
Eric Newberry6235aac2015-08-13 16:03:47 -0700132}
133
Junxiao Shidc4277a2017-07-17 11:34:02 +0000134BOOST_AUTO_TEST_CASE(FromType)
Alexander Afanasyev233750e2014-02-16 00:50:07 -0800135{
Junxiao Shidc4277a2017-07-17 11:34:02 +0000136 Block b1(4);
137 BOOST_CHECK_EQUAL(b1.empty(), false);
138 BOOST_CHECK_EQUAL(b1.type(), 4);
139 BOOST_CHECK_EQUAL(b1.size(), 2); // 1-octet TLV-TYPE and 1-octet TLV-LENGTH
Davide Pesavento5c803b92019-02-02 19:23:48 -0500140 BOOST_CHECK_EQUAL(b1.hasValue(), false);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000141 BOOST_CHECK_EQUAL(b1.value_size(), 0);
Alexander Afanasyev233750e2014-02-16 00:50:07 -0800142
Junxiao Shidc4277a2017-07-17 11:34:02 +0000143 Block b2(258);
Davide Pesavento5c803b92019-02-02 19:23:48 -0500144 BOOST_CHECK_EQUAL(b2.empty(), false);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000145 BOOST_CHECK_EQUAL(b2.type(), 258);
146 BOOST_CHECK_EQUAL(b2.size(), 4); // 3-octet TLV-TYPE and 1-octet TLV-LENGTH
Davide Pesavento5c803b92019-02-02 19:23:48 -0500147 BOOST_CHECK_EQUAL(b2.hasValue(), false);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000148 BOOST_CHECK_EQUAL(b2.value_size(), 0);
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700149}
150
Davide Pesavento5c803b92019-02-02 19:23:48 -0500151BOOST_AUTO_TEST_CASE(FromTypeAndBuffer)
152{
153 const uint8_t VALUE[] = {0x11, 0x12, 0x13, 0x14};
154 auto bufferPtr = make_shared<Buffer>(VALUE, sizeof(VALUE));
155
156 Block b(42, bufferPtr);
157 BOOST_CHECK_EQUAL(b.empty(), false);
158 BOOST_CHECK_EQUAL(b.type(), 42);
159 BOOST_CHECK_EQUAL(b.size(), 6);
160 BOOST_CHECK_EQUAL(b.hasValue(), true);
161 BOOST_CHECK_EQUAL(b.value_size(), sizeof(VALUE));
162}
163
164BOOST_AUTO_TEST_CASE(FromTypeAndBlock)
165{
166 const uint8_t BUFFER[] = {0x80, 0x06, 0x81, 0x01, 0x01, 0x82, 0x01, 0x01};
167 Block nested(BUFFER, sizeof(BUFFER));
168
169 Block b(84, nested);
170 BOOST_CHECK_EQUAL(b.empty(), false);
171 BOOST_CHECK_EQUAL(b.type(), 84);
172 BOOST_CHECK_EQUAL(b.size(), 10);
173 BOOST_CHECK_EQUAL(b.hasValue(), true);
174 BOOST_CHECK_EQUAL(b.value_size(), sizeof(BUFFER));
175}
176
Junxiao Shif0da7892015-04-04 22:16:16 -0700177BOOST_AUTO_TEST_CASE(FromStream)
Alexander Afanasyev21ef2392014-03-25 12:40:22 -0700178{
Junxiao Shidc4277a2017-07-17 11:34:02 +0000179 std::stringstream stream;
180 stream.write(reinterpret_cast<const char*>(TEST_BUFFER), sizeof(TEST_BUFFER));
181 stream.seekg(0);
Alexander Afanasyev21ef2392014-03-25 12:40:22 -0700182
Junxiao Shidc4277a2017-07-17 11:34:02 +0000183 Block b = Block::fromStream(stream);
184 BOOST_CHECK_EQUAL(b.type(), 0);
185 BOOST_CHECK_EQUAL(b.size(), 3);
186 BOOST_CHECK_EQUAL(b.value_size(), 1);
187 BOOST_CHECK_EQUAL(*b.wire(), 0x00);
188 BOOST_CHECK_EQUAL(*b.value(), 0xfa);
Alexander Afanasyev21ef2392014-03-25 12:40:22 -0700189
Junxiao Shidc4277a2017-07-17 11:34:02 +0000190 b = Block::fromStream(stream);
191 BOOST_CHECK_EQUAL(b.type(), 1);
192 BOOST_CHECK_EQUAL(b.size(), 3);
193 BOOST_CHECK_EQUAL(b.value_size(), 1);
194 BOOST_CHECK_EQUAL(*b.wire(), 0x01);
195 BOOST_CHECK_EQUAL(*b.value(), 0xfb);
Alexander Afanasyev21ef2392014-03-25 12:40:22 -0700196
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600197 BOOST_CHECK_THROW(Block::fromStream(stream), tlv::Error);
Alexander Afanasyev21ef2392014-03-25 12:40:22 -0700198}
199
Junxiao Shif0da7892015-04-04 22:16:16 -0700200BOOST_AUTO_TEST_CASE(FromStreamWhitespace) // Bug 2728
201{
Junxiao Shidc4277a2017-07-17 11:34:02 +0000202 const uint8_t PACKET[] = {
Junxiao Shif0da7892015-04-04 22:16:16 -0700203 0x06, 0x20, // Data
204 0x07, 0x11, // Name
Junxiao Shi4ffbb9d2018-03-31 17:16:35 +0000205 0x08, 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, // GenericNameComponent 'hello'
206 0x08, 0x01, 0x31, // GenericNameComponent '1'
207 0x08, 0x05, 0x77, 0x6f, 0x72, 0x6c, 0x64, // GenericNameComponent 'world'
Junxiao Shif0da7892015-04-04 22:16:16 -0700208 0x14, 0x00, // MetaInfo empty
209 0x15, 0x00, // Content empty
210 0x16, 0x05, // SignatureInfo
Junxiao Shidc4277a2017-07-17 11:34:02 +0000211 0x1b, 0x01, 0x01, // SignatureType RSA
212 0x1c, 0x00, // KeyLocator empty
Junxiao Shif0da7892015-04-04 22:16:16 -0700213 0x17, 0x00 // SignatureValue empty
214 };
215 // TLV-LENGTH of <Data> is 0x20 which happens to be ASCII whitespace
216
217 std::stringstream stream;
218 stream.write(reinterpret_cast<const char*>(PACKET), sizeof(PACKET));
219 stream.seekg(0);
220
Junxiao Shidc4277a2017-07-17 11:34:02 +0000221 Block b = Block::fromStream(stream);
222 BOOST_CHECK_EQUAL(b.type(), 6);
223 BOOST_CHECK_EQUAL(b.value_size(), 32);
224 b.parse();
Junxiao Shif0da7892015-04-04 22:16:16 -0700225}
226
Junxiao Shi760cc7b2017-07-22 19:17:49 +0000227BOOST_AUTO_TEST_CASE(FromStreamZeroLength)
Junxiao Shif0da7892015-04-04 22:16:16 -0700228{
Junxiao Shi760cc7b2017-07-22 19:17:49 +0000229 const uint8_t BUFFER[] = {0x70, 0x00,
230 0x71, 0x03, 0x86, 0x11, 0x24,
231 0x72, 0x00};
Junxiao Shif0da7892015-04-04 22:16:16 -0700232
233 std::stringstream stream;
234 stream.write(reinterpret_cast<const char*>(BUFFER), sizeof(BUFFER));
235 stream.seekg(0);
236
Junxiao Shi760cc7b2017-07-22 19:17:49 +0000237 Block b1 = Block::fromStream(stream);
238 BOOST_CHECK_EQUAL(b1.type(), 0x70);
239 BOOST_CHECK_EQUAL(b1.value_size(), 0);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000240
Junxiao Shi760cc7b2017-07-22 19:17:49 +0000241 Block b2 = Block::fromStream(stream);
242 BOOST_CHECK_EQUAL(b2.type(), 0x71);
243 BOOST_CHECK_EQUAL(b2.value_size(), 3);
244 const uint8_t EXPECTED_VALUE2[] = {0x86, 0x11, 0x24};
245 BOOST_CHECK_EQUAL_COLLECTIONS(b2.value_begin(), b2.value_end(),
246 EXPECTED_VALUE2, EXPECTED_VALUE2 + sizeof(EXPECTED_VALUE2));
247
248 Block b3 = Block::fromStream(stream);
249 BOOST_CHECK_EQUAL(b3.type(), 0x72);
250 BOOST_CHECK_EQUAL(b3.value_size(), 0);
251
252 BOOST_CHECK_THROW(Block::fromStream(stream), tlv::Error);
253}
254
255BOOST_AUTO_TEST_CASE(FromStreamPacketTooLarge)
256{
257 const uint8_t BUFFER[] = {0x07, 0xfe, 0x00, 0x01, 0x00, 0x00};
258
259 std::stringstream stream;
260 stream.write(reinterpret_cast<const char*>(BUFFER), sizeof(BUFFER));
261 for (int i = 0; i < 0x10000; ++i) {
262 stream.put('\0');
263 }
264 stream.seekg(0);
265
266 BOOST_CHECK_THROW(Block::fromStream(stream), tlv::Error);
Junxiao Shidc4277a2017-07-17 11:34:02 +0000267}
268
269BOOST_AUTO_TEST_CASE(FromWireBuffer)
270{
271 ConstBufferPtr buffer = make_shared<Buffer>(TEST_BUFFER, sizeof(TEST_BUFFER));
272
273 size_t offset = 0;
274 bool isOk = false;
275 Block b;
276 std::tie(isOk, b) = Block::fromBuffer(buffer, offset);
277 BOOST_CHECK(isOk);
278 BOOST_CHECK_EQUAL(b.type(), 0);
279 BOOST_CHECK_EQUAL(b.size(), 3);
280 BOOST_CHECK_EQUAL(b.value_size(), 1);
281 BOOST_CHECK_EQUAL(*b.wire(), 0x00);
282 BOOST_CHECK_EQUAL(*b.value(), 0xfa);
283 offset += b.size();
284
285 std::tie(isOk, b) = Block::fromBuffer(buffer, offset);
286 BOOST_CHECK(isOk);
287 BOOST_CHECK_EQUAL(b.type(), 1);
288 BOOST_CHECK_EQUAL(b.size(), 3);
289 BOOST_CHECK_EQUAL(b.value_size(), 1);
290 BOOST_CHECK_EQUAL(*b.wire(), 0x01);
291 BOOST_CHECK_EQUAL(*b.value(), 0xfb);
292 offset += b.size();
293
294 std::tie(isOk, b) = Block::fromBuffer(buffer, offset);
295 BOOST_CHECK(!isOk);
296}
297
298BOOST_AUTO_TEST_CASE(FromRawBuffer)
299{
300 size_t offset = 0;
301 bool isOk = false;
302 Block b;
303 std::tie(isOk, b) = Block::fromBuffer(TEST_BUFFER + offset, sizeof(TEST_BUFFER) - offset);
304 BOOST_CHECK(isOk);
305 BOOST_CHECK_EQUAL(b.type(), 0);
306 BOOST_CHECK_EQUAL(b.size(), 3);
307 BOOST_CHECK_EQUAL(b.value_size(), 1);
308 BOOST_CHECK_EQUAL(*b.wire(), 0x00);
309 BOOST_CHECK_EQUAL(*b.value(), 0xfa);
310 offset += b.size();
311
312 std::tie(isOk, b) = Block::fromBuffer(TEST_BUFFER + offset, sizeof(TEST_BUFFER) - offset);
313 BOOST_CHECK(isOk);
314 BOOST_CHECK_EQUAL(b.type(), 1);
315 BOOST_CHECK_EQUAL(b.size(), 3);
316 BOOST_CHECK_EQUAL(b.value_size(), 1);
317 BOOST_CHECK_EQUAL(*b.wire(), 0x01);
318 BOOST_CHECK_EQUAL(*b.value(), 0xfb);
319 offset += b.size();
320
321 std::tie(isOk, b) = Block::fromBuffer(TEST_BUFFER + offset, sizeof(TEST_BUFFER) - offset);
322 BOOST_CHECK(!isOk);
Junxiao Shif0da7892015-04-04 22:16:16 -0700323}
324
Davide Pesaventoeee3e822016-11-26 19:19:34 +0100325BOOST_AUTO_TEST_SUITE_END() // Construction
326
Junxiao Shidc4277a2017-07-17 11:34:02 +0000327BOOST_AUTO_TEST_SUITE(SubElements)
328
329BOOST_AUTO_TEST_CASE(Parse)
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700330{
Junxiao Shidc4277a2017-07-17 11:34:02 +0000331 const uint8_t PACKET[] = {
332 0x06, 0x20, // Data
333 0x07, 0x11, // Name
Junxiao Shi4ffbb9d2018-03-31 17:16:35 +0000334 0x08, 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, // GenericNameComponent 'hello'
335 0x08, 0x01, 0x31, // GenericNameComponent '1'
336 0x08, 0x05, 0x77, 0x6f, 0x72, 0x6c, 0x64, // GenericNameComponent 'world'
Junxiao Shidc4277a2017-07-17 11:34:02 +0000337 0x14, 0x00, // MetaInfo empty
338 0x15, 0x00, // Content empty
339 0x16, 0x05, // SignatureInfo
340 0x1b, 0x01, 0x01, // SignatureType RSA
341 0x1c, 0x00, // KeyLocator empty
342 0x17, 0x00 // SignatureValue empty
343 };
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700344
Junxiao Shidc4277a2017-07-17 11:34:02 +0000345 Block data(PACKET, sizeof(PACKET));
346 data.parse();
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700347
Junxiao Shidc4277a2017-07-17 11:34:02 +0000348 BOOST_CHECK_EQUAL(data.elements_size(), 5);
349 BOOST_CHECK_EQUAL(data.elements().at(0).type(), 0x07);
350 BOOST_CHECK_EQUAL(data.elements().at(0).elements().size(), 0); // parse is not recursive
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700351
Junxiao Shidc4277a2017-07-17 11:34:02 +0000352 BOOST_CHECK(data.get(0x15) == data.elements().at(2));
353 BOOST_CHECK_THROW(data.get(0x01), Block::Error);
354
355 BOOST_CHECK(data.find(0x15) == data.elements_begin() + 2);
356 BOOST_CHECK(data.find(0x01) == data.elements_end());
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700357}
358
Joao Pereira7476ebf2015-07-07 14:54:39 -0400359BOOST_AUTO_TEST_CASE(InsertBeginning)
360{
361 Block masterBlock(tlv::Name);
Junxiao Shi4ffbb9d2018-03-31 17:16:35 +0000362 Block firstBlock = makeStringBlock(tlv::GenericNameComponent, "firstName");
363 Block secondBlock = makeStringBlock(tlv::GenericNameComponent, "secondName");
364 Block thirdBlock = makeStringBlock(tlv::GenericNameComponent, "thirdName");
Joao Pereira7476ebf2015-07-07 14:54:39 -0400365
366 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 0);
367 masterBlock.push_back(secondBlock);
368 masterBlock.push_back(thirdBlock);
369 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 2);
Junxiao Shi4ffbb9d2018-03-31 17:16:35 +0000370 Block::element_const_iterator it = masterBlock.find(tlv::GenericNameComponent);
Joao Pereira7476ebf2015-07-07 14:54:39 -0400371 BOOST_CHECK_EQUAL(*it == secondBlock, true);
372
373 it = masterBlock.insert(it, firstBlock);
374
375 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 3);
376 BOOST_CHECK_EQUAL(*(it + 1) == secondBlock, true);
377 BOOST_CHECK_EQUAL(*(masterBlock.elements_begin()) == firstBlock, true);
378}
379
380BOOST_AUTO_TEST_CASE(InsertEnd)
381{
382 Block masterBlock(tlv::Name);
Junxiao Shi4ffbb9d2018-03-31 17:16:35 +0000383 Block firstBlock = makeStringBlock(tlv::GenericNameComponent, "firstName");
384 Block secondBlock = makeStringBlock(tlv::GenericNameComponent, "secondName");
385 Block thirdBlock = makeStringBlock(tlv::GenericNameComponent, "thirdName");
Joao Pereira7476ebf2015-07-07 14:54:39 -0400386
387 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 0);
388 masterBlock.push_back(firstBlock);
389 masterBlock.push_back(secondBlock);
390 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 2);
391 Block::element_const_iterator it = masterBlock.elements_end();
392 BOOST_CHECK_EQUAL(*(it - 1) == secondBlock, true);
393
394 it = masterBlock.insert(it, thirdBlock);
395
396 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 3);
397 BOOST_CHECK_EQUAL(*(it - 1) == secondBlock, true);
398 BOOST_CHECK_EQUAL(*(masterBlock.elements_end() - 1) == thirdBlock, true);
399}
400
401BOOST_AUTO_TEST_CASE(InsertMiddle)
402{
403 Block masterBlock(tlv::Name);
Junxiao Shi4ffbb9d2018-03-31 17:16:35 +0000404 Block firstBlock = makeStringBlock(tlv::GenericNameComponent, "firstName");
405 Block secondBlock = makeStringBlock(tlv::GenericNameComponent, "secondName");
406 Block thirdBlock = makeStringBlock(tlv::GenericNameComponent, "thirdName");
Joao Pereira7476ebf2015-07-07 14:54:39 -0400407
408 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 0);
409 masterBlock.push_back(firstBlock);
410 masterBlock.push_back(thirdBlock);
411 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 2);
Junxiao Shi4ffbb9d2018-03-31 17:16:35 +0000412 Block::element_const_iterator it = masterBlock.find(tlv::GenericNameComponent);
Joao Pereira7476ebf2015-07-07 14:54:39 -0400413 BOOST_CHECK_EQUAL(*it == firstBlock, true);
414
Junxiao Shidc4277a2017-07-17 11:34:02 +0000415 it = masterBlock.insert(it + 1, secondBlock);
Joao Pereira7476ebf2015-07-07 14:54:39 -0400416
417 BOOST_CHECK_EQUAL(*it == secondBlock, true);
418 BOOST_CHECK_EQUAL(*(it + 1) == thirdBlock, true);
419 BOOST_CHECK_EQUAL(*(it - 1) == firstBlock, true);
420}
421
422BOOST_AUTO_TEST_CASE(EraseSingleElement)
423{
424 Block masterBlock(tlv::Name);
Junxiao Shi4ffbb9d2018-03-31 17:16:35 +0000425 Block firstBlock = makeStringBlock(tlv::GenericNameComponent, "firstName");
426 Block secondBlock = makeStringBlock(tlv::GenericNameComponent, "secondName");
427 Block thirdBlock = makeStringBlock(tlv::GenericNameComponent, "thirdName");
Joao Pereira7476ebf2015-07-07 14:54:39 -0400428
429 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 0);
430 masterBlock.push_back(firstBlock);
431 masterBlock.push_back(secondBlock);
432 masterBlock.push_back(thirdBlock);
433 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 3);
Junxiao Shi4ffbb9d2018-03-31 17:16:35 +0000434 Block::element_const_iterator it = masterBlock.find(tlv::GenericNameComponent);
Joao Pereira7476ebf2015-07-07 14:54:39 -0400435 it++;
436 BOOST_CHECK_EQUAL(*it == secondBlock, true);
437
438 it = masterBlock.erase(it);
439
440 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 2);
441 BOOST_CHECK_EQUAL(*(it) == thirdBlock, true);
442 BOOST_CHECK_EQUAL(*(it - 1) == firstBlock, true);
443}
444
445BOOST_AUTO_TEST_CASE(EraseRange)
446{
447 Block masterBlock(tlv::Name);
Junxiao Shi4ffbb9d2018-03-31 17:16:35 +0000448 Block firstBlock = makeStringBlock(tlv::GenericNameComponent, "firstName");
449 Block secondBlock = makeStringBlock(tlv::GenericNameComponent, "secondName");
450 Block thirdBlock = makeStringBlock(tlv::GenericNameComponent, "thirdName");
451 Block fourthBlock = makeStringBlock(tlv::GenericNameComponent, "fourthName");
452 Block fifthBlock = makeStringBlock(tlv::GenericNameComponent, "fifthName");
453 Block sixthBlock = makeStringBlock(tlv::GenericNameComponent, "sixthName");
Joao Pereira7476ebf2015-07-07 14:54:39 -0400454
455 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 0);
456 masterBlock.push_back(firstBlock);
457 masterBlock.push_back(secondBlock);
458 masterBlock.push_back(thirdBlock);
459 masterBlock.push_back(fourthBlock);
460 masterBlock.push_back(fifthBlock);
461 masterBlock.push_back(sixthBlock);
462 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 6);
Junxiao Shi4ffbb9d2018-03-31 17:16:35 +0000463 Block::element_const_iterator itStart = masterBlock.find(tlv::GenericNameComponent);
Joao Pereira7476ebf2015-07-07 14:54:39 -0400464 itStart++;
465 Block::element_const_iterator itEnd = itStart + 3;
466 BOOST_CHECK_EQUAL(*itStart == secondBlock, true);
467 BOOST_CHECK_EQUAL(*itEnd == fifthBlock, true);
468
469 Block::element_const_iterator newIt = masterBlock.erase(itStart, itEnd);
470
471 BOOST_CHECK_EQUAL(masterBlock.elements_size(), 3);
472 BOOST_CHECK_EQUAL(*(newIt) == fifthBlock, true);
473 BOOST_CHECK_EQUAL(*(newIt - 1) == firstBlock, true);
474}
475
Eric Newberrya3d9fc02015-07-26 10:55:44 -0700476BOOST_AUTO_TEST_CASE(Remove)
477{
478 Block block(tlv::Data);
479 block.push_back(makeNonNegativeIntegerBlock(tlv::ContentType, 0));
480 block.push_back(makeNonNegativeIntegerBlock(tlv::FreshnessPeriod, 123));
481 block.push_back(makeStringBlock(tlv::Name, "ndn:/test-prefix"));
482 block.push_back(makeNonNegativeIntegerBlock(tlv::ContentType, 2));
483 block.push_back(makeNonNegativeIntegerBlock(tlv::ContentType, 1));
484
485 BOOST_CHECK_EQUAL(5, block.elements_size());
486 BOOST_REQUIRE_NO_THROW(block.remove(tlv::ContentType));
487 BOOST_CHECK_EQUAL(2, block.elements_size());
488
489 Block::element_container elements = block.elements();
490
491 BOOST_CHECK_EQUAL(tlv::FreshnessPeriod, elements[0].type());
492 BOOST_CHECK_EQUAL(123, readNonNegativeInteger(elements[0]));
493 BOOST_CHECK_EQUAL(tlv::Name, elements[1].type());
494 BOOST_CHECK(readString(elements[1]).compare("ndn:/test-prefix") == 0);
495}
496
Junxiao Shidc4277a2017-07-17 11:34:02 +0000497BOOST_AUTO_TEST_SUITE_END() // SubElements
498
499BOOST_AUTO_TEST_CASE(Equality)
500{
Davide Pesaventob10024c2017-09-22 01:36:44 -0400501 const uint8_t one[] = {0x08, 0x00};
502 Block a(one, sizeof(one));
503 Block b(one, sizeof(one));
Junxiao Shidc4277a2017-07-17 11:34:02 +0000504 BOOST_CHECK_EQUAL(a == b, true);
505 BOOST_CHECK_EQUAL(a != b, false);
506
Davide Pesaventob10024c2017-09-22 01:36:44 -0400507 const uint8_t two[] = {0x06, 0x00};
508 Block c(two, sizeof(two));
509 Block d(one, sizeof(one));
Junxiao Shidc4277a2017-07-17 11:34:02 +0000510 BOOST_CHECK_EQUAL(c == d, false);
511 BOOST_CHECK_EQUAL(c != d, true);
512
Davide Pesaventob10024c2017-09-22 01:36:44 -0400513 const uint8_t three[] = {0x06, 0x01, 0xcc};
514 Block e(two, sizeof(two));
515 Block f(three, sizeof(three));
Junxiao Shidc4277a2017-07-17 11:34:02 +0000516 BOOST_CHECK_EQUAL(e == f, false);
517 BOOST_CHECK_EQUAL(e != f, true);
518}
519
Junxiao Shi72c0c642018-04-20 15:41:09 +0000520BOOST_AUTO_TEST_CASE(Print)
521{
522 // default constructed
523 Block b;
524 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(b), "[invalid]");
525
526 // zero length
527 b = "0700"_block;
528 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(b), "7[empty]");
529
530 // unparsed
531 b = "0E10FF7E4E6B3B21C902660F16ED589FCCCC"_block;
532 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(b),
533 "14[16]=FF7E4E6B3B21C902660F16ED589FCCCC");
534 // set and restore format flags
535 {
536 std::ostringstream oss;
537 oss << std::showbase << std::hex << 0xd23c4 << b << 0x4981e;
538 BOOST_CHECK_EQUAL(oss.str(), "0xd23c414[16]=FF7E4E6B3B21C902660F16ED589FCCCC0x4981e");
539 }
540
541 // parsed
542 b = "FD010808 0502CADD 59024E42"_block;
543 b.parse();
544 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(b),
545 "264[8]={5[2]=CADD,89[2]=4E42}");
546
547 // parsed then modified: print modified sub-elements
548 b = "FD010808 0502CADD 59024E42"_block;
549 b.parse();
550 b.erase(b.elements_begin());
551 b.push_back("10022386"_block);
552 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(b),
553 "264[8]={89[2]=4E42,16[2]=2386}");
554}
555
Junxiao Shi2b322eb2018-08-24 10:43:27 -0600556BOOST_AUTO_TEST_SUITE(BlockLiteral)
557
558BOOST_AUTO_TEST_CASE(Simple)
559{
560 Block b0 = "0000"_block;
561 BOOST_CHECK_EQUAL(b0.type(), 0x00);
562 BOOST_CHECK_EQUAL(b0.value_size(), 0);
563
564 Block b1 = "0101A0"_block;
565 BOOST_CHECK_EQUAL(b1.type(), 0x01);
566 BOOST_REQUIRE_EQUAL(b1.value_size(), 1);
567 BOOST_CHECK_EQUAL(b1.value()[0], 0xA0);
568}
569
570BOOST_AUTO_TEST_CASE(Comment)
571{
572 Block b0 = "a2b0c0d2eBf0G.B 1+"_block;
573 BOOST_CHECK_EQUAL(b0.type(), 0x20);
574 BOOST_REQUIRE_EQUAL(b0.value_size(), 2);
575 BOOST_CHECK_EQUAL(b0.value()[0], 0xB0);
576 BOOST_CHECK_EQUAL(b0.value()[1], 0xB1);
577}
578
579BOOST_AUTO_TEST_CASE(BadInput)
580{
581 BOOST_CHECK_THROW(""_block, std::invalid_argument);
582 BOOST_CHECK_THROW("1"_block, std::invalid_argument);
583 BOOST_CHECK_THROW("333"_block, std::invalid_argument);
584
585 BOOST_CHECK_THROW("0202C0"_block, tlv::Error);
586 BOOST_CHECK_THROW("0201C0C1"_block, tlv::Error);
587}
588
589BOOST_AUTO_TEST_SUITE_END() // BlockLiteral
590
Davide Pesaventoeee3e822016-11-26 19:19:34 +0100591BOOST_AUTO_TEST_SUITE_END() // TestBlock
592BOOST_AUTO_TEST_SUITE_END() // Encoding
Alexander Afanasyev233750e2014-02-16 00:50:07 -0800593
Alexander Afanasyev74633892015-02-08 18:08:46 -0800594} // namespace tests
Alexander Afanasyev233750e2014-02-16 00:50:07 -0800595} // namespace ndn