blob: b381c4ef408c0667bcd1f009c992121273a15762 [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Jeff Thompson5cae5e52013-07-10 19:41:20 -07002/**
Junxiao Shia1478db2016-09-09 04:13:15 +00003 * Copyright (c) 2013-2016 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
Jeff Thompson53412192013-08-06 13:35:50 -070025#include "name.hpp"
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080026#include "encoding/block.hpp"
Jeff Thompson25b4e612013-10-10 16:03:24 -070027
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080028#include "signature.hpp"
29#include "meta-info.hpp"
30#include "key-locator.hpp"
Alexander Afanasyeva3887ae2014-12-29 16:11:57 -080031#include "tag-host.hpp"
Jeff Thompson5cae5e52013-07-10 19:41:20 -070032
33namespace ndn {
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070034
Junxiao Shic2b8d242014-11-04 08:35:29 -070035/** @brief represents a Data packet
36 */
Alexander Afanasyeva3887ae2014-12-29 16:11:57 -080037class Data : public TagHost, public enable_shared_from_this<Data>
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080038{
Jeff Thompson5cae5e52013-07-10 19:41:20 -070039public:
Junxiao Shic2b8d242014-11-04 08:35:29 -070040 class Error : public tlv::Error
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070041 {
42 public:
43 explicit
44 Error(const std::string& what)
Junxiao Shic2b8d242014-11-04 08:35:29 -070045 : tlv::Error(what)
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070046 {
47 }
48 };
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070049
Jeff Thompson20af0732013-09-12 17:01:45 -070050 /**
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080051 * @brief Create an empty Data object
Alexander Afanasyev770827c2014-05-13 17:42:55 -070052 *
53 * Note that in certain contexts that use Data::shared_from_this(), Data must be
54 * created using `make_shared`:
55 *
56 * shared_ptr<Data> data = make_shared<Data>();
57 *
58 * Otherwise, Data::shared_from_this() will throw an exception.
Jeff Thompson20af0732013-09-12 17:01:45 -070059 */
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080060 Data();
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070061
Jeff Thompson20af0732013-09-12 17:01:45 -070062 /**
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080063 * @brief Create a new Data object with the given name
Alexander Afanasyev770827c2014-05-13 17:42:55 -070064 *
65 * @param name A reference to the name
66 *
67 * Note that in certain contexts that use Data::shared_from_this(), Data must be
68 * created using `make_shared`:
69 *
70 * shared_ptr<Data> data = make_shared<Data>(name);
71 *
72 * Otherwise, Data::shared_from_this() will throw an exception.
Jeff Thompson20af0732013-09-12 17:01:45 -070073 */
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080074 Data(const Name& name);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -080075
76 /**
77 * @brief Create a new Data object from wire encoding
Alexander Afanasyev770827c2014-05-13 17:42:55 -070078 *
79 * Note that in certain contexts that use Data::shared_from_this(), Data must be
80 * created using `make_shared`:
81 *
82 * shared_ptr<Data> data = make_shared<Data>(wire);
83 *
84 * Otherwise, Data::shared_from_this() will throw an exception.
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -080085 */
86 explicit
Alexander Afanasyev197e5652014-06-13 16:56:31 -070087 Data(const Block& wire);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070088
Jeff Thompson25bfdca2013-10-16 17:05:41 -070089 /**
Alexander Afanasyev809805d2014-02-17 17:20:33 -080090 * @brief Fast encoding or block size estimation
Alexander Afanasyev197e5652014-06-13 16:56:31 -070091 *
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070092 * @param encoder EncodingEstimator or EncodingBuffer instance
Alexander Afanasyev197e5652014-06-13 16:56:31 -070093 * @param wantUnsignedPortionOnly Request only unsigned portion to be encoded in block.
94 * If true, only Name, MetaInfo, Content, and SignatureInfo
95 * blocks will be encoded into the block. Note that there
96 * will be no outer TLV header of the Data packet.
Jeff Thompsonb7aefa002013-09-16 18:22:00 -070097 */
Alexander Afanasyev74633892015-02-08 18:08:46 -080098 template<encoding::Tag TAG>
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070099 size_t
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -0700100 wireEncode(EncodingImpl<TAG>& encoder, bool wantUnsignedPortionOnly = false) const;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700101
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800102 /**
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800103 * @brief Encode to a wire format
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800104 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700105 const Block&
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800106 wireEncode() const;
107
108 /**
Alexander Afanasyev197e5652014-06-13 16:56:31 -0700109 * @brief Finalize Data packet encoding with the specified SignatureValue
110 *
111 * @param encoder EncodingBuffer instance, containing Name, MetaInfo, Content, and
112 * SignatureInfo (without outer TLV header of the Data packet).
113 * @param signatureValue SignatureValue block to be added to Data packet to finalize
114 * the wire encoding
115 *
116 * This method is intended to be used in concert with Data::wireEncode(EncodingBuffer&, true)
117 * method to optimize Data packet wire format creation:
118 *
119 * Data data;
120 * ...
121 * EncodingBuffer encoder;
122 * data.wireEncode(encoder, true);
123 * ...
124 * Block signatureValue = <sign_over_unsigned_portion>(encoder.buf(), encoder.size());
125 * data.wireEncode(encoder, signatureValue)
126 */
127 const Block&
128 wireEncode(EncodingBuffer& encoder, const Block& signatureValue) const;
129
130 /**
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800131 * @brief Decode from the wire format
132 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700133 void
134 wireDecode(const Block& wire);
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800135
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800136 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700137 * @brief Check if Data is already has wire encoding
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800138 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700139 bool
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800140 hasWire() const;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700141
142 ////////////////////////////////////////////////////////////////////
143
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700144 /**
145 * @brief Get name of the Data packet
146 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700147 const Name&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800148 getName() const;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700149
Jeff Thompson5cae5e52013-07-10 19:41:20 -0700150 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700151 * @brief Set name to a copy of the given Name
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800152 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700153 * @return This Data so that you can chain calls to update values
Jeff Thompson0cd8c4a2013-09-13 17:46:40 -0700154 */
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700155 Data&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800156 setName(const Name& name);
157
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800158 //
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700159
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700160 /**
Alexander Afanasyev3b703102014-06-13 17:01:14 -0700161 * @brief Get full name of Data packet, including the implicit digest
162 *
163 * @throws Error if Data packet doesn't have a full name yet (wire encoding has not been
164 * yet created)
165 */
166 const Name&
167 getFullName() const;
168
169 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700170 * @brief Get MetaInfo block from Data packet
171 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700172 const MetaInfo&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800173 getMetaInfo() const;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700174
Jeff Thompson0cd8c4a2013-09-13 17:46:40 -0700175 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700176 * @brief Set metaInfo to a copy of the given MetaInfo
177 *
Jeff Thompson6d591972013-10-17 11:16:32 -0700178 * @return This Data so that you can chain calls to update values.
Jeff Thompson0cd8c4a2013-09-13 17:46:40 -0700179 */
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700180 Data&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800181 setMetaInfo(const MetaInfo& metaInfo);
Jeff Thompson46bd45f2013-08-08 16:46:41 -0700182
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800183 //
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700184
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800185 ///////////////////////////////////////////////////////////////
186 ///////////////////////////////////////////////////////////////
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800187 ///////////////////////////////////////////////////////////////
188 // MetaInfo proxy methods
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800189
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700190 uint32_t
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800191 getContentType() const;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700192
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700193 Data&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800194 setContentType(uint32_t type);
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800195
196 //
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700197
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700198 const time::milliseconds&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800199 getFreshnessPeriod() const;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700200
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700201 Data&
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700202 setFreshnessPeriod(const time::milliseconds& freshnessPeriod);
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800203
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800204 //
205
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700206 const name::Component&
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800207 getFinalBlockId() const;
208
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700209 Data&
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800210 setFinalBlockId(const name::Component& finalBlockId);
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800211
212 //
213 ///////////////////////////////////////////////////////////////
214 ///////////////////////////////////////////////////////////////
215 ///////////////////////////////////////////////////////////////
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700216
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800217 /**
218 * @brief Get content Block
219 *
220 * To access content value, one can use value()/value_size() or
221 * value_begin()/value_end() methods of the Block class
222 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700223 const Block&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800224 getContent() const;
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800225
Jeff Thompson0899c0f2013-09-12 12:15:31 -0700226 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700227 * @brief Set the content from the buffer (buffer will be copied)
228 *
229 * @param buffer Pointer to first byte of the buffer
230 * @param bufferSize Size of the buffer
231 *
Jeff Thompson6d591972013-10-17 11:16:32 -0700232 * @return This Data so that you can chain calls to update values.
Jeff Thompson0899c0f2013-09-12 12:15:31 -0700233 */
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700234 Data&
235 setContent(const uint8_t* buffer, size_t bufferSize);
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800236
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700237 /**
238 * @brief Set the content from the block
239 *
240 * Depending on type of the supplied block, there are two cases:
241 *
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600242 * - if block.type() == tlv::Content, then block will be used directly as Data packet's
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700243 * content (no extra copying)
244 *
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600245 * - if block.type() != tlv::Content, then this method will create a new Block with type
246 * tlv::Content and put block as a nested element in the content Block.
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700247 *
248 * @param block The Block containing the content to assign
249 *
250 * @return This Data so that you can chain calls to update values.
251 */
252 Data&
253 setContent(const Block& block);
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800254
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700255 /**
256 * @brief Set the content from the pointer to immutable buffer
257 *
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600258 * This method will create a Block with tlv::Content and set contentValue as a payload
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700259 * for this block. Note that this method is very different from setContent(const
260 * Block&), since it does not require that payload should be a valid TLV element.
261 *
262 * @param contentValue The pointer to immutable buffer containing the content to assign
263 *
264 * @return This Data so that you can chain calls to update values.
265 */
266 Data&
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700267 setContent(const ConstBufferPtr& contentValue);
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800268
269 //
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700270
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700271 const Signature&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800272 getSignature() const;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700273
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800274 /**
275 * @brief Set the signature to a copy of the given signature.
276 * @param signature The signature object which is cloned.
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800277 */
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700278 Data&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800279 setSignature(const Signature& signature);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700280
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700281 Data&
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700282 setSignatureValue(const Block& value);
Yingdi Yua4e57672014-02-06 11:16:17 -0800283
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700284public: // EqualityComparable concept
285 bool
286 operator==(const Data& other) const;
287
288 bool
289 operator!=(const Data& other) const;
290
Spyridon Mastorakis3b54e852015-04-07 08:03:25 -0700291protected:
Jeff Thompsonb7aefa002013-09-16 18:22:00 -0700292 /**
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800293 * @brief Clear the wire encoding.
Jeff Thompsonb7aefa002013-09-16 18:22:00 -0700294 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700295 void
Jeff Thompson0050abe2013-09-17 12:50:25 -0700296 onChanged();
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800297
298private:
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800299 Name m_name;
300 MetaInfo m_metaInfo;
301 mutable Block m_content;
302 Signature m_signature;
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800303
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800304 mutable Block m_wire;
Alexander Afanasyev3b703102014-06-13 17:01:14 -0700305 mutable Name m_fullName;
Jeff Thompson5cae5e52013-07-10 19:41:20 -0700306};
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800307
Alexander Afanasyeva0c5f832014-06-19 13:27:56 -0700308std::ostream&
309operator<<(std::ostream& os, const Data& data);
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800310
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800311inline bool
312Data::hasWire() const
313{
314 return m_wire.hasWire();
315}
316
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700317inline const Name&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800318Data::getName() const
319{
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800320 return m_name;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800321}
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700322
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700323inline const MetaInfo&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800324Data::getMetaInfo() const
325{
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800326 return m_metaInfo;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800327}
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700328
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700329inline uint32_t
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800330Data::getContentType() const
331{
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800332 return m_metaInfo.getType();
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800333}
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700334
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700335inline const time::milliseconds&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800336Data::getFreshnessPeriod() const
337{
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800338 return m_metaInfo.getFreshnessPeriod();
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800339}
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700340
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800341inline const name::Component&
342Data::getFinalBlockId() const
343{
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800344 return m_metaInfo.getFinalBlockId();
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800345}
346
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800347inline const Signature&
348Data::getSignature() const
349{
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800350 return m_signature;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800351}
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700352
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800353} // namespace ndn
354
Jeff Thompson5cae5e52013-07-10 19:41:20 -0700355#endif