blob: 138ea7ccbb8e730487451a741c7ea2f763810440 [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()
Alexander Afanasyeve881e932014-06-08 14:47:03 +030057 : m_scope(-1)
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070058 , m_interestLifetime(time::milliseconds::min())
Alexander Afanasyevc348f832014-02-17 16:35:17 -080059 {
60 }
61
62 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -070063 * @brief Create a new Interest with the given name
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070064 *
Alexander Afanasyevc348f832014-02-17 16:35:17 -080065 * @param name The name for the interest.
Alexander Afanasyev770827c2014-05-13 17:42:55 -070066 *
67 * Note that in certain contexts that use Interest::shared_from_this(), Interest must be
68 * created using `make_shared`:
69 *
70 * shared_ptr<Interest> interest = make_shared<Interest>(name);
71 *
72 * Otherwise, Interest::shared_from_this() will throw an exception.
Alexander Afanasyevc348f832014-02-17 16:35:17 -080073 */
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070074 Interest(const Name& name)
Alexander Afanasyevc348f832014-02-17 16:35:17 -080075 : m_name(name)
Alexander Afanasyevc348f832014-02-17 16:35:17 -080076 , m_scope(-1)
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070077 , m_interestLifetime(time::milliseconds::min())
Alexander Afanasyevc348f832014-02-17 16:35:17 -080078 {
79 }
80
81 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -070082 * @brief Create a new Interest with the given name and interest lifetime
83 *
84 * @param name The name for the interest.
85 * @param interestLifetime The interest lifetime in time::milliseconds, or -1 for none.
86 *
87 * Note that in certain contexts that use Interest::shared_from_this(), Interest must be
88 * created using `make_shared`:
89 *
90 * shared_ptr<Interest> interest = make_shared<Interest>(name, time::seconds(1));
91 *
92 * Otherwise, Interest::shared_from_this() will throw an exception.
Alexander Afanasyevc348f832014-02-17 16:35:17 -080093 */
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070094 Interest(const Name& name, const time::milliseconds& interestLifetime)
Alexander Afanasyevc348f832014-02-17 16:35:17 -080095 : m_name(name)
Alexander Afanasyevc348f832014-02-17 16:35:17 -080096 , m_scope(-1)
97 , m_interestLifetime(interestLifetime)
98 {
99 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700100
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700101 /**
102 * @brief Create a new Interest for the given name, selectors, and guiders
103 *
104 * Note that in certain contexts that use Interest::shared_from_this(), Interest must be
105 * created using `make_shared`:
106 *
107 * shared_ptr<Interest> interest = make_shared<Interest>(...);
108 *
109 * Otherwise, Interest::shared_from_this() will throw an exception.
110 */
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800111 Interest(const Name& name,
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700112 const Selectors& selectors,
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800113 int scope,
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700114 const time::milliseconds& interestLifetime,
115 uint32_t nonce = 0)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800116 : m_name(name)
117 , m_selectors(selectors)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800118 , m_scope(scope)
119 , m_interestLifetime(interestLifetime)
120 {
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300121 if (nonce > 0) {
122 setNonce(nonce);
123 }
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800124 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700125
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800126 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700127 * @brief Create a new Interest for the given name and parameters
Junxiao Shib332e782014-03-31 14:23:46 -0700128 *
129 * @deprecated Interest().setX(...).setY(...)
130 * or use the overload taking Selectors
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700131 *
132 * Note that in certain contexts that use Interest::shared_from_this(), Interest must be
133 * created using `make_shared`:
134 *
135 * shared_ptr<Interest> interest = make_shared<Interest>(...);
136 *
137 * Otherwise, Interest::shared_from_this() will throw an exception.
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800138 */
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700139 DEPRECATED(
Alexander Afanasyev84681982014-01-03 13:26:09 -0800140 Interest(const Name& name,
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700141 int minSuffixComponents, int maxSuffixComponents,
Alexander Afanasyev84681982014-01-03 13:26:09 -0800142 const Exclude& exclude,
143 int childSelector,
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700144 bool mustBeFresh,
Alexander Afanasyev84681982014-01-03 13:26:09 -0800145 int scope,
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700146 const time::milliseconds& interestLifetime,
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700147 uint32_t nonce = 0))
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800148 : m_name(name)
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700149 , m_selectors(Selectors()
150 .setMinSuffixComponents(minSuffixComponents)
151 .setMaxSuffixComponents(maxSuffixComponents)
152 .setExclude(exclude)
153 .setChildSelector(childSelector)
154 .setMustBeFresh(mustBeFresh))
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800155 , m_scope(scope)
156 , m_interestLifetime(interestLifetime)
Jeff Thompson3f76e9e2013-08-21 13:14:58 -0700157 {
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300158 if (nonce > 0) {
159 setNonce(nonce);
160 }
Jeff Thompson3f76e9e2013-08-21 13:14:58 -0700161 }
162
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700163 /**
164 * @brief Create from wire encoding
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700165 *
166 * Note that in certain contexts that use Interest::shared_from_this(), Interest must be
167 * created using `make_shared`:
168 *
169 * shared_ptr<Interest> interest = make_shared<Interest>(wire);
170 *
171 * Otherwise, Interest::shared_from_this() will throw an exception.
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700172 */
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800173 explicit
174 Interest(const Block& wire)
175 {
176 wireDecode(wire);
177 }
178
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800179 /**
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800180 * @brief Fast encoding or block size estimation
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800181 */
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800182 template<bool T>
183 inline size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700184 wireEncode(EncodingImpl<T>& block) const;
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800185
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800186 /**
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800187 * @brief Encode to a wire format
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800188 */
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800189 inline const Block&
Alexander Afanasyev1eb961a2014-01-03 13:51:49 -0800190 wireEncode() const;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800191
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800192 /**
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800193 * @brief Decode from the wire format
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800194 */
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700195 inline void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700196 wireDecode(const Block& wire);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800197
198 /**
199 * @brief Check if already has wire
200 */
201 inline bool
202 hasWire() const;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700203
Jeff Thompsond9e278c2013-07-08 15:20:13 -0700204 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700205 * @brief Encode the name according to the NDN URI Scheme
206 *
207 * If there are interest selectors, this method will append "?" and add the selectors as
208 * a query string. For example, "/test/name?ndn.ChildSelector=1"
Jeff Thompson13e280b2013-12-03 13:12:23 -0800209 */
Alexander Afanasyev84681982014-01-03 13:26:09 -0800210 inline std::string
Jeff Thompson13e280b2013-12-03 13:12:23 -0800211 toUri() const;
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700212
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700213 /**
214 * @brief Check if Interest has any selectors present
215 */
Alexander Afanasyev84681982014-01-03 13:26:09 -0800216 inline bool
217 hasSelectors() const;
218
Alexander Afanasyev84681982014-01-03 13:26:09 -0800219 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700220 * @brief Check if Interest, including selectors, matches the given @p name
221 *
222 * @param name The name to be matched. If this is a Data name, it shall contain the
223 * implicit digest component
Alexander Afanasyev84681982014-01-03 13:26:09 -0800224 */
225 bool
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700226 matchesName(const Name& name) const;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800227
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700228 /**
229 * @brief Check if Interest can be satisfied by @p data.
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700230 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700231 * This method considers Name, MinSuffixComponents, MaxSuffixComponents,
232 * PublisherPublicKeyLocator, and Exclude.
233 * This method does not consider ChildSelector and MustBeFresh.
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700234 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700235 * @todo recognize implicit digest component
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700236 */
237 bool
238 matchesData(const Data& data) const;
239
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800240 ///////////////////////////////////////////////////////////////////////////////
241 ///////////////////////////////////////////////////////////////////////////////
242 ///////////////////////////////////////////////////////////////////////////////
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800243 // Getters/setters
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700244
245 const Name&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800246 getName() const
Jeff Thompsonc0486c12013-07-16 14:36:16 -0700247 {
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800248 return m_name;
249 }
250
251 Interest&
252 setName(const Name& name)
253 {
254 m_name = name;
255 m_wire.reset();
256 return *this;
Jeff Thompsonc0486c12013-07-16 14:36:16 -0700257 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700258
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800259 //
Alexander Afanasyev84681982014-01-03 13:26:09 -0800260
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800261 const Selectors&
262 getSelectors() const
263 {
264 return m_selectors;
265 }
266
267 Interest&
268 setSelectors(const Selectors& selectors)
269 {
270 m_selectors = selectors;
271 m_wire.reset();
272 return *this;
273 }
274
275 //
276
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700277 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800278 getScope() const
279 {
280 return m_scope;
281 }
282
283 Interest&
284 setScope(int scope)
285 {
286 m_scope = scope;
287 m_wire.reset();
288 return *this;
289 }
290
291 //
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700292
293 const time::milliseconds&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800294 getInterestLifetime() const
295 {
296 return m_interestLifetime;
297 }
298
299 Interest&
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700300 setInterestLifetime(const time::milliseconds& interestLifetime)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800301 {
302 m_interestLifetime = interestLifetime;
303 m_wire.reset();
304 return *this;
305 }
306
307 //
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700308
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800309 /**
310 * @brief Get Interest's nonce
311 *
312 * If nonce was not set before this call, it will be automatically assigned to a random value
313 *
314 * Const reference needed for C decoding
315 */
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300316 uint32_t
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800317 getNonce() const;
318
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300319 /**
320 * @brief Check if Nonce set
321 */
322 bool
323 hasNonce() const
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800324 {
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300325 return m_nonce.hasWire();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800326 }
327
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300328 /**
329 * @brief Set Interest's nonce
330 *
331 * Note that if wire format already exists, this call simply replaces nonce in the
332 * existing wire format, without resetting and recreating it.
333 */
334 Interest&
335 setNonce(uint32_t nonce);
336
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800337 //
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800338
339 nfd::LocalControlHeader&
340 getLocalControlHeader()
341 {
342 return m_localControlHeader;
343 }
344
345 const nfd::LocalControlHeader&
346 getLocalControlHeader() const
347 {
348 return m_localControlHeader;
349 }
350
351 // helper methods for LocalControlHeader
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700352
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800353 uint64_t
354 getIncomingFaceId() const
355 {
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800356 return getLocalControlHeader().getIncomingFaceId();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800357 }
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800358
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800359 Interest&
360 setIncomingFaceId(uint64_t incomingFaceId)
361 {
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800362 getLocalControlHeader().setIncomingFaceId(incomingFaceId);
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800363 // ! do not reset Interest's wire !
364 return *this;
365 }
366
367 //
368
369 // NextHopFaceId helpers make sense only for Interests
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700370
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800371 uint64_t
372 getNextHopFaceId() const
373 {
374 return getLocalControlHeader().getNextHopFaceId();
375 }
376
377 Interest&
378 setNextHopFaceId(uint64_t nextHopFaceId)
379 {
380 getLocalControlHeader().setNextHopFaceId(nextHopFaceId);
381 // ! do not reset Interest's wire !
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800382 return *this;
383 }
384
385 //
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700386
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800387 ///////////////////////////////////////////////////////////////////////////////
388 ///////////////////////////////////////////////////////////////////////////////
389 ///////////////////////////////////////////////////////////////////////////////
390 // Wrappers for Selectors
391 //
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700392
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800393 int
394 getMinSuffixComponents() const
395 {
396 return m_selectors.getMinSuffixComponents();
397 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700398
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800399 Interest&
400 setMinSuffixComponents(int minSuffixComponents)
401 {
402 m_selectors.setMinSuffixComponents(minSuffixComponents);
403 m_wire.reset();
404 return *this;
405 }
406
407 //
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700408
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800409 int
410 getMaxSuffixComponents() const
411 {
412 return m_selectors.getMaxSuffixComponents();
413 }
414
415 Interest&
416 setMaxSuffixComponents(int maxSuffixComponents)
417 {
418 m_selectors.setMaxSuffixComponents(maxSuffixComponents);
419 m_wire.reset();
420 return *this;
421 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700422
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800423 //
424
Junxiao Shib332e782014-03-31 14:23:46 -0700425 const KeyLocator&
426 getPublisherPublicKeyLocator() const
427 {
428 return m_selectors.getPublisherPublicKeyLocator();
429 }
430
431 Interest&
432 setPublisherPublicKeyLocator(const KeyLocator& keyLocator)
433 {
434 m_selectors.setPublisherPublicKeyLocator(keyLocator);
435 m_wire.reset();
436 return *this;
437 }
438
439 //
440
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800441 const Exclude&
442 getExclude() const
443 {
444 return m_selectors.getExclude();
445 }
446
447 Interest&
448 setExclude(const Exclude& exclude)
449 {
450 m_selectors.setExclude(exclude);
451 m_wire.reset();
452 return *this;
453 }
454
455 //
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700456
457 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800458 getChildSelector() const
459 {
460 return m_selectors.getChildSelector();
461 }
462
463 Interest&
464 setChildSelector(int childSelector)
465 {
466 m_selectors.setChildSelector(childSelector);
467 m_wire.reset();
468 return *this;
469 }
470
471 //
472
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700473 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800474 getMustBeFresh() const
475 {
476 return m_selectors.getMustBeFresh();
477 }
478
479 Interest&
480 setMustBeFresh(bool mustBeFresh)
481 {
482 m_selectors.setMustBeFresh(mustBeFresh);
483 m_wire.reset();
484 return *this;
485 }
486
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700487public: // EqualityComparable concept
488 bool
489 operator==(const Interest& other) const
490 {
491 return wireEncode() == other.wireEncode();
492 }
493
494 bool
495 operator!=(const Interest& other) const
496 {
497 return !(*this == other);
498 }
499
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800500private:
501 Name m_name;
502 Selectors m_selectors;
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300503 mutable Block m_nonce;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800504 int m_scope;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700505 time::milliseconds m_interestLifetime;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800506
507 mutable Block m_wire;
Yingdi Yua4e57672014-02-06 11:16:17 -0800508
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800509 nfd::LocalControlHeader m_localControlHeader;
510 friend class nfd::LocalControlHeader;
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700511};
Alexander Afanasyev84681982014-01-03 13:26:09 -0800512
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700513std::ostream&
514operator<<(std::ostream& os, const Interest& interest);
Alexander Afanasyev84681982014-01-03 13:26:09 -0800515
516inline std::string
517Interest::toUri() const
518{
519 std::ostringstream os;
520 os << *this;
521 return os.str();
522}
523
524inline bool
525Interest::hasSelectors() const
526{
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800527 return !m_selectors.empty();
Alexander Afanasyev84681982014-01-03 13:26:09 -0800528}
529
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800530template<bool T>
531inline size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700532Interest::wireEncode(EncodingImpl<T>& block) const
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800533{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700534 size_t totalLength = 0;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800535
536 // Interest ::= INTEREST-TYPE TLV-LENGTH
537 // Name
538 // Selectors?
539 // Nonce
540 // Scope?
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700541 // InterestLifetime?
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800542
543 // (reverse encoding)
544
545 // InterestLifetime
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700546 if (getInterestLifetime() >= time::milliseconds::zero() &&
547 getInterestLifetime() != DEFAULT_INTEREST_LIFETIME)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800548 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700549 totalLength += prependNonNegativeIntegerBlock(block,
550 Tlv::InterestLifetime,
551 getInterestLifetime().count());
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800552 }
553
554 // Scope
555 if (getScope() >= 0)
556 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700557 totalLength += prependNonNegativeIntegerBlock(block, Tlv::Scope, getScope());
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800558 }
559
560 // Nonce
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300561 getNonce(); // to ensure that Nonce is properly set
562 totalLength += block.prependBlock(m_nonce);
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800563
564 // Selectors
565 if (!getSelectors().empty())
566 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700567 totalLength += getSelectors().wireEncode(block);
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800568 }
569
570 // Name
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700571 totalLength += getName().wireEncode(block);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700572
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300573 totalLength += block.prependVarNumber(totalLength);
574 totalLength += block.prependVarNumber(Tlv::Interest);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700575 return totalLength;
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700576}
577
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800578inline const Block&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800579Interest::wireEncode() const
580{
581 if (m_wire.hasWire())
582 return m_wire;
583
584 EncodingEstimator estimator;
585 size_t estimatedSize = wireEncode(estimator);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700586
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800587 EncodingBuffer buffer(estimatedSize, 0);
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800588 wireEncode(buffer);
589
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300590 // to ensure that Nonce block points to the right memory location
591 const_cast<Interest*>(this)->wireDecode(buffer.block());
592
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800593 return m_wire;
594}
595
596inline void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700597Interest::wireDecode(const Block& wire)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800598{
599 m_wire = wire;
600 m_wire.parse();
601
602 // Interest ::= INTEREST-TYPE TLV-LENGTH
603 // Name
604 // Selectors?
605 // Nonce
606 // Scope?
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700607 // InterestLifetime?
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800608
609 if (m_wire.type() != Tlv::Interest)
610 throw Tlv::Error("Unexpected TLV number when decoding Interest");
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700611
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800612 // Name
613 m_name.wireDecode(m_wire.get(Tlv::Name));
614
615 // Selectors
616 Block::element_const_iterator val = m_wire.find(Tlv::Selectors);
617 if (val != m_wire.elements_end())
618 {
619 m_selectors.wireDecode(*val);
620 }
621 else
622 m_selectors = Selectors();
623
624 // Nonce
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300625 m_nonce = m_wire.get(Tlv::Nonce);
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800626
627 // Scope
628 val = m_wire.find(Tlv::Scope);
629 if (val != m_wire.elements_end())
630 {
631 m_scope = readNonNegativeInteger(*val);
632 }
633 else
634 m_scope = -1;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700635
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800636 // InterestLifetime
637 val = m_wire.find(Tlv::InterestLifetime);
638 if (val != m_wire.elements_end())
639 {
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700640 m_interestLifetime = time::milliseconds(readNonNegativeInteger(*val));
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800641 }
642 else
643 {
644 m_interestLifetime = DEFAULT_INTEREST_LIFETIME;
645 }
646}
647
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800648inline bool
649Interest::hasWire() const
650{
651 return m_wire.hasWire();
652}
653
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800654
655} // namespace ndn
656
657#endif // NDN_INTEREST_HPP