blob: 9f8de4f9bd829f1d2053063b27353c0b2f45b89b [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:
Junxiao Shi68b53852018-07-25 13:56:38 -060056 using Block::Error::Error;
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -070057 };
58
Junxiao Shicf4ac5b2018-03-28 22:46:06 +000059public: // constructors
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080060 /**
Junxiao Shia36f15d2018-04-04 02:22:11 +000061 * @brief Construct a NameComponent of TLV-TYPE @p type, using empty TLV-VALUE.
Junxiao Shicf4ac5b2018-03-28 22:46:06 +000062 * @throw Error the NameComponent is invalid (see @c ensureValid).
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080063 */
Junxiao Shicf4ac5b2018-03-28 22:46:06 +000064 explicit
65 Component(uint32_t type = tlv::GenericNameComponent);
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080066
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -080067 /**
Junxiao Shicf4ac5b2018-03-28 22:46:06 +000068 * @brief Construct a NameComponent from @p block.
69 * @throw Error the NameComponent is invalid (see @c ensureValid).
Alexander Afanasyev770827c2014-05-13 17:42:55 -070070 *
Junxiao Shicf4ac5b2018-03-28 22:46:06 +000071 * This contructor enables implicit conversion from @c Block.
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -080072 */
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -070073 Component(const Block& wire);
74
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080075 /**
Junxiao Shia36f15d2018-04-04 02:22:11 +000076 * @brief Construct a NameComponent of TLV-TYPE @p type, using TLV-VALUE from @p buffer.
Junxiao Shicf4ac5b2018-03-28 22:46:06 +000077 * @throw Error the NameComponent is invalid (see @c ensureValid).
Alexander Afanasyev770827c2014-05-13 17:42:55 -070078 *
Junxiao Shicf4ac5b2018-03-28 22:46:06 +000079 * This constructor does not copy the underlying buffer, but retains a pointer to it.
80 * Therefore, the caller must not change the underlying buffer.
81 */
82 Component(uint32_t type, ConstBufferPtr buffer);
83
84 /**
85 * @brief Construct a GenericNameComponent, using TLV-VALUE from @p buffer.
86 * @throw Error the NameComponent is invalid (see @c ensureValid).
Alexander Afanasyev770827c2014-05-13 17:42:55 -070087 *
Junxiao Shicf4ac5b2018-03-28 22:46:06 +000088 * This constructor does not copy the underlying buffer, but retains a pointer to it.
89 * Therefore, the caller must not change the underlying buffer.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080090 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070091 explicit
Junxiao Shicf4ac5b2018-03-28 22:46:06 +000092 Component(ConstBufferPtr buffer)
93 : Component(tlv::GenericNameComponent, std::move(buffer))
94 {
95 }
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -070096
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080097 /**
Junxiao Shia36f15d2018-04-04 02:22:11 +000098 * @brief Construct a NameComponent of TLV-TYPE @p type, copying TLV-VALUE from @p buffer.
Junxiao Shicf4ac5b2018-03-28 22:46:06 +000099 */
100 Component(uint32_t type, const Buffer& buffer)
101 : Component(type, buffer.data(), buffer.size())
102 {
103 }
104
105 /**
106 * @brief Construct a GenericNameComponent, copying TLV-VALUE from @p buffer.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800107 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700108 explicit
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000109 Component(const Buffer& buffer)
110 : Component(tlv::GenericNameComponent, buffer)
111 {
112 }
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800113
114 /**
Junxiao Shia36f15d2018-04-04 02:22:11 +0000115 * @brief Construct a NameComponent of TLV-TYPE @p type, copying @p count bytes at @p value as
116 * TLV-VALUE.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800117 */
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000118 Component(uint32_t type, const uint8_t* value, size_t count);
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800119
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700120 /**
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000121 * @brief Construct a GenericNameComponent, copying @p count bytes at @p value as TLV-VALUE.
122 */
123 Component(const uint8_t* value, size_t count)
124 : Component(tlv::GenericNameComponent, value, count)
125 {
126 }
127
128 /**
Junxiao Shia36f15d2018-04-04 02:22:11 +0000129 * @brief Construct a NameComponent of TLV-TYPE @p type, copying TLV-VALUE from a range.
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000130 * @tparam Iterator an @c InputIterator dereferencing to a one-octet value type. More efficient
131 * implementation is available when it is a @c RandomAccessIterator.
132 * @param type the TLV-TYPE.
133 * @param first beginning of the range.
134 * @param last past-end of the range.
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700135 */
Alexander Afanasyev74633892015-02-08 18:08:46 -0800136 template<class Iterator>
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000137 Component(uint32_t type, Iterator first, Iterator last)
138 : Block(makeBinaryBlock(type, first, last))
139 {
140 }
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -0800141
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700142 /**
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000143 * @brief Construct a GenericNameComponent, copying TLV-VALUE from a range.
144 */
145 template<class Iterator>
146 Component(Iterator first, Iterator last)
147 : Component(tlv::GenericNameComponent, first, last)
148 {
149 }
150
151 /**
152 * @brief Construct a GenericNameComponent, copying TLV-VALUE from a null-terminated string.
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700153 *
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000154 * Bytes from the string are copied as is, and not interpreted as URI component.
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700155 */
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -0800156 explicit
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700157 Component(const char* str);
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800158
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700159 /**
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000160 * @brief Construct a GenericNameComponent, copying TLV-VALUE from a string.
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700161 *
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000162 * Bytes from the string are copied as is, and not interpreted as URI component.
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700163 */
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -0800164 explicit
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700165 Component(const std::string& str);
166
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000167public: // encoding and URI
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800168 /**
169 * @brief Fast encoding or block size estimation
170 */
Alexander Afanasyev74633892015-02-08 18:08:46 -0800171 template<encoding::Tag TAG>
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800172 size_t
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -0700173 wireEncode(EncodingImpl<TAG>& encoder) const;
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700174
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800175 /**
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700176 * @brief Encode to a wire format
177 */
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700178 const Block&
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700179 wireEncode() const;
180
181 /**
182 * @brief Decode from the wire format
183 */
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700184 void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700185 wireDecode(const Block& wire);
186
187 /**
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000188 * @brief Decode NameComponent from a URI component.
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700189 *
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000190 * The URI component is read from `[input+beginOffset, input+endOffset)` range.
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700191 *
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000192 * @throw Error URI component does not represent a valid NameComponent.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800193 */
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700194 static Component
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000195 fromEscapedString(const char* input, size_t beginOffset, size_t endOffset)
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800196 {
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000197 return fromEscapedString(std::string(input + beginOffset, input + endOffset));
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800198 }
199
200 /**
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000201 * @brief Decode NameComponent from a URI component.
202 * @throw Error URI component does not represent a valid NameComponent.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800203 */
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700204 static Component
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000205 fromEscapedString(const char* input)
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800206 {
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000207 return fromEscapedString(std::string(input));
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800208 }
209
210 /**
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000211 * @brief Decode NameComponent from a URI component.
212 * @throw Error URI component does not represent a valid NameComponent.
213 */
214 static Component
215 fromEscapedString(std::string input);
216
217 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700218 * @brief Write *this to the output stream, escaping characters according to the NDN URI Scheme
219 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700220 * This also adds "..." to a value with zero or more "."
221 *
Junxiao Shia36f15d2018-04-04 02:22:11 +0000222 * @param os The output stream where to write the URI escaped version of *this
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700223 */
224 void
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700225 toUri(std::ostream& os) const;
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -0800226
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700227 /**
228 * @brief Convert *this by escaping characters according to the NDN URI Scheme
229 *
230 * This also adds "..." to a value with zero or more "."
231 *
232 * @return The escaped string
233 */
234 std::string
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700235 toUri() const;
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700236
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000237public: // naming conventions
Alexander Afanasyev0f232c52014-10-23 13:07:31 -0700238 /**
239 * @brief Check if the component is nonNegativeInteger
Junxiao Shia36f15d2018-04-04 02:22:11 +0000240 * @sa https://named-data.net/doc/NDN-packet-spec/current/tlv.html#non-negative-integer-encoding
Alexander Afanasyev0f232c52014-10-23 13:07:31 -0700241 */
242 bool
243 isNumber() const;
244
245 /**
246 * @brief Check if the component is NameComponentWithMarker per NDN naming conventions
Junxiao Shia36f15d2018-04-04 02:22:11 +0000247 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
Alexander Afanasyev0f232c52014-10-23 13:07:31 -0700248 */
249 bool
250 isNumberWithMarker(uint8_t marker) const;
251
252 /**
253 * @brief Check if the component is version per NDN naming conventions
Junxiao Shia36f15d2018-04-04 02:22:11 +0000254 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
Alexander Afanasyev0f232c52014-10-23 13:07:31 -0700255 */
256 bool
257 isVersion() const;
258
259 /**
260 * @brief Check if the component is segment number per NDN naming conventions
Junxiao Shia36f15d2018-04-04 02:22:11 +0000261 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
Alexander Afanasyev0f232c52014-10-23 13:07:31 -0700262 */
263 bool
264 isSegment() const;
265
266 /**
267 * @brief Check if the component is segment offset per NDN naming conventions
Junxiao Shia36f15d2018-04-04 02:22:11 +0000268 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
Alexander Afanasyev0f232c52014-10-23 13:07:31 -0700269 */
270 bool
271 isSegmentOffset() const;
272
273 /**
274 * @brief Check if the component is timestamp per NDN naming conventions
Junxiao Shia36f15d2018-04-04 02:22:11 +0000275 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
Alexander Afanasyev0f232c52014-10-23 13:07:31 -0700276 */
277 bool
278 isTimestamp() const;
279
280 /**
281 * @brief Check if the component is sequence number per NDN naming conventions
Junxiao Shia36f15d2018-04-04 02:22:11 +0000282 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
Alexander Afanasyev0f232c52014-10-23 13:07:31 -0700283 */
284 bool
285 isSequenceNumber() const;
286
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800287 /**
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700288 * @brief Interpret this name component as nonNegativeInteger
289 *
Junxiao Shia36f15d2018-04-04 02:22:11 +0000290 * @sa https://named-data.net/doc/NDN-packet-spec/current/tlv.html#non-negative-integer-encoding
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700291 *
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800292 * @return The integer number.
293 */
294 uint64_t
295 toNumber() const;
296
297 /**
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700298 * @brief Interpret this name component as NameComponentWithMarker
299 *
Junxiao Shia36f15d2018-04-04 02:22:11 +0000300 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700301 *
302 * @param marker 1-byte octet of the marker
303 * @return The integer number.
304 * @throws Error if name component does not have the specified marker.
305 * tlv::Error if format does not follow NameComponentWithMarker specification.
306 */
307 uint64_t
308 toNumberWithMarker(uint8_t marker) const;
309
310 /**
311 * @brief Interpret as version component using NDN naming conventions
312 *
Junxiao Shia36f15d2018-04-04 02:22:11 +0000313 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700314 *
315 * @throws Error if name component does not have the specified marker.
316 * tlv::Error if format does not follow NameComponentWithMarker specification.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800317 */
318 uint64_t
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700319 toVersion() const;
320
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800321 /**
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700322 * @brief Interpret as segment number component using NDN naming conventions
323 *
Junxiao Shia36f15d2018-04-04 02:22:11 +0000324 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700325 *
326 * @throws Error if name component does not have the specified marker.
327 * tlv::Error if format does not follow NameComponentWithMarker specification.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800328 */
329 uint64_t
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700330 toSegment() const;
331
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800332 /**
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700333 * @brief Interpret as segment offset component using NDN naming conventions
334 *
Junxiao Shia36f15d2018-04-04 02:22:11 +0000335 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700336 *
337 * @throws Error if name component does not have the specified marker.
338 * tlv::Error if format does not follow NameComponentWithMarker specification.
339 */
340 uint64_t
341 toSegmentOffset() const;
342
343 /**
344 * @brief Interpret as timestamp component using NDN naming conventions
345 *
Junxiao Shia36f15d2018-04-04 02:22:11 +0000346 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700347 *
348 * @throws Error if name component does not have the specified marker.
349 * tlv::Error if format does not follow NameComponentWithMarker specification.
350 */
351 time::system_clock::TimePoint
352 toTimestamp() const;
353
354 /**
355 * @brief Interpret as sequence number component using NDN naming conventions
356 *
Junxiao Shia36f15d2018-04-04 02:22:11 +0000357 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700358 *
359 * @throws Error if name component does not have the specified marker.
360 * tlv::Error if format does not follow NameComponentWithMarker specification.
361 */
362 uint64_t
363 toSequenceNumber() const;
364
365 /**
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700366 * @brief Create a component encoded as nonNegativeInteger
367 *
Junxiao Shia36f15d2018-04-04 02:22:11 +0000368 * @sa https://named-data.net/doc/NDN-packet-spec/current/tlv.html#non-negative-integer-encoding
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700369 *
370 * @param number The non-negative number
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800371 * @return The component value.
372 */
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700373 static Component
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800374 fromNumber(uint64_t number);
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800375
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700376 /**
377 * @brief Create a component encoded as NameComponentWithMarker
378 *
379 * NameComponentWithMarker is defined as:
380 *
381 * NameComponentWithMarker ::= NAME-COMPONENT-TYPE TLV-LEGTH
382 * Marker
383 * includedNonNegativeInteger
384 * Marker ::= BYTE
385 * includedNonNegativeInteger ::= BYTE{1,2,4,8}
386 * NDN-TLV := TLV-TYPE TLV-LENGTH TLV-VALUE?
387 * TLV-TYPE := VAR-NUMBER
388 * TLV-LENGTH := VAR-NUMBER
389 * TLV-VALUE := BYTE+
390 *
Junxiao Shia36f15d2018-04-04 02:22:11 +0000391 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700392 *
393 * @param marker 1-byte marker octet
394 * @param number The non-negative number
395 * @return The component value.
396 */
397 static Component
398 fromNumberWithMarker(uint8_t marker, uint64_t number);
399
400 /**
401 * @brief Create version component using NDN naming conventions
402 *
Junxiao Shia36f15d2018-04-04 02:22:11 +0000403 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700404 */
405 static Component
406 fromVersion(uint64_t version);
407
408 /**
409 * @brief Create segment number component using NDN naming conventions
410 *
Junxiao Shia36f15d2018-04-04 02:22:11 +0000411 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700412 */
413 static Component
414 fromSegment(uint64_t segmentNo);
415
416 /**
417 * @brief Create segment offset component using NDN naming conventions
418 *
Junxiao Shia36f15d2018-04-04 02:22:11 +0000419 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700420 */
421 static Component
422 fromSegmentOffset(uint64_t offset);
423
424 /**
425 * @brief Create sequence number component using NDN naming conventions
426 *
Junxiao Shia36f15d2018-04-04 02:22:11 +0000427 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700428 */
429 static Component
430 fromTimestamp(const time::system_clock::TimePoint& timePoint);
431
432 /**
433 * @brief Create sequence number component using NDN naming conventions
434 *
Junxiao Shia36f15d2018-04-04 02:22:11 +0000435 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700436 */
437 static Component
438 fromSequenceNumber(uint64_t seqNo);
439
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000440public: // commonly used TLV-TYPEs
Alexander Afanasyev6486d522014-10-23 14:14:11 -0700441 /**
442 * @brief Check if the component is GenericComponent
443 */
444 bool
445 isGeneric() const;
446
447 /**
448 * @brief Check if the component is ImplicitSha256DigestComponent
449 */
450 bool
451 isImplicitSha256Digest() const;
452
453 /**
454 * @brief Create ImplicitSha256DigestComponent component
455 */
456 static Component
Davide Pesavento3b101d02018-07-21 22:44:09 -0400457 fromImplicitSha256Digest(ConstBufferPtr digest);
Alexander Afanasyev6486d522014-10-23 14:14:11 -0700458
459 /**
460 * @brief Create ImplicitSha256DigestComponent component
461 */
462 static Component
463 fromImplicitSha256Digest(const uint8_t* digest, size_t digestSize);
464
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000465public: // operators
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700466 bool
467 empty() const
468 {
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000469 return value_size() == 0;
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700470 }
471
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800472 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700473 * @brief Check if this is the same component as other
474 *
475 * @param other The other Component to compare with
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800476 * @return true if the components are equal, otherwise false.
477 */
478 bool
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000479 equals(const Component& other) const;
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800480
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800481 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700482 * @brief Compare this to the other Component using NDN canonical ordering
483 *
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800484 * @param other The other Component to compare with.
Joao Pereiraaa8fd162015-06-05 16:35:15 -0400485 * @retval negative this comes before other in canonical ordering
486 * @retval zero this equals other
487 * @retval positive this comes after other in canonical ordering
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800488 *
Junxiao Shia36f15d2018-04-04 02:22:11 +0000489 * @sa https://named-data.net/doc/NDN-packet-spec/current/name.html#canonical-order
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800490 */
491 int
492 compare(const Component& other) const;
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800493
494 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700495 * @brief Check if this is the same component as other
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800496 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700497 * @param other The other Component to compare with.
498 * @return true if the components are equal, otherwise false.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800499 */
500 bool
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700501 operator==(const Component& other) const
502 {
503 return equals(other);
504 }
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700505
506 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700507 * @brief Check if this is not the same component as other
508 * @param other The other Component to compare with
509 * @return true if the components are not equal, otherwise false
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700510 */
511 bool
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700512 operator!=(const Component& other) const
513 {
514 return !equals(other);
515 }
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700516
517 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700518 * @brief Check if the *this is less than or equal to the other in NDN canonical ordering
519 * @param other The other Component to compare with
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700520 *
Junxiao Shia36f15d2018-04-04 02:22:11 +0000521 * @sa https://named-data.net/doc/NDN-packet-spec/current/name.html#canonical-order
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700522 */
523 bool
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700524 operator<=(const Component& other) const
525 {
526 return compare(other) <= 0;
527 }
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800528
529 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700530 * @brief Check if the *this is less than the other in NDN canonical ordering
531 * @param other The other Component to compare with
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800532 *
Junxiao Shia36f15d2018-04-04 02:22:11 +0000533 * @sa https://named-data.net/doc/NDN-packet-spec/current/name.html#canonical-order
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800534 */
535 bool
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700536 operator<(const Component& other) const
537 {
538 return compare(other) < 0;
539 }
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800540
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700541 /**
542 * @brief Check if the *this is greater or equal than the other in NDN canonical ordering
543 * @param other The other Component to compare with
544 *
Junxiao Shia36f15d2018-04-04 02:22:11 +0000545 * @sa https://named-data.net/doc/NDN-packet-spec/current/name.html#canonical-order
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700546 */
547 bool
548 operator>=(const Component& other) const
549 {
550 return compare(other) >= 0;
551 }
552
553 /**
554 * @brief Check if the *this is greater than the other in NDN canonical ordering
555 * @param other The other Component to compare with
556 *
Junxiao Shia36f15d2018-04-04 02:22:11 +0000557 * @sa https://named-data.net/doc/NDN-packet-spec/current/name.html#canonical-order
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700558 */
559 bool
560 operator>(const Component& other) const
561 {
562 return compare(other) > 0;
563 }
564
Junxiao Shicf0aff82018-07-23 06:42:13 -0600565 /**
566 * @brief Get the successor of this name component.
567 *
568 * The successor of a name component is defined as follows:
569 *
570 * C represents the set of name components, and X,Y ∈ C.
571 * Operator < is defined by canonical order on C.
572 * Y is the successor of X, if (a) X < Y, and (b) ∄ Z ∈ C s.t. X < Z < Y.
573 *
574 * In plain words, successor of a name component is the next possible name component.
575 *
576 * Examples:
577 *
578 * - successor of `sha256digest=0000000000000000000000000000000000000000000000000000000000000000`
579 * is `sha256digest=0000000000000000000000000000000000000000000000000000000000000001`.
580 * - successor of `sha256digest=ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff`
581 * is `2=...`.
582 * - successor of `A` is `B`.
583 * - successor of `%FF` is `%00%00`.
584 */
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000585 Component
586 getSuccessor() const;
587
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000588private:
589 /**
590 * @brief Throw @c Error if this NameComponent is invalid.
591 *
592 * A NameComponent is invalid if its TLV-TYPE is outside the 1-65535 range.
593 * Additionally, if this is an ImplicitSha256DigestComponent, the TLV-LENGTH must be 32.
594 */
595 void
596 ensureValid() const;
597
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700598 // !!! NOTE TO IMPLEMENTOR !!!
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700599 //
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700600 // This class MUST NOT contain any data fields.
601 // Block can be reinterpret_cast'ed as Component type.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800602};
603
Davide Pesavento88a0d812017-08-19 21:31:42 -0400604NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(Component);
605
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700606inline std::ostream&
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700607operator<<(std::ostream& os, const Component& component)
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800608{
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700609 component.toUri(os);
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800610 return os;
611}
612
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800613} // namespace name
614} // namespace ndn
615
616#endif // NDN_NAME_COMPONENT_HPP