blob: ea23392c581c9343f7121fa457afc4fb034be756 [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 Afanasyev9c578182014-05-14 17:28:28 -0700131 DEPRECATED(
Alexander Afanasyev84681982014-01-03 13:26:09 -0800132 Interest(const Name& name,
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700133 int minSuffixComponents, int maxSuffixComponents,
Alexander Afanasyev84681982014-01-03 13:26:09 -0800134 const Exclude& exclude,
135 int childSelector,
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700136 bool mustBeFresh,
Alexander Afanasyev84681982014-01-03 13:26:09 -0800137 int scope,
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700138 const time::milliseconds& interestLifetime,
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700139 uint32_t nonce = 0))
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800140 : m_name(name)
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700141 , m_selectors(Selectors()
142 .setMinSuffixComponents(minSuffixComponents)
143 .setMaxSuffixComponents(maxSuffixComponents)
144 .setExclude(exclude)
145 .setChildSelector(childSelector)
146 .setMustBeFresh(mustBeFresh))
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800147 , m_nonce(nonce)
148 , m_scope(scope)
149 , m_interestLifetime(interestLifetime)
Jeff Thompson3f76e9e2013-08-21 13:14:58 -0700150 {
151 }
152
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700153 /**
154 * @brief Create from wire encoding
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700155 *
156 * Note that in certain contexts that use Interest::shared_from_this(), Interest must be
157 * created using `make_shared`:
158 *
159 * shared_ptr<Interest> interest = make_shared<Interest>(wire);
160 *
161 * Otherwise, Interest::shared_from_this() will throw an exception.
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700162 */
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800163 explicit
164 Interest(const Block& wire)
165 {
166 wireDecode(wire);
167 }
168
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800169 /**
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800170 * @brief Fast encoding or block size estimation
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800171 */
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800172 template<bool T>
173 inline size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700174 wireEncode(EncodingImpl<T>& block) const;
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800175
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800176 /**
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800177 * @brief Encode to a wire format
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800178 */
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800179 inline const Block&
Alexander Afanasyev1eb961a2014-01-03 13:51:49 -0800180 wireEncode() const;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800181
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800182 /**
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800183 * @brief Decode from the wire format
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800184 */
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700185 inline void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700186 wireDecode(const Block& wire);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800187
188 /**
189 * @brief Check if already has wire
190 */
191 inline bool
192 hasWire() const;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700193
Jeff Thompsond9e278c2013-07-08 15:20:13 -0700194 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700195 * @brief Encode the name according to the NDN URI Scheme
196 *
197 * If there are interest selectors, this method will append "?" and add the selectors as
198 * a query string. For example, "/test/name?ndn.ChildSelector=1"
Jeff Thompson13e280b2013-12-03 13:12:23 -0800199 */
Alexander Afanasyev84681982014-01-03 13:26:09 -0800200 inline std::string
Jeff Thompson13e280b2013-12-03 13:12:23 -0800201 toUri() const;
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700202
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700203 /**
204 * @brief Check if Interest has any selectors present
205 */
Alexander Afanasyev84681982014-01-03 13:26:09 -0800206 inline bool
207 hasSelectors() const;
208
Alexander Afanasyev84681982014-01-03 13:26:09 -0800209 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700210 * @brief Check if Interest, including selectors, matches the given @p name
211 *
212 * @param name The name to be matched. If this is a Data name, it shall contain the
213 * implicit digest component
Alexander Afanasyev84681982014-01-03 13:26:09 -0800214 */
215 bool
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700216 matchesName(const Name& name) const;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800217
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700218 /**
219 * @brief Check if Interest can be satisfied by @p data.
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700220 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700221 * This method considers Name, MinSuffixComponents, MaxSuffixComponents,
222 * PublisherPublicKeyLocator, and Exclude.
223 * This method does not consider ChildSelector and MustBeFresh.
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700224 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700225 * @todo recognize implicit digest component
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700226 */
227 bool
228 matchesData(const Data& data) const;
229
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800230 ///////////////////////////////////////////////////////////////////////////////
231 ///////////////////////////////////////////////////////////////////////////////
232 ///////////////////////////////////////////////////////////////////////////////
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800233 // Getters/setters
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700234
235 const Name&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800236 getName() const
Jeff Thompsonc0486c12013-07-16 14:36:16 -0700237 {
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800238 return m_name;
239 }
240
241 Interest&
242 setName(const Name& name)
243 {
244 m_name = name;
245 m_wire.reset();
246 return *this;
Jeff Thompsonc0486c12013-07-16 14:36:16 -0700247 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700248
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800249 //
Alexander Afanasyev84681982014-01-03 13:26:09 -0800250
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800251 const Selectors&
252 getSelectors() const
253 {
254 return m_selectors;
255 }
256
257 Interest&
258 setSelectors(const Selectors& selectors)
259 {
260 m_selectors = selectors;
261 m_wire.reset();
262 return *this;
263 }
264
265 //
266
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700267 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800268 getScope() const
269 {
270 return m_scope;
271 }
272
273 Interest&
274 setScope(int scope)
275 {
276 m_scope = scope;
277 m_wire.reset();
278 return *this;
279 }
280
281 //
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700282
283 const time::milliseconds&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800284 getInterestLifetime() const
285 {
286 return m_interestLifetime;
287 }
288
289 Interest&
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700290 setInterestLifetime(const time::milliseconds& interestLifetime)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800291 {
292 m_interestLifetime = interestLifetime;
293 m_wire.reset();
294 return *this;
295 }
296
297 //
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700298
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800299 /**
300 * @brief Get Interest's nonce
301 *
302 * If nonce was not set before this call, it will be automatically assigned to a random value
303 *
304 * Const reference needed for C decoding
305 */
306 const uint32_t&
307 getNonce() const;
308
309 Interest&
310 setNonce(uint32_t nonce)
311 {
312 m_nonce = nonce;
313 m_wire.reset();
314 return *this;
315 }
316
317 //
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800318
319 nfd::LocalControlHeader&
320 getLocalControlHeader()
321 {
322 return m_localControlHeader;
323 }
324
325 const nfd::LocalControlHeader&
326 getLocalControlHeader() const
327 {
328 return m_localControlHeader;
329 }
330
331 // helper methods for LocalControlHeader
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700332
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800333 uint64_t
334 getIncomingFaceId() const
335 {
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800336 return getLocalControlHeader().getIncomingFaceId();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800337 }
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800338
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800339 Interest&
340 setIncomingFaceId(uint64_t incomingFaceId)
341 {
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800342 getLocalControlHeader().setIncomingFaceId(incomingFaceId);
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800343 // ! do not reset Interest's wire !
344 return *this;
345 }
346
347 //
348
349 // NextHopFaceId helpers make sense only for Interests
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700350
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800351 uint64_t
352 getNextHopFaceId() const
353 {
354 return getLocalControlHeader().getNextHopFaceId();
355 }
356
357 Interest&
358 setNextHopFaceId(uint64_t nextHopFaceId)
359 {
360 getLocalControlHeader().setNextHopFaceId(nextHopFaceId);
361 // ! do not reset Interest's wire !
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800362 return *this;
363 }
364
365 //
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700366
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800367 ///////////////////////////////////////////////////////////////////////////////
368 ///////////////////////////////////////////////////////////////////////////////
369 ///////////////////////////////////////////////////////////////////////////////
370 // Wrappers for Selectors
371 //
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700372
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800373 int
374 getMinSuffixComponents() const
375 {
376 return m_selectors.getMinSuffixComponents();
377 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700378
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800379 Interest&
380 setMinSuffixComponents(int minSuffixComponents)
381 {
382 m_selectors.setMinSuffixComponents(minSuffixComponents);
383 m_wire.reset();
384 return *this;
385 }
386
387 //
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700388
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800389 int
390 getMaxSuffixComponents() const
391 {
392 return m_selectors.getMaxSuffixComponents();
393 }
394
395 Interest&
396 setMaxSuffixComponents(int maxSuffixComponents)
397 {
398 m_selectors.setMaxSuffixComponents(maxSuffixComponents);
399 m_wire.reset();
400 return *this;
401 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700402
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800403 //
404
Junxiao Shib332e782014-03-31 14:23:46 -0700405 const KeyLocator&
406 getPublisherPublicKeyLocator() const
407 {
408 return m_selectors.getPublisherPublicKeyLocator();
409 }
410
411 Interest&
412 setPublisherPublicKeyLocator(const KeyLocator& keyLocator)
413 {
414 m_selectors.setPublisherPublicKeyLocator(keyLocator);
415 m_wire.reset();
416 return *this;
417 }
418
419 //
420
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800421 const Exclude&
422 getExclude() const
423 {
424 return m_selectors.getExclude();
425 }
426
427 Interest&
428 setExclude(const Exclude& exclude)
429 {
430 m_selectors.setExclude(exclude);
431 m_wire.reset();
432 return *this;
433 }
434
435 //
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700436
437 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800438 getChildSelector() const
439 {
440 return m_selectors.getChildSelector();
441 }
442
443 Interest&
444 setChildSelector(int childSelector)
445 {
446 m_selectors.setChildSelector(childSelector);
447 m_wire.reset();
448 return *this;
449 }
450
451 //
452
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700453 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800454 getMustBeFresh() const
455 {
456 return m_selectors.getMustBeFresh();
457 }
458
459 Interest&
460 setMustBeFresh(bool mustBeFresh)
461 {
462 m_selectors.setMustBeFresh(mustBeFresh);
463 m_wire.reset();
464 return *this;
465 }
466
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700467public: // EqualityComparable concept
468 bool
469 operator==(const Interest& other) const
470 {
471 return wireEncode() == other.wireEncode();
472 }
473
474 bool
475 operator!=(const Interest& other) const
476 {
477 return !(*this == other);
478 }
479
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800480private:
481 Name m_name;
482 Selectors m_selectors;
483 mutable uint32_t m_nonce;
484 int m_scope;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700485 time::milliseconds m_interestLifetime;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800486
487 mutable Block m_wire;
Yingdi Yua4e57672014-02-06 11:16:17 -0800488
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800489 nfd::LocalControlHeader m_localControlHeader;
490 friend class nfd::LocalControlHeader;
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700491};
Alexander Afanasyev84681982014-01-03 13:26:09 -0800492
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700493std::ostream&
494operator<<(std::ostream& os, const Interest& interest);
Alexander Afanasyev84681982014-01-03 13:26:09 -0800495
496inline std::string
497Interest::toUri() const
498{
499 std::ostringstream os;
500 os << *this;
501 return os.str();
502}
503
504inline bool
505Interest::hasSelectors() const
506{
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800507 return !m_selectors.empty();
Alexander Afanasyev84681982014-01-03 13:26:09 -0800508}
509
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800510template<bool T>
511inline size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700512Interest::wireEncode(EncodingImpl<T>& block) const
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800513{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700514 size_t totalLength = 0;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800515
516 // Interest ::= INTEREST-TYPE TLV-LENGTH
517 // Name
518 // Selectors?
519 // Nonce
520 // Scope?
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700521 // InterestLifetime?
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800522
523 // (reverse encoding)
524
525 // InterestLifetime
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700526 if (getInterestLifetime() >= time::milliseconds::zero() &&
527 getInterestLifetime() != DEFAULT_INTEREST_LIFETIME)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800528 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700529 totalLength += prependNonNegativeIntegerBlock(block,
530 Tlv::InterestLifetime,
531 getInterestLifetime().count());
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800532 }
533
534 // Scope
535 if (getScope() >= 0)
536 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700537 totalLength += prependNonNegativeIntegerBlock(block, Tlv::Scope, getScope());
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800538 }
539
540 // Nonce
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700541 totalLength += prependNonNegativeIntegerBlock(block, Tlv::Nonce, getNonce());
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800542
543 // Selectors
544 if (!getSelectors().empty())
545 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700546 totalLength += getSelectors().wireEncode(block);
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800547 }
548
549 // Name
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700550 totalLength += getName().wireEncode(block);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700551
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700552 totalLength += block.prependVarNumber (totalLength);
553 totalLength += block.prependVarNumber (Tlv::Interest);
554 return totalLength;
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700555}
556
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800557inline const Block&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800558Interest::wireEncode() const
559{
560 if (m_wire.hasWire())
561 return m_wire;
562
563 EncodingEstimator estimator;
564 size_t estimatedSize = wireEncode(estimator);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700565
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800566 EncodingBuffer buffer(estimatedSize, 0);
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800567 wireEncode(buffer);
568
569 m_wire = buffer.block();
570 return m_wire;
571}
572
573inline void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700574Interest::wireDecode(const Block& wire)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800575{
576 m_wire = wire;
577 m_wire.parse();
578
579 // Interest ::= INTEREST-TYPE TLV-LENGTH
580 // Name
581 // Selectors?
582 // Nonce
583 // Scope?
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700584 // InterestLifetime?
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800585
586 if (m_wire.type() != Tlv::Interest)
587 throw Tlv::Error("Unexpected TLV number when decoding Interest");
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700588
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800589 // Name
590 m_name.wireDecode(m_wire.get(Tlv::Name));
591
592 // Selectors
593 Block::element_const_iterator val = m_wire.find(Tlv::Selectors);
594 if (val != m_wire.elements_end())
595 {
596 m_selectors.wireDecode(*val);
597 }
598 else
599 m_selectors = Selectors();
600
601 // Nonce
602 val = m_wire.find(Tlv::Nonce);
603 if (val != m_wire.elements_end())
604 {
605 m_nonce = readNonNegativeInteger(*val);
606 }
607 else
608 m_nonce = 0;
609
610 // Scope
611 val = m_wire.find(Tlv::Scope);
612 if (val != m_wire.elements_end())
613 {
614 m_scope = readNonNegativeInteger(*val);
615 }
616 else
617 m_scope = -1;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700618
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800619 // InterestLifetime
620 val = m_wire.find(Tlv::InterestLifetime);
621 if (val != m_wire.elements_end())
622 {
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700623 m_interestLifetime = time::milliseconds(readNonNegativeInteger(*val));
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800624 }
625 else
626 {
627 m_interestLifetime = DEFAULT_INTEREST_LIFETIME;
628 }
629}
630
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800631inline bool
632Interest::hasWire() const
633{
634 return m_wire.hasWire();
635}
636
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800637
638} // namespace ndn
639
640#endif // NDN_INTEREST_HPP