blob: 78bdfd7926c7db8ec746c4f5a15359aab89630d5 [file] [log] [blame]
Jeff Thompson25b4e612013-10-10 16:03:24 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
Jeff Thompson47eecfc2013-07-07 22:56:46 -07002/**
Jeff Thompson7687dc02013-09-13 11:54:07 -07003 * Copyright (C) 2013 Regents of the University of California.
4 * @author: Jeff Thompson <jefft0@remap.ucla.edu>
Jeff Thompsonec39fbd2013-10-04 10:56:23 -07005 * @author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
6 * @author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
Jeff Thompson47eecfc2013-07-07 22:56:46 -07007 * See COPYING for copyright and distribution information.
Jeff Thompson9c41dfe2013-06-27 12:10:25 -07008 */
9
10#ifndef NDN_NAME_HPP
Jeff Thompson2d27e2f2013-08-09 12:55:00 -070011#define NDN_NAME_HPP
Jeff Thompson9c41dfe2013-06-27 12:10:25 -070012
13#include <vector>
Jeff Thompson443398d2013-07-02 19:45:46 -070014#include <string>
Jeff Thompsonec7789a2013-08-21 11:08:36 -070015#include <sstream>
Alexander Afanasyevaf283d82014-01-03 13:23:34 -080016#include <string.h>
17#include "encoding/block.hpp"
Wentao Shang77949212014-02-01 23:42:24 -080018#include "encoding/encoding-buffer.hpp"
Jeff Thompson25b4e612013-10-10 16:03:24 -070019
Jeff Thompson9c41dfe2013-06-27 12:10:25 -070020namespace ndn {
Jeff Thompson5a6b5ab2013-08-05 15:43:47 -070021
Jeff Thompsonc7d65502013-11-06 17:22:26 -080022/**
23 * A Name holds an array of Name::Component and represents an NDN name.
24 */
Alexander Afanasyevb790d952014-01-24 12:07:53 -080025class Name : public ptr_lib::enable_shared_from_this<Name> {
Jeff Thompson9c41dfe2013-06-27 12:10:25 -070026public:
Jeff Thompsonc1c12e42013-09-13 19:08:45 -070027 /**
Jeff Thompsonc7d65502013-11-06 17:22:26 -080028 * A Name::Component holds a read-only name component value.
Jeff Thompsonc1c12e42013-09-13 19:08:45 -070029 */
Alexander Afanasyev58743332014-01-12 13:24:42 -080030 class Component
Alexander Afanasyevaf283d82014-01-03 13:23:34 -080031 {
Jeff Thompson5a6b5ab2013-08-05 15:43:47 -070032 public:
33 /**
Jeff Thompson46411c92013-09-13 19:31:25 -070034 * Create a new Name::Component with a null value.
Jeff Thompson5a6b5ab2013-08-05 15:43:47 -070035 */
36 Component()
37 {
38 }
Alexander Afanasyevaf283d82014-01-03 13:23:34 -080039
40 // copy constructor OK
41
42 /**
43 * Create a new Name::Component, taking another pointer to the Blob value.
44 * @param value A blob with a pointer to an immutable array. The pointer is copied.
45 */
46 Component(const ConstBufferPtr &buffer)
Alexander Afanasyev58743332014-01-12 13:24:42 -080047 : value_ (buffer)
Alexander Afanasyevaf283d82014-01-03 13:23:34 -080048 {
49 }
Jeff Thompson5a6b5ab2013-08-05 15:43:47 -070050
51 /**
52 * Create a new Name::Component, copying the given value.
53 * @param value The value byte array.
54 */
Alexander Afanasyevaf283d82014-01-03 13:23:34 -080055 Component(const Buffer& value)
Alexander Afanasyev58743332014-01-12 13:24:42 -080056 : value_ (new Buffer(value))
Jeff Thompson5a6b5ab2013-08-05 15:43:47 -070057 {
58 }
59
60 /**
61 * Create a new Name::Component, copying the given value.
62 * @param value Pointer to the value byte array.
63 * @param valueLen Length of value.
64 */
Jeff Thompson97223af2013-09-24 17:01:27 -070065 Component(const uint8_t *value, size_t valueLen)
Alexander Afanasyev58743332014-01-12 13:24:42 -080066 : value_ (new Buffer(value, valueLen))
Alexander Afanasyevaf283d82014-01-03 13:23:34 -080067 {
68 }
69
70 template<class InputIterator>
71 Component(InputIterator begin, InputIterator end)
Alexander Afanasyev58743332014-01-12 13:24:42 -080072 : value_ (new Buffer(begin, end))
Jeff Thompson5a6b5ab2013-08-05 15:43:47 -070073 {
74 }
Jeff Thompson0f743452013-09-12 14:23:18 -070075
Alexander Afanasyev848c61a2014-01-03 13:52:04 -080076 Component(const char *string)
Alexander Afanasyev58743332014-01-12 13:24:42 -080077 : value_ (new Buffer(string, ::strlen(string)))
Alexander Afanasyev848c61a2014-01-03 13:52:04 -080078 {
79 }
80
Alexander Afanasyevaf283d82014-01-03 13:23:34 -080081 const Buffer&
Alexander Afanasyev58743332014-01-12 13:24:42 -080082 getValue() const { return *value_; }
Jeff Thompson6653b0b2013-09-23 12:32:39 -070083
84 /**
85 * Write this component value to result, escaping characters according to the NDN URI Scheme.
86 * This also adds "..." to a value with zero or more ".".
Jeff Thompson6653b0b2013-09-23 12:32:39 -070087 * @param result the string stream to write to.
88 */
89 void
Alexander Afanasyevaf283d82014-01-03 13:23:34 -080090 toEscapedString(std::ostream& result) const
Jeff Thompson6653b0b2013-09-23 12:32:39 -070091 {
Alexander Afanasyev58743332014-01-12 13:24:42 -080092 Name::toEscapedString(*value_, result);
Jeff Thompson6653b0b2013-09-23 12:32:39 -070093 }
94
95 /**
96 * Convert this component value by escaping characters according to the NDN URI Scheme.
97 * This also adds "..." to a value with zero or more ".".
98 * @return The escaped string.
99 */
100 std::string
Jeff Thompsond0159d72013-09-23 13:34:15 -0700101 toEscapedString() const
Jeff Thompson6653b0b2013-09-23 12:32:39 -0700102 {
Alexander Afanasyev58743332014-01-12 13:24:42 -0800103 return Name::toEscapedString(*value_);
Jeff Thompson6653b0b2013-09-23 12:32:39 -0700104 }
Jeff Thompson9bdb3b22013-09-12 12:42:13 -0700105
Jeff Thompson50b37912013-10-08 13:39:33 -0700106 /**
107 * Interpret this name component as a network-ordered number and return an integer.
108 * @return The integer number.
109 */
110 uint64_t
Jeff Thompson25b4e612013-10-10 16:03:24 -0700111 toNumber() const;
Jeff Thompson27cae532013-10-08 12:52:41 -0700112
Jeff Thompson50b37912013-10-08 13:39:33 -0700113 /**
114 * Interpret this name component as a network-ordered number with a marker and return an integer.
115 * @param marker The required first byte of the component.
116 * @return The integer number.
117 * @throw runtime_error If the first byte of the component does not equal the marker.
118 */
119 uint64_t
120 toNumberWithMarker(uint8_t marker) const;
121
122 /**
123 * Interpret this name component as a segment number according to NDN name conventions (a network-ordered number
124 * where the first byte is the marker 0x00).
125 * @return The integer segment number.
126 * @throw runtime_error If the first byte of the component is not the expected marker.
127 */
128 uint64_t
129 toSegment() const
130 {
131 return toNumberWithMarker(0x00);
132 }
133
134 /**
135 * @deprecated Use toSegment.
136 */
137 uint64_t
138 toSeqNum() const
139 {
140 return toSegment();
141 }
142
143 /**
144 * Interpret this name component as a version number according to NDN name conventions (a network-ordered number
145 * where the first byte is the marker 0xFD). Note that this returns the exact number from the component
146 * without converting it to a time representation.
147 * @return The integer segment number.
148 * @throw runtime_error If the first byte of the component is not the expected marker.
149 */
150 uint64_t
151 toVersion() const
152 {
153 return toNumberWithMarker(0xFD);
154 }
Jeff Thompson27cae532013-10-08 12:52:41 -0700155
Jeff Thompsonc1c12e42013-09-13 19:08:45 -0700156 /**
Jeff Thompsond129ac12013-10-11 14:30:12 -0700157 * Create a component whose value is the network-ordered encoding of the number.
158 * Note: if the number is zero, the result is empty.
159 * @param number The number to be encoded.
160 * @return The component value.
161 */
162 static Component
163 fromNumber(uint64_t number);
Jeff Thompson8aac1992013-08-12 17:26:02 -0700164
165 /**
Jeff Thompsond129ac12013-10-11 14:30:12 -0700166 * Create a component whose value is the marker appended with the network-ordered encoding of the number.
167 * Note: if the number is zero, no bytes are used for the number - the result will have only the marker.
168 * @param number The number to be encoded.
169 * @param marker The marker to use as the first byte of the component.
170 * @return The component value.
Jeff Thompson8aac1992013-08-12 17:26:02 -0700171 */
Jeff Thompsond129ac12013-10-11 14:30:12 -0700172 static Component
173 fromNumberWithMarker(uint64_t number, uint8_t marker);
Jeff Thompsona98000c2013-12-16 14:40:09 -0800174
175 /**
176 * Check if this is the same component as other.
177 * @param other The other Component to compare with.
178 * @return true if the components are equal, otherwise false.
179 */
180 bool
181 equals(const Component& other) const
182 {
Alexander Afanasyev58743332014-01-12 13:24:42 -0800183 return *value_ == *other.value_;
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800184 }
185
186 bool
187 empty() const
188 {
Alexander Afanasyev58743332014-01-12 13:24:42 -0800189 return !value_ || value_->empty();
Jeff Thompsona98000c2013-12-16 14:40:09 -0800190 }
191
192 /**
193 * Check if this is the same component as other.
194 * @param other The other Component to compare with.
195 * @return true if the components are equal, otherwise false.
196 */
197 bool
198 operator == (const Component& other) const { return equals(other); }
199
200 /**
201 * Check if this is not the same component as other.
202 * @param other The other Component to compare with.
203 * @return true if the components are not equal, otherwise false.
204 */
205 bool
206 operator != (const Component& other) const { return !equals(other); }
207
208 /**
209 * Compare this to the other Component using NDN canonical ordering.
210 * @param other The other Component to compare with.
211 * @return 0 If they compare equal, -1 if *this comes before other in the canonical ordering, or
212 * 1 if *this comes after other in the canonical ordering.
213 *
214 * @see http://named-data.net/doc/0.2/technical/CanonicalOrder.html
215 */
216 int
217 compare(const Component& other) const;
Jeff Thompson5a6b5ab2013-08-05 15:43:47 -0700218
Jeff Thompsona98000c2013-12-16 14:40:09 -0800219 /**
220 * Return true if this is less than or equal to the other Component in the NDN canonical ordering.
221 * @param other The other Component to compare with.
222 *
223 * @see http://named-data.net/doc/0.2/technical/CanonicalOrder.html
224 */
225 bool
226 operator <= (const Component& other) const { return compare(other) <= 0; }
227
228 /**
229 * Return true if this is less than the other Component in the NDN canonical ordering.
230 * @param other The other Component to compare with.
231 *
232 * @see http://named-data.net/doc/0.2/technical/CanonicalOrder.html
233 */
234 bool
235 operator < (const Component& other) const { return compare(other) < 0; }
236
237 /**
238 * Return true if this is less than or equal to the other Component in the NDN canonical ordering.
239 * @param other The other Component to compare with.
240 *
241 * @see http://named-data.net/doc/0.2/technical/CanonicalOrder.html
242 */
243 bool
244 operator >= (const Component& other) const { return compare(other) >= 0; }
245
246 /**
247 * Return true if this is greater than the other Component in the NDN canonical ordering.
248 * @param other The other Component to compare with.
249 *
250 * @see http://named-data.net/doc/0.2/technical/CanonicalOrder.html
251 */
252 bool
253 operator > (const Component& other) const { return compare(other) > 0; }
Wentao Shang77949212014-02-01 23:42:24 -0800254
255 inline size_t
256 wireEncode (EncodingBuffer& blk);
257
Alexander Afanasyev58743332014-01-12 13:24:42 -0800258 private:
259 ConstBufferPtr value_;
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800260 };
Jeff Thompsona98000c2013-12-16 14:40:09 -0800261
Jeff Thompson443398d2013-07-02 19:45:46 -0700262 /**
263 * Create a new Name with no components.
264 */
Jeff Thompson016ed642013-07-02 14:39:06 -0700265 Name() {
266 }
Jeff Thompson443398d2013-07-02 19:45:46 -0700267
268 /**
Jeff Thompson3f2175b2013-07-31 17:12:47 -0700269 * Create a new Name, copying the name components.
Jeff Thompson5a6b5ab2013-08-05 15:43:47 -0700270 * @param components A vector of Component
Jeff Thompson3f2175b2013-07-31 17:12:47 -0700271 */
Jeff Thompson1656e6a2013-08-29 18:01:48 -0700272 Name(const std::vector<Component>& components)
Jeff Thompson3f2175b2013-07-31 17:12:47 -0700273 : components_(components)
274 {
275 }
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800276
277 Name(const Block &name)
278 {
279 for (Block::element_const_iterator i = name.getAll().begin();
280 i != name.getAll().end();
281 ++i)
282 {
283 append(Component(i->value_begin(), i->value_end()));
284 }
285 }
Jeff Thompson3f2175b2013-07-31 17:12:47 -0700286
287 /**
Jeff Thompson443398d2013-07-02 19:45:46 -0700288 * Parse the uri according to the NDN URI Scheme and create the name with the components.
Jeff Thompson3f2175b2013-07-31 17:12:47 -0700289 * @param uri The URI string.
Jeff Thompson443398d2013-07-02 19:45:46 -0700290 */
Jeff Thompson3549ef32013-09-25 14:05:17 -0700291 Name(const char* uri)
Jeff Thompson67515bd2013-08-15 17:43:22 -0700292 {
293 set(uri);
294 }
Jeff Thompson5a6b5ab2013-08-05 15:43:47 -0700295
Jeff Thompsone5f839b2013-06-28 12:50:38 -0700296 /**
Jeff Thompson3549ef32013-09-25 14:05:17 -0700297 * Parse the uri according to the NDN URI Scheme and create the name with the components.
298 * @param uri The URI string.
299 */
300 Name(const std::string& uri)
301 {
302 set(uri.c_str());
303 }
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700304
Wentao Shang77949212014-02-01 23:42:24 -0800305 size_t
306 wireEncode (EncodingBuffer& blk);
307
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800308 const Block &
309 wireEncode() const;
Alexander Afanasyev848c61a2014-01-03 13:52:04 -0800310
311 void
312 wireDecode(const Block &wire);
Jeff Thompsonb468c312013-07-01 17:50:14 -0700313
314 /**
Jeff Thompson67515bd2013-08-15 17:43:22 -0700315 * Parse the uri according to the NDN URI Scheme and set the name with the components.
Jeff Thompson7781b392013-12-17 11:45:59 -0800316 * @param uri The null-terminated URI string.
Jeff Thompson67515bd2013-08-15 17:43:22 -0700317 */
Jeff Thompson0050abe2013-09-17 12:50:25 -0700318 void
319 set(const char *uri);
Jeff Thompson67515bd2013-08-15 17:43:22 -0700320
321 /**
Jeff Thompson7781b392013-12-17 11:45:59 -0800322 * Parse the uri according to the NDN URI Scheme and set the name with the components.
323 * @param uri The URI string.
324 */
325 void
326 set(const std::string& uri) { set(uri.c_str()); }
327
328 /**
Jeff Thompson0aa66f22013-09-23 13:02:13 -0700329 * Append a new component, copying from value of length valueLength.
Jeff Thompson26b0d792013-09-23 16:19:01 -0700330 * @return This name so that you can chain calls to append.
Jeff Thompsone5f839b2013-06-28 12:50:38 -0700331 */
Jeff Thompson26b0d792013-09-23 16:19:01 -0700332 Name&
Jeff Thompson97223af2013-09-24 17:01:27 -0700333 append(const uint8_t *value, size_t valueLength)
Jeff Thompson0f743452013-09-12 14:23:18 -0700334 {
Jeff Thompson5a6b5ab2013-08-05 15:43:47 -0700335 components_.push_back(Component(value, valueLength));
Jeff Thompson26b0d792013-09-23 16:19:01 -0700336 return *this;
Jeff Thompsone5f839b2013-06-28 12:50:38 -0700337 }
Jeff Thompsonf72b1ac2013-08-16 16:44:41 -0700338
339 /**
Jeff Thompson0aa66f22013-09-23 13:02:13 -0700340 * Append a new component, copying from value.
Jeff Thompson26b0d792013-09-23 16:19:01 -0700341 * @return This name so that you can chain calls to append.
Jeff Thompsonf72b1ac2013-08-16 16:44:41 -0700342 */
Jeff Thompson26b0d792013-09-23 16:19:01 -0700343 Name&
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800344 append(const Buffer& value)
Jeff Thompson0f743452013-09-12 14:23:18 -0700345 {
346 components_.push_back(value);
Jeff Thompson26b0d792013-09-23 16:19:01 -0700347 return *this;
Jeff Thompson0f743452013-09-12 14:23:18 -0700348 }
349
Jeff Thompson26b0d792013-09-23 16:19:01 -0700350 Name&
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800351 append(const ConstBufferPtr &value)
Jeff Thompson0f743452013-09-12 14:23:18 -0700352 {
Jeff Thompsonf72b1ac2013-08-16 16:44:41 -0700353 components_.push_back(value);
Jeff Thompson26b0d792013-09-23 16:19:01 -0700354 return *this;
Jeff Thompsonf72b1ac2013-08-16 16:44:41 -0700355 }
Jeff Thompsone5f839b2013-06-28 12:50:38 -0700356
Jeff Thompson21eb7212013-09-26 09:05:40 -0700357 Name&
358 append(const Component &value)
359 {
360 components_.push_back(value);
361 return *this;
362 }
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800363
Alexander Afanasyev594cdb22014-01-03 15:11:33 -0800364 /**
365 * @brief Append name component that represented as a string
366 *
367 * Note that this method is necessary to ensure correctness and unambiguity of
368 * ``append("string")`` operations (both Component and Name can be implicitly
369 * converted from string, each having different outcomes
370 */
371 Name&
372 append(const char *value)
373 {
374 components_.push_back(Component(value));
375 return *this;
376 }
377
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800378 Name&
379 append(const Block &value)
380 {
381 components_.push_back(Component(value.begin(), value.end()));
382 return *this;
383 }
Jeff Thompson21eb7212013-09-26 09:05:40 -0700384
Jeff Thompsone5f839b2013-06-28 12:50:38 -0700385 /**
Jeff Thompson26b0d792013-09-23 16:19:01 -0700386 * Append the components of the given name to this name.
387 * @param name The Name with components to append.
388 * @return This name so that you can chain calls to append.
Jeff Thompson0aa66f22013-09-23 13:02:13 -0700389 */
Jeff Thompson26b0d792013-09-23 16:19:01 -0700390 Name&
391 append(const Name& name);
392
393 /**
394 * @deprecated Use append.
395 */
396 Name&
Jeff Thompson97223af2013-09-24 17:01:27 -0700397 appendComponent(const uint8_t *value, size_t valueLength)
Jeff Thompson0aa66f22013-09-23 13:02:13 -0700398 {
Jeff Thompson26b0d792013-09-23 16:19:01 -0700399 return append(value, valueLength);
Jeff Thompson0aa66f22013-09-23 13:02:13 -0700400 }
401
402 /**
Jeff Thompson26b0d792013-09-23 16:19:01 -0700403 * @deprecated Use append.
Jeff Thompson0aa66f22013-09-23 13:02:13 -0700404 */
Jeff Thompson26b0d792013-09-23 16:19:01 -0700405 Name&
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800406 appendComponent(const Buffer& value)
Jeff Thompson0aa66f22013-09-23 13:02:13 -0700407 {
Jeff Thompson26b0d792013-09-23 16:19:01 -0700408 return append(value);
Jeff Thompson0aa66f22013-09-23 13:02:13 -0700409 }
410
411 /**
Jeff Thompson26b0d792013-09-23 16:19:01 -0700412 * @deprecated Use append.
Jeff Thompson0aa66f22013-09-23 13:02:13 -0700413 */
Jeff Thompson26b0d792013-09-23 16:19:01 -0700414 Name&
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800415 appendComponent(const ConstBufferPtr &value)
Jeff Thompson26b0d792013-09-23 16:19:01 -0700416 {
417 return append(value);
418 }
419
420 /**
421 * @deprecated Use append.
422 */
423 Name&
Jeff Thompson97223af2013-09-24 17:01:27 -0700424 addComponent(const uint8_t *value, size_t valueLength)
Jeff Thompson26b0d792013-09-23 16:19:01 -0700425 {
426 return append(value, valueLength);
427 }
428
429 /**
430 * @deprecated Use append.
431 */
432 Name&
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800433 addComponent(const Buffer& value)
Jeff Thompson26b0d792013-09-23 16:19:01 -0700434 {
435 return append(value);
436 }
437
438 /**
439 * @deprecated Use append.
440 */
441 Name&
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800442 addComponent(const ConstBufferPtr &value)
Jeff Thompson0aa66f22013-09-23 13:02:13 -0700443 {
Jeff Thompson26b0d792013-09-23 16:19:01 -0700444 return append(value);
Jeff Thompson0aa66f22013-09-23 13:02:13 -0700445 }
446
447 /**
Jeff Thompsone5f839b2013-06-28 12:50:38 -0700448 * Clear all the components.
449 */
Jeff Thompson0050abe2013-09-17 12:50:25 -0700450 void
451 clear() {
Jeff Thompsone5f839b2013-06-28 12:50:38 -0700452 components_.clear();
453 }
454
455 /**
Jeff Thompsoneba62eb2013-10-30 13:24:22 -0700456 * @deprecated use size().
Jeff Thompsone5f839b2013-06-28 12:50:38 -0700457 */
Jeff Thompson97223af2013-09-24 17:01:27 -0700458 size_t
Jeff Thompsoneba62eb2013-10-30 13:24:22 -0700459 getComponentCount() const { return size(); }
Jeff Thompsone5f839b2013-06-28 12:50:38 -0700460
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700461 /**
Jeff Thompsoneba62eb2013-10-30 13:24:22 -0700462 * @deprecated Use get(i).
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700463 */
Jeff Thompson0050abe2013-09-17 12:50:25 -0700464 const Component&
Jeff Thompsoneba62eb2013-10-30 13:24:22 -0700465 getComponent(size_t i) const { return get(i); }
Jeff Thompson443398d2013-07-02 19:45:46 -0700466
Jeff Thompsone6063512013-07-01 15:11:28 -0700467 /**
Jeff Thompsond0159d72013-09-23 13:34:15 -0700468 * Get a new name, constructed as a subset of components.
469 * @param iStartComponent The index if the first component to get.
470 * @param nComponents The number of components starting at iStartComponent.
471 * @return A new name.
472 */
473 Name
474 getSubName(size_t iStartComponent, size_t nComponents) const;
475
476 /**
477 * Get a new name, constructed as a subset of components starting at iStartComponent until the end of the name.
478 * @param iStartComponent The index if the first component to get.
479 * @return A new name.
480 */
481 Name
482 getSubName(size_t iStartComponent) const;
483
484 /**
485 * Return a new Name with the first nComponents components of this Name.
Jeff Thompsoneb0358f2013-12-17 10:59:53 -0800486 * @param nComponents The number of prefix components. If nComponents is -N then return the prefix up
487 * to name.size() - N. For example getPrefix(-1) returns the name without the final component.
Jeff Thompsond0159d72013-09-23 13:34:15 -0700488 * @return A new Name.
489 */
490 Name
Jeff Thompsoneb0358f2013-12-17 10:59:53 -0800491 getPrefix(int nComponents) const
Jeff Thompsond0159d72013-09-23 13:34:15 -0700492 {
Jeff Thompsoneb0358f2013-12-17 10:59:53 -0800493 if (nComponents < 0)
494 return getSubName(0, components_.size() + nComponents);
495 else
496 return getSubName(0, nComponents);
Jeff Thompsond0159d72013-09-23 13:34:15 -0700497 }
498
499 /**
Jeff Thompsone6063512013-07-01 15:11:28 -0700500 * Encode this name as a URI.
Jeff Thompson3f2175b2013-07-31 17:12:47 -0700501 * @return The encoded URI.
Jeff Thompsone6063512013-07-01 15:11:28 -0700502 */
Jeff Thompson0050abe2013-09-17 12:50:25 -0700503 std::string
504 toUri() const;
Jeff Thompsone6063512013-07-01 15:11:28 -0700505
Jeff Thompson21844fc2013-08-08 14:52:51 -0700506 /**
Jeff Thompson8aac1992013-08-12 17:26:02 -0700507 * Append a component with the encoded segment number.
508 * @param segment The segment number.
Jeff Thompson26b0d792013-09-23 16:19:01 -0700509 * @return This name so that you can chain calls to append.
510 */
511 Name&
Jeff Thompsond129ac12013-10-11 14:30:12 -0700512 appendSegment(uint64_t segment)
Jeff Thompson8aac1992013-08-12 17:26:02 -0700513 {
Jeff Thompsond129ac12013-10-11 14:30:12 -0700514 components_.push_back(Component::fromNumberWithMarker(segment, 0x00));
515 return *this;
516 }
517
518 /**
519 * Append a component with the encoded version number.
520 * Note that this encodes the exact value of version without converting from a time representation.
521 * @param version The version number.
522 * @return This name so that you can chain calls to append.
523 */
524 Name&
525 appendVersion(uint64_t version)
526 {
527 components_.push_back(Component::fromNumberWithMarker(version, 0xFD));
Jeff Thompson26b0d792013-09-23 16:19:01 -0700528 return *this;
Jeff Thompson8aac1992013-08-12 17:26:02 -0700529 }
Alexander Afanasyev594cdb22014-01-03 15:11:33 -0800530
531 /**
532 * @brief Append a component with the encoded version number.
533 *
534 * This version of the method creates version number based on the current timestamp
535 * @return This name so that you can chain calls to append.
536 */
537 Name&
538 appendVersion();
Jeff Thompsoncc35cd42013-08-20 12:23:14 -0700539
Jeff Thompsonec7789a2013-08-21 11:08:36 -0700540 /**
Jeff Thompson3c2ab012013-10-02 14:18:16 -0700541 * Check if this name has the same component count and components as the given name.
542 * @param name The Name to check.
543 * @return true if the names are equal, otherwise false.
544 */
545 bool
546 equals(const Name& name) const;
547
548 /**
Jeff Thompsonec7789a2013-08-21 11:08:36 -0700549 * Check if the N components of this name are the same as the first N components of the given name.
550 * @param name The Name to check.
551 * @return true if this matches the given name, otherwise false. This always returns true if this name is empty.
552 */
Jeff Thompson0050abe2013-09-17 12:50:25 -0700553 bool
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800554 isPrefixOf(const Name& name) const;
555
556 bool
557 match(const Name& name) const
558 {
559 return isPrefixOf(name);
560 }
Jeff Thompsonec7789a2013-08-21 11:08:36 -0700561
562 /**
Jeff Thompsond8e53e62013-10-29 16:59:49 -0700563 * Make a Blob value by decoding the escapedString between beginOffset and endOffset according to the NDN URI Scheme.
Jeff Thompson08493592013-11-07 17:44:41 -0800564 * If the escaped string is "", "." or ".." then return a Blob with a null pointer,
565 * which means the component should be skipped in a URI name.
Jeff Thompsond8e53e62013-10-29 16:59:49 -0700566 * @param escapedString The escaped string. It does not need to be null-terminated because we only scan to endOffset.
567 * @param beginOffset The offset in escapedString of the beginning of the portion to decode.
568 * @param endOffset The offset in escapedString of the end of the portion to decode.
569 * @return The Blob value. If the escapedString is not a valid escaped component, then the Blob is a null pointer.
570 */
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800571 static Component
Jeff Thompsond8e53e62013-10-29 16:59:49 -0700572 fromEscapedString(const char *escapedString, size_t beginOffset, size_t endOffset);
573
574 /**
575 * Make a Blob value by decoding the escapedString according to the NDN URI Scheme.
Jeff Thompson08493592013-11-07 17:44:41 -0800576 * If the escaped string is "", "." or ".." then return a Blob with a null pointer,
577 * which means the component should be skipped in a URI name.
Jeff Thompsond8e53e62013-10-29 16:59:49 -0700578 * @param escapedString The null-terminated escaped string.
579 * @return The Blob value. If the escapedString is not a valid escaped component, then the Blob is a null pointer.
580 */
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800581 static Component
Jeff Thompsond8e53e62013-10-29 16:59:49 -0700582 fromEscapedString(const char *escapedString);
583
584 /**
Jeff Thompson7781b392013-12-17 11:45:59 -0800585 * Make a Blob value by decoding the escapedString according to the NDN URI Scheme.
586 * If the escaped string is "", "." or ".." then return a Blob with a null pointer,
587 * which means the component should be skipped in a URI name.
588 * @param escapedString The escaped string.
589 * @return The Blob value. If the escapedString is not a valid escaped component, then the Blob is a null pointer.
590 */
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800591 static Component
Jeff Thompson7781b392013-12-17 11:45:59 -0800592 fromEscapedString(const std::string& escapedString) { return fromEscapedString(escapedString.c_str()); }
593
594 /**
Jeff Thompsonec7789a2013-08-21 11:08:36 -0700595 * Write the value to result, escaping characters according to the NDN URI Scheme.
596 * This also adds "..." to a value with zero or more ".".
597 * @param value the buffer with the value to escape
598 * @param result the string stream to write to.
599 */
Jeff Thompson0050abe2013-09-17 12:50:25 -0700600 static void
Alexander Afanasyev2a742762013-12-28 14:09:46 -0800601 toEscapedString(const uint8_t *value, size_t valueSize, std::ostream& result);
Jeff Thompson21844fc2013-08-08 14:52:51 -0700602
Alexander Afanasyev2a742762013-12-28 14:09:46 -0800603 inline static void
604 toEscapedString(const std::vector<uint8_t>& value, std::ostream& result)
605 {
606 toEscapedString(&*value.begin(), value.size(), result);
607 }
608
Jeff Thompson6653b0b2013-09-23 12:32:39 -0700609 /**
610 * Convert the value by escaping characters according to the NDN URI Scheme.
611 * This also adds "..." to a value with zero or more ".".
612 * @param value the buffer with the value to escape
613 * @return The escaped string.
614 */
Alexander Afanasyev2a742762013-12-28 14:09:46 -0800615 inline static std::string
616 toEscapedString(const uint8_t *value, size_t valueSize)
617 {
618 std::ostringstream result;
619 toEscapedString(value, valueSize, result);
620 return result.str();
621 }
Jeff Thompson6653b0b2013-09-23 12:32:39 -0700622
Alexander Afanasyev2a742762013-12-28 14:09:46 -0800623 static inline std::string
624 toEscapedString(const std::vector<uint8_t>& value)
625 {
626 return toEscapedString(&*value.begin(), value.size());
627 }
628
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700629 //
630 // vector equivalent interface.
631 //
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800632
633 /**
634 * @brief Check if name is emtpy
635 */
636 bool
637 empty() const { return components_.empty(); }
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700638
639 /**
640 * Get the number of components.
641 * @return The number of components.
642 */
643 size_t
Jeff Thompsoneba62eb2013-10-30 13:24:22 -0700644 size() const { return components_.size(); }
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700645
646 /**
647 * Get the component at the given index.
648 * @param i The index of the component, starting from 0.
649 * @return The name component at the index.
650 */
651 const Component&
Alexander Afanasyev8f9aa8b2013-12-30 15:58:57 -0800652 get(ssize_t i) const
653 {
654 if (i >= 0)
655 return components_[i];
656 else
657 return components_[size() + i];
658 }
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700659
Jeff Thompsonafc45a92014-01-15 12:42:45 -0800660 /**
661 * Compare this to the other Name using NDN canonical ordering. If the first components of each name are not equal,
662 * this returns -1 if the first comes before the second using the NDN canonical ordering for name components, or 1 if it comes after.
663 * If they are equal, this compares the second components of each name, etc. If both names are the same up to
664 * the size of the shorter name, this returns -1 if the first name is shorter than the second or 1 if it is longer.
665 * For example, if you std::sort gives: /a/b/d /a/b/cc /c /c/a /bb . This is intuitive because all names
666 * with the prefix /a are next to each other. But it may be also be counter-intuitive because /c comes before /bb
667 * according to NDN canonical ordering since it is shorter.
668 * @param other The other Name to compare with.
669 * @return 0 If they compare equal, -1 if *this comes before other in the canonical ordering, or
670 * 1 if *this comes after other in the canonical ordering.
671 *
672 * @see http://named-data.net/doc/0.2/technical/CanonicalOrder.html
673 */
674 int
675 compare(const Name& other) const;
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700676
677 const Component&
678 operator [] (int i) const
679 {
680 return get(i);
681 }
682
683 /**
684 * Append the component
685 * @param component The component of type T.
686 */
687 template<class T> void
688 push_back(const T &component)
689 {
690 append(component);
691 }
692
Jeff Thompson91737f52013-10-04 11:07:24 -0700693 /**
694 * Check if this name has the same component count and components as the given name.
695 * @param name The Name to check.
696 * @return true if the names are equal, otherwise false.
697 */
698 bool
699 operator == (const Name &name) const { return equals(name); }
700
701 /**
702 * Check if this name has the same component count and components as the given name.
703 * @param name The Name to check.
704 * @return true if the names are not equal, otherwise false.
705 */
706 bool
707 operator != (const Name &name) const { return !equals(name); }
Jeff Thompson82568ad2013-12-17 15:17:40 -0800708
709 /**
Jeff Thompsonafc45a92014-01-15 12:42:45 -0800710 * Return true if this is less than or equal to the other Name in the NDN canonical ordering.
711 * @param other The other Name to compare with.
712 *
713 * @see http://named-data.net/doc/0.2/technical/CanonicalOrder.html
Jeff Thompson82568ad2013-12-17 15:17:40 -0800714 */
Jeff Thompsonafc45a92014-01-15 12:42:45 -0800715 bool
716 operator <= (const Name& other) const { return compare(other) <= 0; }
717
718 /**
719 * Return true if this is less than the other Name in the NDN canonical ordering.
720 * @param other The other Name to compare with.
721 *
722 * @see http://named-data.net/doc/0.2/technical/CanonicalOrder.html
723 */
724 bool
725 operator < (const Name& other) const { return compare(other) < 0; }
726
727 /**
728 * Return true if this is less than or equal to the other Name in the NDN canonical ordering.
729 * @param other The other Name to compare with.
730 *
731 * @see http://named-data.net/doc/0.2/technical/CanonicalOrder.html
732 */
733 bool
734 operator >= (const Name& other) const { return compare(other) >= 0; }
735
736 /**
737 * Return true if this is greater than the other Name in the NDN canonical ordering.
738 * @param other The other Name to compare with.
739 *
740 * @see http://named-data.net/doc/0.2/technical/CanonicalOrder.html
741 */
742 bool
743 operator > (const Name& other) const { return compare(other) > 0; }
Jeff Thompson82568ad2013-12-17 15:17:40 -0800744
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700745 //
746 // Iterator interface to name components.
747 //
748 typedef std::vector<Component>::iterator iterator;
749 typedef std::vector<Component>::const_iterator const_iterator;
750 typedef std::vector<Component>::reverse_iterator reverse_iterator;
751 typedef std::vector<Component>::const_reverse_iterator const_reverse_iterator;
752 typedef std::vector<Component>::reference reference;
753 typedef std::vector<Component>::const_reference const_reference;
754
Alexander Afanasyev58743332014-01-12 13:24:42 -0800755 typedef std::vector<Component>::difference_type difference_type;
756 typedef std::vector<Component>::size_type size_type;
757
758 typedef std::vector<Component>::value_type value_type;
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700759
760 /**
761 * Begin iterator (const).
762 */
763 const_iterator
Jeff Thompson91737f52013-10-04 11:07:24 -0700764 begin() const { return components_.begin(); }
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700765
766 /**
767 * Begin iterator.
768 */
769 iterator
Jeff Thompson91737f52013-10-04 11:07:24 -0700770 begin() { return components_.begin(); }
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700771
772 /**
773 * End iterator (const).
774 */
775 const_iterator
Jeff Thompson91737f52013-10-04 11:07:24 -0700776 end() const { return components_.end(); }
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700777
778 /**
779 * End iterator.
780 */
781 iterator
Jeff Thompson91737f52013-10-04 11:07:24 -0700782 end() { return components_.end(); }
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700783
784 /**
785 * Reverse begin iterator (const).
786 */
787 const_reverse_iterator
Jeff Thompson91737f52013-10-04 11:07:24 -0700788 rbegin() const { return components_.rbegin(); }
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700789
790 /**
791 * Reverse begin iterator.
792 */
793 reverse_iterator
Jeff Thompson91737f52013-10-04 11:07:24 -0700794 rbegin() { return components_.rbegin(); }
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700795
796 /**
797 * Reverse end iterator (const).
798 */
799 const_reverse_iterator
Jeff Thompson91737f52013-10-04 11:07:24 -0700800 rend() const { return components_.rend(); }
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700801
802 /**
803 * Reverse end iterator.
804 */
805 reverse_iterator
Jeff Thompson91737f52013-10-04 11:07:24 -0700806 rend() { return components_.rend(); }
Jeff Thompsonec39fbd2013-10-04 10:56:23 -0700807
Jeff Thompson9c41dfe2013-06-27 12:10:25 -0700808private:
Jeff Thompson5a6b5ab2013-08-05 15:43:47 -0700809 std::vector<Component> components_;
Jeff Thompson9c41dfe2013-06-27 12:10:25 -0700810
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800811 mutable Block wire_;
812};
813
814std::ostream &
815operator << (std::ostream &os, const Name &name);
816
Alexander Afanasyev58743332014-01-12 13:24:42 -0800817inline std::ostream &
818operator << (std::ostream &os, const Name::Component &component)
819{
820 component.toEscapedString(os);
821 return os;
822}
823
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800824inline std::string
825Name::toUri() const
Jeff Thompson49e321a2013-10-04 17:35:59 -0700826{
Alexander Afanasyevaf283d82014-01-03 13:23:34 -0800827 std::ostringstream os;
828 os << *this;
829 return os.str();
Jeff Thompson49e321a2013-10-04 17:35:59 -0700830}
831
Jeff Thompson9c41dfe2013-06-27 12:10:25 -0700832}
833
834#endif
835