blob: 4e3563c5e426369f0521d00bbe528699934fe292 [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 Shicf4ac5b2018-03-28 22:46:06 +000065 * @brief Construct a NameComponent of @p type, using empty TLV-VALUE.
66 * @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 Shicf4ac5b2018-03-28 22:46:06 +000080 * @brief Construct a NameComponent of @p type, using TLV-VALUE from @p buffer.
81 * @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 Shicf4ac5b2018-03-28 22:46:06 +0000102 * @brief Construct a NameComponent of @p type, copying TLV-VALUE from @p buffer.
103 */
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 Shicf4ac5b2018-03-28 22:46:06 +0000119 * @brief Construct a NameComponent of @p type, copying @p count bytes at @p value as TLV-VALUE.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800120 */
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000121 Component(uint32_t type, const uint8_t* value, size_t count);
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800122
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700123 /**
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000124 * @brief Construct a GenericNameComponent, copying @p count bytes at @p value as TLV-VALUE.
125 */
126 Component(const uint8_t* value, size_t count)
127 : Component(tlv::GenericNameComponent, value, count)
128 {
129 }
130
131 /**
132 * @brief Construct a NameComponent of @p type, copying TLV-VALUE from a range.
133 * @tparam Iterator an @c InputIterator dereferencing to a one-octet value type. More efficient
134 * implementation is available when it is a @c RandomAccessIterator.
135 * @param type the TLV-TYPE.
136 * @param first beginning of the range.
137 * @param last past-end of the range.
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700138 */
Alexander Afanasyev74633892015-02-08 18:08:46 -0800139 template<class Iterator>
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000140 Component(uint32_t type, Iterator first, Iterator last)
141 : Block(makeBinaryBlock(type, first, last))
142 {
143 }
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -0800144
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700145 /**
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000146 * @brief Construct a GenericNameComponent, copying TLV-VALUE from a range.
147 */
148 template<class Iterator>
149 Component(Iterator first, Iterator last)
150 : Component(tlv::GenericNameComponent, first, last)
151 {
152 }
153
154 /**
155 * @brief Construct a GenericNameComponent, copying TLV-VALUE from a null-terminated string.
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700156 *
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000157 * Bytes from the string are copied as is, and not interpreted as URI component.
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700158 */
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -0800159 explicit
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700160 Component(const char* str);
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800161
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700162 /**
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000163 * @brief Construct a GenericNameComponent, copying TLV-VALUE from a string.
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700164 *
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000165 * Bytes from the string are copied as is, and not interpreted as URI component.
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700166 */
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -0800167 explicit
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700168 Component(const std::string& str);
169
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000170public: // encoding and URI
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800171 /**
172 * @brief Fast encoding or block size estimation
173 */
Alexander Afanasyev74633892015-02-08 18:08:46 -0800174 template<encoding::Tag TAG>
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800175 size_t
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -0700176 wireEncode(EncodingImpl<TAG>& encoder) const;
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700177
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800178 /**
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700179 * @brief Encode to a wire format
180 */
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700181 const Block&
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700182 wireEncode() const;
183
184 /**
185 * @brief Decode from the wire format
186 */
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700187 void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700188 wireDecode(const Block& wire);
189
190 /**
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000191 * @brief Decode NameComponent from a URI component.
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700192 *
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000193 * The URI component is read from `[input+beginOffset, input+endOffset)` range.
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700194 *
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000195 * @throw Error URI component does not represent a valid NameComponent.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800196 */
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700197 static Component
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000198 fromEscapedString(const char* input, size_t beginOffset, size_t endOffset)
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800199 {
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000200 return fromEscapedString(std::string(input + beginOffset, input + endOffset));
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800201 }
202
203 /**
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000204 * @brief Decode NameComponent from a URI component.
205 * @throw Error URI component does not represent a valid NameComponent.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800206 */
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700207 static Component
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000208 fromEscapedString(const char* input)
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800209 {
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000210 return fromEscapedString(std::string(input));
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800211 }
212
213 /**
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000214 * @brief Decode NameComponent from a URI component.
215 * @throw Error URI component does not represent a valid NameComponent.
216 */
217 static Component
218 fromEscapedString(std::string input);
219
220 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700221 * @brief Write *this to the output stream, escaping characters according to the NDN URI Scheme
222 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700223 * This also adds "..." to a value with zero or more "."
224 *
225 * @param os The output stream to where write the URI escaped version *this
226 */
227 void
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700228 toUri(std::ostream& os) const;
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -0800229
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700230 /**
231 * @brief Convert *this by escaping characters according to the NDN URI Scheme
232 *
233 * This also adds "..." to a value with zero or more "."
234 *
235 * @return The escaped string
236 */
237 std::string
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700238 toUri() const;
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700239
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000240public: // naming conventions
Alexander Afanasyev0f232c52014-10-23 13:07:31 -0700241 /**
242 * @brief Check if the component is nonNegativeInteger
243 * @see http://named-data.net/doc/ndn-tlv/tlv.html#non-negative-integer-encoding
244 */
245 bool
246 isNumber() const;
247
248 /**
249 * @brief Check if the component is NameComponentWithMarker per NDN naming conventions
250 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
251 */
252 bool
253 isNumberWithMarker(uint8_t marker) const;
254
255 /**
256 * @brief Check if the component is version per NDN naming conventions
257 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
258 */
259 bool
260 isVersion() const;
261
262 /**
263 * @brief Check if the component is segment number per NDN naming conventions
264 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
265 */
266 bool
267 isSegment() const;
268
269 /**
270 * @brief Check if the component is segment offset per NDN naming conventions
271 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
272 */
273 bool
274 isSegmentOffset() const;
275
276 /**
277 * @brief Check if the component is timestamp per NDN naming conventions
278 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
279 */
280 bool
281 isTimestamp() const;
282
283 /**
284 * @brief Check if the component is sequence number per NDN naming conventions
285 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
286 */
287 bool
288 isSequenceNumber() const;
289
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800290 /**
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700291 * @brief Interpret this name component as nonNegativeInteger
292 *
293 * @see http://named-data.net/doc/ndn-tlv/tlv.html#non-negative-integer-encoding
294 *
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800295 * @return The integer number.
296 */
297 uint64_t
298 toNumber() const;
299
300 /**
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700301 * @brief Interpret this name component as NameComponentWithMarker
302 *
303 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
304 *
305 * @param marker 1-byte octet of the marker
306 * @return The integer number.
307 * @throws Error if name component does not have the specified marker.
308 * tlv::Error if format does not follow NameComponentWithMarker specification.
309 */
310 uint64_t
311 toNumberWithMarker(uint8_t marker) const;
312
313 /**
314 * @brief Interpret as version component using NDN naming conventions
315 *
316 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
317 *
318 * @throws Error if name component does not have the specified marker.
319 * tlv::Error if format does not follow NameComponentWithMarker specification.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800320 */
321 uint64_t
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700322 toVersion() const;
323
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800324 /**
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700325 * @brief Interpret as segment number component using NDN naming conventions
326 *
327 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
328 *
329 * @throws Error if name component does not have the specified marker.
330 * tlv::Error if format does not follow NameComponentWithMarker specification.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800331 */
332 uint64_t
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700333 toSegment() const;
334
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800335 /**
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700336 * @brief Interpret as segment offset component using NDN naming conventions
337 *
338 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
339 *
340 * @throws Error if name component does not have the specified marker.
341 * tlv::Error if format does not follow NameComponentWithMarker specification.
342 */
343 uint64_t
344 toSegmentOffset() const;
345
346 /**
347 * @brief Interpret as timestamp component using NDN naming conventions
348 *
349 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
350 *
351 * @throws Error if name component does not have the specified marker.
352 * tlv::Error if format does not follow NameComponentWithMarker specification.
353 */
354 time::system_clock::TimePoint
355 toTimestamp() const;
356
357 /**
358 * @brief Interpret as sequence number component using NDN naming conventions
359 *
360 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
361 *
362 * @throws Error if name component does not have the specified marker.
363 * tlv::Error if format does not follow NameComponentWithMarker specification.
364 */
365 uint64_t
366 toSequenceNumber() const;
367
368 /**
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700369 * @brief Create a component encoded as nonNegativeInteger
370 *
371 * @see http://named-data.net/doc/ndn-tlv/tlv.html#non-negative-integer-encoding
372 *
373 * @param number The non-negative number
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800374 * @return The component value.
375 */
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700376 static Component
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800377 fromNumber(uint64_t number);
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800378
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700379 /**
380 * @brief Create a component encoded as NameComponentWithMarker
381 *
382 * NameComponentWithMarker is defined as:
383 *
384 * NameComponentWithMarker ::= NAME-COMPONENT-TYPE TLV-LEGTH
385 * Marker
386 * includedNonNegativeInteger
387 * Marker ::= BYTE
388 * includedNonNegativeInteger ::= BYTE{1,2,4,8}
389 * NDN-TLV := TLV-TYPE TLV-LENGTH TLV-VALUE?
390 * TLV-TYPE := VAR-NUMBER
391 * TLV-LENGTH := VAR-NUMBER
392 * TLV-VALUE := BYTE+
393 *
394 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
395 *
396 * @param marker 1-byte marker octet
397 * @param number The non-negative number
398 * @return The component value.
399 */
400 static Component
401 fromNumberWithMarker(uint8_t marker, uint64_t number);
402
403 /**
404 * @brief Create version component using NDN naming conventions
405 *
406 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
407 */
408 static Component
409 fromVersion(uint64_t version);
410
411 /**
412 * @brief Create segment number component using NDN naming conventions
413 *
414 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
415 */
416 static Component
417 fromSegment(uint64_t segmentNo);
418
419 /**
420 * @brief Create segment offset component using NDN naming conventions
421 *
422 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
423 */
424 static Component
425 fromSegmentOffset(uint64_t offset);
426
427 /**
428 * @brief Create sequence number component using NDN naming conventions
429 *
430 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
431 */
432 static Component
433 fromTimestamp(const time::system_clock::TimePoint& timePoint);
434
435 /**
436 * @brief Create sequence number component using NDN naming conventions
437 *
438 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
439 */
440 static Component
441 fromSequenceNumber(uint64_t seqNo);
442
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000443public: // commonly used TLV-TYPEs
Alexander Afanasyev6486d522014-10-23 14:14:11 -0700444 /**
445 * @brief Check if the component is GenericComponent
446 */
447 bool
448 isGeneric() const;
449
450 /**
451 * @brief Check if the component is ImplicitSha256DigestComponent
452 */
453 bool
454 isImplicitSha256Digest() const;
455
456 /**
457 * @brief Create ImplicitSha256DigestComponent component
458 */
459 static Component
460 fromImplicitSha256Digest(const ConstBufferPtr& digest);
461
462 /**
463 * @brief Create ImplicitSha256DigestComponent component
464 */
465 static Component
466 fromImplicitSha256Digest(const uint8_t* digest, size_t digestSize);
467
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000468public: // operators
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700469 bool
470 empty() const
471 {
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000472 return value_size() == 0;
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700473 }
474
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800475 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700476 * @brief Check if this is the same component as other
477 *
478 * @param other The other Component to compare with
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800479 * @return true if the components are equal, otherwise false.
480 */
481 bool
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000482 equals(const Component& other) const;
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800483
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800484 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700485 * @brief Compare this to the other Component using NDN canonical ordering
486 *
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800487 * @param other The other Component to compare with.
Joao Pereiraaa8fd162015-06-05 16:35:15 -0400488 * @retval negative this comes before other in canonical ordering
489 * @retval zero this equals other
490 * @retval positive this comes after other in canonical ordering
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800491 *
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700492 * @see http://named-data.net/doc/ndn-tlv/name.html#canonical-order
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800493 */
494 int
495 compare(const Component& other) const;
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800496
497 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700498 * @brief Check if this is the same component as other
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800499 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700500 * @param other The other Component to compare with.
501 * @return true if the components are equal, otherwise false.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800502 */
503 bool
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700504 operator==(const Component& other) const
505 {
506 return equals(other);
507 }
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700508
509 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700510 * @brief Check if this is not the same component as other
511 * @param other The other Component to compare with
512 * @return true if the components are not equal, otherwise false
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700513 */
514 bool
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700515 operator!=(const Component& other) const
516 {
517 return !equals(other);
518 }
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700519
520 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700521 * @brief Check if the *this is less than or equal to the other in NDN canonical ordering
522 * @param other The other Component to compare with
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700523 *
524 * @see http://named-data.net/doc/ndn-tlv/name.html#canonical-order
525 */
526 bool
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700527 operator<=(const Component& other) const
528 {
529 return compare(other) <= 0;
530 }
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800531
532 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700533 * @brief Check if the *this is less than the other in NDN canonical ordering
534 * @param other The other Component to compare with
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800535 *
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700536 * @see http://named-data.net/doc/ndn-tlv/name.html#canonical-order
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800537 */
538 bool
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700539 operator<(const Component& other) const
540 {
541 return compare(other) < 0;
542 }
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800543
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700544 /**
545 * @brief Check if the *this is greater or equal than the other in NDN canonical ordering
546 * @param other The other Component to compare with
547 *
548 * @see http://named-data.net/doc/ndn-tlv/name.html#canonical-order
549 */
550 bool
551 operator>=(const Component& other) const
552 {
553 return compare(other) >= 0;
554 }
555
556 /**
557 * @brief Check if the *this is greater than the other in NDN canonical ordering
558 * @param other The other Component to compare with
559 *
560 * @see http://named-data.net/doc/ndn-tlv/name.html#canonical-order
561 */
562 bool
563 operator>(const Component& other) const
564 {
565 return compare(other) > 0;
566 }
567
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000568 Component
569 getSuccessor() const;
570
Junxiao Shicf4ac5b2018-03-28 22:46:06 +0000571private:
572 /**
573 * @brief Throw @c Error if this NameComponent is invalid.
574 *
575 * A NameComponent is invalid if its TLV-TYPE is outside the 1-65535 range.
576 * Additionally, if this is an ImplicitSha256DigestComponent, the TLV-LENGTH must be 32.
577 */
578 void
579 ensureValid() const;
580
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700581 // !!! NOTE TO IMPLEMENTOR !!!
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700582 //
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700583 // This class MUST NOT contain any data fields.
584 // Block can be reinterpret_cast'ed as Component type.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800585};
586
Davide Pesavento88a0d812017-08-19 21:31:42 -0400587NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(Component);
588
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700589inline std::ostream&
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700590operator<<(std::ostream& os, const Component& component)
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800591{
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700592 component.toUri(os);
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800593 return os;
594}
595
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800596} // namespace name
597} // namespace ndn
598
599#endif // NDN_NAME_COMPONENT_HPP