blob: 2cbab7d582c535cbc3871adb144601c0c85ba518 [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/**
Junxiao Shia6452ac2015-01-23 11:21:06 -07003 * Copyright (c) 2013-2015 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 /**
111 * @brief Fast encoding or block size estimation
112 */
Alexander Afanasyev74633892015-02-08 18:08:46 -0800113 template<encoding::Tag TAG>
Wentao Shang77949212014-02-01 23:42:24 -0800114 size_t
Alexander Afanasyev74633892015-02-08 18:08:46 -0800115 wireEncode(EncodingImpl<TAG>& block) const;
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700116
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700117 const Block&
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800118 wireEncode() const;
Alexander Afanasyev848c61a2014-01-03 13:52:04 -0800119
120 void
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700121 wireDecode(const Block& wire);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800122
123 /**
124 * @brief Check if already has wire
125 */
126 bool
127 hasWire() const;
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700128
Jeff Thompsonb468c312013-07-01 17:50:14 -0700129 /**
Alexander Afanasyevc89efb42015-02-10 18:26:42 -0800130 * @deprecated Use appropriate constructor
Jeff Thompson67515bd2013-08-15 17:43:22 -0700131 */
Alexander Afanasyevc89efb42015-02-10 18:26:42 -0800132 DEPRECATED(
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700133 void
Alexander Afanasyevc89efb42015-02-10 18:26:42 -0800134 set(const char* uri));
Jeff Thompson67515bd2013-08-15 17:43:22 -0700135
136 /**
Alexander Afanasyevc89efb42015-02-10 18:26:42 -0800137 * @deprecated Use appropriate constructor
Jeff Thompson7781b392013-12-17 11:45:59 -0800138 */
Alexander Afanasyevc89efb42015-02-10 18:26:42 -0800139 DEPRECATED(
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700140 void
Alexander Afanasyevc89efb42015-02-10 18:26:42 -0800141 set(const std::string& uri));
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700142
Jeff Thompson7781b392013-12-17 11:45:59 -0800143 /**
Alexander Afanasyevc89efb42015-02-10 18:26:42 -0800144 * @brief Append a new component, copying from value of length valueLength.
Jeff Thompson26b0d792013-09-23 16:19:01 -0700145 * @return This name so that you can chain calls to append.
Jeff Thompsone5f839b2013-06-28 12:50:38 -0700146 */
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700147 Name&
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700148 append(const uint8_t* value, size_t valueLength)
Jeff Thompson0f743452013-09-12 14:23:18 -0700149 {
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800150 m_nameBlock.push_back(Component(value, valueLength));
Jeff Thompson26b0d792013-09-23 16:19:01 -0700151 return *this;
Jeff Thompsone5f839b2013-06-28 12:50:38 -0700152 }
Jeff Thompsonf72b1ac2013-08-16 16:44:41 -0700153
Alexander Afanasyevbf9671d2014-02-11 13:44:13 -0800154 /**
Alexander Afanasyev74633892015-02-08 18:08:46 -0800155 * @brief Append a new component, copying from value frome the range [@p first, @p last) of bytes
156 * @param first Iterator pointing to the beginning of the buffer
157 * @param last Iterator pointing to the ending of the buffer
158 * @tparam Iterator iterator type satisfying at least InputIterator concept. Implementation
159 * is more optimal when the iterator type satisfies RandomAccessIterator concept.
160 * It is required that sizeof(std::iterator_traits<Iterator>::value_type) == 1.
Alexander Afanasyevbf9671d2014-02-11 13:44:13 -0800161 * @return This name so that you can chain calls to append.
162 */
Alexander Afanasyev74633892015-02-08 18:08:46 -0800163 template<class Iterator>
Alexander Afanasyevbf9671d2014-02-11 13:44:13 -0800164 Name&
Alexander Afanasyev74633892015-02-08 18:08:46 -0800165 append(Iterator first, Iterator last)
Alexander Afanasyevbf9671d2014-02-11 13:44:13 -0800166 {
Alexander Afanasyev74633892015-02-08 18:08:46 -0800167 m_nameBlock.push_back(Component(first, last));
Alexander Afanasyevbf9671d2014-02-11 13:44:13 -0800168 return *this;
169 }
170
Alexander Afanasyevc89efb42015-02-10 18:26:42 -0800171 /**
172 * @brief Append component @p value
173 */
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700174 Name&
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700175 append(const Component& value)
Jeff Thompson21eb7212013-09-26 09:05:40 -0700176 {
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800177 m_nameBlock.push_back(value);
Jeff Thompson21eb7212013-09-26 09:05:40 -0700178 return *this;
179 }
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800180
Alexander Afanasyev594cdb22014-01-03 15:11:33 -0800181 /**
182 * @brief Append name component that represented as a string
183 *
184 * Note that this method is necessary to ensure correctness and unambiguity of
185 * ``append("string")`` operations (both Component and Name can be implicitly
186 * converted from string, each having different outcomes
187 */
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700188 Name&
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700189 append(const char* value)
Alexander Afanasyev594cdb22014-01-03 15:11:33 -0800190 {
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800191 m_nameBlock.push_back(Component(value));
Alexander Afanasyev594cdb22014-01-03 15:11:33 -0800192 return *this;
193 }
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700194
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800195 Name&
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700196 append(const Block& value)
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800197 {
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600198 if (value.type() == tlv::NameComponent)
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800199 m_nameBlock.push_back(value);
Alexander Afanasyev380420b2014-02-09 20:52:29 -0800200 else
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600201 m_nameBlock.push_back(Block(tlv::NameComponent, value));
Alexander Afanasyev380420b2014-02-09 20:52:29 -0800202
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800203 return *this;
204 }
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700205
Jeff Thompsone5f839b2013-06-28 12:50:38 -0700206 /**
Joao Pereira6f7cfd02015-06-15 11:36:26 -0400207 * @brief append a PartialName to this Name.
208 * @param name the components to append
209 * @return this name
Jeff Thompson0aa66f22013-09-23 13:02:13 -0700210 */
Jeff Thompson26b0d792013-09-23 16:19:01 -0700211 Name&
Joao Pereira6f7cfd02015-06-15 11:36:26 -0400212 append(const PartialName& name);
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700213
Jeff Thompson0aa66f22013-09-23 13:02:13 -0700214 /**
Jeff Thompsone5f839b2013-06-28 12:50:38 -0700215 * Clear all the components.
216 */
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700217 void
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800218 clear()
219 {
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600220 m_nameBlock = Block(tlv::Name);
Jeff Thompsone5f839b2013-06-28 12:50:38 -0700221 }
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700222
Jeff Thompsone5f839b2013-06-28 12:50:38 -0700223 /**
Joao Pereira6f7cfd02015-06-15 11:36:26 -0400224 * @brief Extract a sub-name (PartialName) of @p nComponents components starting
225 * from @p iStartComponent
226 * @param iStartComponent index of the first component;
227 * if iStartComponent is negative, size()+iStartComponent is used instead
Jeff Thompsond0159d72013-09-23 13:34:15 -0700228 * @param nComponents The number of components starting at iStartComponent.
Joao Pereira6f7cfd02015-06-15 11:36:26 -0400229 * Use npos to get the Partial Name until the end of this Name.
230 * @detail If iStartComponent is out of bounds and is negative, will return the components
231 * starting in the beginning of the Name
232 * If iStartComponent is out of bounds and is positive, will return the component "/"
233 * If nComponents is out of bounds, will return the components until the end of
234 * this Name
235 * @return A new partial name
Jeff Thompsond0159d72013-09-23 13:34:15 -0700236 */
Joao Pereira6f7cfd02015-06-15 11:36:26 -0400237 PartialName
238 getSubName(ssize_t iStartComponent, size_t nComponents = npos) const;
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700239
Jeff Thompsond0159d72013-09-23 13:34:15 -0700240 /**
Joao Pereira6f7cfd02015-06-15 11:36:26 -0400241 * @brief Extract a prefix (PartialName) of the name, containing first @p nComponents components
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700242 *
243 * @param nComponents The number of prefix components. If nComponents is -N then return
244 * the prefix up to name.size() - N. For example getPrefix(-1)
245 * returns the name without the final component.
Joao Pereira6f7cfd02015-06-15 11:36:26 -0400246 * @return A new partial name
Jeff Thompsond0159d72013-09-23 13:34:15 -0700247 */
Joao Pereira6f7cfd02015-06-15 11:36:26 -0400248 PartialName
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700249 getPrefix(ssize_t nComponents) const
Jeff Thompsond0159d72013-09-23 13:34:15 -0700250 {
Jeff Thompsoneb0358f2013-12-17 10:59:53 -0800251 if (nComponents < 0)
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800252 return getSubName(0, m_nameBlock.elements_size() + nComponents);
Jeff Thompsoneb0358f2013-12-17 10:59:53 -0800253 else
254 return getSubName(0, nComponents);
Jeff Thompsond0159d72013-09-23 13:34:15 -0700255 }
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700256
Jeff Thompsond0159d72013-09-23 13:34:15 -0700257 /**
Jeff Thompsone6063512013-07-01 15:11:28 -0700258 * Encode this name as a URI.
Jeff Thompson3f2175b2013-07-31 17:12:47 -0700259 * @return The encoded URI.
Jeff Thompsone6063512013-07-01 15:11:28 -0700260 */
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700261 std::string
Jeff Thompson0050abe2013-09-17 12:50:25 -0700262 toUri() const;
Jeff Thompsond129ac12013-10-11 14:30:12 -0700263
264 /**
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700265 * @brief Append a component with the number encoded as nonNegativeInteger
266 *
267 * @see http://named-data.net/doc/ndn-tlv/tlv.html#non-negative-integer-encoding
268 *
Steve DiBenedettoc145d492014-03-11 16:35:45 -0600269 * @param number The non-negative number
270 * @return This name so that you can chain calls to append.
271 */
272 Name&
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700273 appendNumber(uint64_t number);
Steve DiBenedettoc145d492014-03-11 16:35:45 -0600274
Jeff Thompsonec7789a2013-08-21 11:08:36 -0700275 /**
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700276 * @brief Create a component encoded as NameComponentWithMarker
277 *
278 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
279 *
280 * @param marker 1-byte marker octet
281 * @param number The non-negative number
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700282 */
283 Name&
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700284 appendNumberWithMarker(uint8_t marker, uint64_t number);
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700285
286 /**
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700287 * @brief Append version using NDN naming conventions
288 *
289 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
290 */
291 Name&
292 appendVersion(uint64_t version);
293
294 /**
295 * @brief Append version using NDN naming conventions based on current UNIX timestamp
296 * in milliseconds
297 *
298 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700299 */
300 Name&
301 appendVersion();
302
303 /**
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700304 * @brief Append segment number (sequential) using NDN naming conventions
305 *
306 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700307 */
308 Name&
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700309 appendSegment(uint64_t segmentNo);
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700310
311 /**
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700312 * @brief Append segment byte offset using NDN naming conventions
313 *
314 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
315 */
316 Name&
317 appendSegmentOffset(uint64_t offset);
318
319 /**
320 * @brief Append timestamp using NDN naming conventions
321 *
322 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
323 */
324 Name&
325 appendTimestamp(const time::system_clock::TimePoint& timePoint = time::system_clock::now());
326
327 /**
328 * @brief Append sequence number using NDN naming conventions
329 *
330 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
331 */
332 Name&
333 appendSequenceNumber(uint64_t seqNo);
334
335 /**
Alexander Afanasyev6486d522014-10-23 14:14:11 -0700336 * @brief Append ImplicitSha256Digest
337 */
338 Name&
339 appendImplicitSha256Digest(const ConstBufferPtr& digest);
340
341 /**
342 * @brief Append ImplicitSha256Digest
343 */
344 Name&
345 appendImplicitSha256Digest(const uint8_t* digest, size_t digestSize);
346
347 /**
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700348 * @brief Get the successor of a name
349 *
350 * The successor of a name is defined as follows:
351 *
352 * N represents the set of NDN Names, and X,Y ∈ N.
353 * Operator < is defined by canonical order on N.
354 * Y is the successor of X, if (a) X < Y, and (b) ∄ Z ∈ N s.t. X < Z < Y.
355 *
356 * In plain words, successor of a name is the same name, but with its last component
357 * advanced to a next possible value.
358 *
359 * Examples:
360 *
361 * - successor for / is /%00
362 * - successor for /%00%01/%01%02 is /%00%01/%01%03
363 * - successor for /%00%01/%01%FF is /%00%01/%02%00
364 * - successor for /%00%01/%FF%FF is /%00%01/%00%00%00
365 *
Shuo Chen5aa8c742014-06-22 15:00:02 +0800366 * @return a new name
367 */
368 Name
369 getSuccessor() const;
370
371 /**
Jeff Thompson3c2ab012013-10-02 14:18:16 -0700372 * Check if this name has the same component count and components as the given name.
373 * @param name The Name to check.
374 * @return true if the names are equal, otherwise false.
375 */
376 bool
377 equals(const Name& name) const;
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700378
Jeff Thompson3c2ab012013-10-02 14:18:16 -0700379 /**
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700380 * @brief Check if the N components of this name are the same as the first N components
381 * of the given name.
382 *
Jeff Thompsonec7789a2013-08-21 11:08:36 -0700383 * @param name The Name to check.
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700384 * @return true if this matches the given name, otherwise false. This always returns
385 * true if this name is empty.
Jeff Thompsonec7789a2013-08-21 11:08:36 -0700386 */
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700387 bool
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800388 isPrefixOf(const Name& name) const;
389
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700390 //
391 // vector equivalent interface.
392 //
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800393
394 /**
395 * @brief Check if name is emtpy
396 */
397 bool
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700398 empty() const
399 {
400 return m_nameBlock.elements().empty();
401 }
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700402
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700403 /**
404 * Get the number of components.
405 * @return The number of components.
406 */
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700407 size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700408 size() const
409 {
410 return m_nameBlock.elements_size();
411 }
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700412
413 /**
414 * Get the component at the given index.
415 * @param i The index of the component, starting from 0.
416 * @return The name component at the index.
417 */
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700418 const Component&
Alexander Afanasyev8f9aa8b2013-12-30 15:58:57 -0800419 get(ssize_t i) const
420 {
421 if (i >= 0)
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800422 return reinterpret_cast<const Component&>(m_nameBlock.elements()[i]);
Alexander Afanasyev8f9aa8b2013-12-30 15:58:57 -0800423 else
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800424 return reinterpret_cast<const Component&>(m_nameBlock.elements()[size() + i]);
425 }
426
427 const Component&
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700428 operator[](ssize_t i) const
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800429 {
430 return get(i);
Alexander Afanasyev8f9aa8b2013-12-30 15:58:57 -0800431 }
Alexander Afanasyevc2344292014-03-02 00:08:00 +0000432
433 /**
434 * @brief Get component at the specified index
435 *
436 * Unlike get() and operator[] methods, at() checks for out of bounds
437 * and will throw Name::Error when it happens
438 *
439 * @throws Name::Error if index out of bounds
440 */
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800441 const Component&
442 at(ssize_t i) const
443 {
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700444 if ((i >= 0 && static_cast<size_t>(i) >= size()) ||
445 (i < 0 && static_cast<size_t>(-i) > size()))
Alexander Afanasyevc2344292014-03-02 00:08:00 +0000446 throw Error("Requested component does not exist (out of bounds)");
447
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800448 return get(i);
449 }
450
Jeff Thompsonafc45a92014-01-15 12:42:45 -0800451 /**
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700452 * @brief Compare this to the other Name using NDN canonical ordering.
Jeff Thompsonafc45a92014-01-15 12:42:45 -0800453 *
Joao Pereiraaa8fd162015-06-05 16:35:15 -0400454 * If the first components of each name are not equal, this returns a negative value if
455 * the first comes before the second using the NDN canonical ordering for name
456 * components, or a positive value if it comes after. If they are equal, this compares
457 * the second components of each name, etc. If both names are the same up to the size
458 * of the shorter name, this returns a negative value if the first name is shorter than
459 * the second or a positive value if it is longer. For example, if you std::sort gives:
460 * /a/b/d /a/b/cc /c /c/a /bb .
461 * This is intuitive because all names with the prefix /a are next to each other.
462 * But it may be also be counter-intuitive because /c comes before /bb according
463 * to NDN canonical ordering since it is shorter.
Junxiao Shia6452ac2015-01-23 11:21:06 -0700464 *
Joao Pereiraaa8fd162015-06-05 16:35:15 -0400465 * @param other The other Name to compare with.
466 *
467 * @retval negative this comes before other in canonical ordering
468 * @retval zero this equals other
469 * @retval positive this comes after other in canonical ordering
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700470 *
471 * @see http://named-data.net/doc/ndn-tlv/name.html#canonical-order
Jeff Thompsonafc45a92014-01-15 12:42:45 -0800472 */
473 int
Junxiao Shia6452ac2015-01-23 11:21:06 -0700474 compare(const Name& other) const
475 {
476 return this->compare(0, npos, other);
477 }
478
479 /** \brief compares [pos1, pos1+count1) components in this Name
480 * to [pos2, pos2+count2) components in \p other
481 *
482 * This is equivalent to this->getSubName(pos1, count1).compare(other.getSubName(pos2, count2));
483 */
484 int
485 compare(size_t pos1, size_t count1,
486 const Name& other, size_t pos2 = 0, size_t count2 = npos) const;
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700487
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700488 /**
489 * Append the component
490 * @param component The component of type T.
491 */
492 template<class T> void
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700493 push_back(const T& component)
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700494 {
495 append(component);
496 }
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700497
Jeff Thompson91737f52013-10-04 11:07:24 -0700498 /**
499 * Check if this name has the same component count and components as the given name.
500 * @param name The Name to check.
501 * @return true if the names are equal, otherwise false.
502 */
503 bool
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700504 operator==(const Name& name) const
505 {
506 return equals(name);
507 }
Jeff Thompson91737f52013-10-04 11:07:24 -0700508
509 /**
510 * Check if this name has the same component count and components as the given name.
511 * @param name The Name to check.
512 * @return true if the names are not equal, otherwise false.
513 */
514 bool
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700515 operator!=(const Name& name) const
516 {
517 return !equals(name);
518 }
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700519
Jeff Thompson82568ad2013-12-17 15:17:40 -0800520 /**
Jeff Thompsonafc45a92014-01-15 12:42:45 -0800521 * Return true if this is less than or equal to the other Name in the NDN canonical ordering.
522 * @param other The other Name to compare with.
523 *
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700524 * @see http://named-data.net/doc/ndn-tlv/name.html#canonical-order
Jeff Thompson82568ad2013-12-17 15:17:40 -0800525 */
Jeff Thompsonafc45a92014-01-15 12:42:45 -0800526 bool
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700527 operator<=(const Name& other) const
528 {
529 return compare(other) <= 0;
530 }
Jeff Thompsonafc45a92014-01-15 12:42:45 -0800531
532 /**
533 * Return true if this is less than the other Name in the NDN canonical ordering.
534 * @param other The other Name to compare with.
535 *
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700536 * @see http://named-data.net/doc/ndn-tlv/name.html#canonical-order
Jeff Thompsonafc45a92014-01-15 12:42:45 -0800537 */
538 bool
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700539 operator<(const Name& other) const
540 {
541 return compare(other) < 0;
542 }
Jeff Thompsonafc45a92014-01-15 12:42:45 -0800543
544 /**
545 * Return true if this is less than or equal to the other Name in the NDN canonical ordering.
546 * @param other The other Name to compare with.
547 *
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700548 * @see http://named-data.net/doc/ndn-tlv/name.html#canonical-order
Jeff Thompsonafc45a92014-01-15 12:42:45 -0800549 */
550 bool
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700551 operator>=(const Name& other) const
552 {
553 return compare(other) >= 0;
554 }
Jeff Thompsonafc45a92014-01-15 12:42:45 -0800555
556 /**
557 * Return true if this is greater than the other Name in the NDN canonical ordering.
558 * @param other The other Name to compare with.
559 *
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700560 * @see http://named-data.net/doc/ndn-tlv/name.html#canonical-order
Jeff Thompsonafc45a92014-01-15 12:42:45 -0800561 */
562 bool
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700563 operator>(const Name& other) const
564 {
565 return compare(other) > 0;
566 }
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700567
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700568 //
569 // Iterator interface to name components.
570 //
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700571
572 /**
573 * Begin iterator (const).
574 */
575 const_iterator
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800576 begin() const
577 {
578 return reinterpret_cast<const_iterator>(&*m_nameBlock.elements().begin());
579 }
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700580
581 /**
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700582 * End iterator (const).
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800583 *
584 * @todo Check if this crash when there are no elements in the buffer
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700585 */
586 const_iterator
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800587 end() const
588 {
589 return reinterpret_cast<const_iterator>(&*m_nameBlock.elements().end());
590 }
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700591
592 /**
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700593 * Reverse begin iterator (const).
594 */
595 const_reverse_iterator
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800596 rbegin() const
597 {
598 return const_reverse_iterator(end());
599 }
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700600
601 /**
602 * Reverse end iterator (const).
603 */
604 const_reverse_iterator
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800605 rend() const
606 {
607 return const_reverse_iterator(begin());
608 }
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700609
Alexander Afanasyevc89efb42015-02-10 18:26:42 -0800610private:
611 void
612 construct(const char* uri);
613
Junxiao Shia6452ac2015-01-23 11:21:06 -0700614public:
615 /** \brief indicates "until the end" in getSubName and compare
616 */
617 static const size_t npos;
618
Jeff Thompson9c41dfe2013-06-27 12:10:25 -0700619private:
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800620 mutable Block m_nameBlock;
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800621};
622
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700623std::ostream&
624operator<<(std::ostream& os, const Name& name);
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700625
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700626std::istream&
627operator>>(std::istream& is, Name& name);
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -0800628
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800629inline bool
630Name::hasWire() const
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -0800631{
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800632 return m_nameBlock.hasWire();
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -0800633}
634
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800635} // namespace ndn
Jeff Thompson9c41dfe2013-06-27 12:10:25 -0700636
Yingdi Yu90e23582014-11-06 14:21:04 -0800637namespace std {
638template<>
639struct hash<ndn::Name>
640{
641 size_t
642 operator()(const ndn::Name& name) const;
643};
644
645} // namespace std
646
Jeff Thompson9c41dfe2013-06-27 12:10:25 -0700647#endif