blob: 7213f9a96c9a9d0a48604417dd6aebf1ae8aad68 [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -08002/**
Alexander Afanasyevc169a812014-05-20 20:37:29 -04003 * Copyright (c) 2013-2014 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/>
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080024 */
25
26#ifndef NDN_NAME_COMPONENT_HPP
27#define NDN_NAME_COMPONENT_HPP
28
29#include "common.hpp"
30#include "encoding/block.hpp"
Alexander Afanasyev15f67312014-07-22 15:11:09 -070031#include "util/time.hpp"
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080032
33namespace ndn {
34namespace name {
35
Alexander Afanasyev15f67312014-07-22 15:11:09 -070036/// @brief Segment marker for NDN naming conventions
37static const uint8_t SEGMENT_MARKER = 0x00;
38/// @brief Segment offset marker for NDN naming conventions
39static const uint8_t SEGMENT_OFFSET_MARKER = 0xFB;
40/// @brief Version marker for NDN naming conventions
41static const uint8_t VERSION_MARKER = 0xFD;
42/// @brief Timestamp marker for NDN naming conventions
43static const uint8_t TIMESTAMP_MARKER = 0xFC;
44/// @brief Sequence number marker for NDN naming conventions
45static const uint8_t SEQUENCE_NUMBER_MARKER = 0xFE;
46
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080047/**
Alexander Afanasyev3aeeaeb2014-04-22 23:34:23 -070048 * @brief Component holds a read-only name component value.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080049 */
50class Component : public Block
51{
52public:
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070053 /**
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070054 * @brief Error that can be thrown from name::Component
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070055 */
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070056 class Error : public Block::Error
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070057 {
58 public:
59 explicit
60 Error(const std::string& what)
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070061 : Block::Error(what)
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070062 {
63 }
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -070064 };
65
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080066 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -070067 * Create a new name::Component with an empty value
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080068 */
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -070069 Component();
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080070
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -080071 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -070072 * @brief Create name::Component from a wire block
73 *
Steve DiBenedetto54ce6682014-07-22 13:22:57 -060074 * @param wire tlv::NameComponent Block from which to create name::Component
75 * @throws Error if wire.type() is not tlv::NameComponent
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -080076 *
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070077 * Any block can be implicitly converted to name::Component
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -080078 */
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -070079 Component(const Block& wire);
80
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080081 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -070082 * @brief Create a new name::Component from the buffer pointer (buffer pointer will be copied)
83 *
84 * @param buffer A pointer to an immutable buffer
85 *
Steve DiBenedetto54ce6682014-07-22 13:22:57 -060086 * This constructor will create a new tlv::NameComponent Block with `buffer` as a payload.
Alexander Afanasyev770827c2014-05-13 17:42:55 -070087 * Note that this method **will not** allocate new memory for and copy the payload until
88 * toWire() method is called.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080089 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070090 explicit
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -070091 Component(const ConstBufferPtr& buffer);
92
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080093 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -070094 * @brief Create a new name::Component from the buffer (data from buffer will be copied)
95 * @param buffer A reference to the buffer
96 *
Steve DiBenedetto54ce6682014-07-22 13:22:57 -060097 * This constructor will create a new tlv::NameComponent Block with `buffer` as a payload.
Alexander Afanasyev770827c2014-05-13 17:42:55 -070098 * Note that this method **will** allocate new memory for and copy the payload.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080099 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700100 explicit
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700101 Component(const Buffer& buffer);
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800102
103 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700104 * @brief Create a new name::Component from the buffer (data from buffer will be copied)
105 * @param buffer A pointer to the first byte of the buffer
106 * @param bufferSize Size of the buffer
107 *
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600108 * This constructor will create a new tlv::NameComponent Block with `buffer` as a payload.
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700109 * Note that this method **will** allocate new memory for and copy the payload.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800110 */
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700111 Component(const uint8_t* buffer, size_t bufferSize);
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800112
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700113 /**
114 * @brief Create a new name::Component from the buffer (data from buffer will be copied)
115 * @param begin Iterator pointing to the beginning of the buffer
116 * @param end Iterator pointing to the ending of the buffer
117 *
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600118 * This constructor will create a new tlv::NameComponent Block with `buffer` as a payload.
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700119 * Note that this method **will** allocate new memory for and copy the payload.
120 */
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800121 template<class InputIterator>
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700122 Component(InputIterator begin, InputIterator end);
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -0800123
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700124 /**
125 * @brief Create a new name::Component from the C string (data from string will be copied)
126 *
127 * @param str Zero-ended string. Note that this string will be interpreted as is (i.e.,
128 * it will not be interpreted as URI)
129 *
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600130 * This constructor will create a new tlv::NameComponent Block with `buffer` as a payload.
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700131 * Note that this method **will** allocate new memory for and copy the payload.
132 */
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -0800133 explicit
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700134 Component(const char* str);
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800135
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700136 /**
137 * @brief Create a new name::Component from the STL string (data from string will be copied)
138 *
139 * @param str Const reference to STL string. Note that this string will be interpreted
140 * as is (i.e., it will not be interpreted as URI)
141 *
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600142 * This constructor will create a new tlv::NameComponent Block with `buffer` as a payload.
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700143 * Note that this method **will** allocate new memory for and copy the payload.
144 */
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -0800145 explicit
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700146 Component(const std::string& str);
147
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800148 /**
149 * @brief Fast encoding or block size estimation
150 */
151 template<bool T>
152 size_t
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700153 wireEncode(EncodingImpl<T>& block) const;
154
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800155 /**
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700156 * @brief Encode to a wire format
157 */
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700158 const Block&
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700159 wireEncode() const;
160
161 /**
162 * @brief Decode from the wire format
163 */
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700164 void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700165 wireDecode(const Block& wire);
166
167 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700168 * @brief Create name::Component by decoding the escapedString between beginOffset and
169 * endOffset according to the NDN URI Scheme.
170 *
171 * If the escaped string is "", "." or ".." then return an empty name::Component. Note
172 * that an empty name::Component should not be added to Name and if attempted, an
173 * exception will be thrown.
174 *
175 * @param escapedString String containing NDN URI-encoded name
176 * component. [escapedString+beginOffset, beginOffset+endOffset)
177 * must be a valid memory buffer.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800178 * @param beginOffset The offset in escapedString of the beginning of the portion to decode.
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700179 * @param endOffset The offset in escapedString of the end of the portion to decode.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800180 */
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700181 static Component
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700182 fromEscapedString(const char* escapedString, size_t beginOffset, size_t endOffset);
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800183
184 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700185 * @brief Create name::Component by decoding the escapedString according to the NDN URI Scheme
186 *
187 * This overload is a convenience wrapper for fromEscapedString(char*,size_t,size)
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800188 */
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700189 static Component
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700190 fromEscapedString(const char* escapedString)
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800191 {
192 return fromEscapedString(escapedString, 0, ::strlen(escapedString));
193 }
194
195 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700196 * @brief Create name::Component by decoding the escapedString according to the NDN URI Scheme
197 *
198 * This overload is a convenience wrapper for fromEscapedString(char*,size_t,size)
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800199 */
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700200 static Component
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800201 fromEscapedString(const std::string& escapedString)
202 {
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700203 return fromEscapedString(escapedString.c_str(), 0, escapedString.size());
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800204 }
205
206 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700207 * @brief Write *this to the output stream, escaping characters according to the NDN URI Scheme
208 *
209 * @deprecated Use toUri(std::ostream&) instead
210 *
211 * This also adds "..." to a value with zero or more "."
212 *
213 * @param os The output stream to where write the URI escaped version *this
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800214 */
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700215 DEPRECATED(
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700216 void
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700217 toEscapedString(std::ostream& os) const)
218 {
219 return toUri(os);
220 }
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700221
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800222 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700223 * @brief Convert *this by escaping characters according to the NDN URI Scheme
224 *
225 * @deprecated Use toUri() instead
226 *
227 * This also adds "..." to a value with zero or more "."
228 *
229 * @return The escaped string
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800230 */
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700231 DEPRECATED(
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700232 std::string
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700233 toEscapedString() const)
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800234 {
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700235 return toUri();
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800236 }
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -0800237
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700238 /**
239 * @brief Write *this to the output stream, escaping characters according to the NDN URI Scheme
240 *
241 * This also adds "..." to a value with zero or more "."
242 *
243 * @param os The output stream to where write the URI escaped version *this
244 */
245 void
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700246 toUri(std::ostream& os) const;
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -0800247
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700248 /**
249 * @brief Convert *this by escaping characters according to the NDN URI Scheme
250 *
251 * This also adds "..." to a value with zero or more "."
252 *
253 * @return The escaped string
254 */
255 std::string
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700256 toUri() const;
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700257
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800258 /**
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700259 * @brief Interpret this name component as nonNegativeInteger
260 *
261 * @see http://named-data.net/doc/ndn-tlv/tlv.html#non-negative-integer-encoding
262 *
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800263 * @return The integer number.
264 */
265 uint64_t
266 toNumber() const;
267
268 /**
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700269 * @brief Interpret this name component as NameComponentWithMarker
270 *
271 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
272 *
273 * @param marker 1-byte octet of the marker
274 * @return The integer number.
275 * @throws Error if name component does not have the specified marker.
276 * tlv::Error if format does not follow NameComponentWithMarker specification.
277 */
278 uint64_t
279 toNumberWithMarker(uint8_t marker) const;
280
281 /**
282 * @brief Interpret as version component using NDN naming conventions
283 *
284 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
285 *
286 * @throws Error if name component does not have the specified marker.
287 * tlv::Error if format does not follow NameComponentWithMarker specification.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800288 */
289 uint64_t
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700290 toVersion() const;
291
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800292 /**
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700293 * @brief Interpret as segment number component using NDN naming conventions
294 *
295 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
296 *
297 * @throws Error if name component does not have the specified marker.
298 * tlv::Error if format does not follow NameComponentWithMarker specification.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800299 */
300 uint64_t
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700301 toSegment() const;
302
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800303 /**
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700304 * @brief Interpret as segment offset component using NDN naming conventions
305 *
306 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
307 *
308 * @throws Error if name component does not have the specified marker.
309 * tlv::Error if format does not follow NameComponentWithMarker specification.
310 */
311 uint64_t
312 toSegmentOffset() const;
313
314 /**
315 * @brief Interpret as timestamp component using NDN naming conventions
316 *
317 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
318 *
319 * @throws Error if name component does not have the specified marker.
320 * tlv::Error if format does not follow NameComponentWithMarker specification.
321 */
322 time::system_clock::TimePoint
323 toTimestamp() const;
324
325 /**
326 * @brief Interpret as sequence number component using NDN naming conventions
327 *
328 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
329 *
330 * @throws Error if name component does not have the specified marker.
331 * tlv::Error if format does not follow NameComponentWithMarker specification.
332 */
333 uint64_t
334 toSequenceNumber() const;
335
336 /**
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700337 * @brief Create a component encoded as nonNegativeInteger
338 *
339 * @see http://named-data.net/doc/ndn-tlv/tlv.html#non-negative-integer-encoding
340 *
341 * @param number The non-negative number
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800342 * @return The component value.
343 */
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700344 static Component
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800345 fromNumber(uint64_t number);
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800346
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700347 /**
348 * @brief Create a component encoded as NameComponentWithMarker
349 *
350 * NameComponentWithMarker is defined as:
351 *
352 * NameComponentWithMarker ::= NAME-COMPONENT-TYPE TLV-LEGTH
353 * Marker
354 * includedNonNegativeInteger
355 * Marker ::= BYTE
356 * includedNonNegativeInteger ::= BYTE{1,2,4,8}
357 * NDN-TLV := TLV-TYPE TLV-LENGTH TLV-VALUE?
358 * TLV-TYPE := VAR-NUMBER
359 * TLV-LENGTH := VAR-NUMBER
360 * TLV-VALUE := BYTE+
361 *
362 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
363 *
364 * @param marker 1-byte marker octet
365 * @param number The non-negative number
366 * @return The component value.
367 */
368 static Component
369 fromNumberWithMarker(uint8_t marker, uint64_t number);
370
371 /**
372 * @brief Create version component using NDN naming conventions
373 *
374 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
375 */
376 static Component
377 fromVersion(uint64_t version);
378
379 /**
380 * @brief Create segment number component using NDN naming conventions
381 *
382 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
383 */
384 static Component
385 fromSegment(uint64_t segmentNo);
386
387 /**
388 * @brief Create segment offset component using NDN naming conventions
389 *
390 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
391 */
392 static Component
393 fromSegmentOffset(uint64_t offset);
394
395 /**
396 * @brief Create sequence number component using NDN naming conventions
397 *
398 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
399 */
400 static Component
401 fromTimestamp(const time::system_clock::TimePoint& timePoint);
402
403 /**
404 * @brief Create sequence number component using NDN naming conventions
405 *
406 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
407 */
408 static Component
409 fromSequenceNumber(uint64_t seqNo);
410
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700411 bool
412 empty() const
413 {
414 return !hasValue();
415 }
416
Shuo Chen5aa8c742014-06-22 15:00:02 +0800417 Component
418 getSuccessor() const;
419
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800420 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700421 * @brief Check if this is the same component as other
422 *
423 * @param other The other Component to compare with
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800424 * @return true if the components are equal, otherwise false.
425 */
426 bool
427 equals(const Component& other) const
428 {
429 if (value_size() != other.value_size())
430 return false;
Alexander Afanasyev60c86812014-02-20 15:19:33 -0800431 if (value_size() == 0 /* == other.value_size()*/)
432 return true;
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800433
Alexander Afanasyev60c86812014-02-20 15:19:33 -0800434 // somehow, behavior is wrong on OSX 10.9 when component is empty
435 // (probably some bug in STL...)
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800436 return std::equal(value_begin(), value_end(), other.value_begin());
437 }
438
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800439 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700440 * @brief Compare this to the other Component using NDN canonical ordering
441 *
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800442 * @param other The other Component to compare with.
443 * @return 0 If they compare equal, -1 if *this comes before other in the canonical ordering, or
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700444 * 1 if *this comes after other in the canonical ordering.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800445 *
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700446 * @see http://named-data.net/doc/ndn-tlv/name.html#canonical-order
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800447 */
448 int
449 compare(const Component& other) const;
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800450
451 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700452 * @brief Check if this is the same component as other
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800453 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700454 * @param other The other Component to compare with.
455 * @return true if the components are equal, otherwise false.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800456 */
457 bool
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700458 operator==(const Component& other) const
459 {
460 return equals(other);
461 }
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700462
463 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700464 * @brief Check if this is not the same component as other
465 * @param other The other Component to compare with
466 * @return true if the components are not equal, otherwise false
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700467 */
468 bool
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700469 operator!=(const Component& other) const
470 {
471 return !equals(other);
472 }
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700473
474 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700475 * @brief Check if the *this is less than or equal to the other in NDN canonical ordering
476 * @param other The other Component to compare with
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700477 *
478 * @see http://named-data.net/doc/ndn-tlv/name.html#canonical-order
479 */
480 bool
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700481 operator<=(const Component& other) const
482 {
483 return compare(other) <= 0;
484 }
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800485
486 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700487 * @brief Check if the *this is less than the other in NDN canonical ordering
488 * @param other The other Component to compare with
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800489 *
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700490 * @see http://named-data.net/doc/ndn-tlv/name.html#canonical-order
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800491 */
492 bool
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700493 operator<(const Component& other) const
494 {
495 return compare(other) < 0;
496 }
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800497
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700498 /**
499 * @brief Check if the *this is greater or equal than the other in NDN canonical ordering
500 * @param other The other Component to compare with
501 *
502 * @see http://named-data.net/doc/ndn-tlv/name.html#canonical-order
503 */
504 bool
505 operator>=(const Component& other) const
506 {
507 return compare(other) >= 0;
508 }
509
510 /**
511 * @brief Check if the *this is greater than the other in NDN canonical ordering
512 * @param other The other Component to compare with
513 *
514 * @see http://named-data.net/doc/ndn-tlv/name.html#canonical-order
515 */
516 bool
517 operator>(const Component& other) const
518 {
519 return compare(other) > 0;
520 }
521
522 // !!! NOTE TO IMPLEMENTOR !!!
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700523 //
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700524 // This class MUST NOT contain any data fields.
525 // Block can be reinterpret_cast'ed as Component type.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800526};
527
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700528inline std::ostream&
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700529operator<<(std::ostream& os, const Component& component)
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800530{
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700531 component.toUri(os);
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800532 return os;
533}
534
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700535template<class InputIterator>
536inline
537Component::Component(InputIterator begin, InputIterator end)
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600538 : Block(dataBlock(tlv::NameComponent, begin, end))
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700539{
540}
541
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800542} // namespace name
543} // namespace ndn
544
545#endif // NDN_NAME_COMPONENT_HPP