blob: 3c3c59ecd473a020f514bfb4165216ac4e4fc31e [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesavento88a0d812017-08-19 21:31:42 -04002/*
Junxiao Shiebfe4a22018-04-01 23:53:40 +00003 * Copyright (c) 2013-2018 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 Afanasyev01065fb2014-10-02 13:01:46 -070025#include "encoding/block.hpp"
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080026#include "encoding/encoding-buffer.hpp"
Alexander Afanasyev01065fb2014-10-02 13:01:46 -070027#include "name-component.hpp"
Davide Pesavento88a0d812017-08-19 21:31:42 -040028#include "util/time.hpp"
29
Shock Jiangca7ea702014-10-02 11:23:25 -070030#include <list>
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080031
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080032namespace ndn {
33
Eric Newberryb555b002017-05-17 00:30:44 -070034const time::milliseconds DEFAULT_FRESHNESS_PERIOD = time::milliseconds::zero();
35
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080036/**
Davide Pesavento1fd00242018-05-20 00:11:01 -040037 * A MetaInfo holds the meta info which is signed inside the data packet.
Shock Jiangca7ea702014-10-02 11:23:25 -070038 *
39 * The class allows experimentation with application-defined meta information blocks,
40 * which slightly violates NDN-TLV specification. When using the application-defined
41 * meta information blocks be aware that this may result in packet drop (NFD and
42 * previous versions of ndn-cxx will gracefully accept such packet).
43 *
44 * The following definition of MetaInfo block is assumed in this implementation (compared
45 * to the NDN-TLV spec, definition extended to allow optional AppMetaInfo TLV blocks):
46 *
47 * MetaInfo ::= META-INFO-TYPE TLV-LENGTH
48 * ContentType?
49 * FreshnessPeriod?
50 * FinalBlockId?
51 * AppMetaInfo*
52 *
53 * AppMetaInfo ::= any TLV block with type in the restricted application range [128, 252]
54 *
55 * Note that AppMetaInfo blocks are application-defined and must have TLV type from
56 * the restricted application range [128, 252].
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080057 */
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070058class MetaInfo
59{
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080060public:
Shock Jiangca7ea702014-10-02 11:23:25 -070061 class Error : public tlv::Error
62 {
63 public:
64 explicit
65 Error(const std::string& what)
66 : tlv::Error(what)
67 {
68 }
69 };
70
Alexander Afanasyev01065fb2014-10-02 13:01:46 -070071 MetaInfo();
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080072
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070073 /**
74 * @brief Create from wire encoding
75 */
Alexander Afanasyev01065fb2014-10-02 13:01:46 -070076 explicit
77 MetaInfo(const Block& block);
Alexander Afanasyevc348f832014-02-17 16:35:17 -080078
Alexander Afanasyev74633892015-02-08 18:08:46 -080079 template<encoding::Tag TAG>
Alexander Afanasyevc348f832014-02-17 16:35:17 -080080 size_t
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070081 wireEncode(EncodingImpl<TAG>& encoder) const;
Alexander Afanasyevc348f832014-02-17 16:35:17 -080082
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070083 const Block&
Alexander Afanasyevc348f832014-02-17 16:35:17 -080084 wireEncode() const;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070085
Alexander Afanasyevc348f832014-02-17 16:35:17 -080086 void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070087 wireDecode(const Block& wire);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070088
Junxiao Shia464b922014-11-12 21:13:06 -070089public: // getter/setter
Junxiao Shiebfe4a22018-04-01 23:53:40 +000090 /** @brief return ContentType
91 *
92 * If ContentType element is omitted, returns \c tlv::ContentType_Blob.
93 */
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070094 uint32_t
Junxiao Shiebfe4a22018-04-01 23:53:40 +000095 getType() const
96 {
97 return m_type;
98 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070099
Junxiao Shia464b922014-11-12 21:13:06 -0700100 /** @brief set ContentType
Junxiao Shiebfe4a22018-04-01 23:53:40 +0000101 * @param type a number defined in \c tlv::ContentTypeValue
Junxiao Shia464b922014-11-12 21:13:06 -0700102 */
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800103 MetaInfo&
Alexander Afanasyev01065fb2014-10-02 13:01:46 -0700104 setType(uint32_t type);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700105
Junxiao Shiebfe4a22018-04-01 23:53:40 +0000106 /** @brief return FreshnessPeriod
107 *
108 * If FreshnessPeriod element is omitted, returns \c DEFAULT_FRESHNESS_PERIOD.
109 */
110 time::milliseconds
111 getFreshnessPeriod() const
112 {
113 return m_freshnessPeriod;
114 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700115
Eric Newberryb555b002017-05-17 00:30:44 -0700116 /** @brief set FreshnessPeriod
Junxiao Shiebfe4a22018-04-01 23:53:40 +0000117 * @throw std::invalid_argument specified FreshnessPeriod is negative
Eric Newberryb555b002017-05-17 00:30:44 -0700118 */
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800119 MetaInfo&
Eric Newberryb555b002017-05-17 00:30:44 -0700120 setFreshnessPeriod(time::milliseconds freshnessPeriod);
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800121
Junxiao Shiebfe4a22018-04-01 23:53:40 +0000122 /** @brief return FinalBlockId
123 */
124 const optional<name::Component>&
125 getFinalBlock() const
126 {
127 return m_finalBlockId;
128 }
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800129
Junxiao Shiebfe4a22018-04-01 23:53:40 +0000130 /** @brief set FinalBlockId
131 */
132 MetaInfo&
133 setFinalBlock(optional<name::Component> finalBlockId);
134
135 /** @brief return FinalBlockId
136 * @deprecated use @c getFinalBlock
137 *
138 * If FinalBlockId element is omitted, returns a default-constructed @c name::Component.
139 * This is indistinguishable from having an empty GenericNameComponent as FinalBlockId.
140 */
Davide Pesavento1fd00242018-05-20 00:11:01 -0400141 [[deprecated("use getFinalBlock")]]
Junxiao Shiebfe4a22018-04-01 23:53:40 +0000142 name::Component
143 getFinalBlockId() const
144 {
145 return getFinalBlock().value_or(name::Component());
146 }
147
148 /** @brief set FinalBlockId
149 * @deprecated use @c setFinalBlock
150 *
151 * Passing a default-constructed @c name::Component removes FinalBlockId element.
152 * This API does not support adding an empty GenericNameComponent as FinalBlockId.
153 */
Davide Pesavento1fd00242018-05-20 00:11:01 -0400154 [[deprecated("use setFinalBlock")]]
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800155 MetaInfo&
Alexander Afanasyev01065fb2014-10-02 13:01:46 -0700156 setFinalBlockId(const name::Component& finalBlockId);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700157
Junxiao Shia464b922014-11-12 21:13:06 -0700158public: // app-defined MetaInfo items
Shock Jiangca7ea702014-10-02 11:23:25 -0700159 /**
160 * @brief Get all app-defined MetaInfo items
161 *
162 * @note Warning: Experimental API, which may change or disappear in the future
163 *
Junxiao Shiebfe4a22018-04-01 23:53:40 +0000164 * @note If MetaInfo is decoded from wire and setType, setFreshnessPeriod, or setFinalBlock
Shock Jiangca7ea702014-10-02 11:23:25 -0700165 * is called before *AppMetaInfo, all app-defined blocks will be lost
166 */
167 const std::list<Block>&
168 getAppMetaInfo() const;
169
170 /**
171 * @brief Set app-defined MetaInfo items
172 *
173 * This method will replace all existing app-defined MetaInfo items, if they existed.
174 *
175 * @throw Error if some block in @p info has type not in the application range
176 * (http://named-data.net/doc/ndn-tlv/types.html)
177 *
178 * @note Warning: Experimental API, which may change or disappear in the future
179 *
Junxiao Shiebfe4a22018-04-01 23:53:40 +0000180 * @note If MetaInfo is decoded from wire and setType, setFreshnessPeriod, or setFinalBlock
Shock Jiangca7ea702014-10-02 11:23:25 -0700181 * is called before *AppMetaInfo, all app-defined blocks will be lost
182 */
183 MetaInfo&
184 setAppMetaInfo(const std::list<Block>& info);
185
186 /**
187 * @brief Add an app-defined MetaInfo item
188 *
189 * @throw Error if @p block has type not in the application range
190 * (http://named-data.net/doc/ndn-tlv/types.html)
191 *
192 * @note Warning: Experimental API, which may change or disappear in the future
193 *
Junxiao Shiebfe4a22018-04-01 23:53:40 +0000194 * @note If MetaInfo is decoded from wire and setType, setFreshnessPeriod, or setFinalBlock
Shock Jiangca7ea702014-10-02 11:23:25 -0700195 * is called before *AppMetaInfo, all app-defined blocks will be lost
196 */
197 MetaInfo&
198 addAppMetaInfo(const Block& block);
199
200 /**
201 * @brief Remove a first app-defined MetaInfo item with type @p tlvType
202 *
203 * @return true if an item was deleted
204 *
205 * @note Warning: Experimental API, which may change or disappear in the future
206 *
Junxiao Shiebfe4a22018-04-01 23:53:40 +0000207 * @note If MetaInfo is decoded from wire and setType, setFreshnessPeriod, or setFinalBlock
Shock Jiangca7ea702014-10-02 11:23:25 -0700208 * is called before *AppMetaInfo, all app-defined blocks will be lost
209 */
210 bool
211 removeAppMetaInfo(uint32_t tlvType);
212
213 /**
214 * @brief Find a first app-defined MetaInfo item of type @p tlvType
215 *
216 * @return NULL if an item is not found, otherwise const pointer to the item
217 *
218 * @throw Error if @p tlvType is not in the application range
219 * (http://named-data.net/doc/ndn-tlv/types.html)
220 *
221 * @note Warning: Experimental API, which may change or disappear in the future
222 *
Junxiao Shiebfe4a22018-04-01 23:53:40 +0000223 * @note If MetaInfo is decoded from wire and setType, setFreshnessPeriod, or setFinalBlock
Shock Jiangca7ea702014-10-02 11:23:25 -0700224 * is called before *AppMetaInfo, all app-defined blocks will be lost
225 */
226 const Block*
227 findAppMetaInfo(uint32_t tlvType) const;
228
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700229public: // EqualityComparable concept
230 bool
Alexander Afanasyev01065fb2014-10-02 13:01:46 -0700231 operator==(const MetaInfo& other) const;
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700232
233 bool
Alexander Afanasyev01065fb2014-10-02 13:01:46 -0700234 operator!=(const MetaInfo& other) const;
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700235
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800236private:
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800237 uint32_t m_type;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700238 time::milliseconds m_freshnessPeriod;
Junxiao Shiebfe4a22018-04-01 23:53:40 +0000239 optional<name::Component> m_finalBlockId;
Shock Jiangca7ea702014-10-02 11:23:25 -0700240 std::list<Block> m_appMetaInfo;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800241
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800242 mutable Block m_wire;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800243};
244
Davide Pesavento88a0d812017-08-19 21:31:42 -0400245NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(MetaInfo);
246
Alexander Afanasyev01065fb2014-10-02 13:01:46 -0700247std::ostream&
248operator<<(std::ostream& os, const MetaInfo& info);
249
Alexander Afanasyev01065fb2014-10-02 13:01:46 -0700250inline bool
251MetaInfo::operator==(const MetaInfo& other) const
Alexander Afanasyev4ff3c912014-01-03 15:25:02 -0800252{
Alexander Afanasyev01065fb2014-10-02 13:01:46 -0700253 return wireEncode() == other.wireEncode();
254}
Alexander Afanasyev4ff3c912014-01-03 15:25:02 -0800255
Alexander Afanasyev01065fb2014-10-02 13:01:46 -0700256inline bool
257MetaInfo::operator!=(const MetaInfo& other) const
258{
259 return !(*this == other);
Alexander Afanasyev4ff3c912014-01-03 15:25:02 -0800260}
261
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800262} // namespace ndn
263
264#endif // NDN_META_INFO_HPP