blob: 53ff8b98d0ecfbb9aae1e200a1505f203d53f3e0 [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:
Junxiao Shi68b53852018-07-25 13:56:38 -060064 using tlv::Error::Error;
Shock Jiangca7ea702014-10-02 11:23:25 -070065 };
66
Alexander Afanasyev01065fb2014-10-02 13:01:46 -070067 MetaInfo();
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080068
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070069 /**
70 * @brief Create from wire encoding
71 */
Alexander Afanasyev01065fb2014-10-02 13:01:46 -070072 explicit
73 MetaInfo(const Block& block);
Alexander Afanasyevc348f832014-02-17 16:35:17 -080074
Alexander Afanasyev74633892015-02-08 18:08:46 -080075 template<encoding::Tag TAG>
Alexander Afanasyevc348f832014-02-17 16:35:17 -080076 size_t
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070077 wireEncode(EncodingImpl<TAG>& encoder) const;
Alexander Afanasyevc348f832014-02-17 16:35:17 -080078
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070079 const Block&
Alexander Afanasyevc348f832014-02-17 16:35:17 -080080 wireEncode() const;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070081
Alexander Afanasyevc348f832014-02-17 16:35:17 -080082 void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070083 wireDecode(const Block& wire);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070084
Junxiao Shia464b922014-11-12 21:13:06 -070085public: // getter/setter
Junxiao Shiebfe4a22018-04-01 23:53:40 +000086 /** @brief return ContentType
87 *
88 * If ContentType element is omitted, returns \c tlv::ContentType_Blob.
89 */
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070090 uint32_t
Junxiao Shiebfe4a22018-04-01 23:53:40 +000091 getType() const
92 {
93 return m_type;
94 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070095
Junxiao Shia464b922014-11-12 21:13:06 -070096 /** @brief set ContentType
Junxiao Shiebfe4a22018-04-01 23:53:40 +000097 * @param type a number defined in \c tlv::ContentTypeValue
Junxiao Shia464b922014-11-12 21:13:06 -070098 */
Alexander Afanasyev95b0e342014-02-12 21:34:44 -080099 MetaInfo&
Alexander Afanasyev01065fb2014-10-02 13:01:46 -0700100 setType(uint32_t type);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700101
Junxiao Shiebfe4a22018-04-01 23:53:40 +0000102 /** @brief return FreshnessPeriod
103 *
104 * If FreshnessPeriod element is omitted, returns \c DEFAULT_FRESHNESS_PERIOD.
105 */
106 time::milliseconds
107 getFreshnessPeriod() const
108 {
109 return m_freshnessPeriod;
110 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700111
Eric Newberryb555b002017-05-17 00:30:44 -0700112 /** @brief set FreshnessPeriod
Junxiao Shiebfe4a22018-04-01 23:53:40 +0000113 * @throw std::invalid_argument specified FreshnessPeriod is negative
Eric Newberryb555b002017-05-17 00:30:44 -0700114 */
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800115 MetaInfo&
Eric Newberryb555b002017-05-17 00:30:44 -0700116 setFreshnessPeriod(time::milliseconds freshnessPeriod);
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800117
Junxiao Shiebfe4a22018-04-01 23:53:40 +0000118 /** @brief return FinalBlockId
119 */
120 const optional<name::Component>&
121 getFinalBlock() const
122 {
123 return m_finalBlockId;
124 }
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800125
Junxiao Shiebfe4a22018-04-01 23:53:40 +0000126 /** @brief set FinalBlockId
127 */
128 MetaInfo&
129 setFinalBlock(optional<name::Component> finalBlockId);
130
131 /** @brief return FinalBlockId
132 * @deprecated use @c getFinalBlock
133 *
134 * If FinalBlockId element is omitted, returns a default-constructed @c name::Component.
135 * This is indistinguishable from having an empty GenericNameComponent as FinalBlockId.
136 */
Davide Pesavento1fd00242018-05-20 00:11:01 -0400137 [[deprecated("use getFinalBlock")]]
Junxiao Shiebfe4a22018-04-01 23:53:40 +0000138 name::Component
139 getFinalBlockId() const
140 {
141 return getFinalBlock().value_or(name::Component());
142 }
143
144 /** @brief set FinalBlockId
145 * @deprecated use @c setFinalBlock
146 *
147 * Passing a default-constructed @c name::Component removes FinalBlockId element.
148 * This API does not support adding an empty GenericNameComponent as FinalBlockId.
149 */
Davide Pesavento1fd00242018-05-20 00:11:01 -0400150 [[deprecated("use setFinalBlock")]]
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800151 MetaInfo&
Alexander Afanasyev01065fb2014-10-02 13:01:46 -0700152 setFinalBlockId(const name::Component& finalBlockId);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700153
Junxiao Shia464b922014-11-12 21:13:06 -0700154public: // app-defined MetaInfo items
Shock Jiangca7ea702014-10-02 11:23:25 -0700155 /**
156 * @brief Get all app-defined MetaInfo items
157 *
158 * @note Warning: Experimental API, which may change or disappear in the future
159 *
Junxiao Shiebfe4a22018-04-01 23:53:40 +0000160 * @note If MetaInfo is decoded from wire and setType, setFreshnessPeriod, or setFinalBlock
Shock Jiangca7ea702014-10-02 11:23:25 -0700161 * is called before *AppMetaInfo, all app-defined blocks will be lost
162 */
163 const std::list<Block>&
164 getAppMetaInfo() const;
165
166 /**
167 * @brief Set app-defined MetaInfo items
168 *
169 * This method will replace all existing app-defined MetaInfo items, if they existed.
170 *
171 * @throw Error if some block in @p info has type not in the application range
172 * (http://named-data.net/doc/ndn-tlv/types.html)
173 *
174 * @note Warning: Experimental API, which may change or disappear in the future
175 *
Junxiao Shiebfe4a22018-04-01 23:53:40 +0000176 * @note If MetaInfo is decoded from wire and setType, setFreshnessPeriod, or setFinalBlock
Shock Jiangca7ea702014-10-02 11:23:25 -0700177 * is called before *AppMetaInfo, all app-defined blocks will be lost
178 */
179 MetaInfo&
180 setAppMetaInfo(const std::list<Block>& info);
181
182 /**
183 * @brief Add an app-defined MetaInfo item
184 *
185 * @throw Error if @p block has type not in the application range
186 * (http://named-data.net/doc/ndn-tlv/types.html)
187 *
188 * @note Warning: Experimental API, which may change or disappear in the future
189 *
Junxiao Shiebfe4a22018-04-01 23:53:40 +0000190 * @note If MetaInfo is decoded from wire and setType, setFreshnessPeriod, or setFinalBlock
Shock Jiangca7ea702014-10-02 11:23:25 -0700191 * is called before *AppMetaInfo, all app-defined blocks will be lost
192 */
193 MetaInfo&
194 addAppMetaInfo(const Block& block);
195
196 /**
197 * @brief Remove a first app-defined MetaInfo item with type @p tlvType
198 *
199 * @return true if an item was deleted
200 *
201 * @note Warning: Experimental API, which may change or disappear in the future
202 *
Junxiao Shiebfe4a22018-04-01 23:53:40 +0000203 * @note If MetaInfo is decoded from wire and setType, setFreshnessPeriod, or setFinalBlock
Shock Jiangca7ea702014-10-02 11:23:25 -0700204 * is called before *AppMetaInfo, all app-defined blocks will be lost
205 */
206 bool
207 removeAppMetaInfo(uint32_t tlvType);
208
209 /**
210 * @brief Find a first app-defined MetaInfo item of type @p tlvType
211 *
212 * @return NULL if an item is not found, otherwise const pointer to the item
213 *
214 * @throw Error if @p tlvType is not in the application range
215 * (http://named-data.net/doc/ndn-tlv/types.html)
216 *
217 * @note Warning: Experimental API, which may change or disappear in the future
218 *
Junxiao Shiebfe4a22018-04-01 23:53:40 +0000219 * @note If MetaInfo is decoded from wire and setType, setFreshnessPeriod, or setFinalBlock
Shock Jiangca7ea702014-10-02 11:23:25 -0700220 * is called before *AppMetaInfo, all app-defined blocks will be lost
221 */
222 const Block*
223 findAppMetaInfo(uint32_t tlvType) const;
224
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700225public: // EqualityComparable concept
226 bool
Alexander Afanasyev01065fb2014-10-02 13:01:46 -0700227 operator==(const MetaInfo& other) const;
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700228
229 bool
Alexander Afanasyev01065fb2014-10-02 13:01:46 -0700230 operator!=(const MetaInfo& other) const;
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700231
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800232private:
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800233 uint32_t m_type;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700234 time::milliseconds m_freshnessPeriod;
Junxiao Shiebfe4a22018-04-01 23:53:40 +0000235 optional<name::Component> m_finalBlockId;
Shock Jiangca7ea702014-10-02 11:23:25 -0700236 std::list<Block> m_appMetaInfo;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800237
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800238 mutable Block m_wire;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800239};
240
Davide Pesavento88a0d812017-08-19 21:31:42 -0400241NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(MetaInfo);
242
Alexander Afanasyev01065fb2014-10-02 13:01:46 -0700243std::ostream&
244operator<<(std::ostream& os, const MetaInfo& info);
245
Alexander Afanasyev01065fb2014-10-02 13:01:46 -0700246inline bool
247MetaInfo::operator==(const MetaInfo& other) const
Alexander Afanasyev4ff3c912014-01-03 15:25:02 -0800248{
Alexander Afanasyev01065fb2014-10-02 13:01:46 -0700249 return wireEncode() == other.wireEncode();
250}
Alexander Afanasyev4ff3c912014-01-03 15:25:02 -0800251
Alexander Afanasyev01065fb2014-10-02 13:01:46 -0700252inline bool
253MetaInfo::operator!=(const MetaInfo& other) const
254{
255 return !(*this == other);
Alexander Afanasyev4ff3c912014-01-03 15:25:02 -0800256}
257
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800258} // namespace ndn
259
260#endif // NDN_META_INFO_HPP