blob: 47b6b937cc0fd0b0fcf39392ae1ee292209c3a77 [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesavento88a0d812017-08-19 21:31:42 -04002/*
Junxiao Shicf4ac5b2018-03-28 22:46:06 +00003 * Copyright (c) 2013-2018 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 Afanasyev95e8c2f2014-02-06 17:29:30 -080020 */
21
22#ifndef NDN_NAME_COMPONENT_HPP
23#define NDN_NAME_COMPONENT_HPP
24
25#include "common.hpp"
26#include "encoding/block.hpp"
Alexander Afanasyev74633892015-02-08 18:08:46 -080027#include "encoding/block-helpers.hpp"
Alexander Afanasyev15f67312014-07-22 15:11:09 -070028#include "util/time.hpp"
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080029
30namespace ndn {
31namespace name {
32
Alexander Afanasyev15f67312014-07-22 15:11:09 -070033/// @brief Segment marker for NDN naming conventions
34static const uint8_t SEGMENT_MARKER = 0x00;
35/// @brief Segment offset marker for NDN naming conventions
36static const uint8_t SEGMENT_OFFSET_MARKER = 0xFB;
37/// @brief Version marker for NDN naming conventions
38static const uint8_t VERSION_MARKER = 0xFD;
39/// @brief Timestamp marker for NDN naming conventions
40static const uint8_t TIMESTAMP_MARKER = 0xFC;
41/// @brief Sequence number marker for NDN naming conventions
42static const uint8_t SEQUENCE_NUMBER_MARKER = 0xFE;
43
Junxiao Shicf4ac5b2018-03-28 22:46:06 +000044/** @brief Represents a name component.
45 *
46 * The @c Component class provides a read-only view of a @c Block interpreted as a name component.
47 * Although it inherits mutation methods from @c Block base class, they must not be used, because
48 * the enclosing @c Name would not be updated correctly.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080049 */
50class Component : public Block
51{
52public:
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070053 class Error : public Block::Error
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070054 {
55 public:
56 explicit
57 Error(const std::string& what)
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070058 : Block::Error(what)
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070059 {
60 }
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -070061 };
62
Junxiao Shicf4ac5b2018-03-28 22:46:06 +000063public: // constructors
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080064 /**
Junxiao Shia36f15d2018-04-04 02:22:11 +000065 * @brief Construct a NameComponent of TLV-TYPE @p type, using empty TLV-VALUE.
Junxiao Shicf4ac5b2018-03-28 22:46:06 +000066 * @throw Error the NameComponent is invalid (see @c ensureValid).
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080067 */
Junxiao Shicf4ac5b2018-03-28 22:46:06 +000068 explicit
69 Component(uint32_t type = tlv::GenericNameComponent);
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080070
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -080071 /**
Junxiao Shicf4ac5b2018-03-28 22:46:06 +000072 * @brief Construct a NameComponent from @p block.
73 * @throw Error the NameComponent is invalid (see @c ensureValid).
Alexander Afanasyev770827c2014-05-13 17:42:55 -070074 *
Junxiao Shicf4ac5b2018-03-28 22:46:06 +000075 * This contructor enables implicit conversion from @c Block.
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -080076 */
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -070077 Component(const Block& wire);
78
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080079 /**
Junxiao Shia36f15d2018-04-04 02:22:11 +000080 * @brief Construct a NameComponent of TLV-TYPE @p type, using TLV-VALUE from @p buffer.
Junxiao Shicf4ac5b2018-03-28 22:46:06 +000081 * @throw Error the NameComponent is invalid (see @c ensureValid).
Alexander Afanasyev770827c2014-05-13 17:42:55 -070082 *
Junxiao Shicf4ac5b2018-03-28 22:46:06 +000083 * This constructor does not copy the underlying buffer, but retains a pointer to it.
84 * Therefore, the caller must not change the underlying buffer.
85 */
86 Component(uint32_t type, ConstBufferPtr buffer);
87
88 /**
89 * @brief Construct a GenericNameComponent, using TLV-VALUE from @p buffer.
90 * @throw Error the NameComponent is invalid (see @c ensureValid).
Alexander Afanasyev770827c2014-05-13 17:42:55 -070091 *
Junxiao Shicf4ac5b2018-03-28 22:46:06 +000092 * This constructor does not copy the underlying buffer, but retains a pointer to it.
93 * Therefore, the caller must not change the underlying buffer.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080094 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070095 explicit
Junxiao Shicf4ac5b2018-03-28 22:46:06 +000096 Component(ConstBufferPtr buffer)
97 : Component(tlv::GenericNameComponent, std::move(buffer))
98 {
99 }
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700100
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800101 /**
Junxiao Shia36f15d2018-04-04 02:22:11 +0000102 * @brief Construct a NameComponent of TLV-TYPE @p type, copying TLV-VALUE from @p buffer.
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000103 */
104 Component(uint32_t type, const Buffer& buffer)
105 : Component(type, buffer.data(), buffer.size())
106 {
107 }
108
109 /**
110 * @brief Construct a GenericNameComponent, copying TLV-VALUE from @p buffer.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800111 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700112 explicit
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000113 Component(const Buffer& buffer)
114 : Component(tlv::GenericNameComponent, buffer)
115 {
116 }
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800117
118 /**
Junxiao Shia36f15d2018-04-04 02:22:11 +0000119 * @brief Construct a NameComponent of TLV-TYPE @p type, copying @p count bytes at @p value as
120 * TLV-VALUE.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800121 */
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000122 Component(uint32_t type, const uint8_t* value, size_t count);
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800123
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700124 /**
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000125 * @brief Construct a GenericNameComponent, copying @p count bytes at @p value as TLV-VALUE.
126 */
127 Component(const uint8_t* value, size_t count)
128 : Component(tlv::GenericNameComponent, value, count)
129 {
130 }
131
132 /**
Junxiao Shia36f15d2018-04-04 02:22:11 +0000133 * @brief Construct a NameComponent of TLV-TYPE @p type, copying TLV-VALUE from a range.
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000134 * @tparam Iterator an @c InputIterator dereferencing to a one-octet value type. More efficient
135 * implementation is available when it is a @c RandomAccessIterator.
136 * @param type the TLV-TYPE.
137 * @param first beginning of the range.
138 * @param last past-end of the range.
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700139 */
Alexander Afanasyev74633892015-02-08 18:08:46 -0800140 template<class Iterator>
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000141 Component(uint32_t type, Iterator first, Iterator last)
142 : Block(makeBinaryBlock(type, first, last))
143 {
144 }
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -0800145
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700146 /**
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000147 * @brief Construct a GenericNameComponent, copying TLV-VALUE from a range.
148 */
149 template<class Iterator>
150 Component(Iterator first, Iterator last)
151 : Component(tlv::GenericNameComponent, first, last)
152 {
153 }
154
155 /**
156 * @brief Construct a GenericNameComponent, copying TLV-VALUE from a null-terminated string.
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700157 *
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000158 * Bytes from the string are copied as is, and not interpreted as URI component.
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700159 */
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -0800160 explicit
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700161 Component(const char* str);
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800162
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700163 /**
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000164 * @brief Construct a GenericNameComponent, copying TLV-VALUE from a string.
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700165 *
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000166 * Bytes from the string are copied as is, and not interpreted as URI component.
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700167 */
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -0800168 explicit
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700169 Component(const std::string& str);
170
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000171public: // encoding and URI
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800172 /**
173 * @brief Fast encoding or block size estimation
174 */
Alexander Afanasyev74633892015-02-08 18:08:46 -0800175 template<encoding::Tag TAG>
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800176 size_t
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -0700177 wireEncode(EncodingImpl<TAG>& encoder) const;
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700178
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800179 /**
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700180 * @brief Encode to a wire format
181 */
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700182 const Block&
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700183 wireEncode() const;
184
185 /**
186 * @brief Decode from the wire format
187 */
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700188 void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700189 wireDecode(const Block& wire);
190
191 /**
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000192 * @brief Decode NameComponent from a URI component.
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700193 *
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000194 * The URI component is read from `[input+beginOffset, input+endOffset)` range.
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700195 *
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000196 * @throw Error URI component does not represent a valid NameComponent.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800197 */
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700198 static Component
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000199 fromEscapedString(const char* input, size_t beginOffset, size_t endOffset)
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800200 {
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000201 return fromEscapedString(std::string(input + beginOffset, input + endOffset));
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800202 }
203
204 /**
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000205 * @brief Decode NameComponent from a URI component.
206 * @throw Error URI component does not represent a valid NameComponent.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800207 */
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700208 static Component
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000209 fromEscapedString(const char* input)
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800210 {
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000211 return fromEscapedString(std::string(input));
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800212 }
213
214 /**
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000215 * @brief Decode NameComponent from a URI component.
216 * @throw Error URI component does not represent a valid NameComponent.
217 */
218 static Component
219 fromEscapedString(std::string input);
220
221 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700222 * @brief Write *this to the output stream, escaping characters according to the NDN URI Scheme
223 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700224 * This also adds "..." to a value with zero or more "."
225 *
Junxiao Shia36f15d2018-04-04 02:22:11 +0000226 * @param os The output stream where to write the URI escaped version of *this
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700227 */
228 void
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700229 toUri(std::ostream& os) const;
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -0800230
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700231 /**
232 * @brief Convert *this by escaping characters according to the NDN URI Scheme
233 *
234 * This also adds "..." to a value with zero or more "."
235 *
236 * @return The escaped string
237 */
238 std::string
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700239 toUri() const;
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700240
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000241public: // naming conventions
Alexander Afanasyev0f232c52014-10-23 13:07:31 -0700242 /**
243 * @brief Check if the component is nonNegativeInteger
Junxiao Shia36f15d2018-04-04 02:22:11 +0000244 * @sa https://named-data.net/doc/NDN-packet-spec/current/tlv.html#non-negative-integer-encoding
Alexander Afanasyev0f232c52014-10-23 13:07:31 -0700245 */
246 bool
247 isNumber() const;
248
249 /**
250 * @brief Check if the component is NameComponentWithMarker per NDN naming conventions
Junxiao Shia36f15d2018-04-04 02:22:11 +0000251 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
Alexander Afanasyev0f232c52014-10-23 13:07:31 -0700252 */
253 bool
254 isNumberWithMarker(uint8_t marker) const;
255
256 /**
257 * @brief Check if the component is version per NDN naming conventions
Junxiao Shia36f15d2018-04-04 02:22:11 +0000258 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
Alexander Afanasyev0f232c52014-10-23 13:07:31 -0700259 */
260 bool
261 isVersion() const;
262
263 /**
264 * @brief Check if the component is segment number per NDN naming conventions
Junxiao Shia36f15d2018-04-04 02:22:11 +0000265 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
Alexander Afanasyev0f232c52014-10-23 13:07:31 -0700266 */
267 bool
268 isSegment() const;
269
270 /**
271 * @brief Check if the component is segment offset per NDN naming conventions
Junxiao Shia36f15d2018-04-04 02:22:11 +0000272 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
Alexander Afanasyev0f232c52014-10-23 13:07:31 -0700273 */
274 bool
275 isSegmentOffset() const;
276
277 /**
278 * @brief Check if the component is timestamp per NDN naming conventions
Junxiao Shia36f15d2018-04-04 02:22:11 +0000279 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
Alexander Afanasyev0f232c52014-10-23 13:07:31 -0700280 */
281 bool
282 isTimestamp() const;
283
284 /**
285 * @brief Check if the component is sequence number per NDN naming conventions
Junxiao Shia36f15d2018-04-04 02:22:11 +0000286 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
Alexander Afanasyev0f232c52014-10-23 13:07:31 -0700287 */
288 bool
289 isSequenceNumber() const;
290
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800291 /**
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700292 * @brief Interpret this name component as nonNegativeInteger
293 *
Junxiao Shia36f15d2018-04-04 02:22:11 +0000294 * @sa https://named-data.net/doc/NDN-packet-spec/current/tlv.html#non-negative-integer-encoding
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700295 *
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800296 * @return The integer number.
297 */
298 uint64_t
299 toNumber() const;
300
301 /**
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700302 * @brief Interpret this name component as NameComponentWithMarker
303 *
Junxiao Shia36f15d2018-04-04 02:22:11 +0000304 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700305 *
306 * @param marker 1-byte octet of the marker
307 * @return The integer number.
308 * @throws Error if name component does not have the specified marker.
309 * tlv::Error if format does not follow NameComponentWithMarker specification.
310 */
311 uint64_t
312 toNumberWithMarker(uint8_t marker) const;
313
314 /**
315 * @brief Interpret as version component using NDN naming conventions
316 *
Junxiao Shia36f15d2018-04-04 02:22:11 +0000317 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700318 *
319 * @throws Error if name component does not have the specified marker.
320 * tlv::Error if format does not follow NameComponentWithMarker specification.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800321 */
322 uint64_t
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700323 toVersion() const;
324
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800325 /**
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700326 * @brief Interpret as segment number component using NDN naming conventions
327 *
Junxiao Shia36f15d2018-04-04 02:22:11 +0000328 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700329 *
330 * @throws Error if name component does not have the specified marker.
331 * tlv::Error if format does not follow NameComponentWithMarker specification.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800332 */
333 uint64_t
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700334 toSegment() const;
335
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800336 /**
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700337 * @brief Interpret as segment offset component using NDN naming conventions
338 *
Junxiao Shia36f15d2018-04-04 02:22:11 +0000339 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700340 *
341 * @throws Error if name component does not have the specified marker.
342 * tlv::Error if format does not follow NameComponentWithMarker specification.
343 */
344 uint64_t
345 toSegmentOffset() const;
346
347 /**
348 * @brief Interpret as timestamp component using NDN naming conventions
349 *
Junxiao Shia36f15d2018-04-04 02:22:11 +0000350 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700351 *
352 * @throws Error if name component does not have the specified marker.
353 * tlv::Error if format does not follow NameComponentWithMarker specification.
354 */
355 time::system_clock::TimePoint
356 toTimestamp() const;
357
358 /**
359 * @brief Interpret as sequence number component using NDN naming conventions
360 *
Junxiao Shia36f15d2018-04-04 02:22:11 +0000361 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700362 *
363 * @throws Error if name component does not have the specified marker.
364 * tlv::Error if format does not follow NameComponentWithMarker specification.
365 */
366 uint64_t
367 toSequenceNumber() const;
368
369 /**
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700370 * @brief Create a component encoded as nonNegativeInteger
371 *
Junxiao Shia36f15d2018-04-04 02:22:11 +0000372 * @sa https://named-data.net/doc/NDN-packet-spec/current/tlv.html#non-negative-integer-encoding
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700373 *
374 * @param number The non-negative number
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800375 * @return The component value.
376 */
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700377 static Component
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800378 fromNumber(uint64_t number);
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800379
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700380 /**
381 * @brief Create a component encoded as NameComponentWithMarker
382 *
383 * NameComponentWithMarker is defined as:
384 *
385 * NameComponentWithMarker ::= NAME-COMPONENT-TYPE TLV-LEGTH
386 * Marker
387 * includedNonNegativeInteger
388 * Marker ::= BYTE
389 * includedNonNegativeInteger ::= BYTE{1,2,4,8}
390 * NDN-TLV := TLV-TYPE TLV-LENGTH TLV-VALUE?
391 * TLV-TYPE := VAR-NUMBER
392 * TLV-LENGTH := VAR-NUMBER
393 * TLV-VALUE := BYTE+
394 *
Junxiao Shia36f15d2018-04-04 02:22:11 +0000395 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700396 *
397 * @param marker 1-byte marker octet
398 * @param number The non-negative number
399 * @return The component value.
400 */
401 static Component
402 fromNumberWithMarker(uint8_t marker, uint64_t number);
403
404 /**
405 * @brief Create version component using NDN naming conventions
406 *
Junxiao Shia36f15d2018-04-04 02:22:11 +0000407 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700408 */
409 static Component
410 fromVersion(uint64_t version);
411
412 /**
413 * @brief Create segment number component using NDN naming conventions
414 *
Junxiao Shia36f15d2018-04-04 02:22:11 +0000415 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700416 */
417 static Component
418 fromSegment(uint64_t segmentNo);
419
420 /**
421 * @brief Create segment offset component using NDN naming conventions
422 *
Junxiao Shia36f15d2018-04-04 02:22:11 +0000423 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700424 */
425 static Component
426 fromSegmentOffset(uint64_t offset);
427
428 /**
429 * @brief Create sequence number component using NDN naming conventions
430 *
Junxiao Shia36f15d2018-04-04 02:22:11 +0000431 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700432 */
433 static Component
434 fromTimestamp(const time::system_clock::TimePoint& timePoint);
435
436 /**
437 * @brief Create sequence number component using NDN naming conventions
438 *
Junxiao Shia36f15d2018-04-04 02:22:11 +0000439 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700440 */
441 static Component
442 fromSequenceNumber(uint64_t seqNo);
443
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000444public: // commonly used TLV-TYPEs
Alexander Afanasyev6486d522014-10-23 14:14:11 -0700445 /**
446 * @brief Check if the component is GenericComponent
447 */
448 bool
449 isGeneric() const;
450
451 /**
452 * @brief Check if the component is ImplicitSha256DigestComponent
453 */
454 bool
455 isImplicitSha256Digest() const;
456
457 /**
458 * @brief Create ImplicitSha256DigestComponent component
459 */
460 static Component
461 fromImplicitSha256Digest(const ConstBufferPtr& digest);
462
463 /**
464 * @brief Create ImplicitSha256DigestComponent component
465 */
466 static Component
467 fromImplicitSha256Digest(const uint8_t* digest, size_t digestSize);
468
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000469public: // operators
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700470 bool
471 empty() const
472 {
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000473 return value_size() == 0;
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700474 }
475
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800476 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700477 * @brief Check if this is the same component as other
478 *
479 * @param other The other Component to compare with
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800480 * @return true if the components are equal, otherwise false.
481 */
482 bool
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000483 equals(const Component& other) const;
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800484
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800485 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700486 * @brief Compare this to the other Component using NDN canonical ordering
487 *
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800488 * @param other The other Component to compare with.
Joao Pereiraaa8fd162015-06-05 16:35:15 -0400489 * @retval negative this comes before other in canonical ordering
490 * @retval zero this equals other
491 * @retval positive this comes after other in canonical ordering
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800492 *
Junxiao Shia36f15d2018-04-04 02:22:11 +0000493 * @sa https://named-data.net/doc/NDN-packet-spec/current/name.html#canonical-order
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800494 */
495 int
496 compare(const Component& other) const;
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800497
498 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700499 * @brief Check if this is the same component as other
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800500 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700501 * @param other The other Component to compare with.
502 * @return true if the components are equal, otherwise false.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800503 */
504 bool
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700505 operator==(const Component& other) const
506 {
507 return equals(other);
508 }
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700509
510 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700511 * @brief Check if this is not the same component as other
512 * @param other The other Component to compare with
513 * @return true if the components are not equal, otherwise false
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700514 */
515 bool
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700516 operator!=(const Component& other) const
517 {
518 return !equals(other);
519 }
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700520
521 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700522 * @brief Check if the *this is less than or equal to the other in NDN canonical ordering
523 * @param other The other Component to compare with
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700524 *
Junxiao Shia36f15d2018-04-04 02:22:11 +0000525 * @sa https://named-data.net/doc/NDN-packet-spec/current/name.html#canonical-order
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700526 */
527 bool
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700528 operator<=(const Component& other) const
529 {
530 return compare(other) <= 0;
531 }
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800532
533 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700534 * @brief Check if the *this is less than the other in NDN canonical ordering
535 * @param other The other Component to compare with
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800536 *
Junxiao Shia36f15d2018-04-04 02:22:11 +0000537 * @sa https://named-data.net/doc/NDN-packet-spec/current/name.html#canonical-order
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800538 */
539 bool
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700540 operator<(const Component& other) const
541 {
542 return compare(other) < 0;
543 }
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800544
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700545 /**
546 * @brief Check if the *this is greater or equal than the other in NDN canonical ordering
547 * @param other The other Component to compare with
548 *
Junxiao Shia36f15d2018-04-04 02:22:11 +0000549 * @sa https://named-data.net/doc/NDN-packet-spec/current/name.html#canonical-order
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700550 */
551 bool
552 operator>=(const Component& other) const
553 {
554 return compare(other) >= 0;
555 }
556
557 /**
558 * @brief Check if the *this is greater than the other in NDN canonical ordering
559 * @param other The other Component to compare with
560 *
Junxiao Shia36f15d2018-04-04 02:22:11 +0000561 * @sa https://named-data.net/doc/NDN-packet-spec/current/name.html#canonical-order
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700562 */
563 bool
564 operator>(const Component& other) const
565 {
566 return compare(other) > 0;
567 }
568
Junxiao Shicf0aff82018-07-23 06:42:13 -0600569 /**
570 * @brief Get the successor of this name component.
571 *
572 * The successor of a name component is defined as follows:
573 *
574 * C represents the set of name components, and X,Y ∈ C.
575 * Operator < is defined by canonical order on C.
576 * Y is the successor of X, if (a) X < Y, and (b) ∄ Z ∈ C s.t. X < Z < Y.
577 *
578 * In plain words, successor of a name component is the next possible name component.
579 *
580 * Examples:
581 *
582 * - successor of `sha256digest=0000000000000000000000000000000000000000000000000000000000000000`
583 * is `sha256digest=0000000000000000000000000000000000000000000000000000000000000001`.
584 * - successor of `sha256digest=ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff`
585 * is `2=...`.
586 * - successor of `A` is `B`.
587 * - successor of `%FF` is `%00%00`.
588 */
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000589 Component
590 getSuccessor() const;
591
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000592private:
593 /**
594 * @brief Throw @c Error if this NameComponent is invalid.
595 *
596 * A NameComponent is invalid if its TLV-TYPE is outside the 1-65535 range.
597 * Additionally, if this is an ImplicitSha256DigestComponent, the TLV-LENGTH must be 32.
598 */
599 void
600 ensureValid() const;
601
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700602 // !!! NOTE TO IMPLEMENTOR !!!
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700603 //
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700604 // This class MUST NOT contain any data fields.
605 // Block can be reinterpret_cast'ed as Component type.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800606};
607
Davide Pesavento88a0d812017-08-19 21:31:42 -0400608NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(Component);
609
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700610inline std::ostream&
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700611operator<<(std::ostream& os, const Component& component)
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800612{
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700613 component.toUri(os);
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800614 return os;
615}
616
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800617} // namespace name
618} // namespace ndn
619
620#endif // NDN_NAME_COMPONENT_HPP