blob: ea007bd07e121e00a45929ef1297be008f3869fb [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/**
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07003 * Copyright (c) 2013-2014, Regents of the University of California.
4 * All rights reserved.
5 *
6 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
7 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
8 *
9 * This file licensed under New BSD License. See COPYING for detailed information about
10 * ndn-cxx library copyright, permissions, and redistribution restrictions.
11 *
12 * Based on code originally written by Jeff Thompson <jefft0@remap.ucla.edu>
Jeff Thompsonb7f95562013-07-03 18:36:42 -070013 */
14
15#ifndef NDN_INTEREST_HPP
Jeff Thompson2d27e2f2013-08-09 12:55:00 -070016#define NDN_INTEREST_HPP
Jeff Thompsonb7f95562013-07-03 18:36:42 -070017
Alexander Afanasyeve2dcdfd2014-02-07 15:53:28 -080018#include "common.hpp"
Jeff Thompson53412192013-08-06 13:35:50 -070019#include "name.hpp"
Alexander Afanasyevc348f832014-02-17 16:35:17 -080020#include "selectors.hpp"
Alexander Afanasyev90164962014-03-06 08:29:59 +000021#include "interest-filter.hpp"
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -080022#include "management/nfd-local-control-header.hpp"
Jeff Thompsonb7f95562013-07-03 18:36:42 -070023
24namespace ndn {
Alexander Afanasyevc348f832014-02-17 16:35:17 -080025
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070026class Data;
27
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070028const time::seconds DEFAULT_INTEREST_LIFETIME = time::seconds(4);
Alexander Afanasyevc348f832014-02-17 16:35:17 -080029
Jeff Thompson8238d002013-07-10 11:56:49 -070030/**
Jeff Thompson8238d002013-07-10 11:56:49 -070031 * An Interest holds a Name and other fields for an interest.
32 */
Alexander Afanasyevc348f832014-02-17 16:35:17 -080033class Interest : public enable_shared_from_this<Interest>
34{
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070035public:
Jeff Thompson1b4a7b12013-11-15 12:00:02 -080036 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -070037 * @brief Create a new Interest with an empty name (`ndn:/`)
38 *
39 * Note that in certain contexts that use Interest::shared_from_this(), Interest must be
40 * created using `make_shared`:
41 *
42 * shared_ptr<Interest> interest = make_shared<Interest>();
43 *
44 * Otherwise, Interest::shared_from_this() will throw an exception.
Alexander Afanasyevc348f832014-02-17 16:35:17 -080045 */
46 Interest()
47 : m_nonce(0)
48 , m_scope(-1)
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070049 , m_interestLifetime(time::milliseconds::min())
Alexander Afanasyevc348f832014-02-17 16:35:17 -080050 {
51 }
52
53 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -070054 * @brief Create a new Interest with the given name
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070055 *
Alexander Afanasyevc348f832014-02-17 16:35:17 -080056 * @param name The name for the interest.
Alexander Afanasyev770827c2014-05-13 17:42:55 -070057 *
58 * Note that in certain contexts that use Interest::shared_from_this(), Interest must be
59 * created using `make_shared`:
60 *
61 * shared_ptr<Interest> interest = make_shared<Interest>(name);
62 *
63 * Otherwise, Interest::shared_from_this() will throw an exception.
Alexander Afanasyevc348f832014-02-17 16:35:17 -080064 */
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070065 Interest(const Name& name)
Alexander Afanasyevc348f832014-02-17 16:35:17 -080066 : m_name(name)
67 , m_nonce(0)
68 , m_scope(-1)
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070069 , m_interestLifetime(time::milliseconds::min())
Alexander Afanasyevc348f832014-02-17 16:35:17 -080070 {
71 }
72
73 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -070074 * @brief Create a new Interest with the given name and interest lifetime
75 *
76 * @param name The name for the interest.
77 * @param interestLifetime The interest lifetime in time::milliseconds, or -1 for none.
78 *
79 * Note that in certain contexts that use Interest::shared_from_this(), Interest must be
80 * created using `make_shared`:
81 *
82 * shared_ptr<Interest> interest = make_shared<Interest>(name, time::seconds(1));
83 *
84 * Otherwise, Interest::shared_from_this() will throw an exception.
Alexander Afanasyevc348f832014-02-17 16:35:17 -080085 */
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070086 Interest(const Name& name, const time::milliseconds& interestLifetime)
Alexander Afanasyevc348f832014-02-17 16:35:17 -080087 : m_name(name)
88 , m_nonce(0)
89 , m_scope(-1)
90 , m_interestLifetime(interestLifetime)
91 {
92 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070093
Alexander Afanasyev770827c2014-05-13 17:42:55 -070094 /**
95 * @brief Create a new Interest for the given name, selectors, and guiders
96 *
97 * Note that in certain contexts that use Interest::shared_from_this(), Interest must be
98 * created using `make_shared`:
99 *
100 * shared_ptr<Interest> interest = make_shared<Interest>(...);
101 *
102 * Otherwise, Interest::shared_from_this() will throw an exception.
103 */
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800104 Interest(const Name& name,
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700105 const Selectors& selectors,
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800106 int scope,
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700107 const time::milliseconds& interestLifetime,
108 uint32_t nonce = 0)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800109 : m_name(name)
110 , m_selectors(selectors)
111 , m_nonce(nonce)
112 , m_scope(scope)
113 , m_interestLifetime(interestLifetime)
114 {
115 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700116
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800117 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700118 * @brief Create a new Interest for the given name and parameters
Junxiao Shib332e782014-03-31 14:23:46 -0700119 *
120 * @deprecated Interest().setX(...).setY(...)
121 * or use the overload taking Selectors
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700122 *
123 * Note that in certain contexts that use Interest::shared_from_this(), Interest must be
124 * created using `make_shared`:
125 *
126 * shared_ptr<Interest> interest = make_shared<Interest>(...);
127 *
128 * Otherwise, Interest::shared_from_this() will throw an exception.
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800129 */
Alexander Afanasyev84681982014-01-03 13:26:09 -0800130 Interest(const Name& name,
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700131 int minSuffixComponents, int maxSuffixComponents,
Alexander Afanasyev84681982014-01-03 13:26:09 -0800132 const Exclude& exclude,
133 int childSelector,
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700134 bool mustBeFresh,
Alexander Afanasyev84681982014-01-03 13:26:09 -0800135 int scope,
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700136 const time::milliseconds& interestLifetime,
137 uint32_t nonce = 0)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800138 : m_name(name)
139 , m_selectors(minSuffixComponents, maxSuffixComponents, exclude, childSelector, mustBeFresh)
140 , m_nonce(nonce)
141 , m_scope(scope)
142 , m_interestLifetime(interestLifetime)
Jeff Thompson3f76e9e2013-08-21 13:14:58 -0700143 {
144 }
145
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700146 /**
147 * @brief Create from wire encoding
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700148 *
149 * Note that in certain contexts that use Interest::shared_from_this(), Interest must be
150 * created using `make_shared`:
151 *
152 * shared_ptr<Interest> interest = make_shared<Interest>(wire);
153 *
154 * Otherwise, Interest::shared_from_this() will throw an exception.
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700155 */
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800156 explicit
157 Interest(const Block& wire)
158 {
159 wireDecode(wire);
160 }
161
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800162 /**
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800163 * @brief Fast encoding or block size estimation
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800164 */
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800165 template<bool T>
166 inline size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700167 wireEncode(EncodingImpl<T>& block) const;
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800168
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800169 /**
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800170 * @brief Encode to a wire format
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800171 */
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800172 inline const Block&
Alexander Afanasyev1eb961a2014-01-03 13:51:49 -0800173 wireEncode() const;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800174
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800175 /**
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800176 * @brief Decode from the wire format
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800177 */
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700178 inline void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700179 wireDecode(const Block& wire);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800180
181 /**
182 * @brief Check if already has wire
183 */
184 inline bool
185 hasWire() const;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700186
Jeff Thompsond9e278c2013-07-08 15:20:13 -0700187 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700188 * @brief Encode the name according to the NDN URI Scheme
189 *
190 * If there are interest selectors, this method will append "?" and add the selectors as
191 * a query string. For example, "/test/name?ndn.ChildSelector=1"
Jeff Thompson13e280b2013-12-03 13:12:23 -0800192 */
Alexander Afanasyev84681982014-01-03 13:26:09 -0800193 inline std::string
Jeff Thompson13e280b2013-12-03 13:12:23 -0800194 toUri() const;
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700195
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700196 /**
197 * @brief Check if Interest has any selectors present
198 */
Alexander Afanasyev84681982014-01-03 13:26:09 -0800199 inline bool
200 hasSelectors() const;
201
Alexander Afanasyev84681982014-01-03 13:26:09 -0800202 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700203 * @brief Check if Interest, including selectors, matches the given @p name
204 *
205 * @param name The name to be matched. If this is a Data name, it shall contain the
206 * implicit digest component
Alexander Afanasyev84681982014-01-03 13:26:09 -0800207 */
208 bool
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700209 matchesName(const Name& name) const;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800210
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700211 /**
212 * @brief Check if Interest can be satisfied by @p data.
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700213 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700214 * This method considers Name, MinSuffixComponents, MaxSuffixComponents,
215 * PublisherPublicKeyLocator, and Exclude.
216 * This method does not consider ChildSelector and MustBeFresh.
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700217 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700218 * @todo recognize implicit digest component
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700219 */
220 bool
221 matchesData(const Data& data) const;
222
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800223 ///////////////////////////////////////////////////////////////////////////////
224 ///////////////////////////////////////////////////////////////////////////////
225 ///////////////////////////////////////////////////////////////////////////////
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800226 // Getters/setters
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700227
228 const Name&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800229 getName() const
Jeff Thompsonc0486c12013-07-16 14:36:16 -0700230 {
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800231 return m_name;
232 }
233
234 Interest&
235 setName(const Name& name)
236 {
237 m_name = name;
238 m_wire.reset();
239 return *this;
Jeff Thompsonc0486c12013-07-16 14:36:16 -0700240 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700241
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800242 //
Alexander Afanasyev84681982014-01-03 13:26:09 -0800243
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800244 const Selectors&
245 getSelectors() const
246 {
247 return m_selectors;
248 }
249
250 Interest&
251 setSelectors(const Selectors& selectors)
252 {
253 m_selectors = selectors;
254 m_wire.reset();
255 return *this;
256 }
257
258 //
259
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700260 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800261 getScope() const
262 {
263 return m_scope;
264 }
265
266 Interest&
267 setScope(int scope)
268 {
269 m_scope = scope;
270 m_wire.reset();
271 return *this;
272 }
273
274 //
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700275
276 const time::milliseconds&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800277 getInterestLifetime() const
278 {
279 return m_interestLifetime;
280 }
281
282 Interest&
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700283 setInterestLifetime(const time::milliseconds& interestLifetime)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800284 {
285 m_interestLifetime = interestLifetime;
286 m_wire.reset();
287 return *this;
288 }
289
290 //
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700291
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800292 /**
293 * @brief Get Interest's nonce
294 *
295 * If nonce was not set before this call, it will be automatically assigned to a random value
296 *
297 * Const reference needed for C decoding
298 */
299 const uint32_t&
300 getNonce() const;
301
302 Interest&
303 setNonce(uint32_t nonce)
304 {
305 m_nonce = nonce;
306 m_wire.reset();
307 return *this;
308 }
309
310 //
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800311
312 nfd::LocalControlHeader&
313 getLocalControlHeader()
314 {
315 return m_localControlHeader;
316 }
317
318 const nfd::LocalControlHeader&
319 getLocalControlHeader() const
320 {
321 return m_localControlHeader;
322 }
323
324 // helper methods for LocalControlHeader
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700325
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800326 uint64_t
327 getIncomingFaceId() const
328 {
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800329 return getLocalControlHeader().getIncomingFaceId();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800330 }
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800331
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800332 Interest&
333 setIncomingFaceId(uint64_t incomingFaceId)
334 {
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800335 getLocalControlHeader().setIncomingFaceId(incomingFaceId);
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800336 // ! do not reset Interest's wire !
337 return *this;
338 }
339
340 //
341
342 // NextHopFaceId helpers make sense only for Interests
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700343
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800344 uint64_t
345 getNextHopFaceId() const
346 {
347 return getLocalControlHeader().getNextHopFaceId();
348 }
349
350 Interest&
351 setNextHopFaceId(uint64_t nextHopFaceId)
352 {
353 getLocalControlHeader().setNextHopFaceId(nextHopFaceId);
354 // ! do not reset Interest's wire !
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800355 return *this;
356 }
357
358 //
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700359
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800360 ///////////////////////////////////////////////////////////////////////////////
361 ///////////////////////////////////////////////////////////////////////////////
362 ///////////////////////////////////////////////////////////////////////////////
363 // Wrappers for Selectors
364 //
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700365
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800366 int
367 getMinSuffixComponents() const
368 {
369 return m_selectors.getMinSuffixComponents();
370 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700371
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800372 Interest&
373 setMinSuffixComponents(int minSuffixComponents)
374 {
375 m_selectors.setMinSuffixComponents(minSuffixComponents);
376 m_wire.reset();
377 return *this;
378 }
379
380 //
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700381
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800382 int
383 getMaxSuffixComponents() const
384 {
385 return m_selectors.getMaxSuffixComponents();
386 }
387
388 Interest&
389 setMaxSuffixComponents(int maxSuffixComponents)
390 {
391 m_selectors.setMaxSuffixComponents(maxSuffixComponents);
392 m_wire.reset();
393 return *this;
394 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700395
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800396 //
397
Junxiao Shib332e782014-03-31 14:23:46 -0700398 const KeyLocator&
399 getPublisherPublicKeyLocator() const
400 {
401 return m_selectors.getPublisherPublicKeyLocator();
402 }
403
404 Interest&
405 setPublisherPublicKeyLocator(const KeyLocator& keyLocator)
406 {
407 m_selectors.setPublisherPublicKeyLocator(keyLocator);
408 m_wire.reset();
409 return *this;
410 }
411
412 //
413
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800414 const Exclude&
415 getExclude() const
416 {
417 return m_selectors.getExclude();
418 }
419
420 Interest&
421 setExclude(const Exclude& exclude)
422 {
423 m_selectors.setExclude(exclude);
424 m_wire.reset();
425 return *this;
426 }
427
428 //
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700429
430 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800431 getChildSelector() const
432 {
433 return m_selectors.getChildSelector();
434 }
435
436 Interest&
437 setChildSelector(int childSelector)
438 {
439 m_selectors.setChildSelector(childSelector);
440 m_wire.reset();
441 return *this;
442 }
443
444 //
445
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700446 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800447 getMustBeFresh() const
448 {
449 return m_selectors.getMustBeFresh();
450 }
451
452 Interest&
453 setMustBeFresh(bool mustBeFresh)
454 {
455 m_selectors.setMustBeFresh(mustBeFresh);
456 m_wire.reset();
457 return *this;
458 }
459
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700460public: // EqualityComparable concept
461 bool
462 operator==(const Interest& other) const
463 {
464 return wireEncode() == other.wireEncode();
465 }
466
467 bool
468 operator!=(const Interest& other) const
469 {
470 return !(*this == other);
471 }
472
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800473private:
474 Name m_name;
475 Selectors m_selectors;
476 mutable uint32_t m_nonce;
477 int m_scope;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700478 time::milliseconds m_interestLifetime;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800479
480 mutable Block m_wire;
Yingdi Yua4e57672014-02-06 11:16:17 -0800481
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800482 nfd::LocalControlHeader m_localControlHeader;
483 friend class nfd::LocalControlHeader;
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700484};
Alexander Afanasyev84681982014-01-03 13:26:09 -0800485
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700486std::ostream&
487operator<<(std::ostream& os, const Interest& interest);
Alexander Afanasyev84681982014-01-03 13:26:09 -0800488
489inline std::string
490Interest::toUri() const
491{
492 std::ostringstream os;
493 os << *this;
494 return os.str();
495}
496
497inline bool
498Interest::hasSelectors() const
499{
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800500 return !m_selectors.empty();
Alexander Afanasyev84681982014-01-03 13:26:09 -0800501}
502
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800503template<bool T>
504inline size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700505Interest::wireEncode(EncodingImpl<T>& block) const
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800506{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700507 size_t totalLength = 0;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800508
509 // Interest ::= INTEREST-TYPE TLV-LENGTH
510 // Name
511 // Selectors?
512 // Nonce
513 // Scope?
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700514 // InterestLifetime?
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800515
516 // (reverse encoding)
517
518 // InterestLifetime
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700519 if (getInterestLifetime() >= time::milliseconds::zero() &&
520 getInterestLifetime() != DEFAULT_INTEREST_LIFETIME)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800521 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700522 totalLength += prependNonNegativeIntegerBlock(block,
523 Tlv::InterestLifetime,
524 getInterestLifetime().count());
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800525 }
526
527 // Scope
528 if (getScope() >= 0)
529 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700530 totalLength += prependNonNegativeIntegerBlock(block, Tlv::Scope, getScope());
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800531 }
532
533 // Nonce
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700534 totalLength += prependNonNegativeIntegerBlock(block, Tlv::Nonce, getNonce());
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800535
536 // Selectors
537 if (!getSelectors().empty())
538 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700539 totalLength += getSelectors().wireEncode(block);
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800540 }
541
542 // Name
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700543 totalLength += getName().wireEncode(block);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700544
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700545 totalLength += block.prependVarNumber (totalLength);
546 totalLength += block.prependVarNumber (Tlv::Interest);
547 return totalLength;
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700548}
549
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800550inline const Block&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800551Interest::wireEncode() const
552{
553 if (m_wire.hasWire())
554 return m_wire;
555
556 EncodingEstimator estimator;
557 size_t estimatedSize = wireEncode(estimator);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700558
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800559 EncodingBuffer buffer(estimatedSize, 0);
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800560 wireEncode(buffer);
561
562 m_wire = buffer.block();
563 return m_wire;
564}
565
566inline void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700567Interest::wireDecode(const Block& wire)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800568{
569 m_wire = wire;
570 m_wire.parse();
571
572 // Interest ::= INTEREST-TYPE TLV-LENGTH
573 // Name
574 // Selectors?
575 // Nonce
576 // Scope?
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700577 // InterestLifetime?
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800578
579 if (m_wire.type() != Tlv::Interest)
580 throw Tlv::Error("Unexpected TLV number when decoding Interest");
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700581
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800582 // Name
583 m_name.wireDecode(m_wire.get(Tlv::Name));
584
585 // Selectors
586 Block::element_const_iterator val = m_wire.find(Tlv::Selectors);
587 if (val != m_wire.elements_end())
588 {
589 m_selectors.wireDecode(*val);
590 }
591 else
592 m_selectors = Selectors();
593
594 // Nonce
595 val = m_wire.find(Tlv::Nonce);
596 if (val != m_wire.elements_end())
597 {
598 m_nonce = readNonNegativeInteger(*val);
599 }
600 else
601 m_nonce = 0;
602
603 // Scope
604 val = m_wire.find(Tlv::Scope);
605 if (val != m_wire.elements_end())
606 {
607 m_scope = readNonNegativeInteger(*val);
608 }
609 else
610 m_scope = -1;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700611
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800612 // InterestLifetime
613 val = m_wire.find(Tlv::InterestLifetime);
614 if (val != m_wire.elements_end())
615 {
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700616 m_interestLifetime = time::milliseconds(readNonNegativeInteger(*val));
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800617 }
618 else
619 {
620 m_interestLifetime = DEFAULT_INTEREST_LIFETIME;
621 }
622}
623
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800624inline bool
625Interest::hasWire() const
626{
627 return m_wire.hasWire();
628}
629
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800630
631} // namespace ndn
632
633#endif // NDN_INTEREST_HPP