blob: 04cded1936ddcdde529279464d2f17e003b8c395 [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 Afanasyev95b0e342014-02-12 21:34:44 -080025#include "encoding/encoding-buffer.hpp"
26
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080027namespace ndn {
28
29/**
30 * An MetaInfo holds the meta info which is signed inside the data packet.
31 */
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070032class MetaInfo
33{
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080034public:
35 enum {
36 TYPE_DEFAULT = 0,
37 TYPE_LINK = 1,
38 TYPE_KEY = 2
39 };
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070040
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080041 MetaInfo()
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080042 : m_type(TYPE_DEFAULT)
43 , m_freshnessPeriod(-1)
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070044 {
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080045 }
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080046
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070047 /**
48 * @brief Create from wire encoding
49 */
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080050 MetaInfo(const Block& block)
51 {
52 wireDecode(block);
53 }
Alexander Afanasyevc348f832014-02-17 16:35:17 -080054
55 template<bool T>
56 size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070057 wireEncode(EncodingImpl<T>& block) const;
Alexander Afanasyevc348f832014-02-17 16:35:17 -080058
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070059 const Block&
Alexander Afanasyevc348f832014-02-17 16:35:17 -080060 wireEncode() const;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070061
Alexander Afanasyevc348f832014-02-17 16:35:17 -080062 void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070063 wireDecode(const Block& wire);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070064
Alexander Afanasyevc348f832014-02-17 16:35:17 -080065 ///////////////////////////////////////////////////////////////////////////////
Alexander Afanasyev5964fb72014-02-18 12:42:45 -080066 // Getters/setters
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070067
68 uint32_t
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080069 getType() const
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080070 {
71 return m_type;
72 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070073
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080074 MetaInfo&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080075 setType(uint32_t type)
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080076 {
77 m_wire.reset();
78 m_type = type;
79 return *this;
80 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070081
82 const time::milliseconds&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080083 getFreshnessPeriod() const
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080084 {
85 return m_freshnessPeriod;
86 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070087
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080088 MetaInfo&
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070089 setFreshnessPeriod(const time::milliseconds& freshnessPeriod)
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080090 {
91 m_wire.reset();
92 m_freshnessPeriod = freshnessPeriod;
93 return *this;
94 }
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080095
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080096 const name::Component&
97 getFinalBlockId() const
98 {
99 return m_finalBlockId;
100 }
101
102 MetaInfo&
103 setFinalBlockId(const name::Component& finalBlockId)
104 {
105 m_wire.reset();
106 m_finalBlockId = finalBlockId;
107 return *this;
108 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700109
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700110public: // EqualityComparable concept
111 bool
112 operator==(const MetaInfo& other) const
113 {
114 return wireEncode() == other.wireEncode();
115 }
116
117 bool
118 operator!=(const MetaInfo& other) const
119 {
120 return !(*this == other);
121 }
122
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800123private:
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800124 uint32_t m_type;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700125 time::milliseconds m_freshnessPeriod;
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800126 name::Component m_finalBlockId;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800127
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800128 mutable Block m_wire;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800129};
130
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800131template<bool T>
132inline size_t
133MetaInfo::wireEncode(EncodingImpl<T>& blk) const
134{
135 // MetaInfo ::= META-INFO-TYPE TLV-LENGTH
136 // ContentType?
137 // FreshnessPeriod?
138 // FinalBlockId?
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700139
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700140 size_t totalLength = 0;
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800141
142 // FinalBlockId
143 if (!m_finalBlockId.empty())
144 {
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600145 totalLength += prependNestedBlock(blk, tlv::FinalBlockId, m_finalBlockId);
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800146 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700147
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800148 // FreshnessPeriod
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700149 if (m_freshnessPeriod >= time::milliseconds::zero())
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800150 {
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600151 totalLength += prependNonNegativeIntegerBlock(blk, tlv::FreshnessPeriod,
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700152 m_freshnessPeriod.count());
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800153 }
154
155 // ContentType
156 if (m_type != TYPE_DEFAULT)
157 {
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600158 totalLength += prependNonNegativeIntegerBlock(blk, tlv::ContentType, m_type);
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800159 }
160
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700161 totalLength += blk.prependVarNumber(totalLength);
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600162 totalLength += blk.prependVarNumber(tlv::MetaInfo);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700163 return totalLength;
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800164}
165
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700166inline const Block&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800167MetaInfo::wireEncode() const
168{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700169 if (m_wire.hasWire())
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800170 return m_wire;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800171
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800172 EncodingEstimator estimator;
173 size_t estimatedSize = wireEncode(estimator);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700174
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800175 EncodingBuffer buffer(estimatedSize, 0);
176 wireEncode(buffer);
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800177
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800178 m_wire = buffer.block();
179 return m_wire;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800180}
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700181
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800182inline void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700183MetaInfo::wireDecode(const Block& wire)
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800184{
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800185 m_wire = wire;
186 m_wire.parse();
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800187
Alexander Afanasyev213ea6d2014-01-03 15:31:03 -0800188 // MetaInfo ::= META-INFO-TYPE TLV-LENGTH
189 // ContentType?
190 // FreshnessPeriod?
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700191
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800192 // ContentType
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600193 Block::element_const_iterator val = m_wire.find(tlv::ContentType);
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800194 if (val != m_wire.elements().end())
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800195 {
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800196 m_type = readNonNegativeInteger(*val);
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800197 }
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800198 else
199 m_type = TYPE_DEFAULT;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800200
201 // FreshnessPeriod
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600202 val = m_wire.find(tlv::FreshnessPeriod);
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800203 if (val != m_wire.elements().end())
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800204 {
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700205 m_freshnessPeriod = time::milliseconds(readNonNegativeInteger(*val));
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800206 }
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800207 else
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700208 m_freshnessPeriod = time::milliseconds::min();
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800209
210 // FinalBlockId
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600211 val = m_wire.find(tlv::FinalBlockId);
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800212 if (val != m_wire.elements().end())
213 {
214 m_finalBlockId = val->blockFromValue();
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600215 if (m_finalBlockId.type() != tlv::NameComponent)
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800216 {
217 /// @todo May or may not throw exception later...
218 m_finalBlockId.reset();
219 }
220 }
221 else
222 m_finalBlockId.reset();
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800223}
224
Alexander Afanasyev4ff3c912014-01-03 15:25:02 -0800225inline std::ostream&
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700226operator<<(std::ostream& os, const MetaInfo& info)
Alexander Afanasyev4ff3c912014-01-03 15:25:02 -0800227{
228 // ContentType
229 os << "ContentType: " << info.getType();
230
231 // FreshnessPeriod
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700232 if (info.getFreshnessPeriod() >= time::milliseconds::zero()) {
Alexander Afanasyev4ff3c912014-01-03 15:25:02 -0800233 os << ", FreshnessPeriod: " << info.getFreshnessPeriod();
234 }
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800235
236 if (!info.getFinalBlockId().empty()) {
237 os << ", FinalBlockId: ";
238 info.getFinalBlockId().toUri(os);
239 }
Alexander Afanasyev4ff3c912014-01-03 15:25:02 -0800240 return os;
241}
242
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800243} // namespace ndn
244
245#endif // NDN_META_INFO_HPP