blob: 986ef8fcd34d17016a2d8ca82e987f1d51c63364 [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Jeff Thompson47eecfc2013-07-07 22:56:46 -07002/**
Alexander Afanasyev4f512fb2016-05-18 10:47:53 -07003 * Copyright (c) 2013-2016 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 "common.hpp"
30#include "name-component.hpp"
Jeff Thompson25b4e612013-10-10 16:03:24 -070031
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080032#include <boost/iterator/reverse_iterator.hpp>
33
Jeff Thompson9c41dfe2013-06-27 12:10:25 -070034namespace ndn {
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080035
Joao Pereira6f7cfd02015-06-15 11:36:26 -040036class Name;
37
Jeff Thompsonc7d65502013-11-06 17:22:26 -080038/**
Joao Pereira6f7cfd02015-06-15 11:36:26 -040039 * @brief Partial name abstraction to represent an arbitrary sequence of name components
40 */
41typedef Name PartialName;
42
43/**
44 * @brief Name abstraction to represent an absolute name
Jeff Thompsonc7d65502013-11-06 17:22:26 -080045 */
Alexander Afanasyevf73f0632014-05-12 18:02:37 -070046class Name : public enable_shared_from_this<Name>
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070047{
Jeff Thompson9c41dfe2013-06-27 12:10:25 -070048public:
Joao Pereira6f7cfd02015-06-15 11:36:26 -040049 /**
50 * @brief Error that can be thrown from Name
51 */
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070052 class Error : public name::Component::Error
53 {
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -070054 public:
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070055 explicit
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -070056 Error(const std::string& what)
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070057 : name::Component::Error(what)
58 {
59 }
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -070060 };
Alexander Afanasyevaf283d82014-01-03 13:23:34 -080061
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080062 typedef name::Component Component;
63
64 typedef std::vector<Component> component_container;
65
66 typedef Component value_type;
67 typedef void allocator_type;
68 typedef Component& reference;
69 typedef const Component const_reference;
70 typedef Component* pointer;
71 typedef const Component* const_pointer;
72 typedef Component* iterator;
73 typedef const Component* const_iterator;
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -070074
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080075 typedef boost::reverse_iterator<iterator> reverse_iterator;
76 typedef boost::reverse_iterator<const_iterator> const_reverse_iterator;
77
78 typedef component_container::difference_type difference_type;
79 typedef component_container::size_type size_type;
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -070080
Jeff Thompson443398d2013-07-02 19:45:46 -070081 /**
Alexander Afanasyevc89efb42015-02-10 18:26:42 -080082 * @brief Create a new Name with no components.
Jeff Thompson443398d2013-07-02 19:45:46 -070083 */
Alexander Afanasyevc89efb42015-02-10 18:26:42 -080084 Name();
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -080085
86 /**
87 * @brief Create Name object from wire block
88 *
89 * This is a more efficient equivalent for
90 * @code
91 * Name name;
92 * name.wireDecode(wire);
93 * @endcode
94 */
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -080095 explicit
Alexander Afanasyevc89efb42015-02-10 18:26:42 -080096 Name(const Block& wire);
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -070097
Jeff Thompson3f2175b2013-07-31 17:12:47 -070098 /**
Alexander Afanasyevc89efb42015-02-10 18:26:42 -080099 * @brief Create name from @p uri (NDN URI scheme)
100 * @param uri The null-terminated URI string
Jeff Thompson443398d2013-07-02 19:45:46 -0700101 */
Alexander Afanasyevc89efb42015-02-10 18:26:42 -0800102 Name(const char* uri);
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700103
Jeff Thompsone5f839b2013-06-28 12:50:38 -0700104 /**
Alexander Afanasyevc89efb42015-02-10 18:26:42 -0800105 * @brief Create name from @p uri (NDN URI scheme)
106 * @param uri The URI string
Jeff Thompson3549ef32013-09-25 14:05:17 -0700107 */
Alexander Afanasyevc89efb42015-02-10 18:26:42 -0800108 Name(const std::string& uri);
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700109
Alexander Afanasyev380420b2014-02-09 20:52:29 -0800110 /**
Alexander Afanasyev4f512fb2016-05-18 10:47:53 -0700111 * @brief Make a deep copy of the name, reallocating the underlying memory buffer
112 */
113 Name
114 deepCopy() const;
115
116 /**
Alexander Afanasyev380420b2014-02-09 20:52:29 -0800117 * @brief Fast encoding or block size estimation
118 */
Alexander Afanasyev74633892015-02-08 18:08:46 -0800119 template<encoding::Tag TAG>
Wentao Shang77949212014-02-01 23:42:24 -0800120 size_t
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -0700121 wireEncode(EncodingImpl<TAG>& encoder) const;
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700122
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700123 const Block&
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800124 wireEncode() const;
Alexander Afanasyev848c61a2014-01-03 13:52:04 -0800125
126 void
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700127 wireDecode(const Block& wire);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800128
129 /**
130 * @brief Check if already has wire
131 */
132 bool
133 hasWire() const;
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700134
Jeff Thompsonb468c312013-07-01 17:50:14 -0700135 /**
Alexander Afanasyevc89efb42015-02-10 18:26:42 -0800136 * @deprecated Use appropriate constructor
Jeff Thompson67515bd2013-08-15 17:43:22 -0700137 */
Alexander Afanasyevc89efb42015-02-10 18:26:42 -0800138 DEPRECATED(
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700139 void
Alexander Afanasyevc89efb42015-02-10 18:26:42 -0800140 set(const char* uri));
Jeff Thompson67515bd2013-08-15 17:43:22 -0700141
142 /**
Alexander Afanasyevc89efb42015-02-10 18:26:42 -0800143 * @deprecated Use appropriate constructor
Jeff Thompson7781b392013-12-17 11:45:59 -0800144 */
Alexander Afanasyevc89efb42015-02-10 18:26:42 -0800145 DEPRECATED(
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700146 void
Alexander Afanasyevc89efb42015-02-10 18:26:42 -0800147 set(const std::string& uri));
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700148
Jeff Thompson7781b392013-12-17 11:45:59 -0800149 /**
Alexander Afanasyevc89efb42015-02-10 18:26:42 -0800150 * @brief Append a new component, copying from value of length valueLength.
Jeff Thompson26b0d792013-09-23 16:19:01 -0700151 * @return This name so that you can chain calls to append.
Jeff Thompsone5f839b2013-06-28 12:50:38 -0700152 */
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700153 Name&
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700154 append(const uint8_t* value, size_t valueLength)
Jeff Thompson0f743452013-09-12 14:23:18 -0700155 {
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800156 m_nameBlock.push_back(Component(value, valueLength));
Jeff Thompson26b0d792013-09-23 16:19:01 -0700157 return *this;
Jeff Thompsone5f839b2013-06-28 12:50:38 -0700158 }
Jeff Thompsonf72b1ac2013-08-16 16:44:41 -0700159
Alexander Afanasyevbf9671d2014-02-11 13:44:13 -0800160 /**
Alexander Afanasyev74633892015-02-08 18:08:46 -0800161 * @brief Append a new component, copying from value frome the range [@p first, @p last) of bytes
162 * @param first Iterator pointing to the beginning of the buffer
163 * @param last Iterator pointing to the ending of the buffer
164 * @tparam Iterator iterator type satisfying at least InputIterator concept. Implementation
165 * is more optimal when the iterator type satisfies RandomAccessIterator concept.
166 * It is required that sizeof(std::iterator_traits<Iterator>::value_type) == 1.
Alexander Afanasyevbf9671d2014-02-11 13:44:13 -0800167 * @return This name so that you can chain calls to append.
168 */
Alexander Afanasyev74633892015-02-08 18:08:46 -0800169 template<class Iterator>
Alexander Afanasyevbf9671d2014-02-11 13:44:13 -0800170 Name&
Alexander Afanasyev74633892015-02-08 18:08:46 -0800171 append(Iterator first, Iterator last)
Alexander Afanasyevbf9671d2014-02-11 13:44:13 -0800172 {
Alexander Afanasyev74633892015-02-08 18:08:46 -0800173 m_nameBlock.push_back(Component(first, last));
Alexander Afanasyevbf9671d2014-02-11 13:44:13 -0800174 return *this;
175 }
176
Alexander Afanasyevc89efb42015-02-10 18:26:42 -0800177 /**
178 * @brief Append component @p value
179 */
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700180 Name&
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700181 append(const Component& value)
Jeff Thompson21eb7212013-09-26 09:05:40 -0700182 {
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800183 m_nameBlock.push_back(value);
Jeff Thompson21eb7212013-09-26 09:05:40 -0700184 return *this;
185 }
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800186
Alexander Afanasyev594cdb22014-01-03 15:11:33 -0800187 /**
188 * @brief Append name component that represented as a string
189 *
190 * Note that this method is necessary to ensure correctness and unambiguity of
191 * ``append("string")`` operations (both Component and Name can be implicitly
192 * converted from string, each having different outcomes
193 */
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700194 Name&
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700195 append(const char* value)
Alexander Afanasyev594cdb22014-01-03 15:11:33 -0800196 {
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800197 m_nameBlock.push_back(Component(value));
Alexander Afanasyev594cdb22014-01-03 15:11:33 -0800198 return *this;
199 }
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700200
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800201 Name&
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700202 append(const Block& value)
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800203 {
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600204 if (value.type() == tlv::NameComponent)
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800205 m_nameBlock.push_back(value);
Alexander Afanasyev380420b2014-02-09 20:52:29 -0800206 else
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600207 m_nameBlock.push_back(Block(tlv::NameComponent, value));
Alexander Afanasyev380420b2014-02-09 20:52:29 -0800208
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800209 return *this;
210 }
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700211
Jeff Thompsone5f839b2013-06-28 12:50:38 -0700212 /**
Joao Pereira6f7cfd02015-06-15 11:36:26 -0400213 * @brief append a PartialName to this Name.
214 * @param name the components to append
215 * @return this name
Jeff Thompson0aa66f22013-09-23 13:02:13 -0700216 */
Jeff Thompson26b0d792013-09-23 16:19:01 -0700217 Name&
Joao Pereira6f7cfd02015-06-15 11:36:26 -0400218 append(const PartialName& name);
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700219
Jeff Thompson0aa66f22013-09-23 13:02:13 -0700220 /**
Jeff Thompsone5f839b2013-06-28 12:50:38 -0700221 * Clear all the components.
222 */
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700223 void
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800224 clear()
225 {
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600226 m_nameBlock = Block(tlv::Name);
Jeff Thompsone5f839b2013-06-28 12:50:38 -0700227 }
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700228
Jeff Thompsone5f839b2013-06-28 12:50:38 -0700229 /**
Joao Pereira6f7cfd02015-06-15 11:36:26 -0400230 * @brief Extract a sub-name (PartialName) of @p nComponents components starting
231 * from @p iStartComponent
232 * @param iStartComponent index of the first component;
233 * if iStartComponent is negative, size()+iStartComponent is used instead
Jeff Thompsond0159d72013-09-23 13:34:15 -0700234 * @param nComponents The number of components starting at iStartComponent.
Joao Pereira6f7cfd02015-06-15 11:36:26 -0400235 * Use npos to get the Partial Name until the end of this Name.
Davide Pesavento18cf81b2015-09-12 23:36:43 +0200236 * @details If iStartComponent is out of bounds and is negative, returns the components
237 * starting from the beginning of the Name.
238 * If iStartComponent is out of bounds and is positive, returns the component "/".
239 * If nComponents is out of bounds, returns the components until the end of
240 * this Name
Joao Pereira6f7cfd02015-06-15 11:36:26 -0400241 * @return A new partial name
Jeff Thompsond0159d72013-09-23 13:34:15 -0700242 */
Joao Pereira6f7cfd02015-06-15 11:36:26 -0400243 PartialName
244 getSubName(ssize_t iStartComponent, size_t nComponents = npos) const;
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700245
Jeff Thompsond0159d72013-09-23 13:34:15 -0700246 /**
Joao Pereira6f7cfd02015-06-15 11:36:26 -0400247 * @brief Extract a prefix (PartialName) of the name, containing first @p nComponents components
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700248 *
249 * @param nComponents The number of prefix components. If nComponents is -N then return
250 * the prefix up to name.size() - N. For example getPrefix(-1)
251 * returns the name without the final component.
Joao Pereira6f7cfd02015-06-15 11:36:26 -0400252 * @return A new partial name
Jeff Thompsond0159d72013-09-23 13:34:15 -0700253 */
Joao Pereira6f7cfd02015-06-15 11:36:26 -0400254 PartialName
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700255 getPrefix(ssize_t nComponents) const
Jeff Thompsond0159d72013-09-23 13:34:15 -0700256 {
Jeff Thompsoneb0358f2013-12-17 10:59:53 -0800257 if (nComponents < 0)
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800258 return getSubName(0, m_nameBlock.elements_size() + nComponents);
Jeff Thompsoneb0358f2013-12-17 10:59:53 -0800259 else
260 return getSubName(0, nComponents);
Jeff Thompsond0159d72013-09-23 13:34:15 -0700261 }
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700262
Jeff Thompsond0159d72013-09-23 13:34:15 -0700263 /**
Jeff Thompsone6063512013-07-01 15:11:28 -0700264 * Encode this name as a URI.
Jeff Thompson3f2175b2013-07-31 17:12:47 -0700265 * @return The encoded URI.
Jeff Thompsone6063512013-07-01 15:11:28 -0700266 */
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700267 std::string
Jeff Thompson0050abe2013-09-17 12:50:25 -0700268 toUri() const;
Jeff Thompsond129ac12013-10-11 14:30:12 -0700269
270 /**
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700271 * @brief Append a component with the number encoded as nonNegativeInteger
272 *
273 * @see http://named-data.net/doc/ndn-tlv/tlv.html#non-negative-integer-encoding
274 *
Steve DiBenedettoc145d492014-03-11 16:35:45 -0600275 * @param number The non-negative number
276 * @return This name so that you can chain calls to append.
277 */
278 Name&
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700279 appendNumber(uint64_t number);
Steve DiBenedettoc145d492014-03-11 16:35:45 -0600280
Jeff Thompsonec7789a2013-08-21 11:08:36 -0700281 /**
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700282 * @brief Create a component encoded as NameComponentWithMarker
283 *
284 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
285 *
286 * @param marker 1-byte marker octet
287 * @param number The non-negative number
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700288 */
289 Name&
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700290 appendNumberWithMarker(uint8_t marker, uint64_t number);
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700291
292 /**
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700293 * @brief Append version using NDN naming conventions
294 *
295 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
296 */
297 Name&
298 appendVersion(uint64_t version);
299
300 /**
301 * @brief Append version using NDN naming conventions based on current UNIX timestamp
302 * in milliseconds
303 *
304 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700305 */
306 Name&
307 appendVersion();
308
309 /**
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700310 * @brief Append segment number (sequential) using NDN naming conventions
311 *
312 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700313 */
314 Name&
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700315 appendSegment(uint64_t segmentNo);
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700316
317 /**
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700318 * @brief Append segment byte offset using NDN naming conventions
319 *
320 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
321 */
322 Name&
323 appendSegmentOffset(uint64_t offset);
324
325 /**
326 * @brief Append timestamp using NDN naming conventions
327 *
328 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
329 */
330 Name&
331 appendTimestamp(const time::system_clock::TimePoint& timePoint = time::system_clock::now());
332
333 /**
334 * @brief Append sequence number using NDN naming conventions
335 *
336 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
337 */
338 Name&
339 appendSequenceNumber(uint64_t seqNo);
340
341 /**
Alexander Afanasyev6486d522014-10-23 14:14:11 -0700342 * @brief Append ImplicitSha256Digest
343 */
344 Name&
345 appendImplicitSha256Digest(const ConstBufferPtr& digest);
346
347 /**
348 * @brief Append ImplicitSha256Digest
349 */
350 Name&
351 appendImplicitSha256Digest(const uint8_t* digest, size_t digestSize);
352
353 /**
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700354 * @brief Get the successor of a name
355 *
356 * The successor of a name is defined as follows:
357 *
358 * N represents the set of NDN Names, and X,Y ∈ N.
359 * Operator < is defined by canonical order on N.
360 * Y is the successor of X, if (a) X < Y, and (b) ∄ Z ∈ N s.t. X < Z < Y.
361 *
362 * In plain words, successor of a name is the same name, but with its last component
363 * advanced to a next possible value.
364 *
365 * Examples:
366 *
367 * - successor for / is /%00
368 * - successor for /%00%01/%01%02 is /%00%01/%01%03
369 * - successor for /%00%01/%01%FF is /%00%01/%02%00
370 * - successor for /%00%01/%FF%FF is /%00%01/%00%00%00
371 *
Shuo Chen5aa8c742014-06-22 15:00:02 +0800372 * @return a new name
373 */
374 Name
375 getSuccessor() const;
376
377 /**
Jeff Thompson3c2ab012013-10-02 14:18:16 -0700378 * Check if this name has the same component count and components as the given name.
379 * @param name The Name to check.
380 * @return true if the names are equal, otherwise false.
381 */
382 bool
383 equals(const Name& name) const;
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700384
Jeff Thompson3c2ab012013-10-02 14:18:16 -0700385 /**
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700386 * @brief Check if the N components of this name are the same as the first N components
387 * of the given name.
388 *
Jeff Thompsonec7789a2013-08-21 11:08:36 -0700389 * @param name The Name to check.
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700390 * @return true if this matches the given name, otherwise false. This always returns
391 * true if this name is empty.
Jeff Thompsonec7789a2013-08-21 11:08:36 -0700392 */
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700393 bool
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800394 isPrefixOf(const Name& name) const;
395
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700396 //
397 // vector equivalent interface.
398 //
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800399
400 /**
401 * @brief Check if name is emtpy
402 */
403 bool
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700404 empty() const
405 {
406 return m_nameBlock.elements().empty();
407 }
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700408
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700409 /**
410 * Get the number of components.
411 * @return The number of components.
412 */
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700413 size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700414 size() const
415 {
416 return m_nameBlock.elements_size();
417 }
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700418
419 /**
420 * Get the component at the given index.
421 * @param i The index of the component, starting from 0.
422 * @return The name component at the index.
423 */
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700424 const Component&
Alexander Afanasyev8f9aa8b2013-12-30 15:58:57 -0800425 get(ssize_t i) const
426 {
427 if (i >= 0)
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800428 return reinterpret_cast<const Component&>(m_nameBlock.elements()[i]);
Alexander Afanasyev8f9aa8b2013-12-30 15:58:57 -0800429 else
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800430 return reinterpret_cast<const Component&>(m_nameBlock.elements()[size() + i]);
431 }
432
433 const Component&
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700434 operator[](ssize_t i) const
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800435 {
436 return get(i);
Alexander Afanasyev8f9aa8b2013-12-30 15:58:57 -0800437 }
Alexander Afanasyevc2344292014-03-02 00:08:00 +0000438
439 /**
440 * @brief Get component at the specified index
441 *
442 * Unlike get() and operator[] methods, at() checks for out of bounds
443 * and will throw Name::Error when it happens
444 *
445 * @throws Name::Error if index out of bounds
446 */
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800447 const Component&
448 at(ssize_t i) const
449 {
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700450 if ((i >= 0 && static_cast<size_t>(i) >= size()) ||
451 (i < 0 && static_cast<size_t>(-i) > size()))
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700452 BOOST_THROW_EXCEPTION(Error("Requested component does not exist (out of bounds)"));
Alexander Afanasyevc2344292014-03-02 00:08:00 +0000453
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800454 return get(i);
455 }
456
Jeff Thompsonafc45a92014-01-15 12:42:45 -0800457 /**
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700458 * @brief Compare this to the other Name using NDN canonical ordering.
Jeff Thompsonafc45a92014-01-15 12:42:45 -0800459 *
Joao Pereiraaa8fd162015-06-05 16:35:15 -0400460 * If the first components of each name are not equal, this returns a negative value if
461 * the first comes before the second using the NDN canonical ordering for name
462 * components, or a positive value if it comes after. If they are equal, this compares
463 * the second components of each name, etc. If both names are the same up to the size
464 * of the shorter name, this returns a negative value if the first name is shorter than
465 * the second or a positive value if it is longer. For example, if you std::sort gives:
466 * /a/b/d /a/b/cc /c /c/a /bb .
467 * This is intuitive because all names with the prefix /a are next to each other.
468 * But it may be also be counter-intuitive because /c comes before /bb according
469 * to NDN canonical ordering since it is shorter.
Junxiao Shia6452ac2015-01-23 11:21:06 -0700470 *
Joao Pereiraaa8fd162015-06-05 16:35:15 -0400471 * @param other The other Name to compare with.
472 *
473 * @retval negative this comes before other in canonical ordering
474 * @retval zero this equals other
475 * @retval positive this comes after other in canonical ordering
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700476 *
477 * @see http://named-data.net/doc/ndn-tlv/name.html#canonical-order
Jeff Thompsonafc45a92014-01-15 12:42:45 -0800478 */
479 int
Junxiao Shia6452ac2015-01-23 11:21:06 -0700480 compare(const Name& other) const
481 {
482 return this->compare(0, npos, other);
483 }
484
485 /** \brief compares [pos1, pos1+count1) components in this Name
486 * to [pos2, pos2+count2) components in \p other
487 *
488 * This is equivalent to this->getSubName(pos1, count1).compare(other.getSubName(pos2, count2));
489 */
490 int
491 compare(size_t pos1, size_t count1,
492 const Name& other, size_t pos2 = 0, size_t count2 = npos) const;
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700493
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700494 /**
495 * Append the component
496 * @param component The component of type T.
497 */
498 template<class T> void
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700499 push_back(const T& component)
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700500 {
501 append(component);
502 }
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700503
Jeff Thompson91737f52013-10-04 11:07:24 -0700504 /**
505 * Check if this name has the same component count and components as the given name.
506 * @param name The Name to check.
507 * @return true if the names are equal, otherwise false.
508 */
509 bool
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700510 operator==(const Name& name) const
511 {
512 return equals(name);
513 }
Jeff Thompson91737f52013-10-04 11:07:24 -0700514
515 /**
516 * Check if this name has the same component count and components as the given name.
517 * @param name The Name to check.
518 * @return true if the names are not equal, otherwise false.
519 */
520 bool
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700521 operator!=(const Name& name) const
522 {
523 return !equals(name);
524 }
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700525
Jeff Thompson82568ad2013-12-17 15:17:40 -0800526 /**
Jeff Thompsonafc45a92014-01-15 12:42:45 -0800527 * Return true if this is less than or equal to the other Name in the NDN canonical ordering.
528 * @param other The other Name to compare with.
529 *
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700530 * @see http://named-data.net/doc/ndn-tlv/name.html#canonical-order
Jeff Thompson82568ad2013-12-17 15:17:40 -0800531 */
Jeff Thompsonafc45a92014-01-15 12:42:45 -0800532 bool
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700533 operator<=(const Name& other) const
534 {
535 return compare(other) <= 0;
536 }
Jeff Thompsonafc45a92014-01-15 12:42:45 -0800537
538 /**
539 * Return true if this is less than the other Name in the NDN canonical ordering.
540 * @param other The other Name to compare with.
541 *
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700542 * @see http://named-data.net/doc/ndn-tlv/name.html#canonical-order
Jeff Thompsonafc45a92014-01-15 12:42:45 -0800543 */
544 bool
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700545 operator<(const Name& other) const
546 {
547 return compare(other) < 0;
548 }
Jeff Thompsonafc45a92014-01-15 12:42:45 -0800549
550 /**
551 * Return true if this is less than or equal to the other Name in the NDN canonical ordering.
552 * @param other The other Name to compare with.
553 *
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700554 * @see http://named-data.net/doc/ndn-tlv/name.html#canonical-order
Jeff Thompsonafc45a92014-01-15 12:42:45 -0800555 */
556 bool
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700557 operator>=(const Name& other) const
558 {
559 return compare(other) >= 0;
560 }
Jeff Thompsonafc45a92014-01-15 12:42:45 -0800561
562 /**
563 * Return true if this is greater than the other Name in the NDN canonical ordering.
564 * @param other The other Name to compare with.
565 *
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700566 * @see http://named-data.net/doc/ndn-tlv/name.html#canonical-order
Jeff Thompsonafc45a92014-01-15 12:42:45 -0800567 */
568 bool
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700569 operator>(const Name& other) const
570 {
571 return compare(other) > 0;
572 }
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700573
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700574 //
575 // Iterator interface to name components.
576 //
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700577
578 /**
579 * Begin iterator (const).
580 */
581 const_iterator
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800582 begin() const
583 {
584 return reinterpret_cast<const_iterator>(&*m_nameBlock.elements().begin());
585 }
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700586
587 /**
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700588 * End iterator (const).
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800589 *
590 * @todo Check if this crash when there are no elements in the buffer
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700591 */
592 const_iterator
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800593 end() const
594 {
595 return reinterpret_cast<const_iterator>(&*m_nameBlock.elements().end());
596 }
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700597
598 /**
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700599 * Reverse begin iterator (const).
600 */
601 const_reverse_iterator
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800602 rbegin() const
603 {
604 return const_reverse_iterator(end());
605 }
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700606
607 /**
608 * Reverse end iterator (const).
609 */
610 const_reverse_iterator
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800611 rend() const
612 {
613 return const_reverse_iterator(begin());
614 }
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700615
Alexander Afanasyevc89efb42015-02-10 18:26:42 -0800616private:
617 void
618 construct(const char* uri);
619
Junxiao Shia6452ac2015-01-23 11:21:06 -0700620public:
621 /** \brief indicates "until the end" in getSubName and compare
622 */
623 static const size_t npos;
624
Jeff Thompson9c41dfe2013-06-27 12:10:25 -0700625private:
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800626 mutable Block m_nameBlock;
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800627};
628
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700629std::ostream&
630operator<<(std::ostream& os, const Name& name);
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700631
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700632std::istream&
633operator>>(std::istream& is, Name& name);
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -0800634
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800635inline bool
636Name::hasWire() const
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -0800637{
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800638 return m_nameBlock.hasWire();
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -0800639}
640
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800641} // namespace ndn
Jeff Thompson9c41dfe2013-06-27 12:10:25 -0700642
Yingdi Yu90e23582014-11-06 14:21:04 -0800643namespace std {
644template<>
645struct hash<ndn::Name>
646{
647 size_t
648 operator()(const ndn::Name& name) const;
649};
650
651} // namespace std
652
Jeff Thompson9c41dfe2013-06-27 12:10:25 -0700653#endif