blob: c433ae822097eeb456ea7f7c00aa5708e00442e2 [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"
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070019
Jeff Thompson53412192013-08-06 13:35:50 -070020#include "name.hpp"
Alexander Afanasyevc348f832014-02-17 16:35:17 -080021#include "selectors.hpp"
Alexander Afanasyev90164962014-03-06 08:29:59 +000022#include "interest-filter.hpp"
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -080023#include "management/nfd-local-control-header.hpp"
Jeff Thompsonb7f95562013-07-03 18:36:42 -070024
25namespace ndn {
Alexander Afanasyevc348f832014-02-17 16:35:17 -080026
Junxiao Shiaf8eeea2014-03-31 20:10:56 -070027class Data;
28
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070029const time::seconds DEFAULT_INTEREST_LIFETIME = time::seconds(4);
Alexander Afanasyevc348f832014-02-17 16:35:17 -080030
Jeff Thompson8238d002013-07-10 11:56:49 -070031/**
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070032 * An Interest holds a Name and other fields for an Interest
Jeff Thompson8238d002013-07-10 11:56:49 -070033 */
Alexander Afanasyevc348f832014-02-17 16:35:17 -080034class Interest : public enable_shared_from_this<Interest>
35{
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070036public:
Jeff Thompson1b4a7b12013-11-15 12:00:02 -080037 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -070038 * @brief Create a new Interest with an empty name (`ndn:/`)
39 *
40 * Note that in certain contexts that use Interest::shared_from_this(), Interest must be
41 * created using `make_shared`:
42 *
43 * shared_ptr<Interest> interest = make_shared<Interest>();
44 *
45 * Otherwise, Interest::shared_from_this() will throw an exception.
Alexander Afanasyevc348f832014-02-17 16:35:17 -080046 */
47 Interest()
48 : m_nonce(0)
49 , m_scope(-1)
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070050 , m_interestLifetime(time::milliseconds::min())
Alexander Afanasyevc348f832014-02-17 16:35:17 -080051 {
52 }
53
54 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -070055 * @brief Create a new Interest with the given name
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070056 *
Alexander Afanasyevc348f832014-02-17 16:35:17 -080057 * @param name The name for the interest.
Alexander Afanasyev770827c2014-05-13 17:42:55 -070058 *
59 * Note that in certain contexts that use Interest::shared_from_this(), Interest must be
60 * created using `make_shared`:
61 *
62 * shared_ptr<Interest> interest = make_shared<Interest>(name);
63 *
64 * Otherwise, Interest::shared_from_this() will throw an exception.
Alexander Afanasyevc348f832014-02-17 16:35:17 -080065 */
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070066 Interest(const Name& name)
Alexander Afanasyevc348f832014-02-17 16:35:17 -080067 : m_name(name)
68 , m_nonce(0)
69 , m_scope(-1)
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070070 , m_interestLifetime(time::milliseconds::min())
Alexander Afanasyevc348f832014-02-17 16:35:17 -080071 {
72 }
73
74 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -070075 * @brief Create a new Interest with the given name and interest lifetime
76 *
77 * @param name The name for the interest.
78 * @param interestLifetime The interest lifetime in time::milliseconds, or -1 for none.
79 *
80 * Note that in certain contexts that use Interest::shared_from_this(), Interest must be
81 * created using `make_shared`:
82 *
83 * shared_ptr<Interest> interest = make_shared<Interest>(name, time::seconds(1));
84 *
85 * Otherwise, Interest::shared_from_this() will throw an exception.
Alexander Afanasyevc348f832014-02-17 16:35:17 -080086 */
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070087 Interest(const Name& name, const time::milliseconds& interestLifetime)
Alexander Afanasyevc348f832014-02-17 16:35:17 -080088 : m_name(name)
89 , m_nonce(0)
90 , m_scope(-1)
91 , m_interestLifetime(interestLifetime)
92 {
93 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070094
Alexander Afanasyev770827c2014-05-13 17:42:55 -070095 /**
96 * @brief Create a new Interest for the given name, selectors, and guiders
97 *
98 * Note that in certain contexts that use Interest::shared_from_this(), Interest must be
99 * created using `make_shared`:
100 *
101 * shared_ptr<Interest> interest = make_shared<Interest>(...);
102 *
103 * Otherwise, Interest::shared_from_this() will throw an exception.
104 */
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800105 Interest(const Name& name,
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700106 const Selectors& selectors,
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800107 int scope,
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700108 const time::milliseconds& interestLifetime,
109 uint32_t nonce = 0)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800110 : m_name(name)
111 , m_selectors(selectors)
112 , m_nonce(nonce)
113 , m_scope(scope)
114 , m_interestLifetime(interestLifetime)
115 {
116 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700117
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800118 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700119 * @brief Create a new Interest for the given name and parameters
Junxiao Shib332e782014-03-31 14:23:46 -0700120 *
121 * @deprecated Interest().setX(...).setY(...)
122 * or use the overload taking Selectors
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700123 *
124 * Note that in certain contexts that use Interest::shared_from_this(), Interest must be
125 * created using `make_shared`:
126 *
127 * shared_ptr<Interest> interest = make_shared<Interest>(...);
128 *
129 * Otherwise, Interest::shared_from_this() will throw an exception.
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800130 */
Alexander Afanasyev84681982014-01-03 13:26:09 -0800131 Interest(const Name& name,
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700132 int minSuffixComponents, int maxSuffixComponents,
Alexander Afanasyev84681982014-01-03 13:26:09 -0800133 const Exclude& exclude,
134 int childSelector,
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700135 bool mustBeFresh,
Alexander Afanasyev84681982014-01-03 13:26:09 -0800136 int scope,
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700137 const time::milliseconds& interestLifetime,
138 uint32_t nonce = 0)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800139 : m_name(name)
140 , m_selectors(minSuffixComponents, maxSuffixComponents, exclude, childSelector, mustBeFresh)
141 , m_nonce(nonce)
142 , m_scope(scope)
143 , m_interestLifetime(interestLifetime)
Jeff Thompson3f76e9e2013-08-21 13:14:58 -0700144 {
145 }
146
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700147 /**
148 * @brief Create from wire encoding
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700149 *
150 * Note that in certain contexts that use Interest::shared_from_this(), Interest must be
151 * created using `make_shared`:
152 *
153 * shared_ptr<Interest> interest = make_shared<Interest>(wire);
154 *
155 * Otherwise, Interest::shared_from_this() will throw an exception.
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700156 */
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800157 explicit
158 Interest(const Block& wire)
159 {
160 wireDecode(wire);
161 }
162
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800163 /**
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800164 * @brief Fast encoding or block size estimation
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800165 */
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800166 template<bool T>
167 inline size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700168 wireEncode(EncodingImpl<T>& block) const;
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800169
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800170 /**
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800171 * @brief Encode to a wire format
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800172 */
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800173 inline const Block&
Alexander Afanasyev1eb961a2014-01-03 13:51:49 -0800174 wireEncode() const;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800175
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800176 /**
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800177 * @brief Decode from the wire format
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800178 */
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700179 inline void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700180 wireDecode(const Block& wire);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800181
182 /**
183 * @brief Check if already has wire
184 */
185 inline bool
186 hasWire() const;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700187
Jeff Thompsond9e278c2013-07-08 15:20:13 -0700188 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700189 * @brief Encode the name according to the NDN URI Scheme
190 *
191 * If there are interest selectors, this method will append "?" and add the selectors as
192 * a query string. For example, "/test/name?ndn.ChildSelector=1"
Jeff Thompson13e280b2013-12-03 13:12:23 -0800193 */
Alexander Afanasyev84681982014-01-03 13:26:09 -0800194 inline std::string
Jeff Thompson13e280b2013-12-03 13:12:23 -0800195 toUri() const;
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700196
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700197 /**
198 * @brief Check if Interest has any selectors present
199 */
Alexander Afanasyev84681982014-01-03 13:26:09 -0800200 inline bool
201 hasSelectors() const;
202
Alexander Afanasyev84681982014-01-03 13:26:09 -0800203 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700204 * @brief Check if Interest, including selectors, matches the given @p name
205 *
206 * @param name The name to be matched. If this is a Data name, it shall contain the
207 * implicit digest component
Alexander Afanasyev84681982014-01-03 13:26:09 -0800208 */
209 bool
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700210 matchesName(const Name& name) const;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800211
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700212 /**
213 * @brief Check if Interest can be satisfied by @p data.
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700214 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700215 * This method considers Name, MinSuffixComponents, MaxSuffixComponents,
216 * PublisherPublicKeyLocator, and Exclude.
217 * This method does not consider ChildSelector and MustBeFresh.
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700218 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700219 * @todo recognize implicit digest component
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700220 */
221 bool
222 matchesData(const Data& data) const;
223
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800224 ///////////////////////////////////////////////////////////////////////////////
225 ///////////////////////////////////////////////////////////////////////////////
226 ///////////////////////////////////////////////////////////////////////////////
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800227 // Getters/setters
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700228
229 const Name&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800230 getName() const
Jeff Thompsonc0486c12013-07-16 14:36:16 -0700231 {
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800232 return m_name;
233 }
234
235 Interest&
236 setName(const Name& name)
237 {
238 m_name = name;
239 m_wire.reset();
240 return *this;
Jeff Thompsonc0486c12013-07-16 14:36:16 -0700241 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700242
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800243 //
Alexander Afanasyev84681982014-01-03 13:26:09 -0800244
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800245 const Selectors&
246 getSelectors() const
247 {
248 return m_selectors;
249 }
250
251 Interest&
252 setSelectors(const Selectors& selectors)
253 {
254 m_selectors = selectors;
255 m_wire.reset();
256 return *this;
257 }
258
259 //
260
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700261 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800262 getScope() const
263 {
264 return m_scope;
265 }
266
267 Interest&
268 setScope(int scope)
269 {
270 m_scope = scope;
271 m_wire.reset();
272 return *this;
273 }
274
275 //
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700276
277 const time::milliseconds&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800278 getInterestLifetime() const
279 {
280 return m_interestLifetime;
281 }
282
283 Interest&
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700284 setInterestLifetime(const time::milliseconds& interestLifetime)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800285 {
286 m_interestLifetime = interestLifetime;
287 m_wire.reset();
288 return *this;
289 }
290
291 //
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700292
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800293 /**
294 * @brief Get Interest's nonce
295 *
296 * If nonce was not set before this call, it will be automatically assigned to a random value
297 *
298 * Const reference needed for C decoding
299 */
300 const uint32_t&
301 getNonce() const;
302
303 Interest&
304 setNonce(uint32_t nonce)
305 {
306 m_nonce = nonce;
307 m_wire.reset();
308 return *this;
309 }
310
311 //
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800312
313 nfd::LocalControlHeader&
314 getLocalControlHeader()
315 {
316 return m_localControlHeader;
317 }
318
319 const nfd::LocalControlHeader&
320 getLocalControlHeader() const
321 {
322 return m_localControlHeader;
323 }
324
325 // helper methods for LocalControlHeader
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700326
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800327 uint64_t
328 getIncomingFaceId() const
329 {
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800330 return getLocalControlHeader().getIncomingFaceId();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800331 }
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800332
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800333 Interest&
334 setIncomingFaceId(uint64_t incomingFaceId)
335 {
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800336 getLocalControlHeader().setIncomingFaceId(incomingFaceId);
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800337 // ! do not reset Interest's wire !
338 return *this;
339 }
340
341 //
342
343 // NextHopFaceId helpers make sense only for Interests
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700344
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800345 uint64_t
346 getNextHopFaceId() const
347 {
348 return getLocalControlHeader().getNextHopFaceId();
349 }
350
351 Interest&
352 setNextHopFaceId(uint64_t nextHopFaceId)
353 {
354 getLocalControlHeader().setNextHopFaceId(nextHopFaceId);
355 // ! do not reset Interest's wire !
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800356 return *this;
357 }
358
359 //
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700360
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800361 ///////////////////////////////////////////////////////////////////////////////
362 ///////////////////////////////////////////////////////////////////////////////
363 ///////////////////////////////////////////////////////////////////////////////
364 // Wrappers for Selectors
365 //
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700366
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800367 int
368 getMinSuffixComponents() const
369 {
370 return m_selectors.getMinSuffixComponents();
371 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700372
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800373 Interest&
374 setMinSuffixComponents(int minSuffixComponents)
375 {
376 m_selectors.setMinSuffixComponents(minSuffixComponents);
377 m_wire.reset();
378 return *this;
379 }
380
381 //
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700382
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800383 int
384 getMaxSuffixComponents() const
385 {
386 return m_selectors.getMaxSuffixComponents();
387 }
388
389 Interest&
390 setMaxSuffixComponents(int maxSuffixComponents)
391 {
392 m_selectors.setMaxSuffixComponents(maxSuffixComponents);
393 m_wire.reset();
394 return *this;
395 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700396
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800397 //
398
Junxiao Shib332e782014-03-31 14:23:46 -0700399 const KeyLocator&
400 getPublisherPublicKeyLocator() const
401 {
402 return m_selectors.getPublisherPublicKeyLocator();
403 }
404
405 Interest&
406 setPublisherPublicKeyLocator(const KeyLocator& keyLocator)
407 {
408 m_selectors.setPublisherPublicKeyLocator(keyLocator);
409 m_wire.reset();
410 return *this;
411 }
412
413 //
414
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800415 const Exclude&
416 getExclude() const
417 {
418 return m_selectors.getExclude();
419 }
420
421 Interest&
422 setExclude(const Exclude& exclude)
423 {
424 m_selectors.setExclude(exclude);
425 m_wire.reset();
426 return *this;
427 }
428
429 //
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700430
431 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800432 getChildSelector() const
433 {
434 return m_selectors.getChildSelector();
435 }
436
437 Interest&
438 setChildSelector(int childSelector)
439 {
440 m_selectors.setChildSelector(childSelector);
441 m_wire.reset();
442 return *this;
443 }
444
445 //
446
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700447 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800448 getMustBeFresh() const
449 {
450 return m_selectors.getMustBeFresh();
451 }
452
453 Interest&
454 setMustBeFresh(bool mustBeFresh)
455 {
456 m_selectors.setMustBeFresh(mustBeFresh);
457 m_wire.reset();
458 return *this;
459 }
460
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700461public: // EqualityComparable concept
462 bool
463 operator==(const Interest& other) const
464 {
465 return wireEncode() == other.wireEncode();
466 }
467
468 bool
469 operator!=(const Interest& other) const
470 {
471 return !(*this == other);
472 }
473
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800474private:
475 Name m_name;
476 Selectors m_selectors;
477 mutable uint32_t m_nonce;
478 int m_scope;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700479 time::milliseconds m_interestLifetime;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800480
481 mutable Block m_wire;
Yingdi Yua4e57672014-02-06 11:16:17 -0800482
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800483 nfd::LocalControlHeader m_localControlHeader;
484 friend class nfd::LocalControlHeader;
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700485};
Alexander Afanasyev84681982014-01-03 13:26:09 -0800486
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700487std::ostream&
488operator<<(std::ostream& os, const Interest& interest);
Alexander Afanasyev84681982014-01-03 13:26:09 -0800489
490inline std::string
491Interest::toUri() const
492{
493 std::ostringstream os;
494 os << *this;
495 return os.str();
496}
497
498inline bool
499Interest::hasSelectors() const
500{
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800501 return !m_selectors.empty();
Alexander Afanasyev84681982014-01-03 13:26:09 -0800502}
503
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800504template<bool T>
505inline size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700506Interest::wireEncode(EncodingImpl<T>& block) const
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800507{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700508 size_t totalLength = 0;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800509
510 // Interest ::= INTEREST-TYPE TLV-LENGTH
511 // Name
512 // Selectors?
513 // Nonce
514 // Scope?
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700515 // InterestLifetime?
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800516
517 // (reverse encoding)
518
519 // InterestLifetime
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700520 if (getInterestLifetime() >= time::milliseconds::zero() &&
521 getInterestLifetime() != DEFAULT_INTEREST_LIFETIME)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800522 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700523 totalLength += prependNonNegativeIntegerBlock(block,
524 Tlv::InterestLifetime,
525 getInterestLifetime().count());
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800526 }
527
528 // Scope
529 if (getScope() >= 0)
530 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700531 totalLength += prependNonNegativeIntegerBlock(block, Tlv::Scope, getScope());
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800532 }
533
534 // Nonce
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700535 totalLength += prependNonNegativeIntegerBlock(block, Tlv::Nonce, getNonce());
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800536
537 // Selectors
538 if (!getSelectors().empty())
539 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700540 totalLength += getSelectors().wireEncode(block);
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800541 }
542
543 // Name
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700544 totalLength += getName().wireEncode(block);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700545
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700546 totalLength += block.prependVarNumber (totalLength);
547 totalLength += block.prependVarNumber (Tlv::Interest);
548 return totalLength;
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700549}
550
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800551inline const Block&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800552Interest::wireEncode() const
553{
554 if (m_wire.hasWire())
555 return m_wire;
556
557 EncodingEstimator estimator;
558 size_t estimatedSize = wireEncode(estimator);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700559
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800560 EncodingBuffer buffer(estimatedSize, 0);
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800561 wireEncode(buffer);
562
563 m_wire = buffer.block();
564 return m_wire;
565}
566
567inline void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700568Interest::wireDecode(const Block& wire)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800569{
570 m_wire = wire;
571 m_wire.parse();
572
573 // Interest ::= INTEREST-TYPE TLV-LENGTH
574 // Name
575 // Selectors?
576 // Nonce
577 // Scope?
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700578 // InterestLifetime?
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800579
580 if (m_wire.type() != Tlv::Interest)
581 throw Tlv::Error("Unexpected TLV number when decoding Interest");
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700582
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800583 // Name
584 m_name.wireDecode(m_wire.get(Tlv::Name));
585
586 // Selectors
587 Block::element_const_iterator val = m_wire.find(Tlv::Selectors);
588 if (val != m_wire.elements_end())
589 {
590 m_selectors.wireDecode(*val);
591 }
592 else
593 m_selectors = Selectors();
594
595 // Nonce
596 val = m_wire.find(Tlv::Nonce);
597 if (val != m_wire.elements_end())
598 {
599 m_nonce = readNonNegativeInteger(*val);
600 }
601 else
602 m_nonce = 0;
603
604 // Scope
605 val = m_wire.find(Tlv::Scope);
606 if (val != m_wire.elements_end())
607 {
608 m_scope = readNonNegativeInteger(*val);
609 }
610 else
611 m_scope = -1;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700612
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800613 // InterestLifetime
614 val = m_wire.find(Tlv::InterestLifetime);
615 if (val != m_wire.elements_end())
616 {
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700617 m_interestLifetime = time::milliseconds(readNonNegativeInteger(*val));
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800618 }
619 else
620 {
621 m_interestLifetime = DEFAULT_INTEREST_LIFETIME;
622 }
623}
624
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800625inline bool
626Interest::hasWire() const
627{
628 return m_wire.hasWire();
629}
630
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800631
632} // namespace ndn
633
634#endif // NDN_INTEREST_HPP