blob: 9541d6b6c5af880d463106be4173c0f507cad406 [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/*
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.
Jeff Thompson5cae5e52013-07-10 19:41:20 -070020 */
21
Jeff Thompson56ec9e22013-08-02 11:34:07 -070022#ifndef NDN_DATA_HPP
Jeff Thompsona0d18c92013-08-06 13:55:32 -070023#define NDN_DATA_HPP
Jeff Thompson5cae5e52013-07-10 19:41:20 -070024
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080025#include "meta-info.hpp"
Junxiao Shi81206d52017-07-23 12:43:22 +000026#include "name.hpp"
Eric Newberryc3a46792017-09-24 14:54:24 -070027#include "packet-base.hpp"
Junxiao Shi81206d52017-07-23 12:43:22 +000028#include "signature.hpp"
Junxiao Shi81206d52017-07-23 12:43:22 +000029#include "encoding/block.hpp"
Jeff Thompson5cae5e52013-07-10 19:41:20 -070030
31namespace ndn {
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070032
Davide Pesavento1fd00242018-05-20 00:11:01 -040033/** @brief Represents a Data packet.
Junxiao Shic2b8d242014-11-04 08:35:29 -070034 */
Davide Pesavento1fd00242018-05-20 00:11:01 -040035class Data : public PacketBase, public std::enable_shared_from_this<Data>
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080036{
Jeff Thompson5cae5e52013-07-10 19:41:20 -070037public:
Junxiao Shic2b8d242014-11-04 08:35:29 -070038 class Error : public tlv::Error
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070039 {
40 public:
Junxiao Shi68b53852018-07-25 13:56:38 -060041 using tlv::Error::Error;
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070042 };
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070043
Junxiao Shi7d9039b2018-04-14 15:56:28 +000044 /** @brief Construct an unsigned Data packet with given @p name and empty Content.
45 * @warning In certain contexts that use `Data::shared_from_this()`, Data must be created
46 * using `make_shared`. Otherwise, `shared_from_this()` will trigger undefined behavior.
Jeff Thompson20af0732013-09-12 17:01:45 -070047 */
Junxiao Shi9b845352017-07-24 05:04:56 +000048 explicit
Junxiao Shi81206d52017-07-23 12:43:22 +000049 Data(const Name& name = Name());
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070050
Junxiao Shi7d9039b2018-04-14 15:56:28 +000051 /** @brief Construct a Data packet by decoding from @p wire.
52 * @param wire @c tlv::Data element as defined in NDN Packet Format v0.2 or v0.3.
53 * It may be signed or unsigned.
54 * @warning In certain contexts that use `Data::shared_from_this()`, Data must be created
55 * using `make_shared`. Otherwise, `shared_from_this()` will trigger undefined behavior.
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -080056 */
57 explicit
Alexander Afanasyev197e5652014-06-13 16:56:31 -070058 Data(const Block& wire);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070059
Junxiao Shi7d9039b2018-04-14 15:56:28 +000060 /** @brief Prepend wire encoding to @p encoder in NDN Packet Format v0.2.
Junxiao Shi81206d52017-07-23 12:43:22 +000061 * @param encoder EncodingEstimator or EncodingBuffer instance
62 * @param wantUnsignedPortionOnly If true, only prepends Name, MetaInfo, Content, and
63 * SignatureInfo to @p encoder, but omit SignatureValue and outmost Type-Length of Data
64 * element. This is intended to be used with wireEncode(encoder, signatureValue).
65 * @throw Error SignatureBits are not provided and wantUnsignedPortionOnly is false.
Jeff Thompsonb7aefa002013-09-16 18:22:00 -070066 */
Alexander Afanasyev74633892015-02-08 18:08:46 -080067 template<encoding::Tag TAG>
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070068 size_t
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070069 wireEncode(EncodingImpl<TAG>& encoder, bool wantUnsignedPortionOnly = false) const;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070070
Junxiao Shi81206d52017-07-23 12:43:22 +000071 /** @brief Finalize Data packet encoding with the specified SignatureValue
72 * @param encoder EncodingBuffer containing Name, MetaInfo, Content, and SignatureInfo, but
73 * without SignatureValue or outmost Type-Length of Data element
74 * @param signatureValue SignatureValue element
Alexander Afanasyev197e5652014-06-13 16:56:31 -070075 *
Junxiao Shi81206d52017-07-23 12:43:22 +000076 * This method is intended to be used in concert with Data::wireEncode(encoder, true)
77 * @code
Alexander Afanasyev197e5652014-06-13 16:56:31 -070078 * Data data;
79 * ...
80 * EncodingBuffer encoder;
81 * data.wireEncode(encoder, true);
82 * ...
83 * Block signatureValue = <sign_over_unsigned_portion>(encoder.buf(), encoder.size());
84 * data.wireEncode(encoder, signatureValue)
Junxiao Shi81206d52017-07-23 12:43:22 +000085 * @endcode
Alexander Afanasyev197e5652014-06-13 16:56:31 -070086 */
87 const Block&
88 wireEncode(EncodingBuffer& encoder, const Block& signatureValue) const;
89
Junxiao Shi7d9039b2018-04-14 15:56:28 +000090 /** @brief Encode to a @c Block.
91 * @pre Data is signed.
92 *
93 * Normally, this function encodes to NDN Packet Format v0.2. However, if this instance has
94 * cached wire encoding (\c hasWire() is true), the cached encoding is returned and it might
95 * be in v0.3 format.
Junxiao Shi81206d52017-07-23 12:43:22 +000096 */
97 const Block&
98 wireEncode() const;
99
Junxiao Shi7d9039b2018-04-14 15:56:28 +0000100 /** @brief Decode from @p wire in NDN Packet Format v0.2 or v0.3.
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800101 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700102 void
103 wireDecode(const Block& wire);
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800104
Junxiao Shi7d9039b2018-04-14 15:56:28 +0000105 /** @brief Check if this instance has cached wire encoding.
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800106 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700107 bool
Junxiao Shi81206d52017-07-23 12:43:22 +0000108 hasWire() const
109 {
110 return m_wire.hasWire();
111 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700112
Junxiao Shi81206d52017-07-23 12:43:22 +0000113 /** @brief Get full name including implicit digest
114 * @pre hasWire() == true; i.e. wireEncode() must have been called
115 * @throw Error Data has no wire encoding
Alexander Afanasyev3b703102014-06-13 17:01:14 -0700116 */
117 const Name&
118 getFullName() const;
119
Junxiao Shi81206d52017-07-23 12:43:22 +0000120public: // Data fields
121 /** @brief Get name
122 */
123 const Name&
124 getName() const
125 {
126 return m_name;
127 }
128
129 /** @brief Set name
130 * @return a reference to this Data, to allow chaining
131 */
132 Data&
133 setName(const Name& name);
134
135 /** @brief Get MetaInfo
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700136 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700137 const MetaInfo&
Junxiao Shi81206d52017-07-23 12:43:22 +0000138 getMetaInfo() const
139 {
140 return m_metaInfo;
141 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700142
Junxiao Shi81206d52017-07-23 12:43:22 +0000143 /** @brief Set MetaInfo
144 * @return a reference to this Data, to allow chaining
Jeff Thompson0cd8c4a2013-09-13 17:46:40 -0700145 */
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700146 Data&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800147 setMetaInfo(const MetaInfo& metaInfo);
Jeff Thompson46bd45f2013-08-08 16:46:41 -0700148
Junxiao Shi81206d52017-07-23 12:43:22 +0000149 /** @brief Get Content
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800150 *
Junxiao Shi81206d52017-07-23 12:43:22 +0000151 * The Content value is accessible through value()/value_size() or value_begin()/value_end()
152 * methods of the Block class.
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800153 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700154 const Block&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800155 getContent() const;
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800156
Junxiao Shi81206d52017-07-23 12:43:22 +0000157 /** @brief Set Content from a block
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700158 *
Junxiao Shi81206d52017-07-23 12:43:22 +0000159 * If block's TLV-TYPE is Content, it will be used directly as Data's Content element.
160 * If block's TLV-TYPE is not Content, it will be nested into a Content element.
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700161 *
Junxiao Shi81206d52017-07-23 12:43:22 +0000162 * @return a reference to this Data, to allow chaining
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700163 */
164 Data&
165 setContent(const Block& block);
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800166
Junxiao Shi81206d52017-07-23 12:43:22 +0000167 /** @brief Copy Content value from raw buffer
168 * @param value pointer to the first octet of the value
169 * @param valueSize size of the raw buffer
170 * @return a reference to this Data, to allow chaining
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700171 */
172 Data&
Junxiao Shi81206d52017-07-23 12:43:22 +0000173 setContent(const uint8_t* value, size_t valueSize);
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800174
Junxiao Shi81206d52017-07-23 12:43:22 +0000175 /** @brief Set Content from wire buffer
176 * @param value Content value, which does not need to be a TLV element
177 * @return a reference to this Data, to allow chaining
178 */
179 Data&
Davide Pesavento3b101d02018-07-21 22:44:09 -0400180 setContent(ConstBufferPtr value);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700181
Junxiao Shi81206d52017-07-23 12:43:22 +0000182 /** @brief Get Signature
183 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700184 const Signature&
Junxiao Shi81206d52017-07-23 12:43:22 +0000185 getSignature() const
186 {
187 return m_signature;
188 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700189
Junxiao Shi81206d52017-07-23 12:43:22 +0000190 /** @brief Set Signature
191 * @return a reference to this Data, to allow chaining
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800192 */
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
Junxiao Shi81206d52017-07-23 12:43:22 +0000196 /** @brief Set SignatureValue
197 * @return a reference to this Data, to allow chaining
198 */
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700199 Data&
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700200 setSignatureValue(const Block& value);
Yingdi Yua4e57672014-02-06 11:16:17 -0800201
Junxiao Shi81206d52017-07-23 12:43:22 +0000202public: // MetaInfo fields
203 uint32_t
204 getContentType() const
205 {
206 return m_metaInfo.getType();
207 }
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700208
Junxiao Shi81206d52017-07-23 12:43:22 +0000209 Data&
210 setContentType(uint32_t type);
211
Junxiao Shiebfe4a22018-04-01 23:53:40 +0000212 time::milliseconds
Junxiao Shi81206d52017-07-23 12:43:22 +0000213 getFreshnessPeriod() const
214 {
215 return m_metaInfo.getFreshnessPeriod();
216 }
217
218 Data&
Junxiao Shiebfe4a22018-04-01 23:53:40 +0000219 setFreshnessPeriod(time::milliseconds freshnessPeriod);
Junxiao Shi81206d52017-07-23 12:43:22 +0000220
Junxiao Shiebfe4a22018-04-01 23:53:40 +0000221 const optional<name::Component>&
222 getFinalBlock() const
Junxiao Shi81206d52017-07-23 12:43:22 +0000223 {
Junxiao Shiebfe4a22018-04-01 23:53:40 +0000224 return m_metaInfo.getFinalBlock();
Junxiao Shi81206d52017-07-23 12:43:22 +0000225 }
226
227 Data&
Junxiao Shiebfe4a22018-04-01 23:53:40 +0000228 setFinalBlock(optional<name::Component> finalBlockId);
229
230 /** @deprecated Use @c getFinalBlock
231 * @sa MetaInfo::getFinalBlockId
232 */
Davide Pesavento1fd00242018-05-20 00:11:01 -0400233 [[deprecated("use getFinalBlock")]]
Junxiao Shiebfe4a22018-04-01 23:53:40 +0000234 name::Component
235 getFinalBlockId() const;
236
237 /** @deprecated Use @c setFinalBlock
238 * @sa MetaInfo::setFinalBlockId
239 */
Davide Pesavento1fd00242018-05-20 00:11:01 -0400240 [[deprecated("use setFinalBlock")]]
Junxiao Shiebfe4a22018-04-01 23:53:40 +0000241 Data&
Junxiao Shi81206d52017-07-23 12:43:22 +0000242 setFinalBlockId(const name::Component& finalBlockId);
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700243
Spyridon Mastorakis3b54e852015-04-07 08:03:25 -0700244protected:
Junxiao Shi81206d52017-07-23 12:43:22 +0000245 /** @brief Clear wire encoding and cached FullName
246 * @note This does not clear the SignatureValue.
Jeff Thompsonb7aefa002013-09-16 18:22:00 -0700247 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700248 void
Junxiao Shi81206d52017-07-23 12:43:22 +0000249 resetWire();
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800250
251private:
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800252 Name m_name;
253 MetaInfo m_metaInfo;
Junxiao Shi81206d52017-07-23 12:43:22 +0000254 Block m_content;
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800255 Signature m_signature;
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800256
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800257 mutable Block m_wire;
Junxiao Shi81206d52017-07-23 12:43:22 +0000258 mutable Name m_fullName; ///< cached FullName computed from m_wire
Jeff Thompson5cae5e52013-07-10 19:41:20 -0700259};
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800260
Davide Pesavento88a0d812017-08-19 21:31:42 -0400261#ifndef DOXYGEN
262extern template size_t
263Data::wireEncode<encoding::EncoderTag>(EncodingBuffer&, bool) const;
264
265extern template size_t
266Data::wireEncode<encoding::EstimatorTag>(EncodingEstimator&, bool) const;
267#endif
268
Alexander Afanasyeva0c5f832014-06-19 13:27:56 -0700269std::ostream&
270operator<<(std::ostream& os, const Data& data);
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800271
Junxiao Shi81206d52017-07-23 12:43:22 +0000272bool
273operator==(const Data& lhs, const Data& rhs);
274
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800275inline bool
Junxiao Shi81206d52017-07-23 12:43:22 +0000276operator!=(const Data& lhs, const Data& rhs)
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800277{
Junxiao Shi81206d52017-07-23 12:43:22 +0000278 return !(lhs == rhs);
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800279}
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700280
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800281} // namespace ndn
282
Junxiao Shi81206d52017-07-23 12:43:22 +0000283#endif // NDN_DATA_HPP