blob: ad986d7a6aa8a60e64cba39d54a10c9311008607 [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
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080029#include "name-component.hpp"
Junxiao Shiadc334e2017-07-14 20:28:28 +000030#include <iterator>
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080031
Jeff Thompson9c41dfe2013-06-27 12:10:25 -070032namespace ndn {
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080033
Joao Pereira6f7cfd02015-06-15 11:36:26 -040034class Name;
35
Junxiao Shi71ff2312017-07-12 13:32:50 +000036/** @brief Represents an arbitrary sequence of name components
Joao Pereira6f7cfd02015-06-15 11:36:26 -040037 */
Junxiao Shi71ff2312017-07-12 13:32:50 +000038using PartialName = Name;
Joao Pereira6f7cfd02015-06-15 11:36:26 -040039
Junxiao Shi71ff2312017-07-12 13:32:50 +000040/** @brief Represents an absolute name
Jeff Thompsonc7d65502013-11-06 17:22:26 -080041 */
Junxiao Shi8609bf22017-07-12 13:02:55 +000042class Name
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070043{
Junxiao Shi71ff2312017-07-12 13:32:50 +000044public: // nested types
Junxiao Shi68b53852018-07-25 13:56:38 -060045 using Error = name::Component::Error;
Alexander Afanasyevaf283d82014-01-03 13:23:34 -080046
Junxiao Shi71ff2312017-07-12 13:32:50 +000047 using Component = name::Component;
48 using component_container = std::vector<Component>;
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080049
Junxiao Shi71ff2312017-07-12 13:32:50 +000050 // Name appears as a container of name components
51 using value_type = Component;
52 using allocator_type = void;
53 using reference = Component&;
Junxiao Shiadc334e2017-07-14 20:28:28 +000054 using const_reference = const Component&;
Junxiao Shi71ff2312017-07-12 13:32:50 +000055 using pointer = Component*;
56 using const_pointer = const Component*;
Junxiao Shiadc334e2017-07-14 20:28:28 +000057 using iterator = const Component*; // disallow modifying via iterator
Junxiao Shi71ff2312017-07-12 13:32:50 +000058 using const_iterator = const Component*;
Junxiao Shiadc334e2017-07-14 20:28:28 +000059 using reverse_iterator = std::reverse_iterator<iterator>;
60 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
Junxiao Shi71ff2312017-07-12 13:32:50 +000061 using difference_type = component_container::difference_type;
62 using size_type = component_container::size_type;
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080063
Junxiao Shi71ff2312017-07-12 13:32:50 +000064public: // constructors, encoding, decoding
65 /** @brief Create an empty name
66 * @post empty() == true
Jeff Thompson443398d2013-07-02 19:45:46 -070067 */
Alexander Afanasyevc89efb42015-02-10 18:26:42 -080068 Name();
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -080069
Junxiao Shi71ff2312017-07-12 13:32:50 +000070 /** @brief Decode Name from wire encoding
71 * @throw tlv::Error wire encoding is invalid
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -080072 *
Junxiao Shi71ff2312017-07-12 13:32:50 +000073 * This is a more efficient equivalent for
74 * @code
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -080075 * Name name;
76 * name.wireDecode(wire);
Junxiao Shi71ff2312017-07-12 13:32:50 +000077 * @endcode
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -080078 */
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -080079 explicit
Alexander Afanasyevc89efb42015-02-10 18:26:42 -080080 Name(const Block& wire);
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -070081
Junxiao Shi71ff2312017-07-12 13:32:50 +000082 /** @brief Parse name from NDN URI
83 * @param uri a null-terminated URI string
Junxiao Shia36f15d2018-04-04 02:22:11 +000084 * @sa https://named-data.net/doc/NDN-packet-spec/current/name.html#ndn-uri-scheme
Jeff Thompson443398d2013-07-02 19:45:46 -070085 */
Alexander Afanasyevc89efb42015-02-10 18:26:42 -080086 Name(const char* uri);
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -070087
Junxiao Shi71ff2312017-07-12 13:32:50 +000088 /** @brief Create name from NDN URI
89 * @param uri a URI string
Junxiao Shia36f15d2018-04-04 02:22:11 +000090 * @sa https://named-data.net/doc/NDN-packet-spec/current/name.html#ndn-uri-scheme
Jeff Thompson3549ef32013-09-25 14:05:17 -070091 */
Junxiao Shi3188c4032016-07-18 20:53:56 +000092 Name(std::string uri);
Jeff Thompsonec39fbd2013-10-04 10:56:23 -070093
Junxiao Shi71ff2312017-07-12 13:32:50 +000094 /** @brief Get URI representation of the name
95 * @return URI representation; "ndn:" scheme identifier is not included
Junxiao Shia36f15d2018-04-04 02:22:11 +000096 * @sa https://named-data.net/doc/NDN-packet-spec/current/name.html#ndn-uri-scheme
Junxiao Shi71ff2312017-07-12 13:32:50 +000097 * @note To print URI representation into a stream, it is more efficient to use ``os << name``.
Alexander Afanasyev4f512fb2016-05-18 10:47:53 -070098 */
Junxiao Shi71ff2312017-07-12 13:32:50 +000099 std::string
100 toUri() const;
Alexander Afanasyev4f512fb2016-05-18 10:47:53 -0700101
Junxiao Shi71ff2312017-07-12 13:32:50 +0000102 /** @brief Check if this Name instance already has wire encoding
103 */
104 bool
105 hasWire() const
106 {
107 return m_wire.hasWire();
108 }
109
110 /** @brief Fast encoding or block size estimation
Alexander Afanasyev380420b2014-02-09 20:52:29 -0800111 */
Alexander Afanasyev74633892015-02-08 18:08:46 -0800112 template<encoding::Tag TAG>
Wentao Shang77949212014-02-01 23:42:24 -0800113 size_t
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -0700114 wireEncode(EncodingImpl<TAG>& encoder) const;
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700115
Junxiao Shi71ff2312017-07-12 13:32:50 +0000116 /** @brief Perform wire encoding, or return existing wire encoding
117 * @post hasWire() == true
118 */
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700119 const Block&
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800120 wireEncode() const;
Alexander Afanasyev848c61a2014-01-03 13:52:04 -0800121
Junxiao Shi71ff2312017-07-12 13:32:50 +0000122 /** @brief Decode name from wire encoding
123 * @throw tlv::Error wire encoding is invalid
124 * @post hasWire() == true
125 */
Alexander Afanasyev848c61a2014-01-03 13:52:04 -0800126 void
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700127 wireDecode(const Block& wire);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800128
Junxiao Shi71ff2312017-07-12 13:32:50 +0000129 /** @brief Make a deep copy of the name, reallocating the underlying memory buffer
130 */
131 Name
132 deepCopy() const;
133
134public: // access
135 /** @brief Check if name is empty
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800136 */
137 bool
Junxiao Shi71ff2312017-07-12 13:32:50 +0000138 empty() const
Jeff Thompson0f743452013-09-12 14:23:18 -0700139 {
Junxiao Shi71ff2312017-07-12 13:32:50 +0000140 return m_wire.elements().empty();
Jeff Thompsone5f839b2013-06-28 12:50:38 -0700141 }
Jeff Thompsonf72b1ac2013-08-16 16:44:41 -0700142
Junxiao Shi71ff2312017-07-12 13:32:50 +0000143 /** @brief Get number of components
Alexander Afanasyevbf9671d2014-02-11 13:44:13 -0800144 */
Junxiao Shi71ff2312017-07-12 13:32:50 +0000145 size_t
146 size() const
Alexander Afanasyevbf9671d2014-02-11 13:44:13 -0800147 {
Junxiao Shi71ff2312017-07-12 13:32:50 +0000148 return m_wire.elements_size();
Alexander Afanasyevbf9671d2014-02-11 13:44:13 -0800149 }
150
Junxiao Shi71ff2312017-07-12 13:32:50 +0000151 /** @brief Get the component at the given index
152 * @param i zero-based index; if negative, it starts at the end of this name
153 * @warning Indexing out of bounds triggers undefined behavior.
Alexander Afanasyevc89efb42015-02-10 18:26:42 -0800154 */
Junxiao Shi71ff2312017-07-12 13:32:50 +0000155 const Component&
156 get(ssize_t i) const
Jeff Thompson21eb7212013-09-26 09:05:40 -0700157 {
Junxiao Shi71ff2312017-07-12 13:32:50 +0000158 if (i < 0) {
159 i += size();
160 }
161 return reinterpret_cast<const Component&>(m_wire.elements()[i]);
Jeff Thompson21eb7212013-09-26 09:05:40 -0700162 }
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800163
Junxiao Shi71ff2312017-07-12 13:32:50 +0000164 /** @brief Equivalent to get(i)
165 */
166 const Component&
167 operator[](ssize_t i) const
168 {
169 return get(i);
170 }
171
172 /** @brief Get the component at the given index
173 * @param i zero-based index; if negative, size()+i is used instead
174 * @throws Name::Error index is out of bounds
175 */
176 const Component&
177 at(ssize_t i) const;
178
179 /** @brief Extract some components as a sub-name (PartialName)
180 * @param iStartComponent zero-based index of the first component;
181 * if negative, size()+iStartComponent is used instead
182 * @param nComponents Number of components starting at iStartComponent.
183 * Use @p npos to get the PartialName until the end of this Name.
184 * @return a new PartialName containing the extracted components
Alexander Afanasyev594cdb22014-01-03 15:11:33 -0800185 *
Junxiao Shi71ff2312017-07-12 13:32:50 +0000186 * If iStartComponent is positive and indexes out of bounds, returns an empty PartialName.
187 * If iStartComponent is negative and indexes out of bounds, returns components starting from the
188 * beginning of the Name. If nComponents is out of bounds, returns the components until the end
189 * of this Name.
Jeff Thompsond0159d72013-09-23 13:34:15 -0700190 */
Joao Pereira6f7cfd02015-06-15 11:36:26 -0400191 PartialName
192 getSubName(ssize_t iStartComponent, size_t nComponents = npos) const;
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700193
Junxiao Shi71ff2312017-07-12 13:32:50 +0000194 /** @brief Extract a prefix of the name
195 * @param nComponents Number of components; if negative, size()+nComponents is used instead
196 * @return a new Name containing the prefix
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700197 * the prefix up to name.size() - N. For example getPrefix(-1)
198 * returns the name without the final component.
Joao Pereira6f7cfd02015-06-15 11:36:26 -0400199 * @return A new partial name
Jeff Thompsond0159d72013-09-23 13:34:15 -0700200 */
Joao Pereira6f7cfd02015-06-15 11:36:26 -0400201 PartialName
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700202 getPrefix(ssize_t nComponents) const
Jeff Thompsond0159d72013-09-23 13:34:15 -0700203 {
Jeff Thompsoneb0358f2013-12-17 10:59:53 -0800204 if (nComponents < 0)
Junxiao Shi71ff2312017-07-12 13:32:50 +0000205 return getSubName(0, size() + nComponents);
Jeff Thompsoneb0358f2013-12-17 10:59:53 -0800206 else
207 return getSubName(0, nComponents);
Jeff Thompsond0159d72013-09-23 13:34:15 -0700208 }
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700209
Junxiao Shi71ff2312017-07-12 13:32:50 +0000210public: // iterators
211 /** @brief Begin iterator
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700212 */
213 const_iterator
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800214 begin() const
215 {
Junxiao Shif0bf9992017-07-15 15:51:52 +0000216 return reinterpret_cast<const_iterator>(m_wire.elements().data());
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800217 }
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700218
Junxiao Shi71ff2312017-07-12 13:32:50 +0000219 /** @brief End iterator
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700220 */
221 const_iterator
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800222 end() const
223 {
Junxiao Shif0bf9992017-07-15 15:51:52 +0000224 return reinterpret_cast<const_iterator>(m_wire.elements().data() + m_wire.elements().size());
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800225 }
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700226
Junxiao Shi71ff2312017-07-12 13:32:50 +0000227 /** @brief Reverse begin iterator
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700228 */
229 const_reverse_iterator
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800230 rbegin() const
231 {
232 return const_reverse_iterator(end());
233 }
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700234
Junxiao Shi71ff2312017-07-12 13:32:50 +0000235 /** @brief Reverse end iterator
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700236 */
237 const_reverse_iterator
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800238 rend() const
239 {
240 return const_reverse_iterator(begin());
241 }
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700242
Junxiao Shi71ff2312017-07-12 13:32:50 +0000243public: // modifiers
Junxiao Shia36f15d2018-04-04 02:22:11 +0000244 /** @brief Append a component.
245 * @return a reference to this name, to allow chaining.
Junxiao Shi71ff2312017-07-12 13:32:50 +0000246 */
247 Name&
248 append(const Component& component)
249 {
250 m_wire.push_back(component);
251 return *this;
252 }
253
Junxiao Shia36f15d2018-04-04 02:22:11 +0000254 /** @brief Append a NameComponent of TLV-TYPE @p type, copying @p count bytes at @p value as
255 * TLV-VALUE.
256 * @return a reference to this name, to allow chaining.
Junxiao Shi71ff2312017-07-12 13:32:50 +0000257 */
258 Name&
Junxiao Shia36f15d2018-04-04 02:22:11 +0000259 append(uint32_t type, const uint8_t* value, size_t count)
Junxiao Shi71ff2312017-07-12 13:32:50 +0000260 {
Junxiao Shia36f15d2018-04-04 02:22:11 +0000261 return append(Component(type, value, count));
Junxiao Shi71ff2312017-07-12 13:32:50 +0000262 }
263
Junxiao Shia36f15d2018-04-04 02:22:11 +0000264 /** @brief Append a GenericNameComponent, copying @p count bytes at @p value as TLV-VALUE.
265 * @return a reference to this name, to allow chaining.
Junxiao Shi71ff2312017-07-12 13:32:50 +0000266 */
267 Name&
Junxiao Shia36f15d2018-04-04 02:22:11 +0000268 append(const uint8_t* value, size_t count)
Junxiao Shi71ff2312017-07-12 13:32:50 +0000269 {
Junxiao Shia36f15d2018-04-04 02:22:11 +0000270 return append(Component(value, count));
Junxiao Shi71ff2312017-07-12 13:32:50 +0000271 }
272
Junxiao Shia36f15d2018-04-04 02:22:11 +0000273 /** @brief Append a NameComponent of TLV-TYPE @p type, copying TLV-VALUE from a range.
274 * @tparam Iterator an @c InputIterator dereferencing to a one-octet value type. More efficient
275 * implementation is available when it is a @c RandomAccessIterator.
276 * @param type the TLV-TYPE.
277 * @param first beginning of the range.
278 * @param last past-end of the range.
279 * @return a reference to this name, to allow chaining.
280 */
281 template<class Iterator>
282 Name&
283 append(uint32_t type, Iterator first, Iterator last)
284 {
285 return append(Component(type, first, last));
286 }
287
288 /** @brief Append a GenericNameComponent, copying TLV-VALUE from a range.
289 * @tparam Iterator an @c InputIterator dereferencing to a one-octet value type. More efficient
290 * implementation is available when it is a @c RandomAccessIterator.
291 * @param first beginning of the range.
292 * @param last past-end of the range.
293 * @return a reference to this name, to allow chaining.
Junxiao Shi71ff2312017-07-12 13:32:50 +0000294 */
295 template<class Iterator>
296 Name&
297 append(Iterator first, Iterator last)
298 {
Junxiao Shi71ff2312017-07-12 13:32:50 +0000299 return append(Component(first, last));
300 }
301
Junxiao Shia36f15d2018-04-04 02:22:11 +0000302 /** @brief Append a GenericNameComponent, copying TLV-VALUE from a null-terminated string.
303 * @param str a null-terminated string. Bytes from the string are copied as is, and not
304 * interpreted as URI component.
305 * @return a reference to this name, to allow chaining.
306 */
307 Name&
308 append(const char* str)
309 {
310 return append(Component(str));
311 }
312
313 /** @brief Append a GenericNameComponent from a TLV element.
314 * @param value a TLV element. If its type is @c tlv::GenericNameComponent, it is used as is.
315 * Otherwise, it is encapsulated into a GenericNameComponent.
316 * @return a reference to this name, to allow chaining.
Junxiao Shi71ff2312017-07-12 13:32:50 +0000317 */
318 Name&
319 append(const Block& value)
320 {
Junxiao Shia36f15d2018-04-04 02:22:11 +0000321 if (value.type() == tlv::GenericNameComponent) {
Junxiao Shi71ff2312017-07-12 13:32:50 +0000322 m_wire.push_back(value);
323 }
324 else {
Junxiao Shia36f15d2018-04-04 02:22:11 +0000325 m_wire.push_back(Block(tlv::GenericNameComponent, value));
Junxiao Shi71ff2312017-07-12 13:32:50 +0000326 }
Junxiao Shi71ff2312017-07-12 13:32:50 +0000327 return *this;
328 }
329
330 /** @brief Append a component with a nonNegativeInteger
331 * @sa number the number
332 * @return a reference to this name, to allow chaining
Junxiao Shia36f15d2018-04-04 02:22:11 +0000333 * @sa https://named-data.net/doc/NDN-packet-spec/current/tlv.html#non-negative-integer-encoding
Junxiao Shi71ff2312017-07-12 13:32:50 +0000334 */
335 Name&
336 appendNumber(uint64_t number)
337 {
338 return append(Component::fromNumber(number));
339 }
340
341 /** @brief Append a component with a marked number
342 * @param marker 1-octet marker
343 * @param number the number
344 *
345 * The component is encoded as a 1-octet marker, followed by a nonNegativeInteger.
346 *
347 * @return a reference to this name, to allow chaining
348 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
349 */
350 Name&
351 appendNumberWithMarker(uint8_t marker, uint64_t number)
352 {
353 return append(Component::fromNumberWithMarker(marker, number));
354 }
355
356 /** @brief Append a version component
357 * @return a reference to this name, to allow chaining
358 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
359 */
360 Name&
361 appendVersion(uint64_t version)
362 {
363 return append(Component::fromVersion(version));
364 }
365
366 /** @brief Append a version component based on current time
367 *
368 * The version number is the current UNIX timestamp in milliseconds
369 *
370 * @return a reference to this name, to allow chaining
371 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
372 */
373 Name&
374 appendVersion();
375
376 /** @brief Append a segment number (sequential) component
377 * @return a reference to this name, to allow chaining
378 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
379 */
380 Name&
381 appendSegment(uint64_t segmentNo)
382 {
383 return append(Component::fromSegment(segmentNo));
384 }
385
386 /** @brief Append a segment byte offset component
387 * @return a reference to this name, to allow chaining
388 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
389 */
390 Name&
391 appendSegmentOffset(uint64_t offset)
392 {
393 return append(Component::fromSegmentOffset(offset));
394 }
395
396 /** @brief Append a timestamp component
397 * @return a reference to this name, to allow chaining
398 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
399 */
400 Name&
401 appendTimestamp(const time::system_clock::TimePoint& timePoint)
402 {
403 return append(Component::fromTimestamp(timePoint));
404 }
405
406 /** @brief Append a timestamp component based on current time
407 * @return a reference to this name, to allow chaining
408 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
409 */
410 Name&
411 appendTimestamp();
412
413 /** @brief Append a sequence number component
414 * @return a reference to this name, to allow chaining
415 * @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
416 */
417 Name&
418 appendSequenceNumber(uint64_t seqNo)
419 {
420 return append(Component::fromSequenceNumber(seqNo));
421 }
422
423 /** @brief Append an ImplicitSha256Digest component
424 * @return a reference to this name, to allow chaining
425 */
426 Name&
Davide Pesavento3b101d02018-07-21 22:44:09 -0400427 appendImplicitSha256Digest(ConstBufferPtr digest)
Junxiao Shi71ff2312017-07-12 13:32:50 +0000428 {
Davide Pesavento3b101d02018-07-21 22:44:09 -0400429 return append(Component::fromImplicitSha256Digest(std::move(digest)));
Junxiao Shi71ff2312017-07-12 13:32:50 +0000430 }
431
432 /** @brief Append an ImplicitSha256Digest component
433 * @return a reference to this name, to allow chaining
434 */
435 Name&
436 appendImplicitSha256Digest(const uint8_t* digest, size_t digestSize)
437 {
438 return append(Component::fromImplicitSha256Digest(digest, digestSize));
439 }
440
441 /** @brief Append a PartialName
442 * @param name the components to append
443 * @return a reference to this name, to allow chaining
444 */
445 Name&
446 append(const PartialName& name);
447
448 /** @brief Append a component
449 * @note This makes push_back an alias of append, giving Name a similar API as STL vector.
450 */
451 template<class T>
452 void
453 push_back(const T& component)
454 {
455 append(component);
456 }
457
458 /** @brief Remove all components
459 * @post empty() == true
460 */
461 void
462 clear()
463 {
464 m_wire = Block(tlv::Name);
465 }
466
467public: // algorithms
468 /** @brief Get the successor of a name
469 *
470 * The successor of a name is defined as follows:
471 *
472 * N represents the set of NDN Names, and X,Y ∈ N.
473 * Operator < is defined by canonical order on N.
474 * Y is the successor of X, if (a) X < Y, and (b) ∄ Z ∈ N s.t. X < Z < Y.
475 *
476 * In plain words, successor of a name is the same name, but with its last component
477 * advanced to a next possible value.
478 *
479 * Examples:
480 *
Junxiao Shicf0aff82018-07-23 06:42:13 -0600481 * - successor of `/` is
482 * `/sha256digest=0000000000000000000000000000000000000000000000000000000000000000`.
483 * - successor of `/sha256digest=0000000000000000000000000000000000000000000000000000000000000000`
484 * is `/sha256digest=0000000000000000000000000000000000000000000000000000000000000001`.
485 * - successor of `/sha256digest=ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff`
486 * is `/2=...`.
487 * - successor of `/P/A` is `/P/B`.
488 * - successor of `/Q/%FF` is `/Q/%00%00`.
Junxiao Shi71ff2312017-07-12 13:32:50 +0000489 *
490 * @return a new Name containing the successor
491 */
492 Name
493 getSuccessor() const;
494
495 /** @brief Check if this name is a prefix of another name
496 *
497 * This name is a prefix of @p other if the N components of this name are same as the first N
498 * components of @p other.
499 *
500 * @retval true this name is a prefix of @p other
501 * @retval false this name is not a prefix of @p other
502 */
503 bool
504 isPrefixOf(const Name& other) const;
505
506 /** @brief Check if this name equals another name
507 *
508 * Two names are equal if they have the same number of components, and components at each index
509 * are equal.
510 */
511 bool
512 equals(const Name& other) const;
513
514 /** @brief Compare this to the other Name using NDN canonical ordering.
515 *
516 * If the first components of each name are not equal, this returns a negative value if
517 * the first comes before the second using the NDN canonical ordering for name
518 * components, or a positive value if it comes after. If they are equal, this compares
519 * the second components of each name, etc. If both names are the same up to the size
520 * of the shorter name, this returns a negative value if the first name is shorter than
521 * the second or a positive value if it is longer. For example, if you std::sort gives:
522 * /a/b/d /a/b/cc /c /c/a /bb .
523 * This is intuitive because all names with the prefix /a are next to each other.
524 * But it may be also be counter-intuitive because /c comes before /bb according
525 * to NDN canonical ordering since it is shorter.
526 *
527 * @param other The other Name to compare with.
528 *
529 * @retval negative this comes before other in canonical ordering
530 * @retval zero this equals other
531 * @retval positive this comes after other in canonical ordering
532 *
Junxiao Shia36f15d2018-04-04 02:22:11 +0000533 * @sa https://named-data.net/doc/NDN-packet-spec/current/name.html#canonical-order
Junxiao Shi71ff2312017-07-12 13:32:50 +0000534 */
535 int
536 compare(const Name& other) const
537 {
538 return this->compare(0, npos, other);
539 }
540
541 /** @brief compares [pos1, pos1+count1) components in this Name
542 * to [pos2, pos2+count2) components in @p other
543 *
544 * This is equivalent to this->getSubName(pos1, count1).compare(other.getSubName(pos2, count2));
545 */
546 int
547 compare(size_t pos1, size_t count1,
548 const Name& other, size_t pos2 = 0, size_t count2 = npos) const;
549
Junxiao Shia6452ac2015-01-23 11:21:06 -0700550public:
Junxiao Shiadc334e2017-07-14 20:28:28 +0000551 /** @brief indicates "until the end" in getSubName and compare
Junxiao Shia6452ac2015-01-23 11:21:06 -0700552 */
553 static const size_t npos;
554
Jeff Thompson9c41dfe2013-06-27 12:10:25 -0700555private:
Junxiao Shi71ff2312017-07-12 13:32:50 +0000556 mutable Block m_wire;
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800557};
558
Davide Pesavento88a0d812017-08-19 21:31:42 -0400559NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(Name);
560
Junxiao Shi71ff2312017-07-12 13:32:50 +0000561inline bool
562operator==(const Name& lhs, const Name& rhs)
563{
564 return lhs.equals(rhs);
565}
566
567inline bool
568operator!=(const Name& lhs, const Name& rhs)
569{
570 return !lhs.equals(rhs);
571}
572
573inline bool
574operator<=(const Name& lhs, const Name& rhs)
575{
576 return lhs.compare(rhs) <= 0;
577}
578
579inline bool
580operator<(const Name& lhs, const Name& rhs)
581{
582 return lhs.compare(rhs) < 0;
583}
584
585inline bool
586operator>=(const Name& lhs, const Name& rhs)
587{
588 return lhs.compare(rhs) >= 0;
589}
590
591inline bool
592operator>(const Name& lhs, const Name& rhs)
593{
594 return lhs.compare(rhs) > 0;
595}
596
597/** @brief Print URI representation of a name
Junxiao Shia36f15d2018-04-04 02:22:11 +0000598 * @sa https://named-data.net/doc/NDN-packet-spec/current/name.html#ndn-uri-scheme
Junxiao Shi71ff2312017-07-12 13:32:50 +0000599 */
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700600std::ostream&
601operator<<(std::ostream& os, const Name& name);
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700602
Junxiao Shi71ff2312017-07-12 13:32:50 +0000603/** @brief Parse URI from stream as Name
Junxiao Shia36f15d2018-04-04 02:22:11 +0000604 * @sa https://named-data.net/doc/NDN-packet-spec/current/name.html#ndn-uri-scheme
Junxiao Shi71ff2312017-07-12 13:32:50 +0000605 */
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700606std::istream&
607operator>>(std::istream& is, Name& name);
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -0800608
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800609} // namespace ndn
Jeff Thompson9c41dfe2013-06-27 12:10:25 -0700610
Yingdi Yu90e23582014-11-06 14:21:04 -0800611namespace std {
Junxiao Shi71ff2312017-07-12 13:32:50 +0000612
Yingdi Yu90e23582014-11-06 14:21:04 -0800613template<>
614struct hash<ndn::Name>
615{
616 size_t
617 operator()(const ndn::Name& name) const;
618};
619
620} // namespace std
621
Junxiao Shi8609bf22017-07-12 13:02:55 +0000622#endif // NDN_NAME_HPP