blob: ed5605da5739f5e2f2a25ce3a9c90fab7f0b5c8a [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -08002/**
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 Afanasyev2ba8f662014-01-05 22:53:18 -080020 */
21
22#ifndef NDN_META_INFO_HPP
23#define NDN_META_INFO_HPP
24
Alexander Afanasyev15f67312014-07-22 15:11:09 -070025#include "common.hpp"
26#include "encoding/block-helpers.hpp"
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080027#include "encoding/encoding-buffer.hpp"
Alexander Afanasyev15f67312014-07-22 15:11:09 -070028#include "util/time.hpp"
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080029
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080030namespace ndn {
31
32/**
33 * An MetaInfo holds the meta info which is signed inside the data packet.
34 */
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070035class MetaInfo
36{
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080037public:
38 enum {
39 TYPE_DEFAULT = 0,
40 TYPE_LINK = 1,
41 TYPE_KEY = 2
42 };
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070043
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080044 MetaInfo()
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080045 : m_type(TYPE_DEFAULT)
46 , m_freshnessPeriod(-1)
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070047 {
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080048 }
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080049
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070050 /**
51 * @brief Create from wire encoding
52 */
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080053 MetaInfo(const Block& block)
54 {
55 wireDecode(block);
56 }
Alexander Afanasyevc348f832014-02-17 16:35:17 -080057
58 template<bool T>
59 size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070060 wireEncode(EncodingImpl<T>& block) const;
Alexander Afanasyevc348f832014-02-17 16:35:17 -080061
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070062 const Block&
Alexander Afanasyevc348f832014-02-17 16:35:17 -080063 wireEncode() const;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070064
Alexander Afanasyevc348f832014-02-17 16:35:17 -080065 void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070066 wireDecode(const Block& wire);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070067
Alexander Afanasyevc348f832014-02-17 16:35:17 -080068 ///////////////////////////////////////////////////////////////////////////////
Alexander Afanasyev5964fb72014-02-18 12:42:45 -080069 // Getters/setters
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070070
71 uint32_t
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080072 getType() const
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080073 {
74 return m_type;
75 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070076
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080077 MetaInfo&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080078 setType(uint32_t type)
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080079 {
80 m_wire.reset();
81 m_type = type;
82 return *this;
83 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070084
85 const time::milliseconds&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080086 getFreshnessPeriod() const
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080087 {
88 return m_freshnessPeriod;
89 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070090
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080091 MetaInfo&
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070092 setFreshnessPeriod(const time::milliseconds& freshnessPeriod)
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080093 {
94 m_wire.reset();
95 m_freshnessPeriod = freshnessPeriod;
96 return *this;
97 }
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080098
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080099 const name::Component&
100 getFinalBlockId() const
101 {
102 return m_finalBlockId;
103 }
104
105 MetaInfo&
106 setFinalBlockId(const name::Component& finalBlockId)
107 {
108 m_wire.reset();
109 m_finalBlockId = finalBlockId;
110 return *this;
111 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700112
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700113public: // EqualityComparable concept
114 bool
115 operator==(const MetaInfo& other) const
116 {
117 return wireEncode() == other.wireEncode();
118 }
119
120 bool
121 operator!=(const MetaInfo& other) const
122 {
123 return !(*this == other);
124 }
125
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800126private:
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800127 uint32_t m_type;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700128 time::milliseconds m_freshnessPeriod;
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800129 name::Component m_finalBlockId;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800130
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800131 mutable Block m_wire;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800132};
133
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800134template<bool T>
135inline size_t
136MetaInfo::wireEncode(EncodingImpl<T>& blk) const
137{
138 // MetaInfo ::= META-INFO-TYPE TLV-LENGTH
139 // ContentType?
140 // FreshnessPeriod?
141 // FinalBlockId?
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700142
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700143 size_t totalLength = 0;
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800144
145 // FinalBlockId
146 if (!m_finalBlockId.empty())
147 {
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600148 totalLength += prependNestedBlock(blk, tlv::FinalBlockId, m_finalBlockId);
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800149 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700150
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800151 // FreshnessPeriod
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700152 if (m_freshnessPeriod >= time::milliseconds::zero())
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800153 {
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600154 totalLength += prependNonNegativeIntegerBlock(blk, tlv::FreshnessPeriod,
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700155 m_freshnessPeriod.count());
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800156 }
157
158 // ContentType
159 if (m_type != TYPE_DEFAULT)
160 {
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600161 totalLength += prependNonNegativeIntegerBlock(blk, tlv::ContentType, m_type);
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800162 }
163
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700164 totalLength += blk.prependVarNumber(totalLength);
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600165 totalLength += blk.prependVarNumber(tlv::MetaInfo);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700166 return totalLength;
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800167}
168
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700169inline const Block&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800170MetaInfo::wireEncode() const
171{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700172 if (m_wire.hasWire())
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800173 return m_wire;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800174
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800175 EncodingEstimator estimator;
176 size_t estimatedSize = wireEncode(estimator);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700177
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800178 EncodingBuffer buffer(estimatedSize, 0);
179 wireEncode(buffer);
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800180
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800181 m_wire = buffer.block();
182 return m_wire;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800183}
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700184
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800185inline void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700186MetaInfo::wireDecode(const Block& wire)
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800187{
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800188 m_wire = wire;
189 m_wire.parse();
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800190
Alexander Afanasyev213ea6d2014-01-03 15:31:03 -0800191 // MetaInfo ::= META-INFO-TYPE TLV-LENGTH
192 // ContentType?
193 // FreshnessPeriod?
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700194
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800195 // ContentType
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600196 Block::element_const_iterator val = m_wire.find(tlv::ContentType);
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800197 if (val != m_wire.elements().end())
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800198 {
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800199 m_type = readNonNegativeInteger(*val);
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800200 }
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800201 else
202 m_type = TYPE_DEFAULT;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800203
204 // FreshnessPeriod
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600205 val = m_wire.find(tlv::FreshnessPeriod);
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800206 if (val != m_wire.elements().end())
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800207 {
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700208 m_freshnessPeriod = time::milliseconds(readNonNegativeInteger(*val));
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800209 }
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800210 else
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700211 m_freshnessPeriod = time::milliseconds::min();
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800212
213 // FinalBlockId
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600214 val = m_wire.find(tlv::FinalBlockId);
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800215 if (val != m_wire.elements().end())
216 {
217 m_finalBlockId = val->blockFromValue();
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600218 if (m_finalBlockId.type() != tlv::NameComponent)
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800219 {
220 /// @todo May or may not throw exception later...
221 m_finalBlockId.reset();
222 }
223 }
224 else
225 m_finalBlockId.reset();
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800226}
227
Alexander Afanasyev4ff3c912014-01-03 15:25:02 -0800228inline std::ostream&
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700229operator<<(std::ostream& os, const MetaInfo& info)
Alexander Afanasyev4ff3c912014-01-03 15:25:02 -0800230{
231 // ContentType
232 os << "ContentType: " << info.getType();
233
234 // FreshnessPeriod
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700235 if (info.getFreshnessPeriod() >= time::milliseconds::zero()) {
Alexander Afanasyev4ff3c912014-01-03 15:25:02 -0800236 os << ", FreshnessPeriod: " << info.getFreshnessPeriod();
237 }
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800238
239 if (!info.getFinalBlockId().empty()) {
240 os << ", FinalBlockId: ";
241 info.getFinalBlockId().toUri(os);
242 }
Alexander Afanasyev4ff3c912014-01-03 15:25:02 -0800243 return os;
244}
245
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800246} // namespace ndn
247
248#endif // NDN_META_INFO_HPP