blob: 56f98ed71368b229855821632e877fa09152fc81 [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:
41 explicit
42 Error(const std::string& what)
Junxiao Shic2b8d242014-11-04 08:35:29 -070043 : tlv::Error(what)
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070044 {
45 }
46 };
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070047
Junxiao Shi7d9039b2018-04-14 15:56:28 +000048 /** @brief Construct an unsigned Data packet with given @p name and empty Content.
49 * @warning In certain contexts that use `Data::shared_from_this()`, Data must be created
50 * using `make_shared`. Otherwise, `shared_from_this()` will trigger undefined behavior.
Jeff Thompson20af0732013-09-12 17:01:45 -070051 */
Junxiao Shi9b845352017-07-24 05:04:56 +000052 explicit
Junxiao Shi81206d52017-07-23 12:43:22 +000053 Data(const Name& name = Name());
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070054
Junxiao Shi7d9039b2018-04-14 15:56:28 +000055 /** @brief Construct a Data packet by decoding from @p wire.
56 * @param wire @c tlv::Data element as defined in NDN Packet Format v0.2 or v0.3.
57 * It may be signed or unsigned.
58 * @warning In certain contexts that use `Data::shared_from_this()`, Data must be created
59 * using `make_shared`. Otherwise, `shared_from_this()` will trigger undefined behavior.
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -080060 */
61 explicit
Alexander Afanasyev197e5652014-06-13 16:56:31 -070062 Data(const Block& wire);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070063
Junxiao Shi7d9039b2018-04-14 15:56:28 +000064 /** @brief Prepend wire encoding to @p encoder in NDN Packet Format v0.2.
Junxiao Shi81206d52017-07-23 12:43:22 +000065 * @param encoder EncodingEstimator or EncodingBuffer instance
66 * @param wantUnsignedPortionOnly If true, only prepends Name, MetaInfo, Content, and
67 * SignatureInfo to @p encoder, but omit SignatureValue and outmost Type-Length of Data
68 * element. This is intended to be used with wireEncode(encoder, signatureValue).
69 * @throw Error SignatureBits are not provided and wantUnsignedPortionOnly is false.
Jeff Thompsonb7aefa002013-09-16 18:22:00 -070070 */
Alexander Afanasyev74633892015-02-08 18:08:46 -080071 template<encoding::Tag TAG>
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070072 size_t
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070073 wireEncode(EncodingImpl<TAG>& encoder, bool wantUnsignedPortionOnly = false) const;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070074
Junxiao Shi81206d52017-07-23 12:43:22 +000075 /** @brief Finalize Data packet encoding with the specified SignatureValue
76 * @param encoder EncodingBuffer containing Name, MetaInfo, Content, and SignatureInfo, but
77 * without SignatureValue or outmost Type-Length of Data element
78 * @param signatureValue SignatureValue element
Alexander Afanasyev197e5652014-06-13 16:56:31 -070079 *
Junxiao Shi81206d52017-07-23 12:43:22 +000080 * This method is intended to be used in concert with Data::wireEncode(encoder, true)
81 * @code
Alexander Afanasyev197e5652014-06-13 16:56:31 -070082 * Data data;
83 * ...
84 * EncodingBuffer encoder;
85 * data.wireEncode(encoder, true);
86 * ...
87 * Block signatureValue = <sign_over_unsigned_portion>(encoder.buf(), encoder.size());
88 * data.wireEncode(encoder, signatureValue)
Junxiao Shi81206d52017-07-23 12:43:22 +000089 * @endcode
Alexander Afanasyev197e5652014-06-13 16:56:31 -070090 */
91 const Block&
92 wireEncode(EncodingBuffer& encoder, const Block& signatureValue) const;
93
Junxiao Shi7d9039b2018-04-14 15:56:28 +000094 /** @brief Encode to a @c Block.
95 * @pre Data is signed.
96 *
97 * Normally, this function encodes to NDN Packet Format v0.2. However, if this instance has
98 * cached wire encoding (\c hasWire() is true), the cached encoding is returned and it might
99 * be in v0.3 format.
Junxiao Shi81206d52017-07-23 12:43:22 +0000100 */
101 const Block&
102 wireEncode() const;
103
Junxiao Shi7d9039b2018-04-14 15:56:28 +0000104 /** @brief Decode from @p wire in NDN Packet Format v0.2 or v0.3.
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800105 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700106 void
107 wireDecode(const Block& wire);
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800108
Junxiao Shi7d9039b2018-04-14 15:56:28 +0000109 /** @brief Check if this instance has cached wire encoding.
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800110 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700111 bool
Junxiao Shi81206d52017-07-23 12:43:22 +0000112 hasWire() const
113 {
114 return m_wire.hasWire();
115 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700116
Junxiao Shi81206d52017-07-23 12:43:22 +0000117 /** @brief Get full name including implicit digest
118 * @pre hasWire() == true; i.e. wireEncode() must have been called
119 * @throw Error Data has no wire encoding
Alexander Afanasyev3b703102014-06-13 17:01:14 -0700120 */
121 const Name&
122 getFullName() const;
123
Junxiao Shi81206d52017-07-23 12:43:22 +0000124public: // Data fields
125 /** @brief Get name
126 */
127 const Name&
128 getName() const
129 {
130 return m_name;
131 }
132
133 /** @brief Set name
134 * @return a reference to this Data, to allow chaining
135 */
136 Data&
137 setName(const Name& name);
138
139 /** @brief Get MetaInfo
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700140 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700141 const MetaInfo&
Junxiao Shi81206d52017-07-23 12:43:22 +0000142 getMetaInfo() const
143 {
144 return m_metaInfo;
145 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700146
Junxiao Shi81206d52017-07-23 12:43:22 +0000147 /** @brief Set MetaInfo
148 * @return a reference to this Data, to allow chaining
Jeff Thompson0cd8c4a2013-09-13 17:46:40 -0700149 */
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700150 Data&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800151 setMetaInfo(const MetaInfo& metaInfo);
Jeff Thompson46bd45f2013-08-08 16:46:41 -0700152
Junxiao Shi81206d52017-07-23 12:43:22 +0000153 /** @brief Get Content
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800154 *
Junxiao Shi81206d52017-07-23 12:43:22 +0000155 * The Content value is accessible through value()/value_size() or value_begin()/value_end()
156 * methods of the Block class.
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800157 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700158 const Block&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800159 getContent() const;
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800160
Junxiao Shi81206d52017-07-23 12:43:22 +0000161 /** @brief Set Content from a block
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700162 *
Junxiao Shi81206d52017-07-23 12:43:22 +0000163 * If block's TLV-TYPE is Content, it will be used directly as Data's Content element.
164 * If block's TLV-TYPE is not Content, it will be nested into a Content element.
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700165 *
Junxiao Shi81206d52017-07-23 12:43:22 +0000166 * @return a reference to this Data, to allow chaining
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700167 */
168 Data&
169 setContent(const Block& block);
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800170
Junxiao Shi81206d52017-07-23 12:43:22 +0000171 /** @brief Copy Content value from raw buffer
172 * @param value pointer to the first octet of the value
173 * @param valueSize size of the raw buffer
174 * @return a reference to this Data, to allow chaining
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700175 */
176 Data&
Junxiao Shi81206d52017-07-23 12:43:22 +0000177 setContent(const uint8_t* value, size_t valueSize);
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800178
Junxiao Shi81206d52017-07-23 12:43:22 +0000179 /** @brief Set Content from wire buffer
180 * @param value Content value, which does not need to be a TLV element
181 * @return a reference to this Data, to allow chaining
182 */
183 Data&
Davide Pesavento3b101d02018-07-21 22:44:09 -0400184 setContent(ConstBufferPtr value);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700185
Junxiao Shi81206d52017-07-23 12:43:22 +0000186 /** @brief Get Signature
187 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700188 const Signature&
Junxiao Shi81206d52017-07-23 12:43:22 +0000189 getSignature() const
190 {
191 return m_signature;
192 }
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700193
Junxiao Shi81206d52017-07-23 12:43:22 +0000194 /** @brief Set Signature
195 * @return a reference to this Data, to allow chaining
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800196 */
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700197 Data&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800198 setSignature(const Signature& signature);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700199
Junxiao Shi81206d52017-07-23 12:43:22 +0000200 /** @brief Set SignatureValue
201 * @return a reference to this Data, to allow chaining
202 */
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700203 Data&
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700204 setSignatureValue(const Block& value);
Yingdi Yua4e57672014-02-06 11:16:17 -0800205
Junxiao Shi81206d52017-07-23 12:43:22 +0000206public: // MetaInfo fields
207 uint32_t
208 getContentType() const
209 {
210 return m_metaInfo.getType();
211 }
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700212
Junxiao Shi81206d52017-07-23 12:43:22 +0000213 Data&
214 setContentType(uint32_t type);
215
Junxiao Shiebfe4a22018-04-01 23:53:40 +0000216 time::milliseconds
Junxiao Shi81206d52017-07-23 12:43:22 +0000217 getFreshnessPeriod() const
218 {
219 return m_metaInfo.getFreshnessPeriod();
220 }
221
222 Data&
Junxiao Shiebfe4a22018-04-01 23:53:40 +0000223 setFreshnessPeriod(time::milliseconds freshnessPeriod);
Junxiao Shi81206d52017-07-23 12:43:22 +0000224
Junxiao Shiebfe4a22018-04-01 23:53:40 +0000225 const optional<name::Component>&
226 getFinalBlock() const
Junxiao Shi81206d52017-07-23 12:43:22 +0000227 {
Junxiao Shiebfe4a22018-04-01 23:53:40 +0000228 return m_metaInfo.getFinalBlock();
Junxiao Shi81206d52017-07-23 12:43:22 +0000229 }
230
231 Data&
Junxiao Shiebfe4a22018-04-01 23:53:40 +0000232 setFinalBlock(optional<name::Component> finalBlockId);
233
234 /** @deprecated Use @c getFinalBlock
235 * @sa MetaInfo::getFinalBlockId
236 */
Davide Pesavento1fd00242018-05-20 00:11:01 -0400237 [[deprecated("use getFinalBlock")]]
Junxiao Shiebfe4a22018-04-01 23:53:40 +0000238 name::Component
239 getFinalBlockId() const;
240
241 /** @deprecated Use @c setFinalBlock
242 * @sa MetaInfo::setFinalBlockId
243 */
Davide Pesavento1fd00242018-05-20 00:11:01 -0400244 [[deprecated("use setFinalBlock")]]
Junxiao Shiebfe4a22018-04-01 23:53:40 +0000245 Data&
Junxiao Shi81206d52017-07-23 12:43:22 +0000246 setFinalBlockId(const name::Component& finalBlockId);
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700247
Spyridon Mastorakis3b54e852015-04-07 08:03:25 -0700248protected:
Junxiao Shi81206d52017-07-23 12:43:22 +0000249 /** @brief Clear wire encoding and cached FullName
250 * @note This does not clear the SignatureValue.
Jeff Thompsonb7aefa002013-09-16 18:22:00 -0700251 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700252 void
Junxiao Shi81206d52017-07-23 12:43:22 +0000253 resetWire();
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800254
255private:
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800256 Name m_name;
257 MetaInfo m_metaInfo;
Junxiao Shi81206d52017-07-23 12:43:22 +0000258 Block m_content;
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800259 Signature m_signature;
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800260
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800261 mutable Block m_wire;
Junxiao Shi81206d52017-07-23 12:43:22 +0000262 mutable Name m_fullName; ///< cached FullName computed from m_wire
Jeff Thompson5cae5e52013-07-10 19:41:20 -0700263};
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800264
Davide Pesavento88a0d812017-08-19 21:31:42 -0400265#ifndef DOXYGEN
266extern template size_t
267Data::wireEncode<encoding::EncoderTag>(EncodingBuffer&, bool) const;
268
269extern template size_t
270Data::wireEncode<encoding::EstimatorTag>(EncodingEstimator&, bool) const;
271#endif
272
Alexander Afanasyeva0c5f832014-06-19 13:27:56 -0700273std::ostream&
274operator<<(std::ostream& os, const Data& data);
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800275
Junxiao Shi81206d52017-07-23 12:43:22 +0000276bool
277operator==(const Data& lhs, const Data& rhs);
278
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800279inline bool
Junxiao Shi81206d52017-07-23 12:43:22 +0000280operator!=(const Data& lhs, const Data& rhs)
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800281{
Junxiao Shi81206d52017-07-23 12:43:22 +0000282 return !(lhs == rhs);
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800283}
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700284
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800285} // namespace ndn
286
Junxiao Shi81206d52017-07-23 12:43:22 +0000287#endif // NDN_DATA_HPP