blob: 7685433eb4cdfae8b42ba966021aa30b84e4fa65 [file] [log] [blame]
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/**
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.
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080011 */
12
13#ifndef NDN_META_INFO_HPP
14#define NDN_META_INFO_HPP
15
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080016#include "encoding/encoding-buffer.hpp"
17
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080018namespace ndn {
19
20/**
21 * An MetaInfo holds the meta info which is signed inside the data packet.
22 */
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070023class MetaInfo
24{
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080025public:
26 enum {
27 TYPE_DEFAULT = 0,
28 TYPE_LINK = 1,
29 TYPE_KEY = 2
30 };
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070031
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080032 MetaInfo()
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080033 : m_type(TYPE_DEFAULT)
34 , m_freshnessPeriod(-1)
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070035 {
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080036 }
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080037
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070038 /**
39 * @brief Create from wire encoding
40 */
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080041 MetaInfo(const Block& block)
42 {
43 wireDecode(block);
44 }
Alexander Afanasyevc348f832014-02-17 16:35:17 -080045
46 template<bool T>
47 size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070048 wireEncode(EncodingImpl<T>& block) const;
Alexander Afanasyevc348f832014-02-17 16:35:17 -080049
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070050 const Block&
Alexander Afanasyevc348f832014-02-17 16:35:17 -080051 wireEncode() const;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070052
Alexander Afanasyevc348f832014-02-17 16:35:17 -080053 void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070054 wireDecode(const Block& wire);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070055
Alexander Afanasyevc348f832014-02-17 16:35:17 -080056 ///////////////////////////////////////////////////////////////////////////////
Alexander Afanasyev5964fb72014-02-18 12:42:45 -080057 // Getters/setters
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070058
59 uint32_t
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080060 getType() const
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080061 {
62 return m_type;
63 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070064
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080065 MetaInfo&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080066 setType(uint32_t type)
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080067 {
68 m_wire.reset();
69 m_type = type;
70 return *this;
71 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070072
73 const time::milliseconds&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080074 getFreshnessPeriod() const
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080075 {
76 return m_freshnessPeriod;
77 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070078
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080079 MetaInfo&
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070080 setFreshnessPeriod(const time::milliseconds& freshnessPeriod)
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080081 {
82 m_wire.reset();
83 m_freshnessPeriod = freshnessPeriod;
84 return *this;
85 }
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080086
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080087 const name::Component&
88 getFinalBlockId() const
89 {
90 return m_finalBlockId;
91 }
92
93 MetaInfo&
94 setFinalBlockId(const name::Component& finalBlockId)
95 {
96 m_wire.reset();
97 m_finalBlockId = finalBlockId;
98 return *this;
99 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700100
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700101public: // EqualityComparable concept
102 bool
103 operator==(const MetaInfo& other) const
104 {
105 return wireEncode() == other.wireEncode();
106 }
107
108 bool
109 operator!=(const MetaInfo& other) const
110 {
111 return !(*this == other);
112 }
113
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800114private:
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800115 uint32_t m_type;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700116 time::milliseconds m_freshnessPeriod;
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800117 name::Component m_finalBlockId;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800118
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800119 mutable Block m_wire;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800120};
121
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800122template<bool T>
123inline size_t
124MetaInfo::wireEncode(EncodingImpl<T>& blk) const
125{
126 // MetaInfo ::= META-INFO-TYPE TLV-LENGTH
127 // ContentType?
128 // FreshnessPeriod?
129 // FinalBlockId?
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700130
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700131 size_t totalLength = 0;
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800132
133 // FinalBlockId
134 if (!m_finalBlockId.empty())
135 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700136 totalLength += prependNestedBlock(blk, Tlv::FinalBlockId, m_finalBlockId);
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800137 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700138
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800139 // FreshnessPeriod
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700140 if (m_freshnessPeriod >= time::milliseconds::zero())
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800141 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700142 totalLength += prependNonNegativeIntegerBlock(blk, Tlv::FreshnessPeriod,
143 m_freshnessPeriod.count());
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800144 }
145
146 // ContentType
147 if (m_type != TYPE_DEFAULT)
148 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700149 totalLength += prependNonNegativeIntegerBlock(blk, Tlv::ContentType, m_type);
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800150 }
151
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700152 totalLength += blk.prependVarNumber(totalLength);
153 totalLength += blk.prependVarNumber(Tlv::MetaInfo);
154 return totalLength;
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800155}
156
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700157inline const Block&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800158MetaInfo::wireEncode() const
159{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700160 if (m_wire.hasWire())
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800161 return m_wire;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800162
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800163 EncodingEstimator estimator;
164 size_t estimatedSize = wireEncode(estimator);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700165
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800166 EncodingBuffer buffer(estimatedSize, 0);
167 wireEncode(buffer);
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800168
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800169 m_wire = buffer.block();
170 return m_wire;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800171}
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700172
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800173inline void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700174MetaInfo::wireDecode(const Block& wire)
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800175{
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800176 m_wire = wire;
177 m_wire.parse();
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800178
Alexander Afanasyev213ea6d2014-01-03 15:31:03 -0800179 // MetaInfo ::= META-INFO-TYPE TLV-LENGTH
180 // ContentType?
181 // FreshnessPeriod?
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700182
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800183 // ContentType
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800184 Block::element_const_iterator val = m_wire.find(Tlv::ContentType);
185 if (val != m_wire.elements().end())
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800186 {
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800187 m_type = readNonNegativeInteger(*val);
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800188 }
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800189 else
190 m_type = TYPE_DEFAULT;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800191
192 // FreshnessPeriod
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800193 val = m_wire.find(Tlv::FreshnessPeriod);
194 if (val != m_wire.elements().end())
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800195 {
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700196 m_freshnessPeriod = time::milliseconds(readNonNegativeInteger(*val));
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800197 }
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800198 else
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700199 m_freshnessPeriod = time::milliseconds::min();
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800200
201 // FinalBlockId
202 val = m_wire.find(Tlv::FinalBlockId);
203 if (val != m_wire.elements().end())
204 {
205 m_finalBlockId = val->blockFromValue();
206 if (m_finalBlockId.type() != Tlv::NameComponent)
207 {
208 /// @todo May or may not throw exception later...
209 m_finalBlockId.reset();
210 }
211 }
212 else
213 m_finalBlockId.reset();
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800214}
215
Alexander Afanasyev4ff3c912014-01-03 15:25:02 -0800216inline std::ostream&
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700217operator<<(std::ostream& os, const MetaInfo& info)
Alexander Afanasyev4ff3c912014-01-03 15:25:02 -0800218{
219 // ContentType
220 os << "ContentType: " << info.getType();
221
222 // FreshnessPeriod
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700223 if (info.getFreshnessPeriod() >= time::milliseconds::zero()) {
Alexander Afanasyev4ff3c912014-01-03 15:25:02 -0800224 os << ", FreshnessPeriod: " << info.getFreshnessPeriod();
225 }
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800226
227 if (!info.getFinalBlockId().empty()) {
228 os << ", FinalBlockId: ";
229 info.getFinalBlockId().toUri(os);
230 }
Alexander Afanasyev4ff3c912014-01-03 15:25:02 -0800231 return os;
232}
233
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800234} // namespace ndn
235
236#endif // NDN_META_INFO_HPP