blob: 9fa1343d309df397b59621821116113ba894b0c3 [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Junxiao Shi8609bf22017-07-12 13:02:55 +00002/*
Junxiao Shia36f15d2018-04-04 02:22:11 +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 Afanasyevdfa52c42014-04-24 21:10:11 -070020 *
21 * @author Jeff Thompson <jefft0@remap.ucla.edu>
22 * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
23 * @author Zhenkai Zhu <http://irl.cs.ucla.edu/~zhenkai/>
Jeff Thompson9c41dfe2013-06-27 12:10:25 -070024 */
25
26#ifndef NDN_NAME_HPP
Jeff Thompson2d27e2f2013-08-09 12:55:00 -070027#define NDN_NAME_HPP
Jeff Thompson9c41dfe2013-06-27 12:10:25 -070028
Davide Pesavento7e780642018-11-24 15:51:34 -050029#include "ndn-cxx/name-component.hpp"
30
Junxiao Shiadc334e2017-07-14 20:28:28 +000031#include <iterator>
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080032
Jeff Thompson9c41dfe2013-06-27 12:10:25 -070033namespace ndn {
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080034
Joao Pereira6f7cfd02015-06-15 11:36:26 -040035class Name;
36
Junxiao Shi71ff2312017-07-12 13:32:50 +000037/** @brief Represents an arbitrary sequence of name components
Joao Pereira6f7cfd02015-06-15 11:36:26 -040038 */
Junxiao Shi71ff2312017-07-12 13:32:50 +000039using PartialName = Name;
Joao Pereira6f7cfd02015-06-15 11:36:26 -040040
Junxiao Shi71ff2312017-07-12 13:32:50 +000041/** @brief Represents an absolute name
Jeff Thompsonc7d65502013-11-06 17:22:26 -080042 */
Junxiao Shi8609bf22017-07-12 13:02:55 +000043class Name
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070044{
Junxiao Shi71ff2312017-07-12 13:32:50 +000045public: // nested types
Junxiao Shi68b53852018-07-25 13:56:38 -060046 using Error = name::Component::Error;
Alexander Afanasyevaf283d82014-01-03 13:23:34 -080047
Junxiao Shi71ff2312017-07-12 13:32:50 +000048 using Component = name::Component;
49 using component_container = std::vector<Component>;
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080050
Junxiao Shi71ff2312017-07-12 13:32:50 +000051 // Name appears as a container of name components
52 using value_type = Component;
53 using allocator_type = void;
54 using reference = Component&;
Junxiao Shiadc334e2017-07-14 20:28:28 +000055 using const_reference = const Component&;
Junxiao Shi71ff2312017-07-12 13:32:50 +000056 using pointer = Component*;
57 using const_pointer = const Component*;
Junxiao Shiadc334e2017-07-14 20:28:28 +000058 using iterator = const Component*; // disallow modifying via iterator
Junxiao Shi71ff2312017-07-12 13:32:50 +000059 using const_iterator = const Component*;
Junxiao Shiadc334e2017-07-14 20:28:28 +000060 using reverse_iterator = std::reverse_iterator<iterator>;
61 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
Junxiao Shi71ff2312017-07-12 13:32:50 +000062 using difference_type = component_container::difference_type;
63 using size_type = component_container::size_type;
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080064
Junxiao Shi71ff2312017-07-12 13:32:50 +000065public: // constructors, encoding, decoding
66 /** @brief Create an empty name
67 * @post empty() == true
Jeff Thompson443398d2013-07-02 19:45:46 -070068 */
Alexander Afanasyevc89efb42015-02-10 18:26:42 -080069 Name();
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -080070
Junxiao Shi71ff2312017-07-12 13:32:50 +000071 /** @brief Decode Name from wire encoding
72 * @throw tlv::Error wire encoding is invalid
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -080073 *
Junxiao Shi71ff2312017-07-12 13:32:50 +000074 * This is a more efficient equivalent for
75 * @code
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -080076 * Name name;
77 * name.wireDecode(wire);
Junxiao Shi71ff2312017-07-12 13:32:50 +000078 * @endcode
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -080079 */
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -080080 explicit
Alexander Afanasyevc89efb42015-02-10 18:26:42 -080081 Name(const Block& wire);
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -070082
Junxiao Shi71ff2312017-07-12 13:32:50 +000083 /** @brief Parse name from NDN URI
84 * @param uri a null-terminated URI string
Junxiao Shia36f15d2018-04-04 02:22:11 +000085 * @sa https://named-data.net/doc/NDN-packet-spec/current/name.html#ndn-uri-scheme
Jeff Thompson443398d2013-07-02 19:45:46 -070086 */
Alexander Afanasyevc89efb42015-02-10 18:26:42 -080087 Name(const char* uri);
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -070088
Junxiao Shi71ff2312017-07-12 13:32:50 +000089 /** @brief Create name from NDN URI
90 * @param uri a URI string
Junxiao Shia36f15d2018-04-04 02:22:11 +000091 * @sa https://named-data.net/doc/NDN-packet-spec/current/name.html#ndn-uri-scheme
Jeff Thompson3549ef32013-09-25 14:05:17 -070092 */
Junxiao Shi3188c4032016-07-18 20:53:56 +000093 Name(std::string uri);
Jeff Thompsonec39fbd2013-10-04 10:56:23 -070094
Junxiao Shi71ff2312017-07-12 13:32:50 +000095 /** @brief Get URI representation of the name
96 * @return URI representation; "ndn:" scheme identifier is not included
Junxiao Shia36f15d2018-04-04 02:22:11 +000097 * @sa https://named-data.net/doc/NDN-packet-spec/current/name.html#ndn-uri-scheme
Junxiao Shi71ff2312017-07-12 13:32:50 +000098 * @note To print URI representation into a stream, it is more efficient to use ``os << name``.
Alexander Afanasyev4f512fb2016-05-18 10:47:53 -070099 */
Junxiao Shi71ff2312017-07-12 13:32:50 +0000100 std::string
101 toUri() const;
Alexander Afanasyev4f512fb2016-05-18 10:47:53 -0700102
Junxiao Shi71ff2312017-07-12 13:32:50 +0000103 /** @brief Check if this Name instance already has wire encoding
104 */
105 bool
106 hasWire() const
107 {
108 return m_wire.hasWire();
109 }
110
111 /** @brief Fast encoding or block size estimation
Alexander Afanasyev380420b2014-02-09 20:52:29 -0800112 */
Alexander Afanasyev74633892015-02-08 18:08:46 -0800113 template<encoding::Tag TAG>
Wentao Shang77949212014-02-01 23:42:24 -0800114 size_t
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -0700115 wireEncode(EncodingImpl<TAG>& encoder) const;
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700116
Junxiao Shi71ff2312017-07-12 13:32:50 +0000117 /** @brief Perform wire encoding, or return existing wire encoding
118 * @post hasWire() == true
119 */
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700120 const Block&
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800121 wireEncode() const;
Alexander Afanasyev848c61a2014-01-03 13:52:04 -0800122
Junxiao Shi71ff2312017-07-12 13:32:50 +0000123 /** @brief Decode name from wire encoding
124 * @throw tlv::Error wire encoding is invalid
125 * @post hasWire() == true
126 */
Alexander Afanasyev848c61a2014-01-03 13:52:04 -0800127 void
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700128 wireDecode(const Block& wire);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800129
Junxiao Shi71ff2312017-07-12 13:32:50 +0000130 /** @brief Make a deep copy of the name, reallocating the underlying memory buffer
131 */
132 Name
133 deepCopy() const;
134
135public: // access
136 /** @brief Check if name is empty
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800137 */
138 bool
Junxiao Shi71ff2312017-07-12 13:32:50 +0000139 empty() const
Jeff Thompson0f743452013-09-12 14:23:18 -0700140 {
Junxiao Shi71ff2312017-07-12 13:32:50 +0000141 return m_wire.elements().empty();
Jeff Thompsone5f839b2013-06-28 12:50:38 -0700142 }
Jeff Thompsonf72b1ac2013-08-16 16:44:41 -0700143
Junxiao Shi71ff2312017-07-12 13:32:50 +0000144 /** @brief Get number of components
Alexander Afanasyevbf9671d2014-02-11 13:44:13 -0800145 */
Junxiao Shi71ff2312017-07-12 13:32:50 +0000146 size_t
147 size() const
Alexander Afanasyevbf9671d2014-02-11 13:44:13 -0800148 {
Junxiao Shi71ff2312017-07-12 13:32:50 +0000149 return m_wire.elements_size();
Alexander Afanasyevbf9671d2014-02-11 13:44:13 -0800150 }
151
Junxiao Shi71ff2312017-07-12 13:32:50 +0000152 /** @brief Get the component at the given index
153 * @param i zero-based index; if negative, it starts at the end of this name
154 * @warning Indexing out of bounds triggers undefined behavior.
Alexander Afanasyevc89efb42015-02-10 18:26:42 -0800155 */
Junxiao Shi71ff2312017-07-12 13:32:50 +0000156 const Component&
157 get(ssize_t i) const
Jeff Thompson21eb7212013-09-26 09:05:40 -0700158 {
Junxiao Shi71ff2312017-07-12 13:32:50 +0000159 if (i < 0) {
160 i += size();
161 }
162 return reinterpret_cast<const Component&>(m_wire.elements()[i]);
Jeff Thompson21eb7212013-09-26 09:05:40 -0700163 }
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800164
Junxiao Shi71ff2312017-07-12 13:32:50 +0000165 /** @brief Equivalent to get(i)
166 */
167 const Component&
168 operator[](ssize_t i) const
169 {
170 return get(i);
171 }
172
173 /** @brief Get the component at the given index
174 * @param i zero-based index; if negative, size()+i is used instead
175 * @throws Name::Error index is out of bounds
176 */
177 const Component&
178 at(ssize_t i) const;
179
180 /** @brief Extract some components as a sub-name (PartialName)
181 * @param iStartComponent zero-based index of the first component;
182 * if negative, size()+iStartComponent is used instead
183 * @param nComponents Number of components starting at iStartComponent.
184 * Use @p npos to get the PartialName until the end of this Name.
185 * @return a new PartialName containing the extracted components
Alexander Afanasyev594cdb22014-01-03 15:11:33 -0800186 *
Junxiao Shi71ff2312017-07-12 13:32:50 +0000187 * If iStartComponent is positive and indexes out of bounds, returns an empty PartialName.
188 * If iStartComponent is negative and indexes out of bounds, returns components starting from the
189 * beginning of the Name. If nComponents is out of bounds, returns the components until the end
190 * of this Name.
Jeff Thompsond0159d72013-09-23 13:34:15 -0700191 */
Joao Pereira6f7cfd02015-06-15 11:36:26 -0400192 PartialName
193 getSubName(ssize_t iStartComponent, size_t nComponents = npos) const;
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700194
Junxiao Shi71ff2312017-07-12 13:32:50 +0000195 /** @brief Extract a prefix of the name
196 * @param nComponents Number of components; if negative, size()+nComponents is used instead
197 * @return a new Name containing the prefix
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700198 * the prefix up to name.size() - N. For example getPrefix(-1)
199 * returns the name without the final component.
Joao Pereira6f7cfd02015-06-15 11:36:26 -0400200 * @return A new partial name
Jeff Thompsond0159d72013-09-23 13:34:15 -0700201 */
Joao Pereira6f7cfd02015-06-15 11:36:26 -0400202 PartialName
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700203 getPrefix(ssize_t nComponents) const
Jeff Thompsond0159d72013-09-23 13:34:15 -0700204 {
Jeff Thompsoneb0358f2013-12-17 10:59:53 -0800205 if (nComponents < 0)
Junxiao Shi71ff2312017-07-12 13:32:50 +0000206 return getSubName(0, size() + nComponents);
Jeff Thompsoneb0358f2013-12-17 10:59:53 -0800207 else
208 return getSubName(0, nComponents);
Jeff Thompsond0159d72013-09-23 13:34:15 -0700209 }
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700210
Junxiao Shi71ff2312017-07-12 13:32:50 +0000211public: // iterators
212 /** @brief Begin iterator
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700213 */
214 const_iterator
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800215 begin() const
216 {
Junxiao Shif0bf9992017-07-15 15:51:52 +0000217 return reinterpret_cast<const_iterator>(m_wire.elements().data());
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800218 }
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700219
Junxiao Shi71ff2312017-07-12 13:32:50 +0000220 /** @brief End iterator
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700221 */
222 const_iterator
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800223 end() const
224 {
Junxiao Shif0bf9992017-07-15 15:51:52 +0000225 return reinterpret_cast<const_iterator>(m_wire.elements().data() + m_wire.elements().size());
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800226 }
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700227
Junxiao Shi71ff2312017-07-12 13:32:50 +0000228 /** @brief Reverse begin iterator
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700229 */
230 const_reverse_iterator
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800231 rbegin() const
232 {
233 return const_reverse_iterator(end());
234 }
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700235
Junxiao Shi71ff2312017-07-12 13:32:50 +0000236 /** @brief Reverse end iterator
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700237 */
238 const_reverse_iterator
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800239 rend() const
240 {
241 return const_reverse_iterator(begin());
242 }
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700243
Junxiao Shi71ff2312017-07-12 13:32:50 +0000244public: // modifiers
Junxiao Shia36f15d2018-04-04 02:22:11 +0000245 /** @brief Append a component.
246 * @return a reference to this name, to allow chaining.
Junxiao Shi71ff2312017-07-12 13:32:50 +0000247 */
248 Name&
249 append(const Component& component)
250 {
251 m_wire.push_back(component);
252 return *this;
253 }
254
Junxiao Shia36f15d2018-04-04 02:22:11 +0000255 /** @brief Append a NameComponent of TLV-TYPE @p type, copying @p count bytes at @p value as
256 * TLV-VALUE.
257 * @return a reference to this name, to allow chaining.
Junxiao Shi71ff2312017-07-12 13:32:50 +0000258 */
259 Name&
Junxiao Shia36f15d2018-04-04 02:22:11 +0000260 append(uint32_t type, const uint8_t* value, size_t count)
Junxiao Shi71ff2312017-07-12 13:32:50 +0000261 {
Junxiao Shia36f15d2018-04-04 02:22:11 +0000262 return append(Component(type, value, count));
Junxiao Shi71ff2312017-07-12 13:32:50 +0000263 }
264
Junxiao Shia36f15d2018-04-04 02:22:11 +0000265 /** @brief Append a GenericNameComponent, copying @p count bytes at @p value as TLV-VALUE.
266 * @return a reference to this name, to allow chaining.
Junxiao Shi71ff2312017-07-12 13:32:50 +0000267 */
268 Name&
Junxiao Shia36f15d2018-04-04 02:22:11 +0000269 append(const uint8_t* value, size_t count)
Junxiao Shi71ff2312017-07-12 13:32:50 +0000270 {
Junxiao Shia36f15d2018-04-04 02:22:11 +0000271 return append(Component(value, count));
Junxiao Shi71ff2312017-07-12 13:32:50 +0000272 }
273
Junxiao Shia36f15d2018-04-04 02:22:11 +0000274 /** @brief Append a NameComponent of TLV-TYPE @p type, copying TLV-VALUE from a range.
275 * @tparam Iterator an @c InputIterator dereferencing to a one-octet value type. More efficient
276 * implementation is available when it is a @c RandomAccessIterator.
277 * @param type the TLV-TYPE.
278 * @param first beginning of the range.
279 * @param last past-end of the range.
280 * @return a reference to this name, to allow chaining.
281 */
282 template<class Iterator>
283 Name&
284 append(uint32_t type, Iterator first, Iterator last)
285 {
286 return append(Component(type, first, last));
287 }
288
289 /** @brief Append a GenericNameComponent, copying TLV-VALUE from a range.
290 * @tparam Iterator an @c InputIterator dereferencing to a one-octet value type. More efficient
291 * implementation is available when it is a @c RandomAccessIterator.
292 * @param first beginning of the range.
293 * @param last past-end of the range.
294 * @return a reference to this name, to allow chaining.
Junxiao Shi71ff2312017-07-12 13:32:50 +0000295 */
296 template<class Iterator>
297 Name&
298 append(Iterator first, Iterator last)
299 {
Junxiao Shi71ff2312017-07-12 13:32:50 +0000300 return append(Component(first, last));
301 }
302
Junxiao Shia36f15d2018-04-04 02:22:11 +0000303 /** @brief Append a GenericNameComponent, copying TLV-VALUE from a null-terminated string.
304 * @param str a null-terminated string. Bytes from the string are copied as is, and not
305 * interpreted as URI component.
306 * @return a reference to this name, to allow chaining.
307 */
308 Name&
309 append(const char* str)
310 {
311 return append(Component(str));
312 }
313
314 /** @brief Append a GenericNameComponent from a TLV element.
315 * @param value a TLV element. If its type is @c tlv::GenericNameComponent, it is used as is.
316 * Otherwise, it is encapsulated into a GenericNameComponent.
317 * @return a reference to this name, to allow chaining.
Junxiao Shi71ff2312017-07-12 13:32:50 +0000318 */
319 Name&
320 append(const Block& value)
321 {
Junxiao Shia36f15d2018-04-04 02:22:11 +0000322 if (value.type() == tlv::GenericNameComponent) {
Junxiao Shi71ff2312017-07-12 13:32:50 +0000323 m_wire.push_back(value);
324 }
325 else {
Junxiao Shia36f15d2018-04-04 02:22:11 +0000326 m_wire.push_back(Block(tlv::GenericNameComponent, value));
Junxiao Shi71ff2312017-07-12 13:32:50 +0000327 }
Junxiao Shi71ff2312017-07-12 13:32:50 +0000328 return *this;
329 }
330
331 /** @brief Append a component with a nonNegativeInteger
332 * @sa number the number
333 * @return a reference to this name, to allow chaining
Junxiao Shia36f15d2018-04-04 02:22:11 +0000334 * @sa https://named-data.net/doc/NDN-packet-spec/current/tlv.html#non-negative-integer-encoding
Junxiao Shi71ff2312017-07-12 13:32:50 +0000335 */
336 Name&
337 appendNumber(uint64_t number)
338 {
339 return append(Component::fromNumber(number));
340 }
341
342 /** @brief Append a component with a marked number
343 * @param marker 1-octet marker
344 * @param number the number
345 *
346 * The component is encoded as a 1-octet marker, followed by a nonNegativeInteger.
347 *
348 * @return a reference to this name, to allow chaining
349 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
350 */
351 Name&
352 appendNumberWithMarker(uint8_t marker, uint64_t number)
353 {
354 return append(Component::fromNumberWithMarker(marker, number));
355 }
356
357 /** @brief Append a version component
358 * @return a reference to this name, to allow chaining
359 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
360 */
361 Name&
362 appendVersion(uint64_t version)
363 {
364 return append(Component::fromVersion(version));
365 }
366
367 /** @brief Append a version component based on current time
368 *
369 * The version number is the current UNIX timestamp in milliseconds
370 *
371 * @return a reference to this name, to allow chaining
372 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
373 */
374 Name&
375 appendVersion();
376
377 /** @brief Append a segment number (sequential) component
378 * @return a reference to this name, to allow chaining
379 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
380 */
381 Name&
382 appendSegment(uint64_t segmentNo)
383 {
384 return append(Component::fromSegment(segmentNo));
385 }
386
387 /** @brief Append a segment byte offset component
388 * @return a reference to this name, to allow chaining
389 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
390 */
391 Name&
392 appendSegmentOffset(uint64_t offset)
393 {
394 return append(Component::fromSegmentOffset(offset));
395 }
396
397 /** @brief Append a timestamp component
398 * @return a reference to this name, to allow chaining
399 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
400 */
401 Name&
402 appendTimestamp(const time::system_clock::TimePoint& timePoint)
403 {
404 return append(Component::fromTimestamp(timePoint));
405 }
406
407 /** @brief Append a timestamp component based on current time
408 * @return a reference to this name, to allow chaining
409 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
410 */
411 Name&
412 appendTimestamp();
413
414 /** @brief Append a sequence number component
415 * @return a reference to this name, to allow chaining
416 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
417 */
418 Name&
419 appendSequenceNumber(uint64_t seqNo)
420 {
421 return append(Component::fromSequenceNumber(seqNo));
422 }
423
424 /** @brief Append an ImplicitSha256Digest component
425 * @return a reference to this name, to allow chaining
426 */
427 Name&
Davide Pesavento3b101d02018-07-21 22:44:09 -0400428 appendImplicitSha256Digest(ConstBufferPtr digest)
Junxiao Shi71ff2312017-07-12 13:32:50 +0000429 {
Davide Pesavento3b101d02018-07-21 22:44:09 -0400430 return append(Component::fromImplicitSha256Digest(std::move(digest)));
Junxiao Shi71ff2312017-07-12 13:32:50 +0000431 }
432
433 /** @brief Append an ImplicitSha256Digest component
434 * @return a reference to this name, to allow chaining
435 */
436 Name&
437 appendImplicitSha256Digest(const uint8_t* digest, size_t digestSize)
438 {
439 return append(Component::fromImplicitSha256Digest(digest, digestSize));
440 }
441
442 /** @brief Append a PartialName
443 * @param name the components to append
444 * @return a reference to this name, to allow chaining
445 */
446 Name&
447 append(const PartialName& name);
448
449 /** @brief Append a component
450 * @note This makes push_back an alias of append, giving Name a similar API as STL vector.
451 */
452 template<class T>
453 void
454 push_back(const T& component)
455 {
456 append(component);
457 }
458
459 /** @brief Remove all components
460 * @post empty() == true
461 */
462 void
463 clear()
464 {
465 m_wire = Block(tlv::Name);
466 }
467
468public: // algorithms
469 /** @brief Get the successor of a name
470 *
471 * The successor of a name is defined as follows:
472 *
473 * N represents the set of NDN Names, and X,Y ∈ N.
474 * Operator < is defined by canonical order on N.
475 * Y is the successor of X, if (a) X < Y, and (b) ∄ Z ∈ N s.t. X < Z < Y.
476 *
477 * In plain words, successor of a name is the same name, but with its last component
478 * advanced to a next possible value.
479 *
480 * Examples:
481 *
Junxiao Shicf0aff82018-07-23 06:42:13 -0600482 * - successor of `/` is
483 * `/sha256digest=0000000000000000000000000000000000000000000000000000000000000000`.
484 * - successor of `/sha256digest=0000000000000000000000000000000000000000000000000000000000000000`
485 * is `/sha256digest=0000000000000000000000000000000000000000000000000000000000000001`.
486 * - successor of `/sha256digest=ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff`
487 * is `/2=...`.
488 * - successor of `/P/A` is `/P/B`.
489 * - successor of `/Q/%FF` is `/Q/%00%00`.
Junxiao Shi71ff2312017-07-12 13:32:50 +0000490 *
491 * @return a new Name containing the successor
492 */
493 Name
494 getSuccessor() const;
495
496 /** @brief Check if this name is a prefix of another name
497 *
498 * This name is a prefix of @p other if the N components of this name are same as the first N
499 * components of @p other.
500 *
501 * @retval true this name is a prefix of @p other
502 * @retval false this name is not a prefix of @p other
503 */
504 bool
505 isPrefixOf(const Name& other) const;
506
507 /** @brief Check if this name equals another name
508 *
509 * Two names are equal if they have the same number of components, and components at each index
510 * are equal.
511 */
512 bool
513 equals(const Name& other) const;
514
515 /** @brief Compare this to the other Name using NDN canonical ordering.
516 *
517 * If the first components of each name are not equal, this returns a negative value if
518 * the first comes before the second using the NDN canonical ordering for name
519 * components, or a positive value if it comes after. If they are equal, this compares
520 * the second components of each name, etc. If both names are the same up to the size
521 * of the shorter name, this returns a negative value if the first name is shorter than
522 * the second or a positive value if it is longer. For example, if you std::sort gives:
523 * /a/b/d /a/b/cc /c /c/a /bb .
524 * This is intuitive because all names with the prefix /a are next to each other.
525 * But it may be also be counter-intuitive because /c comes before /bb according
526 * to NDN canonical ordering since it is shorter.
527 *
528 * @param other The other Name to compare with.
529 *
530 * @retval negative this comes before other in canonical ordering
531 * @retval zero this equals other
532 * @retval positive this comes after other in canonical ordering
533 *
Junxiao Shia36f15d2018-04-04 02:22:11 +0000534 * @sa https://named-data.net/doc/NDN-packet-spec/current/name.html#canonical-order
Junxiao Shi71ff2312017-07-12 13:32:50 +0000535 */
536 int
537 compare(const Name& other) const
538 {
539 return this->compare(0, npos, other);
540 }
541
542 /** @brief compares [pos1, pos1+count1) components in this Name
543 * to [pos2, pos2+count2) components in @p other
544 *
545 * This is equivalent to this->getSubName(pos1, count1).compare(other.getSubName(pos2, count2));
546 */
547 int
548 compare(size_t pos1, size_t count1,
549 const Name& other, size_t pos2 = 0, size_t count2 = npos) const;
550
Junxiao Shia6452ac2015-01-23 11:21:06 -0700551public:
Junxiao Shiadc334e2017-07-14 20:28:28 +0000552 /** @brief indicates "until the end" in getSubName and compare
Junxiao Shia6452ac2015-01-23 11:21:06 -0700553 */
554 static const size_t npos;
555
Jeff Thompson9c41dfe2013-06-27 12:10:25 -0700556private:
Junxiao Shi71ff2312017-07-12 13:32:50 +0000557 mutable Block m_wire;
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800558};
559
Davide Pesavento88a0d812017-08-19 21:31:42 -0400560NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(Name);
561
Junxiao Shi71ff2312017-07-12 13:32:50 +0000562inline bool
563operator==(const Name& lhs, const Name& rhs)
564{
565 return lhs.equals(rhs);
566}
567
568inline bool
569operator!=(const Name& lhs, const Name& rhs)
570{
571 return !lhs.equals(rhs);
572}
573
574inline bool
575operator<=(const Name& lhs, const Name& rhs)
576{
577 return lhs.compare(rhs) <= 0;
578}
579
580inline bool
581operator<(const Name& lhs, const Name& rhs)
582{
583 return lhs.compare(rhs) < 0;
584}
585
586inline bool
587operator>=(const Name& lhs, const Name& rhs)
588{
589 return lhs.compare(rhs) >= 0;
590}
591
592inline bool
593operator>(const Name& lhs, const Name& rhs)
594{
595 return lhs.compare(rhs) > 0;
596}
597
598/** @brief Print URI representation of a name
Junxiao Shia36f15d2018-04-04 02:22:11 +0000599 * @sa https://named-data.net/doc/NDN-packet-spec/current/name.html#ndn-uri-scheme
Junxiao Shi71ff2312017-07-12 13:32:50 +0000600 */
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700601std::ostream&
602operator<<(std::ostream& os, const Name& name);
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700603
Junxiao Shi71ff2312017-07-12 13:32:50 +0000604/** @brief Parse URI from stream as Name
Junxiao Shia36f15d2018-04-04 02:22:11 +0000605 * @sa https://named-data.net/doc/NDN-packet-spec/current/name.html#ndn-uri-scheme
Junxiao Shi71ff2312017-07-12 13:32:50 +0000606 */
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700607std::istream&
608operator>>(std::istream& is, Name& name);
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -0800609
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800610} // namespace ndn
Jeff Thompson9c41dfe2013-06-27 12:10:25 -0700611
Yingdi Yu90e23582014-11-06 14:21:04 -0800612namespace std {
Junxiao Shi71ff2312017-07-12 13:32:50 +0000613
Yingdi Yu90e23582014-11-06 14:21:04 -0800614template<>
615struct hash<ndn::Name>
616{
617 size_t
618 operator()(const ndn::Name& name) const;
619};
620
621} // namespace std
622
Junxiao Shi8609bf22017-07-12 13:02:55 +0000623#endif // NDN_NAME_HPP