blob: 8042f8b5a1d3f3eb78aeff38e093067ae740ef51 [file] [log] [blame]
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/**
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -07003 * Copyright (C) 2013-2014 Regents of the University of California.
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -08004 * See COPYING for copyright and distribution information.
5 */
6
7#ifndef NDN_META_INFO_HPP
8#define NDN_META_INFO_HPP
9
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080010#include "encoding/encoding-buffer.hpp"
11
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080012namespace ndn {
13
14/**
15 * An MetaInfo holds the meta info which is signed inside the data packet.
16 */
17class MetaInfo {
18public:
19 enum {
20 TYPE_DEFAULT = 0,
21 TYPE_LINK = 1,
22 TYPE_KEY = 2
23 };
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070024
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080025 MetaInfo()
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080026 : m_type(TYPE_DEFAULT)
27 , m_freshnessPeriod(-1)
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070028 {
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080029 }
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080030
31 MetaInfo(const Block& block)
32 {
33 wireDecode(block);
34 }
Alexander Afanasyevc348f832014-02-17 16:35:17 -080035
36 template<bool T>
37 size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070038 wireEncode(EncodingImpl<T>& block) const;
Alexander Afanasyevc348f832014-02-17 16:35:17 -080039
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070040 const Block&
Alexander Afanasyevc348f832014-02-17 16:35:17 -080041 wireEncode() const;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070042
Alexander Afanasyevc348f832014-02-17 16:35:17 -080043 void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070044 wireDecode(const Block& wire);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070045
Alexander Afanasyevc348f832014-02-17 16:35:17 -080046 ///////////////////////////////////////////////////////////////////////////////
Alexander Afanasyev5964fb72014-02-18 12:42:45 -080047 // Getters/setters
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070048
49 uint32_t
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080050 getType() const
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080051 {
52 return m_type;
53 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070054
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080055 MetaInfo&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080056 setType(uint32_t type)
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080057 {
58 m_wire.reset();
59 m_type = type;
60 return *this;
61 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070062
63 const time::milliseconds&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080064 getFreshnessPeriod() const
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080065 {
66 return m_freshnessPeriod;
67 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070068
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080069 MetaInfo&
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070070 setFreshnessPeriod(const time::milliseconds& freshnessPeriod)
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080071 {
72 m_wire.reset();
73 m_freshnessPeriod = freshnessPeriod;
74 return *this;
75 }
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080076
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080077 const name::Component&
78 getFinalBlockId() const
79 {
80 return m_finalBlockId;
81 }
82
83 MetaInfo&
84 setFinalBlockId(const name::Component& finalBlockId)
85 {
86 m_wire.reset();
87 m_finalBlockId = finalBlockId;
88 return *this;
89 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070090
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070091public: // EqualityComparable concept
92 bool
93 operator==(const MetaInfo& other) const
94 {
95 return wireEncode() == other.wireEncode();
96 }
97
98 bool
99 operator!=(const MetaInfo& other) const
100 {
101 return !(*this == other);
102 }
103
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800104private:
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800105 uint32_t m_type;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700106 time::milliseconds m_freshnessPeriod;
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800107 name::Component m_finalBlockId;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800108
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800109 mutable Block m_wire;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800110};
111
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800112template<bool T>
113inline size_t
114MetaInfo::wireEncode(EncodingImpl<T>& blk) const
115{
116 // MetaInfo ::= META-INFO-TYPE TLV-LENGTH
117 // ContentType?
118 // FreshnessPeriod?
119 // FinalBlockId?
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700120
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800121 size_t total_len = 0;
122
123 // FinalBlockId
124 if (!m_finalBlockId.empty())
125 {
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800126 total_len += prependNestedBlock(blk, Tlv::FinalBlockId, m_finalBlockId);
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800127 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700128
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800129 // FreshnessPeriod
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700130 if (m_freshnessPeriod >= time::milliseconds::zero())
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800131 {
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700132 total_len += prependNonNegativeIntegerBlock(blk, Tlv::FreshnessPeriod,
133 m_freshnessPeriod.count());
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800134 }
135
136 // ContentType
137 if (m_type != TYPE_DEFAULT)
138 {
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800139 total_len += prependNonNegativeIntegerBlock(blk, Tlv::ContentType, m_type);
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800140 }
141
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700142 total_len += blk.prependVarNumber(total_len);
143 total_len += blk.prependVarNumber(Tlv::MetaInfo);
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800144 return total_len;
145}
146
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700147inline const Block&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800148MetaInfo::wireEncode() const
149{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700150 if (m_wire.hasWire())
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800151 return m_wire;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800152
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800153 EncodingEstimator estimator;
154 size_t estimatedSize = wireEncode(estimator);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700155
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800156 EncodingBuffer buffer(estimatedSize, 0);
157 wireEncode(buffer);
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800158
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800159 m_wire = buffer.block();
160 return m_wire;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800161}
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700162
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800163inline void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700164MetaInfo::wireDecode(const Block& wire)
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800165{
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800166 m_wire = wire;
167 m_wire.parse();
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800168
Alexander Afanasyev213ea6d2014-01-03 15:31:03 -0800169 // MetaInfo ::= META-INFO-TYPE TLV-LENGTH
170 // ContentType?
171 // FreshnessPeriod?
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700172
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800173 // ContentType
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800174 Block::element_const_iterator val = m_wire.find(Tlv::ContentType);
175 if (val != m_wire.elements().end())
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800176 {
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800177 m_type = readNonNegativeInteger(*val);
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800178 }
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800179 else
180 m_type = TYPE_DEFAULT;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800181
182 // FreshnessPeriod
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800183 val = m_wire.find(Tlv::FreshnessPeriod);
184 if (val != m_wire.elements().end())
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800185 {
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700186 m_freshnessPeriod = time::milliseconds(readNonNegativeInteger(*val));
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800187 }
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800188 else
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700189 m_freshnessPeriod = time::milliseconds::min();
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800190
191 // FinalBlockId
192 val = m_wire.find(Tlv::FinalBlockId);
193 if (val != m_wire.elements().end())
194 {
195 m_finalBlockId = val->blockFromValue();
196 if (m_finalBlockId.type() != Tlv::NameComponent)
197 {
198 /// @todo May or may not throw exception later...
199 m_finalBlockId.reset();
200 }
201 }
202 else
203 m_finalBlockId.reset();
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800204}
205
Alexander Afanasyev4ff3c912014-01-03 15:25:02 -0800206inline std::ostream&
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700207operator<<(std::ostream& os, const MetaInfo& info)
Alexander Afanasyev4ff3c912014-01-03 15:25:02 -0800208{
209 // ContentType
210 os << "ContentType: " << info.getType();
211
212 // FreshnessPeriod
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700213 if (info.getFreshnessPeriod() >= time::milliseconds::zero()) {
Alexander Afanasyev4ff3c912014-01-03 15:25:02 -0800214 os << ", FreshnessPeriod: " << info.getFreshnessPeriod();
215 }
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800216
217 if (!info.getFinalBlockId().empty()) {
218 os << ", FinalBlockId: ";
219 info.getFinalBlockId().toUri(os);
220 }
Alexander Afanasyev4ff3c912014-01-03 15:25:02 -0800221 return os;
222}
223
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800224} // namespace ndn
225
226#endif // NDN_META_INFO_HPP