blob: e49275a53709d91c6f2c20a57b8bcd3944a6788a [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 {
Davide Pesaventodfe9c6b2014-08-25 21:17:10 +0200192 return fromEscapedString(escapedString, 0, std::char_traits<char>::length(escapedString));
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800193 }
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 Afanasyev0f232c52014-10-23 13:07:31 -0700258 ////////////////////////////////////////////////////////////////////////////////
259
260 /**
261 * @brief Check if the component is nonNegativeInteger
262 * @see http://named-data.net/doc/ndn-tlv/tlv.html#non-negative-integer-encoding
263 */
264 bool
265 isNumber() const;
266
267 /**
268 * @brief Check if the component is NameComponentWithMarker per NDN naming conventions
269 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
270 */
271 bool
272 isNumberWithMarker(uint8_t marker) const;
273
274 /**
275 * @brief Check if the component is version per NDN naming conventions
276 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
277 */
278 bool
279 isVersion() const;
280
281 /**
282 * @brief Check if the component is segment number per NDN naming conventions
283 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
284 */
285 bool
286 isSegment() const;
287
288 /**
289 * @brief Check if the component is segment offset per NDN naming conventions
290 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
291 */
292 bool
293 isSegmentOffset() const;
294
295 /**
296 * @brief Check if the component is timestamp per NDN naming conventions
297 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
298 */
299 bool
300 isTimestamp() const;
301
302 /**
303 * @brief Check if the component is sequence number per NDN naming conventions
304 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
305 */
306 bool
307 isSequenceNumber() const;
308
309 ////////////////////////////////////////////////////////////////////////////////
310
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800311 /**
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700312 * @brief Interpret this name component as nonNegativeInteger
313 *
314 * @see http://named-data.net/doc/ndn-tlv/tlv.html#non-negative-integer-encoding
315 *
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800316 * @return The integer number.
317 */
318 uint64_t
319 toNumber() const;
320
321 /**
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700322 * @brief Interpret this name component as NameComponentWithMarker
323 *
324 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
325 *
326 * @param marker 1-byte octet of the marker
327 * @return The integer number.
328 * @throws Error if name component does not have the specified marker.
329 * tlv::Error if format does not follow NameComponentWithMarker specification.
330 */
331 uint64_t
332 toNumberWithMarker(uint8_t marker) const;
333
334 /**
335 * @brief Interpret as version component using NDN naming conventions
336 *
337 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
338 *
339 * @throws Error if name component does not have the specified marker.
340 * tlv::Error if format does not follow NameComponentWithMarker specification.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800341 */
342 uint64_t
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700343 toVersion() const;
344
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800345 /**
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700346 * @brief Interpret as segment number component using NDN naming conventions
347 *
348 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
349 *
350 * @throws Error if name component does not have the specified marker.
351 * tlv::Error if format does not follow NameComponentWithMarker specification.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800352 */
353 uint64_t
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700354 toSegment() const;
355
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800356 /**
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700357 * @brief Interpret as segment offset component using NDN naming conventions
358 *
359 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
360 *
361 * @throws Error if name component does not have the specified marker.
362 * tlv::Error if format does not follow NameComponentWithMarker specification.
363 */
364 uint64_t
365 toSegmentOffset() const;
366
367 /**
368 * @brief Interpret as timestamp component using NDN naming conventions
369 *
370 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
371 *
372 * @throws Error if name component does not have the specified marker.
373 * tlv::Error if format does not follow NameComponentWithMarker specification.
374 */
375 time::system_clock::TimePoint
376 toTimestamp() const;
377
378 /**
379 * @brief Interpret as sequence number component using NDN naming conventions
380 *
381 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
382 *
383 * @throws Error if name component does not have the specified marker.
384 * tlv::Error if format does not follow NameComponentWithMarker specification.
385 */
386 uint64_t
387 toSequenceNumber() const;
388
Alexander Afanasyev0f232c52014-10-23 13:07:31 -0700389 ////////////////////////////////////////////////////////////////////////////////
390
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700391 /**
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700392 * @brief Create a component encoded as nonNegativeInteger
393 *
394 * @see http://named-data.net/doc/ndn-tlv/tlv.html#non-negative-integer-encoding
395 *
396 * @param number The non-negative number
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800397 * @return The component value.
398 */
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700399 static Component
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800400 fromNumber(uint64_t number);
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800401
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700402 /**
403 * @brief Create a component encoded as NameComponentWithMarker
404 *
405 * NameComponentWithMarker is defined as:
406 *
407 * NameComponentWithMarker ::= NAME-COMPONENT-TYPE TLV-LEGTH
408 * Marker
409 * includedNonNegativeInteger
410 * Marker ::= BYTE
411 * includedNonNegativeInteger ::= BYTE{1,2,4,8}
412 * NDN-TLV := TLV-TYPE TLV-LENGTH TLV-VALUE?
413 * TLV-TYPE := VAR-NUMBER
414 * TLV-LENGTH := VAR-NUMBER
415 * TLV-VALUE := BYTE+
416 *
417 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
418 *
419 * @param marker 1-byte marker octet
420 * @param number The non-negative number
421 * @return The component value.
422 */
423 static Component
424 fromNumberWithMarker(uint8_t marker, uint64_t number);
425
426 /**
427 * @brief Create version component using NDN naming conventions
428 *
429 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
430 */
431 static Component
432 fromVersion(uint64_t version);
433
434 /**
435 * @brief Create segment number component using NDN naming conventions
436 *
437 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
438 */
439 static Component
440 fromSegment(uint64_t segmentNo);
441
442 /**
443 * @brief Create segment offset component using NDN naming conventions
444 *
445 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
446 */
447 static Component
448 fromSegmentOffset(uint64_t offset);
449
450 /**
451 * @brief Create sequence number component using NDN naming conventions
452 *
453 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
454 */
455 static Component
456 fromTimestamp(const time::system_clock::TimePoint& timePoint);
457
458 /**
459 * @brief Create sequence number component using NDN naming conventions
460 *
461 * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
462 */
463 static Component
464 fromSequenceNumber(uint64_t seqNo);
465
Alexander Afanasyev6486d522014-10-23 14:14:11 -0700466 ////////////////////////////////////////////////////////////////////////////////
467
468 /**
469 * @brief Check if the component is GenericComponent
470 */
471 bool
472 isGeneric() const;
473
474 /**
475 * @brief Check if the component is ImplicitSha256DigestComponent
476 */
477 bool
478 isImplicitSha256Digest() const;
479
480 /**
481 * @brief Create ImplicitSha256DigestComponent component
482 */
483 static Component
484 fromImplicitSha256Digest(const ConstBufferPtr& digest);
485
486 /**
487 * @brief Create ImplicitSha256DigestComponent component
488 */
489 static Component
490 fromImplicitSha256Digest(const uint8_t* digest, size_t digestSize);
491
492 ////////////////////////////////////////////////////////////////////////////////
493
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700494 bool
495 empty() const
496 {
497 return !hasValue();
498 }
499
Shuo Chen5aa8c742014-06-22 15:00:02 +0800500 Component
501 getSuccessor() const;
502
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800503 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700504 * @brief Check if this is the same component as other
505 *
506 * @param other The other Component to compare with
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800507 * @return true if the components are equal, otherwise false.
508 */
509 bool
510 equals(const Component& other) const
511 {
512 if (value_size() != other.value_size())
513 return false;
Alexander Afanasyev60c86812014-02-20 15:19:33 -0800514 if (value_size() == 0 /* == other.value_size()*/)
515 return true;
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800516
Alexander Afanasyev60c86812014-02-20 15:19:33 -0800517 // somehow, behavior is wrong on OSX 10.9 when component is empty
518 // (probably some bug in STL...)
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800519 return std::equal(value_begin(), value_end(), other.value_begin());
520 }
521
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800522 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700523 * @brief Compare this to the other Component using NDN canonical ordering
524 *
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800525 * @param other The other Component to compare with.
526 * @return 0 If they compare equal, -1 if *this comes before other in the canonical ordering, or
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700527 * 1 if *this comes after other in the canonical ordering.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800528 *
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700529 * @see http://named-data.net/doc/ndn-tlv/name.html#canonical-order
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800530 */
531 int
532 compare(const Component& other) const;
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800533
534 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700535 * @brief Check if this is the same component as other
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800536 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700537 * @param other The other Component to compare with.
538 * @return true if the components are equal, otherwise false.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800539 */
540 bool
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700541 operator==(const Component& other) const
542 {
543 return equals(other);
544 }
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700545
546 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700547 * @brief Check if this is not the same component as other
548 * @param other The other Component to compare with
549 * @return true if the components are not equal, otherwise false
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700550 */
551 bool
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700552 operator!=(const Component& other) const
553 {
554 return !equals(other);
555 }
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700556
557 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700558 * @brief Check if the *this is less than or equal to the other in NDN canonical ordering
559 * @param other The other Component to compare with
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700560 *
561 * @see http://named-data.net/doc/ndn-tlv/name.html#canonical-order
562 */
563 bool
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700564 operator<=(const Component& other) const
565 {
566 return compare(other) <= 0;
567 }
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800568
569 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700570 * @brief Check if the *this is less than the other in NDN canonical ordering
571 * @param other The other Component to compare with
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800572 *
Alexander Afanasyev4b98e8c2014-03-22 19:10:19 -0700573 * @see http://named-data.net/doc/ndn-tlv/name.html#canonical-order
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800574 */
575 bool
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700576 operator<(const Component& other) const
577 {
578 return compare(other) < 0;
579 }
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800580
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700581 /**
582 * @brief Check if the *this is greater or equal than the other in NDN canonical ordering
583 * @param other The other Component to compare with
584 *
585 * @see http://named-data.net/doc/ndn-tlv/name.html#canonical-order
586 */
587 bool
588 operator>=(const Component& other) const
589 {
590 return compare(other) >= 0;
591 }
592
593 /**
594 * @brief Check if the *this is greater than the other in NDN canonical ordering
595 * @param other The other Component to compare with
596 *
597 * @see http://named-data.net/doc/ndn-tlv/name.html#canonical-order
598 */
599 bool
600 operator>(const Component& other) const
601 {
602 return compare(other) > 0;
603 }
604
605 // !!! NOTE TO IMPLEMENTOR !!!
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700606 //
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700607 // This class MUST NOT contain any data fields.
608 // Block can be reinterpret_cast'ed as Component type.
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800609};
610
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700611inline std::ostream&
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700612operator<<(std::ostream& os, const Component& component)
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800613{
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700614 component.toUri(os);
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800615 return os;
616}
617
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700618template<class InputIterator>
619inline
620Component::Component(InputIterator begin, InputIterator end)
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600621 : Block(dataBlock(tlv::NameComponent, begin, end))
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700622{
623}
624
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800625} // namespace name
626} // namespace ndn
627
628#endif // NDN_NAME_COMPONENT_HPP