blob: 26a64b39bca88c1c88909daca4aa848b12e21f7f [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Junxiao Shi81206d52017-07-23 12:43:22 +00002/*
Eric Newberrya3c8bd12020-05-15 17:27:07 -07003 * Copyright (c) 2013-2020 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.
Jeff Thompson5cae5e52013-07-10 19:41:20 -070020 */
21
Davide Pesavento905d40f2020-06-09 21:33:25 -040022#ifndef NDN_CXX_DATA_HPP
23#define NDN_CXX_DATA_HPP
Jeff Thompson5cae5e52013-07-10 19:41:20 -070024
Davide Pesavento14c56cd2020-05-21 01:44:03 -040025#include "ndn-cxx/detail/packet-base.hpp"
26#include "ndn-cxx/encoding/block.hpp"
Davide Pesavento7e780642018-11-24 15:51:34 -050027#include "ndn-cxx/meta-info.hpp"
28#include "ndn-cxx/name.hpp"
Davide Pesavento7e780642018-11-24 15:51:34 -050029#include "ndn-cxx/signature.hpp"
Jeff Thompson5cae5e52013-07-10 19:41:20 -070030
31namespace ndn {
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070032
Davide Pesavento905d40f2020-06-09 21:33:25 -040033/** @brief Represents a %Data packet.
34 * @sa https://named-data.net/doc/NDN-packet-spec/0.3/data.html
Junxiao Shic2b8d242014-11-04 08:35:29 -070035 */
Davide Pesavento1fd00242018-05-20 00:11:01 -040036class Data : public PacketBase, public std::enable_shared_from_this<Data>
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080037{
Jeff Thompson5cae5e52013-07-10 19:41:20 -070038public:
Junxiao Shic2b8d242014-11-04 08:35:29 -070039 class Error : public tlv::Error
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070040 {
41 public:
Junxiao Shi68b53852018-07-25 13:56:38 -060042 using tlv::Error::Error;
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070043 };
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070044
Junxiao Shi7d9039b2018-04-14 15:56:28 +000045 /** @brief Construct an unsigned Data packet with given @p name and empty Content.
Davide Pesavento905d40f2020-06-09 21:33:25 -040046 * @warning In certain contexts that use `Data::shared_from_this()`, Data must be created using
47 * `std::make_shared`. Otherwise, `shared_from_this()` may trigger undefined behavior.
48 * One example where this is necessary is storing Data into a subclass of InMemoryStorage.
Jeff Thompson20af0732013-09-12 17:01:45 -070049 */
Junxiao Shi9b845352017-07-24 05:04:56 +000050 explicit
Junxiao Shi81206d52017-07-23 12:43:22 +000051 Data(const Name& name = Name());
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070052
Junxiao Shi7d9039b2018-04-14 15:56:28 +000053 /** @brief Construct a Data packet by decoding from @p wire.
Davide Pesavento905d40f2020-06-09 21:33:25 -040054 * @param wire TLV block of type tlv::Data; may be signed or unsigned.
55 * @warning In certain contexts that use `Data::shared_from_this()`, Data must be created using
56 * `std::make_shared`. Otherwise, `shared_from_this()` may trigger undefined behavior.
57 * One example where this is necessary is storing Data into a subclass of InMemoryStorage.
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -080058 */
59 explicit
Alexander Afanasyev197e5652014-06-13 16:56:31 -070060 Data(const Block& wire);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070061
Davide Pesavento905d40f2020-06-09 21:33:25 -040062 /** @brief Prepend wire encoding to @p encoder
63 * @param encoder EncodingEstimator or EncodingBuffer instance.
64 * @param wantUnsignedPortionOnly If true, prepend only Name, MetaInfo, Content, and
65 * SignatureInfo to @p encoder, but omit SignatureValue and the outermost TLV
66 * Type and Length of the Data element. This is intended to be used with
67 * wireEncode(EncodingBuffer&, const Block&) const.
68 * @throw Error %Signature is not present and @p wantUnsignedPortionOnly is false.
Jeff Thompsonb7aefa002013-09-16 18:22:00 -070069 */
Alexander Afanasyev74633892015-02-08 18:08:46 -080070 template<encoding::Tag TAG>
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070071 size_t
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070072 wireEncode(EncodingImpl<TAG>& encoder, bool wantUnsignedPortionOnly = false) const;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070073
Junxiao Shi81206d52017-07-23 12:43:22 +000074 /** @brief Finalize Data packet encoding with the specified SignatureValue
75 * @param encoder EncodingBuffer containing Name, MetaInfo, Content, and SignatureInfo, but
Davide Pesavento905d40f2020-06-09 21:33:25 -040076 * without SignatureValue and the outermost Type-Length of the Data element.
77 * @param signatureValue SignatureValue element.
Alexander Afanasyev197e5652014-06-13 16:56:31 -070078 *
Davide Pesavento905d40f2020-06-09 21:33:25 -040079 * This method is intended to be used in concert with `wireEncode(encoder, true)`, e.g.:
Junxiao Shi81206d52017-07-23 12:43:22 +000080 * @code
Alexander Afanasyev197e5652014-06-13 16:56:31 -070081 * Data data;
82 * ...
83 * EncodingBuffer encoder;
84 * data.wireEncode(encoder, true);
85 * ...
86 * Block signatureValue = <sign_over_unsigned_portion>(encoder.buf(), encoder.size());
87 * data.wireEncode(encoder, signatureValue)
Junxiao Shi81206d52017-07-23 12:43:22 +000088 * @endcode
Alexander Afanasyev197e5652014-06-13 16:56:31 -070089 */
90 const Block&
91 wireEncode(EncodingBuffer& encoder, const Block& signatureValue) const;
92
Davide Pesavento905d40f2020-06-09 21:33:25 -040093 /** @brief Encode into a Block.
94 * @pre Data must be signed.
Junxiao Shi81206d52017-07-23 12:43:22 +000095 */
96 const Block&
97 wireEncode() const;
98
Davide Pesavento905d40f2020-06-09 21:33:25 -040099 /** @brief Decode from @p wire.
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800100 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700101 void
102 wireDecode(const Block& wire);
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800103
Junxiao Shi7d9039b2018-04-14 15:56:28 +0000104 /** @brief Check if this instance has cached wire encoding.
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800105 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700106 bool
Davide Pesavento14c56cd2020-05-21 01:44:03 -0400107 hasWire() const noexcept
Junxiao Shi81206d52017-07-23 12:43:22 +0000108 {
109 return m_wire.hasWire();
110 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700111
Junxiao Shi81206d52017-07-23 12:43:22 +0000112 /** @brief Get full name including implicit digest
113 * @pre hasWire() == true; i.e. wireEncode() must have been called
114 * @throw Error Data has no wire encoding
Alexander Afanasyev3b703102014-06-13 17:01:14 -0700115 */
116 const Name&
117 getFullName() const;
118
Junxiao Shi81206d52017-07-23 12:43:22 +0000119public: // Data fields
120 /** @brief Get name
121 */
122 const Name&
Davide Pesavento14c56cd2020-05-21 01:44:03 -0400123 getName() const noexcept
Junxiao Shi81206d52017-07-23 12:43:22 +0000124 {
125 return m_name;
126 }
127
128 /** @brief Set name
129 * @return a reference to this Data, to allow chaining
130 */
131 Data&
132 setName(const Name& name);
133
134 /** @brief Get MetaInfo
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700135 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700136 const MetaInfo&
Davide Pesavento14c56cd2020-05-21 01:44:03 -0400137 getMetaInfo() const noexcept
Junxiao Shi81206d52017-07-23 12:43:22 +0000138 {
139 return m_metaInfo;
140 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700141
Junxiao Shi81206d52017-07-23 12:43:22 +0000142 /** @brief Set MetaInfo
143 * @return a reference to this Data, to allow chaining
Jeff Thompson0cd8c4a2013-09-13 17:46:40 -0700144 */
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700145 Data&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800146 setMetaInfo(const MetaInfo& metaInfo);
Jeff Thompson46bd45f2013-08-08 16:46:41 -0700147
Junxiao Shi81206d52017-07-23 12:43:22 +0000148 /** @brief Get Content
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800149 *
Junxiao Shi81206d52017-07-23 12:43:22 +0000150 * The Content value is accessible through value()/value_size() or value_begin()/value_end()
151 * methods of the Block class.
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800152 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700153 const Block&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800154 getContent() const;
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800155
Davide Pesavento14c56cd2020-05-21 01:44:03 -0400156 /** @brief Set Content from a Block
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700157 *
Davide Pesavento14c56cd2020-05-21 01:44:03 -0400158 * If the block's TLV-TYPE is Content, it will be used directly as this Data's Content element.
159 * Otherwise, the block will be nested into a Content element.
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700160 *
Junxiao Shi81206d52017-07-23 12:43:22 +0000161 * @return a reference to this Data, to allow chaining
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700162 */
163 Data&
164 setContent(const Block& block);
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800165
Davide Pesavento14c56cd2020-05-21 01:44:03 -0400166 /** @brief Set Content by copying from a raw buffer
Junxiao Shi81206d52017-07-23 12:43:22 +0000167 * @param value pointer to the first octet of the value
Davide Pesavento14c56cd2020-05-21 01:44:03 -0400168 * @param valueSize size of the buffer
Junxiao Shi81206d52017-07-23 12:43:22 +0000169 * @return a reference to this Data, to allow chaining
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700170 */
171 Data&
Junxiao Shi81206d52017-07-23 12:43:22 +0000172 setContent(const uint8_t* value, size_t valueSize);
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800173
Davide Pesavento14c56cd2020-05-21 01:44:03 -0400174 /** @brief Set Content from a shared buffer
175 * @param value buffer containing the TLV-VALUE of the content; must not be nullptr
Junxiao Shi81206d52017-07-23 12:43:22 +0000176 * @return a reference to this Data, to allow chaining
177 */
178 Data&
Davide Pesavento3b101d02018-07-21 22:44:09 -0400179 setContent(ConstBufferPtr value);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700180
Junxiao Shi81206d52017-07-23 12:43:22 +0000181 /** @brief Get Signature
Eric Newberrya3c8bd12020-05-15 17:27:07 -0700182 * @deprecated Use getSignatureInfo and getSignatureValue
Junxiao Shi81206d52017-07-23 12:43:22 +0000183 */
Eric Newberrya3c8bd12020-05-15 17:27:07 -0700184 [[deprecated("use getSignatureInfo and getSignatureValue")]]
185 Signature
186 getSignature() const;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700187
Junxiao Shi81206d52017-07-23 12:43:22 +0000188 /** @brief Set Signature
Eric Newberrya3c8bd12020-05-15 17:27:07 -0700189 * @deprecated Use setSignatureInfo and setSignatureValue
Junxiao Shi81206d52017-07-23 12:43:22 +0000190 * @return a reference to this Data, to allow chaining
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800191 */
Eric Newberrya3c8bd12020-05-15 17:27:07 -0700192 [[deprecated("use setSignatureInfo and setSignatureValue")]]
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700193 Data&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800194 setSignature(const Signature& signature);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700195
Eric Newberrya3c8bd12020-05-15 17:27:07 -0700196 /** @brief Get SignatureInfo
197 */
198 const SignatureInfo&
Davide Pesavento14c56cd2020-05-21 01:44:03 -0400199 getSignatureInfo() const noexcept
Eric Newberrya3c8bd12020-05-15 17:27:07 -0700200 {
201 return m_signatureInfo;
202 }
203
204 /** @brief Set SignatureInfo
Davide Pesavento14c56cd2020-05-21 01:44:03 -0400205 *
206 * This is a low-level function that should not normally be called directly by applications.
207 * Instead, provide a SignatureInfo to the SigningInfo object passed to KeyChain::sign().
208 *
Eric Newberrya3c8bd12020-05-15 17:27:07 -0700209 * @return a reference to this Data, to allow chaining
Davide Pesavento14c56cd2020-05-21 01:44:03 -0400210 * @warning SignatureInfo is overwritten when the packet is signed via KeyChain::sign().
211 * @sa SigningInfo
Eric Newberrya3c8bd12020-05-15 17:27:07 -0700212 */
213 Data&
214 setSignatureInfo(const SignatureInfo& info);
215
216 /** @brief Get SignatureValue
217 */
218 const Block&
Davide Pesavento14c56cd2020-05-21 01:44:03 -0400219 getSignatureValue() const noexcept
Eric Newberrya3c8bd12020-05-15 17:27:07 -0700220 {
221 return m_signatureValue;
222 }
223
Junxiao Shi81206d52017-07-23 12:43:22 +0000224 /** @brief Set SignatureValue
Davide Pesavento14c56cd2020-05-21 01:44:03 -0400225 * @param value buffer containing the TLV-VALUE of the SignatureValue; must not be nullptr
226 *
227 * This is a low-level function that should not normally be called directly by applications.
228 * Instead, use KeyChain::sign() to sign the packet.
229 *
Junxiao Shi81206d52017-07-23 12:43:22 +0000230 * @return a reference to this Data, to allow chaining
Davide Pesavento14c56cd2020-05-21 01:44:03 -0400231 * @warning SignatureValue is overwritten when the packet is signed via KeyChain::sign().
Junxiao Shi81206d52017-07-23 12:43:22 +0000232 */
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700233 Data&
Davide Pesavento14c56cd2020-05-21 01:44:03 -0400234 setSignatureValue(ConstBufferPtr value);
Yingdi Yua4e57672014-02-06 11:16:17 -0800235
Junxiao Shi81206d52017-07-23 12:43:22 +0000236public: // MetaInfo fields
237 uint32_t
238 getContentType() const
239 {
240 return m_metaInfo.getType();
241 }
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700242
Junxiao Shi81206d52017-07-23 12:43:22 +0000243 Data&
244 setContentType(uint32_t type);
245
Junxiao Shiebfe4a22018-04-01 23:53:40 +0000246 time::milliseconds
Junxiao Shi81206d52017-07-23 12:43:22 +0000247 getFreshnessPeriod() const
248 {
249 return m_metaInfo.getFreshnessPeriod();
250 }
251
252 Data&
Junxiao Shiebfe4a22018-04-01 23:53:40 +0000253 setFreshnessPeriod(time::milliseconds freshnessPeriod);
Junxiao Shi81206d52017-07-23 12:43:22 +0000254
Junxiao Shiebfe4a22018-04-01 23:53:40 +0000255 const optional<name::Component>&
256 getFinalBlock() const
Junxiao Shi81206d52017-07-23 12:43:22 +0000257 {
Junxiao Shiebfe4a22018-04-01 23:53:40 +0000258 return m_metaInfo.getFinalBlock();
Junxiao Shi81206d52017-07-23 12:43:22 +0000259 }
260
261 Data&
Junxiao Shiebfe4a22018-04-01 23:53:40 +0000262 setFinalBlock(optional<name::Component> finalBlockId);
263
Davide Pesavento14c56cd2020-05-21 01:44:03 -0400264public: // SignatureInfo fields
265 /** @brief Get SignatureType
266 * @return tlv::SignatureTypeValue, or -1 to indicate the signature is invalid
267 */
268 int32_t
269 getSignatureType() const noexcept
270 {
271 return m_signatureInfo.getSignatureType();
272 }
273
274 /** @brief Get KeyLocator
275 */
276 optional<KeyLocator>
277 getKeyLocator() const noexcept
278 {
279 return m_signatureInfo.hasKeyLocator() ? make_optional(m_signatureInfo.getKeyLocator()) : nullopt;
280 }
281
Spyridon Mastorakis3b54e852015-04-07 08:03:25 -0700282protected:
Junxiao Shi81206d52017-07-23 12:43:22 +0000283 /** @brief Clear wire encoding and cached FullName
284 * @note This does not clear the SignatureValue.
Jeff Thompsonb7aefa002013-09-16 18:22:00 -0700285 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700286 void
Junxiao Shi81206d52017-07-23 12:43:22 +0000287 resetWire();
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800288
289private:
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800290 Name m_name;
291 MetaInfo m_metaInfo;
Junxiao Shi81206d52017-07-23 12:43:22 +0000292 Block m_content;
Eric Newberrya3c8bd12020-05-15 17:27:07 -0700293 SignatureInfo m_signatureInfo;
294 Block m_signatureValue;
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800295
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800296 mutable Block m_wire;
Junxiao Shi81206d52017-07-23 12:43:22 +0000297 mutable Name m_fullName; ///< cached FullName computed from m_wire
Jeff Thompson5cae5e52013-07-10 19:41:20 -0700298};
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800299
Davide Pesavento88a0d812017-08-19 21:31:42 -0400300#ifndef DOXYGEN
301extern template size_t
302Data::wireEncode<encoding::EncoderTag>(EncodingBuffer&, bool) const;
303
304extern template size_t
305Data::wireEncode<encoding::EstimatorTag>(EncodingEstimator&, bool) const;
306#endif
307
Alexander Afanasyeva0c5f832014-06-19 13:27:56 -0700308std::ostream&
309operator<<(std::ostream& os, const Data& data);
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800310
Junxiao Shi81206d52017-07-23 12:43:22 +0000311bool
312operator==(const Data& lhs, const Data& rhs);
313
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800314inline bool
Junxiao Shi81206d52017-07-23 12:43:22 +0000315operator!=(const Data& lhs, const Data& rhs)
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800316{
Junxiao Shi81206d52017-07-23 12:43:22 +0000317 return !(lhs == rhs);
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800318}
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700319
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800320} // namespace ndn
321
Davide Pesavento905d40f2020-06-09 21:33:25 -0400322#endif // NDN_CXX_DATA_HPP