blob: 93382588ab7db51400c786d669cc7c5694f7fa34 [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/**
Alexander Afanasyevc169a812014-05-20 20:37:29 -04003 * Copyright (c) 2013-2014 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 Thompson46bd45f2013-08-08 16:46:41 -070025#include "common.hpp"
Jeff Thompson53412192013-08-06 13:35:50 -070026#include "name.hpp"
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080027#include "encoding/block.hpp"
Jeff Thompson25b4e612013-10-10 16:03:24 -070028
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080029#include "signature.hpp"
30#include "meta-info.hpp"
31#include "key-locator.hpp"
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -080032#include "management/nfd-local-control-header.hpp"
Jeff Thompson5cae5e52013-07-10 19:41:20 -070033
34namespace ndn {
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070035
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080036class Data : public enable_shared_from_this<Data>
37{
Jeff Thompson5cae5e52013-07-10 19:41:20 -070038public:
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070039 class Error : public std::runtime_error
40 {
41 public:
42 explicit
43 Error(const std::string& what)
44 : std::runtime_error(what)
45 {
46 }
47 };
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070048
Jeff Thompson20af0732013-09-12 17:01:45 -070049 /**
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080050 * @brief Create an empty Data object
Alexander Afanasyev770827c2014-05-13 17:42:55 -070051 *
52 * Note that in certain contexts that use Data::shared_from_this(), Data must be
53 * created using `make_shared`:
54 *
55 * shared_ptr<Data> data = make_shared<Data>();
56 *
57 * Otherwise, Data::shared_from_this() will throw an exception.
Jeff Thompson20af0732013-09-12 17:01:45 -070058 */
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080059 Data();
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070060
Jeff Thompson20af0732013-09-12 17:01:45 -070061 /**
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080062 * @brief Create a new Data object with the given name
Alexander Afanasyev770827c2014-05-13 17:42:55 -070063 *
64 * @param name A reference to the name
65 *
66 * Note that in certain contexts that use Data::shared_from_this(), Data must be
67 * created using `make_shared`:
68 *
69 * shared_ptr<Data> data = make_shared<Data>(name);
70 *
71 * Otherwise, Data::shared_from_this() will throw an exception.
Jeff Thompson20af0732013-09-12 17:01:45 -070072 */
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080073 Data(const Name& name);
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -080074
75 /**
76 * @brief Create a new Data object from wire encoding
Alexander Afanasyev770827c2014-05-13 17:42:55 -070077 *
78 * Note that in certain contexts that use Data::shared_from_this(), Data must be
79 * created using `make_shared`:
80 *
81 * shared_ptr<Data> data = make_shared<Data>(wire);
82 *
83 * Otherwise, Data::shared_from_this() will throw an exception.
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -080084 */
85 explicit
Alexander Afanasyev197e5652014-06-13 16:56:31 -070086 Data(const Block& wire);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070087
Jeff Thompson25bfdca2013-10-16 17:05:41 -070088 /**
Alexander Afanasyev809805d2014-02-17 17:20:33 -080089 * @brief Fast encoding or block size estimation
Alexander Afanasyev197e5652014-06-13 16:56:31 -070090 *
91 * @param block EncodingEstimator or EncodingBuffer instance
92 * @param wantUnsignedPortionOnly Request only unsigned portion to be encoded in block.
93 * If true, only Name, MetaInfo, Content, and SignatureInfo
94 * blocks will be encoded into the block. Note that there
95 * will be no outer TLV header of the Data packet.
Jeff Thompsonb7aefa002013-09-16 18:22:00 -070096 */
Alexander Afanasyev809805d2014-02-17 17:20:33 -080097 template<bool T>
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070098 size_t
Alexander Afanasyev197e5652014-06-13 16:56:31 -070099 wireEncode(EncodingImpl<T>& block, bool wantUnsignedPortionOnly = false) const;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700100
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800101 /**
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800102 * @brief Encode to a wire format
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800103 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700104 const Block&
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800105 wireEncode() const;
106
107 /**
Alexander Afanasyev197e5652014-06-13 16:56:31 -0700108 * @brief Finalize Data packet encoding with the specified SignatureValue
109 *
110 * @param encoder EncodingBuffer instance, containing Name, MetaInfo, Content, and
111 * SignatureInfo (without outer TLV header of the Data packet).
112 * @param signatureValue SignatureValue block to be added to Data packet to finalize
113 * the wire encoding
114 *
115 * This method is intended to be used in concert with Data::wireEncode(EncodingBuffer&, true)
116 * method to optimize Data packet wire format creation:
117 *
118 * Data data;
119 * ...
120 * EncodingBuffer encoder;
121 * data.wireEncode(encoder, true);
122 * ...
123 * Block signatureValue = <sign_over_unsigned_portion>(encoder.buf(), encoder.size());
124 * data.wireEncode(encoder, signatureValue)
125 */
126 const Block&
127 wireEncode(EncodingBuffer& encoder, const Block& signatureValue) const;
128
129 /**
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800130 * @brief Decode from the wire format
131 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700132 void
133 wireDecode(const Block& wire);
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800134
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800135 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700136 * @brief Check if Data is already has wire encoding
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800137 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700138 bool
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800139 hasWire() const;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700140
141 ////////////////////////////////////////////////////////////////////
142
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700143 /**
144 * @brief Get name of the Data packet
145 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700146 const Name&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800147 getName() const;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700148
Jeff Thompson5cae5e52013-07-10 19:41:20 -0700149 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700150 * @brief Set name to a copy of the given Name
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800151 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700152 * @return This Data so that you can chain calls to update values
Jeff Thompson0cd8c4a2013-09-13 17:46:40 -0700153 */
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700154 Data&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800155 setName(const Name& name);
156
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800157 //
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700158
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700159 /**
160 * @brief Get MetaInfo block from Data packet
161 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700162 const MetaInfo&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800163 getMetaInfo() const;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700164
Jeff Thompson0cd8c4a2013-09-13 17:46:40 -0700165 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700166 * @brief Set metaInfo to a copy of the given MetaInfo
167 *
Jeff Thompson6d591972013-10-17 11:16:32 -0700168 * @return This Data so that you can chain calls to update values.
Jeff Thompson0cd8c4a2013-09-13 17:46:40 -0700169 */
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700170 Data&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800171 setMetaInfo(const MetaInfo& metaInfo);
Jeff Thompson46bd45f2013-08-08 16:46:41 -0700172
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800173 //
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700174
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800175 ///////////////////////////////////////////////////////////////
176 ///////////////////////////////////////////////////////////////
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800177 ///////////////////////////////////////////////////////////////
178 // MetaInfo proxy methods
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800179
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700180 uint32_t
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800181 getContentType() const;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700182
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700183 Data&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800184 setContentType(uint32_t type);
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800185
186 //
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700187
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700188 const time::milliseconds&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800189 getFreshnessPeriod() const;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700190
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700191 Data&
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700192 setFreshnessPeriod(const time::milliseconds& freshnessPeriod);
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800193
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800194 //
195
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700196 const name::Component&
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800197 getFinalBlockId() const;
198
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700199 Data&
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800200 setFinalBlockId(const name::Component& finalBlockId);
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800201
202 //
203 ///////////////////////////////////////////////////////////////
204 ///////////////////////////////////////////////////////////////
205 ///////////////////////////////////////////////////////////////
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700206
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800207 /**
208 * @brief Get content Block
209 *
210 * To access content value, one can use value()/value_size() or
211 * value_begin()/value_end() methods of the Block class
212 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700213 const Block&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800214 getContent() const;
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800215
Jeff Thompson0899c0f2013-09-12 12:15:31 -0700216 /**
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700217 * @brief Set the content from the buffer (buffer will be copied)
218 *
219 * @param buffer Pointer to first byte of the buffer
220 * @param bufferSize Size of the buffer
221 *
Jeff Thompson6d591972013-10-17 11:16:32 -0700222 * @return This Data so that you can chain calls to update values.
Jeff Thompson0899c0f2013-09-12 12:15:31 -0700223 */
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700224 Data&
225 setContent(const uint8_t* buffer, size_t bufferSize);
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800226
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700227 /**
228 * @brief Set the content from the block
229 *
230 * Depending on type of the supplied block, there are two cases:
231 *
232 * - if block.type() == Tlv::Content, then block will be used directly as Data packet's
233 * content (no extra copying)
234 *
235 * - if block.type() != Tlv::Content, then this method will create a new Block with type
236 * Tlv::Content and put block as a nested element in the content Block.
237 *
238 * @param block The Block containing the content to assign
239 *
240 * @return This Data so that you can chain calls to update values.
241 */
242 Data&
243 setContent(const Block& block);
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800244
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700245 /**
246 * @brief Set the content from the pointer to immutable buffer
247 *
248 * This method will create a Block with Tlv::Content and set contentValue as a payload
249 * for this block. Note that this method is very different from setContent(const
250 * Block&), since it does not require that payload should be a valid TLV element.
251 *
252 * @param contentValue The pointer to immutable buffer containing the content to assign
253 *
254 * @return This Data so that you can chain calls to update values.
255 */
256 Data&
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700257 setContent(const ConstBufferPtr& contentValue);
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800258
259 //
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700260
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700261 const Signature&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800262 getSignature() const;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700263
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800264 /**
265 * @brief Set the signature to a copy of the given signature.
266 * @param signature The signature object which is cloned.
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800267 */
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700268 Data&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800269 setSignature(const Signature& signature);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700270
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700271 Data&
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700272 setSignatureValue(const Block& value);
Yingdi Yua4e57672014-02-06 11:16:17 -0800273
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800274 ///////////////////////////////////////////////////////////////
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800275
276 nfd::LocalControlHeader&
277 getLocalControlHeader();
278
279 const nfd::LocalControlHeader&
280 getLocalControlHeader() const;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700281
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700282 uint64_t
Yingdi Yua4e57672014-02-06 11:16:17 -0800283 getIncomingFaceId() const;
284
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700285 Data&
Yingdi Yua4e57672014-02-06 11:16:17 -0800286 setIncomingFaceId(uint64_t incomingFaceId);
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700287
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700288public: // EqualityComparable concept
289 bool
290 operator==(const Data& other) const;
291
292 bool
293 operator!=(const Data& other) const;
294
Jeff Thompson5cae5e52013-07-10 19:41:20 -0700295private:
Jeff Thompsonb7aefa002013-09-16 18:22:00 -0700296 /**
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800297 * @brief Clear the wire encoding.
Jeff Thompsonb7aefa002013-09-16 18:22:00 -0700298 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700299 void
Jeff Thompson0050abe2013-09-17 12:50:25 -0700300 onChanged();
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800301
302private:
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800303 Name m_name;
304 MetaInfo m_metaInfo;
305 mutable Block m_content;
306 Signature m_signature;
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800307
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800308 mutable Block m_wire;
Yingdi Yua4e57672014-02-06 11:16:17 -0800309
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800310 nfd::LocalControlHeader m_localControlHeader;
311 friend class nfd::LocalControlHeader;
Jeff Thompson5cae5e52013-07-10 19:41:20 -0700312};
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800313
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800314
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800315inline bool
316Data::hasWire() const
317{
318 return m_wire.hasWire();
319}
320
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700321inline const Name&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800322Data::getName() const
323{
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800324 return m_name;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800325}
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700326
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700327inline const MetaInfo&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800328Data::getMetaInfo() const
329{
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800330 return m_metaInfo;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800331}
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700332
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700333inline uint32_t
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800334Data::getContentType() const
335{
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800336 return m_metaInfo.getType();
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800337}
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700338
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700339inline const time::milliseconds&
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800340Data::getFreshnessPeriod() const
341{
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800342 return m_metaInfo.getFreshnessPeriod();
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800343}
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700344
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800345inline const name::Component&
346Data::getFinalBlockId() const
347{
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800348 return m_metaInfo.getFinalBlockId();
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800349}
350
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800351inline const Signature&
352Data::getSignature() const
353{
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800354 return m_signature;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800355}
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700356
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800357inline nfd::LocalControlHeader&
358Data::getLocalControlHeader()
359{
360 return m_localControlHeader;
361}
362
363inline const nfd::LocalControlHeader&
364Data::getLocalControlHeader() const
365{
366 return m_localControlHeader;
367}
368
Yingdi Yua4e57672014-02-06 11:16:17 -0800369inline uint64_t
370Data::getIncomingFaceId() const
371{
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800372 return getLocalControlHeader().getIncomingFaceId();
Yingdi Yua4e57672014-02-06 11:16:17 -0800373}
374
Alexander Afanasyev4ff3c912014-01-03 15:25:02 -0800375
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800376} // namespace ndn
377
Jeff Thompson5cae5e52013-07-10 19:41:20 -0700378#endif