blob: d949950b8393dc44b17d6bb38a0706687034ee17 [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Jeff Thompson47eecfc2013-07-07 22:56:46 -07002/**
Alexander 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 * Based on code originally written by Jeff Thompson <jefft0@remap.ucla.edu>
Jeff Thompsonb7f95562013-07-03 18:36:42 -070022 */
23
24#ifndef NDN_INTEREST_HPP
Jeff Thompson2d27e2f2013-08-09 12:55:00 -070025#define NDN_INTEREST_HPP
Jeff Thompsonb7f95562013-07-03 18:36:42 -070026
Alexander Afanasyeve2dcdfd2014-02-07 15:53:28 -080027#include "common.hpp"
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070028
Jeff Thompson53412192013-08-06 13:35:50 -070029#include "name.hpp"
Alexander Afanasyevc348f832014-02-17 16:35:17 -080030#include "selectors.hpp"
Alexander Afanasyev90164962014-03-06 08:29:59 +000031#include "interest-filter.hpp"
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -080032#include "management/nfd-local-control-header.hpp"
Jeff Thompsonb7f95562013-07-03 18:36:42 -070033
34namespace ndn {
Alexander Afanasyevc348f832014-02-17 16:35:17 -080035
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070036class Data;
37
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070038const time::seconds DEFAULT_INTEREST_LIFETIME = time::seconds(4);
Alexander Afanasyevc348f832014-02-17 16:35:17 -080039
Jeff Thompson8238d002013-07-10 11:56:49 -070040/**
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070041 * An Interest holds a Name and other fields for an Interest
Jeff Thompson8238d002013-07-10 11:56:49 -070042 */
Alexander Afanasyevc348f832014-02-17 16:35:17 -080043class Interest : public enable_shared_from_this<Interest>
44{
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070045public:
Jeff Thompson1b4a7b12013-11-15 12:00:02 -080046 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -070047 * @brief Create a new Interest with an empty name (`ndn:/`)
48 *
49 * Note that in certain contexts that use Interest::shared_from_this(), Interest must be
50 * created using `make_shared`:
51 *
52 * shared_ptr<Interest> interest = make_shared<Interest>();
53 *
54 * Otherwise, Interest::shared_from_this() will throw an exception.
Alexander Afanasyevc348f832014-02-17 16:35:17 -080055 */
56 Interest()
57 : m_nonce(0)
58 , m_scope(-1)
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070059 , m_interestLifetime(time::milliseconds::min())
Alexander Afanasyevc348f832014-02-17 16:35:17 -080060 {
61 }
62
63 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -070064 * @brief Create a new Interest with the given name
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070065 *
Alexander Afanasyevc348f832014-02-17 16:35:17 -080066 * @param name The name for the interest.
Alexander Afanasyev770827c2014-05-13 17:42:55 -070067 *
68 * Note that in certain contexts that use Interest::shared_from_this(), Interest must be
69 * created using `make_shared`:
70 *
71 * shared_ptr<Interest> interest = make_shared<Interest>(name);
72 *
73 * Otherwise, Interest::shared_from_this() will throw an exception.
Alexander Afanasyevc348f832014-02-17 16:35:17 -080074 */
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070075 Interest(const Name& name)
Alexander Afanasyevc348f832014-02-17 16:35:17 -080076 : m_name(name)
77 , m_nonce(0)
78 , m_scope(-1)
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070079 , m_interestLifetime(time::milliseconds::min())
Alexander Afanasyevc348f832014-02-17 16:35:17 -080080 {
81 }
82
83 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -070084 * @brief Create a new Interest with the given name and interest lifetime
85 *
86 * @param name The name for the interest.
87 * @param interestLifetime The interest lifetime in time::milliseconds, or -1 for none.
88 *
89 * Note that in certain contexts that use Interest::shared_from_this(), Interest must be
90 * created using `make_shared`:
91 *
92 * shared_ptr<Interest> interest = make_shared<Interest>(name, time::seconds(1));
93 *
94 * Otherwise, Interest::shared_from_this() will throw an exception.
Alexander Afanasyevc348f832014-02-17 16:35:17 -080095 */
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070096 Interest(const Name& name, const time::milliseconds& interestLifetime)
Alexander Afanasyevc348f832014-02-17 16:35:17 -080097 : m_name(name)
98 , m_nonce(0)
99 , m_scope(-1)
100 , m_interestLifetime(interestLifetime)
101 {
102 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700103
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700104 /**
105 * @brief Create a new Interest for the given name, selectors, and guiders
106 *
107 * Note that in certain contexts that use Interest::shared_from_this(), Interest must be
108 * created using `make_shared`:
109 *
110 * shared_ptr<Interest> interest = make_shared<Interest>(...);
111 *
112 * Otherwise, Interest::shared_from_this() will throw an exception.
113 */
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800114 Interest(const Name& name,
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700115 const Selectors& selectors,
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800116 int scope,
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700117 const time::milliseconds& interestLifetime,
118 uint32_t nonce = 0)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800119 : m_name(name)
120 , m_selectors(selectors)
121 , m_nonce(nonce)
122 , m_scope(scope)
123 , m_interestLifetime(interestLifetime)
124 {
125 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700126
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800127 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700128 * @brief Create a new Interest for the given name and parameters
Junxiao Shib332e782014-03-31 14:23:46 -0700129 *
130 * @deprecated Interest().setX(...).setY(...)
131 * or use the overload taking Selectors
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700132 *
133 * Note that in certain contexts that use Interest::shared_from_this(), Interest must be
134 * created using `make_shared`:
135 *
136 * shared_ptr<Interest> interest = make_shared<Interest>(...);
137 *
138 * Otherwise, Interest::shared_from_this() will throw an exception.
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800139 */
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700140 DEPRECATED(
Alexander Afanasyev84681982014-01-03 13:26:09 -0800141 Interest(const Name& name,
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700142 int minSuffixComponents, int maxSuffixComponents,
Alexander Afanasyev84681982014-01-03 13:26:09 -0800143 const Exclude& exclude,
144 int childSelector,
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700145 bool mustBeFresh,
Alexander Afanasyev84681982014-01-03 13:26:09 -0800146 int scope,
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700147 const time::milliseconds& interestLifetime,
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700148 uint32_t nonce = 0))
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800149 : m_name(name)
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700150 , m_selectors(Selectors()
151 .setMinSuffixComponents(minSuffixComponents)
152 .setMaxSuffixComponents(maxSuffixComponents)
153 .setExclude(exclude)
154 .setChildSelector(childSelector)
155 .setMustBeFresh(mustBeFresh))
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800156 , m_nonce(nonce)
157 , m_scope(scope)
158 , m_interestLifetime(interestLifetime)
Jeff Thompson3f76e9e2013-08-21 13:14:58 -0700159 {
160 }
161
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700162 /**
163 * @brief Create from wire encoding
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700164 *
165 * Note that in certain contexts that use Interest::shared_from_this(), Interest must be
166 * created using `make_shared`:
167 *
168 * shared_ptr<Interest> interest = make_shared<Interest>(wire);
169 *
170 * Otherwise, Interest::shared_from_this() will throw an exception.
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700171 */
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800172 explicit
173 Interest(const Block& wire)
174 {
175 wireDecode(wire);
176 }
177
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800178 /**
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800179 * @brief Fast encoding or block size estimation
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800180 */
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800181 template<bool T>
182 inline size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700183 wireEncode(EncodingImpl<T>& block) const;
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800184
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800185 /**
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800186 * @brief Encode to a wire format
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800187 */
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800188 inline const Block&
Alexander Afanasyev1eb961a2014-01-03 13:51:49 -0800189 wireEncode() const;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800190
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800191 /**
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800192 * @brief Decode from the wire format
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800193 */
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700194 inline void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700195 wireDecode(const Block& wire);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800196
197 /**
198 * @brief Check if already has wire
199 */
200 inline bool
201 hasWire() const;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700202
Jeff Thompsond9e278c2013-07-08 15:20:13 -0700203 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700204 * @brief Encode the name according to the NDN URI Scheme
205 *
206 * If there are interest selectors, this method will append "?" and add the selectors as
207 * a query string. For example, "/test/name?ndn.ChildSelector=1"
Jeff Thompson13e280b2013-12-03 13:12:23 -0800208 */
Alexander Afanasyev84681982014-01-03 13:26:09 -0800209 inline std::string
Jeff Thompson13e280b2013-12-03 13:12:23 -0800210 toUri() const;
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700211
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700212 /**
213 * @brief Check if Interest has any selectors present
214 */
Alexander Afanasyev84681982014-01-03 13:26:09 -0800215 inline bool
216 hasSelectors() const;
217
Alexander Afanasyev84681982014-01-03 13:26:09 -0800218 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700219 * @brief Check if Interest, including selectors, matches the given @p name
220 *
221 * @param name The name to be matched. If this is a Data name, it shall contain the
222 * implicit digest component
Alexander Afanasyev84681982014-01-03 13:26:09 -0800223 */
224 bool
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700225 matchesName(const Name& name) const;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800226
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700227 /**
228 * @brief Check if Interest can be satisfied by @p data.
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700229 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700230 * This method considers Name, MinSuffixComponents, MaxSuffixComponents,
231 * PublisherPublicKeyLocator, and Exclude.
232 * This method does not consider ChildSelector and MustBeFresh.
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700233 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700234 * @todo recognize implicit digest component
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700235 */
236 bool
237 matchesData(const Data& data) const;
238
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800239 ///////////////////////////////////////////////////////////////////////////////
240 ///////////////////////////////////////////////////////////////////////////////
241 ///////////////////////////////////////////////////////////////////////////////
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800242 // Getters/setters
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700243
244 const Name&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800245 getName() const
Jeff Thompsonc0486c12013-07-16 14:36:16 -0700246 {
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800247 return m_name;
248 }
249
250 Interest&
251 setName(const Name& name)
252 {
253 m_name = name;
254 m_wire.reset();
255 return *this;
Jeff Thompsonc0486c12013-07-16 14:36:16 -0700256 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700257
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800258 //
Alexander Afanasyev84681982014-01-03 13:26:09 -0800259
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800260 const Selectors&
261 getSelectors() const
262 {
263 return m_selectors;
264 }
265
266 Interest&
267 setSelectors(const Selectors& selectors)
268 {
269 m_selectors = selectors;
270 m_wire.reset();
271 return *this;
272 }
273
274 //
275
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700276 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800277 getScope() const
278 {
279 return m_scope;
280 }
281
282 Interest&
283 setScope(int scope)
284 {
285 m_scope = scope;
286 m_wire.reset();
287 return *this;
288 }
289
290 //
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700291
292 const time::milliseconds&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800293 getInterestLifetime() const
294 {
295 return m_interestLifetime;
296 }
297
298 Interest&
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700299 setInterestLifetime(const time::milliseconds& interestLifetime)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800300 {
301 m_interestLifetime = interestLifetime;
302 m_wire.reset();
303 return *this;
304 }
305
306 //
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700307
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800308 /**
309 * @brief Get Interest's nonce
310 *
311 * If nonce was not set before this call, it will be automatically assigned to a random value
312 *
313 * Const reference needed for C decoding
314 */
315 const uint32_t&
316 getNonce() const;
317
318 Interest&
319 setNonce(uint32_t nonce)
320 {
321 m_nonce = nonce;
322 m_wire.reset();
323 return *this;
324 }
325
326 //
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800327
328 nfd::LocalControlHeader&
329 getLocalControlHeader()
330 {
331 return m_localControlHeader;
332 }
333
334 const nfd::LocalControlHeader&
335 getLocalControlHeader() const
336 {
337 return m_localControlHeader;
338 }
339
340 // helper methods for LocalControlHeader
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700341
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800342 uint64_t
343 getIncomingFaceId() const
344 {
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800345 return getLocalControlHeader().getIncomingFaceId();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800346 }
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800347
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800348 Interest&
349 setIncomingFaceId(uint64_t incomingFaceId)
350 {
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800351 getLocalControlHeader().setIncomingFaceId(incomingFaceId);
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800352 // ! do not reset Interest's wire !
353 return *this;
354 }
355
356 //
357
358 // NextHopFaceId helpers make sense only for Interests
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700359
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800360 uint64_t
361 getNextHopFaceId() const
362 {
363 return getLocalControlHeader().getNextHopFaceId();
364 }
365
366 Interest&
367 setNextHopFaceId(uint64_t nextHopFaceId)
368 {
369 getLocalControlHeader().setNextHopFaceId(nextHopFaceId);
370 // ! do not reset Interest's wire !
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800371 return *this;
372 }
373
374 //
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700375
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800376 ///////////////////////////////////////////////////////////////////////////////
377 ///////////////////////////////////////////////////////////////////////////////
378 ///////////////////////////////////////////////////////////////////////////////
379 // Wrappers for Selectors
380 //
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700381
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800382 int
383 getMinSuffixComponents() const
384 {
385 return m_selectors.getMinSuffixComponents();
386 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700387
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800388 Interest&
389 setMinSuffixComponents(int minSuffixComponents)
390 {
391 m_selectors.setMinSuffixComponents(minSuffixComponents);
392 m_wire.reset();
393 return *this;
394 }
395
396 //
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700397
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800398 int
399 getMaxSuffixComponents() const
400 {
401 return m_selectors.getMaxSuffixComponents();
402 }
403
404 Interest&
405 setMaxSuffixComponents(int maxSuffixComponents)
406 {
407 m_selectors.setMaxSuffixComponents(maxSuffixComponents);
408 m_wire.reset();
409 return *this;
410 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700411
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800412 //
413
Junxiao Shib332e782014-03-31 14:23:46 -0700414 const KeyLocator&
415 getPublisherPublicKeyLocator() const
416 {
417 return m_selectors.getPublisherPublicKeyLocator();
418 }
419
420 Interest&
421 setPublisherPublicKeyLocator(const KeyLocator& keyLocator)
422 {
423 m_selectors.setPublisherPublicKeyLocator(keyLocator);
424 m_wire.reset();
425 return *this;
426 }
427
428 //
429
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800430 const Exclude&
431 getExclude() const
432 {
433 return m_selectors.getExclude();
434 }
435
436 Interest&
437 setExclude(const Exclude& exclude)
438 {
439 m_selectors.setExclude(exclude);
440 m_wire.reset();
441 return *this;
442 }
443
444 //
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700445
446 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800447 getChildSelector() const
448 {
449 return m_selectors.getChildSelector();
450 }
451
452 Interest&
453 setChildSelector(int childSelector)
454 {
455 m_selectors.setChildSelector(childSelector);
456 m_wire.reset();
457 return *this;
458 }
459
460 //
461
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700462 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800463 getMustBeFresh() const
464 {
465 return m_selectors.getMustBeFresh();
466 }
467
468 Interest&
469 setMustBeFresh(bool mustBeFresh)
470 {
471 m_selectors.setMustBeFresh(mustBeFresh);
472 m_wire.reset();
473 return *this;
474 }
475
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700476public: // EqualityComparable concept
477 bool
478 operator==(const Interest& other) const
479 {
480 return wireEncode() == other.wireEncode();
481 }
482
483 bool
484 operator!=(const Interest& other) const
485 {
486 return !(*this == other);
487 }
488
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800489private:
490 Name m_name;
491 Selectors m_selectors;
492 mutable uint32_t m_nonce;
493 int m_scope;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700494 time::milliseconds m_interestLifetime;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800495
496 mutable Block m_wire;
Yingdi Yua4e57672014-02-06 11:16:17 -0800497
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800498 nfd::LocalControlHeader m_localControlHeader;
499 friend class nfd::LocalControlHeader;
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700500};
Alexander Afanasyev84681982014-01-03 13:26:09 -0800501
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700502std::ostream&
503operator<<(std::ostream& os, const Interest& interest);
Alexander Afanasyev84681982014-01-03 13:26:09 -0800504
505inline std::string
506Interest::toUri() const
507{
508 std::ostringstream os;
509 os << *this;
510 return os.str();
511}
512
513inline bool
514Interest::hasSelectors() const
515{
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800516 return !m_selectors.empty();
Alexander Afanasyev84681982014-01-03 13:26:09 -0800517}
518
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800519template<bool T>
520inline size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700521Interest::wireEncode(EncodingImpl<T>& block) const
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800522{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700523 size_t totalLength = 0;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800524
525 // Interest ::= INTEREST-TYPE TLV-LENGTH
526 // Name
527 // Selectors?
528 // Nonce
529 // Scope?
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700530 // InterestLifetime?
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800531
532 // (reverse encoding)
533
534 // InterestLifetime
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700535 if (getInterestLifetime() >= time::milliseconds::zero() &&
536 getInterestLifetime() != DEFAULT_INTEREST_LIFETIME)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800537 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700538 totalLength += prependNonNegativeIntegerBlock(block,
539 Tlv::InterestLifetime,
540 getInterestLifetime().count());
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800541 }
542
543 // Scope
544 if (getScope() >= 0)
545 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700546 totalLength += prependNonNegativeIntegerBlock(block, Tlv::Scope, getScope());
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800547 }
548
549 // Nonce
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700550 totalLength += prependNonNegativeIntegerBlock(block, Tlv::Nonce, getNonce());
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800551
552 // Selectors
553 if (!getSelectors().empty())
554 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700555 totalLength += getSelectors().wireEncode(block);
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800556 }
557
558 // Name
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700559 totalLength += getName().wireEncode(block);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700560
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700561 totalLength += block.prependVarNumber (totalLength);
562 totalLength += block.prependVarNumber (Tlv::Interest);
563 return totalLength;
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700564}
565
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800566inline const Block&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800567Interest::wireEncode() const
568{
569 if (m_wire.hasWire())
570 return m_wire;
571
572 EncodingEstimator estimator;
573 size_t estimatedSize = wireEncode(estimator);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700574
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800575 EncodingBuffer buffer(estimatedSize, 0);
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800576 wireEncode(buffer);
577
578 m_wire = buffer.block();
579 return m_wire;
580}
581
582inline void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700583Interest::wireDecode(const Block& wire)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800584{
585 m_wire = wire;
586 m_wire.parse();
587
588 // Interest ::= INTEREST-TYPE TLV-LENGTH
589 // Name
590 // Selectors?
591 // Nonce
592 // Scope?
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700593 // InterestLifetime?
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800594
595 if (m_wire.type() != Tlv::Interest)
596 throw Tlv::Error("Unexpected TLV number when decoding Interest");
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700597
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800598 // Name
599 m_name.wireDecode(m_wire.get(Tlv::Name));
600
601 // Selectors
602 Block::element_const_iterator val = m_wire.find(Tlv::Selectors);
603 if (val != m_wire.elements_end())
604 {
605 m_selectors.wireDecode(*val);
606 }
607 else
608 m_selectors = Selectors();
609
610 // Nonce
611 val = m_wire.find(Tlv::Nonce);
612 if (val != m_wire.elements_end())
613 {
614 m_nonce = readNonNegativeInteger(*val);
615 }
616 else
617 m_nonce = 0;
618
619 // Scope
620 val = m_wire.find(Tlv::Scope);
621 if (val != m_wire.elements_end())
622 {
623 m_scope = readNonNegativeInteger(*val);
624 }
625 else
626 m_scope = -1;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700627
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800628 // InterestLifetime
629 val = m_wire.find(Tlv::InterestLifetime);
630 if (val != m_wire.elements_end())
631 {
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700632 m_interestLifetime = time::milliseconds(readNonNegativeInteger(*val));
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800633 }
634 else
635 {
636 m_interestLifetime = DEFAULT_INTEREST_LIFETIME;
637 }
638}
639
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800640inline bool
641Interest::hasWire() const
642{
643 return m_wire.hasWire();
644}
645
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800646
647} // namespace ndn
648
649#endif // NDN_INTEREST_HPP